--- parser3/src/targets/isapi/parser3isapi.C 2020/12/15 17:10:38 1.124 +++ parser3/src/targets/isapi/parser3isapi.C 2026/04/25 13:38:46 1.136 @@ -1,11 +1,11 @@ /** @file Parser: IIS extension. - Copyright (c) 2000-2020 Art. Lebedev Studio (http://www.artlebedev.com) - Author: Alexandr Petrosian (http://paf.design.ru) + Copyright (c) 2000-2026 Art. Lebedev Studio (https://www.artlebedev.com) + Authors: Konstantin Morshnev , Alexandr Petrosian */ -volatile const char * IDENT_PARSER3ISAPI_C="$Id: parser3isapi.C,v 1.124 2020/12/15 17:10:38 moko Exp $"; +volatile const char * IDENT_PARSER3ISAPI_C="$Id: parser3isapi.C,v 1.136 2026/04/25 13:38:46 moko Exp $"; #ifndef _MSC_VER # error compile ISAPI module with MSVC [no urge for now to make it autoconf-ed (PAF)] @@ -56,6 +56,8 @@ const int IIS51var_count=sizeof(IIS51var // globals char argv0[MAX_STRING]=""; +const char* parser3_mode="isapi"; // $status:mode +const char *parser3_log_filespec(){ return ""; } // $status:log-filename // SAPI @@ -99,6 +101,14 @@ void SAPI::die(const char* fmt, ...) { // va_end(args); } +void SAPI::send_error(SAPI_Info& SAPI_info, const char *exception_cstr, const char *status){ + // capitalized headers passed for preventing malloc during capitalization + add_header_attribute(SAPI_info, HTTP_STATUS_CAPITALIZED, status); + add_header_attribute(SAPI_info, HTTP_CONTENT_TYPE_CAPITALIZED, "text/plain"); + send_headers(SAPI_info); + send_body(SAPI_info, exception_cstr, strlen(exception_cstr)); +} + char* SAPI::Env::get(SAPI_Info& SAPI_info, const char* name) { char *variable_buf=new(PointerFreeGC) char[MAX_STRING]; DWORD variable_len = MAX_STRING-1; @@ -206,7 +216,7 @@ void SAPI::add_header_attribute(SAPI_Inf } /// @todo intelligent cache-control -void SAPI::send_header(SAPI_Info& SAPI_info) { +void SAPI::send_headers(SAPI_Info& SAPI_info) { HSE_SEND_HEADER_EX_INFO header_info; char status_buf[MAX_STATUS_LENGTH]; @@ -238,6 +248,10 @@ void SAPI::send_header(SAPI_Info& SAPI_i HSE_REQ_SEND_RESPONSE_HEADER_EX, &header_info, NULL, NULL); } +void SAPI::clear_headers(SAPI_Info& SAPI_info) { + SAPI_info.header=new String; +} + size_t SAPI::send_body(SAPI_Info& SAPI_info, const void *buf, size_t size) { DWORD num_bytes=size; if(!SAPI_info.lpECB->WriteClient(SAPI_info.lpECB->ConnID, @@ -272,8 +286,7 @@ static void parser_done() { /// ISAPI // BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer) { pVer->dwExtensionVersion = HSE_VERSION; - strncpy(pVer->lpszExtensionDesc, "Parser " PARSER_VERSION, HSE_MAX_EXT_DLL_NAME_LEN-1); - pVer->lpszExtensionDesc[HSE_MAX_EXT_DLL_NAME_LEN-1]=0; + pa_strncpy(pVer->lpszExtensionDesc, "Parser " PARSER_VERSION, HSE_MAX_EXT_DLL_NAME_LEN); return parser_init(); } // dwFlags & HSE_TERM_MUST_UNLOAD means we can't return false @@ -299,7 +312,7 @@ BOOL WINAPI TerminateExtension( */ void real_parser_handler(SAPI_Info& SAPI_info, bool header_only) { // collect garbage from prev request - PA_GC_GCOLLECT; + pa_gc_collect(); SAPI_info.header=new String; LPEXTENSION_CONTROL_BLOCK lpECB=SAPI_info.lpECB; @@ -307,8 +320,7 @@ void real_parser_handler(SAPI_Info& SAPI // Request info Request_info request_info; memset(&request_info, 0, sizeof(request_info)); - size_t path_translated_buf_size=strlen(lpECB->lpszPathTranslated)+1; - char *filespec_to_process=pa_strdup(lpECB->lpszPathTranslated, path_translated_buf_size); + char *filespec_to_process=pa_strdup(lpECB->lpszPathTranslated); #ifdef WIN32 back_slashes_to_slashes(filespec_to_process); #endif @@ -316,8 +328,8 @@ void real_parser_handler(SAPI_Info& SAPI if(const char* path_info=SAPI::Env::get(SAPI_info, "PATH_INFO")) { // IIS size_t len=strlen(filespec_to_process)-strlen(path_info); - char *buf=new(PointerFreeGC) char[len+1]; - strncpy(buf, filespec_to_process, len); buf[len]=0; + char *buf=new(PointerFreeGC) char[len]; + pa_strncpy(buf, filespec_to_process, len); request_info.document_root=buf; } else throw Exception(PARSER_RUNTIME, 0, "ISAPI: no PATH_INFO defined (in reinventing DOCUMENT_ROOT)"); @@ -336,7 +348,7 @@ void real_parser_handler(SAPI_Info& SAPI // beside by binary static char beside_binary_path[MAX_STRING]; - strncpy(beside_binary_path, argv0, MAX_STRING-1); beside_binary_path[MAX_STRING-1]=0; // filespec of my binary + pa_strncpy(beside_binary_path, argv0, MAX_STRING); // filespec of my binary if(!(rsplit(beside_binary_path, '/') || rsplit(beside_binary_path, '\\'))) { // strip filename // no path, just filename beside_binary_path[0]='.'; beside_binary_path[1]=0; @@ -397,19 +409,19 @@ DWORD WINAPI HttpExtensionProc(LPEXTENSI #endif SAPI_info, header_only); // successful finish - } catch(const Exception& e) { // exception in unhandled exception + } catch(const Exception& e) { // just in case // log it SAPI::log(SAPI_info, "%s", e.comment()); HSE_SEND_HEADER_EX_INFO header_info; - header_info.pszStatus="200 OK"; + header_info.pszStatus="500 Internal Server Error"; header_info.cchStatus=strlen(header_info.pszStatus); header_info.pszHeader=HTTP_CONTENT_TYPE_CAPITALIZED ": text/plain\r\n\r\n"; header_info.cchHeader=strlen(header_info.pszHeader); header_info.fKeepConn=true; // send header - lpECB->dwHttpStatusCode=200; + lpECB->dwHttpStatusCode=500; lpECB->ServerSupportFunction(lpECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX, &header_info, NULL, NULL); // send body