Diff for /parser3/src/main/pa_request.C between versions 1.268 and 1.280.8.1

version 1.268, 2004/07/30 10:02:31 version 1.280.8.1, 2006/04/09 12:25:04
Line 1 Line 1
 /** @file  /** @file
         Parser: request class main part. @see compile.C and execute.C.          Parser: request class main part. @see compile.C and execute.C.
   
         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 36  static const char * const IDENT_REQUEST_ Line 36  static const char * const IDENT_REQUEST_
   
 // consts  // consts
   
 const char* UNHANDLED_EXCEPTION_METHOD_NAME="unhandled_exception";  #define UNHANDLED_EXCEPTION_METHOD_NAME "unhandled_exception"
   
 /// content type of exception response, when no @MAIN:exception handler defined  /// content type of exception response, when no @MAIN:exception handler defined
 const char* UNHANDLED_EXCEPTION_CONTENT_TYPE="text/plain";  const char* UNHANDLED_EXCEPTION_CONTENT_TYPE="text/plain";
Line 53  const char* ORIGINS_CONTENT_TYPE="text/p Line 53  const char* ORIGINS_CONTENT_TYPE="text/p
 #define EXCEPTION_TYPE_PART_NAME "type"  #define EXCEPTION_TYPE_PART_NAME "type"
 #define EXCEPTION_SOURCE_PART_NAME "source"  #define EXCEPTION_SOURCE_PART_NAME "source"
 #define EXCEPTION_COMMENT_PART_NAME "comment"  #define EXCEPTION_COMMENT_PART_NAME "comment"
 #define RESPONSE_BODY_FILE_NAME "file"  
   
 // globals  // globals
   
Line 67  const String exception_type_part_name(EX Line 66  const String exception_type_part_name(EX
 const String exception_source_part_name(EXCEPTION_SOURCE_PART_NAME);  const String exception_source_part_name(EXCEPTION_SOURCE_PART_NAME);
 const String exception_comment_part_name(EXCEPTION_COMMENT_PART_NAME);  const String exception_comment_part_name(EXCEPTION_COMMENT_PART_NAME);
 const String exception_handled_part_name(EXCEPTION_HANDLED_PART_NAME);  const String exception_handled_part_name(EXCEPTION_HANDLED_PART_NAME);
 const String response_body_file_name(RESPONSE_BODY_FILE_NAME);  
   
 // defines for statics  // defines for statics
   
Line 78  const String response_body_file_name(RES Line 76  const String response_body_file_name(RES
 #define POST_PROCESS_METHOD_NAME "postprocess"  #define POST_PROCESS_METHOD_NAME "postprocess"
 #define DOWNLOAD_NAME "download"  #define DOWNLOAD_NAME "download"
 #define CLASS_PATH_NAME "CLASS_PATH"  #define CLASS_PATH_NAME "CLASS_PATH"
   #define RESPONSE_BODY_FILE_NAME "file"
   
 // statics  // statics
   
Line 89  static const String conf_method_name(CON Line 88  static const String conf_method_name(CON
 static const String post_process_method_name(POST_PROCESS_METHOD_NAME);  static const String post_process_method_name(POST_PROCESS_METHOD_NAME);
 static const String download_name(DOWNLOAD_NAME);  static const String download_name(DOWNLOAD_NAME);
 static const String class_path_name(CLASS_PATH_NAME);  static const String class_path_name(CLASS_PATH_NAME);
   static const String response_body_file_name(RESPONSE_BODY_FILE_NAME);
   
 // defines  // defines
   
Line 107  Request::Request(SAPI_Info& asapi_info, Line 107  Request::Request(SAPI_Info& asapi_info,
         wcontext(0),          wcontext(0),
         flang(adefault_lang),          flang(adefault_lang),
         fconnection(0),          fconnection(0),
         finterrupted(false),          finterrupted(false),fbreak(0),
   
         // public          // public
 #ifdef RESOURCES_DEBUG  #ifdef RESOURCES_DEBUG
Line 220  void Request::configure_admin(VStateless Line 220  void Request::configure_admin(VStateless
         if(Value* vcharsets=conf_class.get_element(charsets_name, conf_class, false)) {          if(Value* vcharsets=conf_class.get_element(charsets_name, conf_class, false)) {
                 if(!vcharsets->is_string())                  if(!vcharsets->is_string())
                         if(HashStringValue* charsets=vcharsets->get_hash())                          if(HashStringValue* charsets=vcharsets->get_hash())
                                 charsets->for_each(load_charset, &this->charsets);                                  charsets->for_each<Request_charsets*>(load_charset, &this->charsets);
                         else                          else
                                 throw Exception("parser.runtime",                                  throw Exception("parser.runtime",
                                         0,                                          0,
Line 232  void Request::configure_admin(VStateless Line 232  void Request::configure_admin(VStateless
         methoded_array().configure_admin(*this);          methoded_array().configure_admin(*this);
 }  }
   
   const char* Request::get_exception_cstr(
                                                                                   const Exception& e,
                                                                                   Request::Exception_details& details) {
   #define PA_URI_FORMAT "%s: "
   #define PA_ORIGIN_FILE_POS_FORMAT "%s(%d:%d): "
   #define PA_SOURCE_FORMAT "'%s' "
   #define PA_COMMENT_TYPE_FORMAT "%s [%s]"
           char* result=new(PointerFreeGC) char[MAX_STRING];
   
           if(details.problem_source) { // do we know the guy?
                   if(details.trace) { // do whe know where he came from?
                           Operation::Origin origin=details.trace.origin();
                           snprintf(result, MAX_STRING, 
                                   PA_URI_FORMAT 
                                   PA_ORIGIN_FILE_POS_FORMAT 
                                   PA_SOURCE_FORMAT PA_COMMENT_TYPE_FORMAT,
                                   request_info.uri,
                                   file_list[origin.file_no].cstr(), 1+origin.line, 1+origin.col,
                                   details.problem_source->cstr(),
                                   e.comment(), e.type()
                           );
                   } else
                           snprintf(result, MAX_STRING, 
                                   PA_URI_FORMAT 
                                   PA_SOURCE_FORMAT PA_COMMENT_TYPE_FORMAT,
                                   request_info.uri,
                                   details.problem_source->cstr(),
                                   e.comment(), e.type()
                           );
           } else
                   snprintf(result, MAX_STRING, 
                           PA_URI_FORMAT 
                           PA_COMMENT_TYPE_FORMAT,
                           request_info.uri,
                           e.comment(), e.type()
                   );
   
           return result;
   }
   
   void Request::configure() {
           // configure admin options if not configured yet
           if(!configure_admin_done)
                   configure_admin(main_class);
   
           // configure not-admin=user options
           methoded_array().configure_user(*this);
   
           // $MAIN:MIME-TYPES
           if(Value* element=main_class.get_element(mime_types_name, main_class, false))
                   if(Table *table=element->get_table())
                           mime_types=table;                       
   }
 /**  /**
         load MAIN class, execute @main.          load MAIN class, execute @main.
         MAIN class consists of all the auto.p files we'd manage to find          MAIN class consists of all the auto.p files we'd manage to find
Line 251  struct timeval mt[10]; Line 304  struct timeval mt[10];
 gettimeofday(&mt[0],NULL);  gettimeofday(&mt[0],NULL);
 #endif  #endif
         try {          try {
                   // filling cookies
                   cookie.fill_fields(request_info);
   
                   // filling mail received
                   mail.fill_received(*this);
   
                 // loading config                  // loading config
                 if(config_filespec) {                  if(config_filespec) {
                         const String& filespec=*new String(config_filespec);                          const String& filespec=*new String(config_filespec);
Line 292  gettimeofday(&mt[0],NULL); Line 351  gettimeofday(&mt[0],NULL);
                         }                          }
                 }                  }
   
                 // compile requested file                  try {
                 String& spath_translated=*new String;                          // compile requested file
                 spath_translated.append_help_length(request_info.path_translated, 0, String::L_TAINTED);                          String& spath_translated=*new String;
                 use_file(main_class,                          spath_translated.append_help_length(request_info.path_translated, 0, String::L_TAINTED);
                         spath_translated,                           use_file(main_class,
                         0 /*main_alias*/,                                  spath_translated, 
                         true /*ignore class_path*/);                                  0 /*main_alias*/,
                                   true /*ignore class_path*/);
                 // configure method_frame options if not configured yet  
                 if(!configure_admin_done)                          configure();
                         configure_admin(main_class);                  } catch(...) {
                           configure(); // configure anyway, useful in @unhandled_exception [say, if they would want to mail by SMTP something]
                 // configure not-method_frame=user options                          rethrow;
                 methoded_array().configure_user(*this);                  }
   
                 // $MAIN:MIME-TYPES  
                 if(Value* element=main_class.get_element(mime_types_name, main_class, false))  
                         if(Table *table=element->get_table())  
                                 mime_types=table;                         
   
                 // filling cookies  
                 cookie.fill_fields(request_info);  
   
                 // filling mail received  
                 mail.fill_received(*this);  
   
 #ifdef RESOURCES_DEBUG  #ifdef RESOURCES_DEBUG
 //measure:after compile  //measure:after compile
Line 341  gettimeofday(&mt[2],NULL); Line 389  gettimeofday(&mt[2],NULL);
                         body_value=response.fields().get(body_name); // $response:body                          body_value=response.fields().get(body_name); // $response:body
                 if(!body_value)                  if(!body_value)
                         body_value=new VString(*body_string); // just result of ^main[]                          body_value=new VString(*body_string); // just result of ^main[]
                   // ensure that body_value has no just L_TAINTED parts left
                   if(body_value->is_string())
                   {
                           String& untainted=*new String();
                           untainted.append(*body_value->get_string(), flang);
                           body_value=new VString(untainted);
                   }
   
                 // @postprocess                  // @postprocess
                 if(Value* value=main_class.get_element(post_process_method_name, main_class, false))                  if(Value* value=main_class.get_element(post_process_method_name, main_class, false))
Line 387  t[9]-t[3] Line 442  t[9]-t[3]
         } catch(const Exception& e) { // request handling problem          } catch(const Exception& e) { // request handling problem
                 try {                  try {
                 // we're returning not result, but error explanation                  // we're returning not result, but error explanation
 #define PA_URI_FORMAT "%s: "  
 #define PA_ORIGIN_FILE_POS_FORMAT "%s(%d:%d): "  
 #define PA_SOURCE_FORMAT "'%s' "  
 #define PA_COMMENT_TYPE_FORMAT "%s [%s]"  
                 // log the beast  
                 Request::Exception_details details=get_details(e);  
   
                 if(details.problem_source) { // do we know the guy?                  Request::Exception_details details=get_details(e);
                         if(details.trace) { // do whe know where he came from?                  const char* exception_cstr=get_exception_cstr(e, details);
                                 Operation::Origin origin=details.trace.origin();  
                                 SAPI::log(sapi_info,  
                                         PA_URI_FORMAT   
                                         PA_ORIGIN_FILE_POS_FORMAT   
                                         PA_SOURCE_FORMAT PA_COMMENT_TYPE_FORMAT,  
                                         request_info.uri,  
                                         file_list[origin.file_no].cstr(), 1+origin.line, 1+origin.col,  
                                         details.problem_source->cstr(),  
                                         e.comment(), e.type()  
                                 );  
                         } else  
                                 SAPI::log(sapi_info,  
                                         PA_URI_FORMAT   
                                         PA_SOURCE_FORMAT PA_COMMENT_TYPE_FORMAT,  
                                         request_info.uri,  
                                         details.problem_source->cstr(),  
                                         e.comment(), e.type()  
                                 );  
                 } else  
                         SAPI::log(sapi_info,  
                                 PA_URI_FORMAT   
                                 PA_COMMENT_TYPE_FORMAT,  
                                 request_info.uri,  
                                 e.comment(), e.type()  
                         );  
   
                 // reset language to default                  // reset language to default
                 flang=fdefault_lang;                  flang=fdefault_lang;
Line 471  frame.store_param(*new VTable(&stack_tra Line 495  frame.store_param(*new VTable(&stack_tra
   
 // future $response:body=  // future $response:body=
 //   execute ^unhandled_exception[exception;stack]  //   execute ^unhandled_exception[exception;stack]
   exception_trace.clear(); // forget all about previous life, in case there would be error inside of this method, error handled  would not be mislead by old stack contents (see extract_origin)
 body_string=&execute_method(frame, *method).as_string();  body_string=&execute_method(frame, *method).as_string();
                                 }                                  }
                         }                          }
Line 479  body_string=&execute_method(frame, *meth Line 504  body_string=&execute_method(frame, *meth
                 if(!body_string) {  // couldn't report an error beautifully?                  if(!body_string) {  // couldn't report an error beautifully?
                         // doing that ugly                          // doing that ugly
   
                         // make up result: $origin $source $comment $type $code  
                         char *buf=new(PointerFreeGC) char[MAX_STRING];  
                         size_t printed=0;  
                         if(const String* problem_source=e.problem_source())  
                                 printed+=snprintf(buf+printed, MAX_STRING-printed, "'%s' ",   
                                         problem_source->cstr());  
                         if(const char* comment=e.comment(true))  
                                 printed+=snprintf(buf+printed, MAX_STRING-printed, "%s", comment);  
                         if(const char* type=e.type(true))   
                                 printed+=snprintf(buf+printed, MAX_STRING-printed, "  type: %s",  type);  
   
                         // future $response:content-type                          // future $response:content-type
                         response.fields().put(content_type_name,                           response.fields().put(content_type_name, 
                                 new VString(*new String(UNHANDLED_EXCEPTION_CONTENT_TYPE)));                                  new VString(*new String(UNHANDLED_EXCEPTION_CONTENT_TYPE)));
                         // future $response:body                          // future $response:body
                         body_string=new String(buf);                          body_string=new String(exception_cstr);
                 }                  }
   
                 VString body_vstring(*body_string);                  VString body_vstring(*body_string);
                 VFile* body_file=body_vstring.as_vfile(String::L_UNSPECIFIED, &charsets);                  VFile* body_file=body_vstring.as_vfile(String::L_UNSPECIFIED, &charsets);
   
                   // conditionally log it
                   Value* vhandled=details.vhash.hash().get(exception_handled_part_name);
                   if(!vhandled || !vhandled->as_bool()) {
                           SAPI::log(sapi_info, "%s", exception_cstr);
                   }
   
                 // ERROR. write it out                  // ERROR. write it out
                 output_result(body_file, header_only, false);                  output_result(body_file, header_only, false);
                 } catch(const Exception& e) {                  } catch(const Exception& e) { // exception in unhandled exception
                         throw Exception(e.type(),                          Request::Exception_details details=get_details(e);
                                 e.problem_source(),                          const char* exception_cstr=get_exception_cstr(e, details);
                                 "in request exception handler: %s",                           // unconditionally log the beast
                                         e.comment());                          SAPI::log(sapi_info, "%s", exception_cstr);
   
                           throw Exception(0,
                                   0,
                                   "in %s", 
                                           exception_cstr);
                 }                  }
         }          }
 }  }
