[BACK]Return to cgi-bozo.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / libexec / httpd

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/libexec/httpd/cgi-bozo.c between version 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2008/03/03 22:03:05 version 1.1.1.3, 2009/04/18 07:09:27
Line 1 
Line 1 
 /*      $eterna: cgi-bozo.c,v 1.18 2008/03/03 03:36:11 mrg Exp $        */  /*      $eterna: cgi-bozo.c,v 1.28 2009/04/18 05:36:04 mrg Exp $        */
   
 /*  /*
  * Copyright (c) 1997-2008 Matthew R. Green   * Copyright (c) 1997-2009 Matthew R. Green
  * All rights reserved.   * All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
Line 13 
Line 13 
  *    notice, this list of conditions and the following disclaimer and   *    notice, this list of conditions and the following disclaimer and
  *    dedication in the documentation and/or other materials provided   *    dedication in the documentation and/or other materials provided
  *    with the distribution.   *    with the distribution.
  * 3. The name of the author may not be used to endorse or promote products  
  *    derived from this software without specific prior written permission.  
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Line 58  static int Cflag;  /* added a cgi handle
Line 56  static int Cflag;  /* added a cgi handle
 static  const char *    content_cgihandler(http_req *, const char *);  static  const char *    content_cgihandler(http_req *, const char *);
 static  void            finish_cgi_output(http_req *request, int, int);  static  void            finish_cgi_output(http_req *request, int, int);
 static  int             parse_header(const char *, ssize_t, char **, char **);  static  int             parse_header(const char *, ssize_t, char **, char **);
   static  void            append_index_html(char **);
   
 void  void
 set_cgibin(char *path)  set_cgibin(char *path)
Line 82  spsetenv(const char *env, const char *va
Line 81  spsetenv(const char *env, const char *va
 /*  /*
  * Checks if the request has asked for a cgi-bin.  Should only be called if   * Checks if the request has asked for a cgi-bin.  Should only be called if
  * cgibin is set.  If it starts CGIBIN_PREFIX or has a ncontent handler,   * cgibin is set.  If it starts CGIBIN_PREFIX or has a ncontent handler,
  * process the cgi, otherwise just return.   * process the cgi, otherwise just return.  Returns 0 if it did not handle
    * the request.
  */   */
 void  int
 process_cgi(http_req *request)  process_cgi(http_req *request)
 {  {
         char    buf[WRSZ];          char    buf[WRSZ];
         struct  headers *headp;          struct  headers *headp;
         const char *type, *clen, *info, *cgihandler;          const char *type, *clen, *info, *cgihandler;
         char    *query, *s, *t, *path, *env, *command, *url;          char    *query, *s, *t, *path, *env, *command, *file, *url;
         char    **envp, **curenvp, *argv[4];          char    **envp, **curenvp, *argv[4];
         size_t  len;          size_t  len;
         ssize_t rbytes;          ssize_t rbytes;
Line 99  process_cgi(http_req *request)
Line 99  process_cgi(http_req *request)
         int     sv[2];          int     sv[2];
   
         if (!cgibin && !Cflag)          if (!cgibin && !Cflag)
                 return;                  return 0;
   
         debug((DEBUG_NORMAL, "process_cgi: url `%s'", request->hr_url));  
   
         url = bozostrdup(request->hr_url);          asprintf(&file, "/%s", request->hr_file);
         if ((s = strchr(url, '?')) != NULL) {          if (file == NULL)
                 *s++ = '\0';                  return 0;
                 query = s;          if (request->hr_query && strlen(request->hr_query))
         } else                  query = bozostrdup(request->hr_query);
           else
                 query = NULL;                  query = NULL;
   
           asprintf(&url, "%s%s%s", file, query ? "?" : "", query ? query : "");
           if (url == NULL)
                   goto out;
           debug((DEBUG_NORMAL, "process_cgi: url `%s'", url));
   
         path = NULL;          path = NULL;
         envp = NULL;          envp = NULL;
         cgihandler = NULL;          cgihandler = NULL;
Line 116  process_cgi(http_req *request)
Line 121  process_cgi(http_req *request)
         info = NULL;          info = NULL;
   
         len = strlen(url);          len = strlen(url);
         if (len == 0 || url[len - 1] == '/') {  /* append index.html */  
                 debug((DEBUG_FAT, "appending index.html"));  
                 url = bozorealloc(url, len + strlen(index_html) + 1);  
                 strcat(url, index_html);  
                 debug((DEBUG_NORMAL, "process_cgi: url adjusted to `%s'", url));  
         }  
   
         auth_check(request, url + 1);          if (auth_check(request, url + 1))
                   goto out;
   
         if (!cgibin || strncmp(url + 1, CGIBIN_PREFIX, CGIBIN_PREFIX_LEN) != 0) {          if (!cgibin || strncmp(url + 1, CGIBIN_PREFIX, CGIBIN_PREFIX_LEN) != 0) {
                 cgihandler = content_cgihandler(request, url + 1);                  cgihandler = content_cgihandler(request, file + 1);
                 if (cgihandler == NULL) {                  if (cgihandler == NULL) {
                         free(url);                          debug((DEBUG_FAT, "process_cgi: no handler, returning"));
                         return;                          goto out;
                 }                  }
                   if (len == 0 || file[len - 1] == '/')
                           append_index_html(&file);
                 debug((DEBUG_NORMAL, "process_cgi: cgihandler `%s'",                  debug((DEBUG_NORMAL, "process_cgi: cgihandler `%s'",
                     cgihandler));                      cgihandler));
         }          } else if (len - 1 == CGIBIN_PREFIX_LEN)        /* url is "/cgi-bin/" */
                   append_index_html(&file);
   
         ix = 0;          ix = 0;
         if (cgihandler) {          if (cgihandler) {
                 command = url + 1;                  command = file + 1;
                 path = bozostrdup(cgihandler);                  path = bozostrdup(cgihandler);
                 argv[ix++] = path;                  argv[ix++] = path;
                         /* argv[] = [ path, command, query, NULL ] */                          /* argv[] = [ path, command, query, NULL ] */
         } else {          } else {
                 command = url + CGIBIN_PREFIX_LEN + 1;                  command = file + CGIBIN_PREFIX_LEN + 1;
                 if ((s = strchr(command, '/')) != NULL) {                  if ((s = strchr(command, '/')) != NULL) {
                         info = bozostrdup(s);                          info = bozostrdup(s);
                         *s = '\0';                          *s = '\0';
Line 213  process_cgi(http_req *request)
Line 216  process_cgi(http_req *request)
         spsetenv("GATEWAY_INTERFACE", "CGI/1.1", curenvp++);          spsetenv("GATEWAY_INTERFACE", "CGI/1.1", curenvp++);
         spsetenv("SERVER_PROTOCOL", request->hr_proto, curenvp++);          spsetenv("SERVER_PROTOCOL", request->hr_proto, curenvp++);
         spsetenv("REQUEST_METHOD", request->hr_methodstr, curenvp++);          spsetenv("REQUEST_METHOD", request->hr_methodstr, curenvp++);
         spsetenv("SCRIPT_NAME", url, curenvp++);          spsetenv("SCRIPT_NAME", file, curenvp++);
         spsetenv("SCRIPT_FILENAME", url + 1, curenvp++);          spsetenv("SCRIPT_FILENAME", file + 1, curenvp++);
         spsetenv("SERVER_SOFTWARE", server_software, curenvp++);          spsetenv("SERVER_SOFTWARE", server_software, curenvp++);
         spsetenv("REQUEST_URI", request->hr_url, curenvp++);          spsetenv("REQUEST_URI", request->hr_file, curenvp++);
         spsetenv("DATE_GMT", http_date(), curenvp++);          spsetenv("DATE_GMT", http_date(), curenvp++);
         if (query && *query)          if (query && *query)
                 spsetenv("QUERY_STRING", query, curenvp++);                  spsetenv("QUERY_STRING", query, curenvp++);
Line 234  process_cgi(http_req *request)
Line 237  process_cgi(http_req *request)
                 spsetenv("REMOTE_ADDR", request->hr_remoteaddr, curenvp++);                  spsetenv("REMOTE_ADDR", request->hr_remoteaddr, curenvp++);
         auth_cgi_setenv(request, &curenvp);          auth_cgi_setenv(request, &curenvp);
   
           free(file);
           free(url);
   
         debug((DEBUG_FAT, "process_cgi: going exec %s, %s %s %s",          debug((DEBUG_FAT, "process_cgi: going exec %s, %s %s %s",
             path, argv[0], strornull(argv[1]), strornull(argv[2])));              path, argv[0], strornull(argv[1]), strornull(argv[2])));
   
Line 295  process_cgi(http_req *request)
Line 301  process_cgi(http_req *request)
         }          }
         debug((DEBUG_FAT, "done processing cgi input"));          debug((DEBUG_FAT, "done processing cgi input"));
         exit(0);          exit(0);
   
    out:
           if (query)
                   free(query);
           if (file)
                   free(file);
           if (url)
                   free(url);
           return 0;
 }  }
   
 /*  /*
Line 309  finish_cgi_output(http_req *request, int
Line 324  finish_cgi_output(http_req *request, int
         ssize_t len;          ssize_t len;
         ssize_t rbytes;          ssize_t rbytes;
         SIMPLEQ_HEAD(, headers) headers;          SIMPLEQ_HEAD(, headers) headers;
         struct  headers *hdr;          struct  headers *hdr, *nhdr;
         int     write_header, nheaders = 0;          int     write_header, nheaders = 0;
   
         /* much of this code is like read_request()'s header loop. hmmm... */          /* much of this code is like read_request()'s header loop. hmmm... */
         SIMPLEQ_INIT(&headers);          SIMPLEQ_INIT(&headers);
         write_header = nph == 0;          write_header = nph == 0;
         while (nph == 0 && (str = bozodgetln(in, &len, read)) != NULL) {          while (nph == 0 && (str = bozodgetln(in, &len, read)) != NULL) {
                 char * hdr_name, * hdr_value;                  char    *hdr_name, *hdr_value;
   
                 if (parse_header(str, len, &hdr_name, &hdr_value))                  if (parse_header(str, len, &hdr_name, &hdr_value))
                         break;                          break;
Line 358  finish_cgi_output(http_req *request, int
Line 373  finish_cgi_output(http_req *request, int
         if (nheaders) {          if (nheaders) {
                 debug((DEBUG_OBESE, "process_cgi:  writing delayed HTTP "                  debug((DEBUG_OBESE, "process_cgi:  writing delayed HTTP "
                                     "headers .."));                                      "headers .."));
                 SIMPLEQ_FOREACH(hdr, &headers, h_next) {                  SIMPLEQ_FOREACH_SAFE(hdr, &headers, h_next, nhdr) {
                         bozoprintf("%s: %s\r\n", hdr->h_header, hdr->h_value);                          bozoprintf("%s: %s\r\n", hdr->h_header, hdr->h_value);
                         free(hdr->h_header);                          free(hdr->h_header);
                         free(hdr);                          free(hdr);
Line 386  finish_cgi_output(http_req *request, int
Line 401  finish_cgi_output(http_req *request, int
 }  }
   
 static int  static int
 parse_header(const char * str, ssize_t len, char ** hdr_str, char ** hdr_val)  parse_header(const char *str, ssize_t len, char **hdr_str, char **hdr_val)
 {  {
         char * name, * value;          char    *name, *value;
   
         /* if the string passed is zero-length bail out */          /* if the string passed is zero-length bail out */
         if (*str == '\0')          if (*str == '\0')
                 return -1;                  return -1;
   
         name = value = bozostrdup(str);          value = bozostrdup(str);
   
         /* locate the ':' separator in the header/value */          /* locate the ':' separator in the header/value */
         name = bozostrnsep(&value, ":", &len);          name = bozostrnsep(&value, ":", &len);
Line 422  content_cgihandler(http_req *request, co
Line 437  content_cgihandler(http_req *request, co
 {  {
         struct  content_map     *map;          struct  content_map     *map;
   
           debug((DEBUG_FAT, "content_cgihandler: trying file %s", file));
         map = match_content_map(file, 0);          map = match_content_map(file, 0);
         if (map)          if (map)
                 return (map->cgihandler);                  return (map->cgihandler);
         return (NULL);          return (NULL);
 }  }
   
   static void
   append_index_html(char **url)
   {
           *url = bozorealloc(*url, strlen(*url) + strlen(index_html) + 1);
           strcat(*url, index_html);
           debug((DEBUG_NORMAL, "append_index_html: url adjusted to `%s'", *url));
   }
   
 #ifndef NO_DYNAMIC_CONTENT  #ifndef NO_DYNAMIC_CONTENT
 /* cgi maps are simple ".postfix /path/to/prog" */  /* cgi maps are simple ".postfix /path/to/prog" */
 void  void

Legend:
Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3

CVSweb <webmaster@jp.NetBSD.org>