Diff for /parser3/src/main/pa_request.C between versions 1.384 and 1.389

version 1.384, 2020/10/28 22:32:02 version 1.389, 2020/11/10 22:50:58
Line 121  static const String body_name_upper(BODY Line 121  static const String body_name_upper(BODY
   
 static const String content_type_name_upper(HTTP_CONTENT_TYPE_UPPER);  static const String content_type_name_upper(HTTP_CONTENT_TYPE_UPPER);
 static const String content_disposition_name_upper(CONTENT_DISPOSITION_UPPER);  static const String content_disposition_name_upper(CONTENT_DISPOSITION_UPPER);
 static const String content_disposition_inline(CONTENT_DISPOSITION_INLINE);  
 static const String content_disposition_attachment(CONTENT_DISPOSITION_ATTACHMENT);  static const String content_disposition_attachment(CONTENT_DISPOSITION_ATTACHMENT);
   
 // defines  // defines
Line 402  void Request::core(const char* config_fi Line 401  void Request::core(const char* config_fi
         try {          try {
                 // loading config                  // loading config
                 if(config_filespec)                  if(config_filespec)
                         use_file_directly(main_class, *new String(config_filespec), true, true /*file must exist if 'fail on read problem' not set*/);                          use_file_directly(*new String(config_filespec));
   
                 // filling mail received                  // filling mail received
                 mail.fill_received(*this);                  mail.fill_received(*this);
   
                 // loading auto.p files from document_root/..   
                 // to the one beside requested file.  
                 // all assigned bases from upper dir  
                 {  
                         const char* after=request_info.path_translated;  
                         size_t drlen=strlen(request_info.document_root);  
                         if(memcmp(after, request_info.document_root, drlen)==0) {  
                                 after+=drlen;  
                                 if(after[-1]=='/')   
                                         --after;  
                         }  
                           
                         while(const char* before=strchr(after, '/')) {  
                                 String& sfile_spec=*new String;  
                                 if(after!=request_info.path_translated) {  
                                         sfile_spec.append_strdup(request_info.path_translated, before-request_info.path_translated, String::L_CLEAN);  
                                         sfile_spec << "/" AUTO_FILE_NAME;  
   
                                         use_file_directly(main_class, sfile_spec, true /*fail on read problem*/, false /*but ignore absence, sole user*/);  
                                 }  
                                 for(after=before+1;*after=='/';after++);  
                         }  
                 }  
   
                 try {                  try {
                         // compile requested file                          // compile requested file
                         String& spath_translated=*new String;                          if(request_info.path_translated)
                         spath_translated.append_help_length(request_info.path_translated, 0, String::L_TAINTED);                                  use_file_directly(*new String(request_info.path_translated, String::L_TAINTED), true, true /* load auto.p files */);
                         use_file_directly(main_class, spath_translated);  
   
                         configure();                          configure();
                 } catch(...) {                  } catch(...) {
                         configure(); // configure anyway, useful in @unhandled_exception [say, if they would want to mail by SMTP something]                          configure(); // configure anyway, useful in @unhandled_exception [say, if they would want to mail by SMTP something]
Line 558  uint Request::register_file(String::Body Line 531  uint Request::register_file(String::Body
         return file_list.count()-1;          return file_list.count()-1;
 }  }
   
 void Request::use_file_directly(VStateless_class& aclass, const String& file_spec, bool fail_on_read_problem, bool fail_on_file_absence) {  void Request::use_file_directly(const String& file_spec, bool fail_on_file_absence, bool with_auto_p) {
         // cyclic dependence check          // cyclic dependence check
         if(used_files.get(file_spec))          if(used_files.get(file_spec))
                 return;                  return;
         used_files.put(file_spec, true);          used_files.put(file_spec, true);
   
         if(fail_on_read_problem && !fail_on_file_absence) // ignore file absence if asked for          if(!fail_on_file_absence && !entry_exists(file_spec)) // ignore file absence if asked for
                 if(!entry_exists(file_spec))                  return;
                         return;  
   
         if(const char* source=file_read_text(charsets, file_spec, fail_on_read_problem))          if(with_auto_p) {
                 use_buf(aclass, source, 0, register_file(file_spec));                  // loading auto.p files from document_root/.. 
                   // to the one beside requested file.
                   // all assigned bases from upper dir
                   const char* target=file_spec.cstr();
   
                   // all relative paths are calculated from main document
                   request_info.path_translated=target;
   
                   const char* after=target;
                   size_t drlen=strlen(request_info.document_root);
                   if(memcmp(after, request_info.document_root, drlen)==0) {
                           after+=drlen;
                           if(after[-1]=='/') 
                                   --after;
                   }
   
                   while(const char* before=strchr(after, '/')) {
                           String& sfile_spec=*new String;
                           if(after!=target) {
                                   sfile_spec.append_strdup(target, before-target, String::L_CLEAN);
                                   sfile_spec << "/" AUTO_FILE_NAME;
   
                                   use_file_directly(sfile_spec, false /*ignore absence, sole user*/);
                           }
                           for(after=before+1;*after=='/';after++);
                   }
           }
   
           if(const char* source=file_read_text(charsets, file_spec, true))
                   use_buf(main_class, source, 0, register_file(file_spec));
 }  }
   
   
 void Request::use_file(VStateless_class& aclass, const String& file_name, const String* use_filespec/*absolute*/) {  void Request::use_file(const String& file_name, const String* use_filespec/*absolute*/, bool with_auto_p) {
         if(file_name.is_empty())          if(file_name.is_empty())
                 throw Exception(PARSER_RUNTIME, 0, "usage failed - no filename was specified");                  throw Exception(PARSER_RUNTIME, 0, "usage failed - no filename was specified");
   
         const String* filespec=0;          const String* filespec=0;
   
         if(file_name.first_char()=='/') //absolute path? [no need to scan MAIN:CLASS_PATH]          if(file_name.first_char()=='/') //absolute path? [no need to scan MAIN:CLASS_PATH]
                 filespec=&absolute(file_name);                  filespec=&full_disk_path(file_name);
         else if(use_filespec){ // search in current dir first          else if(use_filespec){ // search in current dir first
                 size_t last_slash_pos=use_filespec->strrpbrk("/");                  size_t last_slash_pos=use_filespec->strrpbrk("/");
                 if(last_slash_pos!=STRING_NOT_FOUND)                  if(last_slash_pos!=STRING_NOT_FOUND)
Line 594  void Request::use_file(VStateless_class& Line 595  void Request::use_file(VStateless_class&
                 searched_along_class_path.put(file_name, true);                  searched_along_class_path.put(file_name, true);
                 if(Value* element=main_class.get_element(class_path_name)) {                  if(Value* element=main_class.get_element(class_path_name)) {
                         if(element->is_string()) {                          if(element->is_string()) {
                                 filespec=file_exist(absolute(element->as_string()), file_name); // found at class_path?                                  filespec=file_exist(full_disk_path(element->as_string()), file_name); // found at class_path?
                         } else if(Table *table=element->get_table()) {                          } else if(Table *table=element->get_table()) {
                                 for(size_t i=table->count(); i--; ) {                                  for(size_t i=table->count(); i--; ) {
                                         const String& path=*(*table->get(i))[0];                                          const String& path=*(*table->get(i))[0];
                                         if(filespec=file_exist(absolute(path), file_name))                                          if(filespec=file_exist(full_disk_path(path), file_name))
                                                 break; // found along class_path                                                  break; // found along class_path
                                 }                                  }
                         } else                          } else
Line 609  void Request::use_file(VStateless_class& Line 610  void Request::use_file(VStateless_class&
                         throw Exception(PARSER_RUNTIME, &file_name, "usage failed - no $" MAIN_CLASS_NAME  ":" CLASS_PATH_NAME " were specified");                          throw Exception(PARSER_RUNTIME, &file_name, "usage failed - no $" MAIN_CLASS_NAME  ":" CLASS_PATH_NAME " were specified");
         }          }
   
         use_file_directly(aclass, *filespec);          use_file_directly(*filespec, true, with_auto_p);
 }  }
   
 void Request::use_file(const String& file_name, const String* use_filespec/*absolute*/, Operation::Origin origin) {  void Request::use_file(const String& file_name, const String* use_filespec/*absolute*/, Operation::Origin origin) {
Line 667  const String& Request::relative(const ch Line 668  const String& Request::relative(const ch
         return result;          return result;
 }  }
   
 const String& Request::absolute(const String& relative_name) {  const String& Request::full_disk_path(const String& relative_name) {
         if(relative_name.first_char()=='/') {          if(relative_name.first_char()=='/') {
                 String& result=*new String(pa_strdup(request_info.document_root));                  String& result=*new String(pa_strdup(request_info.document_root));
                 result << relative_name;                  result << relative_name;
                 return result;                  return result;
         } else           }
                 if(relative_name.pos("://")!=STRING_NOT_FOUND // something like "http://xxx"          if(relative_name.pos("://")!=STRING_NOT_FOUND // something like "http://xxx"
 #ifdef WIN32  #ifdef WIN32
                         || relative_name.pos(":")==1  // DRIVE:                  || relative_name.pos(":")==1  // DRIVE:
                         || relative_name.starts_with("\\\\") // UNC1                  || relative_name.starts_with("\\\\") // UNC1
                         || relative_name.starts_with("//") // UNC2                  || relative_name.starts_with("//") // UNC2
 #endif  #endif
                         )                  )
                         return relative_name;                  return relative_name;
                 else  
                         return relative(request_info.path_translated, relative_name);          return relative(request_info.path_translated ? request_info.path_translated : request_info.document_root, relative_name);
 }  }
   
 #ifndef DOXYGEN  #ifndef DOXYGEN
Line 804  static void output_pieces(Request& r, bo Line 805  static void output_pieces(Request& r, bo
   
         SAPI::send_header(r.sapi_info);          SAPI::send_header(r.sapi_info);
   
         const String& filespec=r.absolute(filename);          const String& filespec=r.full_disk_path(filename);
   
         size_t sent = 0;          size_t sent = 0;
         if(!header_only){          if(!header_only){
Line 850  void Request::output_result(VFile* body_ Line 851  void Request::output_result(VFile* body_
         if(vfile_name) {          if(vfile_name) {
                 const String& sfile_name=vfile_name->as_string();                  const String& sfile_name=vfile_name->as_string();
                 if(sfile_name!=NONAME_DAT) {                  if(sfile_name!=NONAME_DAT) {
                         VHash& hash=*new VHash();                          if(as_attachment) {
                         HashStringValue &h=hash.hash();                                  VHash& hash=*new VHash();
                         h.put(value_name, new VString( as_attachment ? content_disposition_attachment : content_disposition_inline ));                                  hash.hash().put(value_name, new VString(content_disposition_attachment));
                         h.put(content_disposition_filename_name, new VString(*new String(sfile_name, String::L_HTTP_HEADER)));                                  hash.hash().put(content_disposition_filename_name, new VString(*new String(sfile_name, String::L_HTTP_HEADER)));
                                   response.fields().put(content_disposition_name_upper, &hash);
                         response.fields().put(content_disposition_name_upper, &hash);                          }
   
                         if(!body_file_content_type)                          if(!body_file_content_type)
                                 body_file_content_type=new VString(mime_type_of(sfile_name.cstr()));                                  body_file_content_type=new VString(mime_type_of(sfile_name.cstr()));
Line 880  void Request::output_result(VFile* body_ Line 881  void Request::output_result(VFile* body_
                 const String& sresponse_body_file=vresponse_body_file->as_string();                  const String& sresponse_body_file=vresponse_body_file->as_string();
                 uint64_t content_length=0;                  uint64_t content_length=0;
                 time_t atime=0, mtime=0, ctime=0;                  time_t atime=0, mtime=0, ctime=0;
                 file_stat(absolute(sresponse_body_file), content_length, atime, mtime, ctime);                  file_stat(full_disk_path(sresponse_body_file), content_length, atime, mtime, ctime);
   
                 VDate* vdate=0;                  VDate* vdate=0;
                 if(Value* v=body_file->fields().get("mdate")) {                  if(Value* v=body_file->fields().get("mdate")) {

Removed from v.1.384  
changed lines
  Added in v.1.389


E-mail: