@@ -1182,12 +1182,13 @@ class Server {
11821182 void apply_ranges (const Request &req, Response &res,
11831183 std::string &content_type, std::string &boundary) const ;
11841184 bool write_response (Stream &strm, bool close_connection, Request &req,
1185- Response &res);
1185+ Response &res, Error error );
11861186 bool write_response_with_content (Stream &strm, bool close_connection,
1187- const Request &req, Response &res);
1187+ const Request &req, Response &res,
1188+ Error error);
11881189 bool write_response_core (Stream &strm, bool close_connection,
11891190 const Request &req, Response &res,
1190- bool need_apply_ranges);
1191+ bool need_apply_ranges, Error error );
11911192 bool write_content_with_provider (Stream &strm, const Request &req,
11921193 Response &res, const std::string &boundary,
11931194 const std::string &content_type);
@@ -7234,23 +7235,23 @@ inline bool Server::parse_request_line(const char *s, Request &req) const {
72347235}
72357236
72367237inline bool Server::write_response (Stream &strm, bool close_connection,
7237- Request &req, Response &res) {
7238+ Request &req, Response &res, Error error ) {
72387239 // NOTE: `req.ranges` should be empty, otherwise it will be applied
72397240 // incorrectly to the error content.
72407241 req.ranges .clear ();
7241- return write_response_core (strm, close_connection, req, res, false );
7242+ return write_response_core (strm, close_connection, req, res, false , error );
72427243}
72437244
72447245inline bool Server::write_response_with_content (Stream &strm,
72457246 bool close_connection,
72467247 const Request &req,
7247- Response &res) {
7248- return write_response_core (strm, close_connection, req, res, true );
7248+ Response &res, Error error ) {
7249+ return write_response_core (strm, close_connection, req, res, true , error );
72497250}
72507251
72517252inline bool Server::write_response_core (Stream &strm, bool close_connection,
72527253 const Request &req, Response &res,
7253- bool need_apply_ranges) {
7254+ bool need_apply_ranges, Error error ) {
72547255 assert (res.status != -1 );
72557256
72567257 if (400 <= res.status && error_handler_ &&
@@ -7319,6 +7320,11 @@ inline bool Server::write_response_core(Stream &strm, bool close_connection,
73197320 // Log
73207321 if (access_logger_) { access_logger_ (req, res); }
73217322
7323+ if ((error != Error::Success || !ret) && error_logger_) {
7324+ Error final_error = error != Error::Success ? error : Error::Write;
7325+ error_logger_ (req, final_error);
7326+ }
7327+
73227328 return ret;
73237329}
73247330
@@ -7892,15 +7898,15 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
78927898 if (!parse_request_line (line_reader.ptr (), req) ||
78937899 !detail::read_headers (strm, req.headers )) {
78947900 res.status = StatusCode::BadRequest_400;
7895- return write_response (strm, close_connection, req, res);
7901+ return write_response (strm, close_connection, req, res, Error::Read );
78967902 }
78977903
78987904 // Check if the request URI doesn't exceed the limit
78997905 if (req.target .size () > CPPHTTPLIB_REQUEST_URI_MAX_LENGTH ) {
79007906 Headers dummy;
79017907 detail::read_headers (strm, dummy);
79027908 res.status = StatusCode::UriTooLong_414;
7903- return write_response (strm, close_connection, req, res);
7909+ return write_response (strm, close_connection, req, res, Error::Read );
79047910 }
79057911
79067912 if (req.get_header_value (" Connection" ) == " close" ) {
@@ -7926,15 +7932,15 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
79267932 const auto &accept_header = req.get_header_value (" Accept" );
79277933 if (!detail::parse_accept_header (accept_header, req.accept_content_types )) {
79287934 res.status = StatusCode::BadRequest_400;
7929- return write_response (strm, close_connection, req, res);
7935+ return write_response (strm, close_connection, req, res, Error::Success );
79307936 }
79317937 }
79327938
79337939 if (req.has_header (" Range" )) {
79347940 const auto &range_header_value = req.get_header_value (" Range" );
79357941 if (!detail::parse_range_header (range_header_value, req.ranges )) {
79367942 res.status = StatusCode::RangeNotSatisfiable_416;
7937- return write_response (strm, close_connection, req, res);
7943+ return write_response (strm, close_connection, req, res, Error::Success );
79387944 }
79397945 }
79407946
@@ -7953,7 +7959,7 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
79537959 break ;
79547960 default :
79557961 connection_closed = true ;
7956- return write_response (strm, true , req, res);
7962+ return write_response (strm, true , req, res, Error::Success );
79577963 }
79587964 }
79597965
@@ -8014,7 +8020,7 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
80148020 res.content_length_ = 0 ;
80158021 res.content_provider_ = nullptr ;
80168022 res.status = StatusCode::NotFound_404;
8017- return write_response (strm, close_connection, req, res);
8023+ return write_response (strm, close_connection, req, res, Error::Success );
80188024 }
80198025
80208026 auto content_type = res.file_content_content_type_ ;
@@ -8036,14 +8042,20 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
80368042 res.content_length_ = 0 ;
80378043 res.content_provider_ = nullptr ;
80388044 res.status = StatusCode::RangeNotSatisfiable_416;
8039- return write_response (strm, close_connection, req, res);
8045+ return write_response (strm, close_connection, req, res, Error::Success );
80408046 }
80418047
8042- return write_response_with_content (strm, close_connection, req, res);
8048+ return write_response_with_content (strm, close_connection, req, res,
8049+ Error::Success);
80438050 } else {
8044- if (res.status == -1 ) { res.status = StatusCode::NotFound_404; }
8045-
8046- return write_response (strm, close_connection, req, res);
8051+ if (res.status == -1 ) {
8052+ res.status = StatusCode::NotFound_404;
8053+ return write_response (strm, close_connection, req, res, Error::Success);
8054+ } else {
8055+ // Status was set by routing (e.g., read error), preserve it and log as
8056+ // read error
8057+ return write_response (strm, close_connection, req, res, Error::Read);
8058+ }
80478059 }
80488060}
80498061
0 commit comments