home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 8 / CDACTUAL8.iso / share / os2 / varios / apache / util_scr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-03  |  11.1 KB  |  365 lines

  1.  
  2. /* ====================================================================
  3.  * Copyright (c) 1995 The Apache Group.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer. 
  11.  *
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in
  14.  *    the documentation and/or other materials provided with the
  15.  *    distribution.
  16.  *
  17.  * 3. All advertising materials mentioning features or use of this
  18.  *    software must display the following acknowledgment:
  19.  *    "This product includes software developed by the Apache Group
  20.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  21.  *
  22.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  23.  *    endorse or promote products derived from this software without
  24.  *    prior written permission.
  25.  *
  26.  * 5. Redistributions of any form whatsoever must retain the following
  27.  *    acknowledgment:
  28.  *    "This product includes software developed by the Apache Group
  29.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  30.  *
  31.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  32.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  34.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  35.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  36.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  37.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  42.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  43.  * ====================================================================
  44.  *
  45.  * This software consists of voluntary contributions made by many
  46.  * individuals on behalf of the Apache Group and was originally based
  47.  * on public domain software written at the National Center for
  48.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  49.  * For more information on the Apache Group and the Apache HTTP server
  50.  * project, please see <http://www.apache.org/>.
  51.  *
  52.  */
  53.  
  54.  
  55.  
  56. #include "httpd.h"
  57. #include "http_main.h"
  58. #include "http_log.h"
  59. #include "http_protocol.h"
  60. #include "http_core.h"        /* For document_root.  Sigh... */
  61. #include "http_request.h"       /* for sub_req_lookup_uri() */
  62. #include "util_script.h"
  63.  
  64. /*
  65.  * Various utility functions which are common to a whole lot of
  66.  * script-type extensions mechanisms, and might as well be gathered
  67.  * in one place (if only to avoid creating inter-module dependancies
  68.  * where there don't have to be).
  69.  */
  70.  
  71. #define MALFORMED_MESSAGE "malformed header from script. Bad header="
  72. #define MALFORMED_HEADER_LENGTH_TO_SHOW 30
  73.  
  74. char **create_argv(pool *p, char *av0, char *args) {
  75.     register int x,n;
  76.     char **av;
  77.     char *w;
  78.  
  79.     for(x=0,n=2;args[x];x++)
  80.         if(args[x] == '+') ++n;
  81.  
  82.     av = (char **)palloc(p, (n+1)*sizeof(char *));
  83.     av[0] = av0;
  84.  
  85.     for(x=1;x<n;x++) {
  86.         w = getword_nulls(p, &args, '+');
  87.         unescape_url(w);
  88.         av[x] = escape_shell_cmd(p, w);
  89.     }
  90.     av[n] = NULL;
  91.     return av;
  92. }
  93.  
  94. static char *http2env(pool *a, char *w)
  95. {
  96.     char *res = pstrcat (a, "HTTP_", w, NULL);
  97.     char *cp = res;
  98.   
  99.     while (*++cp)
  100.       if (*cp == '-') *cp = '_';
  101.       else *cp = toupper(*cp);
  102.  
  103.     return res;
  104. }
  105.  
  106. char **create_environment(pool *p, table *t)
  107. {
  108.     array_header *env_arr = table_elts (t);
  109.     table_entry *elts = (table_entry *)env_arr->elts;
  110.     char **env = (char **)palloc (p, (env_arr->nelts + 2) *sizeof (char *));
  111.     int i, j;
  112.     char *tz;
  113.  
  114.     j = 0;
  115.     tz = getenv("TZ");
  116.     if (tz!= NULL) env[j++] = pstrcat(p, "TZ=", tz, NULL);
  117.     for (i = 0; i < env_arr->nelts; ++i) {
  118.         if (!elts[i].key) continue;
  119.     env[j++] = pstrcat (p, elts[i].key, "=", elts[i].val, NULL);
  120.     }
  121.  
  122.     env[j] = NULL;
  123.     return env;
  124. }
  125.  
  126. void add_common_vars(request_rec *r)
  127. {
  128.     table *e = r->subprocess_env;
  129.     server_rec *s = r->server;
  130.     conn_rec *c = r->connection;
  131.     const char *rem_logname;
  132.     
  133.     char port[40],*env_path;
  134.     
  135.     array_header *hdrs_arr = table_elts (r->headers_in);
  136.     table_entry *hdrs = (table_entry *)hdrs_arr->elts;
  137.     int i;
  138.     
  139.     /* First, add environment vars from headers... this is as per
  140.      * CGI specs, though other sorts of scripting interfaces see
  141.      * the same vars...
  142.      */
  143.     
  144.     for (i = 0; i < hdrs_arr->nelts; ++i) {
  145.         if (!hdrs[i].key) continue;
  146.  
  147.     /* A few headers are special cased --- Authorization to prevent
  148.      * rogue scripts from capturing passwords; content-type and -length
  149.      * for no particular reason.
  150.      */
  151.     
  152.     if (!strcasecmp (hdrs[i].key, "Content-type")) 
  153.         table_set (e, "CONTENT_TYPE", hdrs[i].val);
  154.     else if (!strcasecmp (hdrs[i].key, "Content-length"))
  155.         table_set (e, "CONTENT_LENGTH", hdrs[i].val);
  156.     else if (!strcasecmp (hdrs[i].key, "Authorization"))
  157.         continue;
  158.     else
  159.         table_set (e, http2env (r->pool, hdrs[i].key), hdrs[i].val);
  160.     }
  161.     
  162.     sprintf(port, "%d", s->port);
  163.  
  164.     if(!(env_path = getenv("PATH")))
  165.         env_path=DEFAULT_PATH;
  166.     
  167.     table_set (e, "PATH", env_path);
  168.     table_set (e, "SERVER_SOFTWARE", SERVER_VERSION);
  169.     table_set (e, "SERVER_NAME", s->server_hostname);
  170.     table_set (e, "SERVER_PORT", port);
  171.     table_set (e, "REMOTE_HOST",
  172.            get_remote_host(c, r->per_dir_config, REMOTE_NAME));
  173.     table_set (e, "REMOTE_ADDR", c->remote_ip);
  174.     table_set (e, "DOCUMENT_ROOT", document_root(r)); /* Apache */
  175.     table_set (e, "SERVER_ADMIN", s->server_admin); /* Apache */
  176.     table_set (e, "SCRIPT_FILENAME", r->filename); /* Shambhala */
  177.     
  178.     if (c->user) table_set(e, "REMOTE_USER", c->user);
  179.     if (c->auth_type) table_set(e, "AUTH_TYPE", c->auth_type);
  180.     rem_logname = get_remote_logname(r);
  181.     if (rem_logname) table_set(e, "REMOTE_IDENT", rem_logname);
  182.     
  183.     /* Apache custom error responses. If we have redirected set two new vars */
  184.     
  185.     if (r->prev) {
  186.         if (r->prev->args) table_set(e,"REDIRECT_QUERY_STRING", r->prev->args);
  187.     if (r->prev->uri) table_set (e, "REDIRECT_URL", r->prev->uri);
  188.     }
  189. }
  190.  
  191.  
  192. void add_cgi_vars(request_rec *r)
  193. {
  194.     table *e = r->subprocess_env;
  195.  
  196.     table_set (e, "GATEWAY_INTERFACE","CGI/1.1");
  197.     table_set (e, "SERVER_PROTOCOL", r->protocol);
  198.     table_set (e, "REQUEST_METHOD", r->method);
  199.     table_set (e, "QUERY_STRING", r->args ? r->args : "");
  200.     
  201.     /* Note that the code below special-cases scripts run from includes,
  202.      * because it "knows" that the sub_request has been hacked to have the
  203.      * args and path_info of the original request, and not any that may have
  204.      * come with the script URI in the include command.  Ugh.
  205.      */
  206.     
  207.     if (!r->path_info || !*r->path_info || !strcmp (r->protocol, "INCLUDED")) {
  208.         table_set (e, "SCRIPT_NAME", r->uri);
  209.     } else {
  210.         int path_info_start = strlen (r->uri) - strlen (r->path_info);
  211.     
  212.     r->uri[path_info_start] = '\0';
  213.     table_set (e, "SCRIPT_NAME", r->uri);
  214.     r->uri[path_info_start] = '/';
  215.     }
  216.     
  217.     if (r->path_info && r->path_info[0]) {
  218.     /*
  219.       * To get PATH_TRANSLATED, treat PATH_INFO as a URI path.
  220.      * Need to re-escape it for this, since the entire URI was
  221.      * un-escaped before we determined where the PATH_INFO began.
  222.       */
  223.     request_rec *pa_req = sub_req_lookup_uri(
  224.                     escape_uri(r->pool, r->path_info), r);
  225.       
  226.         table_set (e, "PATH_INFO", r->path_info);
  227.  
  228.     /* Don't bother destroying pa_req --- it's only created in
  229.      * child processes which are about to jettison their address
  230.      * space anyway.  BTW, we concatenate filename and path_info
  231.      * from the sub_request to be compatible in case the PATH_INFO
  232.      * is pointing to an object which doesn't exist.
  233.      */
  234.     
  235.     if (pa_req->filename)
  236.         table_set (e, "PATH_TRANSLATED",
  237.                pstrcat (r->pool, pa_req->filename, pa_req->path_info,
  238.                 NULL));
  239.     }
  240. }
  241.  
  242. int scan_script_header(request_rec *r, FILE *f)
  243. {
  244.     char w[MAX_STRING_LEN];
  245.     char *l;
  246.     int p;
  247.  
  248.     hard_timeout ("read script header", r);
  249.     
  250.     while(1) {
  251.  
  252.     if (fgets(w, MAX_STRING_LEN-1, f) == NULL) {
  253.         log_reason ("Premature end of script headers", r->filename, r);
  254.         return SERVER_ERROR;
  255.         }
  256.  
  257.     /* Delete terminal (CR?)LF */
  258.     
  259.     p = strlen(w);
  260.     if (p > 0 && w[p-1] == '\n')
  261.     {
  262.         if (p > 1 && w[p-2] == '\015') w[p-2] = '\0';
  263.         else w[p-1] = '\0';
  264.     }
  265.  
  266.         if(w[0] == '\0') {
  267.         kill_timeout (r);
  268.         return OK;
  269.     }
  270.                                    
  271.     /* if we see a bogus header don't ignore it. Shout and scream */
  272.     
  273.         if(!(l = strchr(w,':'))) {
  274.         char malformed[(sizeof MALFORMED_MESSAGE)+1+MALFORMED_HEADER_LENGTH_TO_SHOW];
  275.             strcpy(malformed, MALFORMED_MESSAGE);
  276.             strncat(malformed, w, MALFORMED_HEADER_LENGTH_TO_SHOW);
  277.             /* Soak up all the script output --- may save an outright kill */
  278.         while (fgets(w, MAX_STRING_LEN-1, f) != NULL)
  279.             continue;
  280.         
  281.         kill_timeout (r);
  282.         log_reason (malformed, r->filename, r);
  283.         return SERVER_ERROR;
  284.         }
  285.  
  286.         *l++ = '\0';
  287.     while (*l && isspace (*l)) ++l;
  288.     
  289.         if(!strcasecmp(w,"Content-type")) {
  290.  
  291.         /* Nuke trailing whitespace */
  292.         
  293.         char *endp = l + strlen(l) - 1;
  294.         while (endp > l && isspace(*endp)) *endp-- = '\0';
  295.         
  296.         r->content_type = pstrdup (r->pool, l);
  297.     }
  298.         else if(!strcasecmp(w,"Status")) {
  299.             sscanf(l, "%d", &r->status);
  300.             r->status_line = pstrdup(r->pool, l);
  301.         }
  302.         else if(!strcasecmp(w,"Location")) {
  303.         table_set (r->headers_out, w, l);
  304.         }   
  305.  
  306. /* The HTTP specification says that it is legal to merge duplicate
  307.  * headers into one.  Some browsers that support Cookies don't like
  308.  * merged headers and prefer that each Set-Cookie header is sent
  309.  * separately.  Lets humour those browsers.
  310.  */
  311.     else if(!strcasecmp(w, "Set-Cookie")) {
  312.         table_add(r->err_headers_out, w, l);
  313.     }
  314.         else {
  315.         table_merge (r->err_headers_out, w, l);
  316.         }
  317.     }
  318. }
  319.  
  320. void send_size(size_t size, request_rec *r) {
  321.     char ss[20];
  322.  
  323.     if(size == -1) 
  324.         strcpy(ss, "    -");
  325.     else if(!size) 
  326.         strcpy(ss, "   0k");
  327.     else if(size < 1024) 
  328.         strcpy(ss, "   1k");
  329.     else if(size < 1048576)
  330.         sprintf(ss, "%4dk", size / 1024);
  331.     else
  332.         sprintf(ss, "%4dM", size / 1048576);
  333.     rputs(ss, r);
  334. }
  335.  
  336. #ifdef __EMX__
  337. char **create_argv_cmd(pool *p, char *av0, char *args, char *path) {
  338.     register int x,n;
  339.     char **av;
  340.     char *w;
  341.  
  342.     for(x=0,n=2;args[x];x++)
  343.         if(args[x] == '+') ++n;
  344.  
  345.     /* Add extra strings to array. */
  346.     n = n + 2;
  347.  
  348.     av = (char **)palloc(p, (n+1)*sizeof(char *));
  349.     av[0] = av0;
  350.  
  351.     /* Now insert the extra strings we made room for above. */
  352.     av[1] = strdup("/C");
  353.     av[2] = strdup(path);
  354.  
  355.     for(x=(1+2);x<n;x++) {
  356.         w = getword(p, &args, '+');
  357.         unescape_url(w);
  358.         av[x] = escape_shell_cmd(p, w);
  359.     }
  360.     av[n] = NULL;
  361.     return av;
  362. }
  363. #endif
  364.  
  365.