/* ====================================================================
 * Copyright (c) 1995-1999 The Apache Group.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the Apache Group
 *    for use in the Apache HTTP server project (http://www.apache.org/)."
 *
 * 4. The names "Apache Server" and "Apache Group" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the Apache Group
 *    for use in the Apache HTTP server project (http://www.apache.org/)."
 *
 * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Group and was originally based
 * on public domain software written at the National Center for
 * Supercomputing Applications, University of Illinois, Urbana-Champaign.
 * For more information on the Apache Group and the Apache HTTP server
 * project, please see <http://www.apache.org/>.
 *
 */

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

#define CORE_PRIVATE
#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 "util_date.h"          /* For parseHTTPdate and BAD_DATE */
#include <stdarg.h>
#include "http_conf_globals.h"

#define SET_BYTES_SENT(r) \
  do { if (r->sent_bodyct) \
          ap_bgetopt (r->connection->client, BO_BYTECT, &r->bytes_sent); \
  } while (0)


static int parse_byterange(char *range, long clength, long *start, long *end)
{
    char *dash = strchr(range, '-');

    if (!dash)
        return 0;

    if ((dash == range)) {
        /* In the form "-5" */
        *start = clength - atol(dash + 1);
        *end = clength - 1;
    }
    else {
        *dash = '\0';
        dash++;
        *start = atol(range);
        if (*dash)
            *end = atol(dash);
        else                    /* "5-" */
            *end = clength - 1;
    }

    if (*start < 0)
	*start = 0;

    if (*end >= clength)
        *end = clength - 1;

    if (*start > *end)
	return 0;

    return (*start > 0 || *end < clength - 1);
}

static int internal_byterange(int, long *, request_rec *, const char **, long *,
                              long *);

API_EXPORT(int) ap_set_byterange(request_rec *r)
{
    const char *range, *if_range, *match;
    long range_start, range_end;

    if (!r->clength || r->assbackwards)
        return 0;

    /* Check for Range request-header (HTTP/1.1) or Request-Range for
     * backwards-compatibility with second-draft Luotonen/Franks
     * byte-ranges (e.g. Netscape Navigator 2-3).
     *
     * We support this form, with Request-Range, and (farther down) we
     * send multipart/x-byteranges instead of multipart/byteranges for
     * Request-Range based requests to work around a bug in Netscape
     * Navigator 2-3 and MSIE 3.
     */

    if (!(range = ap_table_get(r->headers_in, "Range")))
        range = ap_table_get(r->headers_in, "Request-Range");

    if (!range || strncasecmp(range, "bytes=", 6)) {
        return 0;
    }

    /* Check the If-Range header for Etag or Date.
     * Note that this check will return false (as required) if either
     * of the two etags are weak.
     */
    if ((if_range = ap_table_get(r->headers_in, "If-Range"))) {
        if (if_range[0] == '"') {
            if (!(match = ap_table_get(r->headers_out, "Etag")) ||
                (strcmp(if_range, match) != 0))
                return 0;
        }
        else if (!(match = ap_table_get(r->headers_out, "Last-Modified")) ||
                 (strcmp(if_range, match) != 0))
            return 0;
    }

    if (!strchr(range, ',')) {
        /* A single range */
        if (!parse_byterange(ap_pstrdup(r->pool, range + 6), r->clength,
                             &range_start, &range_end))
            return 0;

        r->byterange = 1;

        ap_table_setn(r->headers_out, "Content-Range",
	    ap_psprintf(r->pool, "bytes %ld-%ld/%ld",
		range_start, range_end, r->clength));
        ap_table_setn(r->headers_out, "Content-Length",
	    ap_psprintf(r->pool, "%ld", range_end - range_start + 1));
    }
    else {
        /* a multiple range */
        const char *r_range = ap_pstrdup(r->pool, range + 6);
        long tlength = 0;

        r->byterange = 2;
        r->boundary = ap_psprintf(r->pool, "%lx%lx",
				r->request_time, (long) getpid());
        while (internal_byterange(0, &tlength, r, &r_range, NULL, NULL));
        ap_table_setn(r->headers_out, "Content-Length",
	    ap_psprintf(r->pool, "%ld", tlength));
    }

    r->status = PARTIAL_CONTENT;
    r->range = range + 6;

    return 1;
}

API_EXPORT(int) ap_each_byterange(request_rec *r, long *offset, long *length)
{
    return internal_byterange(1, NULL, r, &r->range, offset, length);
}

/* If this function is called with realreq=1, it will spit out
 * the correct headers for a byterange chunk, and set offset and
 * length to the positions they should be.
 *
 * If it is called with realreq=0, it will add to tlength the length
 * it *would* have used with realreq=1.
 *
 * Either case will return 1 if it should be called again, and 0
 * when done.
 */
static int internal_byterange(int realreq, long *tlength, request_rec *r,
                              const char **r_range, long *offset, long *length)
{
    long range_start, range_end;
    char *range;

    if (!**r_range) {
        if (r->byterange > 1) {
            if (realreq)
                ap_rvputs(r, "\015\012--", r->boundary, "--\015\012", NULL);
            else
                *tlength += 4 + strlen(r->boundary) + 4;
        }
        return 0;
    }

    range = ap_getword(r->pool, r_range, ',');
    if (!parse_byterange(range, r->clength, &range_start, &range_end))
        /* Skip this one */
        return internal_byterange(realreq, tlength, r, r_range, offset,
                                  length);

    if (r->byterange > 1) {
        const char *ct = r->content_type ? r->content_type : ap_default_type(r);
        char ts[MAX_STRING_LEN];

        ap_snprintf(ts, sizeof(ts), "%ld-%ld/%ld", range_start, range_end,
                    r->clength);
        if (realreq)
            ap_rvputs(r, "\015\012--", r->boundary, "\015\012Content-type: ",
                   ct, "\015\012Content-range: bytes ", ts, "\015\012\015\012",
                   NULL);
        else
            *tlength += 4 + strlen(r->boundary) + 16 + strlen(ct) + 23 +
                        strlen(ts) + 4;
    }

    if (realreq) {
        *offset = range_start;
        *length = range_end - range_start + 1;
    }
    else {
        *tlength += range_end - range_start + 1;
    }
    return 1;
}

API_EXPORT(int) ap_set_content_length(request_rec *r, long clength)
{
    r->clength = clength;
    ap_table_setn(r->headers_out, "Content-Length", ap_psprintf(r->pool, "%ld", clength));
    return 0;
}

API_EXPORT(int) ap_set_keepalive(request_rec *r)
{
    int ka_sent = 0;
    int wimpy = ap_find_token(r->pool,
                           ap_table_get(r->headers_out, "Connection"), "close");
    const char *conn = ap_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 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);
     *   THEN we can be persistent, which requires more headers be output.
     *
     * Note that the condition evaluation order is extremely important.
     */
    if ((r->connection->keepalive != -1) &&
        ((r->status == HTTP_NOT_MODIFIED) ||
         (r->status == HTTP_NO_CONTENT) ||
         r->header_only ||
         ap_table_get(r->headers_out, "Content-Length") ||
         ap_find_last_token(r->pool,
                         ap_table_get(r->headers_out, "Transfer-Encoding"),
                         "chunked") ||
         ((r->proto_num >= HTTP_VERSION(1,1)) &&
	  (r->chunked = 1))) && /* THIS CODE IS CORRECT, see comment above. */
        r->server->keep_alive &&
        (r->server->keep_alive_timeout > 0) &&
        ((r->server->keep_alive_max == 0) ||
         (r->server->keep_alive_max > r->connection->keepalives)) &&
        !ap_status_drops_connection(r->status) &&
        !wimpy &&
        !ap_find_token(r->pool, conn, "close") &&
        (!ap_table_get(r->subprocess_env, "nokeepalive") ||
         ap_table_get(r->headers_in, "Via")) &&
        ((ka_sent = ap_find_token(r->pool, conn, "keep-alive")) ||
         (r->proto_num >= HTTP_VERSION(1,1)))
       ) {
        int left = r->server->keep_alive_max - r->connection->keepalives;

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

        /* If they sent a Keep-Alive token, send one back */
        if (ka_sent) {
            if (r->server->keep_alive_max)
		ap_table_setn(r->headers_out, "Keep-Alive",
		    ap_psprintf(r->pool, "timeout=%d, max=%d",
                            r->server->keep_alive_timeout, left));
            else
		ap_table_setn(r->headers_out, "Keep-Alive",
		    ap_psprintf(r->pool, "timeout=%d",
                            r->server->keep_alive_timeout));
            ap_table_mergen(r->headers_out, "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)
	ap_table_mergen(r->headers_out, "Connection", "close");

    r->connection->keepalive = 0;

    return 0;
}

/*
 * Return the latest rational time from a request/mtime (modification time)
 * pair.  We return the mtime unless it's in the future, in which case we
 * return the current time.  We use the request time as a reference in order
 * to limit the number of calls to time().  We don't check for futurosity
 * unless the mtime is at least as new as the reference.
 */
API_EXPORT(time_t) ap_rationalize_mtime(request_rec *r, time_t mtime)
{
    time_t now;

    /* For all static responses, it's almost certain that the file was
     * last modified before the beginning of the request.  So there's
     * no reason to call time(NULL) again.  But if the response has been
     * created on demand, then it might be newer than the time the request
     * started.  In this event we really have to call time(NULL) again
     * so that we can give the clients the most accurate Last-Modified.  If we
     * were given a time in the future, we return the current time - the
     * Last-Modified can't be in the future.
     */
    now = (mtime < r->request_time) ? r->request_time : time(NULL);
    return (mtime > now) ? now : mtime;
}

API_EXPORT(int) ap_meets_conditions(request_rec *r)
{
    const char *etag = ap_table_get(r->headers_out, "ETag");
    const char *if_match, *if_modified_since, *if_unmodified, *if_nonematch;
    time_t mtime;

    /* 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;
    }

    mtime = (r->mtime != 0) ? r->mtime : time(NULL);

    /* 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).
     */
    if ((if_match = ap_table_get(r->headers_in, "If-Match")) != NULL) {
        if (if_match[0] != '*' &&
            (etag == NULL || etag[0] == 'W' ||
             !ap_find_list_item(r->pool, if_match, etag))) {
            return HTTP_PRECONDITION_FAILED;
        }
    }
    else {
        /* 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).
         */
        if_unmodified = ap_table_get(r->headers_in, "If-Unmodified-Since");
        if (if_unmodified != NULL) {
            time_t ius = ap_parseHTTPdate(if_unmodified);

            if ((ius != BAD_DATE) && (mtime > ius)) {
                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.
     */
    if_nonematch = ap_table_get(r->headers_in, "If-None-Match");
    if (if_nonematch != NULL) {
        if (r->method_number == M_GET) {
            if (if_nonematch[0] == '*')
                return HTTP_NOT_MODIFIED;
            if (etag != NULL) {
                if (ap_table_get(r->headers_in, "Range")) {
                    if (etag[0] != 'W' &&
                        ap_find_list_item(r->pool, if_nonematch, etag)) {
                        return HTTP_NOT_MODIFIED;
                    }
                }
                else if (strstr(if_nonematch, etag)) {
                    return HTTP_NOT_MODIFIED;
                }
            }
        }
        else if (if_nonematch[0] == '*' ||
                 (etag != NULL &&
                  ap_find_list_item(r->pool, if_nonematch, etag))) {
            return HTTP_PRECONDITION_FAILED;
        }
    }
    /* Else 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.
     */
    else if ((r->method_number == M_GET)
             && ((if_modified_since =
                  ap_table_get(r->headers_in, "If-Modified-Since")) != NULL)) {
        time_t ims = ap_parseHTTPdate(if_modified_since);

        if ((ims >= mtime) && (ims <= r->request_time)) {
            return HTTP_NOT_MODIFIED;
        }
    }
    return OK;
}

/*
 * Construct an entity tag (ETag) from resource information.  If it's a real
 * file, build in some of the file characteristics.  If the modification time
 * is newer than (request-time minus 1 second), mark the ETag as weak - it
 * could be modified again in as short an interval.  We rationalize the
 * modification time we're given to keep it from being in the future.
 */
API_EXPORT(char *) ap_make_etag(request_rec *r, int force_weak)
{
    char *etag;
    char *weak;

    /*
     * Make an ETag header out of various pieces of information. We use
     * the last-modified date and, if we have a real file, the
     * length and inode number - note that this doesn't have to match
     * the content-length (i.e. includes), it just has to be unique
     * for the file.
     *
     * If the request was made within a second of the last-modified date,
     * we send a weak tag instead of a strong one, since it could
     * be modified again later in the second, and the validation
     * would be incorrect.
     */
    
    weak = ((r->request_time - r->mtime > 1) && !force_weak) ? "" : "W/";

    if (r->finfo.st_mode != 0) {
        etag = ap_psprintf(r->pool,
                    "%s\"%lx-%lx-%lx\"", weak,
                    (unsigned long) r->finfo.st_ino,
                    (unsigned long) r->finfo.st_size,
                    (unsigned long) r->mtime);
    }
    else {
        etag = ap_psprintf(r->pool, "%s\"%lx\"", weak,
                    (unsigned long) r->mtime);
    }

    return etag;
}

API_EXPORT(void) ap_set_etag(request_rec *r)
{
    char *etag;
    char *variant_etag, *vlv;
    int vlv_weak;

    if (!r->vlist_validator) {
        etag = ap_make_etag(r, 0);
    }
    else {
        /* If we have a variant list validator (vlv) due to the
         * response being negotiated, then we create a structured
         * entity tag which merges the variant etag with the variant
         * list validator (vlv).  This merging makes revalidation
         * somewhat safer, ensures that caches which can deal with
         * Vary will (eventually) be updated if the set of variants is
         * changed, and is also a protocol requirement for transparent
         * content negotiation.
         */

        /* if the variant list validator is weak, we make the whole
         * structured etag weak.  If we would not, then clients could
         * have problems merging range responses if we have different
         * variants with the same non-globally-unique strong etag.
         */

        vlv = r->vlist_validator;
        vlv_weak = (vlv[0] == 'W');
               
        variant_etag = ap_make_etag(r, vlv_weak);

        /* merge variant_etag and vlv into a structured etag */

        variant_etag[strlen(variant_etag) - 1] = '\0';
        if (vlv_weak)
            vlv += 3;
        else
            vlv++;
        etag = ap_pstrcat(r->pool, variant_etag, ";", vlv, NULL);
    }

    ap_table_setn(r->headers_out, "ETag", etag);
}

/*
 * This function sets the Last-Modified output header field to the value
 * of the mtime field in the request structure - rationalized to keep it from
 * being in the future.
 */
API_EXPORT(void) ap_set_last_modified(request_rec *r)
{
    time_t mod_time = ap_rationalize_mtime(r, r->mtime);

    ap_table_setn(r->headers_out, "Last-Modified",
              ap_gm_timestr_822(r->pool, mod_time));
}

/* 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.
 */
API_EXPORT(int) ap_method_number_of(const char *method)
{
    switch (*method) {
        case 'H':
           if (strcmp(method, "HEAD") == 0)
               return M_GET;   /* see header_only in request_rec */
           break;
        case 'G':
           if (strcmp(method, "GET") == 0)
               return M_GET;
           break;
        case 'P':
           if (strcmp(method, "POST") == 0)
               return M_POST;
           if (strcmp(method, "PUT") == 0)
               return M_PUT;
           if (strcmp(method, "PATCH") == 0)
               return M_PATCH;
           if (strcmp(method, "PROPFIND") == 0)
               return M_PROPFIND;
           if (strcmp(method, "PROPPATCH") == 0)
               return M_PROPPATCH;
           break;
        case 'D':
           if (strcmp(method, "DELETE") == 0)
               return M_DELETE;
           break;
        case 'C':
           if (strcmp(method, "CONNECT") == 0)
               return M_CONNECT;
           if (strcmp(method, "COPY") == 0)
               return M_COPY;
           break;
        case 'M':
           if (strcmp(method, "MKCOL") == 0)
               return M_MKCOL;
           if (strcmp(method, "MOVE") == 0)
               return M_MOVE;
           break;
        case 'O':
           if (strcmp(method, "OPTIONS") == 0)
               return M_OPTIONS;
           break;
        case 'T':
           if (strcmp(method, "TRACE") == 0)
               return M_TRACE;
           break;
        case 'L':
           if (strcmp(method, "LOCK") == 0)
               return M_LOCK;
           break;
        case 'U':
           if (strcmp(method, "UNLOCK") == 0)
               return M_UNLOCK;
           break;
    }
    return M_INVALID;
}

/* Get a line of protocol input, including any continuation lines
 * caused by MIME folding (or broken clients) if fold != 0, and place it
 * in the buffer s, of size n bytes, without the ending newline.
 *
 * Returns -1 on error, or the length of s.
 *
 * Note: Because bgets uses 1 char for newline and 1 char for NUL,
 *       the most we can get is (n - 2) actual characters if it
 *       was ended by a newline, or (n - 1) characters if the line
 *       length exceeded (n - 1).  So, if the result == (n - 1),
 *       then the actual input line exceeded the buffer length,
 *       and it would be a good idea for the caller to puke 400 or 414.
 */
static int getline(char *s, int n, BUFF *in, int fold)
{
    char *pos, next;
    int retval;
    int total = 0;

    pos = s;

    do {
        retval = ap_bgets(pos, n, in);     /* retval == -1 if error, 0 if EOF */

        if (retval <= 0)
            return ((retval < 0) && (total == 0)) ? -1 : total;

        /* retval is the number of characters read, not including NUL      */

        n -= retval;            /* Keep track of how much of s is full     */
        pos += (retval - 1);    /* and where s ends                        */
        total += retval;        /* and how long s has become               */

        if (*pos == '\n') {     /* Did we get a full line of input?        */
            /*
             * Trim any extra trailing spaces or tabs except for the first
             * space or tab at the beginning of a blank string.  This makes
             * it much easier to check field values for exact matches, and
             * saves memory as well.  Terminate string at end of line.
             */
            while (pos > (s + 1) && (*(pos - 1) == ' ' || *(pos - 1) == '\t')) {
                --pos;          /* trim extra trailing spaces or tabs      */
                --total;        /* but not one at the beginning of line    */
                ++n;
            }
            *pos = '\0';
            --total;
            ++n;
        }
        else
            return total;       /* if not, input line exceeded buffer size */

        /* Continue appending if line folding is desired and
         * the last line was not empty and we have room in the buffer and
         * the next line begins with a continuation character.
         */
    } while (fold && (retval != 1) && (n > 1)
                  && (ap_blookc(&next, in) == 1)
                  && ((next == ' ') || (next == '\t')));

    return total;
}

/* parse_uri: break apart the uri
 * Side Effects:
 * - sets r->args to rest after '?' (or NULL if no '?')
 * - sets r->uri to request uri (without r->args part)
 * - sets r->hostname (if not set already) from request (scheme://host:port)
 */
CORE_EXPORT(void) ap_parse_uri(request_rec *r, const char *uri)
{
    int status = HTTP_OK;

    r->unparsed_uri = ap_pstrdup(r->pool, uri);

    if (r->method_number == M_CONNECT) {
	status = ap_parse_hostinfo_components(r->pool, uri, &r->parsed_uri);
    } else {
	/* Simple syntax Errors in URLs are trapped by parse_uri_components(). */
	status = ap_parse_uri_components(r->pool, uri, &r->parsed_uri);
    }

    if (ap_is_HTTP_SUCCESS(status)) {
	/* if it has a scheme we may need to do absoluteURI vhost stuff */
	if (r->parsed_uri.scheme
	    && !strcasecmp(r->parsed_uri.scheme, ap_http_method(r))) {
	    r->hostname = r->parsed_uri.hostname;
	} else if (r->method_number == M_CONNECT) {
	    r->hostname = r->parsed_uri.hostname;
	}
	r->args = r->parsed_uri.query;
	r->uri = r->parsed_uri.path ? r->parsed_uri.path
				    : ap_pstrdup(r->pool, "/");
#if defined(OS2) || defined(WIN32)
	/* Handle path translations for OS/2 and plug security hole.
	 * This will prevent "http://www.wherever.com/..\..\/" from
	 * returning a directory for the root drive.
	 */
	{
	    char *x;

	    for (x = r->uri; (x = strchr(x, '\\')) != NULL; )
		*x = '/';
	}
#endif  /* OS2 || WIN32 */
    }
    else {
	r->args = NULL;
	r->hostname = NULL;
	r->status = status;             /* set error status */
	r->uri = ap_pstrdup(r->pool, uri);
    }
}

static int read_request_line(request_rec *r)
{
    char l[DEFAULT_LIMIT_REQUEST_LINE + 2]; /* getline's two extra for \n\0 */
    const char *ll = l;
    const char *uri;
    conn_rec *conn = r->connection;
    int major = 1, minor = 0;   /* Assume HTTP/1.0 if non-"HTTP" protocol */
    int len;

    /* Read past empty lines until we get a real request line,
     * a read error, the connection closes (EOF), or we timeout.
     *
     * We skip empty lines because browsers have to tack a CRLF on to the end
     * of POSTs to support old CERN webservers.  But note that we may not
     * have flushed any previous response completely to the client yet.
     * We delay the flush as long as possible so that we can improve
     * performance for clients that are pipelining requests.  If a request
     * is pipelined then we won't block during the (implicit) read() below.
     * If the requests aren't pipelined, then the client is still waiting
     * for the final buffer flush from us, and we will block in the implicit
     * read().  B_SAFEREAD ensures that the BUFF layer flushes if it will
     * have to block during a read.
     */
    ap_bsetflag(conn->client, B_SAFEREAD, 1);
    while ((len = getline(l, sizeof(l), conn->client, 0)) <= 0) {
        if ((len < 0) || ap_bgetflag(conn->client, B_EOF)) {
            ap_bsetflag(conn->client, B_SAFEREAD, 0);
	    /* this is a hack to make sure that request time is set,
	     * it's not perfect, but it's better than nothing 
	     */
	    r->request_time = time(0);
            return 0;
        }
    }
    /* we've probably got something to do, ignore graceful restart requests */
#ifdef SIGUSR1
    signal(SIGUSR1, SIG_IGN);
#endif

    ap_bsetflag(conn->client, B_SAFEREAD, 0);

    r->request_time = time(NULL);
    r->the_request = ap_pstrdup(r->pool, l);
    r->method = ap_getword_white(r->pool, &ll);
    uri = ap_getword_white(r->pool, &ll);

    /* Provide quick information about the request method as soon as known */

    r->method_number = ap_method_number_of(r->method);
    if (r->method_number == M_GET && r->method[0] == 'H') {
        r->header_only = 1;
    }

    ap_parse_uri(r, uri);

    /* getline returns (size of max buffer - 1) if it fills up the
     * buffer before finding the end-of-line.  This is only going to
     * happen if it exceeds the configured limit for a request-line.
     */
    if (len > r->server->limit_req_line) {
        r->status    = HTTP_REQUEST_URI_TOO_LARGE;
        r->proto_num = HTTP_VERSION(1,0);
        r->protocol  = ap_pstrdup(r->pool, "HTTP/1.0");
        return 0;
    }

    r->assbackwards = (ll[0] == '\0');
    r->protocol = ap_pstrdup(r->pool, ll[0] ? ll : "HTTP/0.9");

    if (2 == sscanf(r->protocol, "HTTP/%u.%u", &major, &minor)
      && minor < HTTP_VERSION(1,0))	/* don't allow HTTP/0.1000 */
	r->proto_num = HTTP_VERSION(major, minor);
    else
	r->proto_num = HTTP_VERSION(1,0);

    return 1;
}

static void get_mime_headers(request_rec *r)
{
    char field[DEFAULT_LIMIT_REQUEST_FIELDSIZE + 2]; /* getline's two extra */
    conn_rec *c = r->connection;
    char *value;
    char *copy;
    int len;
    unsigned int fields_read = 0;
    table *tmp_headers;

    /* We'll use ap_overlap_tables later to merge these into r->headers_in. */
    tmp_headers = ap_make_table(r->pool, 50);

    /*
     * Read header lines until we get the empty separator line, a read error,
     * the connection closes (EOF), reach the server limit, or we timeout.
     */
    while ((len = getline(field, sizeof(field), c->client, 1)) > 0) {

        if (r->server->limit_req_fields &&
            (++fields_read > r->server->limit_req_fields)) {
            r->status = HTTP_BAD_REQUEST;
            ap_table_setn(r->notes, "error-notes",
                          "The number of request header fields exceeds "
                          "this server's limit.<P>\n");
            return;
        }
        /* getline returns (size of max buffer - 1) if it fills up the
         * buffer before finding the end-of-line.  This is only going to
         * happen if it exceeds the configured limit for a field size.
         */
        if (len > r->server->limit_req_fieldsize) {
            r->status = HTTP_BAD_REQUEST;
            ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool,
                "Size of a request header field exceeds server limit.<P>\n"
                "<PRE>\n", field, "</PRE>\n", NULL));
            return;
        }
        copy = ap_palloc(r->pool, len + 1);
        memcpy(copy, field, len + 1);

        if (!(value = strchr(copy, ':'))) {     /* Find the colon separator */
            r->status = HTTP_BAD_REQUEST;       /* or abort the bad request */
            ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool,
                "Request header field is missing colon separator.<P>\n"
                "<PRE>\n", copy, "</PRE>\n", NULL));
            return;
        }

        *value = '\0';
        ++value;
        while (*value == ' ' || *value == '\t')
            ++value;            /* Skip to start of value   */

	ap_table_addn(tmp_headers, copy, value);
    }

    ap_overlap_tables(r->headers_in, tmp_headers, AP_OVERLAP_TABLES_MERGE);
}

request_rec *ap_read_request(conn_rec *conn)
{
    request_rec *r;
    pool *p;
    const char *expect;
    int access_status;

    p = ap_make_sub_pool(conn->pool);
    r = ap_pcalloc(p, sizeof(request_rec));
    r->pool            = p;
    r->connection      = conn;
    conn->server       = conn->base_server;
    r->server          = conn->server;

    conn->keptalive    = conn->keepalive == 1;
    conn->keepalive    = 0;

    conn->user         = NULL;
    conn->ap_auth_type    = NULL;

    r->headers_in      = ap_make_table(r->pool, 50);
    r->subprocess_env  = ap_make_table(r->pool, 50);
    r->headers_out     = ap_make_table(r->pool, 12);
    r->err_headers_out = ap_make_table(r->pool, 5);
    r->notes           = ap_make_table(r->pool, 5);

    r->request_config  = ap_create_request_config(r->pool);
    r->per_dir_config  = r->server->lookup_defaults;

    r->sent_bodyct     = 0;                      /* bytect isn't for body */

    r->read_length     = 0;
    r->read_body       = REQUEST_NO_BODY;

    r->status          = HTTP_REQUEST_TIME_OUT;  /* Until we get a request */
    r->the_request     = NULL;

#ifdef CHARSET_EBCDIC
    ap_bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 1);
#endif

    /* Get the request... */

    ap_keepalive_timeout("read request line", r);
    if (!read_request_line(r)) {
        ap_kill_timeout(r);
        if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {

            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                         "request failed: URI too long");
            ap_send_error_response(r, 0);
            ap_log_transaction(r);
            return r;
        }
        return NULL;
    }
    if (!r->assbackwards) {
        ap_hard_timeout("read request headers", r);
        get_mime_headers(r);
        ap_kill_timeout(r);
        if (r->status != HTTP_REQUEST_TIME_OUT) {
            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                         "request failed: error reading the headers");
            ap_send_error_response(r, 0);
            ap_log_transaction(r);
            return r;
        }
    }
    else {
        ap_kill_timeout(r);

        if (r->header_only) {
            /*
             * Client asked for headers only with HTTP/0.9, which doesn't send
             * headers! Have to dink things just to make sure the error message
             * comes through...
             */
            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                          "client sent invalid HTTP/0.9 request: HEAD %s",
                          r->uri);
            r->header_only = 0;
            r->status = HTTP_BAD_REQUEST;
            ap_send_error_response(r, 0);
            ap_log_transaction(r);
            return r;
        }
    }

    r->status = HTTP_OK;                         /* Until further notice. */

    /* update what we think the virtual host is based on the headers we've
     * now read
     */
    ap_update_vhost_from_headers(r);

    /* we may have switched to another server */
    r->per_dir_config = r->server->lookup_defaults;

    conn->keptalive = 0;        /* We now have a request to play with */

    if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1,1))) ||
        ((r->proto_num == HTTP_VERSION(1,1)) &&
         !ap_table_get(r->headers_in, "Host"))) {
        /*
         * Client sent us an HTTP/1.1 or later request without telling us the
         * hostname, either with a full URL or a Host: header. We therefore
         * need to (as per the 1.1 spec) send an error.  As a special case,
         * HTTP/1.1 mentions twice (S9, S14.23) that a request MUST contain
         * a Host: header, and the server MUST respond with 400 if it doesn't.
         */
        r->status = HTTP_BAD_REQUEST;
        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                      "client sent HTTP/1.1 request without hostname "
                      "(see RFC2068 section 9, and 14.23): %s", r->uri);
        ap_send_error_response(r, 0);
        ap_log_transaction(r);
        return r;
    }
    if (((expect = ap_table_get(r->headers_in, "Expect")) != NULL) &&
        (expect[0] != '\0')) {
        /*
         * The Expect header field was added to HTTP/1.1 after RFC 2068
         * as a means to signal when a 100 response is desired and,
         * unfortunately, to signal a poor man's mandatory extension that
         * the server must understand or return 417 Expectation Failed.
         */
        if (strcasecmp(expect, "100-continue") == 0) {
            r->expecting_100 = 1;
        }
        else {
            r->status = HTTP_EXPECTATION_FAILED;
            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, r,
                          "client sent an unrecognized expectation value of "
                          "Expect: %s", expect);
            ap_send_error_response(r, 0);
            (void) ap_discard_request_body(r);
            ap_log_transaction(r);
            return r;
        }
    }

    if ((access_status = ap_run_post_read_request(r))) {
        ap_die(access_status, r);
        ap_log_transaction(r);
        return NULL;
    }

    return r;
}

