Diff for /parser3/src/main/pa_request.C between versions 1.278.2.1 and 1.300

version 1.278.2.1, 2005/12/13 11:00:55 version 1.300, 2009/04/29 03:26:50
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-2005 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001-2009 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 58  const char* ORIGINS_CONTENT_TYPE="text/p Line 58  const char* ORIGINS_CONTENT_TYPE="text/p
   
 const String main_method_name(MAIN_METHOD_NAME);  const String main_method_name(MAIN_METHOD_NAME);
 const String auto_method_name(AUTO_METHOD_NAME);  const String auto_method_name(AUTO_METHOD_NAME);
   const String content_transfer_encoding_name(CONTENT_TRANSFER_ENCODING_NAME);
 const String content_disposition_name(CONTENT_DISPOSITION_NAME);  const String content_disposition_name(CONTENT_DISPOSITION_NAME);
 const String content_disposition_value(CONTENT_DISPOSITION_VALUE);  const String content_disposition_inline(CONTENT_DISPOSITION_INLINE);
   const String content_disposition_attachment(CONTENT_DISPOSITION_ATTACHMENT);
 const String content_disposition_filename_name(CONTENT_DISPOSITION_FILENAME_NAME);  const String content_disposition_filename_name(CONTENT_DISPOSITION_FILENAME_NAME);
 const String body_name(BODY_NAME);  const String body_name(BODY_NAME);
 const String exception_type_part_name(EXCEPTION_TYPE_PART_NAME);  const String exception_type_part_name(EXCEPTION_TYPE_PART_NAME);
Line 107  Request::Request(SAPI_Info& asapi_info, Line 109  Request::Request(SAPI_Info& asapi_info,
         wcontext(0),          wcontext(0),
         flang(adefault_lang),          flang(adefault_lang),
         fconnection(0),          fconnection(0),
         finterrupted(false),          finterrupted(false),fskip(SKIP_NOTHING),
   
         // public          // public
 #ifdef RESOURCES_DEBUG  #ifdef RESOURCES_DEBUG
Line 124  Request::Request(SAPI_Info& asapi_info, Line 126  Request::Request(SAPI_Info& asapi_info,
         form(*new VForm(charsets, arequest_info)),          form(*new VForm(charsets, arequest_info)),
         mail(*new VMail),          mail(*new VMail),
         response(*new VResponse(arequest_info, charsets)),          response(*new VResponse(arequest_info, charsets)),
         cookie(*new VCookie),          cookie(*new VCookie(charsets, arequest_info)),
           console(*new VConsole),
   
         // private          // private
         configure_admin_done(false),          configure_admin_done(false),
Line 157  Request::Request(SAPI_Info& asapi_info, Line 160  Request::Request(SAPI_Info& asapi_info,
         if(status_allowed)          if(status_allowed)
                 classes().put(String::Body(STATUS_CLASS_NAME), new VStatus());                  classes().put(String::Body(STATUS_CLASS_NAME), new VStatus());
         // request class          // request class
         classes().put(String::Body(REQUEST_CLASS_NAME), new VRequest(arequest_info, charsets));           classes().put(String::Body(REQUEST_CLASS_NAME), new VRequest(arequest_info, charsets, form));   
         // cookie class          // cookie class
         classes().put(String::Body(COOKIE_CLASS_NAME), &cookie);          classes().put(String::Body(COOKIE_CLASS_NAME), &cookie);
         // console class          // console class
         classes().put(String::Body(CONSOLE_CLASS_NAME), new VConsole());          classes().put(String::Body(CONSOLE_CLASS_NAME), &console);
   
         /// methoded          /// methoded
         // response class          // response class
         classes().put(response.get_class()->name(), &response);          classes().put(response.get_class()->name(), &response);
Line 204  static void load_charset(HashStringValue Line 206  static void load_charset(HashStringValue
 }  }
 void Request::configure_admin(VStateless_class& conf_class) {  void Request::configure_admin(VStateless_class& conf_class) {
         if(configure_admin_done)          if(configure_admin_done)
                 throw Exception("parser.runtime",                  throw Exception(PARSER_RUNTIME,
                 0,                  0,
                 "parser already configured");                  "parser already configured");
         configure_admin_done=true;          configure_admin_done=true;
Line 220  void Request::configure_admin(VStateless Line 222  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,
                                         "$" MAIN_CLASS_NAME ":" CHARSETS_NAME " must be hash");                                          "$" MAIN_CLASS_NAME ":" CHARSETS_NAME " must be hash");
         }          }
Line 304  struct timeval mt[10]; Line 306  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                  // filling mail received
                 mail.fill_received(*this);                  mail.fill_received(*this);
   
Line 373  gettimeofday(&mt[1],NULL); Line 372  gettimeofday(&mt[1],NULL);
                 // execute @main[]                  // execute @main[]
                 const String* body_string=execute_virtual_method(main_class, main_method_name);                  const String* body_string=execute_virtual_method(main_class, main_method_name);
                 if(!body_string)                  if(!body_string)
                         throw Exception("parser.runtime",                          throw Exception(PARSER_RUNTIME,
                                 0,                                  0,
                                 "'"MAIN_METHOD_NAME"' method not found");                                  "'"MAIN_METHOD_NAME"' method not found");
   
Line 406  gettimeofday(&mt[2],NULL); Line 405  gettimeofday(&mt[2],NULL);
                                         VMethodFrame frame(/*method->name, */ *junction, 0/*no parent*/);                                          VMethodFrame frame(/*method->name, */ *junction, 0/*no parent*/);
                                         frame.set_self(main_class);                                          frame.set_self(main_class);
   
                                         frame.store_param(*body_value);                                          frame.store_params(&body_value, 1);
                                         body_value=&execute_method(frame, *method).as_value();                                          body_value=&execute_method(frame, *method).as_value();
                                 }                                  }
   
Line 463  t[9]-t[3] Line 462  t[9]-t[3]
                                 false)) {                                  false)) {
                         if(Junction* junction=value->get_junction()) {                          if(Junction* junction=value->get_junction()) {
                                 if(const Method *method=junction->method) {                                  if(const Method *method=junction->method) {
 // preparing to pass parameters to                                           // preparing to pass parameters to 
 //      @unhandled_exception[exception;stack]                                          //      @unhandled_exception[exception;stack]
 VMethodFrame frame(/*method->name, */ *junction, 0/*no caller*/);                                          VMethodFrame frame(/*method->name, */ *junction, 0/*no caller*/);
 frame.set_self(main_class);                                          frame.set_self(main_class);
   
 // $exception                                          // $stack[^table::create{name   file    lineno  colno}]
 frame.store_param(details.vhash);                                          Table::columns_type stack_trace_columns(new ArrayString);
 // $stack[^table::set{name      origin}]                                          *stack_trace_columns+=new String("name");
 Table::columns_type stack_trace_columns(new ArrayString);                                          *stack_trace_columns+=new String("file");
 *stack_trace_columns+=new String("name");                                          *stack_trace_columns+=new String("lineno");
 *stack_trace_columns+=new String("file");                                          *stack_trace_columns+=new String("colno");
 *stack_trace_columns+=new String("lineno");                                          Table& stack_trace=*new Table(stack_trace_columns);
 *stack_trace_columns+=new String("colno");                                          if(!exception_trace.is_empty()/*signed!*/) 
 Table& stack_trace=*new Table(stack_trace_columns);                                                  for(size_t i=exception_trace.bottom_index(); i<exception_trace.top_index(); i++) {
 if(!exception_trace.is_empty()/*signed!*/)                                                           Trace trace=exception_trace.get(i);
 for(size_t i=exception_trace.bottom_index(); i<exception_trace.top_index(); i++) {                                                          Table::element_type row(new ArrayString);
         Trace trace=exception_trace.get(i);  
         Table::element_type row(new ArrayString);                                                          *row+=trace.name(); // name column
                                                           Operation::Origin origin=trace.origin();
         *row+=trace.name(); // name column                                                          if(origin.file_no) {
         Operation::Origin origin=trace.origin();                                                                  *row+=new String(file_list[origin.file_no], String::L_TAINTED); // 'file' column
         if(origin.file_no) {                                                                  *row+=new String(String::Body::Format(1+origin.line), String::L_CLEAN); // 'lineno' column
                 *row+=new String(file_list[origin.file_no], String::L_TAINTED); // 'file' column                                                                  *row+=new String(String::Body::Format(1+origin.col), String::L_CLEAN); // 'colno' column
                 *row+=new String(String::Body::Format(1+origin.line), String::L_CLEAN); // 'lineno' column                                                          }
                 *row+=new String(String::Body::Format(1+origin.col), String::L_CLEAN); // 'colno' column                                                          stack_trace+=row;
         }                                                  }
         stack_trace+=row;  
 }                                          Value *params[]={&details.vhash, new VTable(&stack_trace)};
 frame.store_param(*new VTable(&stack_trace));                                          frame.store_params(params, 2);
   
 // 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)                                          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 522  body_string=&execute_method(frame, *meth Line 521  body_string=&execute_method(frame, *meth
   
                 // 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) { // exception in unhandled exception                  } catch(const Exception& e) { // exception in unhandled exception
                         Request::Exception_details details=get_details(e);                          Request::Exception_details details=get_details(e);
                         const char* exception_cstr=get_exception_cstr(e, details);                          const char* exception_cstr=get_exception_cstr(e, details);
Line 569  void Request::use_file(VStateless_class& Line 569  void Request::use_file(VStateless_class&
                                                 break; // found along class_path                                                  break; // found along class_path
                                 }                                  }
                         } else                          } else
                                 throw Exception("parser.runtime",                                  throw Exception(PARSER_RUNTIME,
                                         0,                                          0,
                                         "$" CLASS_PATH_NAME " must be string or table");                                          "$" CLASS_PATH_NAME " must be string or table");
                         if(!file_spec)                          if(!file_spec)
                                 throw Exception("parser.runtime",                                  throw Exception(PARSER_RUNTIME,
                                         &file_name,                                          &file_name,
                                         "not found along " MAIN_CLASS_NAME ":" CLASS_PATH_NAME);                                          "not found along " MAIN_CLASS_NAME ":" CLASS_PATH_NAME);
                 }                  }
                 if(!file_spec)                  if(!file_spec)
                         throw Exception("parser.runtime",                          throw Exception(PARSER_RUNTIME,
                                 &file_name,                                  &file_name,
                                 "usage failed - no $" MAIN_CLASS_NAME  ":" CLASS_PATH_NAME " were specified");                                  "usage failed - no $" MAIN_CLASS_NAME  ":" CLASS_PATH_NAME " were specified");
         }          }
Line 601  void Request::use_buf(VStateless_class& Line 601  void Request::use_buf(VStateless_class&
         // temporary zero @auto so to maybe-replace it in compiled code          // temporary zero @auto so to maybe-replace it in compiled code
         Temp_method temp_method_auto(aclass, auto_method_name, 0);          Temp_method temp_method_auto(aclass, auto_method_name, 0);
   
         // compile loaded class          // compile loaded classes
         VStateless_class& cclass=compile(&aclass, source, main_alias, file_no, line_no_offset);          ArrayClass& cclasses=compile(&aclass, source, main_alias, file_no, line_no_offset);
   
         // locate and execute possible @conf[] static  
         VString* vfilespec=          VString* vfilespec=
                 new VString(*new String(file_list[file_no], String::L_TAINTED));                  new VString(*new String(file_list[file_no], String::L_TAINTED));
         Execute_nonvirtual_method_result executed=execute_nonvirtual_method(cclass,   
                 conf_method_name, vfilespec,          for(size_t i=0; i<cclasses.count(); i++){
                 false/*no string result needed*/);                  VStateless_class& cclass=*cclasses.get(i);
         if(executed.method)  
                 configure_admin(cclass/*, executed.method->name*/);                  // locate and execute possible @conf[] static
                   Execute_nonvirtual_method_result executed=execute_nonvirtual_method(cclass, 
         // locate and execute possible @auto[] static                          conf_method_name, vfilespec,
         execute_nonvirtual_method(cclass,                           false/*no string result needed*/);
                 auto_method_name, vfilespec,                  if(executed.method)
                 false/*no result needed*/);                          configure_admin(cclass/*, executed.method->name*/);
   
                   // locate and execute possible @auto[] static
                   execute_nonvirtual_method(cclass, 
                           auto_method_name, vfilespec,
                           false/*no result needed*/);
           }
 }  }
   
 const String& Request::relative(const char* apath, const String& relative_name) {  const String& Request::relative(const char* apath, const String& relative_name) {
Line 656  public: Line 661  public:
 };  };
 #endif  #endif
 static void add_header_attribute(  static void add_header_attribute(
                                  HashStringValue::key_type aattribute,                                    HashStringValue::key_type name, 
                                  HashStringValue::value_type ameaning,                                    HashStringValue::value_type value, 
                                  Add_header_attribute_info* info) {                                   Add_header_attribute_info* info) {
         if(aattribute==BODY_NAME          if(name==BODY_NAME
                 || aattribute==DOWNLOAD_NAME                  || name==DOWNLOAD_NAME
                 || aattribute==CHARSET_NAME)                  || name==CHARSET_NAME)
                 return;                  return;
           
           const char* aname=String(name, String::L_URI).cstr(String::L_UNSPECIFIED, 0, &info->r.charsets);
   
         const char* a=aattribute.cstr();  
         SAPI::add_header_attribute(info->r.sapi_info,          SAPI::add_header_attribute(info->r.sapi_info,
                 a,                   aname, 
                 attributed_meaning_to_string(*ameaning, String::L_HTTP_HEADER, false).                  attributed_meaning_to_string(*value, String::L_URI, false).cstr(String::L_UNSPECIFIED, 0, &info->r.charsets));
                         cstr(String::L_UNSPECIFIED));  
   
         if(strcasecmp(a, "last-modified")==0)          if(strcasecmp(aname, "last-modified")==0)
                 info->add_last_modified = false;                  info->add_last_modified = false;
 }  }
   
Line 836  void Request::output_result(VFile* body_ Line 841  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) {
                         if(as_attachment)                          VHash& hash=*new VHash();
                         {                          HashStringValue &h=hash.hash();
                                 VHash& hash=*new VHash();                          h.put(value_name, new VString( as_attachment ? content_disposition_attachment : content_disposition_inline ));
                                 HashStringValue &h=hash.hash();  
                                 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 862  void Request::output_result(VFile* body_ Line 865  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 881  void Request::output_result(VFile* body_ Line 884  void Request::output_result(VFile* body_
                         if(Value* vdatep=v->as(VDATE_TYPE, false))                          if(Value* vdatep=v->as(VDATE_TYPE, false))
                                 vdate=static_cast<VDate*>(vdatep);                                  vdate=static_cast<VDate*>(vdatep);
                         else                           else 
                                 throw Exception("parser.runtime", 0, "mdate must be a date");                                  throw Exception(PARSER_RUNTIME, 0, "mdate must be a date");
                 }                  }
                 if(!vdate)                  if(!vdate)
                         vdate=new VDate(mtime);                          vdate=new VDate(mtime);
Line 906  const String& Request::mime_type_of(cons Line 909  const String& Request::mime_type_of(cons
                                         if(const String* result=mime_types->item(1))                                          if(const String* result=mime_types->item(1))
                                                 return *result;                                                  return *result;
                                 else                                  else
                                         throw Exception("parser.runtime",                                          throw Exception(PARSER_RUNTIME,
                                                 0,                                                  0,
                                                 MIME_TYPES_NAME  " table column elements must not be empty");                                                  MIME_TYPES_NAME  " table column elements must not be empty");
                 }                  }
Line 915  const String& Request::mime_type_of(cons Line 918  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);  
 }  
   
 GdomeDOMString_auto_ptr Request::transcode(const String::Body s) {  
         return charsets.source().transcode(s);          return charsets.source().transcode(s);
 }  }
   
 const String& Request::transcode(GdomeDOMString* s) {  xmlChar* Request::transcode(const String::Body s) {
         return charsets.source().transcode(s);          return charsets.source().transcode(s);
 }  }
   
 const String& Request::transcode(xmlChar* s) {  const String& Request::transcode(const xmlChar* s) {
         return charsets.source().transcode(s);          return charsets.source().transcode(s);
 }  }
 #endif  #endif
Line 985  Request::Exception_details Request::get_ Line 984  Request::Exception_details Request::get_
                         new VString(*new String(comment, 0, true/*tainted*/)));                          new VString(*new String(comment, 0, true/*tainted*/)));
   
         // $.handled(0)          // $.handled(0)
         hash.put(exception_handled_part_name, new VBool(false));          hash.put(exception_handled_part_name, &VBool::get(false));
   
         return Request::Exception_details(trace, problem_source, vhash);          return Request::Exception_details(trace, problem_source, vhash);
 }  }

Removed from v.1.278.2.1  
changed lines
  Added in v.1.300


E-mail: