@@ -604,6 +604,47 @@ nodeOnly(() => {
604604 await cleanup ( proxiedClient , client ) ;
605605 } ) ;
606606
607+ it ( "can pass through HTTP/2 with duplicate single-value request headers" , async function ( ) {
608+ if ( ! nodeSatisfies ( ">=25.7.0" ) ) this . skip ( ) ;
609+
610+ await server . forGet ( `https://localhost:${ targetPort } /` )
611+ . thenPassThrough ( { ignoreHostHttpsErrors : [ 'localhost' ] } ) ;
612+
613+ const client = http2 . connect ( server . url ) ;
614+
615+ const req = client . request ( {
616+ ':method' : 'CONNECT' ,
617+ ':authority' : `localhost:${ targetPort } `
618+ } ) ;
619+
620+ // Initial response, the proxy has set up our tunnel:
621+ const responseHeaders = await getHttp2Response ( req ) ;
622+ expect ( responseHeaders [ ':status' ] ) . to . equal ( 200 ) ;
623+
624+ // We can now read/write to req as a raw TCP socket to our target server
625+ const proxiedClient = http2 . connect ( `https://localhost:${ targetPort } ` , {
626+ // Tunnel this request through the proxy stream
627+ createConnection : ( ) => tls . connect ( {
628+ socket : req as any ,
629+ ALPNProtocols : [ 'h2' ]
630+ } ) ,
631+ // Allow the test client to send duplicate single-value headers:
632+ strictSingleValueFields : false
633+ } as any ) ;
634+
635+ const proxiedRequest = proxiedClient . request ( {
636+ ':path' : '/' ,
637+ 'user-agent' : [ 'agent-1' , 'agent-2' ] as any
638+ } ) ;
639+ const proxiedResponse = await getHttp2Response ( proxiedRequest ) ;
640+ expect ( proxiedResponse [ ':status' ] ) . to . equal ( 200 ) ;
641+
642+ const responseBody = await getHttp2Body ( proxiedRequest ) ;
643+ expect ( responseBody . toString ( 'utf8' ) ) . to . equal ( "Real HTTP/2 response" ) ;
644+
645+ await cleanup ( proxiedClient , client ) ;
646+ } ) ;
647+
607648 } ) ;
608649
609650 } ) ;
0 commit comments