Apache HTTPD
util_script.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "apr.h"
18#include "apr_lib.h"
19#include "apr_strings.h"
20
21#define APR_WANT_STRFUNC
22#include "apr_want.h"
23
24#if APR_HAVE_STDLIB_H
25#include <stdlib.h>
26#endif
27
28#include "ap_config.h"
29#include "httpd.h"
30#include "http_config.h"
31#include "http_main.h"
32#include "http_log.h"
33#include "http_core.h"
34#include "http_protocol.h"
35#include "http_request.h" /* for sub_req_lookup_uri() */
36#include "util_script.h"
37#include "apr_date.h" /* For apr_date_parse_http() */
38#include "util_ebcdic.h"
39
40#ifdef OS2
41#define INCL_DOS
42#include <os2.h>
43#endif
44
45/*
46 * Various utility functions which are common to a whole lot of
47 * script-type extensions mechanisms, and might as well be gathered
48 * in one place (if only to avoid creating inter-module dependencies
49 * where there don't have to be).
50 */
51
52/* we know core's module_index is 0 */
53#undef APLOG_MODULE_INDEX
54#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
55
56static char *http2env(request_rec *r, const char *w)
57{
58 char *res = (char *)apr_palloc(r->pool, sizeof("HTTP_") + strlen(w));
59 char *cp = res;
60 char c;
61
62 *cp++ = 'H';
63 *cp++ = 'T';
64 *cp++ = 'T';
65 *cp++ = 'P';
66 *cp++ = '_';
67
68 while ((c = *w++) != 0) {
69 if (apr_isalnum(c)) {
70 *cp++ = apr_toupper(c);
71 }
72 else if (c == '-') {
73 *cp++ = '_';
74 }
75 else {
76 if (APLOGrtrace1(r))
78 "Not exporting header with invalid name as envvar: %s",
80 return NULL;
81 }
82 }
83 *cp = 0;
84
85 return res;
86}
87
88static void add_unless_null(apr_table_t *table, const char *name, const char *val)
89{
90 if (name && val) {
91 apr_table_addn(table, name, val);
92 }
93}
94
95/* Sets variable @name in table @dest from r->subprocess_env if
96 * available, else from the environment, else from @fallback if
97 * non-NULL. */
99 const char *name, const char *fallback)
100{
101 const char *val;
102
104 if (!val)
106 if (!val)
108 if (val)
110}
111
113{
115 const apr_table_entry_t *elts = (const apr_table_entry_t *) env_arr->elts;
116 char **env = (char **) apr_palloc(p, (env_arr->nelts + 2) * sizeof(char *));
117 int i, j;
118 char *tz;
119 char *whack;
120
121 j = 0;
122 if (!apr_table_get(t, "TZ")) {
123 tz = getenv("TZ");
124 if (tz != NULL) {
125 env[j++] = apr_pstrcat(p, "TZ=", tz, NULL);
126 }
127 }
128 for (i = 0; i < env_arr->nelts; ++i) {
129 if (!elts[i].key) {
130 continue;
131 }
132 env[j] = apr_pstrcat(p, elts[i].key, "=", elts[i].val, NULL);
133 whack = env[j];
134 if (apr_isdigit(*whack)) {
135 *whack++ = '_';
136 }
137 while (*whack != '=') {
138#ifdef WIN32
139 if (!apr_isalnum(*whack) && *whack != '(' && *whack != ')') {
140#else
141 if (!apr_isalnum(*whack)) {
142#endif
143 *whack = '_';
144 }
145 ++whack;
146 }
147 ++j;
148 }
149
150 env[j] = NULL;
151 return env;
152}
153
155{
156 apr_table_t *e;
157 server_rec *s = r->server;
159 core_dir_config *conf =
161 const char *env_temp;
163 const apr_table_entry_t *hdrs = (const apr_table_entry_t *) hdrs_arr->elts;
164 int i;
166 char *q;
167
168 /* use a temporary apr_table_t which we'll overlap onto
169 * r->subprocess_env later
170 * (exception: if r->subprocess_env is empty at the start,
171 * write directly into it)
172 */
174 e = r->subprocess_env;
175 }
176 else {
177 e = apr_table_make(r->pool, 25 + hdrs_arr->nelts);
178 }
179
180 /* First, add environment vars from headers... this is as per
181 * CGI specs, though other sorts of scripting interfaces see
182 * the same vars...
183 */
184
185 for (i = 0; i < hdrs_arr->nelts; ++i) {
186 if (!hdrs[i].key) {
187 continue;
188 }
189
190 /* A few headers are special cased --- Authorization to prevent
191 * rogue scripts from capturing passwords; content-type and -length
192 * for no particular reason.
193 */
194
195 if (!ap_cstr_casecmp(hdrs[i].key, "Content-type")) {
196 apr_table_addn(e, "CONTENT_TYPE", hdrs[i].val);
197 }
198 else if (!ap_cstr_casecmp(hdrs[i].key, "Content-length")) {
199 apr_table_addn(e, "CONTENT_LENGTH", hdrs[i].val);
200 }
201 /* HTTP_PROXY collides with a popular envvar used to configure
202 * proxies, don't let clients set/override it. But, if you must...
203 */
204#ifndef SECURITY_HOLE_PASS_PROXY
205 else if (!ap_cstr_casecmp(hdrs[i].key, "Proxy")) {
206 ;
207 }
208#endif
209 /*
210 * You really don't want to disable this check, since it leaves you
211 * wide open to CGIs stealing passwords and people viewing them
212 * in the environment with "ps -e". But, if you must...
213 */
214#ifndef SECURITY_HOLE_PASS_AUTHORIZATION
215 else if (!ap_cstr_casecmp(hdrs[i].key, "Authorization")
216 || !ap_cstr_casecmp(hdrs[i].key, "Proxy-Authorization")) {
217 if (conf->cgi_pass_auth == AP_CGI_PASS_AUTH_ON) {
218 add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val);
219 }
220 }
221#endif
222 else
223 add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val);
224 }
225
226 env2env(e, r, "PATH", DEFAULT_PATH);
227#if defined(WIN32)
228 env2env(e, r, "SystemRoot", NULL);
229 env2env(e, r, "COMSPEC", NULL);
230 env2env(e, r, "PATHEXT", NULL);
231 env2env(e, r, "WINDIR", NULL);
232#elif defined(OS2)
233 env2env(e, r, "COMSPEC", NULL);
234 env2env(e, r, "ETC", NULL);
235 env2env(e, r, "DPATH", NULL);
236 env2env(e, r, "PERLLIB_PREFIX", NULL);
237#elif defined(BEOS)
238 env2env(e, r, "LIBRARY_PATH", NULL);
239#elif defined(DARWIN)
240 env2env(e, r, "DYLD_LIBRARY_PATH", NULL);
241#elif defined(_AIX)
242 env2env(e, r, "LIBPATH", NULL);
243#elif defined(__HPUX__)
244 /* HPUX PARISC 2.0W knows both, otherwise redundancy is harmless */
245 env2env(e, r, "SHLIB_PATH", NULL);
246 env2env(e, r, "LD_LIBRARY_PATH", NULL);
247#else /* Some Unix */
248 env2env(e, r, "LD_LIBRARY_PATH", NULL);
249#endif
250
251 apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
252 apr_table_addn(e, "SERVER_SOFTWARE", ap_get_server_banner());
253 apr_table_addn(e, "SERVER_NAME",
255 apr_table_addn(e, "SERVER_ADDR", r->connection->local_ip); /* Apache */
256 apr_table_addn(e, "SERVER_PORT",
258 add_unless_null(e, "REMOTE_HOST",
260 apr_table_addn(e, "REMOTE_ADDR", r->useragent_ip);
261 apr_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r)); /* Apache */
262 apr_table_setn(e, "REQUEST_SCHEME", ap_http_scheme(r));
263 apr_table_addn(e, "CONTEXT_PREFIX", ap_context_prefix(r));
264 apr_table_addn(e, "CONTEXT_DOCUMENT_ROOT", ap_context_document_root(r));
265 apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
266 if (apr_table_get(r->notes, "proxy-noquery") && (q = ap_strchr(r->filename, '?'))) {
268 apr_table_addn(e, "SCRIPT_FILENAME", script_filename);
269 }
270 else {
271 apr_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */
272 }
273
274 rport = c->client_addr->port;
275 apr_table_addn(e, "REMOTE_PORT", apr_itoa(r->pool, rport));
276
277 if (r->user) {
278 apr_table_addn(e, "REMOTE_USER", r->user);
279 }
280 else if (r->prev) {
282
283 while (back) {
284 if (back->user) {
285 apr_table_addn(e, "REDIRECT_REMOTE_USER", back->user);
286 break;
287 }
288 back = back->prev;
289 }
290 }
291 add_unless_null(e, "AUTH_TYPE", r->ap_auth_type);
293 if (env_temp) {
294 apr_table_addn(e, "REMOTE_IDENT", apr_pstrdup(r->pool, env_temp));
295 }
296
297 /* Apache custom error responses. If we have redirected set two new vars */
298
299 if (r->prev) {
301 add_unless_null(e, "REDIRECT_URL", r->prev->uri);
302 }
303 else {
304 /* PR#57785: reconstruct full URL here */
306 if (!uri->scheme) {
307 uri->scheme = (char*)ap_http_scheme(r->prev);
308 }
309 if (!uri->port) {
310 uri->port = ap_get_server_port(r->prev);
311 uri->port_str = apr_psprintf(r->pool, "%u", uri->port);
312 }
313 if (!uri->hostname) {
314 uri->hostname = (char*)ap_get_server_name_for_url(r->prev);
315 }
316 add_unless_null(e, "REDIRECT_URL",
317 apr_uri_unparse(r->pool, uri, 0));
318 }
319 add_unless_null(e, "REDIRECT_QUERY_STRING", r->prev->args);
320 }
321
322 if (e != r->subprocess_env) {
324 }
325}
326
327/* This "cute" little function comes about because the path info on
328 * filenames and URLs aren't always the same. So we take the two,
329 * and find as much of the two that match as possible.
330 */
331
332AP_DECLARE(int) ap_find_path_info(const char *uri, const char *path_info)
333{
334 int lu = strlen(uri);
335 int lp = strlen(path_info);
336
337 while (lu-- && lp-- && uri[lu] == path_info[lp]) {
338 if (path_info[lp] == '/') {
339 while (lu && uri[lu-1] == '/') lu--;
340 }
341 }
342
343 if (lu == -1) {
344 lu = 0;
345 }
346
347 while (uri[lu] != '\0' && uri[lu] != '/') {
348 lu++;
349 }
350 return lu;
351}
352
353/* Obtain the Request-URI from the original request-line, returning
354 * a new string from the request pool containing the URI or "".
355 */
357{
358 char *first, *last;
359
360 if (r->the_request == NULL) {
361 return (char *) apr_pcalloc(r->pool, 1);
362 }
363
364 first = r->the_request; /* use the request-line */
365
366 while (*first && !apr_isspace(*first)) {
367 ++first; /* skip over the method */
368 }
369 while (apr_isspace(*first)) {
370 ++first; /* and the space(s) */
371 }
372
373 last = first;
374 while (*last && !apr_isspace(*last)) {
375 ++last; /* end at next whitespace */
376 }
377
378 return apr_pstrmemdup(r->pool, first, last - first);
379}
380
382{
384 core_dir_config *conf =
387 const char *request_uri_rule;
388
389 apr_table_setn(e, "GATEWAY_INTERFACE", "CGI/1.1");
390 apr_table_setn(e, "SERVER_PROTOCOL", r->protocol);
391 apr_table_setn(e, "REQUEST_METHOD", r->method);
392 apr_table_setn(e, "QUERY_STRING", r->args ? r->args : "");
393
394 if (conf->cgi_var_rules) {
395 request_uri_rule = apr_hash_get(conf->cgi_var_rules, "REQUEST_URI",
397 if (request_uri_rule && !strcmp(request_uri_rule, "current-uri")) {
399 }
400 }
401 apr_table_setn(e, "REQUEST_URI",
403
404 /* Note that the code below special-cases scripts run from includes,
405 * because it "knows" that the sub_request has been hacked to have the
406 * args and path_info of the original request, and not any that may have
407 * come with the script URI in the include command. Ugh.
408 */
409
410 if (!strcmp(r->protocol, "INCLUDED")) {
411 apr_table_setn(e, "SCRIPT_NAME", r->uri);
412 if (r->path_info && *r->path_info) {
413 apr_table_setn(e, "PATH_INFO", r->path_info);
414 }
415 }
416 else if (!r->path_info || !*r->path_info) {
417 apr_table_setn(e, "SCRIPT_NAME", r->uri);
418 }
419 else {
421
422 apr_table_setn(e, "SCRIPT_NAME",
424
425 apr_table_setn(e, "PATH_INFO", r->path_info);
426 }
427
428 if (r->path_info && r->path_info[0]) {
429 /*
430 * To get PATH_TRANSLATED, treat PATH_INFO as a URI path.
431 * Need to re-escape it for this, since the entire URI was
432 * un-escaped before we determined where the PATH_INFO began.
433 */
435
437 NULL);
438
439 if (pa_req->filename) {
440 char *pt = apr_pstrcat(r->pool, pa_req->filename, pa_req->path_info,
441 NULL);
442#ifdef WIN32
443 /* We need to make this a real Windows path name */
445#endif
446 apr_table_setn(e, "PATH_TRANSLATED", pt);
447 }
449 }
450}
451
452
453static int set_cookie_doo_doo(void *v, const char *key, const char *val)
454{
456 return 1;
457}
458
459#define HTTP_UNSET (-HTTP_OK)
460#define SCRIPT_LOG_MARK __FILE__,__LINE__,module_index
461
463 int (*getsfunc) (char *, int, void *),
464 void *getsfunc_data,
465 int module_index)
466{
467 char x[MAX_STRING_LEN];
468 char *w, *l;
469 int p;
471 apr_table_t *merge;
473 int trace_log = APLOG_R_MODULE_IS_LEVEL(r, module_index, APLOG_TRACE1);
474 int first_header = 1;
475
476 if (buffer) {
477 *buffer = '\0';
478 }
479 w = buffer ? buffer : x;
480
481 /* temporary place to hold headers to merge in later */
482 merge = apr_table_make(r->pool, 10);
483
484 /* The HTTP specification says that it is legal to merge duplicate
485 * headers into one. Some browsers that support Cookies don't like
486 * merged headers and prefer that each Set-Cookie header is sent
487 * separately. Lets humour those browsers by not merging.
488 * Oh what a pain it is.
489 */
492
493 while (1) {
494
495 int rv = (*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data);
496 if (rv == 0) {
497 const char *msg = "Premature end of script headers";
498 if (first_header)
499 msg = "End of script output before headers";
500 /* Intentional no APLOGNO */
502 "%s: %s", msg,
505 }
506 else if (rv == -1) {
507 /* Intentional no APLOGNO */
509 "Script timed out before returning headers: %s",
512 }
513
514 /* Delete terminal (CR?)LF */
515
516 p = strlen(w);
517 /* Indeed, the host's '\n':
518 '\012' for UNIX; '\015' for MacOS; '\025' for OS/390
519 -- whatever the script generates.
520 */
521 if (p > 0 && w[p - 1] == '\n') {
522 if (p > 1 && w[p - 2] == CR) {
523 w[p - 2] = '\0';
524 }
525 else {
526 w[p - 1] = '\0';
527 }
528 }
529
530 /*
531 * If we've finished reading the headers, check to make sure any
532 * HTTP/1.1 conditions are met. If so, we're done; normal processing
533 * will handle the script's output. If not, just return the error.
534 * The appropriate thing to do would be to send the script process a
535 * SIGPIPE to let it know we're ignoring it, close the channel to the
536 * script process, and *then* return the failed-to-meet-condition
537 * error. Otherwise we'd be waiting for the script to finish
538 * blithering before telling the client the output was no good.
539 * However, we don't have the information to do that, so we have to
540 * leave it to an upper layer.
541 */
542 if (w[0] == '\0') {
543 int cond_status = OK;
544
545 /* PR#38070: This fails because it gets confused when a
546 * CGI Status header overrides ap_meets_conditions.
547 *
548 * We can fix that by dropping ap_meets_conditions when
549 * Status has been set. Since this is the only place
550 * cgi_status gets used, let's test it explicitly.
551 *
552 * The alternative would be to ignore CGI Status when
553 * ap_meets_conditions returns anything interesting.
554 * That would be safer wrt HTTP, but would break CGI.
555 */
556 if ((cgi_status == HTTP_UNSET) && (r->method_number == M_GET)) {
558 }
562 /* the cookies have already been copied to the cookie_table */
563 apr_table_unset(r->err_headers_out, "Set-Cookie");
566 }
567 return cond_status;
568 }
569
570 if (trace_log) {
571 if (first_header)
573 "Headers from script '%s':",
576 }
577
578 /* if we see a bogus header don't ignore it. Shout and scream */
579
580#if APR_CHARSET_EBCDIC
581 /* Chances are that we received an ASCII header text instead of
582 * the expected EBCDIC header lines. Try to auto-detect:
583 */
584 if (!(l = strchr(w, ':'))) {
585 int maybeASCII = 0, maybeEBCDIC = 0;
586 unsigned char *cp, native;
588
589 for (cp = w; *cp != '\0'; ++cp) {
591 if (apr_isprint(*cp) && !apr_isprint(native))
592 ++maybeEBCDIC;
593 if (!apr_isprint(*cp) && apr_isprint(native))
594 ++maybeASCII;
595 }
596 if (maybeASCII > maybeEBCDIC) {
598 APLOGNO(02660) "CGI Interface Error: "
599 "Script headers apparently ASCII: (CGI = %s)",
600 r->filename);
601 inbytes_left = outbytes_left = cp - w;
603 w, &inbytes_left, w, &outbytes_left);
604 }
605 }
606#endif /*APR_CHARSET_EBCDIC*/
607 if (!(l = strchr(w, ':'))) {
608 if (!buffer) {
609 /* Soak up all the script output - may save an outright kill */
610 while ((*getsfunc)(w, MAX_STRING_LEN - 1, getsfunc_data) > 0) {
611 continue;
612 }
613 }
614
615 /* Intentional no APLOGNO */
617 "malformed header from script '%s': Bad header: %.30s",
620 }
621
622 *l++ = '\0';
623 while (apr_isspace(*l)) {
624 ++l;
625 }
626
627 if (!ap_cstr_casecmp(w, "Content-type")) {
628 char *tmp;
629
630 /* Nuke trailing whitespace */
631
632 char *endp = l + strlen(l) - 1;
633 while (endp > l && apr_isspace(*endp)) {
634 *endp-- = '\0';
635 }
636
637 tmp = apr_pstrdup(r->pool, l);
640 }
641 /*
642 * If the script returned a specific status, that's what
643 * we'll use - otherwise we assume 200 OK.
644 */
645 else if (!ap_cstr_casecmp(w, "Status")) {
646 r->status = cgi_status = atoi(l);
648 /* Intentional no APLOGNO */
650 "Invalid status line from script '%s': %.30s",
652 else
653 if (APLOGrtrace1(r))
655 "Status line from script '%s': %.30s",
658 }
659 else if (!ap_cstr_casecmp(w, "Location")) {
661 }
662 else if (!ap_cstr_casecmp(w, "Content-Length")) {
664 }
665 else if (!ap_cstr_casecmp(w, "Content-Range")) {
667 }
668 else if (!ap_cstr_casecmp(w, "Transfer-Encoding")) {
670 }
671 else if (!ap_cstr_casecmp(w, "ETag")) {
673 }
674 /*
675 * If the script gave us a Last-Modified header, we can't just
676 * pass it on blindly because of restrictions on future or invalid values.
677 */
678 else if (!ap_cstr_casecmp(w, "Last-Modified")) {
680 if (parsed_date != APR_DATE_BAD) {
683 if (APLOGrtrace1(r)) {
685 "Last-Modified"));
686 /*
687 * A Last-Modified header value coming from a (F)CGI source
688 * is considered HTTP input so we assume the GMT timezone.
689 * The following logs should inform the admin about violations
690 * and related actions taken by httpd.
691 * The apr_date_parse_rfc function is 'timezone aware'
692 * and it will be used to generate a more informative set of logs
693 * (we don't use it as a replacement of apr_date_parse_http
694 * for the aforementioned reason).
695 */
697
698 /*
699 * The parsed Last-Modified header datestring has been replaced by httpd.
700 */
703 "The Last-Modified header value %s (%s) "
704 "has been replaced with '%s'", l,
705 parsed_date != parsed_date_tz_aware ? "not in GMT"
706 : "in the future",
707 apr_table_get(r->headers_out, "Last-Modified"));
708 /*
709 * Last-Modified header datestring not in GMT and not considered in the future
710 * by httpd (like now() + 1 hour in the PST timezone). No action is taken but
711 * the admin is warned about the violation.
712 */
713 } else if (parsed_date != parsed_date_tz_aware) {
715 "The Last-Modified header value is not set "
716 "within the GMT timezone (as required)");
717 }
718 }
719 }
720 else {
722 "Ignored invalid header value: Last-Modified: '%s'", l);
723 }
724 }
725 else if (!ap_cstr_casecmp(w, "Set-Cookie")) {
727 }
728 else {
729 apr_table_add(merge, w, l);
730 }
731 first_header = 0;
732 }
733 /* never reached - we leave this function within the while loop above */
734 return OK;
735}
736
745
746static int getsfunc_FILE(char *buf, int len, void *f)
747{
748 return apr_file_gets(buf, len, (apr_file_t *) f) == APR_SUCCESS;
749}
750
757
759 char *buffer, int module_index)
760{
762 module_index);
763}
764
765
766static int getsfunc_BRIGADE(char *buf, int len, void *arg)
767{
769 const char *dst_end = buf + len - 1; /* leave room for terminating null */
770 char *dst = buf;
772 apr_status_t rv;
773 int done = 0;
774
775 while ((dst < dst_end) && !done && e != APR_BRIGADE_SENTINEL(bb)
776 && !APR_BUCKET_IS_EOS(e)) {
777 const char *bucket_data;
779 const char *src;
780 const char *src_end;
781 apr_bucket * next;
782
785 if (rv != APR_SUCCESS || (bucket_data_len == 0)) {
786 *dst = '\0';
787 return APR_STATUS_IS_TIMEUP(rv) ? -1 : 0;
788 }
791 while ((src < src_end) && (dst < dst_end) && !done) {
792 if (*src == '\n') {
793 done = 1;
794 }
795 else if (*src != '\r') {
796 *dst++ = *src;
797 }
798 src++;
799 }
800
801 if (src < src_end) {
803 }
804 next = APR_BUCKET_NEXT(e);
806 e = next;
807 }
808 *dst = 0;
809 return done;
810}
811
819
822 char *buffer,
823 int module_index)
824{
826 module_index);
827}
828
829
830struct vastrs {
832 int arg;
833 const char *curpos;
834};
835
836static int getsfunc_STRING(char *w, int len, void *pvastrs)
837{
838 struct vastrs *strs = (struct vastrs*) pvastrs;
839 const char *p;
840 int t;
841
842 if (!strs->curpos || !*strs->curpos) {
843 w[0] = '\0';
844 return 0;
845 }
846 p = ap_strchr_c(strs->curpos, '\n');
847 if (p)
848 ++p;
849 else
850 p = ap_strchr_c(strs->curpos, '\0');
851 t = p - strs->curpos;
852 if (t > len)
853 t = len;
854 strncpy (w, strs->curpos, t);
855 w[t] = '\0';
856 if (!strs->curpos[t]) {
857 ++strs->arg;
858 strs->curpos = va_arg(strs->args, const char *);
859 }
860 else
861 strs->curpos += t;
862 return t;
863}
864
865/* ap_scan_script_header_err_strs() accepts additional const char* args...
866 * each is treated as one or more header lines, and the first non-header
867 * character is returned to **arg, **data. (The first optional arg is
868 * counted as 0.)
869 */
871 char *buffer,
872 int module_index,
873 const char **termch,
874 int *termarg, ...)
875{
876 struct vastrs strs;
877 int res;
878
879 va_start(strs.args, termarg);
880 strs.arg = 0;
881 strs.curpos = va_arg(strs.args, char*);
883 (void *) &strs, module_index);
884 if (termch)
885 *termch = strs.curpos;
886 if (termarg)
887 *termarg = strs.arg;
888 va_end(strs.args);
889 return res;
890}
891
893 char *buffer,
894 const char **termch,
895 int *termarg, ...)
896{
897 struct vastrs strs;
898 int res;
899
900 va_start(strs.args, termarg);
901 strs.arg = 0;
902 strs.curpos = va_arg(strs.args, char*);
904 (void *) &strs, APLOG_MODULE_INDEX);
905 if (termch)
906 *termch = strs.curpos;
907 if (termarg)
908 *termarg = strs.arg;
909 va_end(strs.args);
910 return res;
911}
912
913static void
915{
916 char *key;
917 char *value;
918 char *strtok_state;
919
920 if (str == NULL) {
921 return;
922 }
923
924 key = apr_strtok(str, "&", &strtok_state);
925 while (key) {
926 value = strchr(key, '=');
927 if (value) {
928 *value = '\0'; /* Split the string in two */
929 value++; /* Skip passed the = */
930 }
931 else {
932 value = "1";
933 }
938 }
939}
940
942{
945 *table = t;
946}
Symbol export macros and hook functions.
#define AP_DECLARE_NONSTD(type)
Definition ap_config.h:77
#define AP_DECLARE(type)
Definition ap_config.h:67
const char apr_size_t len
Definition ap_regex.h:187
APR-UTIL date routines.
APR general purpose library routines.
APR Strings library.
APR Standard Headers Support.
request_rec * r
#define ap_http_scheme(r)
Definition httpd.h:297
#define MAX_STRING_LEN
Definition httpd.h:300
#define DEFAULT_PATH
Definition httpd.h:151
#define OK
Definition httpd.h:456
const char * ap_get_server_banner(void)
Definition core.c:3593
apr_port_t ap_get_server_port(const request_rec *r)
Definition core.c:1199
#define ap_get_core_module_config(v)
Definition http_core.h:383
const char * ap_document_root(request_rec *r)
Definition core.c:829
const char * ap_get_remote_logname(request_rec *r)
Definition core.c:1121
#define AP_CORE_CONFIG_ON
Definition http_core.h:505
const char * ap_get_server_name_for_url(request_rec *r)
Definition core.c:1187
#define APLOGNO(n)
Definition http_log.h:117
#define APLOG_TRACE4
Definition http_log.h:75
#define APLOG_INFO
Definition http_log.h:70
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_R_MODULE_IS_LEVEL(r, module_index, level)
Definition http_log.h:195
#define APLOG_ERR
Definition http_log.h:67
#define APLOG_TOCLIENT
Definition http_log.h:102
#define ap_log_error
Definition http_log.h:370
#define APLOG_MARK
Definition http_log.h:283
#define APLOGrtrace1(r)
Definition http_log.h:246
#define APLOG_TRACE1
Definition http_log.h:72
const unsigned char * buf
Definition util_md5.h:50
int ap_meets_conditions(request_rec *r)
void ap_set_last_modified(request_rec *r)
Definition protocol.c:2280
void ap_set_content_type(request_rec *r, const char *ct)
request_rec * ap_sub_req_lookup_uri(const char *new_uri, const request_rec *r, ap_filter_t *next_filter)
Definition request.c:2297
void ap_destroy_sub_req(request_rec *r)
Definition request.c:2547
void ap_update_mtime(request_rec *r, apr_time_t dependency_mtime)
Definition request.c:2557
void ap_add_common_vars(request_rec *r)
int ap_scan_script_header_err_brigade_ex(request_rec *r, apr_bucket_brigade *bb, char *buffer, int module_index)
int ap_find_path_info(const char *uri, const char *path_info)
char ** ap_create_environment(apr_pool_t *p, apr_table_t *t)
void ap_add_cgi_vars(request_rec *r)
int ap_scan_script_header_err_ex(request_rec *r, apr_file_t *f, char *buffer, int module_index)
int ap_scan_script_header_err_brigade(request_rec *r, apr_bucket_brigade *bb, char *buffer)
int ap_scan_script_header_err_core_ex(request_rec *r, char *buffer, int(*getsfunc)(char *, int, void *), void *getsfunc_data, int module_index)
int ap_scan_script_header_err_core(request_rec *r, char *buffer, int(*getsfunc)(char *, int, void *), void *getsfunc_data)
int ap_scan_script_header_err(request_rec *r, apr_file_t *f, char *buffer)
int ap_scan_script_header_err_strs_ex(request_rec *r, char *buffer, int module_index, const char **termch, int *termarg,...)
void ap_args_to_table(request_rec *r, apr_table_t **table)
int ap_scan_script_header_err_strs(request_rec *r, char *buffer, const char **termch, int *termarg,...)
void const char * arg
Definition http_vhost.h:63
#define CR
Definition httpd.h:722
#define APR_STATUS_IS_TIMEUP(s)
Definition apr_errno.h:534
apr_file_t * f
#define apr_bucket_split(e, point)
#define APR_BUCKET_NEXT(e)
apr_bucket * e
#define APR_BRIGADE_SENTINEL(b)
#define apr_bucket_delete(e)
#define APR_BUCKET_IS_EOS(e)
#define APR_BRIGADE_FIRST(b)
#define apr_bucket_read(e, str, len, block)
@ APR_BLOCK_READ
Definition apr_buckets.h:58
apr_pool_t apr_dbd_t apr_dbd_results_t ** res
Definition apr_dbd.h:287
#define APR_DATE_BAD
Definition apr_date.h:43
const char * src
Definition apr_encode.h:167
const char * uri
Definition apr_uri.h:159
const char apr_size_t * inbytes_left
Definition apr_xlate.h:119
const char apr_size_t char apr_size_t * outbytes_left
Definition apr_xlate.h:121
#define ap_is_HTTP_VALID_RESPONSE(x)
Definition httpd.h:560
#define HTTP_INTERNAL_SERVER_ERROR
Definition httpd.h:535
#define HTTP_GATEWAY_TIME_OUT
Definition httpd.h:539
#define M_GET
Definition httpd.h:592
#define ap_strchr(s, c)
Definition httpd.h:2351
int ap_cstr_casecmp(const char *s1, const char *s2)
Definition util.c:3542
const char * ap_psignature(const char *prefix, request_rec *r)
Definition core.c:3516
char * ap_escape_logitem(apr_pool_t *p, const char *str)
Definition util.c:2183
#define ap_escape_uri(ppool, path)
Definition httpd.h:1836
#define ap_strchr_c(s, c)
Definition httpd.h:2353
const char * ap_context_prefix(request_rec *r)
Definition core.c:839
const char * ap_context_document_root(request_rec *r)
Definition core.c:848
void ap_content_type_tolower(char *s)
Definition util.c:2505
#define ap_escape_html(p, s)
Definition httpd.h:1860
int ap_unescape_url(char *url)
Definition util.c:1939
apr_size_t size
apr_uint32_t val
Definition apr_atomic.h:66
#define apr_isprint(c)
Definition apr_lib.h:221
#define apr_isspace(c)
Definition apr_lib.h:225
#define apr_isalnum(c)
Definition apr_lib.h:203
#define apr_toupper(c)
Definition apr_lib.h:233
#define apr_isdigit(c)
Definition apr_lib.h:209
const char * value
Definition apr_env.h:51
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
const char * key
char * buffer
#define APR_FILEPATH_NATIVE
#define APR_HASH_KEY_STRING
Definition apr_hash.h:47
apr_vformatter_buff_t * c
Definition apr_lib.h:175
char const *const char const *const ** env
apr_interval_time_t t
apr_uint16_t apr_port_t
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
const char char ** last
const char * s
Definition apr_strings.h:95
#define APR_OVERLAP_TABLES_MERGE
Definition apr_tables.h:439
#define APR_OVERLAP_TABLES_SET
Definition apr_tables.h:437
const apr_array_header_t * first
Definition apr_tables.h:207
apr_int64_t apr_time_t
Definition apr_time.h:45
const char * ap_get_useragent_host(request_rec *req, int type, int *str_is_ip)
Definition core.c:1036
#define REMOTE_HOST
Definition http_core.h:100
Apache Configuration.
CORE HTTP Daemon.
#define AP_CGI_PASS_AUTH_ON
Definition http_core.h:671
Apache Logging library.
Command line options.
HTTP protocol handling.
Apache Request library.
HTTP Daemon routines.
apr_pool_t * p
Definition md_event.c:32
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
char * name
Definition apr_tables.h:81
char * scheme
Definition apr_uri.h:87
Structure to store things which are per connection.
Definition httpd.h:1152
char * local_ip
Definition httpd.h:1181
Per-directory configuration.
Definition http_core.h:527
apr_hash_t * cgi_var_rules
Definition http_core.h:683
unsigned int qualify_redirect_url
Definition http_core.h:679
unsigned int cgi_pass_auth
Definition http_core.h:678
A structure that represents the current request.
Definition httpd.h:845
char * user
Definition httpd.h:1005
int status
Definition httpd.h:891
char * uri
Definition httpd.h:1016
char * useragent_ip
Definition httpd.h:1101
request_rec * prev
Definition httpd.h:856
apr_table_t * notes
Definition httpd.h:985
char * the_request
Definition httpd.h:866
int method_number
Definition httpd.h:898
apr_pool_t * pool
Definition httpd.h:847
char * filename
Definition httpd.h:1018
apr_uri_t parsed_uri
Definition httpd.h:1092
conn_rec * connection
Definition httpd.h:849
apr_table_t * err_headers_out
Definition httpd.h:981
apr_table_t * headers_in
Definition httpd.h:976
char * protocol
Definition httpd.h:879
apr_table_t * subprocess_env
Definition httpd.h:983
server_rec * server
Definition httpd.h:851
struct ap_conf_vector_t * per_dir_config
Definition httpd.h:1047
const char * status_line
Definition httpd.h:889
const char * method
Definition httpd.h:900
char * path_info
Definition httpd.h:1024
char * args
Definition httpd.h:1026
char * ap_auth_type
Definition httpd.h:1007
apr_table_t * headers_out
Definition httpd.h:978
A structure to store information for each virtual server.
Definition httpd.h:1322
const char * curpos
va_list args
Utilities for EBCDIC conversion.
#define str
static void add_unless_null(apr_table_t *table, const char *name, const char *val)
Definition util_script.c:88
static char * http2env(request_rec *r, const char *w)
Definition util_script.c:56
static void argstr_to_table(char *str, apr_table_t *parms)
static int getsfunc_FILE(char *buf, int len, void *f)
static char * original_uri(request_rec *r)
static void env2env(apr_table_t *dest, request_rec *r, const char *name, const char *fallback)
Definition util_script.c:98
#define SCRIPT_LOG_MARK
static int getsfunc_STRING(char *w, int len, void *pvastrs)
static int getsfunc_BRIGADE(char *buf, int len, void *arg)
#define APLOG_MODULE_INDEX
Definition util_script.c:54
static int set_cookie_doo_doo(void *v, const char *key, const char *val)
#define HTTP_UNSET
Apache script tools.