| 1087 | } |
| 1088 | |
| 1089 | AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb) |
| 1090 | { |
| 1091 | char *last_field = NULL; |
| 1092 | apr_size_t last_len = 0; |
| 1093 | apr_size_t alloc_len = 0; |
| 1094 | char *field; |
| 1095 | char *value; |
| 1096 | apr_size_t len; |
| 1097 | int fields_read = 0; |
| 1098 | char *tmp_field; |
| 1099 | core_server_config *conf = ap_get_core_module_config(r->server->module_config); |
| 1100 | int strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE); |
| 1101 | |
| 1102 | /* |
| 1103 | * Read header lines until we get the empty separator line, a read error, |
| 1104 | * the connection closes (EOF), reach the server limit, or we timeout. |
| 1105 | */ |
| 1106 | while(1) { |
| 1107 | apr_status_t rv; |
| 1108 | |
| 1109 | field = NULL; |
| 1110 | rv = ap_rgetline(&field, r->server->limit_req_fieldsize + 2, |
| 1111 | &len, r, strict ? AP_GETLINE_CRLF : 0, bb); |
| 1112 | |
| 1113 | if (rv != APR_SUCCESS) { |
| 1114 | if (APR_STATUS_IS_TIMEUP(rv)) { |
| 1115 | r->status = HTTP_REQUEST_TIME_OUT; |
| 1116 | } |
| 1117 | else { |
| 1118 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, |
| 1119 | "Failed to read request header line %s", field); |
| 1120 | r->status = HTTP_BAD_REQUEST; |
| 1121 | } |
| 1122 | |
| 1123 | /* ap_rgetline returns APR_ENOSPC if it fills up the buffer before |
| 1124 | * finding the end-of-line. This is only going to happen if it |
| 1125 | * exceeds the configured limit for a field size. |
| 1126 | */ |
| 1127 | if (rv == APR_ENOSPC) { |
| 1128 | apr_table_setn(r->notes, "error-notes", |
| 1129 | "Size of a request header field " |
| 1130 | "exceeds server limit."); |
| 1131 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00561) |
| 1132 | "Request header exceeds LimitRequestFieldSize%s" |
| 1133 | "%.*s", |
| 1134 | (field && *field) ? ": " : "", |
| 1135 | (field) ? field_name_len(field) : 0, |
| 1136 | (field) ? field : ""); |
| 1137 | } |
| 1138 | return; |
| 1139 | } |
| 1140 | |
| 1141 | /* For all header values, and all obs-fold lines, the presence of |
| 1142 | * additional whitespace is a no-op, so collapse trailing whitespace |
| 1143 | * to save buffer allocation and optimize copy operations. |
| 1144 | * Do not remove the last single whitespace under any condition. |
| 1145 | */ |
| 1146 | while (len > 1 && (field[len-1] == '\t' || field[len-1] == ' ')) { |
no test coverage detected