Skip to content

Commit 7476be7

Browse files
committed
Fix http2 content-length header check (#12747)
Fix issue where in HTTP2 response defined to have no payload like HEAD or 304 reponse to conditional GET were failing with 502 status when having non-zero Content-Length header. According to the RFC they may have Content-length representing the size the payload would have in the case of a 200 regular GET response. See https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.6
1 parent 68e4bd3 commit 7476be7

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

include/proxy/http2/Http2Stream.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "proxy/http2/Http2DependencyTree.h"
3232
#include "tscore/History.h"
3333
#include "proxy/Milestones.h"
34+
#include "proxy/http/HttpSM.h"
3435

3536
class Http2Stream;
3637
class Http2ConnectionState;
@@ -390,11 +391,22 @@ inline bool
390391
Http2Stream::payload_length_is_valid() const
391392
{
392393
uint32_t content_length = _receive_header.get_content_length();
393-
if (content_length != 0 && content_length != data_length) {
394+
HTTPHdr *server_request = &this->get_sm()->t_state.hdr_info.server_request;
395+
uint64_t mask = (MIME_PRESENCE_IF_UNMODIFIED_SINCE | MIME_PRESENCE_IF_MODIFIED_SINCE | MIME_PRESENCE_IF_RANGE |
396+
MIME_PRESENCE_IF_MATCH | MIME_PRESENCE_IF_NONE_MATCH);
397+
398+
// Skip Content-Length check on [RFC 7230] 3.3.2 conditions
399+
bool is_payload_precluded =
400+
this->is_outbound_connection() && (server_request->method_get_wksidx() == HTTP_WKSIDX_HEAD ||
401+
(server_request->method_get_wksidx() == HTTP_WKSIDX_GET && server_request->presence(mask) &&
402+
_receive_header.status_get() == HTTPStatus::NOT_MODIFIED));
403+
404+
if (content_length != 0 && !is_payload_precluded && content_length != data_length) {
394405
Warning("Bad payload length content_length=%d data_legnth=%d session_id=%" PRId64, content_length,
395406
static_cast<int>(data_length), _proxy_ssn->connection_id());
407+
return false;
396408
}
397-
return content_length == 0 || content_length == data_length;
409+
return true;
398410
}
399411

400412
inline bool

0 commit comments

Comments
 (0)