in source/h1_encoder.c [159:221]
static int s_scan_outgoing_trailer(const struct aws_http_headers *headers, size_t *out_size) {
const size_t num_headers = aws_http_headers_count(headers);
size_t total = 0;
for (size_t i = 0; i < num_headers; i++) {
struct aws_http_header header;
aws_http_headers_get_index(headers, i, &header);
/* Validate header field-name (RFC-7230 3.2): field-name = token */
if (!aws_strutil_is_http_token(header.name)) {
AWS_LOGF_ERROR(AWS_LS_HTTP_STREAM, "id=static: Header name is invalid");
return aws_raise_error(AWS_ERROR_HTTP_INVALID_HEADER_NAME);
}
/* Validate header field-value.
* The value itself isn't supposed to have whitespace on either side,
* but we'll trim it off before validation so we don't start needlessly
* failing requests that used to work before we added validation.
* This should be OK because field-value can be sent with any amount
* of whitespace around it, which the other side will just ignore (RFC-7230 3.2):
* header-field = field-name ":" OWS field-value OWS */
struct aws_byte_cursor field_value = aws_strutil_trim_http_whitespace(header.value);
if (!aws_strutil_is_http_field_value(field_value)) {
AWS_LOGF_ERROR(
AWS_LS_HTTP_STREAM,
"id=static: Header '" PRInSTR "' has invalid value",
AWS_BYTE_CURSOR_PRI(header.name));
return aws_raise_error(AWS_ERROR_HTTP_INVALID_HEADER_VALUE);
}
enum aws_http_header_name name_enum = aws_http_str_to_header_name(header.name);
if (name_enum == AWS_HTTP_HEADER_TRANSFER_ENCODING || name_enum == AWS_HTTP_HEADER_CONTENT_LENGTH ||
name_enum == AWS_HTTP_HEADER_HOST || name_enum == AWS_HTTP_HEADER_EXPECT ||
name_enum == AWS_HTTP_HEADER_CACHE_CONTROL || name_enum == AWS_HTTP_HEADER_MAX_FORWARDS ||
name_enum == AWS_HTTP_HEADER_PRAGMA || name_enum == AWS_HTTP_HEADER_RANGE ||
name_enum == AWS_HTTP_HEADER_TE || name_enum == AWS_HTTP_HEADER_CONTENT_ENCODING ||
name_enum == AWS_HTTP_HEADER_CONTENT_TYPE || name_enum == AWS_HTTP_HEADER_CONTENT_RANGE ||
name_enum == AWS_HTTP_HEADER_TRAILER || name_enum == AWS_HTTP_HEADER_WWW_AUTHENTICATE ||
name_enum == AWS_HTTP_HEADER_AUTHORIZATION || name_enum == AWS_HTTP_HEADER_PROXY_AUTHENTICATE ||
name_enum == AWS_HTTP_HEADER_PROXY_AUTHORIZATION || name_enum == AWS_HTTP_HEADER_SET_COOKIE ||
name_enum == AWS_HTTP_HEADER_COOKIE || name_enum == AWS_HTTP_HEADER_AGE ||
name_enum == AWS_HTTP_HEADER_EXPIRES || name_enum == AWS_HTTP_HEADER_DATE ||
name_enum == AWS_HTTP_HEADER_LOCATION || name_enum == AWS_HTTP_HEADER_RETRY_AFTER ||
name_enum == AWS_HTTP_HEADER_VARY || name_enum == AWS_HTTP_HEADER_WARNING) {
AWS_LOGF_ERROR(
AWS_LS_HTTP_STREAM,
"id=static: Trailing Header '" PRInSTR "' has invalid value",
AWS_BYTE_CURSOR_PRI(header.name));
return aws_raise_error(AWS_ERROR_HTTP_INVALID_HEADER_FIELD);
}
int err = 0;
err |= aws_add_size_checked(header.name.len, total, &total);
err |= aws_add_size_checked(header.value.len, total, &total);
err |= aws_add_size_checked(4, total, &total); /* ": " + "\r\n" */
if (err) {
return AWS_OP_ERR;
}
}
if (aws_add_size_checked(2, total, &total)) { /* "\r\n" */
return AWS_OP_ERR;
}
*out_size = total;
return AWS_OP_SUCCESS;
}