parser.rl
changeset 29 c5d00a24af56
parent 22 822094314703
child 33 ba41bfbe87a2
equal deleted inserted replaced
25:6ceafe5ffe7f 29:c5d00a24af56
    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 
   424 	free( p_parsed ), p_parsed = NULL;
   433 	free( p_parsed ), p_parsed = NULL;
   425 
   434 
   426 	return;
   435 	return;
   427 }
   436 }
   428 
   437 
   429 
       
   430 #define COPY_STR( LBL ) copy_string_token( p_parsed->tokens.LBL ## _start, p_parsed->tokens.LBL ## _length )
       
   431 /* #define COPY_IP4( LBL ) copy_ipv4_token(   p_request->tokens.LBL ## _start, p_request->tokens.LBL ## _length ) */
       
   432 
   438 
   433 /*
   439 /*
   434  * Take the previously parsed token locations and copy them into the request struct.
   440  * Take the previously parsed token locations and copy them into the request struct.
   435  *
   441  *
   436  */
   442  */
   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 );