parser.c
changeset 2 8c88756f81b0
child 9 bdf20e6eefd7
equal deleted inserted replaced
1:823d42546cea 2:8c88756f81b0
       
     1 
       
     2 /* #line 1 "parser.rl" */
       
     3 /* vim: set noet nosta sw=4 ts=4 ft=ragel : */
       
     4 /*
       
     5 Copyright (c) 2011, Mahlon E. Smith <mahlon@martini.nu>
       
     6 All rights reserved.
       
     7 Redistribution and use in source and binary forms, with or without
       
     8 modification, are permitted provided that the following conditions are met:
       
     9 
       
    10     * Redistributions of source code must retain the above copyright
       
    11       notice, this list of conditions and the following disclaimer.
       
    12 
       
    13     * Redistributions in binary form must reproduce the above copyright
       
    14       notice, this list of conditions and the following disclaimer in the
       
    15       documentation and/or other materials provided with the distribution.
       
    16 
       
    17     * Neither the name of Mahlon E. Smith nor the names of his
       
    18       contributors may be used to endorse or promote products derived
       
    19       from this software without specific prior written permission.
       
    20 
       
    21 THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
       
    22 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    24 DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
       
    25 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
       
    26 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    27 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
       
    28 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
       
    30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    31 */
       
    32 
       
    33 /*
       
    34 Squid docs:
       
    35 ---------------------------------------------------------------------------
       
    36 TAG: url_rewrite_program
       
    37 Specify the location of the executable for the URL rewriter.
       
    38 Since they can perform almost any function there isn't one included.
       
    39 
       
    40 For each requested URL rewriter will receive on line with the format
       
    41 
       
    42 URL <SP> client_ip "/" fqdn <SP> user <SP> method [<SP> kvpairs]<NL>
       
    43 
       
    44 In the future, the rewriter interface will be extended with
       
    45 key=value pairs ("kvpairs" shown above).  Rewriter programs
       
    46 should be prepared to receive and possibly ignore additional
       
    47 whitespace-separated tokens on each input line.
       
    48 
       
    49 And the rewriter may return a rewritten URL. The other components of
       
    50 the request line does not need to be returned (ignored if they are).
       
    51 
       
    52 The rewriter can also indicate that a client-side redirect should
       
    53 be performed to the new URL. This is done by prefixing the returned
       
    54 URL with "301:" (moved permanently) or 302: (moved temporarily).
       
    55 
       
    56 By default, a URL rewriter is not used.
       
    57 ---------------------------------------------------------------------------
       
    58 */
       
    59 
       
    60 #include "volta.h"
       
    61 
       
    62 
       
    63 /* #line 80 "parser.rl" */
       
    64 
       
    65 
       
    66 /* #line 67 "parser.c" */
       
    67 static const int redirector_start = 1;
       
    68 static const int redirector_first_final = 13;
       
    69 static const int redirector_error = 0;
       
    70 
       
    71 static const int redirector_en_main = 1;
       
    72 
       
    73 
       
    74 /* #line 82 "parser.rl" */
       
    75 
       
    76 /*
       
    77 %%{
       
    78 	machine redirector;
       
    79 
       
    80 	action yay {
       
    81 		printf( "I saw: %s", p+1 );
       
    82 	}
       
    83 
       
    84 	# http://, ftp://, https://, etc
       
    85 	proto = alpha{3,5} . '://';
       
    86 
       
    87 	# http://mahlon:password@example.com or http://mahlon@example.com
       
    88     #       username              optional password
       
    89 	creds = ( alnum | [+._\-] )+ . ( ':' . any+ )? . '@';
       
    90 
       
    91 	main := ( proto . creds ) | proto @yay '\n';
       
    92 }%%
       
    93 %% write data;
       
    94 */
       
    95 
       
    96 
       
    97 /*
       
    98 %%{
       
    99 	machine foo;
       
   100 
       
   101 	OPEN = 0;
       
   102 	CLOSE = 1;
       
   103 
       
   104 	main :=
       
   105 		start:
       
   106 		door_closed: (
       
   107 			OPEN -> door_open -> final
       
   108 		),
       
   109 		door_open: (
       
   110 			CLOSE -> door_closed
       
   111 		);
       
   112 }%%
       
   113 */
       
   114 
       
   115 struct request *
       
   116 parse( char *p )
       
   117 {
       
   118    	/* initial machine state */
       
   119 	short int cs = 0;
       
   120 
       
   121 	/* the client request object */
       
   122 	request c_request;
       
   123 	request *cp_request = &c_request;
       
   124 
       
   125 	/*
       
   126 	char ip[ INET_ADDRSTRLEN ];
       
   127 	inet_pton( AF_INET, "127.0.0.1", &cp_request->ip );
       
   128 	inet_ntop( AF_INET, &cp_request->ip, ip, INET_ADDRSTRLEN );
       
   129 	*/
       
   130 
       
   131 	/* initalize state machine with current line */
       
   132 	char *pe = p + strlen(p) + 1;
       
   133 
       
   134 	/* enter state machine */
       
   135 	
       
   136 /* #line 137 "parser.c" */
       
   137 	{
       
   138 	cs = redirector_start;
       
   139 	}
       
   140 
       
   141 /* #line 143 "parser.rl" */
       
   142 	
       
   143 /* #line 144 "parser.c" */
       
   144 	{
       
   145 	if ( p == pe )
       
   146 		goto _test_eof;
       
   147 	switch ( cs )
       
   148 	{
       
   149 case 1:
       
   150 	if ( (*p) > 90 ) {
       
   151 		if ( 97 <= (*p) && (*p) <= 122 )
       
   152 			goto st2;
       
   153 	} else if ( (*p) >= 65 )
       
   154 		goto st2;
       
   155 	goto st0;
       
   156 st0:
       
   157 cs = 0;
       
   158 	goto _out;
       
   159 st2:
       
   160 	if ( ++p == pe )
       
   161 		goto _test_eof2;
       
   162 case 2:
       
   163 	if ( (*p) > 90 ) {
       
   164 		if ( 97 <= (*p) && (*p) <= 122 )
       
   165 			goto st3;
       
   166 	} else if ( (*p) >= 65 )
       
   167 		goto st3;
       
   168 	goto st0;
       
   169 st3:
       
   170 	if ( ++p == pe )
       
   171 		goto _test_eof3;
       
   172 case 3:
       
   173 	if ( (*p) > 90 ) {
       
   174 		if ( 97 <= (*p) && (*p) <= 122 )
       
   175 			goto st4;
       
   176 	} else if ( (*p) >= 65 )
       
   177 		goto st4;
       
   178 	goto st0;
       
   179 st4:
       
   180 	if ( ++p == pe )
       
   181 		goto _test_eof4;
       
   182 case 4:
       
   183 	if ( (*p) == 58 )
       
   184 		goto st5;
       
   185 	if ( (*p) > 90 ) {
       
   186 		if ( 97 <= (*p) && (*p) <= 122 )
       
   187 			goto st11;
       
   188 	} else if ( (*p) >= 65 )
       
   189 		goto st11;
       
   190 	goto st0;
       
   191 st5:
       
   192 	if ( ++p == pe )
       
   193 		goto _test_eof5;
       
   194 case 5:
       
   195 	if ( (*p) == 47 )
       
   196 		goto st6;
       
   197 	goto st0;
       
   198 st6:
       
   199 	if ( ++p == pe )
       
   200 		goto _test_eof6;
       
   201 case 6:
       
   202 	if ( (*p) == 47 )
       
   203 		goto tr7;
       
   204 	goto st0;
       
   205 tr7:
       
   206 /* #line 68 "parser.rl" */
       
   207 	{
       
   208 		printf( "I saw: %s", p+1 );
       
   209 	}
       
   210 	goto st7;
       
   211 st7:
       
   212 	if ( ++p == pe )
       
   213 		goto _test_eof7;
       
   214 case 7:
       
   215 /* #line 216 "parser.c" */
       
   216 	switch( (*p) ) {
       
   217 		case 10: goto st13;
       
   218 		case 43: goto st8;
       
   219 		case 95: goto st8;
       
   220 	}
       
   221 	if ( (*p) < 48 ) {
       
   222 		if ( 45 <= (*p) && (*p) <= 46 )
       
   223 			goto st8;
       
   224 	} else if ( (*p) > 57 ) {
       
   225 		if ( (*p) > 90 ) {
       
   226 			if ( 97 <= (*p) && (*p) <= 122 )
       
   227 				goto st8;
       
   228 		} else if ( (*p) >= 65 )
       
   229 			goto st8;
       
   230 	} else
       
   231 		goto st8;
       
   232 	goto st0;
       
   233 st13:
       
   234 	if ( ++p == pe )
       
   235 		goto _test_eof13;
       
   236 case 13:
       
   237 	goto st0;
       
   238 st8:
       
   239 	if ( ++p == pe )
       
   240 		goto _test_eof8;
       
   241 case 8:
       
   242 	switch( (*p) ) {
       
   243 		case 43: goto st8;
       
   244 		case 58: goto st9;
       
   245 		case 64: goto st13;
       
   246 		case 95: goto st8;
       
   247 	}
       
   248 	if ( (*p) < 48 ) {
       
   249 		if ( 45 <= (*p) && (*p) <= 46 )
       
   250 			goto st8;
       
   251 	} else if ( (*p) > 57 ) {
       
   252 		if ( (*p) > 90 ) {
       
   253 			if ( 97 <= (*p) && (*p) <= 122 )
       
   254 				goto st8;
       
   255 		} else if ( (*p) >= 65 )
       
   256 			goto st8;
       
   257 	} else
       
   258 		goto st8;
       
   259 	goto st0;
       
   260 st9:
       
   261 	if ( ++p == pe )
       
   262 		goto _test_eof9;
       
   263 case 9:
       
   264 	goto st10;
       
   265 st10:
       
   266 	if ( ++p == pe )
       
   267 		goto _test_eof10;
       
   268 case 10:
       
   269 	if ( (*p) == 64 )
       
   270 		goto st14;
       
   271 	goto st10;
       
   272 st14:
       
   273 	if ( ++p == pe )
       
   274 		goto _test_eof14;
       
   275 case 14:
       
   276 	if ( (*p) == 64 )
       
   277 		goto st14;
       
   278 	goto st10;
       
   279 st11:
       
   280 	if ( ++p == pe )
       
   281 		goto _test_eof11;
       
   282 case 11:
       
   283 	if ( (*p) == 58 )
       
   284 		goto st5;
       
   285 	if ( (*p) > 90 ) {
       
   286 		if ( 97 <= (*p) && (*p) <= 122 )
       
   287 			goto st12;
       
   288 	} else if ( (*p) >= 65 )
       
   289 		goto st12;
       
   290 	goto st0;
       
   291 st12:
       
   292 	if ( ++p == pe )
       
   293 		goto _test_eof12;
       
   294 case 12:
       
   295 	if ( (*p) == 58 )
       
   296 		goto st5;
       
   297 	goto st0;
       
   298 	}
       
   299 	_test_eof2: cs = 2; goto _test_eof; 
       
   300 	_test_eof3: cs = 3; goto _test_eof; 
       
   301 	_test_eof4: cs = 4; goto _test_eof; 
       
   302 	_test_eof5: cs = 5; goto _test_eof; 
       
   303 	_test_eof6: cs = 6; goto _test_eof; 
       
   304 	_test_eof7: cs = 7; goto _test_eof; 
       
   305 	_test_eof13: cs = 13; goto _test_eof; 
       
   306 	_test_eof8: cs = 8; goto _test_eof; 
       
   307 	_test_eof9: cs = 9; goto _test_eof; 
       
   308 	_test_eof10: cs = 10; goto _test_eof; 
       
   309 	_test_eof14: cs = 14; goto _test_eof; 
       
   310 	_test_eof11: cs = 11; goto _test_eof; 
       
   311 	_test_eof12: cs = 12; goto _test_eof; 
       
   312 
       
   313 	_test_eof: {}
       
   314 	_out: {}
       
   315 	}
       
   316 
       
   317 /* #line 144 "parser.rl" */
       
   318 
       
   319 	/* reset the request */
       
   320 	/* c_request = reset_request; */
       
   321 	return( cp_request );
       
   322 }
       
   323