@@ -11,8 +11,8 @@ import {
1111 HTTPMode ,
1212 LENIENT_FLAGS ,
1313 MAJOR , METHOD_MAP , METHODS , METHODS_HTTP , METHODS_ICE , METHODS_RTSP ,
14- MINOR , NUM_MAP , SPECIAL_HEADERS , STRICT_TOKEN ,
15- TOKEN , TYPE ,
14+ MINOR , NUM_MAP , QUOTED_STRING , SPECIAL_HEADERS ,
15+ STRICT_TOKEN , TOKEN , TYPE ,
1616} from './constants' ;
1717import { URL } from './url' ;
1818
@@ -88,7 +88,11 @@ const NODES: ReadonlyArray<string> = [
8888 'chunk_size_otherwise' ,
8989 'chunk_size_almost_done' ,
9090 'chunk_size_almost_done_lf' ,
91- 'chunk_parameters' ,
91+ 'chunk_extensions' ,
92+ 'chunk_extension_name' ,
93+ 'chunk_extension_value' ,
94+ 'chunk_extension_quoted_value' ,
95+ 'chunk_extension_quoted_value_done' ,
9296 'chunk_data' ,
9397 'chunk_data_almost_done' ,
9498 'chunk_data_almost_done_skip' ,
@@ -105,29 +109,33 @@ const NODES: ReadonlyArray<string> = [
105109] ;
106110
107111interface ISpanMap {
108- readonly body : source . Span ;
109- readonly headerField : source . Span ;
110- readonly headerValue : source . Span ;
111112 readonly status : source . Span ;
112113 readonly method : source . Span ;
113114 readonly version : source . Span ;
115+ readonly headerField : source . Span ;
116+ readonly headerValue : source . Span ;
117+ readonly chunkExtensionName : source . Span ;
118+ readonly chunkExtensionValue : source . Span ;
119+ readonly body : source . Span ;
114120}
115121
116122interface ICallbackMap {
117- readonly afterHeadersComplete : source . code . Code ;
118- readonly afterMessageComplete : source . code . Code ;
119- readonly beforeHeadersComplete : source . code . Code ;
120- readonly onChunkComplete : source . code . Code ;
121- readonly onChunkHeader : source . code . Code ;
122- readonly onHeadersComplete : source . code . Code ;
123123 readonly onMessageBegin : source . code . Code ;
124- readonly onMessageComplete : source . code . Code ;
125124 readonly onUrlComplete : source . code . Code ;
126125 readonly onMethodComplete : source . code . Code ;
127126 readonly onVersionComplete : source . code . Code ;
128127 readonly onStatusComplete : source . code . Code ;
128+ readonly beforeHeadersComplete : source . code . Code ;
129129 readonly onHeaderFieldComplete : source . code . Code ;
130130 readonly onHeaderValueComplete : source . code . Code ;
131+ readonly onHeadersComplete : source . code . Code ;
132+ readonly afterHeadersComplete : source . code . Code ;
133+ readonly onChunkHeader : source . code . Code ;
134+ readonly onChunkExtensionName : source . code . Code ;
135+ readonly onChunkExtensionValue : source . code . Code ;
136+ readonly onChunkComplete : source . code . Code ;
137+ readonly onMessageComplete : source . code . Code ;
138+ readonly afterMessageComplete : source . code . Code ;
131139 readonly onReset : source . code . Code ;
132140}
133141
@@ -167,6 +175,8 @@ export class HTTP {
167175
168176 this . span = {
169177 body : p . span ( p . code . span ( 'llhttp__on_body' ) ) ,
178+ chunkExtensionName : p . span ( p . code . span ( 'llhttp__on_chunk_extension_name' ) ) ,
179+ chunkExtensionValue : p . span ( p . code . span ( 'llhttp__on_chunk_extension_value' ) ) ,
170180 headerField : p . span ( p . code . span ( 'llhttp__on_header_field' ) ) ,
171181 headerValue : p . span ( p . code . span ( 'llhttp__on_header_value' ) ) ,
172182 method : p . span ( p . code . span ( 'llhttp__on_method' ) ) ,
@@ -187,6 +197,8 @@ export class HTTP {
187197 onMessageBegin : p . code . match ( 'llhttp__on_message_begin' ) ,
188198 onMessageComplete : p . code . match ( 'llhttp__on_message_complete' ) ,
189199 onChunkHeader : p . code . match ( 'llhttp__on_chunk_header' ) ,
200+ onChunkExtensionName : p . code . match ( 'llhttp__on_chunk_extension_name_complete' ) ,
201+ onChunkExtensionValue : p . code . match ( 'llhttp__on_chunk_extension_value_complete' ) ,
190202 onChunkComplete : p . code . match ( 'llhttp__on_chunk_complete' ) ,
191203 onReset : p . code . match ( 'llhttp__on_reset' ) ,
192204
@@ -855,15 +867,69 @@ export class HTTP {
855867
856868 n ( 'chunk_size_otherwise' )
857869 . match ( '\r' , n ( 'chunk_size_almost_done' ) )
858- . match ( '; ' , n ( 'chunk_parameters ' ) )
870+ . match ( ';' , n ( 'chunk_extensions ' ) )
859871 . otherwise ( p . error ( ERROR . INVALID_CHUNK_SIZE ,
860872 'Invalid character in chunk size' ) ) ;
861873
862- n ( 'chunk_parameters' )
874+ const onChunkExtensionNameCompleted = ( destination : Node ) => {
875+ return this . invokePausable (
876+ 'on_chunk_extension_name' , ERROR . CB_CHUNK_EXTENSION_NAME_COMPLETE , destination ) ;
877+ } ;
878+
879+ const onChunkExtensionValueCompleted = ( destination : Node ) => {
880+ return this . invokePausable (
881+ 'on_chunk_extension_value' , ERROR . CB_CHUNK_EXTENSION_VALUE_COMPLETE , destination ) ;
882+ } ;
883+
884+ n ( 'chunk_extensions' )
885+ . match ( ' ' , p . error ( ERROR . STRICT , 'Invalid character in chunk extensions' ) )
886+ . match ( '\r' , p . error ( ERROR . STRICT , 'Invalid character in chunk extensions' ) )
887+ . otherwise ( this . span . chunkExtensionName . start ( n ( 'chunk_extension_name' ) ) ) ;
888+
889+ n ( 'chunk_extension_name' )
890+ . match ( STRICT_TOKEN , n ( 'chunk_extension_name' ) )
891+ . peek ( '=' , this . span . chunkExtensionName . end ( ) . skipTo (
892+ this . span . chunkExtensionValue . start (
893+ onChunkExtensionNameCompleted ( n ( 'chunk_extension_value' ) ) ,
894+ ) ,
895+ ) )
896+ . peek ( ';' , this . span . chunkExtensionName . end ( ) . skipTo (
897+ onChunkExtensionNameCompleted ( n ( 'chunk_extensions' ) ) ,
898+ ) )
899+ . peek ( '\r' , this . span . chunkExtensionName . end ( ) . skipTo (
900+ onChunkExtensionNameCompleted ( n ( 'chunk_size_almost_done' ) ) ,
901+ ) )
902+ . otherwise ( this . span . chunkExtensionName . end ( ) . skipTo (
903+ p . error ( ERROR . STRICT , 'Invalid character in chunk extensions name' ) ,
904+ ) ) ;
905+
906+ n ( 'chunk_extension_value' )
907+ . match ( '"' , n ( 'chunk_extension_quoted_value' ) )
908+ . match ( STRICT_TOKEN , n ( 'chunk_extension_value' ) )
909+ . peek ( ';' , this . span . chunkExtensionValue . end ( ) . skipTo (
910+ onChunkExtensionValueCompleted ( n ( 'chunk_size_otherwise' ) ) ,
911+ ) )
912+ . peek ( '\r' , this . span . chunkExtensionValue . end ( ) . skipTo (
913+ onChunkExtensionValueCompleted ( n ( 'chunk_size_almost_done' ) ) ,
914+ ) )
915+ . otherwise ( this . span . chunkExtensionValue . end ( ) . skipTo (
916+ p . error ( ERROR . STRICT , 'Invalid character in chunk extensions value' ) ,
917+ ) ) ;
918+
919+ n ( 'chunk_extension_quoted_value' )
920+ . match ( QUOTED_STRING , n ( 'chunk_extension_quoted_value' ) )
921+ . match ( '"' , this . span . chunkExtensionValue . end (
922+ onChunkExtensionValueCompleted ( n ( 'chunk_extension_quoted_value_done' ) ) ,
923+ ) )
924+ . otherwise ( this . span . chunkExtensionValue . end ( ) . skipTo (
925+ p . error ( ERROR . STRICT , 'Invalid character in chunk extensions quoted value' ) ,
926+ ) ) ;
927+
928+ n ( 'chunk_extension_quoted_value_done' )
929+ . match ( ';' , n ( 'chunk_extensions' ) )
863930 . match ( '\r' , n ( 'chunk_size_almost_done' ) )
864- . match ( HEADER_CHARS , n ( 'chunk_parameters' ) )
865931 . otherwise ( p . error ( ERROR . STRICT ,
866- 'Invalid character in chunk parameters ' ) ) ;
932+ 'Invalid character in chunk extensions quote value ' ) ) ;
867933
868934 if ( this . mode === 'strict' ) {
869935 n ( 'chunk_size_almost_done' )
@@ -1094,6 +1160,12 @@ export class HTTP {
10941160 case 'on_chunk_header' :
10951161 cb = this . callback . onChunkHeader ;
10961162 break ;
1163+ case 'on_chunk_extension_name' :
1164+ cb = this . callback . onChunkExtensionName ;
1165+ break ;
1166+ case 'on_chunk_extension_value' :
1167+ cb = this . callback . onChunkExtensionValue ;
1168+ break ;
10971169 case 'on_chunk_complete' :
10981170 cb = this . callback . onChunkComplete ;
10991171 break ;
0 commit comments