Diff for /parser3/src/main/pa_common.C between versions 1.163 and 1.171

version 1.163, 2003/11/06 14:11:14 version 1.171, 2003/12/25 07:31:13
Line 5 Line 5
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
 */  */
   
 static const char* IDENT_COMMON_C="$Date$";   static const char * const IDENT_COMMON_C="$Date$"; 
   
 #include "pa_common.h"  #include "pa_common.h"
 #include "pa_exception.h"  #include "pa_exception.h"
Line 151  static bool set_addr(struct sockaddr_in Line 151  static bool set_addr(struct sockaddr_in
     return true;      return true;
 }  }
   
 static int http_read_response(String& response, int sock, bool fail_on_status_ne_200){  static int http_read_response(char*& response, size_t& response_size, int sock, bool fail_on_status_ne_200){
           response=(char*)pa_malloc_atomic(1/*terminator*/); // setting memory block type
           response[(response_size=0)]=0;
         int result=0;          int result=0;
         size_t EOLat=0;          char* EOLat=0;
         while(true) {          while(true) {
                 char *buf=new(PointerFreeGC) char[MAX_STRING];                   char buf[MAX_STRING*10]; 
                 ssize_t size=recv(sock, buf, MAX_STRING, 0);                   ssize_t received_size=recv(sock, buf, sizeof(buf), 0); 
                 if(size<=0)                  if(received_size<=0)
                         break;                          break;
                 response.append_strdup(buf, size, String::L_TAINTED);                   response=(char*)pa_realloc(response, response_size+received_size+1/*terminator*/);
                 if(!result && (EOLat=response.pos(CRLF, 2))!=STRING_NOT_FOUND) { // checking status in first response                  memcpy(response+response_size, buf, received_size);
                         const String& status_line=response.mid(0, (size_t)EOLat);                  response_size+=received_size;
                   response[response_size]=0;
   
                   if(!result && (EOLat=strstr(response, CRLF))) { // checking status in first response
                           const String status_line(pa_strdup(response, EOLat-response));
                         ArrayString astatus;                           ArrayString astatus; 
                         size_t pos_after=0;                          size_t pos_after=0;
                         status_line.split(astatus, pos_after, " ");                           status_line.split(astatus, pos_after, " "); 
Line 179  static int http_read_response(String& re Line 185  static int http_read_response(String& re
         else          else
                 throw Exception("http.response",                  throw Exception("http.response",
                         0,                          0,
                         "bad response from host - no status found (size=%lu)", response.length());                           "bad response from host - no status found (size=%lu)", response_size); 
 }  }
   
 /* ********************** request *************************** */  /* ********************** request *************************** */
Line 195  static void timeout_handler(int sig){ Line 201  static void timeout_handler(int sig){
 }  }
 #endif  #endif
   
 static int http_request(String& response,  static int http_request(char*& response, size_t& response_size,
                         const char* host, int port,                           const char* host, int port, 
                         const char* request,                           const char* request, 
                         int timeout,                          int 
   #ifdef PA_USE_ALARM
                           timeout
   #endif
                           ,
                         bool fail_on_status_ne_200) {                          bool fail_on_status_ne_200) {
         if(!host)          if(!host)
                 throw Exception("http.host",                   throw Exception("http.host", 
Line 246  static int http_request(String& response Line 256  static int http_request(String& response
                                         0,                                           0, 
                                         "error sending request: %s (%d)", strerror(errno), errno);                                           "error sending request: %s (%d)", strerror(errno), errno); 
   
                         result=http_read_response(response, sock, fail_on_status_ne_200);                           result=http_read_response(response, response_size, sock, fail_on_status_ne_200); 
                         closesocket(sock);                           closesocket(sock); 
 #ifdef PA_USE_ALARM  #ifdef PA_USE_ALARM
                         alarm(0)                          alarm(0)
Line 326  struct File_read_http_result { Line 336  struct File_read_http_result {
 /// @todo build .cookies field. use ^file.tables.SET-COOKIES.menu{ for now  /// @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) {                                              bool as_text,
                                                   HashStringValue *options=0) {
         File_read_http_result result;          File_read_http_result result;
         char host[MAX_STRING];           char host[MAX_STRING]; 
         const char* uri;           const char* uri; 
Line 347  static File_read_http_result file_read_h Line 358  static File_read_http_result file_read_h
                         valid_options++;                          valid_options++;
                         timeout=vtimeout->as_int();                           timeout=vtimeout->as_int(); 
                 }                  }
                 if(vheaders=options->get(http_headers_name)) {                  if((vheaders=options->get(http_headers_name))) {
                         valid_options++;                          valid_options++;
                 }                  }
                 if(Value* vany_status=options->get(http_any_status_name)) {                  if(Value* vany_status=options->get(http_any_status_name)) {
Line 406  static File_read_http_result file_read_h Line 417  static File_read_http_result file_read_h
                 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()) {
                                 Http_pass_header_info info={&charsets, &request};                                  Http_pass_header_info info={&charsets, &request, false};
                                 headers->for_each(http_pass_header, &info);                                   headers->for_each(http_pass_header, &info); 
                                 user_agent_specified=info.user_agent_specified;                                  user_agent_specified=info.user_agent_specified;
                         } else                          } else
Line 428  static File_read_http_result file_read_h Line 439  static File_read_http_result file_read_h
                 *asked_remote_charset);                  *asked_remote_charset);
                   
         //sending request          //sending request
         String response;          char* response;
         int status_code=http_request(response,          size_t response_size;
           int status_code=http_request(response, response_size,
                 host, port, request_cstr,                   host, port, request_cstr, 
                 timeout, fail_on_status_ne_200);                   timeout, fail_on_status_ne_200); 
                   
         //processing results              //processing results    
         size_t pos=response.pos(CRLF CRLF, 4);           char* raw_body; size_t raw_body_size;
         if(pos==STRING_NOT_FOUND || pos<1) {          char* headers_end_at=strstr(response, CRLF CRLF /*change '4' below along!*/); 
           if(headers_end_at) {
                   raw_body=headers_end_at+4;
                   raw_body_size=response_size-(raw_body-response);
           } else
                 throw Exception("http.response",                   throw Exception("http.response", 
                         &connect_string,                          &connect_string,
                         "bad response from host - no headers found");                           "bad response from host - no headers found"); 
         }          
         const String& header_block=response.mid(0, pos);           *headers_end_at=0;
         const String& raw_body=response.mid(pos+4, response.length());           const String header_block(response, headers_end_at-response, true);
                   
         ArrayString aheaders;          ArrayString aheaders;
         result.headers=new HashStringValue;          result.headers=new HashStringValue;
Line 457  static File_read_http_result file_read_h Line 473  static File_read_http_result file_read_h
         Charset* real_remote_charset=0; // undetected, yet          Charset* real_remote_charset=0; // undetected, yet
         for(size_t i=1; i<aheaders_count; i++) {          for(size_t i=1; i<aheaders_count; i++) {
                 const String& line=*aheaders.get(i);                  const String& line=*aheaders.get(i);
                 pos=line.pos(": ", 2);                   size_t pos=line.pos(": ", 2); 
                 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 498  static File_read_http_result file_read_h Line 514  static File_read_http_result file_read_h
                 real_remote_charset=asked_remote_charset;                  real_remote_charset=asked_remote_charset;
   
         // output response          // output response
         String::C real_body=Charset::transcode(          String::C real_body=String::C(raw_body, raw_body_size);
                 String::C(raw_body.cstrm()/*must be modifiable*/, raw_body.length()),          if(as_text && raw_body_size) // must be checked because transcode returns CONST string in case length==0, which contradicts hacking few lines below
                 *real_remote_charset,                  real_body=Charset::transcode(real_body, *real_remote_charset, charsets.source());
                 charsets.source());  
   
         result.str=const_cast<char *>(real_body.str); // hacking a little          result.str=const_cast<char *>(real_body.str); // hacking a little
         result.length=real_body.length;          result.length=real_body.length;
Line 519  struct File_read_action_info { Line 534  struct File_read_action_info {
 static void file_read_action(  static void file_read_action(
                              struct stat& finfo,                                struct stat& finfo, 
                              int f,                                int f, 
                              const String& file_spec, const char* fname, bool as_text,                                const String& file_spec, const char* /*fname*/, bool as_text, 
                              void *context) {                               void *context) {
         File_read_action_info& info=*static_cast<File_read_action_info *>(context);           File_read_action_info& info=*static_cast<File_read_action_info *>(context); 
         if(size_t to_read_size=(size_t)finfo.st_size) {           if(size_t to_read_size=(size_t)finfo.st_size) { 
Line 544  static void file_read_action( Line 559  static void file_read_action(
 File_read_result file_read(Request_charsets& charsets, const String& file_spec,   File_read_result file_read(Request_charsets& charsets, const String& file_spec, 
                            bool as_text, HashStringValue *params,                             bool as_text, HashStringValue *params,
                            bool fail_on_read_problem) {                             bool fail_on_read_problem) {
         File_read_result result={false};          File_read_result result={false, 0, 0, 0};
 #ifdef PA_HTTP  #ifdef PA_HTTP
         if(file_spec.starts_with("http://")) {          if(file_spec.starts_with("http://")) {
                 // fail on read problem                  // fail on read problem
                 File_read_http_result http=file_read_http(charsets, file_spec, params);                  File_read_http_result http=file_read_http(charsets, file_spec, as_text, params);
                 result.success=true;                  result.success=true;
                 result.str=http.str;                  result.str=http.str;
                 result.length=http.length;                  result.length=http.length;
Line 578  File_read_result file_read(Request_chars Line 593  File_read_result file_read(Request_chars
                 }                  }
   
                 fix_line_breaks((char *)(result.str), result.length);                   fix_line_breaks((char *)(result.str), result.length); 
                 // note: after fixing  
                 ((char*&)(result.str))[result.length]=0;  
         }          }
   
         return result;          return result;
Line 754  static void rmdir(const String& file_spe Line 767  static void rmdir(const String& file_spe
                   
         rmdir(file_spec.mid(0, pos_after-1/* / */).cstr(String::L_FILE_SPEC));           rmdir(file_spec.mid(0, pos_after-1/* / */).cstr(String::L_FILE_SPEC)); 
 }  }
 bool file_delete(const String& file_spec, bool fail_on_read_problem) {  bool file_delete(const String& file_spec, bool fail_on_problem) {
         const char* fname=file_spec.cstr(String::L_FILE_SPEC);           const char* fname=file_spec.cstr(String::L_FILE_SPEC); 
         if(unlink(fname)!=0)          if(unlink(fname)!=0)
                 if(fail_on_read_problem)                  if(fail_on_problem)
                         throw Exception(errno==EACCES?"file.access":errno==ENOENT?"file.missing":0,                           throw Exception(errno==EACCES?"file.access":errno==ENOENT?"file.missing":0, 
                                 &file_spec,                                   &file_spec, 
                                 "unlink failed: %s (%d), actual filename '%s'",                                   "unlink failed: %s (%d), actual filename '%s'", 
Line 1073  int __vsnprintf(char* b, size_t s, const Line 1086  int __vsnprintf(char* b, size_t s, const
   
         if(r<0)          if(r<0)
                 r=0;                  r=0;
         else if(r>s)          else if((size_t)r>s)
                 r=s;                  r=s;
 #endif  #endif
         b[r]=0;          b[r]=0;

Removed from v.1.163  
changed lines
  Added in v.1.171


E-mail: