Diff for /parser3/src/main/pa_common.C between versions 1.194 and 1.206

version 1.194, 2004/09/09 13:57:27 version 1.206, 2005/11/16 14:49:41
Line 1 Line 1
 /** @file  /** @file
         Parser: commonly functions.          Parser: commonly functions.
   
         Copyright(c) 2001-2004 ArtLebedev Group (http://www.artlebedev.com)          Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
 */  */
   
Line 21  static const char * const IDENT_COMMON_C Line 21  static const char * const IDENT_COMMON_C
 #include "pa_vint.h"  #include "pa_vint.h"
 #include "pa_vhash.h"  #include "pa_vhash.h"
 #include "pa_vtable.h"  #include "pa_vtable.h"
   #include "pa_socks.h"
   
 #ifdef CYGWIN  #ifdef CYGWIN
 #define _GNU_H_WINDOWS32_SOCKETS  #define _GNU_H_WINDOWS32_SOCKETS
Line 130  char* file_read_text(Request_charsets& c Line 131  char* file_read_text(Request_charsets& c
         return file.success?file.str:0;          return file.success?file.str:0;
 }  }
   
   /// these options were handled but not checked elsewhere, now check them
   static int get_valid_file_options_count(HashStringValue& options)
   {
           int result=0;
           if(options.get(PA_SQL_LIMIT_NAME))
                   result++;
           if(options.get(PA_SQL_OFFSET_NAME))
                   result++;
           if(options.get(PA_COLUMN_SEPARATOR_NAME))
                   result++;
           if(options.get(PA_COLUMN_ENCLOSER_NAME))
                   result++;
           return result;
   }
   
 //http request stuff  //http request stuff
 #ifdef PA_HTTP  #ifdef PA_HTTP
   
