Diff for /parser3/src/main/pa_http.C between versions 1.31 and 1.36

version 1.31, 2009/07/15 13:00:24 version 1.36, 2009/08/22 14:23:51
Line 313  static int http_request(char*& response, Line 313  static int http_request(char*& response,
 struct Http_pass_header_info {  struct Http_pass_header_info {
         Request_charsets* charsets;          Request_charsets* charsets;
         String* request;          String* request;
         bool user_agent_specified;          bool* user_agent_specified;
         bool content_type_specified;          bool* content_type_specified;
           bool* content_type_url_encoded;
 };  };
 #endif  #endif
 static void http_pass_header(HashStringValue::key_type name,   static void http_pass_header(HashStringValue::key_type aname, 
                                 HashStringValue::value_type value,                                   HashStringValue::value_type avalue, 
                                 Http_pass_header_info *info) {                                  Http_pass_header_info *info) {
   
         String aname=String(name, String::L_URI);          String name=String(aname, String::L_URI);
           String value=attributed_meaning_to_string(*avalue, String::L_URI, false);
   
         *info->request << aname << ": "          *info->request << name << ": " << value << CRLF;
                 << attributed_meaning_to_string(*value, String::L_URI, false)  
                 << CRLF;   
                   
         const String::Body name_upper=aname.change_case(info->charsets->source(), String::CC_UPPER);          const String::Body name_upper=name.change_case(info->charsets->source(), String::CC_UPPER);
         if(name_upper==HTTP_USER_AGENT_UPPER)          if(name_upper==HTTP_USER_AGENT_UPPER)
                 info->user_agent_specified=true;                  *info->user_agent_specified=true;
         if(name_upper==HTTP_CONTENT_TYPE_UPPER)          if(name_upper==HTTP_CONTENT_TYPE_UPPER){
                 info->content_type_specified=true;                  *info->content_type_specified=true;
                   *info->content_type_url_encoded=StrStartFromNC(value.cstr(), HTTP_CONTENT_TYPE_FORM_URLENCODED);
           }
 }  }
   
 static void http_pass_cookie(HashStringValue::key_type name,   static void http_pass_cookie(HashStringValue::key_type name, 
Line 399  static void form_value2string( Line 401  static void form_value2string(
 const char* pa_form2string(HashStringValue& form, Request_charsets& charsets) {  const char* pa_form2string(HashStringValue& form, Request_charsets& charsets) {
         String string;          String string;
         form.for_each<String*>(form_value2string, &string);          form.for_each<String*>(form_value2string, &string);
         return string.untaint_cstr(String::L_AS_IS, 0, &charsets);          return string.transcode_and_untaint_cstr(String::L_URI, &charsets);
 }  }
   
 struct FormPart {  struct FormPart {
Line 456  static void form_value2part( Line 458  static void form_value2part(
                 Form_table_value2string_info info(key, part.string);                  Form_table_value2string_info info(key, part.string);
                 part.info = &info;                  part.info = &info;
                 tvalue->for_each(form_table_value2part, &part);                  tvalue->for_each(form_table_value2part, &part);
         } else if(VFile* vfile=static_cast<VFile *>(value->as("file", false))){          } else if(VFile* vfile=static_cast<VFile *>(value->as("file"))){
                 form_file_value2part(key, *vfile, part);                  form_file_value2part(key, *vfile, part);
         } else          } else
                 throw Exception(PARSER_RUNTIME,                  throw Exception(PARSER_RUNTIME,
Line 612  File_read_http_result pa_internal_file_r Line 614  File_read_http_result pa_internal_file_r
                 // influence URLencoding of tainted pieces to String::L_URI lang                  // influence URLencoding of tainted pieces to String::L_URI lang
                 Temp_client_charset temp(r.charsets, *asked_remote_charset);                  Temp_client_charset temp(r.charsets, *asked_remote_charset);
   
                 const char* connect_string_cstr=connect_string.untaint_cstr(String::L_URI, 0, &(r.charsets));                  const char* connect_string_cstr=connect_string.transcode_and_untaint_cstr(String::L_URI, &(r.charsets));
   
                 const char* current=connect_string_cstr;                  const char* current=connect_string_cstr;
                 if(strncmp(current, "http://", 7)!=0)                  if(strncmp(current, "http://", 7)!=0)
Line 622  File_read_http_result pa_internal_file_r Line 624  File_read_http_result pa_internal_file_r
                 current+=7;                  current+=7;
   
                 strncpy(host, current, sizeof(host)-1);  host[sizeof(host)-1]=0;                  strncpy(host, current, sizeof(host)-1);  host[sizeof(host)-1]=0;
                 char* host_uri=lsplit(host, '/');                   char* host_uri=lsplit(host, '/');
                 uri=host_uri?current+(host_uri-1-host):"/";                   uri=host_uri?current+(host_uri-1-host):"/";
                 char* port_cstr=lsplit(host, ':');                   char* port_cstr=lsplit(host, ':');
                 char* error_pos=0;                  char* error_pos=0;
                 port=port_cstr?(short)strtol(port_cstr, &error_pos, 0):80;                  port=port_cstr?(short)strtol(port_cstr, &error_pos, 0):80;
   
Line 650  File_read_http_result pa_internal_file_r Line 652  File_read_http_result pa_internal_file_r
                                 uuid.node[3], uuid.node[4], uuid.node[5]);                                  uuid.node[3], uuid.node[4], uuid.node[5]);
                 }                  }
   
                   String user_headers;
                   bool user_agent_specified=false;
                   bool content_type_specified=false;
                   bool content_type_url_encoded=false;
                   if(vheaders && !vheaders->is_string()) { // allow empty
                           if(HashStringValue *headers=vheaders->get_hash()) {
                                   Http_pass_header_info info={
                                           &(r.charsets),
                                           &user_headers,
                                           &user_agent_specified,
                                           &content_type_specified,
                                           &content_type_url_encoded};
                                   headers->for_each<Http_pass_header_info*>(http_pass_header, &info); 
                           } else
                                   throw Exception(PARSER_RUNTIME, 
                                           0,
                                           "headers param must be hash"); 
                   };
   
                 size_t post_size=0;                  size_t post_size=0;
                 if(form && !method_is_get) {                  if(form && !method_is_get) {
                         head << HTTP_CONTENT_TYPE ": " << (multipart ? HTTP_CONTENT_TYPE_MULTIPART_FORMDATA : HTTP_CONTENT_TYPE_FORM_URLENCODED);                          head << HTTP_CONTENT_TYPE ": " << (multipart ? HTTP_CONTENT_TYPE_MULTIPART_FORMDATA : HTTP_CONTENT_TYPE_FORM_URLENCODED);
Line 665  File_read_http_result pa_internal_file_r Line 686  File_read_http_result pa_internal_file_r
                                 post_size=strlen(body_cstr);                                  post_size=strlen(body_cstr);
                         }                          }
                         head << CRLF;                          head << CRLF;
                 } else if (vbody) {                  } else if(vbody) {
                         // transcode tainted pieces and then URI-encode them                          if(content_type_url_encoded){
                         body_cstr=vbody->as_string().untaint_cstr(String::L_AS_IS, 0, &(r.charsets));                                  // transcode + url-encode
                                   body_cstr=vbody->as_string().transcode_and_untaint_cstr(String::L_URI, &(r.charsets));
                         // now transcode is needed only if own content-type was specified _and_ clean chars with code>127 are in the body                          } else {
                         // @todo: I don't like the current behaviour                                  // content-type != application/x-www-form-urlencoded -> transcode only, don't url-encode!
                         body_cstr=Charset::transcode(                                  body_cstr=Charset::transcode(
                                 String::C(body_cstr, strlen(body_cstr)),                                          String::C(vbody->as_string().cstr(), vbody->as_string().length()),
                                 r.charsets.source(),                                          r.charsets.source(),
                                 *asked_remote_charset                                          *asked_remote_charset
                         );                                  );
                           }
                         post_size=strlen(body_cstr);                          post_size=strlen(body_cstr);
                 }                  }
   
Line 683  File_read_http_result pa_internal_file_r Line 705  File_read_http_result pa_internal_file_r
                 if(const String* authorization_field_value=basic_authorization_field(user_cstr, password_cstr))                  if(const String* authorization_field_value=basic_authorization_field(user_cstr, password_cstr))
                         head<<"authorization: "<<*authorization_field_value<<CRLF;                          head<<"authorization: "<<*authorization_field_value<<CRLF;
   
                 bool user_agent_specified=false;                  head << user_headers;
                 bool content_type_specified=false;  
                 if(vheaders && !vheaders->is_string()) { // allow empty  
                         if(HashStringValue *headers=vheaders->get_hash()) {  
                                 Http_pass_header_info info={&(r.charsets), &head, false};  
                                 headers->for_each<Http_pass_header_info*>(http_pass_header, &info);   
                                 user_agent_specified=info.user_agent_specified;  
                                 content_type_specified=info.content_type_specified;  
                         } else  
                                 throw Exception(PARSER_RUNTIME,   
                                         &connect_string,  
                                         "headers param must be hash");   
                 };  
                 if(!user_agent_specified) // defaulting                  if(!user_agent_specified) // defaulting
                         head << HTTP_USER_AGENT ": " DEFAULT_USER_AGENT CRLF;                          head << HTTP_USER_AGENT ": " DEFAULT_USER_AGENT CRLF;
   
                 if(form && !method_is_get && content_type_specified) // POST + form + content-type was specified                  if(form && !method_is_get && content_type_specified) // POST + form + content-type was specified
                         throw Exception(PARSER_RUNTIME,                          throw Exception(PARSER_RUNTIME,
                                 &connect_string,                                  0,
                                 "$.content-type can't be specified with method POST");                                   "$.content-type can't be specified with method POST"); 
   
                 if(vcookies && !vcookies->is_string()){ // allow empty                  if(vcookies && !vcookies->is_string()){ // allow empty
                         if(HashStringValue* cookies=vcookies->get_hash()) {                          if(HashStringValue* cookies=vcookies->get_hash()) {
                                 head << "cookie: ";                                  head << "cookie: ";
                                 Http_pass_header_info info={&(r.charsets), &head, false};                                  Http_pass_header_info info={&(r.charsets), &head, 0, 0, 0};
                                 cookies->for_each<Http_pass_header_info*>(http_pass_cookie, &info);                                   cookies->for_each<Http_pass_header_info*>(http_pass_cookie, &info); 
                                 head << CRLF;                                  head << CRLF;
                         } else                          } else
                                 throw Exception(PARSER_RUNTIME,                                   throw Exception(PARSER_RUNTIME, 
                                         &connect_string,                                          0,
                                         "cookies param must be hash");                                           "cookies param must be hash"); 
                 }                  }
   
Line 776  File_read_http_result pa_internal_file_r Line 787  File_read_http_result pa_internal_file_r
                         const String::Body HEADER_NAME=line.mid(0, pos).change_case(r.charsets.source(), String::CC_UPPER);                          const String::Body HEADER_NAME=line.mid(0, pos).change_case(r.charsets.source(), String::CC_UPPER);
                         const String& HEADER_VALUE=line.mid(pos+1, line.length()).trim(String::TRIM_BOTH, " \t\r");                          const String& HEADER_VALUE=line.mid(pos+1, line.length()).trim(String::TRIM_BOTH, " \t\r");
                         if(as_text && HEADER_NAME==HTTP_CONTENT_TYPE_UPPER)                          if(as_text && HEADER_NAME==HTTP_CONTENT_TYPE_UPPER)
                                 real_remote_charset=detect_charset(HEADER_VALUE.cstr(), true/*already uppercased*/);                                  real_remote_charset=detect_charset(HEADER_VALUE.cstr());
   
                         // tables                          // tables
                         {                          {

Removed from v.1.31  
changed lines
  Added in v.1.36


E-mail: