--- parser3/src/targets/cgi/parser3.C 2002/01/31 10:20:21 1.151 +++ parser3/src/targets/cgi/parser3.C 2002/04/04 07:57:50 1.166 @@ -1,10 +1,10 @@ /** @file Parser: scripting and CGI main. - Copyright(c) 2001 ArtLebedev Group(http://www.artlebedev.com) - Author: Alexander Petrosyan (http://paf.design.ru) + Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) + Author: Alexandr Petrosian (http://paf.design.ru) - $Id: parser3.C,v 1.151 2002/01/31 10:20:21 paf Exp $ + $Id: parser3.C,v 1.166 2002/04/04 07:57:50 paf Exp $ */ #include "pa_config_includes.h" @@ -29,6 +29,15 @@ #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 @@ -52,6 +61,9 @@ const char **RCSIds[]={ 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 @@ -183,14 +195,16 @@ void SAPI::send_body(Pool& , const void // -char *full_file_spec(char *file_name) { +void full_file_spec(const char *file_name, char *buf, size_t buf_size) { if(file_name && !strchr(file_name, '/')) { - static char cwd[MAX_STRING]; getcwd(cwd, MAX_STRING); - static char buf[MAX_STRING]; - snprintf(buf, MAX_STRING, "%s/%s", cwd, file_name); - return buf; + char cwd[MAX_STRING]; getcwd(cwd, MAX_STRING); + snprintf(buf, buf_size, "%s/%s", cwd, file_name); + } else { + strncpy(buf, file_name, buf_size); } - return file_name; +#ifdef WIN32 + back_slashes_to_slashes(buf); +#endif } /** @@ -218,26 +232,22 @@ void real_parser_handler( // Request info Request::Info request_info; + char document_root_buf[MAX_STRING]; if(cgi) { if(const char *env_document_root=SAPI::get_env(pool, "DOCUMENT_ROOT")) request_info.document_root=env_document_root; else if(const char *path_info=SAPI::get_env(pool, "PATH_INFO")) { // IIS - size_t len=strlen(filespec_to_process)-strlen(path_info); - char *buf=(char *)pool.malloc(len+1); - memcpy(buf, filespec_to_process, len); buf[len]=0; - request_info.document_root=buf; + 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(0, 0, - 0, - "CGI: no PATH_INFO defined(in reinventing DOCUMENT_ROOT)"); + throw Exception("parser.runtime", + 0, + "CGI: no PATH_INFO defined(in reinventing DOCUMENT_ROOT)"); } else { - static char buf[MAX_STRING]; - strncpy(buf, filespec_to_process, MAX_STRING-1); buf[MAX_STRING-1]=0; - if(rsplit(buf, '/') || rsplit(buf, '\\')) // strip filename - request_info.document_root=buf; - else - request_info.document_root=""; + 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"; @@ -258,9 +268,9 @@ void real_parser_handler( } else request_info.uri=path_info; else - throw Exception(0, 0, - 0, - "CGI: no PATH_INFO defined(in reinventing REQUEST_URI)"); + throw Exception("parser.runtime", + 0, + "CGI: no PATH_INFO defined(in reinventing REQUEST_URI)"); #ifndef WIN32 // they've changed this under IIS5. @@ -293,43 +303,55 @@ void real_parser_handler( true /* status_allowed */); // some root-controlled location -#ifdef PARSER_ROOT_CONFIG_DIR - const char *root_config_filespec=PARSER_ROOT_CONFIG_DIR "/" CONFIG_FILE_NAME; + const char *root_config_filespec; + if(const char *root_config_by_env=getenv(PARSER_ROOT_CONFIG_ENV_NAME)) + root_config_filespec=root_config_by_env; + else { +#ifdef ROOT_CONFIG_DIR + root_config_filespec=ROOT_CONFIG_DIR "/" CONFIG_FILE_NAME; #else # ifdef WIN32 - // c:\windows - char root_config_path[MAX_STRING]; - GetWindowsDirectory(root_config_path, MAX_STRING); - - char root_config_filespec[MAX_STRING]; - snprintf(root_config_filespec, MAX_STRING, - "%s/%s", - root_config_path, CONFIG_FILE_NAME); + // c:\windows + char windows_dir[MAX_STRING]; + GetWindowsDirectory(windows_dir, MAX_STRING); + + char buf[MAX_STRING]; + snprintf(buf, MAX_STRING, + "%s/%s", + windows_dir, CONFIG_FILE_NAME); + + root_config_filespec=buf; # else #error must be compiled either configure/make or MSVC++ # endif #endif + } + const char *site_config_filespec; + if(const char *site_config_by_env=getenv(PARSER_SITE_CONFIG_ENV_NAME)) + site_config_filespec=site_config_by_env; + else { // beside by binary // @todo full path, not ./! - static char site_config_path[MAX_STRING]; - strncpy(site_config_path, argv0, MAX_STRING-1); site_config_path[MAX_STRING-1]=0; // filespec of my binary - if(!( - rsplit(site_config_path, '/') || - rsplit(site_config_path, '\\'))) { // strip filename - // no path, just filename - site_config_path[0]='.'; site_config_path[1]=0; + 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 + if(!( + rsplit(beside_binary_path, '/') || + rsplit(beside_binary_path, '\\'))) { // strip filename + // no path, just filename + beside_binary_path[0]='.'; beside_binary_path[1]=0; + } + char buf[MAX_STRING]; + snprintf(buf, MAX_STRING, + "%s/%s", + beside_binary_path, CONFIG_FILE_NAME); + site_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 request.core( - root_config_filespec, false, - site_config_filespec, false, + root_config_filespec, false /*don't fail_on_read_problem*/, + site_config_filespec, false /*don't fail_on_read_problem*/, header_only); // @@ -339,6 +361,16 @@ void real_parser_handler( extern void log_pool_stats(Pool& pool); log_pool_stats(pool); #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( @@ -359,13 +391,13 @@ void call_real_parser_handler__do_SEH( if(system_exception) if(_EXCEPTION_RECORD *er=system_exception->ExceptionRecord) - 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 } @@ -399,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://paf.design.ru)\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, @@ -437,11 +469,9 @@ int main(int argc, char *argv[]) { std::set_new_handler(failed_new); #endif - char *filespec_to_process=cgi?getenv("PATH_TRANSLATED"):argv[1]; -#ifdef WIN32 - back_slashes_to_slashes(filespec_to_process); -#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; @@ -468,5 +498,6 @@ int main(int argc, char *argv[]) { if(!cgi) SAPI::send_body(pool, "\n", 1); #endif +//_asm int 3; return 0; }