util_script.c revision 2b13bc45632d72cdf50ac42149e4fc8bc0d05bf2
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele/* ====================================================================
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * The Apache Software License, Version 1.1
5f5d1b4cc970b7f06ff8ef6526128e9a27303d88nd * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * Redistribution and use in source and binary forms, with or without
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * modification, are permitted provided that the following conditions
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * 1. Redistributions of source code must retain the above copyright
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * notice, this list of conditions and the following disclaimer.
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * 2. Redistributions in binary form must reproduce the above copyright
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * notice, this list of conditions and the following disclaimer in
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * the documentation and/or other materials provided with the
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * distribution.
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * 3. The end-user documentation included with the redistribution,
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * if any, must include the following acknowledgment:
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * "This product includes software developed by the
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * Apache Software Foundation (http://www.apache.org/)."
7db9f691a00ead175b03335457ca296a33ddf31bnd * Alternately, this acknowledgment may appear in the software itself,
3577f1d38e53397f6b431c02011f875316b2f070nd * if and wherever such third-party acknowledgments normally appear.
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * 4. The names "Apache" and "Apache Software Foundation" must
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * not be used to endorse or promote products derived from this
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * software without prior written permission. For written
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * permission, please contact apache@apache.org.
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * 5. Products derived from this software may not be called "Apache",
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * nor may "Apache" appear in their name, without prior written
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * permission of the Apache Software Foundation.
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * SUCH DAMAGE.
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * ====================================================================
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * This software consists of voluntary contributions made by many
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * individuals on behalf of the Apache Software Foundation. For more
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * information on the Apache Software Foundation, please see
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * Portions of this software are based upon public domain software
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive * originally written at the National Center for Supercomputing Applications,
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive * University of Illinois, Urbana-Champaign.
d7604f90897d9b08b227c127ff5392393178911crpluem * Various utility functions which are common to a whole lot of
d7604f90897d9b08b227c127ff5392393178911crpluem * script-type extensions mechanisms, and might as well be gathered
d7604f90897d9b08b227c127ff5392393178911crpluem * in one place (if only to avoid creating inter-module dependancies
d7604f90897d9b08b227c127ff5392393178911crpluem * where there don't have to be).
c6f41bc69d643835804e7e831776d3d46c6f5962slive#define MALFORMED_MESSAGE "malformed header from script. Bad header="
c6f41bc69d643835804e7e831776d3d46c6f5962slive char *res = (char *)apr_palloc(a, sizeof("HTTP_") + strlen(w));
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive while ((c = *w++) != 0) {
67f57b90aea98fc792b6c6e67bd27ee35f7d026bigalicAP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t)
67f57b90aea98fc792b6c6e67bd27ee35f7d026bigalic const apr_array_header_t *env_arr = apr_table_elts(t);
67f57b90aea98fc792b6c6e67bd27ee35f7d026bigalic const apr_table_entry_t *elts = (const apr_table_entry_t *) env_arr->elts;
67f57b90aea98fc792b6c6e67bd27ee35f7d026bigalic char **env = (char **) apr_palloc(p, (env_arr->nelts + 2) * sizeof(char *));
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun env[j] = apr_pstrcat(p, elts[i].key, "=", elts[i].val, NULL);
4ab980a06412fd86f52a6d054fb7e26de155c530erikabeleAP_DECLARE(void) ap_add_common_vars(request_rec *r)
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele#if defined(WIN32) || defined(OS2) || defined(BEOS)
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele const char *host;
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele const apr_array_header_t *hdrs_arr = apr_table_elts(r->headers_in);
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele const apr_table_entry_t *hdrs = (const apr_table_entry_t *) hdrs_arr->elts;
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele /* use a temporary apr_table_t which we'll overlap onto
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * r->subprocess_env later
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * (exception: if r->subprocess_env is empty at the start,
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * write directly into it)
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele /* First, add environment vars from headers... this is as per
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * CGI specs, though other sorts of scripting interfaces see
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * the same vars...
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun /* A few headers are special cased --- Authorization to prevent
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * rogue scripts from capturing passwords; content-type and -length
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * for no particular reason.
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun else if (!strcasecmp(hdrs[i].key, "Content-length")) {
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * You really don't want to disable this check, since it leaves you
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * wide open to CGIs stealing passwords and people viewing them
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * in the environment with "ps -e". But, if you must...
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun || !strcasecmp(hdrs[i].key, "Proxy-Authorization")) {
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun apr_table_addn(e, http2env(r->pool, hdrs[i].key), hdrs[i].val);
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_path));
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele if ((env_temp = getenv("LIBRARY_PATH")) != NULL) {
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele apr_table_addn(e, "SERVER_SOFTWARE", ap_get_server_version());
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun apr_table_addn(e, "SERVER_NAME", ap_get_server_name(r));
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele apr_table_addn(e, "SERVER_ADDR", r->connection->local_ip); /* Apache */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele apr_psprintf(r->pool, "%u", ap_get_server_port(r)));
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST, NULL);
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun apr_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r)); /* Apache */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele apr_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele apr_table_addn(e, "REMOTE_PORT", apr_itoa(r->pool, rport));
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun apr_table_addn(e, "REMOTE_IDENT", apr_pstrdup(r->pool, rem_logname));
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun /* Apache custom error responses. If we have redirected set two new vars */
df321386f1d9ed17a3e5e6468807996a12890d50gryzor apr_table_addn(e, "REDIRECT_QUERY_STRING", r->prev->args);
df321386f1d9ed17a3e5e6468807996a12890d50gryzor if (e != r->subprocess_env) {
df321386f1d9ed17a3e5e6468807996a12890d50gryzor apr_table_overlap(r->subprocess_env, e, APR_OVERLAP_TABLES_SET);
df321386f1d9ed17a3e5e6468807996a12890d50gryzor/* This "cute" little function comes about because the path info on
df321386f1d9ed17a3e5e6468807996a12890d50gryzor * filenames and URLs aren't always the same. So we take the two,
df321386f1d9ed17a3e5e6468807996a12890d50gryzor * and find as much of the two that match as possible.
df321386f1d9ed17a3e5e6468807996a12890d50gryzorAP_DECLARE(int) ap_find_path_info(const char *uri, const char *path_info)
b3c1e4e5b0fc67887a85bc388c16949a21e66f51humbedooh/* Obtain the Request-URI from the original request-line, returning
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * a new string from the request pool containing the URI or "".
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele return apr_pstrmemdup(r->pool, first, last - first);
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele apr_table_setn(e, "QUERY_STRING", r->args ? r->args : "");
188629185b3dcdb7856d000373166e3f0b131187humbedooh /* Note that the code below special-cases scripts run from includes,
8c2f1f25121a96f35a3b95912fdd85586513c80ehumbedooh * because it "knows" that the sub_request has been hacked to have the
188629185b3dcdb7856d000373166e3f0b131187humbedooh * args and path_info of the original request, and not any that may have
188629185b3dcdb7856d000373166e3f0b131187humbedooh * come with the script URI in the include command. Ugh.
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun int path_info_start = ap_find_path_info(r->uri, r->path_info);
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * To get PATH_TRANSLATED, treat PATH_INFO as a URI path.
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * Need to re-escape it for this, since the entire URI was
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * un-escaped before we determined where the PATH_INFO began.
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun pa_req = ap_sub_req_lookup_uri(ap_escape_uri(r->pool, r->path_info), r,
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun char *pt = apr_pstrcat(r->pool, pa_req->filename, pa_req->path_info,
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele /* We need to make this a real Windows path name */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele apr_filepath_merge(&pt, "", pt, APR_FILEPATH_NATIVE, r->pool);
4ab980a06412fd86f52a6d054fb7e26de155c530erikabelestatic int set_cookie_doo_doo(void *v, const char *key, const char *val)
ad93f15b0bef55041347cdbad447d94296eb89f2nilgunAP_DECLARE(int) ap_scan_script_header_err_core(request_rec *r, char *buffer,
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele int (*getsfunc) (char *, int, void *),
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun char *w, *l;
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun /* temporary place to hold headers to merge in later */
bd43fc31993cfc191e744a9490481f4294894099covener /* The HTTP specification says that it is legal to merge duplicate
bd43fc31993cfc191e744a9490481f4294894099covener * headers into one. Some browsers that support Cookies don't like
bd43fc31993cfc191e744a9490481f4294894099covener * merged headers and prefer that each Set-Cookie header is sent
bd43fc31993cfc191e744a9490481f4294894099covener * separately. Lets humour those browsers by not merging.
bd43fc31993cfc191e744a9490481f4294894099covener * Oh what a pain it is.
bd43fc31993cfc191e744a9490481f4294894099covener apr_table_do(set_cookie_doo_doo, cookie_table, r->err_headers_out, "Set-Cookie", NULL);
bd43fc31993cfc191e744a9490481f4294894099covener while (1) {
bd43fc31993cfc191e744a9490481f4294894099covener if ((*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data) == 0) {
bd43fc31993cfc191e744a9490481f4294894099covener ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR|APLOG_TOCLIENT, 0, r,
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele "Premature end of script headers: %s",
return HTTP_INTERNAL_SERVER_ERROR;
p = strlen(w);
return cond_status;
++maybeEBCDIC;
++maybeASCII;
r->filename);
if (!buffer) {
return HTTP_INTERNAL_SERVER_ERROR;
while (*l && apr_isspace(*l)) {
char *tmp;
return OK;
char *buffer)
int done = 0;
const char *bucket_data;
const char *src;
const char *src_end;
src++;
e = next;
*dst = 0;
char *buffer)
struct vastrs {
int arg;
const char *curpos;
if (t > len)
t = len;
char *buffer,
const char **termch,
int *termarg, ...)
int res;
if (termch)
if (termarg)
return res;