Imported Upstream version 2.5.11
[libapache-mod-security.git] / apache2 / t / regression / target / 00-targets.t
1 ### Test basic targets
2
3 # ARGS
4 {
5         type => "target",
6         comment => "ARGS (get)",
7         conf => qq(
8                 SecRuleEngine On
9                 SecRequestBodyAccess On
10                 SecResponseBodyAccess On
11                 SecResponseBodyMimeType null
12                 SecDebugLog $ENV{DEBUG_LOG}
13                 SecDebugLogLevel 9
14                 SecRule ARGS "val1" "phase:2,log,pass"
15                 SecRule ARGS "val2" "phase:2,log,pass"
16         ),
17         match_log => {
18                 error => [ qr/Pattern match "val1" at ARGS.*Pattern match "val2" at ARGS/s, 1 ],
19                 debug => [ qr/Adding request argument \(QUERY_STRING\): name "arg1", value "val1".*Adding request argument \(QUERY_STRING\): name "arg2", value "val2"/s, 1 ],
20         },
21         match_response => {
22                 status => qr/^200$/,
23         },
24         request => new HTTP::Request(
25                 GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
26         ),
27 },
28 {
29         type => "target",
30         comment => "ARGS (post)",
31         conf => qq(
32                 SecRuleEngine On
33                 SecRequestBodyAccess On
34                 SecResponseBodyAccess On
35                 SecResponseBodyMimeType null
36                 SecDebugLog $ENV{DEBUG_LOG}
37                 SecDebugLogLevel 9
38                 SecRule ARGS "val1" "phase:2,log,pass"
39                 SecRule ARGS "val2" "phase:2,log,pass"
40         ),
41         match_log => {
42                 error => [ qr/Pattern match "val1" at ARGS.*Pattern match "val2" at ARGS/s, 1 ],
43                 debug => [ qr/Adding request argument \(BODY\): name "arg1", value "val1".*Adding request argument \(BODY\): name "arg2", value "val2"/s, 1 ],
44         },
45         match_response => {
46                 status => qr/^200$/,
47         },
48         request => new HTTP::Request(
49                 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
50                 [
51                         "Content-Type" => "application/x-www-form-urlencoded",
52                 ],
53                 "arg1=val1&arg2=val2",
54         ),
55 },
56
57 # ARGS_COMBINED_SIZE
58 {
59         type => "target",
60         comment => "ARGS_COMBINED_SIZE (get)",
61         conf => qq(
62                 SecRuleEngine On
63                 SecRequestBodyAccess On
64                 SecResponseBodyAccess On
65                 SecResponseBodyMimeType null
66                 SecRule ARGS_COMBINED_SIZE "\@eq 16" "phase:2,log,pass"
67         ),
68         match_log => {
69                 error => [ qr/Operator EQ matched 16 at ARGS_COMBINED_SIZE\./s, 1 ],
70         },
71         match_response => {
72                 status => qr/^200$/,
73         },
74         request => new HTTP::Request(
75                 GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
76         ),
77 },
78 {
79         type => "target",
80         comment => "ARGS_COMBINED_SIZE (post)",
81         conf => qq(
82                 SecRuleEngine On
83                 SecRequestBodyAccess On
84                 SecResponseBodyAccess On
85                 SecResponseBodyMimeType null
86                 SecRule ARGS_COMBINED_SIZE "\@eq 16" "phase:2,log,pass"
87         ),
88         match_log => {
89                 error => [ qr/Operator EQ matched 16 at ARGS_COMBINED_SIZE\./s, 1 ],
90         },
91         match_response => {
92                 status => qr/^200$/,
93         },
94         request => new HTTP::Request(
95                 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
96                 [
97                         "Content-Type" => "application/x-www-form-urlencoded",
98                 ],
99                 "arg1=val1&arg2=val2",
100         ),
101 },
102
103 # ARGS_NAMES
104 {
105         type => "target",
106         comment => "ARGS_NAMES (get)",
107         conf => qq(
108                 SecRuleEngine On
109                 SecRequestBodyAccess On
110                 SecResponseBodyAccess On
111                 SecResponseBodyMimeType null
112                 SecDebugLog $ENV{DEBUG_LOG}
113                 SecDebugLogLevel 9
114                 SecRule ARGS_NAMES "arg1" "phase:2,log,pass"
115                 SecRule ARGS_NAMES "arg2" "phase:2,log,pass"
116         ),
117         match_log => {
118                 error => [ qr/Pattern match "arg1" at ARGS.*Pattern match "arg2" at ARGS/s, 1 ],
119                 debug => [ qr/Adding request argument \(QUERY_STRING\): name "arg1", value "val1".*Adding request argument \(QUERY_STRING\): name "arg2", value "val2"/s, 1 ],
120         },
121         match_response => {
122                 status => qr/^200$/,
123         },
124         request => new HTTP::Request(
125                 GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
126         ),
127 },
128 {
129         type => "target",
130         comment => "ARGS_NAMES (post)",
131         conf => qq(
132                 SecRuleEngine On
133                 SecRequestBodyAccess On
134                 SecResponseBodyAccess On
135                 SecResponseBodyMimeType null
136                 SecDebugLog $ENV{DEBUG_LOG}
137                 SecDebugLogLevel 9
138                 SecRule ARGS_NAMES "arg1" "phase:2,log,pass"
139                 SecRule ARGS_NAMES "arg2" "phase:2,log,pass"
140         ),
141         match_log => {
142                 error => [ qr/Pattern match "arg1" at ARGS_NAMES.*Pattern match "arg2" at ARGS_NAMES/s, 1 ],
143                 debug => [ qr/Adding request argument \(BODY\): name "arg1", value "val1".*Adding request argument \(BODY\): name "arg2", value "val2"/s, 1 ],
144         },
145         match_response => {
146                 status => qr/^200$/,
147         },
148         request => new HTTP::Request(
149                 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
150                 [
151                         "Content-Type" => "application/x-www-form-urlencoded",
152                 ],
153                 "arg1=val1&arg2=val2",
154         ),
155 },
156
157 # ARGS_GET
158 {
159         type => "target",
160         comment => "ARGS_GET (get)",
161         conf => qq(
162                 SecRuleEngine On
163                 SecRequestBodyAccess On
164                 SecResponseBodyAccess On
165                 SecResponseBodyMimeType null
166                 SecDebugLog $ENV{DEBUG_LOG}
167                 SecDebugLogLevel 9
168                 SecRule ARGS_GET "val1" "phase:2,log,pass"
169                 SecRule ARGS_GET "val2" "phase:2,log,pass"
170         ),
171         match_log => {
172                 error => [ qr/Pattern match "val1" at ARGS_GET.*Pattern match "val2" at ARGS_GET/s, 1 ],
173                 debug => [ qr/Adding request argument \(QUERY_STRING\): name "arg1", value "val1".*Adding request argument \(QUERY_STRING\): name "arg2", value "val2"/s, 1 ],
174         },
175         match_response => {
176                 status => qr/^200$/,
177         },
178         request => new HTTP::Request(
179                 GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
180         ),
181 },
182 {
183         type => "target",
184         comment => "ARGS_GET (post)",
185         conf => qq(
186                 SecRuleEngine On
187                 SecRequestBodyAccess On
188                 SecResponseBodyAccess On
189                 SecResponseBodyMimeType null
190                 SecDebugLog $ENV{DEBUG_LOG}
191                 SecDebugLogLevel 9
192                 SecRule ARGS_GET "val1" "phase:2,log,pass"
193                 SecRule ARGS_GET "val2" "phase:2,log,pass"
194         ),
195         match_log => {
196                 -error => [ qr/Pattern match/, 1 ],
197                 debug => [ qr/Adding request argument \(BODY\): name "arg1", value "val1".*Adding request argument \(BODY\): name "arg2", value "val2"/s, 1 ],
198         },
199         match_response => {
200                 status => qr/^200$/,
201         },
202         request => new HTTP::Request(
203                 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
204                 [
205                         "Content-Type" => "application/x-www-form-urlencoded",
206                 ],
207                 "arg1=val1&arg2=val2",
208         ),
209 },
210
211 # ARGS_GET_NAMES
212 {
213         type => "target",
214         comment => "ARGS_GET_NAMES (get)",
215         conf => qq(
216                 SecRuleEngine On
217                 SecRequestBodyAccess On
218                 SecResponseBodyAccess On
219                 SecResponseBodyMimeType null
220                 SecDebugLog $ENV{DEBUG_LOG}
221                 SecDebugLogLevel 9
222                 SecRule ARGS_GET_NAMES "arg1" "phase:2,log,pass"
223                 SecRule ARGS_GET_NAMES "arg2" "phase:2,log,pass"
224         ),
225         match_log => {
226                 error => [ qr/Pattern match "arg1" at ARGS_GET.*Pattern match "arg2" at ARGS_GET/s, 1 ],
227                 debug => [ qr/Adding request argument \(QUERY_STRING\): name "arg1", value "val1".*Adding request argument \(QUERY_STRING\): name "arg2", value "val2"/s, 1 ],
228         },
229         match_response => {
230                 status => qr/^200$/,
231         },
232         request => new HTTP::Request(
233                 GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
234         ),
235 },
236 {
237         type => "target",
238         comment => "ARGS_GET_NAMES (post)",
239         conf => qq(
240                 SecRuleEngine On
241                 SecRequestBodyAccess On
242                 SecResponseBodyAccess On
243                 SecResponseBodyMimeType null
244                 SecDebugLog $ENV{DEBUG_LOG}
245                 SecDebugLogLevel 9
246                 SecRule ARGS_GET_NAMES "arg1" "phase:2,log,pass"
247                 SecRule ARGS_GET_NAMES "arg2" "phase:2,log,pass"
248         ),
249         match_log => {
250                 -error => [ qr/Pattern match/, 1 ],
251                 debug => [ qr/Adding request argument \(BODY\): name "arg1", value "val1".*Adding request argument \(BODY\): name "arg2", value "val2"/s, 1 ],
252         },
253         match_response => {
254                 status => qr/^200$/,
255         },
256         request => new HTTP::Request(
257                 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
258                 [
259                         "Content-Type" => "application/x-www-form-urlencoded",
260                 ],
261                 "arg1=val1&arg2=val2",
262         ),
263 },
264
265 # ARGS_POST
266 {
267         type => "target",
268         comment => "ARGS_POST (get)",
269         conf => qq(
270                 SecRuleEngine On
271                 SecRequestBodyAccess On
272                 SecResponseBodyAccess On
273                 SecResponseBodyMimeType null
274                 SecDebugLog $ENV{DEBUG_LOG}
275                 SecDebugLogLevel 9
276                 SecRule ARGS_POST "val1" "phase:2,log,pass"
277                 SecRule ARGS_POST "val2" "phase:2,log,pass"
278         ),
279         match_log => {
280                 -error => [ qr/Pattern match/, 1 ],
281                 debug => [ qr/Adding request argument \(QUERY_STRING\): name "arg1", value "val1".*Adding request argument \(QUERY_STRING\): name "arg2", value "val2"/s, 1 ],
282         },
283         match_response => {
284                 status => qr/^200$/,
285         },
286         request => new HTTP::Request(
287                 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
288         ),
289 },
290 {
291         type => "target",
292         comment => "ARGS_POST (post)",
293         conf => qq(
294                 SecRuleEngine On
295                 SecRequestBodyAccess On
296                 SecResponseBodyAccess On
297                 SecResponseBodyMimeType null
298                 SecDebugLog $ENV{DEBUG_LOG}
299                 SecDebugLogLevel 9
300                 SecRule ARGS_POST "val1" "phase:2,log,pass"
301                 SecRule ARGS_POST "val2" "phase:2,log,pass"
302         ),
303         match_log => {
304                 error => [ qr/Pattern match "val1" at ARGS_POST.*Pattern match "val2" at ARGS_POST/s, 1 ],
305                 debug => [ qr/Adding request argument \(BODY\): name "arg1", value "val1".*Adding request argument \(BODY\): name "arg2", value "val2"/s, 1 ],
306         },
307         match_response => {
308                 status => qr/^200$/,
309         },
310         request => new HTTP::Request(
311                 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
312                 [
313                         "Content-Type" => "application/x-www-form-urlencoded",
314                 ],
315                 "arg1=val1&arg2=val2",
316         ),
317 },
318
319 # ARGS_POST_NAMES
320 {
321         type => "target",
322         comment => "ARGS_POST_NAMES (get)",
323         conf => qq(
324                 SecRuleEngine On
325                 SecRequestBodyAccess On
326                 SecResponseBodyAccess On
327                 SecResponseBodyMimeType null
328                 SecDebugLog $ENV{DEBUG_LOG}
329                 SecDebugLogLevel 9
330                 SecRule ARGS_POST_NAMES "arg1" "phase:2,log,pass"
331                 SecRule ARGS_POST_NAMES "arg2" "phase:2,log,pass"
332         ),
333         match_log => {
334                 -error => [ qr/Pattern match/, 1 ],
335                 debug => [ qr/Adding request argument \(QUERY_STRING\): name "arg1", value "val1".*Adding request argument \(QUERY_STRING\): name "arg2", value "val2"/s, 1 ],
336         },
337         match_response => {
338                 status => qr/^200$/,
339         },
340         request => new HTTP::Request(
341                 GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?arg1=val1&arg2=val2",
342         ),
343 },
344 {
345         type => "target",
346         comment => "ARGS_POST_NAMES (post)",
347         conf => qq(
348                 SecRuleEngine On
349                 SecRequestBodyAccess On
350                 SecResponseBodyAccess On
351                 SecResponseBodyMimeType null
352                 SecDebugLog $ENV{DEBUG_LOG}
353                 SecDebugLogLevel 9
354                 SecRule ARGS_POST_NAMES "arg1" "phase:2,log,pass"
355                 SecRule ARGS_POST_NAMES "arg2" "phase:2,log,pass"
356         ),
357         match_log => {
358                 error => [ qr/Pattern match "arg1" at ARGS_POST.*Pattern match "arg2" at ARGS_POST/s, 1 ],
359                 debug => [ qr/Adding request argument \(BODY\): name "arg1", value "val1".*Adding request argument \(BODY\): name "arg2", value "val2"/s, 1 ],
360         },
361         match_response => {
362                 status => qr/^200$/,
363         },
364         request => new HTTP::Request(
365                 POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
366                 [
367                         "Content-Type" => "application/x-www-form-urlencoded",
368                 ],
369                 "arg1=val1&arg2=val2",
370         ),
371 },
372
373 # AUTH_TYPE
374 #{
375 #       type => "target",
376 #       comment => "AUTH_TYPE",
377 #       conf => qq(
378 #               <IfVersion >= 2.2>
379 #                       <IfModule !mod_authn_file.c>
380 #                               LoadModule authn_file_module modules/mod_authn_file.so
381 #                       </IfModule>
382 #               </IfVersion>
383 ##              <IfVersion ~ ^2.0.>
384 ##                      <IfModule !mod_auth.c>
385 ##                              LoadModule auth_module modules/mod_auth.so
386 ##                      </IfModule>
387 ##              </IfVersion>
388 #               <Location />
389 #                       AuthType Basic
390 #                       AuthName Test
391 #                       AuthUserFile "$ENV{CONF_DIR}/htpasswd"
392 #                       Require user nobody
393 #               </Location>
394 #               SecRuleEngine On
395 #               SecRequestBodyAccess On
396 #               SecResponseBodyAccess On
397 #               SecResponseBodyMimeType null
398 ##              SecDebugLog $ENV{DEBUG_LOG}
399 ##              SecDebugLogLevel 9
400 #               SecRule REQUEST_HEADERS:Authorization "Basic (.*)" "phase:2,log,pass,capture,chain"
401 #               SecRule TX:1 "nobody:test" "t:none,t:base64Decode,chain"
402 #               SecRule AUTH_TYPE "Basic"
403 #       ),
404 #       match_log => {
405 #               error => [ qr/Pattern match "Basic" at AUTH_TYPE/s, 1 ],
406 #       },
407 #       match_response => {
408 #               status => qr/^200$/,
409 #       },
410 #       request => new HTTP::Request(
411 #               GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
412 #               [
413 #                       "Authorization" => "Basic bm9ib2R5OnRlc3Q="
414 #               ],
415 #       ),
416 #},
417
418 ## ENH: We cannot include this test as we cannot distribute the database.
419 ##      Instead we should create a simple test DB of our own.
420 ## GEO
421 #{
422 #       type => "target",
423 #       comment => "GEO (ip)",
424 #       conf => qq(
425 #               SecRuleEngine On
426 #               SecDebugLog $ENV{DEBUG_LOG}
427 #               SecDebugLogLevel 9
428 #        SecGeoLookupDB GeoLiteCity.dat
429 #               SecRule ARGS:ip "\@geoLookup" "phase:2,log,pass,t:none"
430 #               SecRule GEO:COUNTRY_CODE "\@streq US" "phase:2,log,pass,t:none"
431 #               SecRule GEO:COUNTRY_CODE3 "\@streq USA" "phase:2,log,pass,t:none"
432 #               SecRule GEO:COUNTRY_NAME "\@streq United States" "phase:2,log,pass,t:none"
433 #        # ENH: Not in this database?
434 #               SecRule GEO:COUNTRY_CONTINENT "\@streq NA" "phase:2,log,pass,t:none"
435 #               SecRule GEO:REGION "\@streq CA" "phase:2,log,pass,t:none"
436 #               SecRule GEO:CITY "\@streq San Diego" "phase:2,log,pass,t:none"
437 #               SecRule GEO:POSTAL_CODE "\@streq 92123" "phase:2,log,pass,t:none"
438 #               SecRule GEO:LATITUDE "\@beginsWith 32.8" "phase:2,log,pass,t:none"
439 #               SecRule GEO:LONGITUDE "\@beginsWith 117.1" "phase:2,log,pass,t:none"
440 #               SecRule GEO:DMA_CODE "\@streq 825" "phase:2,log,pass,t:none"
441 #               SecRule GEO:AREA_CODE "\@streq 858" "phase:2,log,pass,t:none"
442 #       ),
443 #       match_log => {
444 #               debug => [ qr/Geo lookup for "216.75.21.122" succeeded.*match "US" at GEO:COUNTRY_CODE.*match "USA" at GEO:COUNTRY_CODE3.*match "United States" at GEO:COUNTRY_NAME.*match "NA" at GEO:COUNTRY_CONTINENT.*match "CA" at GEO:REGION.*match "San Diego" at GEO:CITY.*match "92123" at GEO:POSTAL_CODE.*match "32.8" at GEO:LATITUDE.*match "825" at GEO:DMA_CODE.*match "858" at GEO:AREA_CODE/si, 1 ],
445 #       },
446 #       match_response => {
447 #               status => qr/^200$/,
448 #       },
449 #       request => new HTTP::Request(
450 #               GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?ip=216.75.21.122",
451 #       ),
452 #},
453 #{
454 #       type => "target",
455 #       comment => "GEO (host)",
456 #       conf => qq(
457 #               SecRuleEngine On
458 #               SecDebugLog $ENV{DEBUG_LOG}
459 #               SecDebugLogLevel 9
460 #        SecGeoLookupDB GeoLiteCity.dat
461 #               SecRule ARGS:host "\@geoLookup" "phase:2,log,pass,t:none"
462 #               SecRule GEO:COUNTRY_CODE "\@streq US" "phase:2,log,pass,t:none"
463 #               SecRule GEO:COUNTRY_CODE3 "\@streq USA" "phase:2,log,pass,t:none"
464 #               SecRule GEO:COUNTRY_NAME "\@streq United States" "phase:2,log,pass,t:none"
465 #        # ENH: Not in this database?
466 #               SecRule GEO:COUNTRY_CONTINENT "\@streq NA" "phase:2,log,pass,t:none"
467 #               SecRule GEO:REGION "\@streq CA" "phase:2,log,pass,t:none"
468 #               SecRule GEO:CITY "\@streq San Diego" "phase:2,log,pass,t:none"
469 #               SecRule GEO:POSTAL_CODE "\@streq 92123" "phase:2,log,pass,t:none"
470 #               SecRule GEO:LATITUDE "\@beginsWith 32.8" "phase:2,log,pass,t:none"
471 #               SecRule GEO:LONGITUDE "\@beginsWith 117.1" "phase:2,log,pass,t:none"
472 #               SecRule GEO:DMA_CODE "\@streq 825" "phase:2,log,pass,t:none"
473 #               SecRule GEO:AREA_CODE "\@streq 858" "phase:2,log,pass,t:none"
474 #       ),
475 #       match_log => {
476 #               debug => [ qr/Using address "\d+\.\d+\.\d+\.\d+".*Geo lookup for "www\.modsecurity\.org" succeeded.*match "US" at GEO:COUNTRY_CODE.*match "USA" at GEO:COUNTRY_CODE3.*match "United States" at GEO:COUNTRY_NAME.*match "NA" at GEO:COUNTRY_CONTINENT.*match "CA" at GEO:REGION.*match "San Diego" at GEO:CITY.*match "92123" at GEO:POSTAL_CODE.*match "32.8" at GEO:LATITUDE.*match "825" at GEO:DMA_CODE.*match "858" at GEO:AREA_CODE/si, 1 ],
477 #       },
478 #       match_response => {
479 #               status => qr/^200$/,
480 #       },
481 #       request => new HTTP::Request(
482 #               GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?host=www.modsecurity.org",
483 #       ),
484 #},
485 #{
486 #       type => "target",
487 #       comment => "GEO (failed lookup)",
488 #       conf => qq(
489 #               SecRuleEngine On
490 #               SecDebugLog $ENV{DEBUG_LOG}
491 #               SecDebugLogLevel 9
492 #        SecGeoLookupDB GeoLiteCity.dat
493 #               SecRule ARGS:ip "\@geoLookup" "phase:2,log,pass,t:none"
494 #               SecRule \&GEO "\@eq 0" "phase:2,log,deny,status:403,t:none"
495 #               SecRule ARGS:badip "\@geoLookup" "phase:2,log,pass,t:none"
496 #               SecRule \&GEO "!\@eq 0" "phase:2,log,deny,status:403,t:none"
497 #       ),
498 #       match_log => {
499 #               -debug => [ qr/Geo lookup for "127\.0\.0\.1" succeeded/si, 1 ],
500 #       },
501 #       match_response => {
502 #               status => qr/^200$/,
503 #       },
504 #       request => new HTTP::Request(
505 #               GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?ip=216.75.21.122&badip=127.0.0.1",
506 #       ),
507 #},
508
509 # TODO: ENV
510 # TODO: FILES
511 # TODO: FILES_COMBINED_SIZE
512 # TODO: FILES_NAMES
513 # TODO: FILES_SIZES
514 # TODO: FILES_TMPNAMES
515 # TODO: HIGHEST_SEVERITY
516 # TODO: MATCHED_VAR
517 # TODO: MATCHED_VAR_NAME
518 # TODO: MODSEC_BUILD
519 # TODO: MULTIPART_CRLF_LF_LINES
520 # TODO: MULTIPART_STRICT_ERROR
521 # TODO: MULTIPART_UNMATCHED_BOUNDARY
522 # TODO: PATH_INFO
523 # TODO: QUERY_STRING
524 # TODO: REMOTE_ADDR
525 # TODO: REMOTE_HOST
526 # TODO: REMOTE_PORT
527 # TODO: REMOTE_USER
528 # TODO: REQBODY_PROCESSOR
529 # TODO: REQBODY_PROCESSOR_ERROR
530 # TODO: REQBODY_PROCESSOR_ERROR_MSG
531 # TODO: REQUEST_BASENAME
532 # TODO: REQUEST_BODY
533 # TODO: REQUEST_COOKIES
534 # TODO: REQUEST_COOKIES_NAMES
535 # TODO: REQUEST_FILENAME
536 # TODO: REQUEST_HEADERS
537 # TODO: REQUEST_HEADERS_NAMES
538 # TODO: REQUEST_LINE
539 # TODO: REQUEST_METHOD
540 # TODO: REQUEST_PROTOCOL
541 # TODO: REQUEST_URI
542 # TODO: REQUEST_URI_RAW
543 # TODO: RESPONSE_BODY
544 # TODO: RESPONSE_CONTENT_LENGTH
545 # TODO: RESPONSE_CONTENT_TYPE
546 # TODO: RESPONSE_HEADERS
547 # TODO: RESPONSE_HEADERS_NAMES
548 # TODO: RESPONSE_PROTOCOL
549 # TODO: RESPONSE_STATUS
550 # TODO: RULE
551 # TODO: SCRIPT_BASENAME
552 # TODO: SCRIPT_FILENAME
553 # TODO: SCRIPT_GID
554 # TODO: SCRIPT_GROUPNAME
555 # TODO: SCRIPT_MODE
556 # TODO: SCRIPT_UID
557 # TODO: SCRIPT_USERNAME
558 # TODO: SERVER_ADDR
559 # TODO: SERVER_NAME
560 # TODO: SERVER_PORT
561 # TODO: SESSION
562 # TODO: SESSIONID
563 # TODO: TIME
564 # TODO: TIME_DAY
565 # TODO: TIME_EPOCH
566 # TODO: TIME_HOUR
567 # TODO: TIME_MIN
568 # TODO: TIME_MON
569 # TODO: TIME_SEC
570 # TODO: TIME_WDAY
571 # TODO: TIME_YEAR
572 # TODO: TX
573 # TODO: USERID
574 # TODO: WEBAPPID
575 # TODO: WEBSERVER_ERROR_LOG
576 # TODO: XML
577