--- parser3/src/targets/isapi/parser3isapi.C 2003/07/24 11:31:25 1.83 +++ parser3/src/targets/isapi/parser3isapi.C 2007/11/27 09:58:05 1.99 @@ -1,11 +1,11 @@ /** @file Parser: IIS extension. - Copyright (c) 2000,2001-2003 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2000,2001-2005 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char* IDENT_PARSER3ISAPI_C="$Date: 2003/07/24 11:31:25 $"; +static const char * const IDENT_PARSER3ISAPI_C="$Date: 2007/11/27 09:58:05 $"; #ifndef _MSC_VER # error compile ISAPI module with MSVC [no urge for now to make it autoconf-ed (PAF)] @@ -19,11 +19,19 @@ static const char* IDENT_PARSER3ISAPI_C= #include "pa_version.h" #include "pa_socks.h" +#define WINVER 0x0400 #include #include #include +// defines + +#if _MSC_VER && !defined(_DEBUG) +# define PA_SUPPRESS_SYSTEM_EXCEPTION +#endif + + #define MAX_STATUS_LENGTH sizeof("xxxx LONGEST STATUS DESCRIPTION") // consts @@ -69,19 +77,19 @@ public: void SAPI::log(SAPI_Info& SAPI_info, const char* fmt, ...) { va_list args; va_start(args,fmt); - char buf[MAX_STRING]; + char buf[MAX_LOG_STRING]; const char* prefix="PARSER_ERROR:"; strcpy(buf, prefix); char *start=buf+strlen(prefix); - DWORD size=vsnprintf(start, MAX_STRING-strlen(prefix), fmt, args); - remove_crlf(start, start+size); + DWORD size=vsnprintf(start, MAX_LOG_STRING-strlen(prefix), fmt, args); + size=remove_crlf(start, start+size); SAPI_info.lpECB->ServerSupportFunction(SAPI_info.lpECB->ConnID, HSE_APPEND_LOG_PARAMETER, buf, &size, 0); } /// @todo event log -static void die_or_abort(const char* fmt, va_list args, bool write_core) { +static void abort(const char* fmt, va_list args) { if(FILE *log=fopen("c:\\parser3die.log", "at")) { vfprintf(log, fmt, args); fclose(log); @@ -92,15 +100,15 @@ static void die_or_abort(const char* fmt void SAPI::die(const char* fmt, ...) { va_list args; va_start(args, fmt); - die_or_abort(fmt, args, false/*write core?*/); - va_end(args); + ::abort(fmt, args); +// va_end(args); } void SAPI::abort(const char* fmt, ...) { va_list args; va_start(args, fmt); - die_or_abort(fmt, args, true/*write core?*/); - va_end(args); + ::abort(fmt, args); +// va_end(args); } char* SAPI::get_env(SAPI_Info& SAPI_info, const char* name) { @@ -147,8 +155,8 @@ const char* const *SAPI::environment(SAP // we know this buf is writable char* all_http_vars=SAPI::get_env(info, "ALL_HTTP"); const int http_var_count=grep_char(all_http_vars, '\n')+1/*\n for theoretical(never saw) this \0*/; - - const char* *result=new const char*[IIS51var_count+http_var_count+1/*0*/]; + + const char* *result=new(PointerFreeGC) const char*[IIS51var_count+http_var_count+1/*0*/]; const char* *cur=result; // IIS5.1 vars @@ -243,10 +251,12 @@ void SAPI::send_header(SAPI_Info& SAPI_i HSE_REQ_SEND_RESPONSE_HEADER_EX, &header_info, NULL, NULL); } -void SAPI::send_body(SAPI_Info& SAPI_info, const void *buf, size_t size) { +size_t SAPI::send_body(SAPI_Info& SAPI_info, const void *buf, size_t size) { DWORD num_bytes=size; - SAPI_info.lpECB->WriteClient(SAPI_info.lpECB->ConnID, - const_cast(buf), &num_bytes, HSE_IO_SYNC); + if(!SAPI_info.lpECB->WriteClient(SAPI_info.lpECB->ConnID, + const_cast(buf), &num_bytes, HSE_IO_SYNC)) + return 0; + return (size_t)num_bytes; } @@ -258,20 +268,28 @@ static bool parser_init() { try { // init socks - pa_init_socks(); + pa_socks_init(); // init global variables pa_globals_init(); // successful finish return true; - } catch(const Exception& e) { // global problem - const char* body=e.comment(); + } catch(.../*const Exception& e*/) { // global problem + //const char* body=e.comment(); // unsuccessful finish return false; } } +static void parser_done() { + // finalize global variables + pa_globals_done(); + + // + pa_socks_done(); +} + /// ISAPI // BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer) { pVer->dwExtensionVersion = HSE_VERSION; @@ -279,6 +297,15 @@ BOOL WINAPI GetExtensionVersion(HSE_VERS pVer->lpszExtensionDesc[HSE_MAX_EXT_DLL_NAME_LEN-1]=0; return parser_init(); } +// dwFlags & HSE_TERM_MUST_UNLOAD means we can't return false +BOOL WINAPI TerminateExtension( + DWORD /*dwFlags*/ +) +{ + parser_done(); + + return TRUE; +} /** ISAPI // main workhorse @@ -291,8 +318,17 @@ BOOL WINAPI GetExtensionVersion(HSE_VERS @test PARSER_VERSION from outside */ - void real_parser_handler(SAPI_Info& SAPI_info, bool header_only) { + // collect garbage from prev request +#ifndef PA_DEBUG_DISABLE_GC + { + int saved=GC_dont_gc; + GC_dont_gc=0; + GC_gcollect(); + GC_dont_gc=saved; + } +#endif + SAPI_info.header=new String; LPEXTENSION_CONTROL_BLOCK lpECB=SAPI_info.lpECB; @@ -312,7 +348,7 @@ void real_parser_handler(SAPI_Info& SAPI strncpy(buf, filespec_to_process, len); buf[len]=0; request_info.document_root=buf; } else - throw Exception("parser.runtime", + throw Exception(PARSER_RUNTIME, 0, "ISAPI: no PATH_INFO defined (in reinventing DOCUMENT_ROOT)"); @@ -362,30 +398,52 @@ void real_parser_handler(SAPI_Info& SAPI header_only); } -void call_real_parser_handler__do_SEH(SAPI_Info& SAPI_info, bool header_only) { -#if _MSC_VER & !defined(_DEBUG) +#ifdef PA_SUPPRESS_SYSTEM_EXCEPTION +static const Exception +call_real_parser_handler__do_PEH_return_it( + SAPI_Info& SAPI_info, bool header_only) +{ + try { + real_parser_handler(SAPI_info, header_only); + } catch(const Exception& e) { + return e; + } + + return Exception(); +} +static void call_real_parser_handler__supress_system_exception( + SAPI_Info& SAPI_info, bool header_only) +{ + Exception parser_exception; LPEXCEPTION_POINTERS system_exception=0; + __try { -#endif - real_parser_handler(SAPI_info, header_only); - -#if _MSC_VER & !defined(_DEBUG) + parser_exception=call_real_parser_handler__do_PEH_return_it( + SAPI_info, header_only); } __except ( (system_exception=GetExceptionInformation()), - EXCEPTION_EXECUTE_HANDLER) { - + EXCEPTION_EXECUTE_HANDLER) + { + if(system_exception) if(_EXCEPTION_RECORD *er=system_exception->ExceptionRecord) - throw Exception(0, - 0, - "Exception 0x%08X at 0x%08X", er->ExceptionCode, er->ExceptionAddress); - else - throw Exception(0, 0, "Exception "); + throw Exception("system", + 0, + "0x%08X at 0x%08X", er->ExceptionCode, er->ExceptionAddress); else - throw Exception(0, 0, "Exception "); + throw Exception("system", + 0, + ""); + else + throw Exception("system", + 0, + ""); } -#endif + + if(parser_exception) + throw Exception(parser_exception); } +#endif DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpECB) { //_asm int 3; @@ -397,7 +455,12 @@ DWORD WINAPI HttpExtensionProc(LPEXTENSI bool header_only=strcasecmp(lpECB->lpszMethod, "HEAD")==0; try { // global try - call_real_parser_handler__do_SEH(SAPI_info, header_only); +#ifdef PA_SUPPRESS_SYSTEM_EXCEPTION + call_real_parser_handler__supress_system_exception( +#else + real_parser_handler( +#endif + SAPI_info, header_only); // successful finish } catch(const Exception& e) { // global problem // don't allocate anything on pool here: @@ -414,7 +477,7 @@ DWORD WINAPI HttpExtensionProc(LPEXTENSI char header_buf[MAX_STRING]; int header_len=snprintf(header_buf, MAX_STRING, "content-type: text/plain\r\n" - "content-length: %lu\r\n" + "content-length: %u\r\n" // "expires: Fri, 23 Mar 2001 09:32:23 GMT\r\n" "\r\n", content_length); @@ -447,7 +510,7 @@ DWORD WINAPI HttpExtensionProc(LPEXTENSI char header_buf[MAX_STRING]; int header_len=snprintf(header_buf, MAX_STRING, "content-type: text/plain\r\n" - "content-length: %lu\r\n" + "content-length: %u\r\n" "expires: Fri, 23 Mar 2001 09:32:23 GMT\r\n" "\r\n", content_length); @@ -473,8 +536,8 @@ DWORD WINAPI HttpExtensionProc(LPEXTENSI BOOL WINAPI DllMain( HINSTANCE hinstDLL, // handle to the DLL module - DWORD fdwReason, // reason for calling function - LPVOID lpvReserved // reserved + DWORD /*fdwReason*/, // reason for calling function + LPVOID /*lpvReserved*/ // reserved ) { GetModuleFileName(