--- parser3/src/main/pa_request.C 2002/10/16 07:32:51 1.235 +++ parser3/src/main/pa_request.C 2003/01/28 11:38:50 1.245.2.1 @@ -1,11 +1,11 @@ /** @file Parser: request class main part. @see compile.C and execute.C. - Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) + Copyright (c) 2001, 2003 ArtLebedev Group (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) */ -static const char* IDENT_REQUEST_C="$Date: 2002/10/16 07:32:51 $"; +static const char* IDENT_REQUEST_C="$Date: 2003/01/28 11:38:50 $"; #include "pa_sapi.h" #include "pa_common.h" @@ -68,11 +68,12 @@ Request::Request(Pool& apool, #ifdef RESOURCES_DEBUG , sql_connect_time(0),sql_request_time(0) #endif - , self(0), method_frame(0), rcontext(0), wcontext(0) + , method_frame(0), rcontext(0), wcontext(0), + finterrupted(false) { // default charsets - pool().set_source_charset(*utf8_charset); - pool().set_client_charset(*utf8_charset); + pool().set_source_charset(UTF8_charset); + pool().set_client_charset(UTF8_charset); // maybe expire old caches cache_managers->maybe_expire(); @@ -118,6 +119,8 @@ Request::~Request() { #endif } +Value *Request::get_self() { return method_frame?&method_frame->self():0; } + static void load_charset(const Hash::Key& akey, Hash::Val *avalue, void *) { charsets->load_charset(akey, static_cast(avalue)->as_string()); } @@ -136,13 +139,14 @@ void Request::configure_admin(VStateless ... ] */ - if(Value *vcharsets=conf_class.get_element(*charsets_name, &conf_class, false)) { - if(Hash *charsets=vcharsets->get_hash(0)) - charsets->for_each(load_charset); - else if(!vcharsets->get_string()) - throw Exception("parser.runtime", - 0, - "$" MAIN_CLASS_NAME ":" CHARSETS_NAME " must be hash"); + if(Value *vcharsets=conf_class.get_element(*charsets_name, conf_class, false)) { + if(!vcharsets->is_string()) + if(Hash *charsets=vcharsets->get_hash(0)) + charsets->for_each(load_charset); + else + throw Exception("parser.runtime", + 0, + "$" MAIN_CLASS_NAME ":" CHARSETS_NAME " must be hash"); } // configure method_frame options @@ -227,7 +231,7 @@ gettimeofday(&mt[0],NULL); methoded_array->configure_user(*this); // $MAIN:MIME-TYPES - if(Value *element=main_class.get_element(*mime_types_name, &main_class, false)) + if(Value *element=main_class.get_element(*mime_types_name, main_class, false)) if(Table *table=element->get_table()) mime_types=table; @@ -261,7 +265,7 @@ gettimeofday(&mt[2],NULL); // @postprocess if(Value *value=main_class.get_element( *NEW String(pool(), POST_PROCESS_METHOD_NAME), - &main_class, + main_class, false)) if(Junction *junction=value->get_junction()) if(const Method *method=junction->method) { @@ -282,7 +286,12 @@ gettimeofday(&mt[2],NULL); // extract response body Value *body_value=static_cast( - response.fields().get(*body_name)); + response.fields().get(*download_name)); + bool as_attachment=body_value!=0; + if(!body_value) + body_value=static_cast( + response.fields().get(*body_name)); + if(body_value) // there is some $response:body body_file=body_value->as_vfile(); else if(lorigins_mode) @@ -295,7 +304,7 @@ gettimeofday(&mt[3],NULL); #endif // OK. write out the result - output_result(*body_file, header_only); + output_result(*body_file, header_only, as_attachment); #ifdef RESOURCES_DEBUG //measure:after output_result @@ -356,7 +365,7 @@ t[9]-t[3] // in a gracefull way... if(Value *value=main_class.get_element( *NEW String(pool(), UNHANDLED_EXCEPTION_METHOD_NAME), - &main_class, + main_class, false)) { if(Junction *junction=value->get_junction()) { if(const Method *method=junction->method) { @@ -433,7 +442,7 @@ t[9]-t[3] const VFile *body_file=body_vstring.as_vfile(); // ERROR. write it out - output_result(*body_file, header_only); + output_result(*body_file, header_only, false); } catch(const Exception& ) { /*re*/throw; } @@ -455,7 +464,7 @@ VStateless_class *Request::use_file(VSta file_spec=&absolute(file_name); else { 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()) { file_spec=file_readable(absolute(element->as_string()), file_name); // found at class_path? } else if(Table *table=element->get_table()) { @@ -536,13 +545,15 @@ const String& Request::absolute(const St result << relative_name; return result; } else - return relative(info.path_translated, relative_name); + return relative_name.pos("://")<0? relative(info.path_translated, relative_name) + :relative_name; // something like "http://xxx" } static void add_header_attribute(const Hash::Key& aattribute, Hash::Val *ameaning, void *info) { Request& r=*static_cast(info); if(aattribute==BODY_NAME + || aattribute==DOWNLOAD_NAME || aattribute==CHARSET_NAME) return; @@ -551,9 +562,10 @@ static void add_header_attribute(const H SAPI::add_header_attribute(pool, aattribute.cstr(), - attributed_meaning_to_string(lmeaning, String::UL_HTTP_HEADER).cstr()); + attributed_meaning_to_string(lmeaning, String::UL_HTTP_HEADER, false) + .cstr(String::UL_UNSPECIFIED)); } -void Request::output_result(const VFile& body_file, bool header_only) { +void Request::output_result(const VFile& body_file, bool header_only, bool as_attachment) { // header: cookies cookie.output_result(); @@ -574,7 +586,10 @@ void Request::output_result(const VFile& if(VString *vfile_name=static_cast(body_file.fields().get(*name_name))) if(vfile_name->string()!=NONAME_DAT) { VHash& vhash=*NEW VHash(pool()); - vhash.hash(0).put(*content_disposition_filename_name, vfile_name); + Hash& hash=vhash.hash(0); + if(as_attachment) + hash.put(*value_name, NEW VString(*content_disposition_value)); + hash.put(*content_disposition_filename_name, vfile_name); response.fields().put(*content_disposition_name, &vhash); } @@ -626,5 +641,5 @@ const String& Request::mime_type_of(cons } bool Request::origins_mode() { - return main_class.get_element(*origins_mode_name, &main_class, false)!=0; // $ORIGINS mode + return main_class.get_element(*origins_mode_name, main_class, false)!=0; // $ORIGINS mode }