/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * http_protocol.c --- routines which directly communicate with the client.
 *
 * Code originally by Rob McCool; much redone by Robert S. Thau
 * and the Apache Software Foundation.
 */

#include "apr.h"
#include "apr_strings.h"
#include "apr_buckets.h"
#include "apr_lib.h"
#include "apr_signal.h"

#define APR_WANT_STDIO          /* for sscanf */
#define APR_WANT_STRFUNC
#define APR_WANT_MEMFUNC
#include "apr_want.h"

#include "util_filter.h"
#include "ap_config.h"
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_protocol.h"
#include "http_main.h"
#include "http_request.h"
#include "http_vhost.h"
#include "http_log.h"           /* For errors detected in basic auth common
                                 * support code... */
#include "apr_date.h"           /* For apr_date_parse_http and APR_DATE_BAD */
#include "util_charset.h"
#include "util_ebcdic.h"
#include "util_time.h"
#include "ap_mpm.h"

#include "mod_core.h"

#if APR_HAVE_STDARG_H
#include <stdarg.h>
#endif
#if APR_HAVE_UNISTD_H
#include <unistd.h>
#endif

APLOG_USE_MODULE(http);

/* New Apache routine to map status codes into array indices
 *  e.g.  100 -> 0,  101 -> 1,  200 -> 2 ...
 * The number of status lines must equal the value of
 * RESPONSE_CODES (httpd.h) and must be listed in order.
 * No gaps are allowed between X00 and the largest Xnn
 * for any X (see ap_index_of_response).
 * When adding a new code here, add a define to httpd.h
 * as well.
 */

static const char * const status_lines[RESPONSE_CODES] =
{
    "100 Continue",
    "101 Switching Protocols",
    "102 Processing",
    "103 Early Hints",
#define LEVEL_200  4
    "200 OK",
    "201 Created",
    "202 Accepted",
    "203 Non-Authoritative Information",
    "204 No Content",
    "205 Reset Content",
    "206 Partial Content",
    "207 Multi-Status",
    "208 Already Reported",
    NULL, /* 209 */
    NULL, /* 210 */
    NULL, /* 211 */
    NULL, /* 212 */
    NULL, /* 213 */
    NULL, /* 214 */
    NULL, /* 215 */
    NULL, /* 216 */
    NULL, /* 217 */
    NULL, /* 218 */
    NULL, /* 219 */
    NULL, /* 220 */
    NULL, /* 221 */
    NULL, /* 222 */
    NULL, /* 223 */
    NULL, /* 224 */
    NULL, /* 225 */
    "226 IM Used",
#define LEVEL_300 31
    "300 Multiple Choices",
    "301 Moved Permanently",
    "302 Found",
    "303 See Other",
    "304 Not Modified",
    "305 Use Proxy",
    NULL, /* 306 */
    "307 Temporary Redirect",
    "308 Permanent Redirect",
#define LEVEL_400 40
    "400 Bad Request",
    "401 Unauthorized",
    "402 Payment Required",
    "403 Forbidden",
    "404 Not Found",
    "405 Method Not Allowed",
    "406 Not Acceptable",
    "407 Proxy Authentication Required",
    "408 Request Timeout",
    "409 Conflict",
    "410 Gone",
    "411 Length Required",
    "412 Precondition Failed",
    "413 Request Entity Too Large",
    "414 Request-URI Too Long",
    "415 Unsupported Media Type",
    "416 Requested Range Not Satisfiable",
    "417 Expectation Failed",
    "418 I'm A Teapot",
    NULL, /* 419 */
    NULL, /* 420 */
    "421 Misdirected Request",
    "422 Unprocessable Entity",
    "423 Locked",
    "424 Failed Dependency",
    "425 Too Early",
    "426 Upgrade Required",
    NULL, /* 427 */
    "428 Precondition Required",
    "429 Too Many Requests",
    NULL, /* 430 */
    "431 Request Header Fields Too Large",
    NULL, /* 432 */
    NULL, /* 433 */
    NULL, /* 434 */
    NULL, /* 435 */
    NULL, /* 436 */
    NULL, /* 437 */
    NULL, /* 438 */
    NULL, /* 439 */
    NULL, /* 440 */
    NULL, /* 441 */
    NULL, /* 442 */
    NULL, /* 443 */
    NULL, /* 444 */
    NULL, /* 445 */
    NULL, /* 446 */
    NULL, /* 447 */
    NULL, /* 448 */
    NULL, /* 449 */
    NULL, /* 450 */
    "451 Unavailable For Legal Reasons",
#define LEVEL_500 92
    "500 Internal Server Error",
    "501 Not Implemented",
    "502 Bad Gateway",
    "503 Service Unavailable",
    "504 Gateway Timeout",
    "505 HTTP Version Not Supported",
    "506 Variant Also Negotiates",
    "507 Insufficient Storage",
    "508 Loop Detected",
    NULL, /* 509 */
    "510 Not Extended",
    "511 Network Authentication Required"
};

APR_HOOK_STRUCT(
    APR_HOOK_LINK(insert_error_filter)
)

AP_IMPLEMENT_HOOK_VOID(insert_error_filter, (request_rec *r), (r))

/* The index of the first bit field that is used to index into a limit
 * bitmask. M_INVALID + 1 to METHOD_NUMBER_LAST.
 */
#define METHOD_NUMBER_FIRST (M_INVALID + 1)

/* The max method number. Method numbers are used to shift bitmasks,
 * so this cannot exceed 63, and all bits high is equal to -1, which is a
 * special flag, so the last bit used has index 62.
 */
#define METHOD_NUMBER_LAST  62

static int is_mpm_running(void)
{
    int mpm_state = 0;

    if (ap_mpm_query(AP_MPMQ_MPM_STATE, &mpm_state)) {
      return 0;
    }

    if (mpm_state == AP_MPMQ_STOPPING) {
      return 0;
    }

    return 1;
}

int ap_h1_set_keepalive(request_rec *r, ap_bucket_response *resp)
{
    int ka_sent, left = 0, wimpy;
    const char *conn;

    if (r->proto_num >= HTTP_VERSION(2,0)) {
        goto update_keepalives;
    }

    ka_sent = 0;
    left = r->server->keep_alive_max - r->connection->keepalives;
    wimpy = ap_find_token(r->pool,
                          apr_table_get(resp->headers, "Connection"),
                          "close");
    conn = apr_table_get(r->headers_in, "Connection");

    /* The following convoluted conditional determines whether or not
     * the current connection should remain persistent after this response
     * (a.k.a. HTTP Keep-Alive) and whether or not the output message
     * body should use the HTTP/1.1 chunked transfer-coding.  In English,
     *
     *   IF  we have not marked this connection as errored;
     *   and the client isn't expecting 100-continue (PR47087 - more
     *       input here could be the client continuing when we're
     *       closing the request).
     *   and the response body has a defined length due to the status code
     *       being 304 or 204, the request method being HEAD, already
     *       having defined Content-Length or Transfer-Encoding: chunked, or
     *       the request version being HTTP/1.1 and thus capable of being set
     *       as chunked [we know the (r->chunked = 1) side-effect is ugly];
     *   and the server configuration enables keep-alive;
     *   and the server configuration has a reasonable inter-request timeout;
     *   and there is no maximum # requests or the max hasn't been reached;
     *   and the response status does not require a close;
     *   and the response generator has not already indicated close;
     *   and the client did not request non-persistence (Connection: close);
     *   and    we haven't been configured to ignore the buggy twit
     *       or they're a buggy twit coming through a HTTP/1.1 proxy
     *   and    the client is requesting an HTTP/1.0-style keep-alive
     *       or the client claims to be HTTP/1.1 compliant (perhaps a proxy);
     *   and this MPM process is not already exiting
     *   THEN we can be persistent, which requires more headers be output.
     *
     * Note that the condition evaluation order is extremely important.
     */
    if ((r->connection->keepalive != AP_CONN_CLOSE)
        && !r->expecting_100
        && (r->header_only
            || AP_STATUS_IS_HEADER_ONLY(resp->status)
            || apr_table_get(resp->headers, "Content-Length")
            || ap_is_chunked(r->pool,
                             apr_table_get(resp->headers, "Transfer-Encoding"))
            || ((r->proto_num >= HTTP_VERSION(1,1))
                && (r->chunked = 1))) /* THIS CODE IS CORRECT, see above. */
        && r->server->keep_alive
        && (r->server->keep_alive_timeout > 0)
        && ((r->server->keep_alive_max == 0)
            || (left > 0))
        && !ap_status_drops_connection(resp->status)
        && !wimpy
        && !ap_find_token(r->pool, conn, "close")
        && (!apr_table_get(r->subprocess_env, "nokeepalive")
            || apr_table_get(r->headers_in, "Via"))
        && ((ka_sent = ap_find_token(r->pool, conn, "keep-alive"))
            || (r->proto_num >= HTTP_VERSION(1,1)))
        && is_mpm_running()) {

        r->connection->keepalive = AP_CONN_KEEPALIVE;
        r->connection->keepalives++;

        /* If they sent a Keep-Alive token, send one back */
        if (ka_sent) {
            if (r->server->keep_alive_max) {
                apr_table_setn(resp->headers, "Keep-Alive",
                       apr_psprintf(r->pool, "timeout=%d, max=%d",
                            (int)apr_time_sec(r->server->keep_alive_timeout),
                            left));
            }
            else {
                apr_table_setn(resp->headers, "Keep-Alive",
                      apr_psprintf(r->pool, "timeout=%d",
                            (int)apr_time_sec(r->server->keep_alive_timeout)));
            }
            apr_table_mergen(resp->headers, "Connection", "Keep-Alive");
        }

        return 1;
    }

    /* Otherwise, we need to indicate that we will be closing this
     * connection immediately after the current response.
     *
     * We only really need to send "close" to HTTP/1.1 clients, but we
     * always send it anyway, because a broken proxy may identify itself
     * as HTTP/1.0, but pass our request along with our HTTP/1.1 tag
     * to a HTTP/1.1 client. Better safe than sorry.
     */
    if (!wimpy) {
        apr_table_mergen(resp->headers, "Connection", "close");
    }

update_keepalives:
    /*
     * If we had previously been a keepalive connection and this
     * is the last one, then bump up the number of keepalives
     * we've had
     */
    if ((r->connection->keepalive != AP_CONN_CLOSE)
        && r->server->keep_alive_max
        && !left) {
        r->connection->keepalives++;
    }
    r->connection->keepalive = AP_CONN_CLOSE;

    return 0;
}

AP_DECLARE(int) ap_set_keepalive(request_rec *r)
{
    ap_bucket_response resp;

    memset(&resp, 0, sizeof(resp));
    resp.status = r->status;
    resp.headers = r->headers_out;
    resp.notes = r->notes;
    return ap_h1_set_keepalive(r, &resp);
}

AP_DECLARE(ap_condition_e) ap_condition_if_match(request_rec *r,
        apr_table_t *headers)
{
    const char *if_match, *etag;

    /* A server MUST use the strong comparison function (see section 13.3.3)
     * to compare the entity tags in If-Match.
     */
    if ((if_match = apr_table_get(r->headers_in, "If-Match")) != NULL) {
        if (if_match[0] == '*'
                || ((etag = apr_table_get(headers, "ETag")) != NULL
                        && ap_find_etag_strong(r->pool, if_match, etag))) {
            return AP_CONDITION_STRONG;
        }
        else {
            return AP_CONDITION_NOMATCH;
        }
    }

    return AP_CONDITION_NONE;
}

AP_DECLARE(ap_condition_e) ap_condition_if_unmodified_since(request_rec *r,
        apr_table_t *headers)
{
    const char *if_unmodified;

    if_unmodified = apr_table_get(r->headers_in, "If-Unmodified-Since");
    if (if_unmodified) {
        apr_int64_t mtime, reqtime;

        apr_time_t ius = apr_time_sec(apr_date_parse_http(if_unmodified));

        /* All of our comparisons must be in seconds, because that's the
         * highest time resolution the HTTP specification allows.
         */
        mtime = apr_time_sec(apr_date_parse_http(
                        apr_table_get(headers, "Last-Modified")));
        if (mtime == APR_DATE_BAD) {
            mtime = apr_time_sec(r->mtime ? r->mtime : apr_time_now());
        }

        reqtime = apr_time_sec(apr_date_parse_http(
                        apr_table_get(headers, "Date")));
        if (!reqtime) {
            reqtime = apr_time_sec(r->request_time);
        }

        if ((ius != APR_DATE_BAD) && (mtime > ius)) {
            if (reqtime < mtime + 60) {
                if (apr_table_get(r->headers_in, "Range")) {
                    /* weak matches not allowed with Range requests */
                    return AP_CONDITION_NOMATCH;
                }
                else {
                    return AP_CONDITION_WEAK;
                }
            }
            else {
                return AP_CONDITION_STRONG;
            }
        }
        else {
            return AP_CONDITION_NOMATCH;
        }
    }

    return AP_CONDITION_NONE;
}

AP_DECLARE(ap_condition_e) ap_condition_if_none_match(request_rec *r,
        apr_table_t *headers)
{
    const char *if_nonematch, *etag;

    if_nonematch = apr_table_get(r->headers_in, "If-None-Match");
    if (if_nonematch != NULL) {

        if (if_nonematch[0] == '*') {
            return AP_CONDITION_STRONG;
        }

        /* See section 13.3.3 for rules on how to determine if two entities tags
         * match. The weak comparison function can only be used with GET or HEAD
         * requests.
         */
        if (r->method_number == M_GET) {
            if ((etag = apr_table_get(headers, "ETag")) != NULL) {
                if (apr_table_get(r->headers_in, "Range")) {
                    if (ap_find_etag_strong(r->pool, if_nonematch, etag)) {
                        return AP_CONDITION_STRONG;
                    }
                }
                else {
                    if (ap_find_etag_weak(r->pool, if_nonematch, etag)) {
                        return AP_CONDITION_WEAK;
                    }
                }
            }
        }

        else if ((etag = apr_table_get(headers, "ETag")) != NULL
                && ap_find_etag_strong(r->pool, if_nonematch, etag)) {
            return AP_CONDITION_STRONG;
        }
        return AP_CONDITION_NOMATCH;
    }

    return AP_CONDITION_NONE;
}

AP_DECLARE(ap_condition_e) ap_condition_if_modified_since(request_rec *r,
        apr_table_t *headers)
{
    const char *if_modified_since;

    if ((if_modified_since = apr_table_get(r->headers_in, "If-Modified-Since"))
            != NULL) {
        apr_int64_t mtime;
        apr_int64_t ims, reqtime;

        /* All of our comparisons must be in seconds, because that's the
         * highest time resolution the HTTP specification allows.
         */

        mtime = apr_time_sec(apr_date_parse_http(
                        apr_table_get(headers, "Last-Modified")));
        if (mtime == APR_DATE_BAD) {
            mtime = apr_time_sec(r->mtime ? r->mtime : apr_time_now());
        }

        reqtime = apr_time_sec(apr_date_parse_http(
                        apr_table_get(headers, "Date")));
        if (!reqtime) {
            reqtime = apr_time_sec(r->request_time);
        }

        ims = apr_time_sec(apr_date_parse_http(if_modified_since));

        if (ims >= mtime && ims <= reqtime) {
            if (reqtime < mtime + 60) {
                if (apr_table_get(r->headers_in, "Range")) {
                    /* weak matches not allowed with Range requests */
                    return AP_CONDITION_NOMATCH;
                }
                else {
                    return AP_CONDITION_WEAK;
                }
            }
            else {
                return AP_CONDITION_STRONG;
            }
        }
        else {
            return AP_CONDITION_NOMATCH;
        }
    }

    return AP_CONDITION_NONE;
}

AP_DECLARE(ap_condition_e) ap_condition_if_range(request_rec *r,
        apr_table_t *headers)
{
    const char *if_range, *etag;

    if ((if_range = apr_table_get(r->headers_in, "If-Range"))
            && apr_table_get(r->headers_in, "Range")) {
        if (if_range[0] == '"') {

            if ((etag = apr_table_get(headers, "ETag"))
                    && !strcmp(if_range, etag)) {
                return AP_CONDITION_STRONG;
            }
            else {
                return AP_CONDITION_NOMATCH;
            }

        }
        else {
            apr_int64_t mtime;
            apr_int64_t rtime, reqtime;

            /* All of our comparisons must be in seconds, because that's the
             * highest time resolution the HTTP specification allows.
             */

            mtime = apr_time_sec(apr_date_parse_http(
                            apr_table_get(headers, "Last-Modified")));
            if (mtime == APR_DATE_BAD) {
                mtime = apr_time_sec(r->mtime ? r->mtime : apr_time_now());
            }

            reqtime = apr_time_sec(apr_date_parse_http(
                            apr_table_get(headers, "Date")));
            if (!reqtime) {
                reqtime = apr_time_sec(r->request_time);
            }

            rtime = apr_time_sec(apr_date_parse_http(if_range));

            if (rtime == mtime) {
                if (reqtime < mtime + 60) {
                    /* weak matches not allowed with Range requests */
                    return AP_CONDITION_NOMATCH;
                }
                else {
                    return AP_CONDITION_STRONG;
                }
            }
            else {
                return AP_CONDITION_NOMATCH;
            }
        }
    }

    return AP_CONDITION_NONE;
}

AP_DECLARE(int) ap_meets_conditions(request_rec *r)
{
    int not_modified = -1; /* unset by default */
    ap_condition_e cond;

    /* Check for conditional requests --- note that we only want to do
     * this if we are successful so far and we are not processing a
     * subrequest or an ErrorDocument.
     *
     * The order of the checks is important, since ETag checks are supposed
     * to be more accurate than checks relative to the modification time.
     * However, not all documents are guaranteed to *have* ETags, and some
     * might have Last-Modified values w/o ETags, so this gets a little
     * complicated.
     */

    if (!ap_is_HTTP_SUCCESS(r->status) || r->no_local_copy) {
        return OK;
    }

    /* If an If-Match request-header field was given
     * AND the field value is not "*" (meaning match anything)
     * AND if our strong ETag does not match any entity tag in that field,
     *     respond with a status of 412 (Precondition Failed).
     */
    cond = ap_condition_if_match(r, r->headers_out);
    if (AP_CONDITION_NOMATCH == cond) {
        return HTTP_PRECONDITION_FAILED;
    }

    /* Else if a valid If-Unmodified-Since request-header field was given
     * AND the requested resource has been modified since the time
     * specified in this field, then the server MUST
     *     respond with a status of 412 (Precondition Failed).
     */
    cond = ap_condition_if_unmodified_since(r, r->headers_out);
    if (AP_CONDITION_NOMATCH == cond) {
        not_modified = 0;
    }
    else if (cond >= AP_CONDITION_WEAK) {
        return HTTP_PRECONDITION_FAILED;
    }

    /* If an If-None-Match request-header field was given
     * AND the field value is "*" (meaning match anything)
     *     OR our ETag matches any of the entity tags in that field, fail.
     *
     * If the request method was GET or HEAD, failure means the server
     *    SHOULD respond with a 304 (Not Modified) response.
     * For all other request methods, failure means the server MUST
     *    respond with a status of 412 (Precondition Failed).
     *
     * GET or HEAD allow weak etag comparison, all other methods require
     * strong comparison.  We can only use weak if it's not a range request.
     */
    cond = ap_condition_if_none_match(r, r->headers_out);
    if (AP_CONDITION_NOMATCH == cond) {
        not_modified = 0;
    }
    else if (cond >= AP_CONDITION_WEAK) {
        if (r->method_number == M_GET) {
            if (not_modified) {
                not_modified = 1;
            }
        }
        else {
            return HTTP_PRECONDITION_FAILED;
        }
    }

    /* If a valid If-Modified-Since request-header field was given
     * AND it is a GET or HEAD request
     * AND the requested resource has not been modified since the time
     * specified in this field, then the server MUST
     *    respond with a status of 304 (Not Modified).
     * A date later than the server's current request time is invalid.
     */
    cond = ap_condition_if_modified_since(r, r->headers_out);
    if (AP_CONDITION_NOMATCH == cond) {
        not_modified = 0;
    }
    else if (cond >= AP_CONDITION_WEAK) {
        if (r->method_number == M_GET) {
            if (not_modified) {
                not_modified = 1;
            }
        }
    }

    /* If an If-Range and an Range header is present, we must return
     * 200 OK. The byterange filter will convert it to a range response.
     */
    cond = ap_condition_if_range(r, r->headers_out);
    if (cond > AP_CONDITION_NONE) {
        return OK;
    }

    if (not_modified == 1) {
        return HTTP_NOT_MODIFIED;
    }

    return OK;
}

/**
 * Singleton registry of additional methods. This maps new method names
 * such as "MYGET" to methnums, which are int offsets into bitmasks.
 *
 * This follows the same technique as standard M_GET, M_POST, etc. These
 * are dynamically assigned when modules are loaded and <Limit GET MYGET>
 * directives are processed.
 */
static apr_hash_t *methods_registry = NULL;
static int cur_method_number = METHOD_NUMBER_FIRST;

/* internal function to register one method/number pair */
static void register_one_method(apr_pool_t *p, const char *methname,
                                int methnum)
{
    int *pnum = apr_palloc(p, sizeof(*pnum));

    *pnum = methnum;
    apr_hash_set(methods_registry, methname, APR_HASH_KEY_STRING, pnum);
}

/* This internal function is used to clear the method registry
 * and reset the cur_method_number counter.
 */
static apr_status_t ap_method_registry_destroy(void *notused)
{
    methods_registry = NULL;
    cur_method_number = METHOD_NUMBER_FIRST;
    return APR_SUCCESS;
}

AP_DECLARE(void) ap_method_registry_init(apr_pool_t *p)
{
    methods_registry = apr_hash_make(p);
    apr_pool_cleanup_register(p, NULL,
                              ap_method_registry_destroy,
                              apr_pool_cleanup_null);

    /* put all the standard methods into the registry hash to ease the
     * mapping operations between name and number
     * HEAD is a special-instance of the GET method and shares the same ID
     */
    register_one_method(p, "GET", M_GET);
    register_one_method(p, "HEAD", M_GET);
    register_one_method(p, "PUT", M_PUT);
    register_one_method(p, "POST", M_POST);
    register_one_method(p, "DELETE", M_DELETE);
    register_one_method(p, "CONNECT", M_CONNECT);
    register_one_method(p, "OPTIONS", M_OPTIONS);
    register_one_method(p, "TRACE", M_TRACE);
    register_one_method(p, "PATCH", M_PATCH);
    register_one_method(p, "PROPFIND", M_PROPFIND);
    register_one_method(p, "PROPPATCH", M_PROPPATCH);
    register_one_method(p, "MKCOL", M_MKCOL);
    register_one_method(p, "COPY", M_COPY);
    register_one_method(p, "MOVE", M_MOVE);
    register_one_method(p, "LOCK", M_LOCK);
    register_one_method(p, "UNLOCK", M_UNLOCK);
    register_one_method(p, "VERSION-CONTROL", M_VERSION_CONTROL);
    register_one_method(p, "CHECKOUT", M_CHECKOUT);
    register_one_method(p, "UNCHECKOUT", M_UNCHECKOUT);
    register_one_method(p, "CHECKIN", M_CHECKIN);
    register_one_method(p, "UPDATE", M_UPDATE);
    register_one_method(p, "LABEL", M_LABEL);
    register_one_method(p, "REPORT", M_REPORT);
    register_one_method(p, "MKWORKSPACE", M_MKWORKSPACE);
    register_one_method(p, "MKACTIVITY", M_MKACTIVITY);
    register_one_method(p, "BASELINE-CONTROL", M_BASELINE_CONTROL);
    register_one_method(p, "MERGE", M_MERGE);
}

AP_DECLARE(int) ap_method_register(apr_pool_t *p, const char *methname)
{
    int *methnum;

    if (methname == NULL) {
        return M_INVALID;
    }

    /* Check if the method was previously registered.  If it was
     * return the associated method number.
     */
    methnum = (int *)apr_hash_get(methods_registry, methname,
                                  APR_HASH_KEY_STRING);
    if (methnum != NULL)
        return *methnum;

    if (cur_method_number > METHOD_NUMBER_LAST) {
        /* The method registry  has run out of dynamically
         * assignable method numbers. Log this and return M_INVALID.
         */
        ap_log_perror(APLOG_MARK, APLOG_ERR, 0, p, APLOGNO(01610)
                      "Maximum new request methods %d reached while "
                      "registering method %s.",
                      METHOD_NUMBER_LAST, methname);
        return M_INVALID;
    }

    register_one_method(p, methname, cur_method_number);
    return cur_method_number++;
}

/* Get the method number associated with the given string, assumed to
 * contain an HTTP method.  Returns M_INVALID if not recognized.
 *
 * This is the first step toward placing method names in a configurable
 * list.  Hopefully it (and other routines) can eventually be moved to
 * something like a mod_http_methods.c, complete with config stuff.
 */
AP_DECLARE(int) ap_method_number_of(const char *method)
{
    int len = strlen(method);

    /* check if the method has been dynamically registered */
    int *methnum = apr_hash_get(methods_registry, method, len);

    if (methnum != NULL) {
        return *methnum;
    }

    return M_INVALID;
}

/*
 * Turn a known method number into a name.
 */
AP_DECLARE(const char *) ap_method_name_of(apr_pool_t *p, int methnum)
{
    apr_hash_index_t *hi = apr_hash_first(p, methods_registry);

    /* scan through the hash table, looking for a value that matches
       the provided method number. */
    for (; hi; hi = apr_hash_next(hi)) {
        const void *key;
        void *val;

        apr_hash_this(hi, &key, NULL, &val);
        if (*(int *)val == methnum)
            return key;
    }

    /* it wasn't found in the hash */
    return NULL;
}

/* The index is found by its offset from the x00 code of each level.
 * Although this is fast, it will need to be replaced if some nutcase
 * decides to define a high-numbered code before the lower numbers.
 * If that sad event occurs, replace the code below with a linear search
 * from status_lines[shortcut[i]] to status_lines[shortcut[i+1]-1];
 * or use NULL to fill the gaps.
 */
static int index_of_response(int status)
{
    static int shortcut[6] = {0, LEVEL_200, LEVEL_300, LEVEL_400, LEVEL_500,
                                 RESPONSE_CODES};
    int i, pos;

    if (status < 100) {     /* Below 100 is illegal for HTTP status */
        return -1;
    }
    if (status > 999) {     /* Above 999 is also illegal for HTTP status */
        return -1;
    }

    for (i = 0; i < 5; i++) {
        status -= 100;
        if (status < 100) {
            pos = (status + shortcut[i]);
            if (pos < shortcut[i + 1] && status_lines[pos] != NULL) {
                return pos;
            }
            else {
                break;
            }
        }
    }
    return -2;              /* Status unknown (falls in gap) or above 600 */
}

AP_DECLARE(int) ap_index_of_response(int status)
{
    int index = index_of_response(status);
    return (index < 0) ? LEVEL_500 : index;
}

AP_DECLARE(const char *) ap_get_status_line_ex(apr_pool_t *p, int status)
{
    int index = index_of_response(status);
    if (index >= 0) {
        return status_lines[index];
    }
    else if (index == -2) {
        return apr_psprintf(p, "%i Status %i", status, status);
    }
    return status_lines[LEVEL_500];
}

AP_DECLARE(const char *) ap_get_status_line(int status)
{
    return status_lines[ap_index_of_response(status)];
}

/* Build the Allow field-value from the request handler method mask.
 */
static char *make_allow(request_rec *r)
{
    ap_method_mask_t mask;
    apr_array_header_t *allow = apr_array_make(r->pool, 10, sizeof(char *));
    apr_hash_index_t *hi = apr_hash_first(r->pool, methods_registry);
    /* For TRACE below */
    core_server_config *conf =
        ap_get_core_module_config(r->server->module_config);

    mask = r->allowed_methods->method_mask;

    for (; hi; hi = apr_hash_next(hi)) {
        const void *key;
        void *val;

        apr_hash_this(hi, &key, NULL, &val);
        if ((mask & (AP_METHOD_BIT << *(int *)val)) != 0) {
            APR_ARRAY_PUSH(allow, const char *) = key;
        }
    }

    /* TRACE is tested on a per-server basis */
    if (conf->trace_enable != AP_TRACE_DISABLE)
        *(const char **)apr_array_push(allow) = "TRACE";

    /* ### this is rather annoying. we should enforce registration of
       ### these methods */
    if ((mask & (AP_METHOD_BIT << M_INVALID))
        && (r->allowed_methods->method_list != NULL)
        && (r->allowed_methods->method_list->nelts != 0)) {
        apr_array_cat(allow, r->allowed_methods->method_list);
    }

    return apr_array_pstrcat(r->pool, allow, ',');
}

AP_DECLARE(int) ap_send_http_options(request_rec *r)
{
    if (r->assbackwards) {
        return DECLINED;
    }

    apr_table_setn(r->headers_out, "Allow", make_allow(r));

    /* the request finalization will send an EOS, which will flush all
     * the headers out (including the Allow header)
     */

    return OK;
}

AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct)
{
    if (!ct) {
        r->content_type = NULL;
    }
    else if (!r->content_type || strcmp(r->content_type, ct)) {
        r->content_type = ct;
        AP_REQUEST_SET_BNOTE(r, AP_REQUEST_TRUSTED_CT, 0);
    }
}
AP_DECLARE(void) ap_set_content_type_ex(request_rec *r, const char *ct, int trusted)
{
    ap_set_content_type(r, ct);
    AP_REQUEST_SET_BNOTE(r, AP_REQUEST_TRUSTED_CT, trusted ? AP_REQUEST_TRUSTED_CT : 0);
}

AP_DECLARE(void) ap_set_accept_ranges(request_rec *r)
{
    core_dir_config *d = ap_get_core_module_config(r->per_dir_config);
    apr_table_setn(r->headers_out, "Accept-Ranges",
                  (d->max_ranges == AP_MAXRANGES_NORANGES) ? "none"
                                                           : "bytes");
}
static const char *add_optional_notes(request_rec *r,
                                      const char *prefix,
                                      const char *key,
                                      const char *suffix)
{
    const char *notes, *result;

    if ((notes = apr_table_get(r->notes, key)) == NULL) {
        result = apr_pstrcat(r->pool, prefix, suffix, NULL);
    }
    else {
        result = apr_pstrcat(r->pool, prefix, notes, suffix, NULL);
    }

    return result;
}

/* construct and return the default error message for a given
 * HTTP defined error code
 */
static const char *get_canned_error_string(int status,
                                           request_rec *r,
                                           const char *location)
{
    apr_pool_t *p = r->pool;
    const char *error_notes, *h1, *s1;
    const char *method = r->method;
    if (r->subprocess_env && apr_table_get(r->subprocess_env, "REQUEST_METHOD"))
        method =  apr_table_get(r->subprocess_env, "REQUEST_METHOD");

    switch (status) {
    case HTTP_MOVED_PERMANENTLY:
    case HTTP_MOVED_TEMPORARILY:
    case HTTP_TEMPORARY_REDIRECT:
    case HTTP_PERMANENT_REDIRECT:
        return(apr_pstrcat(p,
                           "<p>The document has moved <a href=\"",
                           ap_escape_html(r->pool, location),
                           "\">here</a>.</p>\n",
                           NULL));
    case HTTP_SEE_OTHER:
        return(apr_pstrcat(p,
                           "<p>The answer to your request is located "
                           "<a href=\"",
                           ap_escape_html(r->pool, location),
                           "\">here</a>.</p>\n",
                           NULL));
    case HTTP_USE_PROXY:
        return("<p>This resource is only accessible "
               "through the proxy\n"
               "<br />\nYou will need to configure "
               "your client to use that proxy.</p>\n");
    case HTTP_PROXY_AUTHENTICATION_REQUIRED:
    case HTTP_UNAUTHORIZED:
        return("<p>This server could not verify that you\n"
               "are authorized to access the document\n"
               "requested.  Either you supplied the wrong\n"
               "credentials (e.g., bad password), or your\n"
               "browser doesn't understand how to supply\n"
               "the credentials required.</p>\n");
    case HTTP_BAD_REQUEST:
        return(add_optional_notes(r,
                                  "<p>Your browser sent a request that "
                                  "this server could not understand.<br />\n",
                                  "error-notes",
                                  "</p>\n"));
    case HTTP_FORBIDDEN:
        return(add_optional_notes(r, "<p>You don't have permission to access this resource.", "error-notes", "</p>\n"));
    case HTTP_NOT_FOUND:
        return("<p>The requested URL was not found on this server.</p>\n");
    case HTTP_METHOD_NOT_ALLOWED:
        return(apr_pstrcat(p,
                           "<p>The requested method ",
                           ap_escape_html(r->pool, method),
                           " is not allowed for this URL.</p>\n",
                           NULL));
    case HTTP_NOT_ACCEPTABLE:
        return(add_optional_notes(r, 
            "<p>An appropriate representation of the requested resource "
            "could not be found on this server.</p>\n",
            "variant-list", ""));
    case HTTP_MULTIPLE_CHOICES:
        return(add_optional_notes(r, "", "variant-list", ""));
    case HTTP_LENGTH_REQUIRED:
        s1 = apr_pstrcat(p,
                         "<p>A request of the requested method ",
                         ap_escape_html(r->pool, method),
                         " requires a valid Content-length.<br />\n",
                         NULL);
        return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
    case HTTP_PRECONDITION_FAILED:
        return("<p>The precondition on the request "
               "for this URL evaluated to false.</p>\n");
    case HTTP_NOT_IMPLEMENTED:
        s1 = apr_pstrcat(p,
                         "<p>",
                         ap_escape_html(r->pool, method),
                         " not supported for current URL.<br />\n",
                         NULL);
        return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
    case HTTP_BAD_GATEWAY:
        s1 = "<p>The proxy server received an invalid" CRLF
            "response from an upstream server.<br />" CRLF;
        return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
    case HTTP_VARIANT_ALSO_VARIES:
        return("<p>A variant for the requested "
               "resource\n<pre>\n"
               "\n</pre>\nis itself a negotiable resource. "
               "This indicates a configuration error.</p>\n");
    case HTTP_REQUEST_TIME_OUT:
        return("<p>Server timeout waiting for the HTTP request from the client.</p>\n");
    case HTTP_GONE:
        return("<p>The requested resource is no longer available on this server"
               " and there is no forwarding address.\n"
               "Please remove all references to this resource.</p>\n");
    case HTTP_REQUEST_ENTITY_TOO_LARGE:
        return(apr_pstrcat(p,
                           "The requested resource does not allow request data with ",
                           ap_escape_html(r->pool, method),
                           " requests, or the amount of data provided in\n"
                           "the request exceeds the capacity limit.\n",
                           NULL));
    case HTTP_REQUEST_URI_TOO_LARGE:
        s1 = "<p>The requested URL's length exceeds the capacity\n"
             "limit for this server.<br />\n";
        return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
    case HTTP_UNSUPPORTED_MEDIA_TYPE:
        return("<p>The supplied request data is not in a format\n"
               "acceptable for processing by this resource.</p>\n");
    case HTTP_RANGE_NOT_SATISFIABLE:
        return("<p>None of the range-specifier values in the Range\n"
               "request-header field overlap the current extent\n"
               "of the selected resource.</p>\n");
    case HTTP_EXPECTATION_FAILED:
        s1 = apr_table_get(r->headers_in, "Expect");
        if (s1)
            s1 = apr_pstrcat(p,
                     "<p>The expectation given in the Expect request-header\n"
                     "field could not be met by this server.\n"
                     "The client sent<pre>\n    Expect: ",
                     ap_escape_html(r->pool, s1), "\n</pre>\n",
                     NULL);
        else
            s1 = "<p>No expectation was seen, the Expect request-header \n"
                 "field was not presented by the client.\n";
        return add_optional_notes(r, s1, "error-notes", "</p>"
                   "<p>Only the 100-continue expectation is supported.</p>\n");
    case HTTP_UNPROCESSABLE_ENTITY:
        return("<p>The server understands the media type of the\n"
               "request entity, but was unable to process the\n"
               "contained instructions.</p>\n");
    case HTTP_LOCKED:
        return("<p>The requested resource is currently locked.\n"
               "The lock must be released or proper identification\n"
               "given before the method can be applied.</p>\n");
    case HTTP_FAILED_DEPENDENCY:
        return("<p>The method could not be performed on the resource\n"
               "because the requested action depended on another\n"
               "action and that other action failed.</p>\n");
    case HTTP_TOO_EARLY:
        return("<p>The request could not be processed as TLS\n"
               "early data and should be retried.</p>\n");
    case HTTP_UPGRADE_REQUIRED:
        return("<p>The requested resource can only be retrieved\n"
               "using SSL.  The server is willing to upgrade the current\n"
               "connection to SSL, but your client doesn't support it.\n"
               "Either upgrade your client, or try requesting the page\n"
               "using https://\n");
    case HTTP_PRECONDITION_REQUIRED:
        return("<p>The request is required to be conditional.</p>\n");
    case HTTP_TOO_MANY_REQUESTS:
        return("<p>The user has sent too many requests\n"
               "in a given amount of time.</p>\n");
    case HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE:
        return("<p>The server refused this request because\n"
               "the request header fields are too large.</p>\n");
    case HTTP_INSUFFICIENT_STORAGE:
        return("<p>The method could not be performed on the resource\n"
               "because the server is unable to store the\n"
               "representation needed to successfully complete the\n"
               "request.  There is insufficient free space left in\n"
               "your storage allocation.</p>\n");
    case HTTP_SERVICE_UNAVAILABLE:
        return("<p>The server is temporarily unable to service your\n"
               "request due to maintenance downtime or capacity\n"
               "problems. Please try again later.</p>\n");
    case HTTP_GATEWAY_TIME_OUT:
        return("<p>The gateway did not receive a timely response\n"
               "from the upstream server or application.</p>\n");
    case HTTP_LOOP_DETECTED:
        return("<p>The server terminated an operation because\n"
               "it encountered an infinite loop.</p>\n");
    case HTTP_NOT_EXTENDED:
        return("<p>A mandatory extension policy in the request is not\n"
               "accepted by the server for this resource.</p>\n");
    case HTTP_NETWORK_AUTHENTICATION_REQUIRED:
        return("<p>The client needs to authenticate to gain\n"
               "network access.</p>\n");
    case HTTP_IM_A_TEAPOT:
        return("<p>The resulting entity body MAY be short and\n"
                "stout.</p>\n");
    case HTTP_MISDIRECTED_REQUEST:
        return("<p>The client needs a new connection for this\n"
               "request as the requested host name does not match\n"
               "the Server Name Indication (SNI) in use for this\n"
               "connection.</p>\n");
    case HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
        return(add_optional_notes(r, 
               "<p>Access to this URL has been denied for legal reasons.<br />\n",
               "error-notes", "</p>\n"));
    default:                    /* HTTP_INTERNAL_SERVER_ERROR */
        /*
         * This comparison to expose error-notes could be modified to
         * use a configuration directive and export based on that
         * directive.  For now "*" is used to designate an error-notes
         * that is totally safe for any user to see (ie lacks paths,
         * database passwords, etc.)
         */
        if (((error_notes = apr_table_get(r->notes,
                                          "error-notes")) != NULL)
            && (h1 = apr_table_get(r->notes, "verbose-error-to")) != NULL
            && (strcmp(h1, "*") == 0)) {
            return(apr_pstrcat(p, error_notes, "<p />\n", NULL));
        }
        else {
            return(apr_pstrcat(p,
                               "<p>The server encountered an internal "
                               "error or\n"
                               "misconfiguration and was unable to complete\n"
                               "your request.</p>\n"
                               "<p>Please contact the server "
                               "administrator at \n ",
                               ap_escape_html(r->pool,
                                              r->server->server_admin),
                               " to inform them of the time this "
                               "error occurred,\n"
                               " and the actions you performed just before "
                               "this error.</p>\n"
                               "<p>More information about this error "
                               "may be available\n"
                               "in the server error log.</p>\n",
                               NULL));
        }
        /*
         * It would be nice to give the user the information they need to
         * fix the problem directly since many users don't have access to
         * the error_log (think University sites) even though they can easily
         * get this error by misconfiguring an htaccess file.  However, the
         * e error notes tend to include the real file pathname in this case,
         * which some people consider to be a breach of privacy.  Until we
         * can figure out a way to remove the pathname, leave this commented.
         *
         * if ((error_notes = apr_table_get(r->notes,
         *                                  "error-notes")) != NULL) {
         *     return(apr_pstrcat(p, error_notes, "<p />\n", NULL);
         * }
         * else {
         *     return "";
         * }
         */
    }
}

