On 07/29/2016 07:37 PM, [email protected] wrote:
> Author: wrowe
> Date: Fri Jul 29 17:37:41 2016
> New Revision: 1754556
>
> URL: http://svn.apache.org/viewvc?rev=1754556&view=rev
> Log:
> Introduce ap_scan_http_token / ap_scan_http_field_content for a much
> more efficient pass through the header text; rather than reparsing
> the strings over and over under the HTTP_CONFORMANCE_STRICT fules.
>
> Improve logic and legibility by eliminating multiple repetitive tests
> of the STRICT flag, and simply reorder 'classic' behavior first and
> this new parser second to simplify the diff. Because of the whitespace
> change (which I had wished to dodge), reading this --ignore-all-space
> is a whole lot easier. Particularly against 2.4.x branch, which is now
> identical in the 'classic' logic flow. Both of which I'll share with dev@
>
>
> Modified:
> httpd/httpd/trunk/server/protocol.c
>
> Modified: httpd/httpd/trunk/server/protocol.c
> URL:
> http://svn.apache.org/viewvc/httpd/httpd/trunk/server/protocol.c?rev=1754556&r1=1754555&r2=1754556&view=diff
> ==============================================================================
> --- httpd/httpd/trunk/server/protocol.c (original)
> +++ httpd/httpd/trunk/server/protocol.c Fri Jul 29 17:37:41 2016
> @@ -900,71 +900,106 @@ AP_DECLARE(void) ap_get_mime_headers_cor
> return;
> }
>
> - if (!(value = strchr(last_field, ':'))) { /* Find ':' or
> */
> - r->status = HTTP_BAD_REQUEST; /* abort bad request
> */
> - apr_table_setn(r->notes, "error-notes",
> - apr_psprintf(r->pool,
> - "Request header field is "
> - "missing ':' separator.<br
> />\n"
> - "<pre>\n%.*s</pre>\n",
> - (int)LOG_NAME_MAX_LEN,
> - ap_escape_html(r->pool,
> - last_field)));
> - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
> APLOGNO(00564)
> - "Request header field is missing ':' "
> - "separator: %.*s", (int)LOG_NAME_MAX_LEN,
> - last_field);
> - return;
> - }
> + if (!(conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT)) {
> + {
> + /* Not Strict, using the legacy parser */
> +
> + if (!(value = strchr(last_field, ':'))) { /* Find ':' or
> */
> + r->status = HTTP_BAD_REQUEST; /* abort bad request
> */
> + apr_table_setn(r->notes, "error-notes",
> + apr_psprintf(r->pool,
> + "Request header field is "
> + "missing ':' separator.<br />\n"
> + "<pre>\n%.*s</pre>\n",
> + (int)LOG_NAME_MAX_LEN,
> + ap_escape_html(r->pool,
> + last_field)));
> + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
> APLOGNO(00564)
> + "Request header field is missing ':' "
> + "separator: %.*s",
> (int)LOG_NAME_MAX_LEN,
> + last_field);
> + return;
> + }
>
> - tmp_field = value - 1; /* last character of field-name */
> + tmp_field = value - 1; /* last character of field-name */
>
> - *value++ = '\0'; /* NUL-terminate at colon */
> + *value++ = '\0'; /* NUL-terminate at colon */
>
> - while (*value == ' ' || *value == '\t') {
> - ++value; /* Skip to start of value */
> - }
> + while (*value == ' ' || *value == '\t') {
> + ++value; /* Skip to start of value */
> + }
>
> - /* Strip LWS after field-name: */
> - while (tmp_field > last_field
> - && (*tmp_field == ' ' || *tmp_field == '\t')) {
> - *tmp_field-- = '\0';
> - }
> + /* Strip LWS after field-name: */
> + while (tmp_field > last_field
> + && (*tmp_field == ' ' || *tmp_field == '\t')) {
> + *tmp_field-- = '\0';
> + }
>
> - /* Strip LWS after field-value: */
> - tmp_field = last_field + last_len - 1;
> - while (tmp_field > value
> - && (*tmp_field == ' ' || *tmp_field == '\t')) {
> - *tmp_field-- = '\0';
> + /* Strip LWS after field-value: */
> + tmp_field = last_field + last_len - 1;
> + while (tmp_field > value
> + && (*tmp_field == ' ' || *tmp_field == '\t')) {
> + *tmp_field-- = '\0';
> + }
> }
> + else /* Using strict RFC7230 parsing */
> + {
> + /* Ensure valid token chars before ':' per RFC 7230
> 3.2.4 */
> + if (!(value = (char *)ap_scan_http_token(last_field))
Hm, how could ap_scan_http_token ever return NULL?
> + || *value != ':') {
> + r->status = HTTP_BAD_REQUEST;
> + apr_table_setn(r->notes, "error-notes",
> + apr_psprintf(r->pool,
> + "Request header field name "
> + "is malformed.<br />\n"
> + "<pre>\n%.*s</pre>\n",
> + (int)LOG_NAME_MAX_LEN,
> + ap_escape_html(r->pool,
> last_field)));
> + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
> APLOGNO(02426)
> + "Request header field name is
> malformed: "
> + "%.*s", (int)LOG_NAME_MAX_LEN,
> last_field);
> + return;
> + }
Regards
RĂ¼diger