Diff for /parser3/src/targets/cgi/parser3.C between versions 1.130 and 1.184

version 1.130, 2001/11/08 11:52:34 version 1.184, 2002/06/24 11:59:33
Line 1 Line 1
 /** @file  /** @file
         Parser: scripting and CGI main.          Parser: scripting and CGI main.
   
         Copyright(c) 2001 ArtLebedev Group(http://www.artlebedev.com)          Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
         Author: Alexander Petrosyan <paf@design.ru>(http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
   
         $Id$          $Id$
 */  */
   
 #include "pa_config_includes.h"  #include "pa_config_includes.h"
   
 #ifdef WIN32  #if _MSC_VER
 #       include <windows.h>  #       include <new.h>
   #       include <crtdbg.h>
 #endif  #endif
   
 #include "pa_sapi.h"  #include "pa_sapi.h"
Line 21 Line 22
 #include "pa_version.h"  #include "pa_version.h"
 #include "pool_storage.h"  #include "pool_storage.h"
   
 #ifdef XML  #ifdef WIN32
 #include <XalanTransformer/XalanCAPI.h>  #       include <windows.h>
   #       include "getopt.h"
   #else
   #       include <getopt.h>
 #endif  #endif
   
 //#define DEBUG_POOL_MALLOC  //#define DEBUG_POOL_MALLOC
   //#define DEBUG_STRING_APPENDS_VS_EXPANDS
   //#define DEBUG_MAIL_RECEIVE "test2.eml"
   
   #ifdef DEBUG_STRING_APPENDS_VS_EXPANDS
   extern ulong 
           string_piece_appends, 
           wcontext_result_size,
           total_alloc_size,
           string_string_shortcut_economy;
   #endif
   
 // consts  // consts
   
   #ifndef _PROFILE
 extern const char *main_RCSIds[];  extern const char *main_RCSIds[];
 #ifdef USE_SMTP  #ifdef USE_SMTP
 extern const char *smtp_RCSIds[];  extern const char *smtp_RCSIds[];
Line 37  extern const char *gd_RCSIds[]; Line 52  extern const char *gd_RCSIds[];
 extern const char *classes_RCSIds[];  extern const char *classes_RCSIds[];
 extern const char *types_RCSIds[];  extern const char *types_RCSIds[];
 extern const char *parser3_RCSIds[];  extern const char *parser3_RCSIds[];
 #ifdef XML  
 extern const char *xalan_patched_RCSIds[];  
 #endif  
 const char **RCSIds[]={  const char **RCSIds[]={
         main_RCSIds,          main_RCSIds,
 #ifdef USE_SMTP  #ifdef USE_SMTP
Line 49  const char **RCSIds[]={ Line 61  const char **RCSIds[]={
         classes_RCSIds,          classes_RCSIds,
         types_RCSIds,          types_RCSIds,
         parser3_RCSIds,          parser3_RCSIds,
 #ifdef XML  
         xalan_patched_RCSIds,  
 #endif  
         0          0
 };  };
   #endif
   
   #define REDIRECT_PREFIX "REDIRECT_"
   #define PARSER_CONFIG_ENV_NAME "CGI_PARSER_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 
   
 const char *argv0;  static const char *argv0;
 Pool_storage pool_storage;  static Pool *pool; // global pool [dont describe to doxygen: it confuses it with param names]
 Pool pool(&pool_storage); // global pool [dont describe to doxygen: it confuses it with param names]  static bool cgi; ///< we were started as CGI?
 bool cgi; ///< we were started as CGI?  static bool mail_received=false; ///< we were started with -m option? [asked to parse incoming message to $mail:received]
   
 // SAPI  // SAPI
   
Line 83  static void log(const char *fmt, va_list Line 96  static void log(const char *fmt, va_list
   
         // prefix          // prefix
         time_t t=time(0);          time_t t=time(0);
         const char *stamp=ctime(&t);          if(const char *stamp=ctime(&t)) { // never saw that
         fprintf(f, "[%.*s] ", strlen(stamp)-1, stamp);                  if(size_t len=strlen(stamp)) // saw once stamp being =""
                           fprintf(f, "[%.*s] ", len-1, stamp);
           }
         // message          // message
   
         char buf[MAX_STRING];          char buf[MAX_STRING];
Line 110  void SAPI::log(Pool& , const char *fmt, Line 125  void SAPI::log(Pool& , const char *fmt,
 }  }
   
 void SAPI::die(const char *fmt, ...) {  void SAPI::die(const char *fmt, ...) {
   #ifdef DEBUG_POOL_MALLOC
           extern void log_pool_stats(Pool& pool);
           log_pool_stats(*pool);
   #endif
   
     va_list args;      va_list args;
         va_start(args,fmt);          va_start(args,fmt);
           // log
   
           // logging is more important than user 
           // she can cancel download, we'd get SIG_PIPE, 
           // nothing would be logged then
         ::log(fmt, args);          ::log(fmt, args);
   
           // inform user
   
           char body[MAX_STRING];
           int content_length=vsnprintf(body, MAX_STRING, fmt, args);
   
         va_end(args);          va_end(args);
   
           // prepare header
           // let's be honest, that's bad we couldn't produce valid output
           SAPI::add_header_attribute(*pool, "status", "500");
           SAPI::add_header_attribute(*pool, "content-type", "text/plain");
           char content_length_cstr[MAX_NUMBER];
           snprintf(content_length_cstr, sizeof(content_length_cstr), "%u", content_length);
           SAPI::add_header_attribute(*pool, "content-length", content_length_cstr);
   
           // send header
           SAPI::send_header(*pool);
   
           // body
           SAPI::send_body(*pool, body, content_length);
   
         exit(1);          exit(1);
 }  }
   
Line 122  const char *SAPI::get_env(Pool& , const Line 167  const char *SAPI::get_env(Pool& , const
         return getenv(name);          return getenv(name);
 }  }
   
   const char *const *SAPI::environment(Pool&) {
   #ifdef _MSC_VER
           extern char **_environ;
           return _environ;
   #else
           extern char **environ;
           return environ;
   #endif
   }
   
 size_t SAPI::read_post(Pool& , char *buf, size_t max_bytes) {  size_t SAPI::read_post(Pool& , char *buf, size_t max_bytes) {
         size_t read_size=0;          size_t read_size=0;
         do {          do {
Line 143  void SAPI::add_header_attribute(Pool& , Line 198  void SAPI::add_header_attribute(Pool& ,
 /// @todo intelligent cache-control  /// @todo intelligent cache-control
 void SAPI::send_header(Pool& ) {  void SAPI::send_header(Pool& ) {
         if(cgi) {          if(cgi) {
                 puts("expires: Fri, 23 Mar 2001 09:32:23 GMT");  //              puts("expires: Fri, 23 Mar 2001 09:32:23 GMT");
   
                 // header | body  delimiter                  // header | body  delimiter
                 puts("");                  puts("");
Line 156  void SAPI::send_body(Pool& , const void Line 211  void SAPI::send_body(Pool& , const void
   
 //  //
   
 char *full_file_spec(char *file_name) {  static void full_file_spec(const char *file_name, char *buf, size_t buf_size) {
         if(file_name && !strchr(file_name, '/')) {          if(file_name)
                 static char cwd[MAX_STRING];  getcwd(cwd, MAX_STRING);                  if(file_name[0]=='/' 
                 static char buf[MAX_STRING];  #ifdef WIN32
                 snprintf(buf, MAX_STRING, "%s/%s", cwd, file_name);                          || (file_name[0] && file_name[1]==':')
                 return buf;  #endif
         }                          ) 
         return file_name;                          strncpy(buf, file_name, buf_size);
                   else {
                           char cwd[MAX_STRING];  getcwd(cwd, MAX_STRING);
                           snprintf(buf, buf_size, "%s/%s", cwd, file_name);
                   }
           else
                   buf[0]=0;
   #ifdef WIN32
           back_slashes_to_slashes(buf);
   #endif
 }  }
   
 /**  /**
Line 173  main workhorse Line 237  main workhorse
                 IIS: remove trailing default-document[index.html] from $request.uri.                  IIS: remove trailing default-document[index.html] from $request.uri.
                 to do that we need to consult metabase,                  to do that we need to consult metabase,
                 wich is tested but seems slow.                  wich is tested but seems slow.
                   IIS5 todo find out proper 'illegal call' check 
 */  */
 void real_parser_handler(  static void real_parser_handler(
                                         const char *filespec_to_process,                                          const char *filespec_to_process,
                                         const char *request_method, bool header_only) {                                          const char *request_method, bool header_only) {
         // init socks          // init socks
         init_socks(pool);          init_socks(*pool);
           
 #ifdef XML  
         /**  
         * Initialize Xerces and Xalan.  
         *  
         * Should be called only once per process before making  
         * any other API calls.  
         */  
         //_asm int 3;  
         XalanInitialize();  
 #endif  
                   
         // init global classes          // init global classes
         init_methoded_array(pool);          init_methoded_array(*pool);
         // init global variables          // init global variables
         pa_globals_init(pool);          pa_globals_init(*pool);
                   
         if(!filespec_to_process)          if(!filespec_to_process)
                 throw Exception(0, 0,                  SAPI::die("Parser/%s", PARSER_VERSION);
                 0,  
                 "Parser/%s", PARSER_VERSION);  
                   
         // 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";
         const char *query_string=SAPI::get_env(pool, "QUERY_STRING");          const char *query_string=SAPI::get_env(*pool, "QUERY_STRING");
         request_info.query_string=query_string;          request_info.query_string=query_string;
         if(cgi) {          if(cgi) {
                 if(const char *env_request_uri=SAPI::get_env(pool, "REQUEST_URI"))                  if(const char *env_request_uri=SAPI::get_env(*pool, "REQUEST_URI"))
                         request_info.uri=env_request_uri;                          request_info.uri=env_request_uri;
                 else if(const char *path_info=SAPI::get_env(pool, "PATH_INFO"))                  else if(const char *path_info=SAPI::get_env(*pool, "PATH_INFO"))
                         if(query_string) {                          if(query_string) {
                                 char *reconstructed_uri=(char *)pool.malloc(                                  char *reconstructed_uri=(char *)pool->malloc(
                                         strlen(path_info)+1/*'?'*/+                                          strlen(path_info)+1/*'?'*/+
                                         strlen(query_string)+1/*0*/);                                          strlen(query_string)+1/*0*/);
                                 strcpy(reconstructed_uri, path_info);                                  strcpy(reconstructed_uri, path_info);
Line 242  void real_parser_handler( Line 290  void real_parser_handler(
                                 request_info.uri=reconstructed_uri;                                  request_info.uri=reconstructed_uri;
                         } 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)");
                                                   
                         if(const char *script_name=SAPI::get_env(pool, "SCRIPT_NAME")) {  #ifndef WIN32
                           // they've changed this under IIS5.
                           if(const char *script_name=SAPI::get_env(*pool, "SCRIPT_NAME")) {
                                 size_t script_name_len=strlen(script_name);                                  size_t script_name_len=strlen(script_name);
                                 size_t uri_len=strlen(request_info.uri);                                  size_t uri_len=strlen(request_info.uri);
                                 if(strncmp(request_info.uri,script_name, script_name_len)==0 &&                                  if(strncmp(request_info.uri,script_name, script_name_len)==0 &&
                                         script_name_len != uri_len) // under IIS they are the same                                          script_name_len != uri_len) // under IIS they are the same
                                         throw Exception(0, 0,                                          SAPI::die("CGI: illegal call");
                                         0,  
                                         "CGI: illegal call");  
                         }                          }
   #endif
         } else          } else
                 request_info.uri=0;                  request_info.uri="";
                   
         request_info.content_type=SAPI::get_env(pool, "CONTENT_TYPE");          request_info.content_type=SAPI::get_env(*pool, "CONTENT_TYPE");
         const char *content_length=SAPI::get_env(pool, "CONTENT_LENGTH");          const char *content_length=SAPI::get_env(*pool, "CONTENT_LENGTH");
         request_info.content_length=(content_length?atoi(content_length):0);          request_info.content_length=(content_length?atoi(content_length):0);
         request_info.cookie=SAPI::get_env(pool, "HTTP_COOKIE");          request_info.cookie=SAPI::get_env(*pool, "HTTP_COOKIE");
         request_info.user_agent=SAPI::get_env(pool, "HTTP_USER_AGENT");          request_info.mail_received=mail_received;
           
         // prepare to process request          // prepare to process request
         Request request(pool,          Request request(*pool,
                 request_info,                  request_info,
                 cgi ? String::UL_USER_HTML : String::UL_AS_IS,  /*#ifdef _DEBUG
                   String::UL_HTML|String::UL_OPTIMIZE_BIT
   #else*/
                   cgi ? String::UL_HTML|String::UL_OPTIMIZE_BIT : String::UL_AS_IS
   /*#endif*/
                   ,
                 true /* status_allowed */);                  true /* status_allowed */);
                   
         // some root-controlled location          const char *config_filespec_cstr;
 #ifdef SYSCONFDIR          char config_filespec_buf[MAX_STRING];
         const char *root_config_filespec=SYSCONFDIR "/" CONFIG_FILE_NAME;          const char *config_by_env=getenv(PARSER_CONFIG_ENV_NAME);
 #else          if(!config_by_env)
 #       ifdef WIN32                  config_by_env=getenv(REDIRECT_PREFIX PARSER_CONFIG_ENV_NAME);
         // c:\windows          if(config_by_env)
         char root_config_path[MAX_STRING];                  config_filespec_cstr=config_by_env;
         GetWindowsDirectory(root_config_path, MAX_STRING);          else {
           
         char root_config_filespec[MAX_STRING];  
         snprintf(root_config_filespec, MAX_STRING,   
                 "%s/%s",   
                 root_config_path, CONFIG_FILE_NAME);  
 #       else  
 #error must be compiled either configure/make or MSVC++  
 #       endif  
 #endif  
           
         // 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;
                   }
                   snprintf(config_filespec_buf, MAX_STRING, 
                           "%s/%s", 
                           beside_binary_path, AUTO_FILE_NAME);
                   config_filespec_cstr=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,                  config_filespec_cstr, false /*fail_on_read_problem*/,
                 site_config_filespec, false,  
                 header_only);                  header_only);
                   
         //          //
Line 316  void real_parser_handler( Line 359  void real_parser_handler(
                   
 #ifdef DEBUG_POOL_MALLOC  #ifdef DEBUG_POOL_MALLOC
         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(  static void call_real_parser_handler__do_SEH(
                                                                  const char *filespec_to_process,                                                                   const char *filespec_to_process,
                                                                  const char *request_method, bool header_only) {                                                                   const char *request_method, bool header_only) {
 #if _MSC_VER & !defined(_DEBUG)  #if _MSC_VER && !defined(_DEBUG)
         LPEXCEPTION_POINTERS system_exception=0;          LPEXCEPTION_POINTERS system_exception=0;
         __try {          __try {
 #endif  #endif
Line 331  void call_real_parser_handler__do_SEH( Line 384  void call_real_parser_handler__do_SEH(
                         filespec_to_process,                          filespec_to_process,
                         request_method, header_only);                          request_method, header_only);
                                   
 #if _MSC_VER & !defined(_DEBUG)  #if _MSC_VER && !defined(_DEBUG)
         } __except (          } __except (
                 (system_exception=GetExceptionInformation()),                   (system_exception=GetExceptionInformation()), 
                 EXCEPTION_EXECUTE_HANDLER) {                  EXCEPTION_EXECUTE_HANDLER) {
                                   
                 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
 }  }
   
   #if _MSC_VER
   int failed_new(size_t size) {
           SAPI::die("out of memory in 'new', failed to allocated %u bytes", size);
           return 0; // not reached
   }
   #endif
   
   #ifdef HAVE_SET_NEW_HANDLER
   static void failed_new() {
       SAPI::die("out of memory in 'new'");
   }
   #endif
   
   static void usage(const char *program) {
           fprintf(stderr,
                   "Parser/%s Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)\n"
                   "Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)\n"
                   "\n"
                   "Usage: %s [options] file\n"
                   "Options are:\n"
   #ifdef WITH_MAIL_RECEIVE
                   "    -m  Parse mail, put received letter to $mail:received\n"
   #endif
                   "    -h  Display usage information (this message)\n"
                   , PARSER_VERSION, 
                   program);
           exit(EINVAL);
   }
   
 int main(int argc, char *argv[]) {  int main(int argc, char *argv[]) {
         int result;          Pool_storage global_pool_storage;
           Pool global_pool(&global_pool_storage);
           pool=&global_pool;
   
   #ifdef DEBUG_MAIL_RECEIVE
           if(FILE *fake_in=fopen(DEBUG_MAIL_RECEIVE, "rt")) {
                   dup2(fake_in->_file, 0/*STDIN_FILENO*/);
           }
   #endif
   
   #ifdef _DEBUG
   //      _crtBreakAlloc=33112;
   #endif
   //      _asm int 3;
         argv0=argv[0];          argv0=argv[0];
   
         umask(2);          umask(2);
Line 362  int main(int argc, char *argv[]) { Line 457  int main(int argc, char *argv[]) {
                 getenv("GATEWAY_INTERFACE") ||                   getenv("GATEWAY_INTERFACE") || 
                 getenv("REQUEST_METHOD");                  getenv("REQUEST_METHOD");
                   
         if(!cgi) {          char *raw_filespec_to_process;
                 if(argc<2) {          if(cgi) 
                         printf(                  raw_filespec_to_process=getenv("PATH_TRANSLATED");
                                 "Parser/%s Copyright(c) 2001 ArtLebedev Group(http://www.artlebedev.com)\n"          else {
                                 "Author: Alexander Petrosyan <paf@design.ru>(http://paf.design.ru)\n"                  optind = 1;
                                 "\n"                  opterr = 0;
                                 "Usage: %s <file>\n",                  int c;
                                 PARSER_VERSION,                   while((c = getopt(argc, argv, "h"
                                 argv0?argv0:"parser3");  #ifdef WITH_MAIL_RECEIVE
                         return 1;                          "m"
   #endif
                           )) > 0) {
                           switch (c) {
                           case 'h':
                                   usage(argv[0]);
                                   break;
   #ifdef WITH_MAIL_RECEIVE
                           case 'm':
                                   mail_received=true;
                                   break;
   #endif
                           default:
                                   fprintf(stderr, "%s: invalid option '%c'\n", argv[0], optopt);
                                   usage(argv[0]);
                                   break;
                           }
                   }
                   if (optind != argc - 1) {
                           fprintf(stderr, "%s: file not specified\n", argv[0]);
                           usage(argv[0]);
                 }                  }
                   
                   raw_filespec_to_process=argv[optind++];
         }          }
   
 #ifdef WIN32  #ifdef WIN32
Line 381  int main(int argc, char *argv[]) { Line 498  int main(int argc, char *argv[]) {
         setmode(fileno(stderr), _O_BINARY);          setmode(fileno(stderr), _O_BINARY);
 #endif  #endif
   
         char *filespec_to_process=cgi?getenv("PATH_TRANSLATED"):argv[1];  #if _MSC_VER
 #ifdef WIN32          _set_new_handler(failed_new);
         back_slashes_to_slashes(filespec_to_process);  
   #ifdef _DEBUG
           // Get current flag
           int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
   
           // Turn on leak-checking bit
           tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
   
           // Set flag to the new value
           _CrtSetDbgFlag( tmpFlag );
   //      _CrtSetBreakAlloc(471);
   
   #endif
   
   #endif
   
   #ifdef HAVE_SET_NEW_HANDLER
           std::set_new_handler(failed_new);
 #endif  #endif
         filespec_to_process=full_file_spec(filespec_to_process);  
           char filespec_to_process[MAX_STRING];
           full_file_spec(raw_filespec_to_process, filespec_to_process, sizeof(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;
   
         try { // global try          try { // global try
                 call_real_parser_handler__do_SEH(                  call_real_parser_handler__do_SEH(
                         filespec_to_process,                          filespec_to_process,
                         request_method, header_only);                          request_method, header_only);
   
                 // successful finish  
                 result=0;  
         } catch(const Exception& e) { // global problem           } catch(const Exception& e) { // global problem 
                 // don't allocate anything on pool here:                  // don't allocate anything on pool here:
                 //   possible pool' exception not catch-ed now                  //   possible pool' exception not catch-ed now
                 //   and there could be out-of-memory exception                  //   and there could be out-of-memory exception
   
                 const char *body=e.comment();                  SAPI::die("exception in request exception handler: %s", e.comment());
                 // log it  #ifndef _DEBUG
                 SAPI::log(pool, "exception in request exception handler: %s", body);          } catch(...) { 
                   SAPI::die("<unknown exception>");
                 //  #endif
                 int content_length=strlen(body);  
   
                 // prepare header  
                 SAPI::add_header_attribute(pool, "content-type", "text/plain");  
                 char content_length_cstr[MAX_NUMBER];  
                 snprintf(content_length_cstr, MAX_NUMBER, "%u", content_length);  
                 SAPI::add_header_attribute(pool, "content-length", content_length_cstr);  
   
                 // send header  
                 SAPI::send_header(pool);  
   
                 // body  
                 if(!header_only)  
                         SAPI::send_body(pool, body, content_length);  
   
                 // unsuccessful finish  
                 result=1;  
         }          }
                   
   
 #ifndef WIN32  #ifndef WIN32
         //           // 
         if(!cgi)          if(!cgi)
                 SAPI::send_body(pool, "\n", 1);                  SAPI::send_body(*pool, "\n", 1);
 #endif  #endif
         return result;  //_asm int 3;
           return 0;
 }  }

Removed from v.1.130  
changed lines
  Added in v.1.184


E-mail: