MCPcopy Create free account
hub / github.com/apache/trafficserver / validate_hdr_content_length

Function validate_hdr_content_length

src/proxy/hdrs/HTTP.cc:1245–1303  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1243}
1244
1245ParseResult
1246validate_hdr_content_length(HdrHeap *heap, HTTPHdrImpl *hh)
1247{
1248 MIMEField *content_length_field = mime_hdr_field_find(hh->m_fields_impl, MIME_FIELD_CONTENT_LENGTH, MIME_LEN_CONTENT_LENGTH);
1249
1250 if (content_length_field) {
1251 // RFC 7230 section 3.3.3:
1252 // If a message is received with both a Transfer-Encoding and a
1253 // Content-Length header field, the Transfer-Encoding overrides
1254 // the Content-Length
1255 if (mime_hdr_field_find(hh->m_fields_impl, MIME_FIELD_TRANSFER_ENCODING, MIME_LEN_TRANSFER_ENCODING) != nullptr) {
1256 // Delete all Content-Length headers
1257 Dbg(dbg_ctl_http, "Transfer-Encoding header and Content-Length headers the request, removing all Content-Length headers");
1258 mime_hdr_field_delete(heap, hh->m_fields_impl, content_length_field, true);
1259 return PARSE_RESULT_DONE;
1260 }
1261
1262 // RFC 7230 section 3.3.3:
1263 // If a message is received without Transfer-Encoding and with
1264 // either multiple Content-Length header fields having differing
1265 // field-values or a single Content-Length header field having an
1266 // invalid value, then the message framing is invalid and the
1267 // recipient MUST treat it as an unrecoverable error. If this is a
1268 // request message, the server MUST respond with a 400 (Bad Request)
1269 // status code and then close the connection
1270 std::string_view value = content_length_field->value_get();
1271
1272 // RFC 9110 section 8.6.
1273 // Content-Length = 1*DIGIT
1274 //
1275 if (value.empty()) {
1276 Dbg(dbg_ctl_http, "Content-Length headers don't match the ABNF, returning parse error");
1277 return PARSE_RESULT_ERROR;
1278 }
1279
1280 // If the content-length value contains a non-numeric value, the header is invalid
1281 if (std::find_if(value.cbegin(), value.cend(), [](std::string_view::value_type c) { return !std::isdigit(c); }) !=
1282 value.cend()) {
1283 Dbg(dbg_ctl_http, "Content-Length value contains non-digit, returning parse error");
1284 return PARSE_RESULT_ERROR;
1285 }
1286
1287 while (content_length_field->has_dups()) {
1288 std::string_view value_dup = content_length_field->m_next_dup->value_get();
1289
1290 if ((value.length() != value_dup.length()) || value.compare(value_dup) != 0) {
1291 // Values are different, parse error
1292 Dbg(dbg_ctl_http, "Content-Length headers don't match, returning parse error");
1293 return PARSE_RESULT_ERROR;
1294 } else {
1295 // Delete the duplicate since it has the same value
1296 Dbg(dbg_ctl_http, "Deleting duplicate Content-Length header");
1297 mime_hdr_field_delete(heap, hh->m_fields_impl, content_length_field->m_next_dup, false);
1298 }
1299 }
1300 }
1301
1302 return PARSE_RESULT_DONE;

Callers 2

http_parser_parse_reqFunction · 0.85
http_parser_parse_respFunction · 0.85

Calls 7

mime_hdr_field_findFunction · 0.85
mime_hdr_field_deleteFunction · 0.85
has_dupsMethod · 0.80
value_getMethod · 0.45
emptyMethod · 0.45
lengthMethod · 0.45
compareMethod · 0.45

Tested by

no test coverage detected