--- parser3/src/main/pa_request.C 2024/11/04 03:53:25 1.429 +++ parser3/src/main/pa_request.C 2024/11/10 12:57:17 1.431 @@ -35,7 +35,7 @@ #include "pa_vdate.h" #include "pa_varray.h" -volatile const char * IDENT_PA_REQUEST_C="$Id: pa_request.C,v 1.429 2024/11/04 03:53:25 moko Exp $" IDENT_PA_REQUEST_H IDENT_PA_REQUEST_CHARSETS_H IDENT_PA_REQUEST_INFO_H IDENT_PA_VCONSOLE_H; +volatile const char * IDENT_PA_REQUEST_C="$Id: pa_request.C,v 1.431 2024/11/10 12:57:17 moko Exp $" IDENT_PA_REQUEST_H IDENT_PA_REQUEST_CHARSETS_H IDENT_PA_REQUEST_INFO_H IDENT_PA_VCONSOLE_H; // consts @@ -484,9 +484,6 @@ void Request::configure() { */ void Request::core(const char* config_filespec, bool header_only, const String &amain_method_name, const String* amain_class_name) { - VFile* body_file=NULL; - bool as_attachment=false; - try { // loading config if(config_filespec) @@ -513,7 +510,7 @@ void Request::core(const char* config_fi // extract response body Value* body_value=response.fields().get(download_name_upper); // $response:download? - as_attachment=body_value!=0; + bool as_attachment=body_value!=0; if(!body_value) body_value=response.fields().get(body_name_upper); // $response:body if(!body_value) @@ -528,23 +525,24 @@ void Request::core(const char* config_fi }); } - body_file=body_value->as_vfile(flang, &charsets); - + // can throw exceptions while handling $response:download[] + output_result(body_value->as_vfile(flang, &charsets), header_only, as_attachment); } catch(const Exception& e) { // request handling problem - try { - // we're returning not result, but error explanation - - Request::Exception_details details=get_details(e); - const char* exception_cstr=get_exception_cstr(e, details); - // reset language to default - flang=fdefault_lang; - // reset response - response.fields().clear(); + // we're returning not result, but error explanation + Request::Exception_details details=get_details(e); + const char* exception_cstr=get_exception_cstr(e, details); + + // reset language to default + flang=fdefault_lang; + // reset response + response.fields().clear(); + SAPI::clear_headers(sapi_info); - // this is what we'd return in $response:body - const String* body_string=0; + // this is what we'd return in $response:body + const String* body_string=0; + try { // maybe we'd be lucky enough as to report an error in a gracefull way... if(const Method *method=main_class.get_method(*new String(UNHANDLED_EXCEPTION_METHOD_NAME))) { // preparing parameters to @unhandled_exception[exception;stack] @@ -565,27 +563,23 @@ void Request::core(const char* config_fi if(!vhandled || !vhandled->as_bool()) { SAPI::log(sapi_info, "%s", exception_cstr); } - - if(body_string) { // could report an error beautifully? - VString body_vstring(*body_string); - - body_file=body_vstring.as_vfile(flang, &charsets); - as_attachment=false; - } else { - // doing that ugly - SAPI::send_error(sapi_info, exception_cstr, !strcmp(e.type(), "file.missing") ? "404" : "500"); - return; - } - - } catch(const Exception& e) { // exception in unhandled exception + } catch(const Exception& e) { // exception in @unhandled_exception Request::Exception_details details=get_details(e); - // unconditionally log the beast in exception handler - throw Exception(0, 0, "Unhandled exception in %s", get_exception_cstr(e, details)); + // logging both initial and new exceptions + SAPI::log(sapi_info, "%s", exception_cstr); + SAPI::log(sapi_info, "Exception in @unhandled_exception at %s", get_exception_cstr(e, details)); + SAPI::send_error(sapi_info, "Exception in @unhandled_exception, details are available in Parser error log."); + return; } - } - // write out the result outside of try as network exceptions should not be handled by parser code. - output_result(body_file, header_only, as_attachment); + if(body_string) { // could report an error beautifully? + VString body_vstring(*body_string); + output_result(body_vstring.as_vfile(flang, &charsets), header_only, false); + } else { + // doing that ugly + SAPI::send_error(sapi_info, exception_cstr, strcmp(e.type(), "file.missing") ? "500" : "404"); + } + } } uint Request::register_file(String::Body file_spec) { @@ -782,7 +776,7 @@ static void output_sole_piece(Request& r SAPI::add_header_attribute(r.sapi_info, HTTP_CONTENT_LENGTH, pa_uitoa(output.length)); // send header - SAPI::send_header(r.sapi_info); + SAPI::send_headers(r.sapi_info); // send body if(!header_only) @@ -846,7 +840,7 @@ struct Send_range_action_info { static void send_range(struct stat& /*finfo*/, int f, const String& /*file_spec*/, void *context){ Send_range_action_info &info = *(Send_range_action_info*)context; - SAPI::send_header(info.r->sapi_info); + SAPI::send_headers(info.r->sapi_info); pa_lseek(f, info.offset, SEEK_SET); const size_t BUFSIZE = 128*0x400; @@ -917,7 +911,7 @@ static void output_pieces(Request& r, bo SAPI::add_header_attribute(r.sapi_info, "last-modified", attributed_meaning_to_string(date, String::L_AS_IS, true).cstr()); if(header_only){ - SAPI::send_header(r.sapi_info); + SAPI::send_headers(r.sapi_info); } else { Send_range_action_info info = { &r, offset, part_length}; file_read_action_under_lock(r.full_disk_path(filename), "send", send_range, &info);