Diff for /parser3/src/main/pa_common.C between versions 1.143.2.21.2.27 and 1.160

version 1.143.2.21.2.27, 2003/04/11 12:29:00 version 1.160, 2003/10/30 12:13:44
Line 19  static const char* IDENT_COMMON_C="$Date Line 19  static const char* IDENT_COMMON_C="$Date
 #ifdef PA_HTTP  #ifdef PA_HTTP
 #include "pa_vstring.h"  #include "pa_vstring.h"
 #include "pa_vint.h"  #include "pa_vint.h"
   #include "pa_vhash.h"
   #include "pa_vtable.h"
   
 #ifdef CYGWIN  #ifdef CYGWIN
 #define _GNU_H_WINDOWS32_SOCKETS  #define _GNU_H_WINDOWS32_SOCKETS
Line 133  const String file_status_name(FILE_STATU Line 135  const String file_status_name(FILE_STATU
 #define HTTP_HEADERS_NAME "headers"  #define HTTP_HEADERS_NAME "headers"
 #define HTTP_ANY_STATUS_NAME "any-status"  #define HTTP_ANY_STATUS_NAME "any-status"
 #define HTTP_CHARSET_NAME "charset"  #define HTTP_CHARSET_NAME "charset"
   #define HTTP_TABLES_NAME "tables"
   
 // statics  // statics
   
Line 141  static const String http_timeout_name(HT Line 144  static const String http_timeout_name(HT
 static const String http_headers_name(HTTP_HEADERS_NAME);  static const String http_headers_name(HTTP_HEADERS_NAME);
 static const String http_any_status_name(HTTP_ANY_STATUS_NAME);  static const String http_any_status_name(HTTP_ANY_STATUS_NAME);
 static const String http_charset_name(HTTP_CHARSET_NAME);  static const String http_charset_name(HTTP_CHARSET_NAME);
   static const String http_tables_name(HTTP_TABLES_NAME);
   
 // defines  // defines
   
Line 168  void fix_line_breaks(char *str, size_t& Line 172  void fix_line_breaks(char *str, size_t&
                 } else // \r, not \n = Macintosh                  } else // \r, not \n = Macintosh
                         bol=eol+1;                          bol=eol+1;
         }          }
         // last piece without \r, including terminating 0          // last piece without \r
         if(dest!=bol)          if(dest!=bol)
                 memcpy(dest, bol, eob-bol);                   memcpy(dest, bol, eob-bol); 
           str[length]=0; // terminating
 }  }
   
 char* file_read_text(Request_charsets& charsets,   char* file_read_text(Request_charsets& charsets, 
Line 185  char* file_read_text(Request_charsets& c Line 190  char* file_read_text(Request_charsets& c
 #ifdef PA_HTTP  #ifdef PA_HTTP
 //http request stuff  //http request stuff
   
   #undef CRLF
   #define CRLF "\r\n"
   
 static bool set_addr(struct sockaddr_in *addr, const char* host, const short port){  static bool set_addr(struct sockaddr_in *addr, const char* host, const short port){
     memset(addr, 0, sizeof(*addr));       memset(addr, 0, sizeof(*addr)); 
     addr->sin_family=AF_INET;      addr->sin_family=AF_INET;
Line 208  static int http_read_response(String& re Line 216  static int http_read_response(String& re
                 if(size<=0)                  if(size<=0)
                         break;                          break;
                 response.append_strdup(buf, size, String::L_TAINTED);                   response.append_strdup(buf, size, String::L_TAINTED); 
                 if(!result && (EOLat=response.pos("\r\n", 2))!=STRING_NOT_FOUND) { // checking status in first response                  if(!result && (EOLat=response.pos(CRLF, 2))!=STRING_NOT_FOUND) { // checking status in first response
                         const String& status_line=response.mid(0, (size_t)EOLat);                          const String& status_line=response.mid(0, (size_t)EOLat);
                         ArrayString astatus;                           ArrayString astatus; 
                         size_t pos_after=0;                          size_t pos_after=0;
Line 325  static void http_pass_header(HashStringV Line 333  static void http_pass_header(HashStringV
                              Http_pass_header_info *info) {                               Http_pass_header_info *info) {
     *info->request <<key<<": "      *info->request <<key<<": "
         << attributed_meaning_to_string(*value, String::L_HTTP_HEADER, false)          << attributed_meaning_to_string(*value, String::L_HTTP_HEADER, false)
         << "\n";           << CRLF; 
                   
     if(String(key, String::L_TAINTED).change_case(info->charsets->source(), String::CC_UPPER)=="USER-AGENT")      if(String(key, String::L_TAINTED).change_case(info->charsets->source(), String::CC_UPPER)=="USER-AGENT")
         info->user_agent_specified=true;          info->user_agent_specified=true;
Line 333  static void http_pass_header(HashStringV Line 341  static void http_pass_header(HashStringV
   
   
 static Charset* detect_charset(Charset& source_charset, const String& content_type_value) {  static Charset* detect_charset(Charset& source_charset, const String& content_type_value) {
         const StringBody CONTENT_TYPE_VALUE=          const String::Body CONTENT_TYPE_VALUE=
                 content_type_value.change_case(source_charset, String::CC_UPPER);                  content_type_value.change_case(source_charset, String::CC_UPPER);
         // content-type: xxx/xxx; source_charset=WE-NEED-THIS          // content-type: xxx/xxx; source_charset=WE-NEED-THIS
         // content-type: xxx/xxx; source_charset="WE-NEED-THIS"          // content-type: xxx/xxx; source_charset="WE-NEED-THIS"
Line 355  static Charset* detect_charset(Charset& Line 363  static Charset* detect_charset(Charset&
                         if(delim_pos!=STRING_NOT_FOUND)                          if(delim_pos!=STRING_NOT_FOUND)
                                 charset_end=delim_pos;                                  charset_end=delim_pos;
                 }                  }
                 const StringBody CHARSET_NAME_BODY=                  const String::Body CHARSET_NAME_BODY=
                         CONTENT_TYPE_VALUE.mid(charset_begin, charset_end);                          CONTENT_TYPE_VALUE.mid(charset_begin, charset_end);
   
                 return &charsets.get(CHARSET_NAME_BODY);                  return &charsets.get(CHARSET_NAME_BODY);
Line 371  struct File_read_http_result { Line 379  struct File_read_http_result {
         HashStringValue* headers;          HashStringValue* headers;
 };   }; 
 #endif  #endif
   /// @todo build .cookies field. use ^file.tables.SET-COOKIES.menu{ for now
 static File_read_http_result file_read_http(Request_charsets& charsets,   static File_read_http_result file_read_http(Request_charsets& charsets, 
                                             const String& file_spec,                                               const String& file_spec, 
                                             HashStringValue *options=0) {                                              HashStringValue *options=0) {
Line 448  static File_read_http_result file_read_h Line 457  static File_read_http_result file_read_h
                         request<<method;                          request<<method;
                 else                  else
                         request<<"GET";                          request<<"GET";
                 request<< " "<< uri <<" HTTP/1.0\n"                  request<< " "<< uri <<" HTTP/1.0" CRLF
                         "host: "<< host <<"\n";                           "host: "<< host << CRLF; 
                 bool user_agent_specified=false;                  bool user_agent_specified=false;
                 if(vheaders && !vheaders->is_string()) { // allow empty                  if(vheaders && !vheaders->is_string()) { // allow empty
                         if(HashStringValue *headers=vheaders->get_hash()) {                          if(HashStringValue *headers=vheaders->get_hash()) {
Line 462  static File_read_http_result file_read_h Line 471  static File_read_http_result file_read_h
                                         "headers param must be hash");                                           "headers param must be hash"); 
                 };                  };
                 if(!user_agent_specified) // defaulting                  if(!user_agent_specified) // defaulting
                         request << "user-agent: " DEFAULT_USER_AGENT "\n";                          request << "user-agent: " DEFAULT_USER_AGENT CRLF;
                 request<<"\n";                   request << CRLF; 
   
                 request_cstr=request.cstr(String::L_UNSPECIFIED);                  request_cstr=request.cstr(String::L_UNSPECIFIED);
         }          }
Line 481  static File_read_http_result file_read_h Line 490  static File_read_http_result file_read_h
                 timeout, fail_on_status_ne_200);                   timeout, fail_on_status_ne_200); 
                   
         //processing results              //processing results    
         size_t pos=response.pos("\r\n\r\n", 4);           size_t pos=response.pos(CRLF CRLF, 4); 
         if(pos==STRING_NOT_FOUND || pos<1) {          if(pos==STRING_NOT_FOUND || pos<1) {
                 throw Exception("http.response",                   throw Exception("http.response", 
                         &connect_string,                          &connect_string,
Line 492  static File_read_http_result file_read_h Line 501  static File_read_http_result file_read_h
                   
         ArrayString aheaders;          ArrayString aheaders;
         result.headers=new HashStringValue;          result.headers=new HashStringValue;
           VHash* vtables=new VHash;
           result.headers->put(http_tables_name, vtables);
           HashStringValue& tables=vtables->hash();
   
         size_t pos_after=0;          size_t pos_after=0;
         header_block.split(aheaders, pos_after, "\r\n");           header_block.split(aheaders, pos_after, CRLF); 
                   
         //processing headers          //processing headers
         size_t aheaders_count=aheaders.count();          size_t aheaders_count=aheaders.count();
Line 505  static File_read_http_result file_read_h Line 518  static File_read_http_result file_read_h
                         throw Exception("http.response",                           throw Exception("http.response", 
                                 &connect_string,                                  &connect_string,
                                 "bad response from host - bad header \"%s\"", line.cstr());                                  "bad response from host - bad header \"%s\"", line.cstr());
                 const StringBody HEADER_NAME=                  const String::Body HEADER_NAME=
                         line.mid(0, pos).change_case(charsets.source(), String::CC_UPPER);                          line.mid(0, pos).change_case(charsets.source(), String::CC_UPPER);
                 const String& header_value=line.mid(pos+2, line.length());                  const String& header_value=line.mid(pos+2, line.length());
                 if(HEADER_NAME=="CONTENT-TYPE")                  if(HEADER_NAME=="CONTENT-TYPE")
                         real_remote_charset=detect_charset(charsets.source(), header_value);                          real_remote_charset=detect_charset(charsets.source(), header_value);
   
                   // tables
                   {
                           Value *valready=(Value *)tables.get(HEADER_NAME);
                           bool existed=valready!=0;
                           Table *table;
                           if(existed) {
                                   // second+ appearence
                                   table=valready->get_table();
                           } else {
                                   // first appearence
                                   Table::columns_type columns =new ArrayString(1);
                                   *columns+=new String("value");
                                   table=new Table(columns);
                           }
                           // this string becomes next row
                           ArrayString& row=*new ArrayString(1);
                           row+=&header_value;
                           *table+=&row;
                           // not existed before? add it
                           if(!existed)
                                   tables.put(HEADER_NAME, new VTable(table));
                   }
   
                 result.headers->put(HEADER_NAME, new VString(header_value));                  result.headers->put(HEADER_NAME, new VString(header_value));
         }          }
         // defaulting to used-asked charset [it's never empty!]          // defaulting to used-asked charset [it's never empty!]
Line 548  static void file_read_action( Line 585  static void file_read_action(
                 if(ssize_t(*info.data_size)<0 || *info.data_size>to_read_size)                  if(ssize_t(*info.data_size)<0 || *info.data_size>to_read_size)
                         throw Exception(0,                           throw Exception(0, 
                                 &file_spec,                                   &file_spec, 
                                 "read failed: actually read %lu bytes count not in [0..%lu] valid range",                                   "read failed: actually read %l bytes count not in [0..%lu] valid range", 
                                         *info.data_size, to_read_size);                                           *info.data_size, to_read_size); 
         } else { // empty file          } else { // empty file
                 if(as_text) {                  if(as_text) {
Line 586  File_read_result file_read(Request_chars Line 623  File_read_result file_read(Request_chars
                 // UTF-8 signature: EF BB BF                  // UTF-8 signature: EF BB BF
                 if(result.length>=3) {                  if(result.length>=3) {
                         char *in=(char *)result.str;                          char *in=(char *)result.str;
                         if(strncmp(in, "\xEB\xBB\xBF", 3)==0) {                          if(strncmp(in, "\xEF\xBB\xBF", 3)==0) {
                                 result.str=in+3; result.length-=3;// skip prefix                                  result.str=in+3; result.length-=3;// skip prefix
                         }                          }
                 }                  }

Removed from v.1.143.2.21.2.27  
changed lines
  Added in v.1.160


E-mail: