@@ -69,9 +69,9 @@ function lazyllhttp () {
6969 let useWasmSIMD = process . arch !== 'ppc64'
7070 // The Env Variable UNDICI_NO_WASM_SIMD allows explicitly overriding the default behavior
7171 if ( process . env . UNDICI_NO_WASM_SIMD === '1' ) {
72- useWasmSIMD = true
73- } else if ( process . env . UNDICI_NO_WASM_SIMD === '0' ) {
7472 useWasmSIMD = false
73+ } else if ( process . env . UNDICI_NO_WASM_SIMD === '0' ) {
74+ useWasmSIMD = true
7575 }
7676
7777 if ( useWasmSIMD ) {
@@ -216,6 +216,7 @@ class Parser {
216216 */
217217 this . socket = socket
218218 this . timeout = null
219+ this . timeoutWeakRef = new WeakRef ( this )
219220 this . timeoutValue = null
220221 this . timeoutType = null
221222 this . statusCode = 0
@@ -253,9 +254,9 @@ class Parser {
253254
254255 if ( delay ) {
255256 if ( type & USE_FAST_TIMER ) {
256- this . timeout = timers . setFastTimeout ( onParserTimeout , delay , new WeakRef ( this ) )
257+ this . timeout = timers . setFastTimeout ( onParserTimeout , delay , this . timeoutWeakRef )
257258 } else {
258- this . timeout = setTimeout ( onParserTimeout , delay , new WeakRef ( this ) )
259+ this . timeout = setTimeout ( onParserTimeout , delay , this . timeoutWeakRef )
259260 this . timeout ?. unref ( )
260261 }
261262 }
@@ -349,23 +350,62 @@ class Parser {
349350 this . paused = true
350351 socket . unshift ( data )
351352 } else {
352- const ptr = llhttp . llhttp_get_error_reason ( this . ptr )
353- let message = ''
354- if ( ptr ) {
355- const len = new Uint8Array ( llhttp . memory . buffer , ptr ) . indexOf ( 0 )
356- message =
357- 'Response does not match the HTTP/1.1 protocol (' +
358- Buffer . from ( llhttp . memory . buffer , ptr , len ) . toString ( ) +
359- ')'
360- }
361- throw new HTTPParserError ( message , constants . ERROR [ ret ] , data )
353+ throw this . createError ( ret , data )
362354 }
363355 }
364356 } catch ( err ) {
365357 util . destroy ( socket , err )
366358 }
367359 }
368360
361+ finish ( ) {
362+ assert ( currentParser === null )
363+ assert ( this . ptr != null )
364+ assert ( ! this . paused )
365+
366+ const { llhttp } = this
367+
368+ let ret
369+
370+ try {
371+ currentParser = this
372+ ret = llhttp . llhttp_finish ( this . ptr )
373+ } finally {
374+ currentParser = null
375+ }
376+
377+ if ( ret === constants . ERROR . OK ) {
378+ return null
379+ }
380+
381+ if ( ret === constants . ERROR . PAUSED || ret === constants . ERROR . PAUSED_UPGRADE ) {
382+ this . paused = true
383+ return null
384+ }
385+
386+ return this . createError ( ret , EMPTY_BUF )
387+ }
388+
389+ createError ( ret , data ) {
390+ const { llhttp, contentLength, bytesRead } = this
391+
392+ if ( contentLength && bytesRead !== parseInt ( contentLength , 10 ) ) {
393+ return new ResponseContentLengthMismatchError ( )
394+ }
395+
396+ const ptr = llhttp . llhttp_get_error_reason ( this . ptr )
397+ let message = ''
398+ if ( ptr ) {
399+ const len = new Uint8Array ( llhttp . memory . buffer , ptr ) . indexOf ( 0 )
400+ message =
401+ 'Response does not match the HTTP/1.1 protocol (' +
402+ Buffer . from ( llhttp . memory . buffer , ptr , len ) . toString ( ) +
403+ ')'
404+ }
405+
406+ return new HTTPParserError ( message , constants . ERROR [ ret ] , data )
407+ }
408+
369409 destroy ( ) {
370410 assert ( currentParser === null )
371411 assert ( this . ptr != null )
@@ -870,8 +910,11 @@ function onHttpSocketError (err) {
870910 // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded
871911 // to the user.
872912 if ( err . code === 'ECONNRESET' && parser . statusCode && ! parser . shouldKeepAlive ) {
873- // We treat all incoming data so for as a valid response.
874- parser . onMessageComplete ( )
913+ const parserErr = parser . finish ( )
914+ if ( parserErr ) {
915+ this [ kError ] = parserErr
916+ this [ kClient ] [ kOnError ] ( parserErr )
917+ }
875918 return
876919 }
877920
@@ -888,8 +931,10 @@ function onHttpSocketEnd () {
888931 const parser = this [ kParser ]
889932
890933 if ( parser . statusCode && ! parser . shouldKeepAlive ) {
891- // We treat all incoming data so far as a valid response.
892- parser . onMessageComplete ( )
934+ const parserErr = parser . finish ( )
935+ if ( parserErr ) {
936+ util . destroy ( this , parserErr )
937+ }
893938 return
894939 }
895940
@@ -901,8 +946,7 @@ function onHttpSocketClose () {
901946
902947 if ( parser ) {
903948 if ( ! this [ kError ] && parser . statusCode && ! parser . shouldKeepAlive ) {
904- // We treat all incoming data so far as a valid response.
905- parser . onMessageComplete ( )
949+ this [ kError ] = parser . finish ( ) || this [ kError ]
906950 }
907951
908952 this [ kParser ] . destroy ( )
0 commit comments