Diff for /parser3/src/main/pa_request.C between versions 1.46 and 1.67

version 1.46, 2001/03/18 16:32:25 version 1.67, 2001/03/23 08:47:46
Line 1 Line 1
 /*  /** @file
         Parser          Parser: request class main part. @see compile.C and execute.C.
   
         Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
   
         Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)          Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
   
         $Id$          $Id$
Line 8 Line 10
   
 #include <string.h>  #include <string.h>
   
   #include "pa_common.h"
 #include "pa_request.h"  #include "pa_request.h"
 #include "pa_wwrapper.h"  #include "pa_wwrapper.h"
 #include "pa_common.h"  
 #include "pa_vclass.h"  #include "pa_vclass.h"
 #include "_root.h"  #include "_root.h"
 #include "_env.h"  
 #include "_table.h"  #include "_table.h"
 #include "pa_globals.h"  #include "pa_globals.h"
 #include "pa_vint.h"  #include "pa_vint.h"
Line 29  Request::Request(Pool& apool, Line 30  Request::Request(Pool& apool,
         form(apool),          form(apool),
         request(apool, *this),          request(apool, *this),
         response(apool),          response(apool),
           cookie(apool),
         fclasses(apool),          fclasses(apool),
         fdefault_lang(adefault_lang), flang(adefault_lang),          fdefault_lang(adefault_lang), flang(adefault_lang),
         info(ainfo),          info(ainfo),
Line 41  Request::Request(Pool& apool, Line 43  Request::Request(Pool& apool,
         classes().put(*root_class_name, &ROOT);          classes().put(*root_class_name, &ROOT);
         // table class          // table class
         classes().put(*table_class_name, table_class);            classes().put(*table_class_name, table_class);  
 //      table_class->set_name(*table_class_name);  
   
         // env class          // env class
         classes().put(*env_class_name, &env);          classes().put(*env_class_name, &env);
Line 51  Request::Request(Pool& apool, Line 52  Request::Request(Pool& apool,
         classes().put(*request_class_name, &request);             classes().put(*request_class_name, &request);   
         // response class          // response class
         classes().put(*response_class_name, &response);           classes().put(*response_class_name, &response); 
           // cookie class
           classes().put(*cookie_class_name, &cookie);
 }  }
   
 void output_response_attribute(const Hash::Key& akey, Hash::Value *avalue, void *info) {  static void add_header_attribute(const Hash::Key& aattribute, Hash::Val *ameaning, 
         String *key_to_exclude=static_cast<String *>(info);                                                                   void *info) {
         if(akey==*key_to_exclude || !avalue)          String *attribute_to_exclude=static_cast<String *>(info);
           if(aattribute==*attribute_to_exclude)
                 return;                  return;
   
         String key(akey);          Value& lmeaning=*static_cast<Value *>(ameaning);
         key.change_lang(String::Untaint_lang::URI);          Pool& pool=lmeaning.pool();
   
         String value=static_cast<Value *>(avalue)->as_string();  
         value.change_lang(String::Untaint_lang::URI);  
   
         (*service_funcs.output_header_attribute)(          String attribute(pool);
                 key.cstr(),           (*service_funcs.add_header_attribute)(pool,
                 value.cstr());                  attribute.append(aattribute, String::UL_HEADER, true).cstr(), 
                   attributed_meaning_to_string(lmeaning).cstr());
 }  }
   
 void Request::core(Exception& system_exception,  /**
                                    const char *sys_auto_path1,          load MAIN class, execute @main.
                                    const char *sys_auto_path2) {          MAIN class consists of all the auto.p files we'd manage to find
           plus
           the file user requested us to process
           all located classes become children of one another,
           composing class we name 'MAIN'
   */
   void Request::core(const char *root_auto_path, bool root_auto_fail,
                                      const char *site_auto_path, bool site_auto_fail,
                                      bool header_only) {
         VStateless_class *main_class=0;          VStateless_class *main_class=0;
         bool need_rethrow=false;  Exception rethrow_me;          bool need_rethrow=false;  Exception rethrow_me;
         TRY {          TRY {
                 char *auto_filespec=(char *)malloc(MAX_STRING);                  char *auto_filespec=(char *)malloc(MAX_STRING);
                                   
                 // load MAIN class,                  // loading root auto.p 
                 //      it consists of all the auto.p files we'd manage to find                  if(root_auto_path) {
                 //      plus                          strncpy(auto_filespec, root_auto_path, MAX_STRING-strlen("/" AUTO_FILE_NAME));
                 //      the file user requested us to process                          strcat(auto_filespec, "/" AUTO_FILE_NAME);
                 //      all located classes become children of one another,  
                 //      composing class we name 'MAIN'  
   
                 // loading system auto.p 1  
                 if(sys_auto_path1) {  
                         strncpy(auto_filespec, sys_auto_path1, MAX_STRING-strlen(AUTO_FILE_NAME));  
                         strcat(auto_filespec, AUTO_FILE_NAME);  
                         main_class=use_file(                          main_class=use_file(
                                 auto_filespec, false/*ignore possible read problem*/,                                  auto_filespec, root_auto_fail,
                                 main_class_name, main_class);                                  main_class_name, main_class);
                 }                  }
   
                 // loading system auto.p 2                  // loading site auto.p
                 if(sys_auto_path2) {                  if(site_auto_path) {
                         strncpy(auto_filespec, sys_auto_path2, MAX_STRING-strlen(AUTO_FILE_NAME));                          strncpy(auto_filespec, site_auto_path, MAX_STRING-strlen("/" AUTO_FILE_NAME));
                         strcat(auto_filespec, AUTO_FILE_NAME);                          strcat(auto_filespec, "/" AUTO_FILE_NAME);
                         main_class=use_file(                          main_class=use_file(
                                 auto_filespec, false/*ignore possible read problem*/,                                  auto_filespec, site_auto_fail,
                                 main_class_name, main_class);                                  main_class_name, main_class);
                 }                  }
   
Line 112  void Request::core(Exception& system_exc Line 115  void Request::core(Exception& system_exc
                 int post_max_size=value?value:10*0x400*400;                  int post_max_size=value?value:10*0x400*400;
   
                 form.fill_fields(*this, post_max_size);                  form.fill_fields(*this, post_max_size);
                   cookie.fill_fields(*this);
   
                 // TODO: load site auto.p files, all assigned bases from upper dir                  // TODO: load site auto.p files, all assigned bases from upper dir
                 /*char *site_auto_file="Y:\\parser3\\src\\auto.p";                  /*char *site_auto_file="Y:\\parser3\\src\\auto.p";
Line 121  void Request::core(Exception& system_exc Line 125  void Request::core(Exception& system_exc
   
                 // $MAIN:defaults                  // $MAIN:defaults
                 Value *defaults=main_class?main_class->get_element(*defaults_name):0;                  Value *defaults=main_class?main_class->get_element(*defaults_name):0;
                 // $defaults.content-type                  fdefault_content_type=defaults?defaults->get_element(*content_type_name):0;
                 element=defaults?defaults->get_element(*content_type_name):0;  
                 response.fields().put(*content_type_name, fdefault_content_type=element);  
   
                 // there must be some auto.p  
                 if(!main_class)  
                         THROW(0,0,  
                                 0,  
                                 "no 'auto.p' found (nither system nor any site's)");  
   
                 // compiling requested file                  // compiling requested file
                 main_class=use_file(info.path_translated, true/*don't ignore read problem*/,                  main_class=use_file(info.path_translated, true/*don't ignore read problem*/,
Line 149  void Request::core(Exception& system_exc Line 145  void Request::core(Exception& system_exc
                         body_string=&body_value->as_string();// TODO: IMAGE&FILE                          body_string=&body_value->as_string();// TODO: IMAGE&FILE
   
                 // OK. write out the result                  // OK. write out the result
                 output_result(*body_string);                  output_result(*body_string, header_only);
         }           } 
         CATCH(e) {          CATCH(e) {
                 TRY {                  TRY {
Line 161  void Request::core(Exception& system_exc Line 157  void Request::core(Exception& system_exc
                         // reset response                          // reset response
                         response.fields().clear();                          response.fields().clear();
   
                         // this is what we'd return in $response:content-type  
                         Value *content_type;  
   
                         // this is what we'd return in $response:body                          // this is what we'd return in $response:body
                         const String *body_string=0;                          const String *body_string=0;
   
Line 202  void Request::core(Exception& system_exc Line 195  void Request::core(Exception& system_exc
                                                         String source_name(pool(), "source");                                                          String source_name(pool(), "source");
                                                         Value *source_value=0;                                                          Value *source_value=0;
                                                         if(problem_source) {                                                          if(problem_source) {
                                                                 String& problem_source_copy=*NEW String(*problem_source);                                                                  String& problem_source_copy=*NEW String(pool());
                                                                 problem_source_copy.change_lang(flang);                                                                  problem_source_copy.append(*problem_source, 
                                                                           flang, true);
                                                                 source_value=NEW VString(problem_source_copy);                                                                  source_value=NEW VString(problem_source_copy);
                                                         }                                                          }
                                                         frame.store_param(source_name,                                                           frame.store_param(source_name, 
Line 220  void Request::core(Exception& system_exc Line 214  void Request::core(Exception& system_exc
                                                         String type_name(pool(), "type");                                                          String type_name(pool(), "type");
                                                         Value *type_value;                                                          Value *type_value;
                                                         if(e.type()) {                                                          if(e.type()) {
                                                                 String& type_copy=*NEW String(*e.type());                                                                  String& type_copy=*NEW String(pool());
                                                                 type_copy.change_lang(flang);                                                                  type_value=NEW VString(type_copy.append(*e.type(), 
                                                                 type_value=NEW VString(type_copy);                                                                          flang, true));
                                                         } else                                                          } else
                                                                 type_value=NEW VUnknown(pool());                                                                  type_value=NEW VUnknown(pool());
                                                         frame.store_param(type_name, type_value);                                                          frame.store_param(type_name, type_value);
Line 231  void Request::core(Exception& system_exc Line 225  void Request::core(Exception& system_exc
                                                         String code_name(pool(), "code");                                                          String code_name(pool(), "code");
                                                         Value *code_value;                                                          Value *code_value;
                                                         if(e.code()) {                                                          if(e.code()) {
                                                                 String& code_copy=*NEW String(*e.code());                                                                  String& code_copy=*NEW String(pool());
                                                                 code_copy.change_lang(flang);                                                                  code_value=NEW VString(code_copy.append(*e.code(), 
                                                                 code_value=NEW VString(code_copy);                                                                          flang, true));
                                                         } else                                                          } else
                                                                 code_value=NEW VUnknown(pool());                                                                  code_value=NEW VUnknown(pool());
                                                         frame.store_param(code_name, code_value);                                                          frame.store_param(code_name, code_value);
   
                                                         // future $response:content-type=  
                                                         //   content-type from any auto.p  
                                                         content_type=fdefault_content_type;  
                                                         // future $response:body=                                                          // future $response:body=
                                                         //   execute ^exception[origin;source;comment;type;code]                                                          //   execute ^exception[origin;source;comment;type;code]
                                                         body_string=execute_method(frame, *method);                                                          body_string=execute_method(frame, *method);
Line 277  void Request::core(Exception& system_exc Line 268  void Request::core(Exception& system_exc
                                 }                                  }
   
                                 // future $response:content-type                                  // future $response:content-type
                                 String &content_type_value=*NEW String(pool(), "text/plain");                                  response.fields().put(*content_type_name, 
                                 content_type=NEW VString(content_type_value);                                          NEW VString(*NEW String(pool(), "text/plain")));
                                 // future $response:body                                  // future $response:body
                                 body_string=NEW String(pool(), buf);                                  body_string=NEW String(pool(), buf);
                         }                          }
   
                         // set $response:content-type  
                         response.fields().put(*content_type_name, content_type);  
   
                         // ERROR. write it out                          // ERROR. write it out
                         output_result(*body_string);                          output_result(*body_string, header_only);
                 }                  }
                 CATCH(e) {                  CATCH(e) {
                         // exception in request exception handler                          // exception in request exception handler
Line 300  void Request::core(Exception& system_exc Line 288  void Request::core(Exception& system_exc
                   // any throw() would try to use zero exception() pointer                     // any throw() would try to use zero exception() pointer 
   
         if(need_rethrow) // there were an exception set for us to rethrow?          if(need_rethrow) // there were an exception set for us to rethrow?
                 system_exception._throw(rethrow_me.type(), rethrow_me.code(),                  THROW(rethrow_me.type(), rethrow_me.code(),
                         rethrow_me.problem_source(),                          rethrow_me.problem_source(),
                         rethrow_me.comment());                          rethrow_me.comment());
   
 }  }
   
 VStateless_class *Request::use_file(  /// @todo find|solve cyclic dependences
                                                                         const char *file, bool fail_on_read_problem,  VStateless_class *Request::use_file(const char *file, bool fail_on_read_problem,
                                                                         const String *name,                                                                           const String *name, 
                                                                         VStateless_class *base_class) {                                                                          VStateless_class *base_class) {
         // TODO: обнаружить|решить cyclic dependences          char *source=file_read_text(pool(), file, fail_on_read_problem);
         char *source=file_read(pool(), file, fail_on_read_problem);  
         if(!source)          if(!source)
                 return base_class;                  return base_class;
   
         return use_buf(source, file, 0/*new class*/, name, base_class);          return use_buf(source, file, 0/*new class*/, name, base_class);
 }  }
   
 VStateless_class *Request::use_buf(  VStateless_class *Request::use_buf(const char *source, const char *file,
                                                                    const char *source, const char *file,  
                                                                    VStateless_class *aclass, const String *name,                                                                      VStateless_class *aclass, const String *name, 
                                                                    VStateless_class *base_class) {                                                                     VStateless_class *base_class) {
         // compile loaded class          // compile loaded class
Line 330  VStateless_class *Request::use_buf( Line 316  VStateless_class *Request::use_buf(
         return &cclass;          return &cclass;
 }  }
   
 void Request::fail_if_junction_(bool is,   /**
                                                                 Value& value, const String& method_name, char *msg) {          - fail_if_junction(true, junction = fail
           - fail_if_junction(false, not junction = fail
   */
   void Request::fail_if_junction_(bool is, Value& value, 
                                                                   const String& method_name, const char *msg) {
   
         // fail_if_junction(true, junction = fail  
         // fail_if_junction(false, not junction = fail  
         if((value.get_junction()!=0) ^ !is)          if((value.get_junction()!=0) ^ !is)
                 THROW(0, 0,                  THROW(0, 0,
                         &method_name,                          &method_name,
Line 344  void Request::fail_if_junction_(bool is, Line 332  void Request::fail_if_junction_(bool is,
 char *Request::relative(const char *path, const char *file) {  char *Request::relative(const char *path, const char *file) {
     char *result=(char *)malloc(strlen(path)+strlen(file)+1);      char *result=(char *)malloc(strlen(path)+strlen(file)+1);
         strcpy(result, path);          strcpy(result, path);
     rsplit(result, PATH_DELIMITER_CHAR);      rsplit(result, '/');
     strcat(result, PATH_DELIMITER_STRING);      strcat(result, "/");
     strcat(result, file);      strcat(result, file);
     return result;      return result;
 }  }
Line 357  char *Request::absolute(const char *name Line 345  char *Request::absolute(const char *name
                 strcat(result, name);                  strcat(result, name);
                 return result;                  return result;
         } else           } else 
                 return relative(info.uri, name);                  return relative(info.path_translated, name);
 }  }
   
 void Request::output_result(const String& body_string) {  void Request::output_result(const String& body_string, bool header_only) {
         // header: response fields           // header: cookies
         response.fields().foreach(output_response_attribute, /*excluding*/ body_name);          cookie.output_result();
           
           // set default content-type
           if(fdefault_content_type)
                   response.fields().put_dont_replace(*content_type_name, fdefault_content_type);
   
           // prepare header: $response:fields without :body
           response.fields().foreach(add_header_attribute, /*excluding*/ body_name);
   
           // prepare...
         const char *body=body_string.cstr();          const char *body=body_string.cstr();
         if(size_t content_length=strlen(body)) {          size_t content_length=strlen(body);
                 // header: content-length  
           // prepare header: content-length
           if(content_length) { // useful for redirecting [header "location: http://..."]
                 char content_length_cstr[MAX_NUMBER];                  char content_length_cstr[MAX_NUMBER];
                 snprintf(content_length_cstr, MAX_NUMBER, "%d", content_length);                  snprintf(content_length_cstr, MAX_NUMBER, "%lu", content_length);
                 (*service_funcs.output_header_attribute)("content-length",                   (*service_funcs.add_header_attribute)(pool(), "content-length", content_length_cstr);
                         content_length_cstr);  
                 // body  
                 (*service_funcs.output_body)(body, content_length);  
         }          }
 }  
   
   
           // send header
           (*service_funcs.send_header)(pool());
   
           // send body
           if(!header_only)
                   (*service_funcs.send_body)(pool(), body, content_length);
   }

Removed from v.1.46  
changed lines
  Added in v.1.67


E-mail: