Diff for /parser3/src/targets/cgi/pa_sapi_info.h between versions 1.9 and 1.20

version 1.9, 2020/11/12 16:16:01 version 1.20, 2024/11/09 15:38:21
Line 8 Line 8
   
 /// IIS refuses to read bigger chunks  /// IIS refuses to read bigger chunks
 const size_t READ_POST_CHUNK_SIZE=0x400*0x400; // 1M  const size_t READ_POST_CHUNK_SIZE=0x400*0x400; // 1M
   const int HEADERS_SENT = 999; // can't send error message after headers have been sent
   
   // for signal handlers and cgi console detection
   static Request *request=0;
   
   
 class SAPI_Info : public PA_Allocated {  class SAPI_Info : public PA_Allocated {
 public:  public:
         int http_response_code;          int http_response_code;
           String::Body headers;
   
         SAPI_Info() : http_response_code(200) {}          SAPI_Info() : http_response_code(200) {}
   
Line 22  public: Line 28  public:
                         return 0;                          return 0;
         }          }
   
         virtual bool set_env(const char* name, const char* value) {          virtual bool set_env(const char*, const char*) {
                 return false;                  return false;
         }          }
   
Line 40  public: Line 46  public:
                 return 0;                  return 0;
         }          }
   
         virtual void add_header_attribute(const char* dont_store_key, const char* dont_store_value) {          virtual void add_header(const char* dont_store_key, const char* dont_store_value) {
                   if(strcasecmp(dont_store_key, "location")==0)
                           http_response_code=302;
                 if(strcasecmp(dont_store_key, HTTP_STATUS)==0)                  if(strcasecmp(dont_store_key, HTTP_STATUS)==0)
                         http_response_code=atoi(dont_store_value);                          http_response_code=atoi(dont_store_value);
         }          }
   
         virtual void send_header() {}          virtual void send_headers() {}
   
         virtual size_t send_body(const void *buf, size_t size) {          virtual size_t send_body(const void *buf, size_t size) {
                 return stdout_write(buf, size);                  return stdout_write(buf, size);
         }          }
   
 } *sapiInfo = NULL;          virtual void send_error(const char *exception_cstr, const char *status){
                   http_response_code=atoi(status);
                   send_body(exception_cstr, strlen(exception_cstr));
           }
   };
   
 class SAPI_Info_CGI : public SAPI_Info {  class SAPI_Info_CGI : public SAPI_Info {
 public:  public:
Line 67  public: Line 79  public:
                 return read_size;                  return read_size;
         }          }
   
         virtual void add_header_attribute(const char* dont_store_key, const char* dont_store_value) {          virtual void add_header(const char* dont_store_key, const char* dont_store_value) {
                 SAPI_Info::add_header_attribute(dont_store_key, dont_store_value);                  headers << capitalize(dont_store_key) << ": " << pa_strdup(dont_store_value) << "\r\n";
 //              if(!request || !request->console.was_used())  
                         printf("%s: %s\n", capitalize(dont_store_key), dont_store_value);  
         }          }
   
         virtual void send_header() {          virtual void send_headers() {
                 puts("");                  if(!request || !request->console.was_used()){
                           headers << "\r\n";
                           send_body(headers.cstr(), headers.length());
                           http_response_code=HEADERS_SENT;
                   }
         }          }
   
           virtual void send_error(const char *exception_cstr, const char *status){
                   if (http_response_code==HEADERS_SENT)
                           return;
                   // memory allocation is not allowed
                   char buf[MAX_STRING];
                   snprintf(buf, MAX_STRING, HTTP_STATUS_CAPITALIZED ": %s\r\n"
                                   HTTP_CONTENT_TYPE_CAPITALIZED ": text/plain\r\n\r\n", status);
                   send_body(buf, strlen(buf));
                   send_body(exception_cstr, strlen(exception_cstr));
           }
   
 };  };
   
 char* replace_char(char* str, char from, char to){  static char* replace_char(char* str, char from, char to){
     for(char *pos = strchr(str,from); pos; pos=strchr(pos,from)) {      for(char *pos = strchr(str,from); pos; pos=strchr(pos,from)) {
         *pos = to;          *pos = to;
     }      }
Line 91  class SAPI_Info_HTTPD : public SAPI_Info Line 115  class SAPI_Info_HTTPD : public SAPI_Info
 public:  public:
   
         HTTPD_Connection &connection;          HTTPD_Connection &connection;
         String output;  
         HashStringString env;          HashStringString env;
   
         SAPI_Info_HTTPD(HTTPD_Connection &aconnection) : connection(aconnection) {}          SAPI_Info_HTTPD(HTTPD_Connection &aconnection) : connection(aconnection) {}
   
         void populate_env() {          void populate_env() {
                 String::Body host("localhost");                  String::Body host("localhost");
                 for(Array_iterator<HTTP_Headers::Header> i(connection.headers()); i.has_next(); ){                  for(Array_iterator<HTTP_Headers::Header> i(connection.headers()); i; ){
                         HTTP_Headers::Header header=i.next();                          HTTP_Headers::Header header=i.next();
                         String name("HTTP_");                          String name("HTTP_");
                         name << replace_char(header.name.cstrm(), '-', '_');                          name << replace_char(header.name.cstrm(), '-', '_');
Line 118  public: Line 141  public:
                 env.put("QUERY_STRING", connection.query());                  env.put("QUERY_STRING", connection.query());
   
                 env.put("SERVER_NAME", host);                  env.put("SERVER_NAME", host);
                   env.put("SERVER_PORT", HTTPD_Server::port);
                 env.put("REMOTE_ADDR", connection.remote_addr);                  env.put("REMOTE_ADDR", connection.remote_addr);
   
         }          }
   
         virtual char* get_env(const char* name) {          virtual char* get_env(const char* name) {
                 String::Body value = env.get(name);                  String::Body request_value = env.get(name);
                 return !value ? NULL : value.cstrm();                  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) {          virtual bool set_env(const char* name, const char* value) {
Line 148  public: Line 176  public:
                 return connection.read_post(buf, max_bytes);                  return connection.read_post(buf, max_bytes);
         }          }
   
         virtual void add_header_attribute(const char* dont_store_key, const char* dont_store_value) {  
                 if(strcasecmp(dont_store_key, "location")==0)  
                         http_response_code=302;  
                 if(strcasecmp(dont_store_key, HTTP_STATUS)==0)  
                         http_response_code=atoi(dont_store_value);  
                 else  
                         output << capitalize(dont_store_key) << ": " << pa_strdup(dont_store_value) << "\r\n";  
         }  
   
         static const char *exception_http_status(const char *type) {          static const char *exception_http_status(const char *type) {
                 struct Lookup {                  struct Lookup {
                         const char *code;                          const char *code;
                         const char *type;                          const char *type;
                 } static lookup[] = {                  } static lookup[] = {
                           {  "",  "httpd.write"},
                         {"400", "httpd.request"},                          {"400", "httpd.request"},
                         {"400", "http.response"},                          {"400", "http.response"},
                         {"404", "file.missing"},                          {"404", "file.missing"},
                         {"408", "httpd.timeout"},                          {"408", "httpd.timeout"},
                           {"408", "httpd.read"},
                         {"501", "httpd.method"},                          {"501", "httpd.method"},
                         { NULL, ""}                          { NULL, ""}
                 };                  };
Line 182  public: Line 203  public:
                         const char *message;                          const char *message;
                 } static lookup[] = {                  } static lookup[] = {
                         {200, "OK"},                          {200, "OK"},
                           {204, "No Content"},
                         {206, "Partial Content"},                          {206, "Partial Content"},
                         {301, "Moved Permanently"},                          {301, "Moved Permanently"},
                         {302, "Found"},                          {302, "Found"},
Line 191  public: Line 213  public:
                         {403, "Forbidden"},                          {403, "Forbidden"},
                         {404, "Not Found"},                          {404, "Not Found"},
                         {408, "Request Timeout"},                          {408, "Request Timeout"},
                           {416, "Range Not Satisfiable"},
                         {500, "Internal Server Error"},                          {500, "Internal Server Error"},
                         {501, "Not Implemented"},                          {501, "Not Implemented"},
                         {502, "Bad Gateway"},                          {502, "Bad Gateway"},
Line 204  public: Line 227  public:
                 return cur->message;                  return cur->message;
         }          }
   
         virtual void send_header() {          virtual void add_header(const char* dont_store_key, const char* dont_store_value) {
                   if(strcasecmp(dont_store_key, "location")==0)
                           http_response_code=302;
                   if(strcasecmp(dont_store_key, HTTP_STATUS)==0)
                           http_response_code=atoi(dont_store_value);
                   else
                           headers << capitalize(dont_store_key) << ": " << pa_strdup(dont_store_value) << "\r\n";
           }
   
           virtual void send_headers() {
                 String result("HTTP/1.0 ");                  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" << headers << "\r\n";
                 send_body(result.cstr(), result.length());                  send_body(result.cstr(), result.length());
                   http_response_code=HEADERS_SENT;
         }          }
   
         virtual size_t send_body(const void *buf, size_t size) {          virtual size_t send_body(const void *buf, size_t size) {
                 return connection.send_body(buf, size);                  return connection.send_body(buf, size);
         }          }
   
           virtual void send_error(const char *exception_cstr, const char *status){
                   if (http_response_code==HEADERS_SENT)
                           return;
                   // memory allocation is not allowed
                   char buf[MAX_STRING];
                   snprintf(buf, MAX_STRING, "HTTP/1.0 %s %s\r\n"
                                   HTTP_CONTENT_TYPE_CAPITALIZED ": text/plain\r\n\r\n", status, status_message(atoi(status)));
                   send_body(buf, strlen(buf));
                   send_body(exception_cstr, strlen(exception_cstr));
           }
   
 };  };
   
 #endif  #endif

Removed from v.1.9  
changed lines
  Added in v.1.20


E-mail: