@@ -86,7 +86,7 @@ import {
8686 getDnsLookupFunction ,
8787 getTrustedCAs ,
8888 buildUpstreamErrorTags ,
89- getUrlHostname ,
89+ getEffectiveHostname ,
9090 applyDestinationTransforms
9191} from '../passthrough-handling' ;
9292
@@ -422,11 +422,17 @@ export class PassThroughStepImpl extends PassThroughStep {
422422 // Capture raw request data:
423423 let { method, url : reqUrl , rawHeaders, destination } = clientReq as OngoingRequest ;
424424 let { protocol, pathname, search : query } = url . parse ( reqUrl ) ;
425- let hostname : string = destination . hostname ;
425+ const clientSocket = ( clientReq as any ) . socket as net . Socket ;
426+
427+ // Actual IP address or hostname
428+ let hostAddress = destination . hostname ;
429+ // Same as hostAddress, unless it's an IP, in which case it's our best guess of the
430+ // functional 'name' for the host (from Host header or SNI).
431+ let hostname : string = getEffectiveHostname ( hostAddress , clientSocket , rawHeaders ) ;
426432 let port : string | null | undefined = destination . port . toString ( ) ;
427433
428434 // Check if this request is a request loop:
429- if ( isSocketLoop ( this . outgoingSockets , ( clientReq as any ) . socket ) ) {
435+ if ( isSocketLoop ( this . outgoingSockets , clientSocket ) ) {
430436 throw new Error ( oneLine `
431437 Passthrough loop detected. This probably means you're sending a request directly
432438 to a passthrough endpoint, which is forwarding it to the target URL, which is a
@@ -444,8 +450,8 @@ export class PassThroughStepImpl extends PassThroughStep {
444450
445451 const isH2Downstream = isHttp2 ( clientReq ) ;
446452
447- hostname = await getClientRelativeHostname (
448- hostname ,
453+ hostAddress = await getClientRelativeHostname (
454+ hostAddress ,
449455 clientReq . remoteIpAddress ,
450456 getDnsLookupFunction ( this . lookupOptions )
451457 ) ;
@@ -466,6 +472,8 @@ export class PassThroughStepImpl extends PassThroughStep {
466472 matchReplaceBody
467473 } = this . transformRequest ;
468474
475+ const originalHostname = hostname ;
476+
469477 ( {
470478 reqUrl,
471479 protocol,
@@ -484,6 +492,12 @@ export class PassThroughStepImpl extends PassThroughStep {
484492 query
485493 } ) ) ;
486494
495+ // If you modify the hostname, we also treat that as modifying the
496+ // resulting destination in turn:
497+ if ( hostname !== originalHostname ) {
498+ hostAddress = hostname ;
499+ }
500+
487501 if ( replaceMethod ) {
488502 method = replaceMethod ;
489503 }
@@ -579,8 +593,7 @@ export class PassThroughStepImpl extends PassThroughStep {
579593
580594 if ( modifiedReq ?. response ) {
581595 if ( modifiedReq . response === 'close' ) {
582- const socket : net . Socket = ( clientReq as any ) . socket ;
583- socket . end ( ) ;
596+ clientSocket . end ( ) ;
584597 throw new AbortError ( 'Connection closed intentionally by rule' , 'E_RULE_BREQ_CLOSE' ) ;
585598 } else if ( modifiedReq . response === 'reset' ) {
586599 requireSocketResetSupport ( ) ;
@@ -594,18 +607,27 @@ export class PassThroughStepImpl extends PassThroughStep {
594607 }
595608
596609 method = modifiedReq ?. method || method ;
597- reqUrl = modifiedReq ?. url || reqUrl ;
610+
611+ // Reparse the new URL, if necessary
612+ if ( modifiedReq ?. url ) {
613+ if ( ! isAbsoluteUrl ( modifiedReq ?. url ) ) throw new Error ( "Overridden request URLs must be absolute" ) ;
614+
615+ reqUrl = modifiedReq . url ;
616+
617+ const parsedUrl = url . parse ( reqUrl ) ;
618+ ( { protocol, port, pathname, search : query } = parsedUrl ) ;
619+ hostname = parsedUrl . hostname ! ;
620+ hostAddress = hostname ;
621+ }
598622
599623 let headers = modifiedReq ?. headers || clientHeaders ;
600624
601625 // We need to make sure the Host/:authority header is updated correctly - following the user's returned value if
602626 // they provided one, but updating it if not to match the effective target URL of the request:
603- const expectedTargetUrl = modifiedReq ?. url ?? reqUrl ;
604-
605627 Object . assign ( headers ,
606628 isH2Downstream
607- ? getH2HeadersAfterModification ( expectedTargetUrl , clientHeaders , modifiedReq ?. headers )
608- : { 'host' : getHostAfterModification ( expectedTargetUrl , clientHeaders , modifiedReq ?. headers ) }
629+ ? getH2HeadersAfterModification ( reqUrl , clientHeaders , modifiedReq ?. headers )
630+ : { 'host' : getHostAfterModification ( reqUrl , clientHeaders , modifiedReq ?. headers ) }
609631 ) ;
610632
611633 validateCustomHeaders (
@@ -630,14 +652,6 @@ export class PassThroughStepImpl extends PassThroughStep {
630652 }
631653 }
632654
633- // Reparse the new URL, if necessary
634- if ( modifiedReq ?. url ) {
635- if ( ! isAbsoluteUrl ( modifiedReq ?. url ) ) throw new Error ( "Overridden request URLs must be absolute" ) ;
636- const parsedUrl = url . parse ( reqUrl ) ;
637- ( { protocol, port, pathname, search : query } = parsedUrl ) ;
638- hostname = parsedUrl . hostname ! ;
639- }
640-
641655 rawHeaders = objectHeadersToRaw ( headers ) ;
642656 }
643657
@@ -726,7 +740,7 @@ export class PassThroughStepImpl extends PassThroughStep {
726740 serverReq = await makeRequest ( {
727741 protocol,
728742 method,
729- hostname,
743+ hostname : hostAddress ,
730744 port,
731745 family,
732746 path : `${ pathname || '/' } ${ query || '' } ` ,
@@ -739,7 +753,7 @@ export class PassThroughStepImpl extends PassThroughStep {
739753 agent,
740754
741755 // TLS options:
742- ...getUpstreamTlsOptions ( strictHttpsChecks ) ,
756+ ...getUpstreamTlsOptions ( { strictHttpsChecks, serverName : hostname } ) ,
743757 ...clientCert ,
744758 ...caConfig
745759 } , ( serverRes ) => ( async ( ) => {
@@ -944,7 +958,7 @@ export class PassThroughStepImpl extends PassThroughStep {
944958 }
945959
946960 if ( modifiedRes === 'close' ) {
947- ( clientReq as any ) . socket . end ( ) ;
961+ clientSocket . end ( ) ;
948962 } else if ( modifiedRes === 'reset' ) {
949963 requireSocketResetSupport ( ) ;
950964 resetOrDestroy ( clientReq ) ;
@@ -1151,12 +1165,10 @@ export class PassThroughStepImpl extends PassThroughStep {
11511165 // Fire rule events, to allow in-depth debugging of upstream traffic & modifications,
11521166 // so anybody interested can see _exactly_ what we're sending upstream here:
11531167 if ( options . emitEventCallback ) {
1154- const urlHost = getUrlHostname ( hostname , rawHeaders ) ;
1155-
11561168 options . emitEventCallback ( 'passthrough-request-head' , {
11571169 method,
11581170 protocol : protocol ! . replace ( / : $ / , '' ) ,
1159- hostname : urlHost ,
1171+ hostname,
11601172 port,
11611173 path : `${ pathname || '/' } ${ query || '' } ` ,
11621174 rawHeaders
0 commit comments