@@ -279,29 +279,71 @@ class Parser {
279279
280280 const offset = llhttp . llhttp_get_error_pos ( this . ptr ) - currentBufferPtr
281281
282- if ( ret === constants . ERROR . PAUSED_UPGRADE ) {
283- this . onUpgrade ( data . slice ( offset ) )
284- } else if ( ret === constants . ERROR . PAUSED ) {
285- this . paused = true
286- socket . unshift ( data . slice ( offset ) )
287- } else if ( ret !== constants . ERROR . OK ) {
288- const ptr = llhttp . llhttp_get_error_reason ( this . ptr )
289- let message = ''
290- /* istanbul ignore else: difficult to make a test case for */
291- if ( ptr ) {
292- const len = new Uint8Array ( llhttp . memory . buffer , ptr ) . indexOf ( 0 )
293- message =
294- 'Response does not match the HTTP/1.1 protocol (' +
295- Buffer . from ( llhttp . memory . buffer , ptr , len ) . toString ( ) +
296- ')'
282+ if ( ret !== constants . ERROR . OK ) {
283+ const body = data . subarray ( offset )
284+
285+ if ( ret === constants . ERROR . PAUSED_UPGRADE ) {
286+ this . onUpgrade ( body )
287+ } else if ( ret === constants . ERROR . PAUSED ) {
288+ this . paused = true
289+ socket . unshift ( body )
290+ } else {
291+ throw this . createError ( ret , body )
297292 }
298- throw new HTTPParserError ( message , constants . ERROR [ ret ] , data . slice ( offset ) )
299293 }
300294 } catch ( err ) {
301295 util . destroy ( socket , err )
302296 }
303297 }
304298
299+ finish ( ) {
300+ assert ( currentParser === null )
301+ assert ( this . ptr != null )
302+ assert ( ! this . paused )
303+
304+ const { llhttp } = this
305+
306+ let ret
307+
308+ try {
309+ currentParser = this
310+ ret = llhttp . llhttp_finish ( this . ptr )
311+ } finally {
312+ currentParser = null
313+ }
314+
315+ if ( ret === constants . ERROR . OK ) {
316+ return null
317+ }
318+
319+ if ( ret === constants . ERROR . PAUSED || ret === constants . ERROR . PAUSED_UPGRADE ) {
320+ this . paused = true
321+ return null
322+ }
323+
324+ return this . createError ( ret , EMPTY_BUF )
325+ }
326+
327+ createError ( ret , data ) {
328+ const { llhttp, contentLength, bytesRead } = this
329+
330+ if ( contentLength && bytesRead !== parseInt ( contentLength , 10 ) ) {
331+ return new ResponseContentLengthMismatchError ( )
332+ }
333+
334+ const ptr = llhttp . llhttp_get_error_reason ( this . ptr )
335+ let message = ''
336+ if ( ptr ) {
337+ const len = new Uint8Array ( llhttp . memory . buffer , ptr ) . indexOf ( 0 )
338+ message =
339+ 'Response does not match the HTTP/1.1 protocol (' +
340+ Buffer . from ( llhttp . memory . buffer , ptr , len ) . toString ( ) +
341+ ')'
342+ }
343+
344+ return new HTTPParserError ( message , constants . ERROR [ ret ] , data )
345+ }
346+
305347 destroy ( ) {
306348 assert ( this . ptr != null )
307349 assert ( currentParser == null )
@@ -673,8 +715,11 @@ async function connectH1 (client, socket) {
673715 // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
674716 // to the user.
675717 if ( err . code === 'ECONNRESET' && parser . statusCode && ! parser . shouldKeepAlive ) {
676- // We treat all incoming data so for as a valid response.
677- parser . onMessageComplete ( )
718+ const parserErr = parser . finish ( )
719+ if ( parserErr ) {
720+ this [ kError ] = parserErr
721+ this [ kClient ] [ kOnError ] ( parserErr )
722+ }
678723 return
679724 }
680725
@@ -693,8 +738,10 @@ async function connectH1 (client, socket) {
693738 const parser = this [ kParser ]
694739
695740 if ( parser . statusCode && ! parser . shouldKeepAlive ) {
696- // We treat all incoming data so far as a valid response.
697- parser . onMessageComplete ( )
741+ const parserErr = parser . finish ( )
742+ if ( parserErr ) {
743+ util . destroy ( this , parserErr )
744+ }
698745 return
699746 }
700747
@@ -706,8 +753,7 @@ async function connectH1 (client, socket) {
706753
707754 if ( parser ) {
708755 if ( ! this [ kError ] && parser . statusCode && ! parser . shouldKeepAlive ) {
709- // We treat all incoming data so far as a valid response.
710- parser . onMessageComplete ( )
756+ this [ kError ] = parser . finish ( ) || this [ kError ]
711757 }
712758
713759 this [ kParser ] . destroy ( )
0 commit comments