|
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 |