Line 535  void Request::use_file(VStateless_class& Line 560  void Request::use_file(VStateless_class&
                 file_spec=0;                  file_spec=0;
                 if(Value* element=main_class.get_element(class_path_name, main_class, false)) {                  if(Value* element=main_class.get_element(class_path_name, main_class, false)) {
                         if(element->is_string()) {                          if(element->is_string()) {
                                 file_spec=file_readable(absolute(element->as_string()), file_name); // found at class_path?                                  file_spec=file_exist(absolute(element->as_string()), file_name); // found at class_path?
                         } else if(Table *table=element->get_table()) {                          } else if(Table *table=element->get_table()) {
                                 int size=table->count();                                  int size=table->count();
                                 for(int i=size; i--; ) {                                  for(int i=size; i--; ) {
                                         const String& path=*(*table->get(i))[0];                                          const String& path=*(*table->get(i))[0];
                                         if((file_spec=file_readable(absolute(path), file_name)))                                          if((file_spec=file_exist(absolute(path), file_name)))
                                                 break; // found along class_path                                                  break; // found along class_path
                                 }                                  }
                         } else                          } else
Line 649  static void add_header_attribute( Line 674  static void add_header_attribute(
                 info->add_last_modified = false;                  info->add_last_modified = false;
 }  }
   
 /*  
                 if(v = opts->get("mdate")){  
                         ++valid_options;  
                         if(Value* vdate=v->as(VDATE_TYPE, false))  
                                 date=static_cast<VDate*>(vdate);  
                         else throw Exception("parser.runtime", 0, "mdate must be a date");  
                 }  
                 if(v = opts->get("disposition")){  
                         ++valid_options;  
                         if(!v->is("string")) throw Exception("parser.runtime", 0, "disposition must be a string");  
                         disposition = v->get_string()->cstr();  
                         if(strcmp(disposition, "inline") && strcmp(disposition, "attachment")) throw Exception("parser.runtime", 0, "disposition can be only 'inline' or 'attachment'");  
                 }  
                 if(valid_options != opts->count())  
                         throw Exception("parser.runtime", 0, "invalid option passed");  
         }  
   
         auto_file f = fopen(c_from_file_name, "rb");  
         if(f == 0)  
                 throw Exception("parser.runtime", 0, "Can't open file");  
   
         if(fseek(f, 0, SEEK_END)!=0)  
                 throw Exception("parser.runtime", 0, "Can't seek file");  
   
         size_t file_length = (size_t)ftell(f);  
         if(file_length == (size_t)-1)  
                 throw Exception("parser.runtime", 0, "can't get file size");  
         if(file_length <= offset)  
                 throw Exception("parser.runtime", 0, "offset too big");  
           
         size_t content_length = file_length-offset;  
         if(limit != (size_t)-1)  
                 content_length = limit<content_length?limit:content_length;  
   
         size_t part_length = content_length;  
   
         const size_t BUFSIZE = 4096;  
         unsigned char buf[BUFSIZE];  
         const char *range = SAPI::get_env(r.sapi_info, "HTTP_RANGE");  
         if(range){  
                 Array<Range> ar;  
                 parse_range(new String(range), ar);  
                 size_t count = ar.count();  
                 if(count == 1){  
                         Range &rg = ar.get_ref(0);  
                         if(rg.start == (size_t)-1 && rg.end == (size_t)-1){  
                                 SAPI::add_header_attribute(r.sapi_info, "status", "416 Requested Range Not Satisfiable");  
                                 return;  
                         }  
                         if(rg.start == (size_t)-1 && rg.end != (size_t)-1){  
                                 rg.start = content_length - rg.end;  
                                 rg.end = content_length;  
                                 offset += rg.start;  
                                 part_length = rg.end-rg.start;  
                         }else if(rg.start != (size_t)-1 && rg.end == (size_t)-1){  
                                 rg.end = content_length-1;  
                                 offset += rg.start;  
                                 part_length -= rg.start;  
                         }  
                         if(part_length == 0){  
                                 SAPI::add_header_attribute(r.sapi_info, "status", "204 No Content");  
                                 return;  
                         }  
                         SAPI::add_header_attribute(r.sapi_info, "status", "206 Partial Content");  
                         snprintf((char*)buf, BUFSIZE, "bytes %u-%u/%u", rg.start, rg.end, content_length);  
                         SAPI::add_header_attribute(r.sapi_info, "Content-Range", (char*)buf);  
                 }else if(count != 0){  
                         SAPI::add_header_attribute(r.sapi_info, "status", "501 Not Implemented");  
                         return;  
                 }  
         }  
   
         fseek(f, offset, SEEK_SET);  
         snprintf((char*)buf, BUFSIZE, "%u", part_length);  
         SAPI::add_header_attribute(r.sapi_info, "Content-Length", (char*)buf);  
   
         if(info.add_content_disposition && disposition){  
                 const char *fname = 0;  
                 if(to_file_name){  
                         fname = to_file_name->as_string().cstr();  
                 }else{  
                         const char *fname = c_from_file_name;  
                         const char *p1 = strrchr(fname, '/');  
                         const char *p2 = strrchr(fname, '\\');  
                         if(p1 || p2)  
                                 fname = max(p1, p2)+1;  
                 }  
   
                 snprintf((char*)buf, BUFSIZE, "%s; filename=\"%s\"", disposition, fname);  
                 SAPI::add_header_attribute(r.sapi_info, "Content-Disposition", (char*)buf);  
         }  
         if(info.add_content_type)  
                 SAPI::add_header_attribute(r.sapi_info, "Content-Type", r.mime_type_of(c_from_file_name).cstr());  
         if(info.add_last_modified){  
                 if(date == 0){  
                         struct stat st;   
                         if(stat(c_from_file_name, &st)!=0) throw Exception("parser.runtime", 0, "can't get file stat");  
                         date = new VDate(st.st_mtime);  
                 }  
                 const String &s = attributed_meaning_to_string(*date, String::L_AS_IS, true);  
                 SAPI::add_header_attribute(r.sapi_info, "Last-Modified", s.cstr());  
         }  
         r.cookie.output_result(r.sapi_info);  
         SAPI::send_header(r.sapi_info);  
   
         const char* request_method=getenv("REQUEST_METHOD");  
         bool header_only=request_method && strcasecmp(request_method, "HEAD")==0;  
         size_t sent = 0;  
         if(!header_only){  
                 size_t to_read = 0;  
                 size_t size = 0;  
                 do{  
                         to_read = part_length<BUFSIZE?part_length:BUFSIZE;  
                         to_read = fread(buf, 1, to_read, f);  
                         if(to_read == 0)  
                                 break;  
                         size = SAPI::send_body(r.sapi_info, buf, to_read);  
                         sent += size;  
                         if(size != to_read)  
                                 break;  
                         part_length -= to_read;  
                 }while(part_length);  
         }  
         // set flag to bypass other outputs  
         r.response.fields().put("ignore", new VString(*new String("y")));  
         r.write_no_lang(*new VInt(sent));  
 }  
   
   
 */  
   
   
   
 static void output_sole_piece(Request& r,  static void output_sole_piece(Request& r,
                                                           bool header_only,                                                             bool header_only, 
                                                           VFile& body_file,                                                            VFile& body_file,
Line 843  static void output_pieces(Request& r, Line 735  static void output_pieces(Request& r,
                                                   Value& date,                                                    Value& date,
                                                   bool add_last_modified)                                                     bool add_last_modified) 
 {  {
           SAPI::add_header_attribute(r.sapi_info, "Accept-Ranges", "bytes");
   
         const size_t BUFSIZE = 10*0x400;          const size_t BUFSIZE = 10*0x400;
         char buf[BUFSIZE];          char buf[BUFSIZE];
         const char *range = SAPI::get_env(r.sapi_info, "HTTP_RANGE");          const char *range = SAPI::get_env(r.sapi_info, "HTTP_RANGE");
Line 927  void Request::output_result(VFile* body_ Line 821  void Request::output_result(VFile* body_
         Value* vfile_name=body_file->fields().get(name_name);          Value* vfile_name=body_file->fields().get(name_name);
         if(!vfile_name) {          if(!vfile_name) {
                 vfile_name=body_file->fields().get(response_body_file_name);                  vfile_name=body_file->fields().get(response_body_file_name);
                 const String& sfile_name=vfile_name->as_string();                  if(vfile_name)
                   {
                           const String& sfile_name=vfile_name->as_string();
   
                 char* name_cstr=sfile_name.cstrm();                          char* name_cstr=sfile_name.cstrm();
                 if(char *after_slash=rsplit(name_cstr, '\\'))                          if(char *after_slash=rsplit(name_cstr, '\\'))
                         name_cstr=after_slash;                                  name_cstr=after_slash;
                 if(char *after_slash=rsplit(name_cstr, '/'))                          if(char *after_slash=rsplit(name_cstr, '/'))
                         name_cstr=after_slash;                                  name_cstr=after_slash;
                 vfile_name=new VString(*new String(name_cstr));                           vfile_name=new VString(*new String(name_cstr)); 
                   }
         }          }
         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();  
                         HashStringValue &h=hash.hash();  
                         if(as_attachment)                          if(as_attachment)
                           {
                                   VHash& hash=*new VHash();
                                   HashStringValue &h=hash.hash();
                                 h.put(value_name, new VString(content_disposition_value));                                  h.put(value_name, new VString(content_disposition_value));
                         h.put(content_disposition_filename_name, vfile_name);                                  h.put(content_disposition_filename_name, vfile_name);
                         response.fields().put(content_disposition_name, &hash);                                  response.fields().put(content_disposition_name, &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 963  void Request::output_result(VFile* body_ Line 862  void Request::output_result(VFile* body_
   
         // prepare header: $response:fields without :body          // prepare header: $response:fields without :body
         Add_header_attribute_info info(*this);          Add_header_attribute_info info(*this);
         response.fields().for_each(add_header_attribute, &info);          response.fields().for_each<Add_header_attribute_info*>(add_header_attribute, &info);
   
         if(body_file_content_type)          if(body_file_content_type)
                 if(HashStringValue *hash=body_file_content_type->get_hash())                  if(HashStringValue *hash=body_file_content_type->get_hash())
Line 1016  const String& Request::mime_type_of(cons Line 915  const String& Request::mime_type_of(cons
 }  }
   
 #ifdef XML  #ifdef XML
 GdomeDOMString_auto_ptr Request::transcode(const String& s) {  xmlChar* Request::transcode(const String& s) {
         return charsets.source().transcode(s);          return charsets.source().transcode(s);
 }  }
   
 GdomeDOMString_auto_ptr Request::transcode(const String::Body s) {  xmlChar* Request::transcode(const String::Body s) {
         return charsets.source().transcode(s);          return charsets.source().transcode(s);
 }  }
   
 const String& Request::transcode(GdomeDOMString* s) {  const String& Request::transcode(const xmlChar* s) {
         return charsets.source().transcode(s);  
 }  
   
 const String& Request::transcode(xmlChar* s) {  
         return charsets.source().transcode(s);          return charsets.source().transcode(s);
 }  }
 #endif  #endif
Line 1039  const Request::Trace Request::Exception_ Line 934  const Request::Trace Request::Exception_
         if(!is_empty()) {          if(!is_empty()) {
                 result=bottom_value();                  result=bottom_value();
                 if(!problem_source) { // we don't know who trigged the bug?                  if(!problem_source) { // we don't know who trigged the bug?
                         problem_source=result.name(); // consider the stack-top-guy did that                          problem_source=result.name(); // consider the stack-top-guy (we usually know source of next-from-throw-point exception) did that
                         fbottom++;                          fbottom++;
                 } else if(result.name()==problem_source) // it is that same guy?                  } else if(result.name()==problem_source) // it is that same guy?
                         fbottom++; // throw away that trace                          fbottom++; // throw away that trace
                 // else stack top contains not us,                   else {
                 //      leaving result intact                          // stack top contains not us, 
                 //      it would help ^throw                          //      leaving result intact
                           //      it would help ^throw
                   }
         }          }
   
         return result;          return result;

Removed from v.1.268  
changed lines
  Added in v.1.280.8.1


E-mail: