Logo Search packages:      
Sourcecode: parser version File versions  Download package

static void real_parser_handler ( const char *  filespec_to_process,
const char *  request_method,
bool  header_only 
) [static]

main workhorse

Todo:
IIS: remove trailing default-document[index.html] from $request.uri. to do that we need to consult metabase, wich is tested but seems slow.

Definition at line 366 of file parser3.C.

References Request_info::args_skip, Request_info::argv, cgi, Request_info::content_length, Request_info::content_type, Request_info::cookie, Request::core(), SAPI::die(), Request_info::document_root, String::L_AS_IS, String::L_HTML, String::L_OPTIMIZE_BIT, SAPI::log(), mail_received, Request_info::mail_received, MAX_STRING, Request_info::method, pa_globals_done(), pa_globals_init(), Request_info::path_translated, Request_info::query_string, and Request_info::uri.

{
      // init socks
      pa_socks_init();

      // init global variables
      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);
      
      // Request info
      Request_info request_info;  memset(&request_info, 0, sizeof(request_info));
      char document_root_buf[MAX_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
            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=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;

            if(env_request_uri) { // apache & others stuck to standards
                  /*
                        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
                        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'

                        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)");
            }
      } else
            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.argv=argv_all;
      request_info.args_skip=args_skip;

      // get request_info ptr for signal handlers
      ::request_info=&request_info;
      if(execution_canceled)
            SAPI::die("Execution canceled");

#ifdef PA_DEBUG_CGI_ENTRY_EXIT
      log("request_info: method=%s, uri=%s, q=%s, dr=%s, pt=%s, cookies=%s, cl=%u", 
            request_info.method,
            request_info.uri,
            request_info.query_string,
            request_info.document_root,
            request_info.path_translated,
            request_info.cookie,
            request_info.content_length);
#endif

      // prepare to process request
      Request request(SAPI_info, request_info,
            cgi ? String::Language(String::L_HTML|String::L_OPTIMIZE_BIT) : String::L_AS_IS,
            true /* status_allowed */);

      // get request ptr for signal handlers
      ::request=&request;

      char config_filespec_buf[MAX_STRING];
      if(!config_filespec_cstr) {
            const char* config_by_env=getenv(PARSER_CONFIG_ENV_NAME);
            if(!config_by_env)
                  config_by_env=getenv(REDIRECT_PREFIX PARSER_CONFIG_ENV_NAME);
            if(config_by_env)
                  config_filespec_cstr=config_by_env;
            else {
                  // beside by binary
                  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
                        // @todo full path, not ./!
                        beside_binary_path[0]='.'; beside_binary_path[1]=0;
                  }
                  snprintf(config_filespec_buf, MAX_STRING, 
                        "%s/%s", 
                        beside_binary_path, AUTO_FILE_NAME);
                  config_filespec_cstr=config_filespec_buf;
                  fail_on_config_read_problem=entry_exists(config_filespec_cstr);
            }
      }
      
      // process the request
      request.core(
            config_filespec_cstr, fail_on_config_read_problem,
            header_only);

      // no request [prevent signal handlers from accessing invalid memory]
      ::request=0;

      // finalize global variables
      pa_globals_done();

      //
      pa_socks_done();
}


Generated by  Doxygen 1.6.0   Back to index