Diff for /parser3/src/targets/cgi/parser3.C between versions 1.154 and 1.166

version 1.154, 2002/02/08 08:31:32 version 1.166, 2002/04/04 07:57:50
Line 1 Line 1
 /** @file  /** @file
         Parser: scripting and CGI main.          Parser: scripting and CGI main.
   
         Copyright(c) 2001, 2002 ArtLebedev Group(http://www.artlebedev.com)          Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
   
         $Id$          $Id$
Line 29 Line 29
 #endif  #endif
   
 //#define DEBUG_POOL_MALLOC  //#define DEBUG_POOL_MALLOC
   //#define DEBUG_STRING_APPENDS_VS_EXPANDS
   
   #ifdef DEBUG_STRING_APPENDS_VS_EXPANDS
   extern ulong 
           string_piece_appends, 
           wcontext_result_size,
           total_alloc_size,
           string_string_shortcut_economy;
   #endif
   
 // consts  // consts
   
Line 52  const char **RCSIds[]={ Line 61  const char **RCSIds[]={
         0          0
 };  };
   
   const char *PARSER_ROOT_CONFIG_ENV_NAME="HTTP_PARSER_ROOT_CONFIG";
   const char *PARSER_SITE_CONFIG_ENV_NAME="HTTP_PARSER_SITE_CONFIG";
   
 /// IIS refuses to read bigger chunks  /// IIS refuses to read bigger chunks
 const size_t READ_POST_CHUNK_SIZE=0x400*0x400; // 1M   const size_t READ_POST_CHUNK_SIZE=0x400*0x400; // 1M 
   
Line 183  void SAPI::send_body(Pool& , const void Line 195  void SAPI::send_body(Pool& , const void
   
 //  //
   
 char *full_file_spec(char *file_name) {  void full_file_spec(const char *file_name, char *buf, size_t buf_size) {
         if(file_name && !strchr(file_name, '/')) {          if(file_name && !strchr(file_name, '/')) {
                 static char cwd[MAX_STRING];  getcwd(cwd, MAX_STRING);                  char cwd[MAX_STRING];  getcwd(cwd, MAX_STRING);
                 static char buf[MAX_STRING];                  snprintf(buf, buf_size, "%s/%s", cwd, file_name);
                 snprintf(buf, MAX_STRING, "%s/%s", cwd, file_name);          } else {
                 return buf;                  strncpy(buf, file_name, buf_size);
         }          }
         return file_name;  #ifdef WIN32
           back_slashes_to_slashes(buf);
   #endif
 }  }
   
 /**  /**
Line 218  void real_parser_handler( Line 232  void real_parser_handler(
                   
         // Request info          // Request info
         Request::Info request_info;          Request::Info request_info;
           char document_root_buf[MAX_STRING];
         if(cgi) {          if(cgi) {
                 if(const char *env_document_root=SAPI::get_env(pool, "DOCUMENT_ROOT"))                  if(const char *env_document_root=SAPI::get_env(pool, "DOCUMENT_ROOT"))
                         request_info.document_root=env_document_root;                          request_info.document_root=env_document_root;
                 else if(const char *path_info=SAPI::get_env(pool, "PATH_INFO")) {                  else if(const char *path_info=SAPI::get_env(pool, "PATH_INFO")) {
                         // IIS                          // IIS
                         size_t len=strlen(filespec_to_process)-strlen(path_info);                          size_t len=min(sizeof(document_root_buf)-1, strlen(filespec_to_process)-strlen(path_info));
                         char *buf=(char *)pool.malloc(len+1);                          memcpy(document_root_buf, filespec_to_process, len); document_root_buf[len]=0;
                         memcpy(buf, filespec_to_process, len); buf[len]=0;                          request_info.document_root=document_root_buf;
                         request_info.document_root=buf;  
                 } else                  } else
                         throw Exception(0, 0,                          throw Exception("parser.runtime",
                         0,                                  0,
                         "CGI: no PATH_INFO defined(in reinventing DOCUMENT_ROOT)");                                  "CGI: no PATH_INFO defined(in reinventing DOCUMENT_ROOT)");
         } else {          } else {
                 static char buf[MAX_STRING];                  full_file_spec("", document_root_buf, sizeof(document_root_buf));
                 strncpy(buf, filespec_to_process, MAX_STRING-1); buf[MAX_STRING-1]=0;                  request_info.document_root=document_root_buf;
                 if(rsplit(buf, '/') || rsplit(buf, '\\')) // strip filename  
                         request_info.document_root=buf;  
                 else  
                         request_info.document_root="";  
         }          }
         request_info.path_translated=filespec_to_process;          request_info.path_translated=filespec_to_process;
         request_info.method=request_method ? request_method : "GET";          request_info.method=request_method ? request_method : "GET";
Line 258  void real_parser_handler( Line 268  void real_parser_handler(
                         } else                          } else
                                 request_info.uri=path_info;                                  request_info.uri=path_info;
                         else                          else
                                 throw Exception(0, 0,                                  throw Exception("parser.runtime",
                                 0,                                          0,
                                 "CGI: no PATH_INFO defined(in reinventing REQUEST_URI)");                                          "CGI: no PATH_INFO defined(in reinventing REQUEST_URI)");
                                                   
 #ifndef WIN32  #ifndef WIN32
                         // they've changed this under IIS5.                          // they've changed this under IIS5.
Line 293  void real_parser_handler( Line 303  void real_parser_handler(
                 true /* status_allowed */);                  true /* status_allowed */);
                   
         // some root-controlled location          // some root-controlled location
           const char *root_config_filespec;
           if(const char *root_config_by_env=getenv(PARSER_ROOT_CONFIG_ENV_NAME))
                   root_config_filespec=root_config_by_env;
           else {
 #ifdef ROOT_CONFIG_DIR  #ifdef ROOT_CONFIG_DIR
         const char *root_config_filespec=ROOT_CONFIG_DIR "/" CONFIG_FILE_NAME;                  root_config_filespec=ROOT_CONFIG_DIR "/" CONFIG_FILE_NAME;
 #else  #else
 #       ifdef WIN32  #       ifdef WIN32
         // c:\windows                  // c:\windows
         char root_config_path[MAX_STRING];                  char windows_dir[MAX_STRING];
         GetWindowsDirectory(root_config_path, MAX_STRING);                  GetWindowsDirectory(windows_dir, MAX_STRING);
           
         char root_config_filespec[MAX_STRING];                  char buf[MAX_STRING];
         snprintf(root_config_filespec, MAX_STRING,                   snprintf(buf, MAX_STRING, 
                 "%s/%s",                           "%s/%s", 
                 root_config_path, CONFIG_FILE_NAME);                          windows_dir, CONFIG_FILE_NAME);
                   
                   root_config_filespec=buf;
 #       else  #       else
 #error must be compiled either configure/make or MSVC++  #error must be compiled either configure/make or MSVC++
 #       endif  #       endif
 #endif  #endif
           }
                   
           const char *site_config_filespec;
           if(const char *site_config_by_env=getenv(PARSER_SITE_CONFIG_ENV_NAME))
                   site_config_filespec=site_config_by_env;
           else {
         // beside by binary          // beside by binary
         // @todo full path, not ./!          // @todo full path, not ./!
         static char site_config_path[MAX_STRING];                  char beside_binary_path[MAX_STRING];
         strncpy(site_config_path, argv0, MAX_STRING-1);  site_config_path[MAX_STRING-1]=0; // filespec of my binary                  strncpy(beside_binary_path, argv0, MAX_STRING-1);  beside_binary_path[MAX_STRING-1]=0; // filespec of my binary
         if(!(                  if(!(
                 rsplit(site_config_path, '/') ||                           rsplit(beside_binary_path, '/') || 
                 rsplit(site_config_path, '\\'))) { // strip filename                          rsplit(beside_binary_path, '\\'))) { // strip filename
                 // no path, just filename                          // no path, just filename
                 site_config_path[0]='.'; site_config_path[1]=0;                          beside_binary_path[0]='.'; beside_binary_path[1]=0;
                   }
                   char buf[MAX_STRING];
                   snprintf(buf, MAX_STRING, 
                           "%s/%s", 
                           beside_binary_path, CONFIG_FILE_NAME);
                   site_config_filespec=buf;
         }          }
                   
         char site_config_filespec[MAX_STRING];  
         snprintf(site_config_filespec, MAX_STRING,   
                 "%s/%s",   
                 site_config_path, CONFIG_FILE_NAME);  
           
         // process the request          // process the request
         request.core(          request.core(
                 root_config_filespec, false,                  root_config_filespec, false /*don't fail_on_read_problem*/,
                 site_config_filespec, false,                  site_config_filespec, false /*don't fail_on_read_problem*/,
                 header_only);                  header_only);
                   
         //          //
Line 339  void real_parser_handler( Line 361  void real_parser_handler(
         extern void log_pool_stats(Pool& pool);          extern void log_pool_stats(Pool& pool);
         log_pool_stats(pool);          log_pool_stats(pool);
 #endif  #endif
   
   #ifdef DEBUG_STRING_APPENDS_VS_EXPANDS
           SAPI::log(pool, 
                   "string piece appends=%lu, wcontext_result_size=%lu, string_string_shortcut_economy_closer=%lu, total_alloc_size=%lu", 
                   string_piece_appends,
                   wcontext_result_size,
                   string_string_shortcut_economy,
                   total_alloc_size);
   #endif
   
 }  }
   
 void call_real_parser_handler__do_SEH(  void call_real_parser_handler__do_SEH(
Line 359  void call_real_parser_handler__do_SEH( Line 391  void call_real_parser_handler__do_SEH(
                                   
                 if(system_exception)                  if(system_exception)
                         if(_EXCEPTION_RECORD *er=system_exception->ExceptionRecord)                          if(_EXCEPTION_RECORD *er=system_exception->ExceptionRecord)
                                 throw Exception(0, 0,                                  throw Exception(0,
                                 0,                                          0,
                                 "Exception 0x%08X at 0x%08X", er->ExceptionCode,  er->ExceptionAddress);                                          "Exception 0x%08X at 0x%08X", er->ExceptionCode,  er->ExceptionAddress);
                         else                          else
                                 throw Exception(0, 0, 0, "Exception <no exception record>");                                  throw Exception(0, 0, "Exception <no exception record>");
                         else                          else
                                 throw Exception(0, 0, 0, "Exception <no exception information>");                                  throw Exception(0, 0, "Exception <no exception information>");
         }          }
 #endif  #endif
 }  }
Line 399  int main(int argc, char *argv[]) { Line 431  int main(int argc, char *argv[]) {
         if(!cgi) {          if(!cgi) {
                 if(argc<2) {                  if(argc<2) {
                         printf(                          printf(
                                 "Parser/%s Copyright(c) 2001, 2002 ArtLebedev Group(http://www.artlebedev.com)\n"                                  "Parser/%s Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)\n"
                                 "Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)\n"                                  "Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)\n"
                                 "\n"                                  "\n"
                                 "Usage: %s <file>\n",                                  "Usage: %s <file>\n",
Line 437  int main(int argc, char *argv[]) { Line 469  int main(int argc, char *argv[]) {
         std::set_new_handler(failed_new);          std::set_new_handler(failed_new);
 #endif  #endif
   
         char *filespec_to_process=cgi?getenv("PATH_TRANSLATED"):argv[1];          char *raw_filespec_to_process=cgi?getenv("PATH_TRANSLATED"):argv[1];
 #ifdef WIN32          char filespec_to_process[MAX_STRING];
         back_slashes_to_slashes(filespec_to_process);          full_file_spec(raw_filespec_to_process, filespec_to_process, sizeof(filespec_to_process));
 #endif  
         filespec_to_process=full_file_spec(filespec_to_process);  
   
         const char *request_method=getenv("REQUEST_METHOD");          const char *request_method=getenv("REQUEST_METHOD");
         bool header_only=request_method && strcasecmp(request_method, "HEAD")==0;          bool header_only=request_method && strcasecmp(request_method, "HEAD")==0;
Line 468  int main(int argc, char *argv[]) { Line 498  int main(int argc, char *argv[]) {
         if(!cgi)          if(!cgi)
                 SAPI::send_body(pool, "\n", 1);                  SAPI::send_body(pool, "\n", 1);
 #endif  #endif
   //_asm int 3;
         return 0;          return 0;
 }  }

Removed from v.1.154  
changed lines
  Added in v.1.166


E-mail: