@@ -24,7 +24,15 @@ import { shouldPassThrough } from '../util/server-utils';
2424import {
2525 getParentSocket ,
2626 buildSocketTimingInfo ,
27- buildSocketEventData
27+ buildSocketEventData ,
28+ SocketIsh ,
29+ InitialRemoteAddress ,
30+ InitialRemotePort ,
31+ SocketTimingInfo ,
32+ LastTunnelAddress ,
33+ LastHopEncrypted ,
34+ TlsMetadata ,
35+ TlsSetupCompleted
2836} from '../util/socket-util' ;
2937import { MockttpHttpsOptions } from '../mockttp' ;
3038import { buildSocksServer , SocksTcpAddress } from './socks-server' ;
@@ -43,10 +51,10 @@ const originalSocketInit = (<any>tls.TLSSocket.prototype)._init;
4351 const loadSNI = _handle . oncertcb ;
4452 _handle . oncertcb = function ( info : any ) {
4553 tlsSocket . servername = info . servername ;
46- tlsSocket . initialRemoteAddress = tlsSocket . remoteAddress || // Normal case
54+ tlsSocket [ InitialRemoteAddress ] = tlsSocket . remoteAddress || // Normal case
4755 tlsSocket . _parent ?. remoteAddress || // For early failing sockets
4856 tlsSocket . _handle ?. _parentWrap ?. stream ?. remoteAddress ; // For HTTP/2 CONNECT
49- tlsSocket . initialRemotePort = tlsSocket . remotePort ||
57+ tlsSocket [ InitialRemotePort ] = tlsSocket . remotePort ||
5058 tlsSocket . _parent ?. remotePort ||
5159 tlsSocket . _handle ?. _parentWrap ?. stream ?. remotePort ;
5260
@@ -76,7 +84,7 @@ function ifTlsDropped(socket: tls.TLSSocket, errorCallback: () => void) {
7684 // Even if these are shut later on, that doesn't mean they're are rejected connections.
7785 // To differentiate the two cases, we consider connections OK after waiting 10x longer
7886 // than the initial TLS handshake for an unhappy disconnection.
79- const timing = socket . __timingInfo ;
87+ const timing = socket [ SocketTimingInfo ] ;
8088 const tlsSetupDuration = timing
8189 ? timing . tlsConnectedTimestamp ! - ( timing . tunnelSetupTimestamp ! || timing . initialSocketTimestamp )
8290 : 0 ;
@@ -89,11 +97,11 @@ function ifTlsDropped(socket: tls.TLSSocket, errorCallback: () => void) {
8997 . then ( ( ) => {
9098 // Mark the socket as having completed TLS setup - this ensures that future
9199 // errors fire as client errors, not TLS setup errors.
92- socket . tlsSetupCompleted = true ;
100+ socket [ TlsSetupCompleted ] = true ;
93101 } )
94102 . catch ( ( ) => {
95103 // If TLS setup was confirmed in any way, we know we don't have a TLS error.
96- if ( socket . tlsSetupCompleted ) return ;
104+ if ( socket [ TlsSetupCompleted ] ) return ;
97105
98106 // To get here, the socket must have connected & done the TLS handshake, but then
99107 // closed/ended without ever sending any data. We can fairly confidently assume
@@ -227,8 +235,8 @@ export async function createComboServer(
227235
228236 if ( options . debug ) console . log ( `Proxying SOCKS TCP connection to ${ addressString } ` ) ;
229237
230- socket . __timingInfo ! . tunnelSetupTimestamp = now ( ) ;
231- socket . __lastHopConnectAddress = addressString ;
238+ socket [ SocketTimingInfo ] ! . tunnelSetupTimestamp = now ( ) ;
239+ socket [ LastTunnelAddress ] = addressString ;
232240
233241 // Put the socket back into the server, so we can handle the data within:
234242 server . emit ( 'connection' , socket ) ;
@@ -245,11 +253,11 @@ export async function createComboServer(
245253 ( server as any ) . _httpServer . requireHostHeader = false ;
246254
247255 server . on ( 'connection' , ( socket : net . Socket | http2 . ServerHttp2Stream ) => {
248- socket . __timingInfo = socket . __timingInfo || buildSocketTimingInfo ( ) ;
256+ socket [ SocketTimingInfo ] ||= buildSocketTimingInfo ( ) ;
249257
250258 // All sockets are initially marked as using unencrypted upstream connections.
251259 // If TLS is used, this is upgraded to 'true' by secureConnection below.
252- socket . __lastHopEncrypted = false ;
260+ socket [ LastHopEncrypted ] = false ;
253261
254262 // For actual sockets, set NODELAY to avoid any buffering whilst streaming. This is
255263 // off by default in Node HTTP, but likely to be enabled soon & is default in curl.
@@ -265,14 +273,14 @@ export async function createComboServer(
265273 copyTimingDetails ( parentSocket , socket ) ;
266274 // With TLS metadata, we only propagate directly from parent sockets, not through
267275 // CONNECT etc - we only want it if the final hop is TLS, previous values don't matter.
268- socket . __tlsMetadata ??= parentSocket . __tlsMetadata ;
269- } else if ( ! socket . __timingInfo ) {
270- socket . __timingInfo = buildSocketTimingInfo ( ) ;
276+ socket [ TlsMetadata ] ??= parentSocket [ TlsMetadata ] ;
277+ } else if ( ! socket [ SocketTimingInfo ] ) {
278+ socket [ SocketTimingInfo ] = buildSocketTimingInfo ( ) ;
271279 }
272280
273- socket . __timingInfo ! . tlsConnectedTimestamp = now ( ) ;
281+ socket [ SocketTimingInfo ] ! . tlsConnectedTimestamp = now ( ) ;
274282
275- socket . __lastHopEncrypted = true ;
283+ socket [ LastHopEncrypted ] = true ;
276284 ifTlsDropped ( socket , ( ) => {
277285 tlsClientErrorListener ( socket , buildTlsError ( socket , 'closed' ) ) ;
278286 } ) ;
@@ -282,7 +290,7 @@ export async function createComboServer(
282290 // happens immediately after the connection preface, as long as the connection is OK.
283291 server ! . on ( 'session' , ( session ) => {
284292 session . once ( 'remoteSettings' , ( ) => {
285- session . socket . tlsSetupCompleted = true ;
293+ ( session . socket as tls . TLSSocket ) [ TlsSetupCompleted ] = true ;
286294 } ) ;
287295 } ) ;
288296
@@ -321,8 +329,8 @@ export async function createComboServer(
321329 if ( options . debug ) console . log ( `Proxying HTTP/1 CONNECT to ${ connectUrl } ` ) ;
322330
323331 socket . write ( 'HTTP/' + req . httpVersion + ' 200 OK\r\n\r\n' , 'utf-8' , ( ) => {
324- socket . __timingInfo ! . tunnelSetupTimestamp = now ( ) ;
325- socket . __lastHopConnectAddress = connectUrl ;
332+ socket [ SocketTimingInfo ] ! . tunnelSetupTimestamp = now ( ) ;
333+ socket [ LastTunnelAddress ] = connectUrl ;
326334 server . emit ( 'connection' , socket ) ;
327335 } ) ;
328336 }
@@ -343,7 +351,7 @@ export async function createComboServer(
343351 res . writeHead ( 200 , { } ) ;
344352 copyAddressDetails ( res . socket , res . stream ) ;
345353 copyTimingDetails ( res . socket , res . stream ) ;
346- res . stream . __lastHopConnectAddress = connectUrl ;
354+ res . stream [ LastTunnelAddress ] = connectUrl ;
347355
348356 // When layering HTTP/2 on JS streams, we have to make sure the JS stream won't autoclose
349357 // when the other side does, because the upper HTTP/2 layers want to handle shutdown, so
@@ -359,15 +367,13 @@ export async function createComboServer(
359367 return makeDestroyable ( server ) ;
360368}
361369
362- type SocketIsh < MinProps extends keyof net . Socket > =
363- streams . Duplex & Partial < Pick < net . Socket , MinProps > > ;
364370
365371const SOCKET_ADDRESS_METADATA_FIELDS = [
366372 'localAddress' ,
367373 'localPort' ,
368374 'remoteAddress' ,
369375 'remotePort' ,
370- '__lastHopConnectAddress'
376+ LastTunnelAddress
371377] as const ;
372378
373379// Update the target socket(-ish) with the address details from the source socket,
@@ -388,13 +394,13 @@ function copyAddressDetails(
388394 } ) ;
389395}
390396
391- function copyTimingDetails < T extends SocketIsh < '__timingInfo' > > (
392- source : SocketIsh < '__timingInfo' > ,
397+ function copyTimingDetails < T extends SocketIsh < typeof SocketTimingInfo > > (
398+ source : SocketIsh < typeof SocketTimingInfo > ,
393399 target : T
394- ) : asserts target is T & { __timingInfo : Required < net . Socket > [ '__timingInfo' ] } {
395- if ( ! target . __timingInfo ) {
400+ ) : asserts target is T & { [ SocketTimingInfo ] : Required < net . Socket > [ typeof SocketTimingInfo ] } {
401+ if ( ! target [ SocketTimingInfo ] ) {
396402 // Clone timing info, don't copy it - child sockets get their own independent timing stats
397- target . __timingInfo = Object . assign ( { } , source . __timingInfo ) ;
403+ target [ SocketTimingInfo ] = Object . assign ( { } , source [ SocketTimingInfo ] ) ;
398404 }
399405}
400406
@@ -427,17 +433,17 @@ function analyzeAndMaybePassThroughTls(
427433 // CONNECT or SOCKS) is even better. Note that this may be a hostname or IPv4/6 address:
428434 let connectHostname : string | undefined ;
429435 let connectPort : string | undefined ;
430- if ( socket . __lastHopConnectAddress ) {
431- const lastColonIndex = socket . __lastHopConnectAddress . lastIndexOf ( ':' ) ;
436+ if ( socket [ LastTunnelAddress ] ) {
437+ const lastColonIndex = socket [ LastTunnelAddress ] . lastIndexOf ( ':' ) ;
432438 if ( lastColonIndex !== - 1 ) {
433- connectHostname = socket . __lastHopConnectAddress . slice ( 0 , lastColonIndex ) ;
434- connectPort = socket . __lastHopConnectAddress . slice ( lastColonIndex + 1 ) ;
439+ connectHostname = socket [ LastTunnelAddress ] . slice ( 0 , lastColonIndex ) ;
440+ connectPort = socket [ LastTunnelAddress ] . slice ( lastColonIndex + 1 ) ;
435441 } else {
436- connectHostname = socket . __lastHopConnectAddress ;
442+ connectHostname = socket [ LastTunnelAddress ] ;
437443 }
438444 }
439445
440- socket . __tlsMetadata = {
446+ socket [ TlsMetadata ] = {
441447 sniHostname,
442448 connectHostname,
443449 connectPort,
0 commit comments