@@ -27,7 +27,7 @@ class ParserDelegate
2727
2828extern "C" {
2929
30- int parseHeaders (char * buffer , int length , ParserDelegate * delegate );
30+ int parseHeaders (int file , ParserDelegate * delegate );
3131
3232
3333#line 74 "http_state.rl"
@@ -40,6 +40,47 @@ static const char _http_simple_actions[] = {
4040 3 , 1 , 4 , 1 , 5 , 1 , 6
4141};
4242
43+ static const char _http_simple_key_offsets [] = {
44+ 0 , 0 , 1 , 8 , 10 , 13 , 17 , 18 ,
45+ 21
46+ };
47+
48+ static const char _http_simple_trans_keys [] = {
49+ 10 , 32 , 45 , 58 , 65 , 90 , 97 , 122 ,
50+ 32 , 58 , 32 , 33 , 126 , 13 , 32 , 33 ,
51+ 126 , 10 , 13 , 32 , 126 , 13 , 45 , 65 ,
52+ 90 , 97 , 122 , 0
53+ };
54+
55+ static const char _http_simple_single_lengths [] = {
56+ 0 , 1 , 3 , 2 , 1 , 2 , 1 , 1 ,
57+ 2
58+ };
59+
60+ static const char _http_simple_range_lengths [] = {
61+ 0 , 0 , 2 , 0 , 1 , 1 , 0 , 1 ,
62+ 2
63+ };
64+
65+ static const char _http_simple_index_offsets [] = {
66+ 0 , 0 , 2 , 8 , 11 , 14 , 18 , 20 ,
67+ 23
68+ };
69+
70+ static const char _http_simple_trans_targs [] = {
71+ 8 , 0 , 3 , 2 , 4 , 2 , 2 , 0 ,
72+ 3 , 4 , 0 , 5 , 7 , 0 , 6 , 5 ,
73+ 7 , 0 , 8 , 0 , 6 , 7 , 0 , 1 ,
74+ 2 , 2 , 2 , 0 , 0
75+ };
76+
77+ static const char _http_simple_trans_actions [] = {
78+ 13 , 0 , 1 , 0 , 1 , 0 , 0 , 0 ,
79+ 0 , 0 , 0 , 5 , 5 , 0 , 3 , 5 ,
80+ 5 , 0 , 11 , 0 , 3 , 0 , 0 , 0 ,
81+ 5 , 5 , 5 , 0 , 0
82+ };
83+
4384static const char _http_simple_to_state_actions [] = {
4485 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
4586 7
@@ -59,7 +100,7 @@ static const int http_simple_en_main = 8;
59100
60101#line 77 "http_state.rl"
61102
62- int parseHeaders (char * buffer , int length , ParserDelegate * delegate )
103+ int parseHeaders (int file , ParserDelegate * delegate )
63104{
64105 // machine state
65106 int cs , act , done = 0 ;
@@ -69,7 +110,7 @@ int parseHeaders(char *buffer, int length, ParserDelegate *delegate)
69110 char * myTs ;
70111
71112
72- #line 73 "http_state.c"
113+ #line 114 "http_state.c"
73114 {
74115 cs = http_simple_start ;
75116 ts = 0 ;
@@ -79,14 +120,26 @@ int parseHeaders(char *buffer, int length, ParserDelegate *delegate)
79120
80121#line 88 "http_state.rl"
81122
123+ #define READ_CHUNK_SIZE 2
124+ int bufferSize = READ_CHUNK_SIZE ;
125+ char * buffer = (char * )calloc (bufferSize + 1 , 1 );
126+ char * p = buffer ;
82127 while (!done ) {
83- char * p = buffer , * pe = (buffer + length );
128+ ssize_t readBytes = read (file , p , READ_CHUNK_SIZE );
129+ if (readBytes <= 0 ) {
130+ printf ("EOF!?\n" );
131+ return -1 ;
132+ }
133+ char * pe = (p + readBytes );
84134
85135
86- #line 87 "http_state.c"
136+ #line 137 "http_state.c"
87137 {
138+ int _klen ;
139+ unsigned int _trans ;
88140 const char * _acts ;
89141 unsigned int _nacts ;
142+ const char * _keys ;
90143
91144 if ( p == pe )
92145 goto _test_eof ;
@@ -101,97 +154,70 @@ int parseHeaders(char *buffer, int length, ParserDelegate *delegate)
101154#line 1 "NONE"
102155 {ts = p ;}
103156 break ;
104- #line 105 "http_state.c"
157+ #line 158 "http_state.c"
105158 }
106159 }
107160
108- switch ( cs ) {
109- case 8 :
110- switch ( (* p ) ) {
111- case 13 : goto tr12 ;
112- case 45 : goto tr13 ;
113- }
114- if ( (* p ) > 90 ) {
115- if ( 97 <= (* p ) && (* p ) <= 122 )
116- goto tr13 ;
117- } else if ( (* p ) >= 65 )
118- goto tr13 ;
119- goto tr1 ;
120- case 0 :
121- goto _out ;
122- case 1 :
123- if ( (* p ) == 10 )
124- goto tr0 ;
125- goto tr1 ;
126- case 2 :
127- switch ( (* p ) ) {
128- case 32 : goto tr2 ;
129- case 45 : goto tr3 ;
130- case 58 : goto tr4 ;
131- }
132- if ( (* p ) > 90 ) {
133- if ( 97 <= (* p ) && (* p ) <= 122 )
134- goto tr3 ;
135- } else if ( (* p ) >= 65 )
136- goto tr3 ;
137- goto tr1 ;
138- case 3 :
139- switch ( (* p ) ) {
140- case 32 : goto tr5 ;
141- case 58 : goto tr6 ;
142- }
143- goto tr1 ;
144- case 4 :
145- if ( (* p ) == 32 )
146- goto tr7 ;
147- if ( 33 <= (* p ) && (* p ) <= 126 )
148- goto tr8 ;
149- goto tr1 ;
150- case 5 :
151- switch ( (* p ) ) {
152- case 13 : goto tr9 ;
153- case 32 : goto tr7 ;
161+ _keys = _http_simple_trans_keys + _http_simple_key_offsets [cs ];
162+ _trans = _http_simple_index_offsets [cs ];
163+
164+ _klen = _http_simple_single_lengths [cs ];
165+ if ( _klen > 0 ) {
166+ const char * _lower = _keys ;
167+ const char * _mid ;
168+ const char * _upper = _keys + _klen - 1 ;
169+ while (1 ) {
170+ if ( _upper < _lower )
171+ break ;
172+
173+ _mid = _lower + ((_upper - _lower ) >> 1 );
174+ if ( (* p ) < * _mid )
175+ _upper = _mid - 1 ;
176+ else if ( (* p ) > * _mid )
177+ _lower = _mid + 1 ;
178+ else {
179+ _trans += (unsigned int )(_mid - _keys );
180+ goto _match ;
181+ }
182+ }
183+ _keys += _klen ;
184+ _trans += _klen ;
154185 }
155- if ( 33 <= (* p ) && (* p ) <= 126 )
156- goto tr8 ;
157- goto tr1 ;
158- case 6 :
159- if ( (* p ) == 10 )
160- goto tr10 ;
161- goto tr1 ;
162- case 7 :
163- if ( (* p ) == 13 )
164- goto tr9 ;
165- if ( 32 <= (* p ) && (* p ) <= 126 )
166- goto tr11 ;
167- goto tr1 ;
186+
187+ _klen = _http_simple_range_lengths [cs ];
188+ if ( _klen > 0 ) {
189+ const char * _lower = _keys ;
190+ const char * _mid ;
191+ const char * _upper = _keys + (_klen <<1 ) - 2 ;
192+ while (1 ) {
193+ if ( _upper < _lower )
194+ break ;
195+
196+ _mid = _lower + (((_upper - _lower ) >> 1 ) & ~1 );
197+ if ( (* p ) < _mid [0 ] )
198+ _upper = _mid - 2 ;
199+ else if ( (* p ) > _mid [1 ] )
200+ _lower = _mid + 2 ;
201+ else {
202+ _trans += (unsigned int )((_mid - _keys )>>1 );
203+ goto _match ;
204+ }
205+ }
206+ _trans += _klen ;
168207 }
169208
170- tr1 : cs = 0 ; goto _again ;
171- tr12 : cs = 1 ; goto _again ;
172- tr3 : cs = 2 ; goto _again ;
173- tr13 : cs = 2 ; goto f2 ;
174- tr5 : cs = 3 ; goto _again ;
175- tr2 : cs = 3 ; goto f1 ;
176- tr6 : cs = 4 ; goto _again ;
177- tr4 : cs = 4 ; goto f1 ;
178- tr7 : cs = 5 ; goto f2 ;
179- tr9 : cs = 6 ; goto f3 ;
180- tr11 : cs = 7 ; goto _again ;
181- tr8 : cs = 7 ; goto f2 ;
182- tr0 : cs = 8 ; goto f0 ;
183- tr10 : cs = 8 ; goto f4 ;
184-
185- f1 : _acts = _http_simple_actions + 1 ; goto execFuncs ;
186- f3 : _acts = _http_simple_actions + 3 ; goto execFuncs ;
187- f2 : _acts = _http_simple_actions + 5 ; goto execFuncs ;
188- f4 : _acts = _http_simple_actions + 11 ; goto execFuncs ;
189- f0 : _acts = _http_simple_actions + 13 ; goto execFuncs ;
190-
191- execFuncs :
192- _nacts = * _acts ++ ;
193- while ( _nacts -- > 0 ) {
194- switch ( * _acts ++ ) {
209+ _match :
210+ cs = _http_simple_trans_targs [_trans ];
211+
212+ if ( _http_simple_trans_actions [_trans ] == 0 )
213+ goto _again ;
214+
215+ _acts = _http_simple_actions + _http_simple_trans_actions [_trans ];
216+ _nacts = (unsigned int ) * _acts ++ ;
217+ while ( _nacts -- > 0 )
218+ {
219+ switch ( * _acts ++ )
220+ {
195221 case 0 :
196222#line 33 "http_state.rl"
197223 {
@@ -232,10 +258,9 @@ case 7:
232258 {p ++ ; goto _out ; }
233259 }}
234260 break ;
235- #line 236 "http_state.c"
261+ #line 262 "http_state.c"
236262 }
237263 }
238- goto _again ;
239264
240265_again :
241266 _acts = _http_simple_actions + _http_simple_to_state_actions [cs ];
@@ -246,7 +271,7 @@ case 7:
246271#line 1 "NONE"
247272 {ts = 0 ;}
248273 break ;
249- #line 250 "http_state.c"
274+ #line 275 "http_state.c"
250275 }
251276 }
252277
@@ -258,21 +283,29 @@ case 7:
258283 _out : {}
259284 }
260285
261- #line 93 "http_state.rl"
286+ #line 102 "http_state.rl"
262287
263288 if (cs == http_simple_error ) {
264- printf ("error state\n" );
265- return -1 ;
289+ printf ("error parsing\n" );
266290 }
267- if (!done && p == pe ) {
268- // EOF
269- printf ("EOF??" );
270- return -1 ;
291+ if (!done ) {
292+ bufferSize *= 2 ;
293+ char * newBuffer = (char * )realloc (buffer , bufferSize + 1 );
294+ if (!newBuffer ) {
295+ free (buffer );
296+ printf ("OUT OF MEMORY\n" );
297+ return 0 ;
298+ }
299+ if (newBuffer != buffer ) {
300+ myTs = newBuffer + (myTs - buffer );
301+ p = newBuffer + (p - buffer );
302+ buffer = newBuffer ;
303+ }
271304 }
272-
273305 }
306+ free (buffer );
274307 // return how many bytes we actually parsed
275- return (te - buffer );
308+ return (p - buffer );
276309}
277310
278311#ifdef DEBUG_HTTP
@@ -292,11 +325,14 @@ class SomeDelegate : public ParserDelegate
292325
293326int main (int argc , char * * argv ) {
294327 if (argc > 0 ) {
295- char * buff = (char * )malloc (2048 );
328+ char * buff = (char * )calloc (2048 , 1 );
296329 SomeDelegate * delegate = new SomeDelegate ();
297330 int f = open (argv [1 ], O_RDONLY );
298- int readBytes = read (f , buff , 2048 );
299- parseHeaders (buff , readBytes , delegate );
331+ int parsedBytes = parseHeaders (f , delegate );
332+ if (parsedBytes > 0 ) {
333+ read (f , buff , 2048 );
334+ printf ("body:\n%s" , buff );
335+ }
300336 close (f );
301337 free (buff );
302338 delete delegate ;
0 commit comments