Line 164  static int http_read_response(char*& res Line 180  static int http_read_response(char*& res
         while(true) {          while(true) {
                 char buf[MAX_STRING*10];                   char buf[MAX_STRING*10]; 
                 ssize_t received_size=recv(sock, buf, sizeof(buf), 0);                   ssize_t received_size=recv(sock, buf, sizeof(buf), 0); 
                 if(received_size<=0)                  if(received_size==0)
                           break;
                   if(received_size<0) {
                           if(int no=pa_socks_errno())
                                   throw Exception("http.timeout", 
                                           0, 
                                           "error receiving response: %s (%d)", pa_socks_strerr(no), no); 
                         break;                          break;
                   }
                 response=(char*)pa_realloc(response, response_size+received_size+1/*terminator*/);                  response=(char*)pa_realloc(response, response_size+received_size+1/*terminator*/);
                 memcpy(response+response_size, buf, received_size);                  memcpy(response+response_size, buf, received_size);
                 response_size+=received_size;                  response_size+=received_size;
Line 201  static int http_read_response(char*& res Line 224  static int http_read_response(char*& res
   
 #ifdef PA_USE_ALARM  #ifdef PA_USE_ALARM
 static sigjmp_buf timeout_env;  static sigjmp_buf timeout_env;
 static void timeout_handler(int sig){  static void timeout_handler(int /*sig*/){
     siglongjmp(timeout_env, 1);       siglongjmp(timeout_env, 1); 
 }  }
 #endif  #endif
Line 209  static void timeout_handler(int sig){ Line 232  static void timeout_handler(int sig){
 static int http_request(char*& response, size_t& response_size,  static int http_request(char*& response, size_t& response_size,
                         const char* host, short port,                           const char* host, short port, 
                         const char* request,                           const char* request, 
                         int                           int timeout_secs,
 #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", 
                         0,                           0, 
                         "zero hostname");  //never                          "zero hostname");  //never
   
           volatile // to prevent makeing it register variable, because it will be clobbered by longjmp [thanks gcc warning]
                   int sock=-1;
 #ifdef PA_USE_ALARM  #ifdef PA_USE_ALARM
         signal(SIGALRM, timeout_handler);           signal(SIGALRM, timeout_handler); 
 #endif  #endif
         int sock=-1;  
 #ifdef PA_USE_ALARM  #ifdef PA_USE_ALARM
         if(sigsetjmp(timeout_env, 1)) {          if(sigsetjmp(timeout_env, 1)) {
                 // stupid gcc [2.95.4] generated bad code                  // stupid gcc [2.95.4] generated bad code
                 // which failed to handle sigsetjmp+throw: crashed inside of pre-throw code.                  // which failed to handle sigsetjmp+throw: crashed inside of pre-throw code.
                 // rewritten simplier [though duplicating closesocket code]                  // rewritten simplier [athough duplicating closesocket code]
                 if(sock>=0)                   if(sock>=0) 
                         closesocket(sock);                           closesocket(sock); 
                 throw Exception("http.timeout",                   throw Exception("http.timeout", 
                         origin_string,                           0, 
                         "timeout occured while retrieving document");                           "timeout occured while retrieving document"); 
                 return 0; // never                  return 0; // never
         } else {          } else {
                 alarm(timeout);                   alarm(timeout_secs); 
 #endif  #endif
                 try {                  try {
                         int result;                          int result;
Line 247  static int http_request(char*& response, Line 267  static int http_request(char*& response,
                                         0,                                           0, 
                                         "can not resolve hostname \"%s\"", host);                                           "can not resolve hostname \"%s\"", host); 
                                                   
                         if((sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP/*0*/))<0)                          if((sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP/*0*/))<0) {
                                   int no=pa_socks_errno();
                                 throw Exception("http.connect",                                   throw Exception("http.connect", 
                                         0,                                           0, 
                                         "can not make socket: %s (%d)", strerror(errno), errno);                                           "can not make socket: %s (%d)", pa_socks_strerr(no), no); 
                         if(connect(sock, (struct sockaddr *)&dest, sizeof(dest)))                          }
   
                           // To enable SO_DONTLINGER (that is, disable SO_LINGER) 
                           // l_onoff should be set to zero and setsockopt should be called
                           linger dont_linger={0,0};
                           setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char *)&dont_linger, sizeof(dont_linger));
   
   #ifdef WIN32
   // SO_*TIMEO can be defined in .h but not implemlemented in protocol,
   // failing subsequently with Option not supported by protocol (99) message
   // could not suppress that, so leaving this only for win32
                           int timeout_ms=timeout_secs*1000;
                           setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout_ms, sizeof(timeout_ms));
                           setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout_ms, sizeof(timeout_ms));
   #endif
   
                           if(connect(sock, (struct sockaddr *)&dest, sizeof(dest))) {
                                   int no=pa_socks_errno();
                                 throw Exception("http.connect",                                   throw Exception("http.connect", 
                                         0,                                           0, 
                                         "can not connect to host \"%s\": %s (%d)", host, strerror(errno), errno);                                           "can not connect to host \"%s\": %s (%d)", host, pa_socks_strerr(no), no); 
                           }
                         size_t request_size=strlen(request);                          size_t request_size=strlen(request);
                         if(send(sock, request, request_size, 0)!=(ssize_t)request_size)                          if(send(sock, request, request_size, 0)!=(ssize_t)request_size) {
                                 throw Exception("http.connect",                                   int no=pa_socks_errno();
                                   throw Exception("http.timeout", 
                                         0,                                           0, 
                                         "error sending request: %s (%d)", strerror(errno), errno);                                           "error sending request: %s (%d)", pa_socks_strerr(no), no); 
                           }
   
                         result=http_read_response(response, response_size, sock, fail_on_status_ne_200);                           result=http_read_response(response, response_size, sock, fail_on_status_ne_200); 
                         closesocket(sock);                           closesocket(sock); 
Line 424  static File_read_http_result file_read_h Line 465  static File_read_http_result file_read_h
         const char* method="GET"; bool method_is_get;          const char* method="GET"; bool method_is_get;
         HashStringValue* form=0;          HashStringValue* form=0;
         const char* body_cstr=0;          const char* body_cstr=0;
         int timeout=2;          int timeout_secs=2;
         bool fail_on_status_ne_200=true;          bool fail_on_status_ne_200=true;
         Value* vheaders=0;          Value* vheaders=0;
         Charset *asked_remote_charset=0;          Charset *asked_remote_charset=0;
Line 432  static File_read_http_result file_read_h Line 473  static File_read_http_result file_read_h
         const char* password_cstr=0;          const char* password_cstr=0;
   
         if(options) {          if(options) {
                 int valid_options=0;                  int valid_options=get_valid_file_options_count(*options);
   
                 if(Value* vmethod=options->get(HTTP_METHOD_NAME)) {                  if(Value* vmethod=options->get(HTTP_METHOD_NAME)) {
                         valid_options++;                          valid_options++;
                         method=vmethod->as_string().cstr();                          method=vmethod->as_string().cstr();
Line 447  static File_read_http_result file_read_h Line 489  static File_read_http_result file_read_h
                 }                   } 
                 if(Value* vtimeout=options->get(HTTP_TIMEOUT_NAME)) {                  if(Value* vtimeout=options->get(HTTP_TIMEOUT_NAME)) {
                         valid_options++;                          valid_options++;
                         timeout=vtimeout->as_int();                           timeout_secs=vtimeout->as_int(); 
                 }                   } 
                 if((vheaders=options->get(HTTP_HEADERS_NAME))) {                  if((vheaders=options->get(HTTP_HEADERS_NAME))) {
                         valid_options++;                          valid_options++;
Line 579  static File_read_http_result file_read_h Line 621  static File_read_http_result file_read_h
         size_t response_size;          size_t response_size;
         int status_code=http_request(response, response_size,          int status_code=http_request(response, response_size,
                 host, port, request_head_and_body.cstr(),                   host, port, request_head_and_body.cstr(), 
                 timeout, fail_on_status_ne_200);                   timeout_secs, fail_on_status_ne_200); 
                   
         //processing results              //processing results    
         char* raw_body; size_t raw_body_size;          char* raw_body; size_t raw_body_size;
Line 709  File_read_result file_read(Request_chars Line 751  File_read_result file_read(Request_chars
         File_read_result result={false, 0, 0, 0};          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://")) {
                   if(offset || count)
                           throw Exception("parser.runtime",
                                   0,
                                   "offset and load options are not supported for HTTP:// file load");
   
                 // fail on read problem                  // fail on read problem
                 File_read_http_result http=file_read_http(charsets, file_spec, as_text, params);                  File_read_http_result http=file_read_http(charsets, file_spec, as_text, params);
                 result.success=true;                  result.success=true;
Line 717  File_read_result file_read(Request_chars Line 764  File_read_result file_read(Request_chars
                 result.headers=http.headers;                   result.headers=http.headers; 
         } else {          } else {
 #endif  #endif
                 if(params && params->count())                  if(params) {
                         throw Exception("parser.runtime",                          int valid_options=get_valid_file_options_count(*params);
                                 0,                          if(valid_options!=params->count())
                                 "invalid option passed");                                  throw Exception("parser.runtime",
                                           0,
                                           "invalid option passed");
                   }
   
                 File_read_action_info info={&result.str, &result.length,                  File_read_action_info info={&result.str, &result.length,
                         buf, offset, count};                           buf, offset, count}; 
Line 818  bool file_read_action_under_lock(const S Line 868  bool file_read_action_under_lock(const S
         }          }
 }  }
   
 static void create_dir_for_file(const String& file_spec) {  void create_dir_for_file(const String& file_spec) {
         size_t pos_after=1;          size_t pos_after=1;
         size_t pos_before;          size_t pos_before;
         while((pos_before=file_spec.pos('/', pos_after))!=STRING_NOT_FOUND) {          while((pos_before=file_spec.pos('/', pos_after))!=STRING_NOT_FOUND) {

Removed from v.1.194  
changed lines
  Added in v.1.206


E-mail: