31 #include "volta.h" |
31 #include "volta.h" |
32 |
32 |
33 #define MARK_S( LBL ) p_parsed->tokens.LBL ## _start = p; |
33 #define MARK_S( LBL ) p_parsed->tokens.LBL ## _start = p; |
34 #define MARK_E( LBL ) p_parsed->tokens.LBL ## _length = p - ( *pe + p_parsed->tokens.LBL ## _start ); |
34 #define MARK_E( LBL ) p_parsed->tokens.LBL ## _length = p - ( *pe + p_parsed->tokens.LBL ## _start ); |
35 |
35 |
|
36 #define COPY_STR( LBL ) copy_string_token( p_parsed->tokens.LBL ## _start, p_parsed->tokens.LBL ## _length ) |
|
37 /* #define COPY_IP4( LBL ) copy_ipv4_token( p_request->tokens.LBL ## _start, p_request->tokens.LBL ## _length ) */ |
|
38 |
36 /* |
39 /* |
37 * Tokenize an incoming line from squid, returning a parsed and populated |
40 * Tokenize an incoming line from squid, returning a parsed and populated |
38 * structure to make redirection decisions against. This pointer should |
41 * structure to make redirection decisions against. This pointer should |
39 * be freed using finish_parsed() after use. |
42 * be freed using finish_parsed() after use. |
40 * |
43 * |
77 p_parsed->type = REQUEST; |
80 p_parsed->type = REQUEST; |
78 |
81 |
79 %%{ |
82 %%{ |
80 machine request_parser; |
83 machine request_parser; |
81 |
84 |
82 action channel_id_found { |
85 action chid_start { MARK_S(chid) } |
83 debug( 1, LOC, "Channel ID found in redirector input. Set 'url_rewrite_concurrency' to '0' in squid.\n" ); |
86 action chid_finish { MARK_E(chid) } |
84 fbreak; |
|
85 } |
|
86 |
|
87 action scheme_start { MARK_S(scheme) } |
87 action scheme_start { MARK_S(scheme) } |
88 action scheme_finish { MARK_E(scheme) } |
88 action scheme_finish { MARK_E(scheme) } |
89 action host_start { MARK_S(host) } |
89 action host_start { MARK_S(host) } |
90 action host_finish { MARK_E(host) } |
90 action host_finish { MARK_E(host) } |
91 action port_start { p_parsed->tokens.port_start = p+1; } # strip leading colon |
91 action port_start { p_parsed->tokens.port_start = p+1; } # strip leading colon |
139 |
139 |
140 hostname = host_component ( '.' host_component )* '.'?; |
140 hostname = host_component ( '.' host_component )* '.'?; |
141 ipv4 = digit{1,3} '.' digit{1,3} '.' digit{1,3} '.' digit{1,3}; |
141 ipv4 = digit{1,3} '.' digit{1,3} '.' digit{1,3} '.' digit{1,3}; |
142 ipv6 = ( xdigit | ':' )+; |
142 ipv6 = ( xdigit | ':' )+; |
143 |
143 |
144 channel_id = ( digit+ space ) %channel_id_found; |
144 channel_id = ( digit+ space ) >chid_start %chid_finish; |
145 scheme = ( alpha{3,5} '://' ) >scheme_start %scheme_finish @!scheme_error; |
145 scheme = ( alpha{3,5} '://' ) >scheme_start %scheme_finish @!scheme_error; |
146 host = ( hostname | ipv4 ) >host_start %host_finish @!host_error; |
146 host = ( hostname | ipv4 ) >host_start %host_finish @!host_error; |
147 port = ( ':' digit{1,5} ) >port_start %port_finish; |
147 port = ( ':' digit{1,5} ) >port_start %port_finish; |
148 path = path_segment* >path_start %path_finish; |
148 path = path_segment* >path_start %path_finish; |
149 client_ip = ipv4 >c_ip_start %c_ip_finish @!c_ip_error; |
149 client_ip = ipv4 >c_ip_start %c_ip_finish @!c_ip_error; |
166 }%% |
166 }%% |
167 |
167 |
168 /* state machine */ |
168 /* state machine */ |
169 %% write exec; |
169 %% write exec; |
170 |
170 |
171 /* If we were given an invalid line, bail early */ |
171 /* |
|
172 * If we were given an invalid line, bail early after remembering |
|
173 * the channel ID. |
|
174 * |
|
175 */ |
172 if ( cs < %%{ write first_final; }%% ) { |
176 if ( cs < %%{ write first_final; }%% ) { |
173 free( p_parsed ), p_parsed = NULL; |
|
174 debug( 3, LOC, "Invalid request line (%d), skipped\n", v.timer.lines + 1 ); |
177 debug( 3, LOC, "Invalid request line (%d), skipped\n", v.timer.lines + 1 ); |
175 debug( 4, LOC, "%s", line ); |
178 debug( 4, LOC, "%s", line ); |
176 return( NULL ); |
179 p_parsed->chid = COPY_STR( chid ); |
|
180 return( p_parsed ); |
177 } |
181 } |
178 |
182 |
179 debug( 6, LOC, "%s", line ); |
183 debug( 6, LOC, "%s", line ); |
180 (void)populate_parsed( p_parsed ); |
184 (void)populate_parsed( p_parsed ); |
181 return( p_parsed ); |
185 return( p_parsed ); |
355 if ( (p_parsed = malloc( sizeof(parsed) )) == NULL ) { |
359 if ( (p_parsed = malloc( sizeof(parsed) )) == NULL ) { |
356 debug( 5, LOC, "Unable to allocate memory for parsed struct: %s\n", strerror(errno) ); |
360 debug( 5, LOC, "Unable to allocate memory for parsed struct: %s\n", strerror(errno) ); |
357 return( NULL ); |
361 return( NULL ); |
358 } |
362 } |
359 |
363 |
|
364 p_parsed->valid = 0; |
360 p_parsed->type = 0; |
365 p_parsed->type = 0; |
361 p_parsed->negate = 0; |
366 p_parsed->negate = 0; |
362 p_parsed->lua = 0; |
367 p_parsed->lua = 0; |
|
368 p_parsed->chid = NULL; |
363 p_parsed->path_re = NULL; |
369 p_parsed->path_re = NULL; |
364 p_parsed->redir = NULL; |
370 p_parsed->redir = NULL; |
365 p_parsed->scheme = NULL; |
371 p_parsed->scheme = NULL; |
366 p_parsed->host = NULL; |
372 p_parsed->host = NULL; |
367 p_parsed->tld = NULL; |
373 p_parsed->tld = NULL; |
370 p_parsed->user = NULL; |
376 p_parsed->user = NULL; |
371 p_parsed->method = NULL; |
377 p_parsed->method = NULL; |
372 p_parsed->client_ip = NULL; |
378 p_parsed->client_ip = NULL; |
373 p_parsed->luapath = NULL; |
379 p_parsed->luapath = NULL; |
374 |
380 |
|
381 p_parsed->tokens.chid_start = NULL; |
375 p_parsed->tokens.path_re_start = NULL; |
382 p_parsed->tokens.path_re_start = NULL; |
376 p_parsed->tokens.redir_start = NULL; |
383 p_parsed->tokens.redir_start = NULL; |
377 p_parsed->tokens.scheme_start = NULL; |
384 p_parsed->tokens.scheme_start = NULL; |
378 p_parsed->tokens.host_start = NULL; |
385 p_parsed->tokens.host_start = NULL; |
379 p_parsed->tokens.port_start = NULL; |
386 p_parsed->tokens.port_start = NULL; |
380 p_parsed->tokens.path_start = NULL; |
387 p_parsed->tokens.path_start = NULL; |
381 p_parsed->tokens.meth_start = NULL; |
388 p_parsed->tokens.meth_start = NULL; |
382 p_parsed->tokens.c_ip_start = NULL; |
389 p_parsed->tokens.c_ip_start = NULL; |
383 p_parsed->tokens.luapath_start = NULL; |
390 p_parsed->tokens.luapath_start = NULL; |
|
391 p_parsed->tokens.chid_length = 0; |
384 p_parsed->tokens.path_re_length = 0; |
392 p_parsed->tokens.path_re_length = 0; |
385 p_parsed->tokens.redir_length = 0; |
393 p_parsed->tokens.redir_length = 0; |
386 p_parsed->tokens.scheme_length = 0; |
394 p_parsed->tokens.scheme_length = 0; |
387 p_parsed->tokens.host_length = 0; |
395 p_parsed->tokens.host_length = 0; |
388 p_parsed->tokens.port_length = 0; |
396 p_parsed->tokens.port_length = 0; |
408 free( p_parsed->host ); |
416 free( p_parsed->host ); |
409 free( p_parsed->path ); |
417 free( p_parsed->path ); |
410 free( p_parsed->port ); |
418 free( p_parsed->port ); |
411 |
419 |
412 if ( p_parsed->type == REQUEST ) { |
420 if ( p_parsed->type == REQUEST ) { |
|
421 free( p_parsed->chid ); |
413 free( p_parsed->tld ); |
422 free( p_parsed->tld ); |
414 free( p_parsed->method ); |
423 free( p_parsed->method ); |
415 free( p_parsed->client_ip ); |
424 free( p_parsed->client_ip ); |
416 } |
425 } |
417 |
426 |
441 p_parsed->host = COPY_STR( host ); |
447 p_parsed->host = COPY_STR( host ); |
442 p_parsed->path = COPY_STR( path ); |
448 p_parsed->path = COPY_STR( path ); |
443 p_parsed->port = COPY_STR( port ); |
449 p_parsed->port = COPY_STR( port ); |
444 |
450 |
445 if ( p_parsed->type == REQUEST ) { |
451 if ( p_parsed->type == REQUEST ) { |
|
452 p_parsed->valid = 1; |
|
453 p_parsed->chid = COPY_STR( chid ); |
446 p_parsed->method = COPY_STR( meth ); |
454 p_parsed->method = COPY_STR( meth ); |
447 p_parsed->client_ip = COPY_STR( c_ip ); |
455 p_parsed->client_ip = COPY_STR( c_ip ); |
448 /* p_request->client_ip = COPY_IP4( c_ip ); */ |
456 /* p_request->client_ip = COPY_IP4( c_ip ); */ |
449 |
457 |
450 (void)lowercase_str( p_parsed->host, p_parsed->tokens.host_length ); |
458 (void)lowercase_str( p_parsed->host, p_parsed->tokens.host_length ); |