/* We should have named this send_canned_response, since it is used for any
 * response that can be generated by the server from the request record.
 * This includes all 204 (no content), 3xx (redirect), 4xx (client error),
 * and 5xx (server error) messages that have not been redirected to another
 * handler via the ErrorDocument feature.
 */
AP_DECLARE(void) ap_send_error_response(request_rec *r, int recursive_error)
{
    int status = r->status;
    int idx = ap_index_of_response(status);
    char *custom_response;
    const char *location = apr_table_get(r->headers_out, "Location");

    /* At this point, we are starting the response over, so we have to reset
     * this value.
     */
    r->eos_sent = 0;

    /* and we need to get rid of any RESOURCE filters that might be lurking
     * around, thinking they are in the middle of the original request
     */

    r->output_filters = r->proto_output_filters;

    ap_run_insert_error_filter(r);

    /* We need to special-case the handling of 204 and 304 responses,
     * since they have specific HTTP requirements and do not include a
     * message body.  Note that being assbackwards here is not an option.
     */
    if (AP_STATUS_IS_HEADER_ONLY(status)) {
        ap_finalize_request_protocol(r);
        return;
    }

    /*
     * It's possible that the Location field might be in r->err_headers_out
     * instead of r->headers_out; use the latter if possible, else the
     * former.
     */
    if (location == NULL) {
        location = apr_table_get(r->err_headers_out, "Location");
    }

    if (!r->assbackwards) {

        /* For all HTTP/1.x responses for which we generate the message,
         * we need to avoid inheriting the "normal status" header fields
         * that may have been set by the request handler before the
         * error or redirect, except for Location on external redirects.
         */
        apr_table_clear(r->headers_out);

        if (ap_is_HTTP_REDIRECT(status) || (status == HTTP_CREATED)) {
            if ((location != NULL) && *location) {
                apr_table_setn(r->headers_out, "Location", location);
            }
            else {
                location = "";   /* avoids coredump when printing, below */
            }
        }

        r->content_languages = NULL;
        r->content_encoding = NULL;
        r->clength = 0;

        if (apr_table_get(r->subprocess_env,
                          "suppress-error-charset") != NULL) {
            core_request_config *request_conf =
                        ap_get_core_module_config(r->request_config);
            request_conf->suppress_charset = 1; /* avoid adding default
                                                 * charset later
                                                 */
            ap_set_content_type_ex(r, "text/html", 1);
        }
        else {
            ap_set_content_type_ex(r, "text/html; charset=iso-8859-1", 1);
        }

        if ((status == HTTP_METHOD_NOT_ALLOWED)
            || (status == HTTP_NOT_IMPLEMENTED)) {
            apr_table_setn(r->headers_out, "Allow", make_allow(r));
        }

        if (r->header_only) {
            ap_finalize_request_protocol(r);
            return;
        }
    }

    if ((custom_response = ap_response_code_string(r, idx))) {
        /*
         * We have a custom response output. This should only be
         * a text-string to write back. But if the ErrorDocument
         * was a local redirect and the requested resource failed
         * for any reason, the custom_response will still hold the
         * redirect URL. We don't really want to output this URL
         * as a text message, so first check the custom response
         * string to ensure that it is a text-string (using the
         * same test used in ap_die(), i.e. does it start with a ").
         *
         * If it's not a text string, we've got a recursive error or
         * an external redirect.  If it's a recursive error, ap_die passes
         * us the second error code so we can write both, and has already
         * backed up to the original error.  If it's an external redirect,
         * it hasn't happened yet; we may never know if it fails.
         */
        if (custom_response[0] == '\"') {
            ap_rvputs_proto_in_ascii(r, custom_response + 1, NULL);
            ap_finalize_request_protocol(r);
            return;
        }
    }
    {
        const char *title = status_lines[idx];
        const char *h1;

        /* Accept a status_line set by a module, but only if it begins
         * with the correct 3 digit status code
         */
        if (r->status_line) {
            char *end;
            int len = strlen(r->status_line);
            if (len >= 3
                && apr_strtoi64(r->status_line, &end, 10) == r->status
                && (end - 3) == r->status_line
                && (len < 4 || apr_isspace(r->status_line[3]))
                && (len < 5 || apr_isalnum(r->status_line[4]))) {
                /* Since we passed the above check, we know that length three
                 * is equivalent to only a 3 digit numeric http status.
                 * RFC2616 mandates a trailing space, let's add it.
                 * If we have an empty reason phrase, we also add "Unknown Reason".
                 */
                if (len == 3) {
                    r->status_line = apr_pstrcat(r->pool, r->status_line, " Unknown Reason", NULL);
                } else if (len == 4) {
                    r->status_line = apr_pstrcat(r->pool, r->status_line, "Unknown Reason", NULL);
                }
                title = r->status_line;
            }
        }

        /* folks decided they didn't want the error code in the H1 text */
        h1 = &title[4];

        /* can't count on a charset filter being in place here,
         * so do ebcdic->ascii translation explicitly (if needed)
         */

        ap_rvputs_proto_in_ascii(r,
                  DOCTYPE_HTML_4_01
                  "<html><head>\n<title>", title,
                  "</title>\n</head><body>\n<h1>", h1, "</h1>\n",
                  NULL);

        ap_rvputs_proto_in_ascii(r,
                                 get_canned_error_string(status, r, location),
                                 NULL);

        if (recursive_error) {
            ap_rvputs_proto_in_ascii(r, "<p>Additionally, a ",
                      status_lines[ap_index_of_response(recursive_error)],
                      "\nerror was encountered while trying to use an "
                      "ErrorDocument to handle the request.</p>\n", NULL);
        }
        ap_rvputs_proto_in_ascii(r, ap_psignature("<hr>\n", r), NULL);
        ap_rvputs_proto_in_ascii(r, "</body></html>\n", NULL);
    }
    ap_finalize_request_protocol(r);
}

/*
 * Create a new method list with the specified number of preallocated
 * extension slots.
 */
AP_DECLARE(ap_method_list_t *) ap_make_method_list(apr_pool_t *p, int nelts)
{
    ap_method_list_t *ml;

    ml = (ap_method_list_t *) apr_palloc(p, sizeof(ap_method_list_t));
    ml->method_mask = 0;
    ml->method_list = apr_array_make(p, nelts, sizeof(char *));
    return ml;
}

/*
 * Make a copy of a method list (primarily for subrequests that may
 * subsequently change it; don't want them changing the parent's, too!).
 */
AP_DECLARE(void) ap_copy_method_list(ap_method_list_t *dest,
                                     ap_method_list_t *src)
{
    int i;
    char **imethods;
    char **omethods;

    dest->method_mask = src->method_mask;
    imethods = (char **) src->method_list->elts;
    for (i = 0; i < src->method_list->nelts; ++i) {
        omethods = (char **) apr_array_push(dest->method_list);
        *omethods = apr_pstrdup(dest->method_list->pool, imethods[i]);
    }
}

/*
 * Return true if the specified HTTP method is in the provided
 * method list.
 */
AP_DECLARE(int) ap_method_in_list(ap_method_list_t *l, const char *method)
{
    int methnum;

    /*
     * If it's one of our known methods, use the shortcut and check the
     * bitmask.
     */
    methnum = ap_method_number_of(method);
    if (methnum != M_INVALID) {
        return !!(l->method_mask & (AP_METHOD_BIT << methnum));
    }
    /*
     * Otherwise, see if the method name is in the array of string names.
     */
    if ((l->method_list == NULL) || (l->method_list->nelts == 0)) {
        return 0;
    }

    return ap_array_str_contains(l->method_list, method);
}

/*
 * Add the specified method to a method list (if it isn't already there).
 */
AP_DECLARE(void) ap_method_list_add(ap_method_list_t *l, const char *method)
{
    int methnum;
    const char **xmethod;

    /*
     * If it's one of our known methods, use the shortcut and use the
     * bitmask.
     */
    methnum = ap_method_number_of(method);
    if (methnum != M_INVALID) {
        l->method_mask |= (AP_METHOD_BIT << methnum);
        return;
    }
    /*
     * Otherwise, see if the method name is in the array of string names.
     */
    if (ap_array_str_contains(l->method_list, method)) {
        return;
    }

    xmethod = (const char **) apr_array_push(l->method_list);
    *xmethod = method;
}

/*
 * Remove the specified method from a method list.
 */
AP_DECLARE(void) ap_method_list_remove(ap_method_list_t *l,
                                       const char *method)
{
    int methnum;
    char **methods;

    /*
     * If it's a known methods, either builtin or registered
     * by a module, use the bitmask.
     */
    methnum = ap_method_number_of(method);
    if (methnum != M_INVALID) {
        l->method_mask &= ~(AP_METHOD_BIT << methnum);
        return;
    }
    /*
     * Otherwise, see if the method name is in the array of string names.
     */
    if (l->method_list->nelts != 0) {
        int i, j, k;
        methods = (char **)l->method_list->elts;
        for (i = 0; i < l->method_list->nelts; ) {
            if (strcmp(method, methods[i]) == 0) {
                for (j = i, k = i + 1; k < l->method_list->nelts; ++j, ++k) {
                    methods[j] = methods[k];
                }
                --l->method_list->nelts;
            }
            else {
                ++i;
            }
        }
    }
}

/*
 * Reset a method list to be completely empty.
 */
AP_DECLARE(void) ap_clear_method_list(ap_method_list_t *l)
{
    l->method_mask = 0;
    l->method_list->nelts = 0;
}

AP_DECLARE(apr_status_t) ap_h1_append_header(apr_bucket_brigade *bb,
                                             apr_pool_t *pool,
                                             const char *name, const char *value)
{
#if APR_CHARSET_EBCDIC
    char *headfield;
    apr_size_t len;

    headfield = apr_pstrcat(pool, name, ": ", value, CRLF, NULL);
    len = strlen(headfield);

    ap_xlate_proto_to_ascii(headfield, len);
    return apr_brigade_write(bb, NULL, NULL, headfield, len);
#else
    struct iovec vec[4];
    struct iovec *v = vec;
    v->iov_base = (void *)name;
    v->iov_len = strlen(name);
    v++;
    v->iov_base = ": ";
    v->iov_len = sizeof(": ") - 1;
    v++;
    v->iov_base = (void *)value;
    v->iov_len = strlen(value);
    v++;
    v->iov_base = CRLF;
    v->iov_len = sizeof(CRLF) - 1;
    return apr_brigade_writev(bb, NULL, NULL, vec, 4);
#endif /* !APR_CHARSET_EBCDIC */
}

AP_DECLARE(apr_status_t) ap_h1_append_headers(apr_bucket_brigade *bb,
                                              request_rec *r,
                                              apr_table_t *headers)
{
    const apr_array_header_t *elts;
    const apr_table_entry_t *t_elt;
    const apr_table_entry_t *t_end;
    struct iovec *vec;
    struct iovec *vec_next;

    elts = apr_table_elts(headers);
    if (elts->nelts == 0) {
        return APR_SUCCESS;
    }
    t_elt = (const apr_table_entry_t *)(elts->elts);
    t_end = t_elt + elts->nelts;
    vec = (struct iovec *)apr_palloc(r->pool, 4 * elts->nelts *
                                     sizeof(struct iovec));
    vec_next = vec;

    /* For each field, generate
     *    name ": " value CRLF
     */
    do {
        if (t_elt->key && t_elt->val) {
            vec_next->iov_base = (void*)(t_elt->key);
            vec_next->iov_len = strlen(t_elt->key);
            vec_next++;
            vec_next->iov_base = ": ";
            vec_next->iov_len = sizeof(": ") - 1;
            vec_next++;
            vec_next->iov_base = (void*)(t_elt->val);
            vec_next->iov_len = strlen(t_elt->val);
            vec_next++;
            vec_next->iov_base = CRLF;
            vec_next->iov_len = sizeof(CRLF) - 1;
            vec_next++;
        }
        t_elt++;
    } while (t_elt < t_end);

    if (APLOGrtrace4(r)) {
        t_elt = (const apr_table_entry_t *)(elts->elts);
        do {
            ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "  %s: %s",
                          t_elt->key, t_elt->val);
            t_elt++;
        } while (t_elt < t_end);
    }

#if APR_CHARSET_EBCDIC
    {
        apr_size_t len;
        char *tmp = apr_pstrcatv(r->pool, vec, vec_next - vec, &len);
        ap_xlate_proto_to_ascii(tmp, len);
        return apr_brigade_write(bb, NULL, NULL, tmp, len);
    }
#else
    return apr_brigade_writev(bb, NULL, NULL, vec, vec_next - vec);
#endif
}

AP_DECLARE(apr_status_t) ap_h1_terminate_header(apr_bucket_brigade *bb)
{
    char crlf[] = CRLF;
    apr_size_t buflen;

    buflen = strlen(crlf);
    ap_xlate_proto_to_ascii(crlf, buflen);
    return apr_brigade_write(bb, NULL, NULL, crlf, buflen);
}

AP_DECLARE(void) ap_h1_add_end_chunk(apr_bucket_brigade *b,
                                     apr_bucket *eos,
                                     request_rec *r,
                                     apr_table_t *trailers)
{
    if (!trailers || apr_is_empty_table(trailers)) {
        apr_bucket *e;

        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                      "append empty end chunk");
        e = apr_bucket_immortal_create(ZERO_ASCII CRLF_ASCII
                                       CRLF_ASCII, 5, b->bucket_alloc);
        if (eos) {
            APR_BUCKET_INSERT_BEFORE(eos, e);
        }
        else {
            APR_BRIGADE_INSERT_TAIL(b, e);
        }
    }
    else {
        apr_bucket_brigade *tmp;

        ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
                      "append end chunk with trailers");
        tmp = eos? apr_brigade_split_ex(b, eos, NULL) : NULL;
        apr_brigade_write(b, NULL, NULL, ZERO_ASCII CRLF_ASCII, 3);
        ap_h1_append_headers(b, r, trailers);
        ap_h1_terminate_header(b);
        if (tmp) APR_BRIGADE_CONCAT(b, tmp);
    }
}

typedef enum {
    rrl_none, rrl_badprotocol, rrl_badmethod, rrl_badwhitespace, rrl_excesswhitespace,
    rrl_missinguri, rrl_baduri, rrl_trailingtext,
} rrl_error;

/* get the length of a name for logging, but no more than 80 bytes */
#define LOG_NAME_MAX_LEN 80
static int log_name_len(const char *name)
{
    apr_size_t len = strlen(name);
    return (len > LOG_NAME_MAX_LEN)? LOG_NAME_MAX_LEN : (int)len;
}

static void rrl_log_error(request_rec *r, rrl_error error, const char *etoken)
{
    switch (error) {
    case rrl_none:
        break;
    case rrl_badprotocol:
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02418)
                      "HTTP Request Line; Unrecognized protocol '%.*s' "
                      "(perhaps whitespace was injected?)",
                      log_name_len(etoken), etoken);
        break;
    case rrl_badmethod:
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03445)
                      "HTTP Request Line; Invalid method token: '%.*s'",
                      log_name_len(etoken), etoken);
        break;
    case rrl_badwhitespace:
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03447)
                      "HTTP Request Line; Invalid whitespace");
        break;
    case rrl_excesswhitespace:
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03448)
                      "HTTP Request Line; Excess whitespace "
                      "(disallowed by HttpProtocolOptions Strict)");
        break;
    case rrl_missinguri:
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03446)
                      "HTTP Request Line; Missing URI");
        break;
    case rrl_baduri:
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03454)
                      "HTTP Request Line; URI incorrectly encoded: '%.*s'",
                      log_name_len(etoken), etoken);
        break;
    case rrl_trailingtext:
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03449)
                      "HTTP Request Line; Extraneous text found '%.*s' "
                      "(perhaps whitespace was injected?)",
                      log_name_len(etoken), etoken);
        break;
    }
}

/* remember the first error we encountered during tokenization */
#define RRL_ERROR(e, et, y, yt)     \
    do { \
        if (e == rrl_none) {\
            e = y; et = yt;\
        }\
    } while (0)

static rrl_error tokenize_request_line(
        char *line, int strict,
        const char **pmethod, const char **puri, const char **pprotocol,
        const char **perror_token)
{
    char *method, *protocol, *uri, *ll;
    rrl_error e = rrl_none;
    char *etoken = NULL;
    apr_size_t len = 0;

    method = line;
    /* If there is whitespace before a method, skip it and mark in error */
    if (apr_isspace(*method)) {
        RRL_ERROR(e, etoken, rrl_badwhitespace, method);
        for ( ; apr_isspace(*method); ++method)
            ;
    }

    /* Scan the method up to the next whitespace, ensure it contains only
     * valid http-token characters, otherwise mark in error
     */
    if (strict) {
        ll = (char*) ap_scan_http_token(method);
    }
    else {
        ll = (char*) ap_scan_vchar_obstext(method);
    }

    if ((ll == method) || (*ll && !apr_isspace(*ll))) {
        RRL_ERROR(e, etoken, rrl_badmethod, ll);
        ll = strpbrk(ll, "\t\n\v\f\r ");
    }

    /* Verify method terminated with a single SP, or mark as specific error */
    if (!ll) {
        RRL_ERROR(e, etoken, rrl_missinguri, NULL);
        protocol = uri = "";
        goto done;
    }
    else if (strict && ll[0] && apr_isspace(ll[1])) {
        RRL_ERROR(e, etoken, rrl_excesswhitespace, ll);
    }

    /* Advance uri pointer over leading whitespace, NUL terminate the method
     * If non-SP whitespace is encountered, mark as specific error
     */
    for (uri = ll; apr_isspace(*uri); ++uri)
        if (*uri != ' ')
            RRL_ERROR(e, etoken, rrl_badwhitespace, uri);
    *ll = '\0';

    if (!*uri)
        RRL_ERROR(e, etoken, rrl_missinguri, NULL);

    /* Scan the URI up to the next whitespace, ensure it contains no raw
     * control characters, otherwise mark in error
     */
    ll = (char*) ap_scan_vchar_obstext(uri);
    if (ll == uri || (*ll && !apr_isspace(*ll))) {
        RRL_ERROR(e, etoken, rrl_baduri, ll);
        ll = strpbrk(ll, "\t\n\v\f\r ");
    }

    /* Verify URI terminated with a single SP, or mark as specific error */
    if (!ll) {
        protocol = "";
        goto done;
    }
    else if (strict && ll[0] && apr_isspace(ll[1])) {
        RRL_ERROR(e, etoken, rrl_excesswhitespace, ll);
    }

    /* Advance protocol pointer over leading whitespace, NUL terminate the uri
     * If non-SP whitespace is encountered, mark as specific error
     */
    for (protocol = ll; apr_isspace(*protocol); ++protocol)
        if (*protocol != ' ')
            RRL_ERROR(e, etoken, rrl_badwhitespace, protocol);
    *ll = '\0';

    /* Scan the protocol up to the next whitespace, validation comes later */
    if (!(ll = (char*) ap_scan_vchar_obstext(protocol))) {
        len = strlen(protocol);
        goto done;
    }
    len = ll - protocol;

    /* Advance over trailing whitespace, if found mark in error,
     * determine if trailing text is found, unconditionally mark in error,
     * finally NUL terminate the protocol string
     */
    if (*ll && !apr_isspace(*ll)) {
        RRL_ERROR(e, etoken, rrl_badprotocol, ll);
    }
    else if (strict && *ll) {
        RRL_ERROR(e, etoken, rrl_excesswhitespace, ll);
    }
    else {
        for ( ; apr_isspace(*ll); ++ll)
            if (*ll != ' ') {
                RRL_ERROR(e, etoken, rrl_badwhitespace, ll);
                break;
            }
        if (*ll)
            RRL_ERROR(e, etoken, rrl_trailingtext, ll);
    }
    *((char *)protocol + len) = '\0';

done:
    *pmethod = method;
    *puri = uri;
    *pprotocol = protocol;
    *perror_token = etoken;
    return e;
}

AP_DECLARE(int) ap_h1_tokenize_request_line(
        request_rec *r, const char *line,
        const char **pmethod, const char **puri, const char **pprotocol)
{
    core_server_config *conf = ap_get_core_module_config(r->server->module_config);
    int strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);
    rrl_error error;
    const char *error_token;

    ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
                  "ap_tokenize_request_line: '%s'", line);
    error = tokenize_request_line(apr_pstrdup(r->pool, line), strict, pmethod,
                                  puri, pprotocol, &error_token);
    ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
                  "ap_tokenize_request: error=%d, method=%s, uri=%s, protocol=%s",
                  error, *pmethod, *puri, *pprotocol);
    if (error != rrl_none) {
        rrl_log_error(r, error, error_token);
        return 0;
    }
    return 1;
}
