|
|
| version 1.3, 2020/10/11 22:59:19 | version 1.8, 2020/10/26 23:15:51 |
|---|---|
| Line 13 class SAPI_Info : public PA_Allocated { | Line 13 class SAPI_Info : public PA_Allocated { |
| public: | public: |
| int http_response_code; | int http_response_code; |
| SAPI_Info() : http_response_code(0) {} | SAPI_Info() : http_response_code(200) {} |
| virtual char* get_env(const char* name) { | virtual char* get_env(const char* name) { |
| if(char *local=getenv(name)) | if(char *local=getenv(name)) |
| Line 22 public: | Line 22 public: |
| return 0; | return 0; |
| } | } |
| virtual bool set_env(const char* name, const char* value) { | |
| return false; | |
| } | |
| virtual const char* const *get_env() { | virtual const char* const *get_env() { |
| #ifdef _MSC_VER | #ifdef _MSC_VER |
| extern char **_environ; | extern char **_environ; |
| Line 47 public: | Line 51 public: |
| return stdout_write(buf, size); | return stdout_write(buf, size); |
| } | } |
| virtual void die(const char *content, int content_length) { | |
| stdout_write(content, content_length); | |
| } | |
| } *sapiInfo = NULL; | } *sapiInfo = NULL; |
| class SAPI_Info_CGI : public SAPI_Info { | class SAPI_Info_CGI : public SAPI_Info { |
| Line 77 public: | Line 77 public: |
| puts(""); | puts(""); |
| } | } |
| virtual void die(const char *content, int content_length) { | |
| // prepare header | |
| // let's be honest, that's bad we couldn't produce valid output | |
| // capitalized headers passed for preventing malloc during capitalization | |
| add_header_attribute(HTTP_STATUS_CAPITALIZED, "500"); | |
| add_header_attribute(HTTP_CONTENT_TYPE_CAPITALIZED, "text/plain"); | |
| // don't use 'format' function because it calls malloc | |
| char content_length_cstr[MAX_NUMBER]; | |
| snprintf(content_length_cstr, sizeof(content_length_cstr), "%u", content_length); | |
| add_header_attribute(HTTP_CONTENT_LENGTH_CAPITALIZED, content_length_cstr); | |
| // send header | |
| send_header(); | |
| // body | |
| send_body(content, content_length); | |
| } | |
| }; | }; |
| Line 143 public: | Line 127 public: |
| return !value ? NULL : value.cstrm(); | return !value ? NULL : value.cstrm(); |
| } | } |
| virtual bool set_env(const char* name, const char* value) { | |
| env.put(name, *new String(value)); | |
| return true; | |
| } | |
| virtual const char* const *get_env() { | virtual const char* const *get_env() { |
| const char** result=new(PointerGC) const char*[env.count()+1/*0*/]; | const char** result=new(PointerGC) const char*[env.count()+1/*0*/]; |
| const char** cur=result; | const char** cur=result; |
| Line 155 public: | Line 144 public: |
| return result; | return result; |
| } | } |
| virtual size_t read_post(char *, size_t) { | virtual size_t read_post(char *buf, size_t max_bytes) { |
| return 0; | return connection.read_post(buf, max_bytes); |
| } | } |
| virtual void add_header_attribute(const char* dont_store_key, const char* dont_store_value) { | virtual void add_header_attribute(const char* dont_store_key, const char* dont_store_value) { |
| Line 168 public: | Line 157 public: |
| output << capitalize(dont_store_key) << ": " << pa_strdup(dont_store_value) << "\r\n"; | output << capitalize(dont_store_key) << ": " << pa_strdup(dont_store_value) << "\r\n"; |
| } | } |
| static const char *message(int code) { | static const char *exception_http_status(const char *type) { |
| struct Lookup { | |
| const char *code; | |
| const char *type; | |
| } static lookup[] = { | |
| {"400", "httpd.request"}, | |
| {"404", "file.missing"}, | |
| {"408", "httpd.timeout"}, | |
| {"501", "httpd.method"}, | |
| { NULL, ""} | |
| }; | |
| Lookup *cur = lookup; | |
| for(; cur->code; cur++) | |
| if(!strcmp(type, cur->type)) | |
| return cur->code; | |
| return "500"; | |
| } | |
| static const char *status_message(int code) { | |
| struct Lookup { | struct Lookup { |
| int code; | int code; |
| const char *message; | const char *message; |
| Line 177 public: | Line 184 public: |
| {206, "Partial Content"}, | {206, "Partial Content"}, |
| {301, "Moved Permanently"}, | {301, "Moved Permanently"}, |
| {302, "Found"}, | {302, "Found"}, |
| {304, "Not Modified"}, | |
| {400, "Bad Request"}, | {400, "Bad Request"}, |
| {401, "Unauthorized"}, | {401, "Unauthorized"}, |
| {403, "Forbidden"}, | {403, "Forbidden"}, |
| {404, "Not Found"}, | {404, "Not Found"}, |
| {408, "Request Timeout"}, | |
| {500, "Internal Server Error"}, | {500, "Internal Server Error"}, |
| {501, "Not Implemented"}, | {501, "Not Implemented"}, |
| {502, "Bad Gateway"}, | {502, "Bad Gateway"}, |
| Line 196 public: | Line 205 public: |
| virtual void send_header() { | virtual void send_header() { |
| String result("HTTP/1.0 "); | String result("HTTP/1.0 "); |
| result << String::Body::Format(http_response_code) << " " << message(http_response_code) << "\r\n" << output << "\r\n"; | result << String::Body::Format(http_response_code) << " " << status_message(http_response_code) << "\r\n" << output << "\r\n"; |
| send_body(result.cstr(), result.length()); | send_body(result.cstr(), result.length()); |
| } | } |
| virtual size_t send_body(const void *buf, size_t size) { | virtual size_t send_body(const void *buf, size_t size) { |
| if(send(connection.sock, buf, size, 0)!=(ssize_t)size) { | return connection.send_body(buf, size); |
| int no=pa_socks_errno(); | |
| throw Exception("httpd.timeout", 0, "error sending response: %s (%d)", pa_socks_strerr(no), no); | |
| } | |
| return size; | |
| } | } |
| }; | }; |