Diff for /parser3/src/targets/isapi/parser3isapi.C between versions 1.72 and 1.82.2.2

version 1.72, 2002/06/11 12:20:42 version 1.82.2.2, 2003/01/31 16:05:59
Line 1 Line 1
 /** @file  /** @file
         Parser: IIS extension.          Parser: IIS extension.
   
         Copyright (c) 2000,2001, 2002 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2000,2001-2003 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)
   
         $Id$  
 */  */
   
   static const char* IDENT_PARSER3ISAPI_C="$Date$";
   
 #ifndef _MSC_VER  #ifndef _MSC_VER
 #       error compile ISAPI module with MSVC [no urge for now to make it autoconf-ed (PAF)]  #       error compile ISAPI module with MSVC [no urge for now to make it autoconf-ed (PAF)]
 #endif  #endif
Line 30 Line 30
   
 // consts  // consts
   
 extern const char *main_RCSIds[];  const char* IIS51vars[]={
 #ifdef USE_SMTP          "APPL_MD_PATH", "APPL_PHYSICAL_PATH",
 extern const char *smtp_RCSIds[];          "AUTH_PASSWORD", "AUTH_TYPE", "AUTH_USER",
 #endif          "CERT_COOKIE", "CERT_FLAGS", "CERT_ISSUER", "CERT_KEYSIZE", "CERT_SECRETKEYSIZE",
 extern const char *gd_RCSIds[];          "CERT_SERIALNUMBER", "CERT_SERVER_ISSUER", "CERT_SERVER_SUBJECT", "CERT_SUBJECT",
 extern const char *classes_RCSIds[];          "CONTENT_LENGTH", "CONTENT_TYPE",
 extern const char *types_RCSIds[];          "LOGON_USER",
 extern const char *parser3isapi_RCSIds[];          "HTTPS", "HTTPS_KEYSIZE", "HTTPS_SECRETKEYSIZE", "HTTPS_SERVER_ISSUER", "HTTPS_SERVER_SUBJECT",
 const char **RCSIds[]={          "INSTANCE_ID",  "INSTANCE_META_PATH",
         main_RCSIds,          "PATH_INFO",    "PATH_TRANSLATED",
 #ifdef USE_SMTP          "QUERY_STRING",
         smtp_RCSIds,          "REMOTE_ADDR", "REMOTE_HOST", "REMOTE_USER", "REQUEST_METHOD",
 #endif          "SCRIPT_NAME",
         gd_RCSIds,          "SERVER_NAME", "SERVER_PORT", "SERVER_PORT_SECURE", "SERVER_PROTOCOL", "SERVER_SOFTWARE",
         classes_RCSIds,          "URL",
         types_RCSIds,  
         parser3isapi_RCSIds,  
         0  
 };  };
   const int IIS51var_count=sizeof(IIS51vars)/sizeof(*IIS51vars);
   
 // globals  // globals
   
