http_protocol.c revision 6db54801798f6021bb464de7b3fdcc9dc3150f7b
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering/* ====================================================================
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * Copyright (c) 1995-1999 The Apache Group. All rights reserved.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * Redistribution and use in source and binary forms, with or without
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * modification, are permitted provided that the following conditions
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * 1. Redistributions of source code must retain the above copyright
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * notice, this list of conditions and the following disclaimer.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * 2. Redistributions in binary form must reproduce the above copyright
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * notice, this list of conditions and the following disclaimer in
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * the documentation and/or other materials provided with the
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * distribution.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * 3. All advertising materials mentioning features or use of this
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * software must display the following acknowledgment:
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * "This product includes software developed by the Apache Group
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * for use in the Apache HTTP server project (http://www.apache.org/)."
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * 4. The names "Apache Server" and "Apache Group" must not be used to
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * endorse or promote products derived from this software without
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * prior written permission. For written permission, please contact
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * apache@apache.org.
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering * 5. Products derived from this software may not be called "Apache"
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * nor may "Apache" appear in their names without prior written
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * permission of the Apache Group.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * 6. Redistributions of any form whatsoever must retain the following
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * acknowledgment:
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * "This product includes software developed by the Apache Group
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * for use in the Apache HTTP server project (http://www.apache.org/)."
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * OF THE POSSIBILITY OF SUCH DAMAGE.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * ====================================================================
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * This software consists of voluntary contributions made by many
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * individuals on behalf of the Apache Group and was originally based
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * on public domain software written at the National Center for
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * Supercomputing Applications, University of Illinois, Urbana-Champaign.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * For more information on the Apache Group and the Apache HTTP server
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * project, please see <http://www.apache.org/>.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * http_protocol.c --- routines which directly communicate with the client.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * Code originally by Rob McCool; much redone by Robert S. Thau
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * and the Apache Group.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering#include "http_log.h" /* For errors detected in basic auth common
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * support code... */
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering#include "util_date.h" /* For parseHTTPdate and BAD_DATE */
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ap_bgetopt (r->connection->client, BO_BYTECT, &r->bytes_sent); \
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poetteringstatic int parse_byterange(char *range, long clength, long *start, long *end)
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering /* In the form "-5" */
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering else /* "5-" */
72c0a2c255b172ebbb2a2b7dab7c9aec4c9582d9Lennart Poettering return (*start > 0 || *end < clength - 1);
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poetteringstatic int internal_byterange(int, long *, request_rec *, const char **,
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart PoetteringAPI_EXPORT(int) ap_set_byterange(request_rec *r)
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering /* Check for Range request-header (HTTP/1.1) or Request-Range for
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * backwards-compatibility with second-draft Luotonen/Franks
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * byte-ranges (e.g. Netscape Navigator 2-3).
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * We support this form, with Request-Range, and (farther down) we
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * send multipart/x-byteranges instead of multipart/byteranges for
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * Request-Range based requests to work around a bug in Netscape
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * Navigator 2-3 and MSIE 3.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering if (!(range = ap_table_get(r->headers_in, "Range")))
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering range = ap_table_get(r->headers_in, "Request-Range");
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering if (!range || strncasecmp(range, "bytes=", 6)) {
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering /* Check the If-Range header for Etag or Date.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * Note that this check will return false (as required) if either
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * of the two etags are weak.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering if ((if_range = ap_table_get(r->headers_in, "If-Range"))) {
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering if (!(match = ap_table_get(r->headers_out, "Etag")) ||
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering else if (!(match = ap_table_get(r->headers_out, "Last-Modified")) ||
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering /* A single range */
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering if (!parse_byterange(ap_pstrdup(r->pool, range + 6), r->clength,
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ap_table_setn(r->headers_out, "Content-Range",
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ap_psprintf(r->pool, "bytes %ld-%ld/%ld",
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ap_table_setn(r->headers_out, "Content-Length",
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ap_psprintf(r->pool, "%ld", range_end - range_start + 1));
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering /* a multiple range */
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering const char *r_range = ap_pstrdup(r->pool, range + 6);
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering r->boundary = ap_psprintf(r->pool, "%lx%lx",
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering while (internal_byterange(0, &tlength, r, &r_range, NULL, NULL));
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ap_table_setn(r->headers_out, "Content-Length",
72c0a2c255b172ebbb2a2b7dab7c9aec4c9582d9Lennart PoetteringAPI_EXPORT(int) ap_each_byterange(request_rec *r, ap_off_t *offset,
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering return internal_byterange(1, NULL, r, &r->range, offset, length);
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering/* If this function is called with realreq=1, it will spit out
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * the correct headers for a byterange chunk, and set offset and
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * length to the positions they should be.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * If it is called with realreq=0, it will add to tlength the length
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * it *would* have used with realreq=1.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * Either case will return 1 if it should be called again, and 0
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poetteringstatic int internal_byterange(int realreq, long *tlength, request_rec *r,
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ap_rvputs(r, "\015\012--", r->boundary, "--\015\012", NULL);
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering range = ap_getword(r->pool, r_range, ',');
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering if (!parse_byterange(range, r->clength, &range_start, &range_end))
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering /* Skip this one */
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering return internal_byterange(realreq, tlength, r, r_range, offset,
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering const char *ct = r->content_type ? r->content_type : ap_default_type(r);
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ap_snprintf(ts, sizeof(ts), "%ld-%ld/%ld", range_start, range_end,
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ap_rvputs(r, "\015\012--", r->boundary, "\015\012Content-type: ",
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ct, "\015\012Content-range: bytes ", ts, "\015\012\015\012",
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering *tlength += 4 + strlen(r->boundary) + 16 + strlen(ct) + 23 +
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart PoetteringAPI_EXPORT(int) ap_set_content_length(request_rec *r, long clength)
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ap_table_setn(r->headers_out, "Content-Length", ap_psprintf(r->pool, "%ld", clength));
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart PoetteringAPI_EXPORT(int) ap_set_keepalive(request_rec *r)
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ap_table_get(r->headers_out, "Connection"), "close");
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering const char *conn = ap_table_get(r->headers_in, "Connection");
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering /* The following convoluted conditional determines whether or not
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * the current connection should remain persistent after this response
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * (a.k.a. HTTP Keep-Alive) and whether or not the output message
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * body should use the HTTP/1.1 chunked transfer-coding. In English,
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * IF we have not marked this connection as errored;
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * and the response body has a defined length due to the status code
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * being 304 or 204, the request method being HEAD, already
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * having defined Content-Length or Transfer-Encoding: chunked, or
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * the request version being HTTP/1.1 and thus capable of being set
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * as chunked [we know the (r->chunked = 1) side-effect is ugly];
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * and the server configuration enables keep-alive;
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * and the server configuration has a reasonable inter-request timeout;
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * and there is no maximum # requests or the max hasn't been reached;
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * and the response status does not require a close;
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * and the response generator has not already indicated close;
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * and the client did not request non-persistence (Connection: close);
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * and we haven't been configured to ignore the buggy twit
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * or they're a buggy twit coming through a HTTP/1.1 proxy
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * and the client is requesting an HTTP/1.0-style keep-alive
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * or the client claims to be HTTP/1.1 compliant (perhaps a proxy);
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * THEN we can be persistent, which requires more headers be output.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering * Note that the condition evaluation order is extremely important.
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ap_table_get(r->headers_out, "Content-Length") ||
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering ap_table_get(r->headers_out, "Transfer-Encoding"),
ce30c8dcb41dfe9264f79f30c7f51c0e74576638Lennart Poettering (r->chunked = 1))) && /* THIS CODE IS CORRECT, see comment above. */
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering (r->server->keep_alive_max > r->connection->keepalives)) &&
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering !ap_status_drops_connection(r->status) &&
if (ka_sent) {
if (!wimpy)
return OK;
return HTTP_PRECONDITION_FAILED;
return HTTP_PRECONDITION_FAILED;
return HTTP_NOT_MODIFIED;
return HTTP_NOT_MODIFIED;
return HTTP_NOT_MODIFIED;
return HTTP_PRECONDITION_FAILED;
&& ((if_modified_since =
return HTTP_NOT_MODIFIED;
return OK;
char *etag;
char *weak;
(unsigned long) r->mtime);
(unsigned long) r->mtime);
return etag;
char *etag;
int vlv_weak;
if (!r->vlist_validator) {
if (vlv_weak)
vlv++;
* something like a mod_http_methods.c, complete with config stuff.
switch (*method) {
return M_GET;
return M_POST;
return M_PUT;
return M_PATCH;
return M_PROPFIND;
return M_PROPPATCH;
return M_DELETE;
return M_CONNECT;
return M_COPY;
return M_MKCOL;
return M_MOVE;
return M_OPTIONS;
return M_TRACE;
return M_LOCK;
return M_UNLOCK;
return M_INVALID;
int retval;
int total = 0;
pos = s;
if (retval <= 0)
--total;
return total;
* This will prevent "http://www.wherever.com/..\..\/" from
const char *ll = l;
const char *uri;
int len;
char *value;
char *copy;
int len;
unsigned int fields_read = 0;
++value;
request_rec *r;
ap_context_t *p;
const char *expect;
int access_status;
r->pool = p;
r->read_length = 0;
#ifdef CHARSET_EBCDIC
if (!read_request_line(r)) {
ap_send_error_response(r, 0);
return NULL;
if (!r->assbackwards) {
get_mime_headers(r);
ap_send_error_response(r, 0);
if (r->header_only) {
r->uri);
r->header_only = 0;
ap_send_error_response(r, 0);
ap_send_error_response(r, 0);
ap_send_error_response(r, 0);
(void) ap_discard_request_body(r);
return NULL;
NULL));
return DECLINED;
if (!ap_auth_name(r)) {
return SERVER_ERROR;
if (!auth_line) {
return AUTH_REQUIRED;
return AUTH_REQUIRED;
auth_line++;
*pw = t;
return OK;
* The number of status lines must equal the value of RESPONSE_CODES (httpd.h)
#ifdef UTS21
int i, pos;
return LEVEL_500;
return pos;
* In other words, don't change this one without checking table_do in alloc.c.
char *protocol;
#ifdef CHARSET_EBCDIC
if (r->assbackwards)
if (!r->status_line)
if (r->proxyreq
#ifdef CHARSET_EBCDIC
#ifdef CHARSET_EBCDIC
if (!convert)
long int bs;
NULL);
int rv;
while (r->prev)
r = r->prev;
return rv;
ap_table_do((int (*) (void *, const char *, const char *))
return OK;
const long int zero = 0L;
if (r->assbackwards)
return DECLINED;
ap_set_keepalive(r);
terminate_header(r);
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
const char *ua;
* consisting of comma/space-separated tokens.
char *start;
char **strpp;
start = e;
++i, ++strpp) {
const long int zero = 0L;
#ifdef CHARSET_EBCDIC
if (r->assbackwards) {
if (!r->main)
r->headers_out);
fixup_vary(r);
#ifdef CHARSET_EBCDIC
ap_set_keepalive(r);
if (r->chunked) {
else if (r->content_type)
if (r->content_encoding)
else if (r->content_language)
terminate_header(r);
if (r->chunked)
#ifdef CHARSET_EBCDIC
if (!convert)
r->chunked = 0;
unsigned long max_body;
r->read_chunked = 0;
r->remaining = 0;
if (tenc) {
return HTTP_NOT_IMPLEMENTED;
else if (lenp) {
++pos;
return HTTP_BAD_REQUEST;
return HTTP_REQUEST_ENTITY_TOO_LARGE;
return HTTP_REQUEST_ENTITY_TOO_LARGE;
return OK;
NULL);
ap_rflush(r);
static long get_chunk_size(char *b)
long chunksize = 0;
while (ap_isxdigit(*b)) {
int xvalue = 0;
return chunksize;
long chunk_start = 0;
unsigned long max_body;
return len_read;
if (bufsiz <= 0)
max_body);
get_mime_headers(r);
chunk_start = 0;
if (len_read < 0) {
return chunk_start;
if (c != LF) {
int rv;
return rv;
if (r->expecting_100) {
return OK;
if (rv < 0)
return HTTP_BAD_REQUEST;
return OK;
long len;
#ifdef HAVE_SENDFILE
return len;
long total_bytes_sent = 0;
ap_ssize_t w;
ap_ssize_t n;
if (length == 0)
o = IOBUFSIZE;
total_bytes_sent += w;
SET_BYTES_SENT(r);
return total_bytes_sent;
long total_bytes_sent = 0;
long zero_timeout = 0;
ap_ssize_t w;
ap_ssize_t n;
if (length == 0) {
(void) ap_rflush(r);
(void) ap_rflush(r);
total_bytes_sent += w;
SET_BYTES_SENT(r);
return total_bytes_sent;
#ifdef USE_MMAP_FILES
#ifndef MMAP_SEGMENT_SIZE
ap_ssize_t w;
char *addr;
if (length == 0)
n = MMAP_SEGMENT_SIZE;
total_bytes_sent += w;
offset += w;
SET_BYTES_SENT(r);
return total_bytes_sent;
return EOF;
return EOF;
SET_BYTES_SENT(r);
int rcode;
return EOF;
if (rcode < 0) {
return EOF;
SET_BYTES_SENT(r);
return rcode;
ap_ssize_t n;
return EOF;
return EOF;
SET_BYTES_SENT(r);
SET_BYTES_SENT(r);
SET_BYTES_SENT(r);
ap_ssize_t i;
return EOF;
if (x == NULL)
j = strlen(x);
return EOF;
SET_BYTES_SENT(r);
return EOF;
char *custom_response;
r->headers_out);
ap_set_keepalive(r);
(void *) r, r->headers_out,
NULL);
terminate_header(r);
if (!r->assbackwards) {
r->clength = 0;
if (r->header_only) {
ap_rflush(r);
ap_rflush(r);
r = r->prev;
const char *h1;
const char *error_notes;
ap_rvputs(r,
NULL);
switch (status) {
case HTTP_MOVED_PERMANENTLY:
case HTTP_MOVED_TEMPORARILY:
case HTTP_TEMPORARY_REDIRECT:
NULL);
case HTTP_SEE_OTHER:
NULL);
case HTTP_USE_PROXY:
case AUTH_REQUIRED:
case BAD_REQUEST:
case HTTP_FORBIDDEN:
case NOT_FOUND:
case METHOD_NOT_ALLOWED:
case NOT_ACCEPTABLE:
ap_rvputs(r,
case MULTIPLE_CHOICES:
const char *list;
case LENGTH_REQUIRED:
case PRECONDITION_FAILED:
case HTTP_NOT_IMPLEMENTED:
case BAD_GATEWAY:
case VARIANT_ALSO_VARIES:
case HTTP_REQUEST_TIME_OUT:
case HTTP_GONE:
NULL);
case HTTP_EXPECTATION_FAILED:
NULL);
case HTTP_LOCKED:
case HTTP_FAILED_DEPENDENCY:
case HTTP_SERVICE_UNAVAILABLE:
case HTTP_GATEWAY_TIME_OUT:
case HTTP_NOT_EXTENDED:
if (recursive_error) {
ap_rflush(r);
NULL)