--- parser3/src/targets/cgi/parser3.C 2016/11/28 00:37:16 1.274 +++ parser3/src/targets/cgi/parser3.C 2019/12/27 21:32:33 1.286 @@ -1,11 +1,11 @@ /** @file Parser: scripting and CGI main. - Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com) + Copyright (c) 2001-2017 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ -volatile const char * IDENT_PARSER3_C="$Id: parser3.C,v 1.274 2016/11/28 00:37:16 moko Exp $"; +volatile const char * IDENT_PARSER3_C="$Id: parser3.C,v 1.286 2019/12/27 21:32:33 moko Exp $"; #include "pa_config_includes.h" @@ -13,7 +13,6 @@ volatile const char * IDENT_PARSER3_C="$ #include "classes.h" #include "pa_common.h" #include "pa_request.h" -#include "pa_socks.h" #include "pa_version.h" #include "pa_vconsole.h" @@ -26,9 +25,9 @@ volatile const char * IDENT_PARSER3_C="$ // defines // comment remove me after debugging -//#define PA_DEBUG_CGI_ENTRY_EXIT "c:\\parser\\debug-parser3.log" +//#define PA_DEBUG_CGI_ENTRY_EXIT "parser3-debug.log" -#if _MSC_VER && !defined(_DEBUG) +#if defined(_MSC_VER) && !defined(_DEBUG) # define PA_SUPPRESS_SYSTEM_EXCEPTION #endif @@ -58,7 +57,8 @@ bool execution_canceled=false; // SAPI -struct SAPI_Info { +class SAPI_Info { +public: int http_response_code; } SAPI_info = { 0 }; @@ -257,9 +257,9 @@ static void full_file_spec(const char* f #ifdef WIN32 || file_name[0] && file_name[1]==':' #endif - ) - strncpy(buf, file_name, buf_size); - else { + ){ + strncpy(buf, file_name, buf_size-1); buf[buf_size-1]=0; + } else { char cwd[MAX_STRING]; snprintf(buf, buf_size, "%s/%s", getcwd(cwd, MAX_STRING) ? cwd : "", file_name); } @@ -301,7 +301,7 @@ static void SIGPIPE_handler(int /*sig*/) execution_canceled=true; if(request) - request->set_interrupted(true); + request->set_skip(Request::SKIP_INTERRUPTED); } #endif @@ -338,6 +338,10 @@ const char* maybe_reconstruct_IIS_status return original; } + +#define MAYBE_RECONSTRUCT_IIS_STATUS_IN_QS(s) maybe_reconstruct_IIS_status_in_qs(s) +#else +#define MAYBE_RECONSTRUCT_IIS_STATUS_IN_QS(s) s #endif @@ -361,115 +365,90 @@ main workhorse wich is tested but seems slow. */ static void real_parser_handler(const char* filespec_to_process, const char* request_method, bool header_only) { - // init socks - pa_socks_init(); - // init global variables + // init libraries pa_globals_init(); if(!filespec_to_process || !*filespec_to_process) - SAPI::die("Parser/%s" -#ifdef PA_DEBUG_CGI_ENTRY_EXIT - " with entry/exit tracing" -#endif - , PARSER_VERSION); + SAPI::die("Parser/%s", PARSER_VERSION); // Request info - Request_info request_info; memset(&request_info, 0, sizeof(request_info)); + Request_info request_info; memset(&request_info, 0, sizeof(request_info)); char document_root_buf[MAX_STRING]; + + request_info.path_translated = filespec_to_process; + request_info.method = request_method ? request_method : "GET"; + request_info.query_string = MAYBE_RECONSTRUCT_IIS_STATUS_IN_QS(getenv("QUERY_STRING")); + if(cgi) { - if(const char* env_document_root=getenv("DOCUMENT_ROOT")) - request_info.document_root=env_document_root; - else if(const char* path_info=getenv("PATH_INFO")) { - // IIS - size_t len=min(sizeof(document_root_buf)-1, strlen(filespec_to_process)-strlen(path_info)); - memcpy(document_root_buf, filespec_to_process, len); document_root_buf[len]=0; - request_info.document_root=document_root_buf; - } else - throw Exception(PARSER_RUNTIME, 0, "CGI: no PATH_INFO defined(in reinventing DOCUMENT_ROOT)"); - } else { - full_file_spec("", document_root_buf, sizeof(document_root_buf)); - request_info.document_root=document_root_buf; - } - request_info.path_translated=filespec_to_process; - request_info.method=request_method ? request_method : "GET"; - const char* query_string= -#ifdef WIN32 - maybe_reconstruct_IIS_status_in_qs -#endif - (getenv("QUERY_STRING")); - request_info.query_string=query_string; - if(cgi) { - // few absolute obligatory + // obligatory const char* path_info=getenv("PATH_INFO"); if(!path_info) SAPI::die("CGI: illegal call (missing PATH_INFO)"); - const char* script_name=getenv("SCRIPT_NAME"); - if(!script_name) - SAPI::die("CGI: illegal call (missing SCRIPT_NAME)"); - - const char* env_request_uri=request_info.strip_absolute_uri(getenv("REQUEST_URI")); - if(env_request_uri) - request_info.uri=env_request_uri; - else - if(query_string) { - char* reconstructed_uri=new(PointerFreeGC) char[strlen(path_info) + 1/*'?'*/+ strlen(query_string) + 1/*0*/]; - strcpy(reconstructed_uri, path_info); - strcat(reconstructed_uri, "?"); - strcat(reconstructed_uri, query_string); - request_info.uri=reconstructed_uri; - } else - request_info.uri=path_info; + + request_info.document_root = getenv("DOCUMENT_ROOT"); + if(!request_info.document_root) { + // IIS or fcgiwrap minimalistic setup + ssize_t prefix_len = strlen(filespec_to_process) - strlen(path_info); + if(prefix_len < 0 || strcmp(filespec_to_process + prefix_len, path_info) != 0) + SAPI::die("CGI: illegal call (invalid PATH_INFO in reinventing DOCUMENT_ROOT)"); + + char* document_root = new(PointerFreeGC) char[prefix_len + 1/*0*/]; + memcpy(document_root, filespec_to_process, prefix_len); document_root[prefix_len] = 0; + request_info.document_root = document_root; + } - if(env_request_uri) { // apache & others stuck to standards + request_info.uri = request_info.strip_absolute_uri(getenv("REQUEST_URI")); + if(request_info.uri) { // apache & others stuck to standards + // another obligatory + const char* script_name = getenv("SCRIPT_NAME"); + if(!script_name) + SAPI::die("CGI: illegal call (missing SCRIPT_NAME)"); /* http://parser3/env.html?123 =OK $request:uri=/env.html?123 REQUEST_URI='/env.html?123' SCRIPT_NAME='/cgi-bin/parser3' PATH_INFO='/env.html' - + http://parser3/cgi-bin/parser3/env.html?123 =ERROR $request:uri=/cgi-bin/parser3/env.html?123 REQUEST_URI='/cgi-bin/parser3/env.html?123' SCRIPT_NAME='/cgi-bin/parser3' PATH_INFO='/env.html' */ - size_t script_name_len=strlen(script_name); - size_t uri_len=strlen(env_request_uri); - if(strncmp(env_request_uri, script_name, script_name_len)==0 && script_name_len != uri_len) // under IIS they are the same + size_t script_name_len = strlen(script_name); + size_t uri_len = strlen(request_info.uri); + if(strncmp(request_info.uri, script_name, script_name_len)==0 && script_name_len != uri_len) // under IIS they are the same SAPI::die("CGI: illegal call (1)"); - } else { // seen on IIS5 - /* - http://nestle/env.html?123 =OK - $request:uri=/env.html?123 - REQUEST_URI='' - SCRIPT_NAME='/env.html' - PATH_INFO='/env.html' + } else { // fcgiwrap minimalistic setup - http://nestle/cgi-bin/parser3.exe/env.html =ERROR - $request:uri=/env.html - REQUEST_URI='' - SCRIPT_NAME='/cgi-bin/parser3.exe' - PATH_INFO='/env.html' - */ - if(strcmp(script_name, path_info)!=0) - SAPI::die("CGI: illegal call (2)"); + if(request_info.query_string && *request_info.query_string) { + char* reconstructed_uri = new(PointerFreeGC) char[strlen(path_info) + 1/*'?'*/+ strlen(request_info.query_string) + 1/*0*/]; + strcpy(reconstructed_uri, path_info); + strcat(reconstructed_uri, "?"); + strcat(reconstructed_uri, request_info.query_string); + request_info.uri = reconstructed_uri; + } else + request_info.uri = path_info; } - } else - request_info.uri=""; + } else{ + full_file_spec("", document_root_buf, sizeof(document_root_buf)); + request_info.document_root = document_root_buf; + request_info.uri = ""; + } - request_info.content_type=getenv("CONTENT_TYPE"); - const char* content_length=getenv("CONTENT_LENGTH"); - request_info.content_length=(content_length?atoi(content_length):0); - request_info.cookie=getenv("HTTP_COOKIE"); - request_info.mail_received=mail_received; + request_info.content_type = getenv("CONTENT_TYPE"); + const char* content_length = getenv("CONTENT_LENGTH"); + request_info.content_length = content_length ? atoi(content_length) : 0; + request_info.cookie = getenv("HTTP_COOKIE"); + request_info.mail_received = mail_received; - request_info.argv=argv_all; - request_info.args_skip=args_skip; + request_info.argv = argv_all; + request_info.args_skip = args_skip; // get request_info ptr for signal handlers - ::request_info=&request_info; + ::request_info = &request_info; if(execution_canceled) SAPI::die("Execution canceled"); @@ -519,11 +498,8 @@ static void real_parser_handler(const ch // ::request cleared in RequestController desctructor to prevent signal handlers from accessing invalid memory } - // finalize global variables + // finalize libraries pa_globals_done(); - - // - pa_socks_done(); } #ifdef PA_SUPPRESS_SYSTEM_EXCEPTION @@ -569,7 +545,7 @@ static void call_real_parser_handler__su static void usage(const char* program) { printf( "Parser/%s\n" - "Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com)\n" + "Copyright (c) 2001-2017 Art. Lebedev Studio (http://www.artlebedev.com)\n" "Author: Alexandr Petrosian (http://paf.design.ru)\n" "\n" "Usage: %s [options] file\n" @@ -589,14 +565,6 @@ int main(int argc, char *argv[]) { log("main: entry"); #endif -#ifndef PA_DEBUG_DISABLE_GC - GC_java_finalization=0; - // Dont collect unless explicitly requested - // this is quicker (~30% ), but less memory-efficient(~8%) - // so deciding for speed - GC_dont_gc=1; -#endif - #ifdef SIGUSR1 if(signal(SIGUSR1, SIGUSR1_handler)==SIG_ERR) SAPI::die("Can not set handler for SIGUSR1");