/*
 * A couple of other functions which initialize some of the fields of
 * a request structure, as appropriate for adjuncts of one kind or another
 * to a request in progress.  Best here, rather than elsewhere, since
 * *someone* has to set the protocol-specific fields...
 */

void ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r)
{
    rnew->the_request     = r->the_request;  /* Keep original request-line */

    rnew->assbackwards    = 1;   /* Don't send headers from this. */
    rnew->no_local_copy   = 1;   /* Don't try to send USE_LOCAL_COPY for a
                                  * fragment. */
    rnew->method          = "GET";
    rnew->method_number   = M_GET;
    rnew->protocol        = "INCLUDED";

    rnew->status          = HTTP_OK;

    rnew->headers_in      = r->headers_in;
    rnew->subprocess_env  = ap_copy_table(rnew->pool, r->subprocess_env);
    rnew->headers_out     = ap_make_table(rnew->pool, 5);
    rnew->err_headers_out = ap_make_table(rnew->pool, 5);
    rnew->notes           = ap_make_table(rnew->pool, 5);

    rnew->expecting_100   = r->expecting_100;
    rnew->read_length     = r->read_length;
    rnew->read_body       = REQUEST_NO_BODY;

    rnew->main = (request_rec *) r;
}

void ap_finalize_sub_req_protocol(request_rec *sub)
{
    SET_BYTES_SENT(sub->main);
}

/*
 * Support for the Basic authentication protocol, and a bit for Digest.
 */

API_EXPORT(void) ap_note_auth_failure(request_rec *r)
{
    if (!strcasecmp(ap_auth_type(r), "Basic"))
        ap_note_basic_auth_failure(r);
    else if (!strcasecmp(ap_auth_type(r), "Digest"))
        ap_note_digest_auth_failure(r);
}

API_EXPORT(void) ap_note_basic_auth_failure(request_rec *r)
{
    if (strcasecmp(ap_auth_type(r), "Basic"))
        ap_note_auth_failure(r);
    else
        ap_table_setn(r->err_headers_out,
                  r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
                  ap_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r), "\"",
                          NULL));
}

API_EXPORT(void) ap_note_digest_auth_failure(request_rec *r)
{
    ap_table_setn(r->err_headers_out,
	    r->proxyreq ? "Proxy-Authenticate" : "WWW-Authenticate",
	    ap_psprintf(r->pool, "Digest realm=\"%s\", nonce=\"%lu\"",
		ap_auth_name(r), r->request_time));
}

API_EXPORT(int) ap_get_basic_auth_pw(request_rec *r, const char **pw)
{
    const char *auth_line = ap_table_get(r->headers_in,
                                      r->proxyreq ? "Proxy-Authorization"
                                                  : "Authorization");
    const char *t;

    if (!(t = ap_auth_type(r)) || strcasecmp(t, "Basic"))
        return DECLINED;

    if (!ap_auth_name(r)) {
        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR,
		    r, "need AuthName: %s", r->uri);
        return SERVER_ERROR;
    }

    if (!auth_line) {
        ap_note_basic_auth_failure(r);
        return AUTH_REQUIRED;
    }

    if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) {
        /* Client tried to authenticate using wrong auth scheme */
        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                    "client used wrong authentication scheme: %s", r->uri);
        ap_note_basic_auth_failure(r);
        return AUTH_REQUIRED;
    }

    /* CHARSET_EBCDIC Issue's here ?!? Compare with 32/9 instead
     * as we are operating on an octed stream ?
     */
    while (*auth_line== ' ' || *auth_line== '\t')
        auth_line++;

    t = ap_pbase64decode(r->pool, auth_line);
    /* Note that this allocation has to be made from r->connection->pool
     * because it has the lifetime of the connection.  The other allocations
     * are temporary and can be tossed away any time.
     */
    r->connection->user = ap_getword_nulls (r->connection->pool, &t, ':');
    r->connection->ap_auth_type = "Basic";

    *pw = t;

    return OK;
}

/* New Apache routine to map status codes into array indicies
 *  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.
 */

#ifdef UTS21
/* The second const triggers an assembler bug on UTS 2.1.
 * Another workaround is to move some code out of this file into another,
 *   but this is easier.  Dave Dykstra, 3/31/99 
 */
static const char * status_lines[RESPONSE_CODES] =
#else
static const char * const status_lines[RESPONSE_CODES] =
#endif
{
    "100 Continue",
    "101 Switching Protocols",
    "102 Processing",
#define LEVEL_200  3
    "200 OK",
    "201 Created",
    "202 Accepted",
    "203 Non-Authoritative Information",
    "204 No Content",
    "205 Reset Content",
    "206 Partial Content",
    "207 Multi-Status",
#define LEVEL_300 11
    "300 Multiple Choices",
    "301 Moved Permanently",
    "302 Found",
    "303 See Other",
    "304 Not Modified",
    "305 Use Proxy",
    "306 unused",
    "307 Temporary Redirect",
#define LEVEL_400 19
    "400 Bad Request",
    "401 Authorization Required",
    "402 Payment Required",
    "403 Forbidden",
    "404 Not Found",
    "405 Method Not Allowed",
    "406 Not Acceptable",
    "407 Proxy Authentication Required",
    "408 Request Time-out",
    "409 Conflict",
    "410 Gone",
    "411 Length Required",
    "412 Precondition Failed",
    "413 Request Entity Too Large",
    "414 Request-URI Too Large",
    "415 Unsupported Media Type",
    "416 Requested Range Not Satisfiable",
    "417 Expectation Failed",
    "418 unused",
    "419 unused",
    "420 unused",
    "421 unused",
    "422 Unprocessable Entity",
    "423 Locked",
    "424 Failed Dependency",
#define LEVEL_500 44
    "500 Internal Server Error",
    "501 Method Not Implemented",
    "502 Bad Gateway",
    "503 Service Temporarily Unavailable",
    "504 Gateway Time-out",
    "505 HTTP Version Not Supported",
    "506 Variant Also Negotiates",
    "507 Insufficient Storage",
    "508 unused",
    "509 unused",
    "510 Not Extended"
};

/* 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];
 */
API_EXPORT(int) ap_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 LEVEL_500;

    for (i = 0; i < 5; i++) {
        status -= 100;
        if (status < 100) {
            pos = (status + shortcut[i]);
            if (pos < shortcut[i + 1])
                return pos;
            else
                return LEVEL_500;       /* status unknown (falls in gap) */
        }
    }
    return LEVEL_500;           /* 600 or above is also illegal */
}

/* Send a single HTTP header field to the client.  Note that this function
 * is used in calls to table_do(), so their interfaces are co-dependent.
 * In other words, don't change this one without checking table_do in alloc.c.
 * It returns true unless there was a write error of some kind.
 */
API_EXPORT_NONSTD(int) ap_send_header_field(request_rec *r,
    const char *fieldname, const char *fieldval)
{
    return (0 < ap_rvputs(r, fieldname, ": ", fieldval, "\015\012", NULL));
}

API_EXPORT(void) ap_basic_http_header(request_rec *r)
{
    char *protocol;
#ifdef CHARSET_EBCDIC
    int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
#endif /*CHARSET_EBCDIC*/

    if (r->assbackwards)
        return;

    if (!r->status_line)
        r->status_line = status_lines[ap_index_of_response(r->status)];

    /* mod_proxy is only HTTP/1.0, so avoid sending HTTP/1.1 error response;
     * kluge around broken browsers when indicated by force-response-1.0
     */
    if (r->proxyreq
        || (r->proto_num == HTTP_VERSION(1,0)
            && ap_table_get(r->subprocess_env, "force-response-1.0"))) {

        protocol = "HTTP/1.0";
        r->connection->keepalive = -1;
    }
    else
        protocol = SERVER_PROTOCOL;

#ifdef CHARSET_EBCDIC
    ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
#endif /*CHARSET_EBCDIC*/

    /* Output the HTTP/1.x Status-Line and the Date and Server fields */

    ap_rvputs(r, protocol, " ", r->status_line, "\015\012", NULL);

    ap_send_header_field(r, "Date", ap_gm_timestr_822(r->pool, r->request_time));
    ap_send_header_field(r, "Server", ap_get_server_version());

    ap_table_unset(r->headers_out, "Date");        /* Avoid bogosity */
    ap_table_unset(r->headers_out, "Server");
#ifdef CHARSET_EBCDIC
    if (!convert)
        ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
#endif /*CHARSET_EBCDIC*/
}

/* Navigator versions 2.x, 3.x and 4.0 betas up to and including 4.0b2
 * have a header parsing bug.  If the terminating \r\n occur starting
 * at offset 256, 257 or 258 of output then it will not properly parse
 * the headers.  Curiously it doesn't exhibit this problem at 512, 513.
 * We are guessing that this is because their initial read of a new request
 * uses a 256 byte buffer, and subsequent reads use a larger buffer.
 * So the problem might exist at different offsets as well.
 *
 * This should also work on keepalive connections assuming they use the
 * same small buffer for the first read of each new request.
 *
 * At any rate, we check the bytes written so far and, if we are about to
 * tickle the bug, we instead insert a bogus padding header.  Since the bug
 * manifests as a broken image in Navigator, users blame the server.  :(
 * It is more expensive to check the User-Agent than it is to just add the
 * bytes, so we haven't used the BrowserMatch feature here.
 */
static void terminate_header(BUFF *client)
{
    long int bs;

    ap_bgetopt(client, BO_BYTECT, &bs);
    if (bs >= 255 && bs <= 257)
        ap_bputs("X-Pad: avoid browser bug\015\012", client);

    ap_bputs("\015\012", client);  /* Send the terminating empty line */
}

/* Build the Allow field-value from the request handler method mask.
 * Note that we always allow TRACE, since it is handled below.
 */
static char *make_allow(request_rec *r)
{
    return 2 + ap_pstrcat(r->pool,
                   (r->allowed & (1 << M_GET))       ? ", GET, HEAD" : "",
                   (r->allowed & (1 << M_POST))      ? ", POST"      : "",
                   (r->allowed & (1 << M_PUT))       ? ", PUT"       : "",
                   (r->allowed & (1 << M_DELETE))    ? ", DELETE"    : "",
                   (r->allowed & (1 << M_CONNECT))   ? ", CONNECT"   : "",
                   (r->allowed & (1 << M_OPTIONS))   ? ", OPTIONS"   : "",
                   (r->allowed & (1 << M_PATCH))     ? ", PATCH"     : "",
                   (r->allowed & (1 << M_PROPFIND))  ? ", PROPFIND"  : "",
                   (r->allowed & (1 << M_PROPPATCH)) ? ", PROPPATCH" : "",
                   (r->allowed & (1 << M_MKCOL))     ? ", MKCOL"     : "",
                   (r->allowed & (1 << M_COPY))      ? ", COPY"      : "",
                   (r->allowed & (1 << M_MOVE))      ? ", MOVE"      : "",
                   (r->allowed & (1 << M_LOCK))      ? ", LOCK"      : "",
                   (r->allowed & (1 << M_UNLOCK))    ? ", UNLOCK"    : "",
                   ", TRACE",
                   NULL);
}

API_EXPORT(int) ap_send_http_trace(request_rec *r)
{
    int rv;

    /* Get the original request */
    while (r->prev)
        r = r->prev;

    if ((rv = ap_setup_client_block(r, REQUEST_NO_BODY)))
        return rv;

    ap_hard_timeout("send TRACE", r);

    r->content_type = "message/http";
    ap_send_http_header(r);

    /* Now we recreate the request, and echo it back */

    ap_rvputs(r, r->the_request, "\015\012", NULL);

    ap_table_do((int (*) (void *, const char *, const char *))
                ap_send_header_field, (void *) r, r->headers_in, NULL);
    ap_rputs("\015\012", r);

    ap_kill_timeout(r);
    return OK;
}

int ap_send_http_options(request_rec *r)
{
    const long int zero = 0L;

    if (r->assbackwards)
        return DECLINED;

    ap_hard_timeout("send OPTIONS", r);

    ap_basic_http_header(r);

    ap_table_setn(r->headers_out, "Content-Length", "0");
    ap_table_setn(r->headers_out, "Allow", make_allow(r));
    ap_set_keepalive(r);

    ap_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field,
             (void *) r, r->headers_out, NULL);

    terminate_header(r->connection->client);

    ap_kill_timeout(r);
    ap_bsetopt(r->connection->client, BO_BYTECT, &zero);

    return OK;
}

/*
 * Here we try to be compatible with clients that want multipart/x-byteranges
 * instead of multipart/byteranges (also see above), as per HTTP/1.1. We
 * look for the Request-Range header (e.g. Netscape 2 and 3) as an indication
 * that the browser supports an older protocol. We also check User-Agent
 * for Microsoft Internet Explorer 3, which needs this as well.
 */
static int use_range_x(request_rec *r)
{
    const char *ua;
    return (ap_table_get(r->headers_in, "Request-Range") ||
            ((ua = ap_table_get(r->headers_in, "User-Agent"))
             && strstr(ua, "MSIE 3")));
}

/* This routine is called by ap_table_do and merges all instances of
 * the passed field values into a single array that will be further
 * processed by some later routine.  Originally intended to help split
 * and recombine multiple Vary fields, though it is generic to any field
 * consisting of comma/space-separated tokens.
 */
static int uniq_field_values(void *d, const char *key, const char *val)
{
    array_header *values;
    char *start;
    char *e;
    char **strpp;
    int  i;

    values = (array_header *)d;

    e = ap_pstrdup(values->pool, val);

    do {
        /* Find a non-empty fieldname */

        while (*e == ',' || ap_isspace(*e)) {
            ++e;
        }
        if (*e == '\0') {
            break;
        }
        start = e;
        while (*e != '\0' && *e != ',' && !ap_isspace(*e)) {
            ++e;
        }
        if (*e != '\0') {
            *e++ = '\0';
        }

        /* Now add it to values if it isn't already represented.
         * Could be replaced by a ap_array_strcasecmp() if we had one.
         */
        for (i = 0, strpp = (char **) values->elts; i < values->nelts;
             ++i, ++strpp) {
            if (*strpp && strcasecmp(*strpp, start) == 0) {
                break;
            }
        }
        if (i == values->nelts) {  /* if not found */
           *(char **)ap_push_array(values) = start;
        }
    } while (*e != '\0');

    return 1;
}

/*
 * Since some clients choke violently on multiple Vary fields, or
 * Vary fields with duplicate tokens, combine any multiples and remove
 * any duplicates.
 */
static void fixup_vary(request_rec *r)
{
    array_header *varies;

    varies = ap_make_array(r->pool, 5, sizeof(char *));

    /* Extract all Vary fields from the headers_out, separate each into
     * its comma-separated fieldname values, and then add them to varies
     * if not already present in the array.
     */
    ap_table_do((int (*)(void *, const char *, const char *))uniq_field_values,
		(void *) varies, r->headers_out, "Vary", NULL);

    /* If we found any, replace old Vary fields with unique-ified value */

    if (varies->nelts > 0) {
	ap_table_setn(r->headers_out, "Vary",
		      ap_array_pstrcat(r->pool, varies, ','));
    }
}

API_EXPORT(void) ap_send_http_header(request_rec *r)
{
    int i;
    const long int zero = 0L;
#ifdef CHARSET_EBCDIC
    int convert = ap_bgetflag(r->connection->client, B_EBCDIC2ASCII);
#endif /*CHARSET_EBCDIC*/

    if (r->assbackwards) {
        if (!r->main)
            ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
        r->sent_bodyct = 1;
        return;
    }

    /*
     * Now that we are ready to send a response, we need to combine the two
     * header field tables into a single table.  If we don't do this, our
     * later attempts to set or unset a given fieldname might be bypassed.
     */
    if (!ap_is_empty_table(r->err_headers_out))
        r->headers_out = ap_overlay_tables(r->pool, r->err_headers_out,
                                        r->headers_out);

    /*
     * Remove the 'Vary' header field if the client can't handle it.
     * Since this will have nasty effects on HTTP/1.1 caches, force
     * the response into HTTP/1.0 mode.
     */
    if (ap_table_get(r->subprocess_env, "force-no-vary") != NULL) {
	ap_table_unset(r->headers_out, "Vary");
	r->proto_num = HTTP_VERSION(1,0);
	ap_table_set(r->subprocess_env, "force-response-1.0", "1");
    }
    else {
	fixup_vary(r);
    }

    ap_hard_timeout("send headers", r);

    ap_basic_http_header(r);

#ifdef CHARSET_EBCDIC
    ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
#endif /*CHARSET_EBCDIC*/

    ap_set_keepalive(r);

    if (r->chunked) {
        ap_table_mergen(r->headers_out, "Transfer-Encoding", "chunked");
        ap_table_unset(r->headers_out, "Content-Length");
    }

    if (r->byterange > 1)
        ap_table_setn(r->headers_out, "Content-Type",
                  ap_pstrcat(r->pool, "multipart", use_range_x(r) ? "/x-" : "/",
                          "byteranges; boundary=", r->boundary, NULL));
    else if (r->content_type)
        ap_table_setn(r->headers_out, "Content-Type", r->content_type);
    else
        ap_table_setn(r->headers_out, "Content-Type", ap_default_type(r));

    if (r->content_encoding)
        ap_table_setn(r->headers_out, "Content-Encoding", r->content_encoding);

    if (r->content_languages && r->content_languages->nelts) {
        for (i = 0; i < r->content_languages->nelts; ++i) {
            ap_table_mergen(r->headers_out, "Content-Language",
                        ((char **) (r->content_languages->elts))[i]);
        }
    }
    else if (r->content_language)
        ap_table_setn(r->headers_out, "Content-Language", r->content_language);

    /*
     * Control cachability for non-cachable responses if not already set by
     * some other part of the server configuration.
     */
    if (r->no_cache && !ap_table_get(r->headers_out, "Expires"))
        ap_table_addn(r->headers_out, "Expires",
                  ap_gm_timestr_822(r->pool, r->request_time));

    /* Send the entire table of header fields, terminated by an empty line. */

    ap_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field,
             (void *) r, r->headers_out, NULL);

    terminate_header(r->connection->client);

    ap_kill_timeout(r);

    ap_bsetopt(r->connection->client, BO_BYTECT, &zero);
    r->sent_bodyct = 1;         /* Whatever follows is real body stuff... */

    /* Set buffer flags for the body */
    if (r->chunked)
        ap_bsetflag(r->connection->client, B_CHUNK, 1);
#ifdef CHARSET_EBCDIC
    if (!convert)
        ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
#endif /*CHARSET_EBCDIC*/
}

/* finalize_request_protocol is called at completion of sending the
 * response.  It's sole purpose is to send the terminating protocol
 * information for any wrappers around the response message body
 * (i.e., transfer encodings).  It should have been named finalize_response.
 */
API_EXPORT(void) ap_finalize_request_protocol(request_rec *r)
{
    if (r->chunked && !r->connection->aborted) {
        /*
         * Turn off chunked encoding --- we can only do this once.
         */
        r->chunked = 0;
        ap_bsetflag(r->connection->client, B_CHUNK, 0);

        ap_soft_timeout("send ending chunk", r);
        ap_rputs("0\015\012", r);
        /* If we had footer "headers", we'd send them now */
        ap_rputs("\015\012", r);
        ap_kill_timeout(r);
    }
}

/* Here we deal with getting the request message body from the client.
 * Whether or not the request contains a body is signaled by the presence
 * of a non-zero Content-Length or by a Transfer-Encoding: chunked.
 *
 * Note that this is more complicated than it was in Apache 1.1 and prior
 * versions, because chunked support means that the module does less.
 *
 * The proper procedure is this:
 *
 * 1. Call setup_client_block() near the beginning of the request
 *    handler. This will set up all the necessary properties, and will
 *    return either OK, or an error code. If the latter, the module should
 *    return that error code. The second parameter selects the policy to
 *    apply if the request message indicates a body, and how a chunked
 *    transfer-coding should be interpreted. Choose one of
 *
 *    REQUEST_NO_BODY          Send 413 error if message has any body
 *    REQUEST_CHUNKED_ERROR    Send 411 error if body without Content-Length
 *    REQUEST_CHUNKED_DECHUNK  If chunked, remove the chunks for me.
 *    REQUEST_CHUNKED_PASS     Pass the chunks to me without removal.
 *
 *    In order to use the last two options, the caller MUST provide a buffer
 *    large enough to hold a chunk-size line, including any extensions.
 *
 * 2. When you are ready to read a body (if any), call should_client_block().
 *    This will tell the module whether or not to read input. If it is 0,
 *    the module should assume that there is no message body to read.
 *    This step also sends a 100 Continue response to HTTP/1.1 clients,
 *    so should not be called until the module is *definitely* ready to
 *    read content. (otherwise, the point of the 100 response is defeated).
 *    Never call this function more than once.
 *
 * 3. Finally, call get_client_block in a loop. Pass it a buffer and its size.
 *    It will put data into the buffer (not necessarily a full buffer), and
 *    return the length of the input block. When it is done reading, it will
 *    return 0 if EOF, or -1 if there was an error.
 *    If an error occurs on input, we force an end to keepalive.
 */

API_EXPORT(int) ap_setup_client_block(request_rec *r, int read_policy)
{
    const char *tenc = ap_table_get(r->headers_in, "Transfer-Encoding");
    const char *lenp = ap_table_get(r->headers_in, "Content-Length");
    unsigned long max_body;

    r->read_body = read_policy;
    r->read_chunked = 0;
    r->remaining = 0;

    if (tenc) {
        if (strcasecmp(tenc, "chunked")) {
            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                        "Unknown Transfer-Encoding %s", tenc);
            return HTTP_NOT_IMPLEMENTED;
        }
        if (r->read_body == REQUEST_CHUNKED_ERROR) {
            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                        "chunked Transfer-Encoding forbidden: %s", r->uri);
            return (lenp) ? HTTP_BAD_REQUEST : HTTP_LENGTH_REQUIRED;
        }

        r->read_chunked = 1;
    }
    else if (lenp) {
        const char *pos = lenp;

        while (ap_isdigit(*pos) || ap_isspace(*pos))
            ++pos;
        if (*pos != '\0') {
            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                        "Invalid Content-Length %s", lenp);
            return HTTP_BAD_REQUEST;
        }

        r->remaining = atol(lenp);
    }

    if ((r->read_body == REQUEST_NO_BODY) &&
        (r->read_chunked || (r->remaining > 0))) {
        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
                    "%s with body is not allowed for %s", r->method, r->uri);
        return HTTP_REQUEST_ENTITY_TOO_LARGE;
    }

    max_body = ap_get_limit_req_body(r);
    if (max_body && (r->remaining > max_body)) {
        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
          "Request content-length of %s is larger than the configured "
          "limit of %lu", lenp, max_body);
        return HTTP_REQUEST_ENTITY_TOO_LARGE;
    }

    return OK;
}

API_EXPORT(int) ap_should_client_block(request_rec *r)
{
    /* First check if we have already read the request body */

    if (r->read_length || (!r->read_chunked && (r->remaining <= 0)))
        return 0;

    if (r->expecting_100 && r->proto_num >= HTTP_VERSION(1,1)) {
        /* sending 100 Continue interim response */
        ap_rvputs(r, SERVER_PROTOCOL, " ", status_lines[0], "\015\012\015\012",
                  NULL);
        ap_rflush(r);
    }

    return 1;
}

static long get_chunk_size(char *b)
{
    long chunksize = 0;

    while (ap_isxdigit(*b)) {
        int xvalue = 0;

        if (*b >= '0' && *b <= '9')
            xvalue = *b - '0';
        else if (*b >= 'A' && *b <= 'F')
            xvalue = *b - 'A' + 0xa;
        else if (*b >= 'a' && *b <= 'f')
            xvalue = *b - 'a' + 0xa;

        chunksize = (chunksize << 4) | xvalue;
        ++b;
    }

    return chunksize;
}

/* get_client_block is called in a loop to get the request message body.
 * This is quite simple if the client includes a content-length
 * (the normal case), but gets messy if the body is chunked. Note that
 * r->remaining is used to maintain state across calls and that
 * r->read_length is the total number of bytes given to the caller
 * across all invocations.  It is messy because we have to be careful not
 * to read past the data provided by the client, since these reads block.
 * Returns 0 on End-of-body, -1 on error or premature chunk end.
 *
 * Reading the chunked encoding requires a buffer size large enough to
 * hold a chunk-size line, including any extensions. For now, we'll leave
 * that to the caller, at least until we can come up with a better solution.
 */
API_EXPORT(long) ap_get_client_block(request_rec *r, char *buffer, int bufsiz)
{
    int c;
    long len_read, len_to_read;
    long chunk_start = 0;
    unsigned long max_body;

    if (!r->read_chunked) {     /* Content-length read */
        len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
        len_read = ap_bread(r->connection->client, buffer, len_to_read);
        if (len_read <= 0) {
            if (len_read < 0)
                r->connection->keepalive = -1;
            return len_read;
        }
        r->read_length += len_read;
        r->remaining -= len_read;
        return len_read;
    }

    /*
     * Handle chunked reading Note: we are careful to shorten the input
     * bufsiz so that there will always be enough space for us to add a CRLF
     * (if necessary).
     */
    if (r->read_body == REQUEST_CHUNKED_PASS)
        bufsiz -= 2;
    if (bufsiz <= 0)
        return -1;              /* Cannot read chunked with a small buffer */

    /* Check to see if we have already read too much request data.
     * For efficiency reasons, we only check this at the top of each
     * caller read pass, since the limit exists just to stop infinite
     * length requests and nobody cares if it goes over by one buffer.
     */
    max_body = ap_get_limit_req_body(r);
    if (max_body && (r->read_length > max_body)) {
        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
            "Chunked request body is larger than the configured limit of %lu",
            max_body);
        r->connection->keepalive = -1;
        return -1;
    }

    if (r->remaining == 0) {    /* Start of new chunk */

        chunk_start = getline(buffer, bufsiz, r->connection->client, 0);
        if ((chunk_start <= 0) || (chunk_start >= (bufsiz - 1))
            || !ap_isxdigit(*buffer)) {
            r->connection->keepalive = -1;
            return -1;
        }

        len_to_read = get_chunk_size(buffer);

        if (len_to_read == 0) { /* Last chunk indicated, get footers */
            if (r->read_body == REQUEST_CHUNKED_DECHUNK) {
                get_mime_headers(r);
                ap_snprintf(buffer, bufsiz, "%ld", r->read_length);
                ap_table_unset(r->headers_in, "Transfer-Encoding");
                ap_table_setn(r->headers_in, "Content-Length",
                    ap_pstrdup(r->pool, buffer));
                return 0;
            }
            r->remaining = -1;  /* Indicate footers in-progress */
        }
        else {
            r->remaining = len_to_read;
        }
        if (r->read_body == REQUEST_CHUNKED_PASS) {
            buffer[chunk_start++] = CR; /* Restore chunk-size line end  */
            buffer[chunk_start++] = LF;
            buffer += chunk_start;      /* and pass line on to caller   */
            bufsiz -= chunk_start;
        }
        else {
            /* REQUEST_CHUNKED_DECHUNK -- do not include the length of the
             * header in the return value
             */
            chunk_start = 0;
        }
    }
                                /* When REQUEST_CHUNKED_PASS, we are */
    if (r->remaining == -1) {   /* reading footers until empty line  */
        len_read = chunk_start;

        while ((bufsiz > 1) && ((len_read =
                  getline(buffer, bufsiz, r->connection->client, 1)) > 0)) {

            if (len_read != (bufsiz - 1)) {
                buffer[len_read++] = CR;        /* Restore footer line end  */
                buffer[len_read++] = LF;
            }
            chunk_start += len_read;
            buffer += len_read;
            bufsiz -= len_read;
        }
        if (len_read < 0) {
            r->connection->keepalive = -1;
            return -1;
        }

        if (len_read == 0) {    /* Indicates an empty line */
            buffer[0] = CR;
            buffer[1] = LF;
            chunk_start += 2;
            r->remaining = -2;
        }
        r->read_length += chunk_start;
        return chunk_start;
    }
                                /* When REQUEST_CHUNKED_PASS, we     */
    if (r->remaining == -2) {   /* finished footers when last called */
        r->remaining = 0;       /* so now we must signal EOF         */
        return 0;
    }

    /* Otherwise, we are in the midst of reading a chunk of data */

    len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;

    len_read = ap_bread(r->connection->client, buffer, len_to_read);
    if (len_read <= 0) {
        r->connection->keepalive = -1;
        return -1;
    }

    r->remaining -= len_read;

    if (r->remaining == 0) {    /* End of chunk, get trailing CRLF */
        if ((c = ap_bgetc(r->connection->client)) == CR) {
            c = ap_bgetc(r->connection->client);
        }
        if (c != LF) {
            r->connection->keepalive = -1;
            return -1;
        }
        if (r->read_body == REQUEST_CHUNKED_PASS) {
            buffer[len_read++] = CR;
            buffer[len_read++] = LF;
        }
    }
    r->read_length += (chunk_start + len_read);

    return (chunk_start + len_read);
}

/* In HTTP/1.1, any method can have a body.  However, most GET handlers
 * wouldn't know what to do with a request body if they received one.
 * This helper routine tests for and reads any message body in the request,
 * simply discarding whatever it receives.  We need to do this because
 * failing to read the request body would cause it to be interpreted
 * as the next request on a persistent connection.
 *
 * Since we return an error status if the request is malformed, this
 * routine should be called at the beginning of a no-body handler, e.g.,
 *
 *    if ((retval = ap_discard_request_body(r)) != OK)
 *        return retval;
 */
API_EXPORT(int) ap_discard_request_body(request_rec *r)
{
    int rv;

    if ((rv = ap_setup_client_block(r, REQUEST_CHUNKED_PASS)))
        return rv;

    /* In order to avoid sending 100 Continue when we already know the
     * final response status, and yet not kill the connection if there is
     * no request body to be read, we need to duplicate the test from
     * ap_should_client_block() here negated rather than call it directly.
     */
    if ((r->read_length == 0) && (r->read_chunked || (r->remaining > 0))) {
        char dumpbuf[HUGE_STRING_LEN];

        if (r->expecting_100) {
            r->connection->keepalive = -1;
            return OK;
        }
        ap_hard_timeout("reading request body", r);
        while ((rv = ap_get_client_block(r, dumpbuf, HUGE_STRING_LEN)) > 0)
            continue;
        ap_kill_timeout(r);

        if (rv < 0)
            return HTTP_BAD_REQUEST;
    }
    return OK;
}

/*
 * Send the body of a response to the client.
 */
API_EXPORT(long) ap_send_fd(FILE *f, request_rec *r)
{
    return ap_send_fd_length(f, r, -1);
}

API_EXPORT(long) ap_send_fd_length(FILE *f, request_rec *r, long length)
{
    char buf[IOBUFSIZE];
    long total_bytes_sent = 0;
    register int n, w, o, len;

    if (length == 0)
        return 0;

    ap_soft_timeout("send body", r);

    while (!r->connection->aborted) {
        if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
            len = length - total_bytes_sent;
        else
            len = IOBUFSIZE;

        while ((n = fread(buf, sizeof(char), len, f)) < 1
               && ferror(f) && errno == EINTR && !r->connection->aborted)
            continue;

        if (n < 1) {
            break;
        }
        o = 0;

        while (n && !r->connection->aborted) {
            w = ap_bwrite(r->connection->client, &buf[o], n);
            if (w > 0) {
                ap_reset_timeout(r); /* reset timeout after successful write */
                total_bytes_sent += w;
                n -= w;
                o += w;
            }
            else if (w < 0) {
                if (!r->connection->aborted) {
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
                     "client stopped connection before send body completed");
                    ap_bsetflag(r->connection->client, B_EOUT, 1);
                    r->connection->aborted = 1;
                }
                break;
            }
        }
    }

    ap_kill_timeout(r);
    SET_BYTES_SENT(r);
    return total_bytes_sent;
}

/*
 * Send the body of a response to the client.
 */
API_EXPORT(long) ap_send_fb(BUFF *fb, request_rec *r)
{
    return ap_send_fb_length(fb, r, -1);
}

API_EXPORT(long) ap_send_fb_length(BUFF *fb, request_rec *r, long length)
{
    char buf[IOBUFSIZE];
    long total_bytes_sent = 0;
    register int n, w, o, len, fd;
    fd_set fds;

    if (length == 0)
        return 0;

    /* Make fb unbuffered and non-blocking */
    ap_bsetflag(fb, B_RD, 0);
#ifndef TPF    
    ap_bnonblock(fb, B_RD);
#endif
    fd = ap_bfileno(fb, B_RD);
#ifdef CHECK_FD_SETSIZE
    if (fd >= FD_SETSIZE) {
	ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL,
	    "send body: filedescriptor (%u) larger than FD_SETSIZE (%u) "
	    "found, you probably need to rebuild Apache with a "
	    "larger FD_SETSIZE", fd, FD_SETSIZE);
	return 0;
    }
#endif

    ap_soft_timeout("send body", r);

    FD_ZERO(&fds);
    while (!r->connection->aborted) {
#ifdef NDELAY_PIPE_RETURNS_ZERO
	/* Contributed by dwd@bell-labs.com for UTS 2.1.2, where the fcntl */
	/*   O_NDELAY flag causes read to return 0 when there's nothing */
	/*   available when reading from a pipe.  That makes it tricky */
	/*   to detect end-of-file :-(.  This stupid bug is even documented */
	/*   in the read(2) man page where it says that everything but */
	/*   pipes return -1 and EAGAIN.  That makes it a feature, right? */
	int afterselect = 0;
#endif
        if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
            len = length - total_bytes_sent;
        else
            len = IOBUFSIZE;

        do {
            n = ap_bread(fb, buf, len);
#ifdef NDELAY_PIPE_RETURNS_ZERO
	    if ((n > 0) || (n == 0 && afterselect))
		break;
#else
            if (n >= 0)
                break;
#endif
            if (r->connection->aborted)
                break;
            if (n < 0 && errno != EAGAIN)
                break;

            /* we need to block, so flush the output first */
            if (ap_bflush(r->connection->client) < 0) {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
                    "client stopped connection before send body completed");
                ap_bsetflag(r->connection->client, B_EOUT, 1);
                r->connection->aborted = 1;
                break;
            }
            FD_SET(fd, &fds);
            /*
             * we don't care what select says, we might as well loop back
             * around and try another read
             */
            ap_select(fd + 1, &fds, NULL, NULL, NULL);
#ifdef NDELAY_PIPE_RETURNS_ZERO
	    afterselect = 1;
#endif
        } while (!r->connection->aborted);

        if (n < 1 || r->connection->aborted) {
            break;
        }
        o = 0;

        while (n && !r->connection->aborted) {
            w = ap_bwrite(r->connection->client, &buf[o], n);
            if (w > 0) {
                ap_reset_timeout(r); /* reset timeout after successful write */
                total_bytes_sent += w;
                n -= w;
                o += w;
            }
            else if (w < 0) {
                if (!r->connection->aborted) {
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
                       "client stopped connection before send body completed");
                    ap_bsetflag(r->connection->client, B_EOUT, 1);
                    r->connection->aborted = 1;
                }
                break;
            }
        }
    }

    ap_kill_timeout(r);
    SET_BYTES_SENT(r);
    return total_bytes_sent;
}



/* The code writes MMAP_SEGMENT_SIZE bytes at a time.  This is due to Apache's
 * timeout model, which is a timeout per-write rather than a time for the
 * entire transaction to complete.  Essentially this should be small enough
 * so that in one Timeout period, your slowest clients should be reasonably
 * able to receive this many bytes.
 *
 * To take advantage of zero-copy TCP under Solaris 2.6 this should be a
 * multiple of 16k.  (And you need a SunATM2.0 network card.)
 */
#ifndef MMAP_SEGMENT_SIZE
#define MMAP_SEGMENT_SIZE       32768
#endif

/* send data from an in-memory buffer */
API_EXPORT(size_t) ap_send_mmap(void *mm, request_rec *r, size_t offset,
                             size_t length)
{
    size_t total_bytes_sent = 0;
    int n, w;

    if (length == 0)
        return 0;

    ap_soft_timeout("send mmap", r);

    length += offset;
    while (!r->connection->aborted && offset < length) {
        if (length - offset > MMAP_SEGMENT_SIZE) {
            n = MMAP_SEGMENT_SIZE;
        }
        else {
            n = length - offset;
        }

        while (n && !r->connection->aborted) {
            w = ap_bwrite(r->connection->client, (char *) mm + offset, n);
            if (w > 0) {
                ap_reset_timeout(r); /* reset timeout after successful write */
                total_bytes_sent += w;
                n -= w;
                offset += w;
            }
            else if (w < 0) {
                if (!r->connection->aborted) {
                    ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
                       "client stopped connection before send mmap completed");
                    ap_bsetflag(r->connection->client, B_EOUT, 1);
                    r->connection->aborted = 1;
                }
                break;
            }
        }
    }

    ap_kill_timeout(r);
    SET_BYTES_SENT(r);
    return total_bytes_sent;
}

API_EXPORT(int) ap_rputc(int c, request_rec *r)
{
    if (r->connection->aborted)
        return EOF;

    if (ap_bputc(c, r->connection->client) < 0) {
        if (!r->connection->aborted) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
                "client stopped connection before rputc completed");
            ap_bsetflag(r->connection->client, B_EOUT, 1);
            r->connection->aborted = 1;
        }
        return EOF;
    }
    SET_BYTES_SENT(r);
    return c;
}

API_EXPORT(int) ap_rputs(const char *str, request_rec *r)
{
    int rcode;

    if (r->connection->aborted)
        return EOF;
    
    rcode = ap_bputs(str, r->connection->client);
    if (rcode < 0) {
        if (!r->connection->aborted) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
                "client stopped connection before rputs completed");
            ap_bsetflag(r->connection->client, B_EOUT, 1);
            r->connection->aborted = 1;
        }
        return EOF;
    }
    SET_BYTES_SENT(r);
    return rcode;
}

API_EXPORT(int) ap_rwrite(const void *buf, int nbyte, request_rec *r)
{
    int n;

    if (r->connection->aborted)
        return -1;

    n = ap_bwrite(r->connection->client, buf, nbyte);
    if (n < 0) {
        if (!r->connection->aborted) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
                "client stopped connection before rwrite completed");
            ap_bsetflag(r->connection->client, B_EOUT, 1);
            r->connection->aborted = 1;
        }
        return -1;
    }
    SET_BYTES_SENT(r);
    return n;
}

API_EXPORT(int) ap_vrprintf(request_rec *r, const char *fmt, va_list ap)
{
    int n;

    if (r->connection->aborted)
        return -1;

    n = ap_vbprintf(r->connection->client, fmt, ap);

    if (n < 0) {
        if (!r->connection->aborted) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
                "client stopped connection before vrprintf completed");
            ap_bsetflag(r->connection->client, B_EOUT, 1);
            r->connection->aborted = 1;
        }
        return -1;
    }
    SET_BYTES_SENT(r);
    return n;
}

API_EXPORT(int) ap_rprintf(request_rec *r, const char *fmt,...)
{
    va_list vlist;
    int n;

    if (r->connection->aborted)
        return -1;

    va_start(vlist, fmt);
    n = ap_vbprintf(r->connection->client, fmt, vlist);
    va_end(vlist);

    if (n < 0) {
        if (!r->connection->aborted) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
                "client stopped connection before rprintf completed");
            ap_bsetflag(r->connection->client, B_EOUT, 1);
            r->connection->aborted = 1;
        }
        return -1;
    }
    SET_BYTES_SENT(r);
    return n;
}

API_EXPORT_NONSTD(int) ap_rvputs(request_rec *r,...)
{
    va_list args;
    int i, j, k;
    const char *x;
    BUFF *fb = r->connection->client;

    if (r->connection->aborted)
        return EOF;

    va_start(args, r);
    for (k = 0;;) {
        x = va_arg(args, const char *);
        if (x == NULL)
            break;
        j = strlen(x);
        i = ap_bwrite(fb, x, j);
        if (i != j) {
            va_end(args);
            if (!r->connection->aborted) {
                ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
                    "client stopped connection before rvputs completed");
                ap_bsetflag(r->connection->client, B_EOUT, 1);
                r->connection->aborted = 1;
            }
            return EOF;
        }
        k += i;
    }
    va_end(args);

    SET_BYTES_SENT(r);
    return k;
}

API_EXPORT(int) ap_rflush(request_rec *r)
{
    if (ap_bflush(r->connection->client) < 0) {
        if (!r->connection->aborted) {
            ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
                "client stopped connection before rflush completed");
            ap_bsetflag(r->connection->client, B_EOUT, 1);
            r->connection->aborted = 1;
        }
        return EOF;
    }
    return 0;
}

/* 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.
 */
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 = ap_table_get(r->headers_out, "Location");

    /*
     * 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 = ap_table_get(r->err_headers_out, "Location");
    }
    /* 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 (status == HTTP_NOT_MODIFIED) {
        if (!ap_is_empty_table(r->err_headers_out))
            r->headers_out = ap_overlay_tables(r->pool, r->err_headers_out,
                                               r->headers_out);
        ap_hard_timeout("send 304", r);

        ap_basic_http_header(r);
        ap_set_keepalive(r);

        ap_table_do((int (*)(void *, const char *, const char *)) ap_send_header_field,
                    (void *) r, r->headers_out,
                    "Connection",
                    "Keep-Alive",
                    "ETag",
                    "Content-Location",
                    "Expires",
                    "Cache-Control",
                    "Vary",
                    "Warning",
                    "WWW-Authenticate",
                    "Proxy-Authenticate",
                    NULL);

        terminate_header(r->connection->client);

        ap_kill_timeout(r);
        return;
    }

    if (status == HTTP_NO_CONTENT) {
        ap_send_http_header(r);
        ap_finalize_request_protocol(r);
        return;
    }

    if (!r->assbackwards) {
        table *tmp = r->headers_out;

        /* 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.
         */
        r->headers_out = r->err_headers_out;
        r->err_headers_out = tmp;
        ap_clear_table(r->err_headers_out);

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

        r->content_language = NULL;
        r->content_languages = NULL;
        r->content_encoding = NULL;
        r->clength = 0;
        r->content_type = "text/html";

        if ((status == METHOD_NOT_ALLOWED) || (status == NOT_IMPLEMENTED))
            ap_table_setn(r->headers_out, "Allow", make_allow(r));

        ap_send_http_header(r);

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

    ap_hard_timeout("send error body", r);

    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 doesn't, we've got a recursive error, so find
         * the original error and output that as well.
         */
        if (custom_response[0] == '\"') {
            ap_rputs(custom_response + 1, r);
            ap_kill_timeout(r);
            ap_finalize_request_protocol(r);
            ap_rflush(r);
            return;
        }
        /*
         * Redirect failed, so get back the original error
         */
        while (r->prev && (r->prev->status != HTTP_OK))
            r = r->prev;
    }
    {
        const char *title = status_lines[idx];
        const char *h1;
        const char *error_notes;

        /* Accept a status_line set by a module, but only if it begins
         * with the 3 digit status code
         */
        if (r->status_line != NULL
            && strlen(r->status_line) > 4       /* long enough */
            && ap_isdigit(r->status_line[0])
            && ap_isdigit(r->status_line[1])
            && ap_isdigit(r->status_line[2])
            && ap_isspace(r->status_line[3])
            && ap_isalnum(r->status_line[4])) {
            title = r->status_line;
        }

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

        ap_rvputs(r,
                  DOCTYPE_HTML_2_0
                  "<HTML><HEAD>\n<TITLE>", title,
                  "</TITLE>\n</HEAD><BODY>\n<H1>", h1, "</H1>\n",
                  NULL);

	switch (status) {
	case HTTP_MOVED_PERMANENTLY:
	case HTTP_MOVED_TEMPORARILY:
	case HTTP_TEMPORARY_REDIRECT:
	    ap_rvputs(r, "The document has moved <A HREF=\"",
		      ap_escape_html(r->pool, location), "\">here</A>.<P>\n",
		      NULL);
	    break;
	case HTTP_SEE_OTHER:
	    ap_rvputs(r, "The answer to your request is located <A HREF=\"",
		      ap_escape_html(r->pool, location), "\">here</A>.<P>\n",
		      NULL);
	    break;
	case HTTP_USE_PROXY:
	    ap_rvputs(r, "This resource is only accessible "
		      "through the proxy\n",
		      ap_escape_html(r->pool, location),
		      "<BR>\nYou will need to ",
		      "configure your client to use that proxy.<P>\n", NULL);
	    break;
	case HTTP_PROXY_AUTHENTICATION_REQUIRED:
	case AUTH_REQUIRED:
	    ap_rputs("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", r);
	    break;
	case BAD_REQUEST:
	    ap_rputs("Your browser sent a request that "
	             "this server could not understand.<P>\n", r);
	    if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
		ap_rvputs(r, error_notes, "<P>\n", NULL);
	    }
	    break;
	case HTTP_FORBIDDEN:
	    ap_rvputs(r, "You don't have permission to access ",
		      ap_escape_html(r->pool, r->uri),
		      "\non this server.<P>\n", NULL);
	    break;
	case NOT_FOUND:
	    ap_rvputs(r, "The requested URL ",
		      ap_escape_html(r->pool, r->uri),
		      " was not found on this server.<P>\n", NULL);
	    break;
	case METHOD_NOT_ALLOWED:
	    ap_rvputs(r, "The requested method ", r->method,
		      " is not allowed "
		      "for the URL ", ap_escape_html(r->pool, r->uri),
		      ".<P>\n", NULL);
	    break;
	case NOT_ACCEPTABLE:
	    ap_rvputs(r,
		      "An appropriate representation of the "
		      "requested resource ",
		      ap_escape_html(r->pool, r->uri),
		      " could not be found on this server.<P>\n", NULL);
	    /* fall through */
	case MULTIPLE_CHOICES:
	    {
		const char *list;
		if ((list = ap_table_get(r->notes, "variant-list")))
		    ap_rputs(list, r);
	    }
	    break;
	case LENGTH_REQUIRED:
	    ap_rvputs(r, "A request of the requested method ", r->method,
		      " requires a valid Content-length.<P>\n", NULL);
	    if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
		ap_rvputs(r, error_notes, "<P>\n", NULL);
	    }
	    break;
	case PRECONDITION_FAILED:
	    ap_rvputs(r, "The precondition on the request for the URL ",
		      ap_escape_html(r->pool, r->uri),
		      " evaluated to false.<P>\n", NULL);
	    break;
	case HTTP_NOT_IMPLEMENTED:
	    ap_rvputs(r, ap_escape_html(r->pool, r->method), " to ",
		      ap_escape_html(r->pool, r->uri),
		      " not supported.<P>\n", NULL);
	    if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
		ap_rvputs(r, error_notes, "<P>\n", NULL);
	    }
	    break;
	case BAD_GATEWAY:
	    ap_rputs("The proxy server received an invalid\015\012"
	             "response from an upstream server.<P>\015\012", r);
	    if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
		ap_rvputs(r, error_notes, "<P>\n", NULL);
	    }
	    break;
	case VARIANT_ALSO_VARIES:
	    ap_rvputs(r, "A variant for the requested resource\n<PRE>\n",
		      ap_escape_html(r->pool, r->uri),
		      "\n</PRE>\nis itself a negotiable resource. "
		      "This indicates a configuration error.<P>\n", NULL);
	    break;
	case HTTP_REQUEST_TIME_OUT:
	    ap_rputs("I'm tired of waiting for your request.\n", r);
	    break;
	case HTTP_GONE:
	    ap_rvputs(r, "The requested resource<BR>",
		      ap_escape_html(r->pool, r->uri),
		      "<BR>\nis no longer available on this server ",
		      "and there is no forwarding address.\n",
		      "Please remove all references to this resource.\n",
		      NULL);
	    break;
	case HTTP_REQUEST_ENTITY_TOO_LARGE:
	    ap_rvputs(r, "The requested resource<BR>",
		      ap_escape_html(r->pool, r->uri), "<BR>\n",
		      "does not allow request data with ", r->method,
		      " requests, or the amount of data provided in\n",
		      "the request exceeds the capacity limit.\n", NULL);
	    break;
	case HTTP_REQUEST_URI_TOO_LARGE:
	    ap_rputs("The requested URL's length exceeds the capacity\n"
	             "limit for this server.<P>\n", r);
	    if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) {
		ap_rvputs(r, error_notes, "<P>\n", NULL);
	    }
	    break;
	case HTTP_UNSUPPORTED_MEDIA_TYPE:
	    ap_rputs("The supplied request data is not in a format\n"
	             "acceptable for processing by this resource.\n", r);
	    break;
	case HTTP_RANGE_NOT_SATISFIABLE:
	    ap_rputs("None of the range-specifier values in the Range\n"
	             "request-header field overlap the current extent\n"
	             "of the selected resource.\n", r);
	    break;
	case HTTP_EXPECTATION_FAILED:
	    ap_rvputs(r, "The expectation given in the Expect request-header"
	              "\nfield could not be met by this server.<P>\n"
	              "The client sent<PRE>\n    Expect: ",
	              ap_table_get(r->headers_in, "Expect"), "\n</PRE>\n"
	              "but we only allow the 100-continue expectation.\n",
	              NULL);
	    break;
	case HTTP_UNPROCESSABLE_ENTITY:
	    ap_rputs("The server understands the media type of the\n"
	             "request entity, but was unable to process the\n"
	             "contained instructions.\n", r);
	    break;
	case HTTP_LOCKED:
	    ap_rputs("The requested resource is currently locked.\n"
	             "The lock must be released or proper identification\n"
	             "given before the method can be applied.\n", r);
	    break;
	case HTTP_FAILED_DEPENDENCY:
	    ap_rputs("The method could not be performed on the resource\n"
	             "because the requested action depended on another\n"
	             "action and that other action failed.\n", r);
	    break;
	case HTTP_INSUFFICIENT_STORAGE:
	    ap_rputs("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.\n", r);
	    break;
	case HTTP_SERVICE_UNAVAILABLE:
	    ap_rputs("The server is temporarily unable to service your\n"
	             "request due to maintenance downtime or capacity\n"
	             "problems. Please try again later.\n", r);
	    break;
	case HTTP_GATEWAY_TIME_OUT:
	    ap_rputs("The proxy server did not receive a timely response\n"
	             "from the upstream server.\n", r);
	    break;
	case HTTP_NOT_EXTENDED:
	    ap_rputs("A mandatory extension policy in the request is not\n"
	             "accepted by the server for this resource.\n", r);
	    break;
	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 = ap_table_get(r->notes, "error-notes")) != NULL)
		&& (h1 = ap_table_get(r->notes, "verbose-error-to")) != NULL
		&& (strcmp(h1, "*") == 0)) {
	        ap_rvputs(r, error_notes, "<P>\n", NULL);
	    }
	    else {
	        ap_rvputs(r, "The server encountered an internal error or\n"
	             "misconfiguration and was unable to complete\n"
	             "your request.<P>\n"
	             "Please contact the server administrator,\n ",
	             ap_escape_html(r->pool, r->server->server_admin),
	             " and inform them of the time the error occurred,\n"
	             "and anything you might have done that may have\n"
	             "caused the error.<P>\n"
		     "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
	  * 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 = ap_table_get(r->notes, "error-notes")) != NULL) {
	  *     ap_rvputs(r, error_notes, "<P>\n", NULL);
	  * }
	  */
	    break;
	}

        if (recursive_error) {
            ap_rvputs(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.\n", NULL);
        }
        ap_rputs(ap_psignature("<HR>\n", r), r);
        ap_rputs("</BODY></HTML>\n", r);
    }
    ap_kill_timeout(r);
    ap_finalize_request_protocol(r);
    ap_rflush(r);
}
