11import * as _ from 'lodash' ;
22import HttpsProxyAgent = require( 'https-proxy-agent' ) ;
3- import * as semver from 'semver' ;
43
54import {
65 getLocal ,
@@ -16,7 +15,6 @@ import {
1615 delay ,
1716 openRawSocket ,
1817 openRawTlsSocket ,
19- writeAndReset ,
2018 watchForEvent ,
2119 http2DirectRequest
2220} from "../../test-utils" ;
@@ -149,41 +147,63 @@ describe("TLS error subscriptions", () => {
149147 await expectNoClientErrors ( ) ;
150148 } ) ;
151149
152- it ( "should not be sent for requests from TLS clients that reset later in the connection" , async function ( ) {
153- this . retries ( 3 ) ; // Can be slightly unstable, due to the race for RESET
150+ it ( "should be sent for requests from TLS clients that reset directly after handshake" , async function ( ) {
151+ const events : any [ ] = [ ] ;
152+ await goodServer . on ( 'tls-client-error' , ( ) => events . push ( 'tls-client-error' ) ) ;
153+ await goodServer . on ( 'client-error' , ( ) => events . push ( 'client-error' ) ) ;
154+
155+ const tcpSocket = await openRawSocket ( goodServer )
156+ await openRawTlsSocket ( tcpSocket ) ;
157+ tcpSocket . resetAndDestroy ( ) ;
158+
159+ await delay ( 50 ) ;
154160
161+ // We see a TLS error (reset like this is a common form of cert rejection) but no client error
162+ // (no HTTP request has even been attempted):
163+ expect ( events ) . to . deep . equal ( [ 'tls-client-error' ] ) ;
164+ } ) ;
165+
166+ it ( "should not be sent for requests from TLS clients that reset later in the connection" , async function ( ) {
155167 let seenTlsErrorPromise = getDeferred < TlsHandshakeFailure > ( ) ;
156168 await goodServer . on ( 'tls-client-error' , ( r ) => seenTlsErrorPromise . resolve ( r ) ) ;
157169
158170 let seenClientErrorPromise = getDeferred < ClientError > ( ) ;
159171 await goodServer . on ( 'client-error' , ( e ) => seenClientErrorPromise . resolve ( e ) ) ;
160172
161- const tlsSocket = await openRawTlsSocket ( goodServer ) ;
162- writeAndReset ( tlsSocket , "GET / HTTP/1.1\r\n\r\n" ) ;
173+ const tcpSocket = await openRawSocket ( goodServer )
174+ const tlsSocket = await openRawTlsSocket ( tcpSocket ) ;
175+ tlsSocket . write ( "GET / HTTP/1.1\r\nHost: hello.world.invalid\r\n" ) ; // Incomplete HTTP request
176+
177+ // Kill the underlying socket before the request head completes (but after some content is sent):
178+ setTimeout ( ( ) => {
179+ tcpSocket . resetAndDestroy ( )
180+ } , 10 ) ;
163181
164182 const seenTlsError = await Promise . race ( [
165- delay ( 100 ) . then ( ( ) => false ) ,
183+ delay ( 50 ) . then ( ( ) => false ) ,
166184 seenTlsErrorPromise
167185 ] ) ;
168- expect ( seenTlsError ) . to . equal ( false ) ;
186+
169187
170188 // No TLS error, but we do expect a client reset error:
189+ expect ( seenTlsError ) . to . equal ( false ) ;
171190 expect ( ( await seenClientErrorPromise ) . errorCode ) . to . equal ( 'ECONNRESET' ) ;
172191 } ) ;
173192
174193 it ( "should not be sent for requests from non-TLS clients that reset before sending anything" , async ( ) => {
175194 let seenTlsErrorPromise = getDeferred < TlsHandshakeFailure > ( ) ;
176195 await goodServer . on ( 'tls-client-error' , ( r ) => seenTlsErrorPromise . resolve ( r ) ) ;
177196
178- const tlsSocket = await openRawSocket ( goodServer ) ;
179- writeAndReset ( tlsSocket , "" ) ; // Send nothing, just connect & RESET
197+ const rawSocket = await openRawSocket ( goodServer ) ;
198+ rawSocket . resetAndDestroy ( ) ; // Immediate reset without sending any data
180199
181200 const seenTlsError = await Promise . race ( [
182- delay ( 100 ) . then ( ( ) => false ) ,
201+ delay ( 50 ) . then ( ( ) => false ) ,
183202 seenTlsErrorPromise
184203 ] ) ;
185- expect ( seenTlsError ) . to . equal ( false ) ;
186204
205+ // No TLS error, no client reset error:
206+ expect ( seenTlsError ) . to . equal ( false ) ;
187207 await expectNoClientErrors ( ) ;
188208 } ) ;
189209 } ) ;
0 commit comments