@@ -961,7 +961,7 @@ class Server {
961961 bool parse_request_line (const char *s, Request &req) const ;
962962 void apply_ranges (const Request &req, Response &res,
963963 std::string &content_type, std::string &boundary) const ;
964- bool write_response (Stream &strm, bool close_connection, const Request &req,
964+ bool write_response (Stream &strm, bool close_connection, Request &req,
965965 Response &res);
966966 bool write_response_with_content (Stream &strm, bool close_connection,
967967 const Request &req, Response &res);
@@ -4728,21 +4728,21 @@ serialize_multipart_formdata(const MultipartFormDataItems &items,
47284728 return body;
47294729}
47304730
4731- inline bool normalize_ranges (Request &req, Response &res) {
4732- ssize_t contant_len = static_cast <ssize_t >(
4733- res.content_length_ ? res.content_length_ : res.body .size ());
4731+ inline bool range_error (Request &req, Response &res) {
4732+ if (!req.ranges .empty () && 200 <= res.status && res.status < 300 ) {
4733+ ssize_t contant_len = static_cast <ssize_t >(
4734+ res.content_length_ ? res.content_length_ : res.body .size ());
47344735
4735- ssize_t prev_first_pos = -1 ;
4736- ssize_t prev_last_pos = -1 ;
4737- size_t overwrapping_count = 0 ;
4736+ ssize_t prev_first_pos = -1 ;
4737+ ssize_t prev_last_pos = -1 ;
4738+ size_t overwrapping_count = 0 ;
47384739
4739- if (!req.ranges .empty ()) {
47404740 // NOTE: The following Range check is based on '14.2. Range' in RFC 9110
47414741 // 'HTTP Semantics' to avoid potential denial-of-service attacks.
47424742 // https://www.rfc-editor.org/rfc/rfc9110#section-14.2
47434743
47444744 // Too many ranges
4745- if (req.ranges .size () > CPPHTTPLIB_RANGE_MAX_COUNT) { return false ; }
4745+ if (req.ranges .size () > CPPHTTPLIB_RANGE_MAX_COUNT) { return true ; }
47464746
47474747 for (auto &r : req.ranges ) {
47484748 auto &first_pos = r.first ;
@@ -4763,24 +4763,24 @@ inline bool normalize_ranges(Request &req, Response &res) {
47634763 // Range must be within content length
47644764 if (!(0 <= first_pos && first_pos <= last_pos &&
47654765 last_pos <= contant_len - 1 )) {
4766- return false ;
4766+ return true ;
47674767 }
47684768
47694769 // Ranges must be in ascending order
4770- if (first_pos <= prev_first_pos) { return false ; }
4770+ if (first_pos <= prev_first_pos) { return true ; }
47714771
47724772 // Request must not have more than two overlapping ranges
47734773 if (first_pos <= prev_last_pos) {
47744774 overwrapping_count++;
4775- if (overwrapping_count > 2 ) { return false ; }
4775+ if (overwrapping_count > 2 ) { return true ; }
47764776 }
47774777
47784778 prev_first_pos = (std::max)(prev_first_pos, first_pos);
47794779 prev_last_pos = (std::max)(prev_last_pos, last_pos);
47804780 }
47814781 }
47824782
4783- return true ;
4783+ return false ;
47844784}
47854785
47864786inline std::pair<size_t , size_t >
@@ -5987,7 +5987,10 @@ inline bool Server::parse_request_line(const char *s, Request &req) const {
59875987}
59885988
59895989inline bool Server::write_response (Stream &strm, bool close_connection,
5990- const Request &req, Response &res) {
5990+ Request &req, Response &res) {
5991+ // NOTE: `req.ranges` should be empty, otherwise it will be applied
5992+ // incorrectly to the error content.
5993+ req.ranges .clear ();
59915994 return write_response_core (strm, close_connection, req, res, false );
59925995}
59935996
@@ -6694,7 +6697,7 @@ Server::process_request(Stream &strm, bool close_connection,
66946697 }
66956698 }
66966699
6697- // Rounting
6700+ // Routing
66986701 auto routed = false ;
66996702#ifdef CPPHTTPLIB_NO_EXCEPTIONS
67006703 routed = routing (req, res, strm);
@@ -6731,21 +6734,23 @@ Server::process_request(Stream &strm, bool close_connection,
67316734 }
67326735#endif
67336736 if (routed) {
6734- if (detail::normalize_ranges (req, res)) {
6735- if (res.status == -1 ) {
6736- res.status = req.ranges .empty () ? StatusCode::OK_200
6737- : StatusCode::PartialContent_206;
6738- }
6739- return write_response_with_content (strm, close_connection, req, res);
6740- } else {
6737+ if (res.status == -1 ) {
6738+ res.status = req.ranges .empty () ? StatusCode::OK_200
6739+ : StatusCode::PartialContent_206;
6740+ }
6741+
6742+ if (detail::range_error (req, res)) {
67416743 res.body .clear ();
67426744 res.content_length_ = 0 ;
67436745 res.content_provider_ = nullptr ;
67446746 res.status = StatusCode::RangeNotSatisfiable_416;
67456747 return write_response (strm, close_connection, req, res);
67466748 }
6749+
6750+ return write_response_with_content (strm, close_connection, req, res);
67476751 } else {
67486752 if (res.status == -1 ) { res.status = StatusCode::NotFound_404; }
6753+
67496754 return write_response (strm, close_connection, req, res);
67506755 }
67516756}
0 commit comments