Line 69  struct SAPI_func_context { Line 67  struct SAPI_func_context {
 #endif  #endif
   
 // goes to 'cs-uri-query' log file field. webmaster: switch it ON[default OFF].  // goes to 'cs-uri-query' log file field. webmaster: switch it ON[default OFF].
 void SAPI::log(Pool& pool, const char *fmt, ...) {  void SAPI::log(Pool& pool, const char* fmt, ...) {
         SAPI_func_context& ctx=*static_cast<SAPI_func_context *>(pool.get_context());          SAPI_func_context& ctx=*static_cast<SAPI_func_context *>(pool.get_context());
                   
         va_list args;          va_list args;
         va_start(args,fmt);          va_start(args,fmt);
         char buf[MAX_STRING];          char buf[MAX_STRING];
         const char *prefix="PARSER_ERROR:";          const char* prefix="PARSER_ERROR:";
         strcpy(buf, prefix);          strcpy(buf, prefix);
         char *start=buf+strlen(prefix);          char *start=buf+strlen(prefix);
         DWORD size=vsnprintf(start, MAX_STRING-strlen(prefix), fmt, args);          DWORD size=vsnprintf(start, MAX_STRING-strlen(prefix), fmt, args);
Line 86  void SAPI::log(Pool& pool, const char *f Line 84  void SAPI::log(Pool& pool, const char *f
 }  }
   
 /// @todo event log  /// @todo event log
 void SAPI::die(const char *fmt, ...) {  void SAPI::die(const char* fmt, ...) {
         if(FILE *log=fopen("c:\\die.log", "at")) {          if(FILE *log=fopen("c:\\die.log", "at")) {
                 va_list args;                  va_list args;
                 va_start(args,fmt);                  va_start(args,fmt);
                 vfprintf(log, fmt, args);                  vfprintf(log, fmt, args);
                 fclose(log);                  fclose(log);
         }          }
         exit(1);          // exit & try to produce core dump
           abort();
 }  }
   
 const char *SAPI::get_env(Pool& pool, const char *name) {  const char* SAPI::get_env(Pool& pool, const char* name) {
         SAPI_func_context& ctx=*static_cast<SAPI_func_context *>(pool.get_context());          SAPI_func_context& ctx=*static_cast<SAPI_func_context *>(pool.get_context());
   
         char *variable_buf=(char *)pool.malloc(MAX_STRING);          char *variable_buf=(char *)pool.malloc(MAX_STRING);
Line 104  const char *SAPI::get_env(Pool& pool, co Line 103  const char *SAPI::get_env(Pool& pool, co
   
         if(ctx.lpECB->GetServerVariable(ctx.lpECB->ConnID, const_cast<char *>(name),           if(ctx.lpECB->GetServerVariable(ctx.lpECB->ConnID, const_cast<char *>(name), 
                 variable_buf, &variable_len)) {                  variable_buf, &variable_len)) {
                 variable_buf[variable_len]=0;                  if(*variable_buf) { // saw returning len=1 && *buf=0 :(
                 return variable_buf;                          variable_buf[variable_len]=0;
                           return variable_buf;
                   }
         } else if (GetLastError()==ERROR_INSUFFICIENT_BUFFER) {          } else if (GetLastError()==ERROR_INSUFFICIENT_BUFFER) {
                 variable_buf=(char *)pool.malloc(variable_len+1);                  variable_buf=(char *)pool.malloc(variable_len+1);
                                   
                 if(ctx.lpECB->GetServerVariable(ctx.lpECB->ConnID, const_cast<char *>(name),                   if(ctx.lpECB->GetServerVariable(ctx.lpECB->ConnID, const_cast<char *>(name), 
                         variable_buf, &variable_len)) {                          variable_buf, &variable_len)) {
                         variable_buf[variable_len]=0;                          if(*variable_buf) {
                         return variable_buf;                                  variable_buf[variable_len]=0;
                                   return variable_buf;
                           }
                 }                  }
         }          }
                                   
         return 0;          return 0;
 }  }
   
 static int grep_char(const char *s, char c) {  static int grep_char(const char* s, char c) {
         int result=0;          int result=0;
         if(s) {          if(s) {
                 while(s=strchr(s, c)) {                  while(s=strchr(s, c)) {
Line 129  static int grep_char(const char *s, char Line 132  static int grep_char(const char *s, char
         }          }
         return result;          return result;
 }  }
 static const char *mk_env_pair(Pool& pool, const char *key, const char *value) {  static const char* mk_env_pair(Pool& pool, const char* key, const char* value) {
         char *result=(char *)pool.malloc(strlen(key)+1/*=*/+strlen(value)+1/*0*/);          char *result=(char *)pool.malloc(strlen(key)+1/*=*/+strlen(value)+1/*0*/);
         strcpy(result, key); strcat(result, "="); strcat(result, value);          strcpy(result, key); strcat(result, "="); strcat(result, value);
         return result;          return result;
 }  }
 const char *const *SAPI::environment(Pool& pool) {  const char* const *SAPI::environment(Pool& pool) {
         const char *IIS51vars[]={  
                 "APPL_MD_PATH", "APPL_PHYSICAL_PATH",  
                 "AUTH_PASSWORD", "AUTH_TYPE", "AUTH_USER",  
                 "CERT_COOKIE", "CERT_FLAGS", "CERT_ISSUER", "CERT_KEYSIZE", "CERT_SECRETKEYSIZE",  
                 "CERT_SERIALNUMBER", "CERT_SERVER_ISSUER", "CERT_SERVER_SUBJECT", "CERT_SUBJECT",  
                 "CONTENT_LENGTH", "CONTENT_TYPE",  
                 "LOGON_USER",  
                 "HTTPS", "HTTPS_KEYSIZE", "HTTPS_SECRETKEYSIZE", "HTTPS_SERVER_ISSUER", "HTTPS_SERVER_SUBJECT",  
                 "INSTANCE_ID",  "INSTANCE_META_PATH",  
                 "PATH_INFO",    "PATH_TRANSLATED",  
                 "QUERY_STRING",  
                 "REMOTE_ADDR", "REMOTE_HOST", "REMOTE_USER", "REQUEST_METHOD",  
                 "SCRIPT_NAME",  
                 "SERVER_NAME", "SERVER_PORT", "SERVER_PORT_SECURE", "SERVER_PROTOCOL", "SERVER_SOFTWARE",  
                 "URL",  
         };  
         const int IIS51var_count=sizeof(IIS51vars)/sizeof(*IIS51vars);  
   
         // we know this buf is writable          // we know this buf is writable
         char *all_http_vars=const_cast<char *>(SAPI::get_env(pool, "ALL_HTTP"));          char *all_http_vars=const_cast<char *>(SAPI::get_env(pool, "ALL_HTTP"));
         const int http_var_count=grep_char(all_http_vars, '\n')+1/*\n for theoretical(never saw) this \0*/;          const int http_var_count=grep_char(all_http_vars, '\n')+1/*\n for theoretical(never saw) this \0*/;
                   
         const char **result=          const char* *result=
                 (const char **)pool.malloc(sizeof(char *)*(IIS51var_count+http_var_count+1/*0*/));                  (const char* *)pool.malloc(sizeof(char *)*(IIS51var_count+http_var_count+1/*0*/));
         const char **cur=result;          const char* *cur=result;
   
         // IIS5.1 vars          // IIS5.1 vars
         for(int i=0; i<IIS51var_count; i++) {          for(int i=0; i<IIS51var_count; i++) {
                 const char *key=IIS51vars[i];                  const char* key=IIS51vars[i];
                 if(const char *value=SAPI::get_env(pool, key))                  if(const char* value=SAPI::get_env(pool, key))
                         *cur++=mk_env_pair(pool, key, value);                          *cur++=mk_env_pair(pool, key, value);
         }          }
   
Line 211  size_t SAPI::read_post(Pool& pool, char Line 196  size_t SAPI::read_post(Pool& pool, char
         return total_read;          return total_read;
 }  }
   
 void SAPI::add_header_attribute(Pool& pool, const char *key, const char *value) {  void SAPI::add_header_attribute(Pool& pool, 
                                                                   const char* dont_store_key, const char* dont_store_value) {
         SAPI_func_context& ctx=*static_cast<SAPI_func_context *>(pool.get_context());          SAPI_func_context& ctx=*static_cast<SAPI_func_context *>(pool.get_context());
   
         if(strcasecmp(key, "location")==0)           if(strcasecmp(key, "location")==0) 
                 ctx.http_response_code=302;                  ctx.http_response_code=302;
   
         if(strcasecmp(key, "status")==0)           if(strcasecmp(key, "status")==0) 
                 ctx.http_response_code=atoi(value);                  ctx.http_response_code=atoi(dont_store_value);
         else {          else {
                 ctx.header->APPEND_CONST(key);  todo: copy dont_store_ to nonvilotile
                   ctx.header->APPEND_CONST(dont_store_key);
                 ctx.header->APPEND_CONST(": ");                  ctx.header->APPEND_CONST(": ");
                 ctx.header->APPEND_CONST(value);                  ctx.header->APPEND_CONST(dont_store_value);
                 ctx.header->APPEND_CONST("\r\n");                  ctx.header->APPEND_CONST("\r\n");
         }          }
 }  }
Line 304  static bool parser_init() { Line 291  static bool parser_init() {
                 // successful finish                  // successful finish
                 return true;                  return true;
         } catch(const Exception& e) { // global problem           } catch(const Exception& e) { // global problem 
                 const char *body=e.comment();                  const char* body=e.comment();
                                   
                 // unsuccessful finish                  // unsuccessful finish
                 return false;                  return false;
Line 344  void real_parser_handler(Pool& pool, LPE Line 331  void real_parser_handler(Pool& pool, LPE
         back_slashes_to_slashes(filespec_to_process);          back_slashes_to_slashes(filespec_to_process);
 #endif  #endif
   
         if(const char *path_info=SAPI::get_env(pool, "PATH_INFO")) {          if(const char* path_info=SAPI::get_env(pool, "PATH_INFO")) {
                 // IIS                  // IIS
                 size_t len=strlen(filespec_to_process)-strlen(path_info);                  size_t len=strlen(filespec_to_process)-strlen(path_info);
                 char *buf=(char *)pool.malloc(len+1);                  char *buf=(char *)pool.malloc(len+1);
Line 372  void real_parser_handler(Pool& pool, LPE Line 359  void real_parser_handler(Pool& pool, LPE
         request_info.content_type=lpECB->lpszContentType;          request_info.content_type=lpECB->lpszContentType;
         request_info.content_length=lpECB->cbTotalBytes;          request_info.content_length=lpECB->cbTotalBytes;
         request_info.cookie=SAPI::get_env(pool, "HTTP_COOKIE");          request_info.cookie=SAPI::get_env(pool, "HTTP_COOKIE");
           request_info.mail_received=false;
                   
         // prepare to process request          // prepare to process request
         Request request(pool,          Request request(pool,
Line 385  void real_parser_handler(Pool& pool, LPE Line 372  void real_parser_handler(Pool& pool, LPE
 #endif  #endif
                         /* status_allowed */);                          /* status_allowed */);
   
         // some root-controlled location  
         //   c:\windows  
         char root_config_path[MAX_STRING];  
         GetWindowsDirectory(root_config_path, MAX_STRING);  
         // must be dynamic: rethrowing from request.core   
         //   may return 'source' which can be inside of 'root auto.p@exeception'  
         char *root_config_filespec=(char *)pool.malloc(MAX_STRING);  
         snprintf(root_config_filespec, MAX_STRING,   
                 "%s/%s",   
                 root_config_path, CONFIG_FILE_NAME);  
   
         // beside by binary          // beside by binary
         static char site_config_path[MAX_STRING];          static char beside_binary_path[MAX_STRING];
         strncpy(site_config_path, argv0, MAX_STRING-1);  site_config_path[MAX_STRING-1]=0; // filespec of my binary          strncpy(beside_binary_path, argv0, MAX_STRING-1);  beside_binary_path[MAX_STRING-1]=0; // filespec of my binary
         if(!(          if(!(
                 rsplit(site_config_path, '/') ||                   rsplit(beside_binary_path, '/') || 
                 rsplit(site_config_path, '\\'))) { // strip filename                  rsplit(beside_binary_path, '\\'))) { // strip filename
                 // no path, just filename                  // no path, just filename
                 site_config_path[0]='.'; site_config_path[1]=0;                  beside_binary_path[0]='.'; beside_binary_path[1]=0;
         }                 }       
         char site_config_filespec[MAX_STRING];          char config_filespec[MAX_STRING];
         snprintf(site_config_filespec, MAX_STRING,           snprintf(config_filespec, MAX_STRING, 
                 "%s/%s",                   "%s/%s", 
                 site_config_path, CONFIG_FILE_NAME);                  beside_binary_path, AUTO_FILE_NAME);
           bool fail_on_config_read_problem=entry_exists(config_filespec);
   
         // process the request          // process the request
         request.core(          request.core(
                 root_config_filespec, false /*fail_on_read_problem*/, // /path/to/root/parser3.conf                  config_filespec, fail_on_config_read_problem, // /path/to/first/auto.p
                 site_config_filespec, false /*fail_on_read_problem*/, // /path/to/site/parser3.conf  
                 header_only);                  header_only);
 }  }
   
Line 450  inline DWORD RealHttpExtensionProc(LPEXT Line 426  inline DWORD RealHttpExtensionProc(LPEXT
         SAPI_func_context ctx={          SAPI_func_context ctx={
                 lpECB,                  lpECB,
                 0, // filling later: so that if there would be error pool would have ctx                  0, // filling later: so that if there would be error pool would have ctx
                 200 // default http_response_code                  200 // default http_response_code [lpECB->dwHttpStatusCode seems to be always 0, even on 404 redirect to /404.html]
         };          };
         pool.set_context(&ctx);// no allocations before this line!          pool.set_context(&ctx);// no allocations before this line!
   
Line 462  inline DWORD RealHttpExtensionProc(LPEXT Line 438  inline DWORD RealHttpExtensionProc(LPEXT
                 // don't allocate anything on pool here:                  // don't allocate anything on pool here:
                 //   possible pool' exception not catch-ed now                  //   possible pool' exception not catch-ed now
                         //   and there could be out-of-memory exception                          //   and there could be out-of-memory exception
                 const char *body=e.comment();                  const char* body=e.comment();
                 // log it                  // log it
                 SAPI::log(pool, "exception in request exception handler: %s", body);                  SAPI::log(pool, "exception in request exception handler: %s", body);
   
Line 497  inline DWORD RealHttpExtensionProc(LPEXT Line 473  inline DWORD RealHttpExtensionProc(LPEXT
                 // unsuccessful finish                  // unsuccessful finish
         }          }
 /*  /*
                 const char *body="test";                  const char* body="test";
   
                 //                  //
                 int content_length=strlen(body);                  int content_length=strlen(body);

Removed from v.1.72  
changed lines
  Added in v.1.82.2.2


E-mail: