|
|
| version 1.318, 2010/05/20 04:36:20 | version 1.329, 2012/03/16 09:24:14 |
|---|---|
| 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-2009 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com) |
| Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) | Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) |
| */ | */ |
| static const char * const IDENT_REQUEST_C="$Date$"; | |
| #include "pa_sapi.h" | #include "pa_sapi.h" |
| #include "pa_common.h" | #include "pa_common.h" |
| #include "pa_request.h" | #include "pa_request.h" |
| Line 34 static const char * const IDENT_REQUEST_ | Line 32 static const char * const IDENT_REQUEST_ |
| #include "pa_vconsole.h" | #include "pa_vconsole.h" |
| #include "pa_vdate.h" | #include "pa_vdate.h" |
| volatile const char * IDENT_PA_REQUEST_C="$Id$" IDENT_PA_REQUEST_H IDENT_PA_REQUEST_CHARSETS_H IDENT_PA_REQUEST_INFO_H IDENT_PA_VCONSOLE_H; | |
| // consts | // consts |
| #define UNHANDLED_EXCEPTION_METHOD_NAME "unhandled_exception" | #define UNHANDLED_EXCEPTION_METHOD_NAME "unhandled_exception" |
| Line 97 VStateless_class& VClassMAIN_create(); | Line 97 VStateless_class& VClassMAIN_create(); |
| // | // |
| Request::Request(SAPI_Info& asapi_info, Request_info& arequest_info, | Request::Request(SAPI_Info& asapi_info, Request_info& arequest_info, |
| String::Language adefault_lang, bool status_allowed): | String::Language adefault_lang): |
| // private | // private |
| anti_endless_execute_recoursion(0), | anti_endless_execute_recoursion(0), |
| anti_endless_json_string_recoursion(0), | |
| // public | // public |
| method_frame(0), | method_frame(0), |
| Line 157 Request::Request(SAPI_Info& asapi_info, | Line 158 Request::Request(SAPI_Info& asapi_info, |
| // env class | // env class |
| classes().put(String::Body(ENV_CLASS_NAME), new VEnv(asapi_info)); | classes().put(String::Body(ENV_CLASS_NAME), new VEnv(asapi_info)); |
| // status class | // status class |
| 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, form)); | classes().put(String::Body(REQUEST_CLASS_NAME), new VRequest(arequest_info, charsets, form)); |
| // cookie class | // cookie class |
| Line 205 Value* Request::get_class(const String& | Line 205 Value* Request::get_class(const String& |
| if(Junction* junction=value->get_junction()) | if(Junction* junction=value->get_junction()) |
| if(const Method *method=junction->method) { | if(const Method *method=junction->method) { |
| Value *vname=new VString(name); | Value *vname=new VString(name); |
| VMethodFrame frame(*junction, 0/*no parent*/); | VMethodFrame frame(*method, 0 /*no parent*/, main_class); |
| frame.set_self(main_class); | |
| frame.store_params(&vname, 1); | frame.store_params(&vname, 1); |
| // we don't need the result | // we don't need the result |
| execute_method(frame, *method); | execute_method(frame); |
| result=classes().get(name); | result=classes().get(name); |
| } | } |
| Line 409 gettimeofday(&mt[2],NULL); | Line 408 gettimeofday(&mt[2],NULL); |
| if(const Method *method=junction->method) { | if(const Method *method=junction->method) { |
| // preparing to pass parameters to | // preparing to pass parameters to |
| // @postprocess[data] | // @postprocess[data] |
| VMethodFrame frame(/*method->name, */ *junction, 0/*no parent*/); | VMethodFrame frame(*method, 0 /*no parent*/, main_class); |
| frame.set_self(main_class); | |
| frame.store_params(&body_value, 1); | frame.store_params(&body_value, 1); |
| body_value=&execute_method(frame, *method).as_value(); | execute_method(frame); |
| body_value=&frame.result().as_value(); | |
| } | } |
| VFile* body_file=body_value->as_vfile(flang, &charsets); | VFile* body_file=body_value->as_vfile(flang, &charsets); |
| Line 467 t[9]-t[3] | Line 467 t[9]-t[3] |
| 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*/); | |
| frame.set_self(main_class); | |
| // $stack[^table::create{name file lineno colno}] | // $stack[^table::create{name file lineno colno}] |
| Table::columns_type stack_trace_columns(new ArrayString); | Table::columns_type stack_trace_columns(new ArrayString); |
| Line 492 t[9]-t[3] | Line 490 t[9]-t[3] |
| stack_trace+=row; | stack_trace+=row; |
| } | } |
| Value *params[]={&details.vhash, 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(); | |
| VMethodFrame frame(*method, 0 /*no caller*/, main_class); | |
| Value *params[]={&details.vhash, new VTable(&stack_trace)}; | |
| frame.store_params(params, 2); | |
| execute_method(frame); | |
| body_string=&frame.result().as_string(); | |
| } | } |
| } | } |
| } | } |
| Line 566 void Request::use_file(VStateless_class& | Line 568 void Request::use_file(VStateless_class& |
| const String& file_name, | const String& file_name, |
| const String* use_filespec/*absolute*/) { | const String* use_filespec/*absolute*/) { |
| if(file_name.is_empty()) | |
| 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] |
| Line 844 void Request::output_result(VFile* body_ | Line 851 void Request::output_result(VFile* body_ |
| 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) { |
| Line 853 void Request::output_result(VFile* body_ | Line 860 void Request::output_result(VFile* body_ |
| VHash& hash=*new VHash(); | VHash& hash=*new VHash(); |
| HashStringValue &h=hash.hash(); | HashStringValue &h=hash.hash(); |
| h.put(value_name, new VString( as_attachment ? content_disposition_attachment : content_disposition_inline )); | h.put(value_name, new VString( as_attachment ? content_disposition_attachment : content_disposition_inline )); |
| h.put(content_disposition_filename_name, vfile_name); | h.put(content_disposition_filename_name, new VString(String(sfile_name, String::L_HTTP_HEADER))); |
| response.fields().put(content_disposition, &hash); | response.fields().put(content_disposition, &hash); |
| Line 909 void Request::output_result(VFile* body_ | Line 916 void Request::output_result(VFile* body_ |
| } | } |
| } | } |
| const String& Request::mime_type_of(const String* file_name) { | |
| return mime_type_of(file_name?file_name->taint_cstr(String::L_FILE_SPEC):0); | |
| } | |
| const String& Request::mime_type_of(const char* user_file_name_cstr) { | const String& Request::mime_type_of(const char* user_file_name_cstr) { |
| if(mime_types) | if(mime_types) |
| if(const char* cext=strrchr(user_file_name_cstr, '.')) { | if(const char* cext=strrchr(user_file_name_cstr, '.')) { |
| Line 926 const String& Request::mime_type_of(cons | Line 937 const String& Request::mime_type_of(cons |
| return *new String("application/octet-stream"); | return *new String("application/octet-stream"); |
| } | } |
| const String* Request::get_method_filename(const Method* method){ | |
| if(ArrayOperation* code=method->parser_code) | |
| return get_used_filename(code->get(1).origin.file_no); // todo@ check if 1 is always origin | |
| return 0; | |
| } | |
| const String* Request::get_used_filename(uint file_no){ | const String* Request::get_used_filename(uint file_no){ |
| if(file_no < file_list.count()) | if(file_no < file_list.count()) |
| return new String(file_list[file_no], String::L_TAINTED); | return new String(file_list[file_no], String::L_TAINTED); |