--- parser3/src/targets/cgi/parser3.C 2001/10/22 16:44:43 1.124 +++ parser3/src/targets/cgi/parser3.C 2002/04/04 07:57:50 1.166 @@ -1,16 +1,19 @@ /** @file Parser: scripting and CGI main. - Copyright(c) 2001 ArtLebedev Group(http://www.artlebedev.com) - Author: Alexander Petrosyan (http://design.ru/paf) + Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) + Author: Alexandr Petrosian (http://paf.design.ru) - $Id: parser3.C,v 1.124 2001/10/22 16:44:43 parser Exp $ + $Id: parser3.C,v 1.166 2002/04/04 07:57:50 paf Exp $ */ #include "pa_config_includes.h" -#ifdef WIN32 -# include +#if _MSC_VER +# include +# include +#else +# include "pa_config_paths.h" #endif #include "pa_sapi.h" @@ -19,12 +22,22 @@ #include "pa_request.h" #include "pa_socks.h" #include "pa_version.h" +#include "pool_storage.h" -#ifdef XML -#include +#ifdef WIN32 +# include #endif //#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 @@ -36,9 +49,6 @@ extern const char *gd_RCSIds[]; extern const char *classes_RCSIds[]; extern const char *types_RCSIds[]; extern const char *parser3_RCSIds[]; -#ifdef XML -extern const char *xalan_patched_RCSIds[]; -#endif const char **RCSIds[]={ main_RCSIds, #ifdef USE_SMTP @@ -48,17 +58,18 @@ const char **RCSIds[]={ classes_RCSIds, types_RCSIds, parser3_RCSIds, -#ifdef XML - xalan_patched_RCSIds, -#endif 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 const size_t READ_POST_CHUNK_SIZE=0x400*0x400; // 1M const char *argv0; -Pool pool(0); // global pool [dont describe to doxygen: it confuses it with param names] +Pool_storage pool_storage; +Pool pool(&pool_storage); // global pool [dont describe to doxygen: it confuses it with param names] bool cgi; ///< we were started as CGI? // SAPI @@ -108,11 +119,41 @@ void SAPI::log(Pool& , 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_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); + + // inform user + + char body[MAX_STRING]; + int content_length=vsnprintf(body, MAX_STRING, fmt, 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, MAX_NUMBER, "%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); } @@ -125,7 +166,7 @@ size_t SAPI::read_post(Pool& , char *buf do { int chunk_size=read(fileno(stdin), buf+read_size, min(READ_POST_CHUNK_SIZE, max_bytes-read_size)); - if(chunk_size<0) + if(chunk_size<=0) break; read_size+=chunk_size; } while(read_sizeExceptionRecord) - throw Exception(0, 0, - 0, - "Exception 0x%08X at 0x%08X", er->ExceptionCode, er->ExceptionAddress); + throw Exception(0, + 0, + "Exception 0x%08X at 0x%08X", er->ExceptionCode, er->ExceptionAddress); else - throw Exception(0, 0, 0, "Exception "); + throw Exception(0, 0, "Exception "); else - throw Exception(0, 0, 0, "Exception "); + throw Exception(0, 0, "Exception "); } #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 +void failed_new() { + SAPI::die("out of memory in 'new'"); +} +#endif + int main(int argc, char *argv[]) { - int result; +// _asm int 3; argv0=argv[0]; umask(2); @@ -363,8 +431,8 @@ int main(int argc, char *argv[]) { if(!cgi) { if(argc<2) { printf( - "Parser/%s Copyright(c) 2001 ArtLebedev Group(http://www.artlebedev.com)\n" - "Author: Alexander Petrosyan (http://design.ru/paf)\n" + "Parser/%s Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)\n" + "Author: Alexandr Petrosian (http://paf.design.ru)\n" "\n" "Usage: %s \n", PARSER_VERSION, @@ -379,48 +447,49 @@ int main(int argc, char *argv[]) { setmode(fileno(stderr), _O_BINARY); #endif - char *filespec_to_process=cgi?getenv("PATH_TRANSLATED"):argv[1]; -#ifdef WIN32 - back_slashes_to_slashes(filespec_to_process); +#if _MSC_VER + _set_new_handler(failed_new); + +#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 - filespec_to_process=full_file_spec(filespec_to_process); + + char *raw_filespec_to_process=cgi?getenv("PATH_TRANSLATED"):argv[1]; + 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"); bool header_only=request_method && strcasecmp(request_method, "HEAD")==0; + try { // global try call_real_parser_handler__do_SEH( filespec_to_process, request_method, header_only); - - // successful finish - result=0; } catch(const Exception& e) { // global problem // don't allocate anything on pool here: // possible pool' exception not catch-ed now // and there could be out-of-memory exception - const char *body=e.comment(); - // log it - SAPI::log(pool, "exception in request exception handler: %s", body); - - // - 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; + SAPI::die("exception in request exception handler: %s", e.comment()); +#ifndef _DEBUG + } catch(...) { + SAPI::die(""); +#endif } @@ -429,5 +498,6 @@ int main(int argc, char *argv[]) { if(!cgi) SAPI::send_body(pool, "\n", 1); #endif - return result; +//_asm int 3; + return 0; }