--- parser3/src/targets/cgi/pa_sapi_info.h 2020/11/12 16:16:01 1.9 +++ parser3/src/targets/cgi/pa_sapi_info.h 2024/11/04 22:58:37 1.19 @@ -1,7 +1,7 @@ #ifndef PA_SAPI_INFO_H #define PA_SAPI_INFO_H -#define IDENT_PA_SAPI_INFO_H "$Id: pa_sapi_info.h,v 1.9 2020/11/12 16:16:01 moko Exp $" +#define IDENT_PA_SAPI_INFO_H "$Id: pa_sapi_info.h,v 1.19 2024/11/04 22:58:37 moko Exp $" #include "pa_sapi.h" #include "pa_http.h" @@ -9,6 +9,10 @@ /// IIS refuses to read bigger chunks const size_t READ_POST_CHUNK_SIZE=0x400*0x400; // 1M +// for signal handlers and cgi console detection +static Request *request=0; + + class SAPI_Info : public PA_Allocated { public: int http_response_code; @@ -22,7 +26,7 @@ public: return 0; } - virtual bool set_env(const char* name, const char* value) { + virtual bool set_env(const char*, const char*) { return false; } @@ -51,7 +55,7 @@ public: return stdout_write(buf, size); } -} *sapiInfo = NULL; +}; class SAPI_Info_CGI : public SAPI_Info { public: @@ -69,7 +73,7 @@ public: virtual void add_header_attribute(const char* dont_store_key, const char* dont_store_value) { SAPI_Info::add_header_attribute(dont_store_key, dont_store_value); -// if(!request || !request->console.was_used()) + if(!request || !request->console.was_used()) printf("%s: %s\n", capitalize(dont_store_key), dont_store_value); } @@ -91,14 +95,14 @@ class SAPI_Info_HTTPD : public SAPI_Info public: HTTPD_Connection &connection; - String output; + String::Body output; HashStringString env; SAPI_Info_HTTPD(HTTPD_Connection &aconnection) : connection(aconnection) {} void populate_env() { String::Body host("localhost"); - for(Array_iterator i(connection.headers()); i.has_next(); ){ + for(Array_iterator i(connection.headers()); i; ){ HTTP_Headers::Header header=i.next(); String name("HTTP_"); name << replace_char(header.name.cstrm(), '-', '_'); @@ -118,13 +122,18 @@ public: env.put("QUERY_STRING", connection.query()); env.put("SERVER_NAME", host); + env.put("SERVER_PORT", HTTPD_Server::port); env.put("REMOTE_ADDR", connection.remote_addr); } virtual char* get_env(const char* name) { - String::Body value = env.get(name); - return !value ? NULL : value.cstrm(); + String::Body request_value = env.get(name); + if(!request_value.is_empty()) + return request_value.cstrm(); + if(char *server_value=getenv(name)) + return pa_strdup(server_value); + return NULL; } virtual bool set_env(const char* name, const char* value) { @@ -157,15 +166,22 @@ public: output << capitalize(dont_store_key) << ": " << pa_strdup(dont_store_value) << "\r\n"; } + void clear_response_headers() { + http_response_code=200; + output.clear(); + } + static const char *exception_http_status(const char *type) { struct Lookup { const char *code; const char *type; } static lookup[] = { + { "", "httpd.write"}, {"400", "httpd.request"}, {"400", "http.response"}, {"404", "file.missing"}, {"408", "httpd.timeout"}, + {"408", "httpd.read"}, {"501", "httpd.method"}, { NULL, ""} }; @@ -182,6 +198,7 @@ public: const char *message; } static lookup[] = { {200, "OK"}, + {204, "No Content"}, {206, "Partial Content"}, {301, "Moved Permanently"}, {302, "Found"}, @@ -191,6 +208,7 @@ public: {403, "Forbidden"}, {404, "Not Found"}, {408, "Request Timeout"}, + {416, "Range Not Satisfiable"}, {500, "Internal Server Error"}, {501, "Not Implemented"}, {502, "Bad Gateway"}, @@ -206,7 +224,7 @@ public: virtual void send_header() { String result("HTTP/1.0 "); - result << String::Body::Format(http_response_code) << " " << status_message(http_response_code) << "\r\n" << output << "\r\n"; + result << pa_uitoa(http_response_code) << " " << status_message(http_response_code) << "\r\n" << output << "\r\n"; send_body(result.cstr(), result.length()); }