--- parser3/src/main/pa_request.C 2001/11/19 12:17:06 1.182 +++ parser3/src/main/pa_request.C 2001/12/14 12:53:48 1.184 @@ -4,7 +4,7 @@ Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) Author: Alexander Petrosyan (http://paf.design.ru) - $Id: pa_request.C,v 1.182 2001/11/19 12:17:06 paf Exp $ + $Id: pa_request.C,v 1.184 2001/12/14 12:53:48 paf Exp $ */ #include "pa_config_includes.h" @@ -43,8 +43,8 @@ static void load_charset(const Hash::Key Charset_connection& connection= charset_manager->get_connection(akey, value.as_string()); - // charset->pcre_tables - CTYPE.put(akey, connection.pcre_tables()); + // charset->transcoder + CTYPE.put(akey, &connection.transcoder()); } // @@ -74,6 +74,9 @@ Request::Request(Pool& apool, classes_conf(apool), anti_endless_execute_recoursion(0), trace(apool) +#ifdef RESOURCES_DEBUG + ,sql_connect_time(0),sql_request_time(0) +#endif { // maybe expire old caches cache_managers->maybe_expire(); @@ -122,6 +125,13 @@ void Request::core( const char *root_config_filespec, bool root_config_fail_on_read_problem, const char *site_config_filespec, bool site_config_fail_on_read_problem, bool header_only) { + +#ifdef RESOURCES_DEBUG +//measures +struct timeval mt[10]; +//measure:before all +gettimeofday(&mt[0],NULL); +#endif try { char *auto_filespec=(char *)malloc(MAX_STRING); @@ -206,17 +216,6 @@ void Request::core( OP.configure_user(*this); methoded_array->configure_user(*this); - // $MAIN:DEFAULTS - Value *defaults=main_class->get_element(*defaults_name); - // value must be allocated on request's pool for that pool used on - // meaning constructing @see attributed_meaning_to_string - default_content_type=defaults?defaults->get_element(*content_type_name):0; - // record default charset - if(default_content_type) - if(Hash *hash=default_content_type->get_hash(0)) - if(Value *vcharset=(Value *)hash->get(*charset_name)) - pool().set_charset(vcharset->as_string()); - // $MAIN:MIME-TYPES if(Value *element=main_class->get_element(*mime_types_name)) if(Table *table=element->get_table()) @@ -228,6 +227,10 @@ void Request::core( // filling cookies cookie.fill_fields(*this); +#ifdef RESOURCES_DEBUG +//measure:after compile +gettimeofday(&mt[1],NULL); +#endif // execute @main[] const String *body_string=execute_virtual_method( *main_class, *main_method_name); @@ -236,9 +239,13 @@ void Request::core( 0, "'"MAIN_METHOD_NAME"' method not found"); +#ifdef RESOURCES_DEBUG + //measure:after main +gettimeofday(&mt[2],NULL); +#endif + VString body_vstring_before_post_process(*body_string); VString *body_vstring_after_post_process=&body_vstring_before_post_process; - // @postprocess if(Value *value=main_class->get_element(*post_process_method_name)) if(Junction *junction=value->get_junction()) @@ -268,8 +275,32 @@ void Request::core( response.fields().put(*content_type_name, NEW VString(*NEW String(pool(), ORIGINS_CONTENT_TYPE))); +#ifdef RESOURCES_DEBUG +//measure:after postprocess +gettimeofday(&mt[3],NULL); +#endif + // OK. write out the result output_result(*body_file, header_only); + +#ifdef RESOURCES_DEBUG + //measure:after output_result +gettimeofday(&mt[9],NULL); +t[9]=mt[9].tv_sec+mt[9].tv_usec/1000000.0; + +double t[10]; +for(int i=0;i<10;i++) + t[i]=mt[i].tv_sec+mt[i].tv_usec/1000000.0; +//measure:log2 compile,main,postprocess,output +SAPI::log(pool(), "rmeasure: %s,%.2f,%.2f,%.2f %.2f,%.2f %.2f", +info.uri, +t[1]-t[0], +t[2]-t[1], +t[3]-t[2], +sql_connect_time,sql_request_time, +t[9]-t[3] +); +#endif } catch(const Exception& e) { // request handling problem // we're returning not result, but error explanation try { @@ -537,7 +568,8 @@ const String& Request::absolute(const St static void add_header_attribute(const Hash::Key& aattribute, Hash::Val *ameaning, void *info) { Request& r=*static_cast(info); - if(aattribute==*body_name) + if(aattribute==BODY_NAME + || aattribute==CHARSET_NAME) return; Value& lmeaning=*static_cast(ameaning); @@ -574,14 +606,28 @@ void Request::output_result(const VFile& // prepare header: $response:fields without :body response.fields().for_each(add_header_attribute, this); - // prepare... - const void *body=body_file.value_ptr(); - size_t content_length=body_file.value_size(); + // source bytes+transcoder + const Transcoder *source_transcoder=transcoder(); + const void *source_body=body_file.value_ptr(); + size_t source_content_length=body_file.value_size(); + + // client bytes+transcoder + Transcoder *client_transcoder; + Value *vclient_charset=static_cast(response.fields().get(*charset_name)); + client_transcoder=vclient_charset?(Transcoder *)CTYPE.get(vclient_charset->as_string()):0; + const void *client_body; + size_t client_content_length; + + // transcode + transcoder_transcode(pool(), + source_transcoder, source_body, source_content_length, + client_transcoder, client_body, client_content_length + ); // prepare header: content-length - if(content_length) { // useful for redirecting [header "location: http://..."] + if(client_content_length) { // useful for redirecting [header "location: http://..."] char content_length_cstr[MAX_NUMBER]; - snprintf(content_length_cstr, MAX_NUMBER, "%u", content_length); + snprintf(content_length_cstr, MAX_NUMBER, "%u", client_content_length); SAPI::add_header_attribute(pool(), "content-length", content_length_cstr); } @@ -590,7 +636,7 @@ void Request::output_result(const VFile& // send body if(!header_only) - SAPI::send_body(pool(), body, content_length); + SAPI::send_body(pool(), client_body, client_content_length); } const String& Request::mime_type_of(const char *user_file_name_cstr) { @@ -608,9 +654,13 @@ const String& Request::mime_type_of(cons return *NEW String(pool(), "application/octet-stream"); } +const Transcoder* Request::transcoder() { + return (Transcoder *)CTYPE.get(pool().get_charset()); +} + const unsigned char *Request::pcre_tables() { - if(unsigned char *result=(unsigned char *)CTYPE.get(pool().get_charset())) - return result; + if(const Transcoder *ltranscoder=transcoder()) + return ltranscoder->pcre_tables; // this is not for pcre itself, // it can do default, it's for string.lower&co