http_protocol.c revision fa861fc5a880d2c3a5ecc0ec71fa7da556adf5c1
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance/* ====================================================================
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * The Apache Software License, Version 1.1
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * Redistribution and use in source and binary forms, with or without
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * modification, are permitted provided that the following conditions
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * 1. Redistributions of source code must retain the above copyright
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * notice, this list of conditions and the following disclaimer.
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * 2. Redistributions in binary form must reproduce the above copyright
e32f2729ffc4e828e41a528f47a4815d4a1689f0Felix Gabriel Mance * notice, this list of conditions and the following disclaimer in
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * the documentation and/or other materials provided with the
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * distribution.
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * 3. The end-user documentation included with the redistribution,
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * if any, must include the following acknowledgment:
fc05327b875b5723b6c17849b83477f29ec12c90Felix Gabriel Mance * "This product includes software developed by the
fc05327b875b5723b6c17849b83477f29ec12c90Felix Gabriel Mance * Apache Software Foundation (http://www.apache.org/)."
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * Alternately, this acknowledgment may appear in the software itself,
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * if and wherever such third-party acknowledgments normally appear.
fc05327b875b5723b6c17849b83477f29ec12c90Felix Gabriel Mance * 4. The names "Apache" and "Apache Software Foundation" must
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * not be used to endorse or promote products derived from this
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * software without prior written permission. For written
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * permission, please contact apache@apache.org.
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel Mance * 5. Products derived from this software may not be called "Apache",
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * nor may "Apache" appear in their name, without prior written
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * permission of the Apache Software Foundation.
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
bed4f1f668ac5d014595c17199fa786aacda4e4cChristian Maeder * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
bed4f1f668ac5d014595c17199fa786aacda4e4cChristian Maeder * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
bed4f1f668ac5d014595c17199fa786aacda4e4cChristian Maeder * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * SUCH DAMAGE.
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * ====================================================================
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * This software consists of voluntary contributions made by many
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * individuals on behalf of the Apache Software Foundation. For more
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * information on the Apache Software Foundation, please see
e05e1babc9a0edf2ebd39713d5c44fd0a035d6daFelix Gabriel Mance * Portions of this software are based upon public domain software
e05e1babc9a0edf2ebd39713d5c44fd0a035d6daFelix Gabriel Mance * originally written at the National Center for Supercomputing Applications,
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance * University of Illinois, Urbana-Champaign.
1341e758a8a0785dd7063b93aed3989f13b36f2aFelix Gabriel Mance * http_protocol.c --- routines which directly communicate with the client.
1341e758a8a0785dd7063b93aed3989f13b36f2aFelix Gabriel Mance * Code originally by Rob McCool; much redone by Robert S. Thau
1341e758a8a0785dd7063b93aed3989f13b36f2aFelix Gabriel Mance * and the Apache Software Foundation.
137edd3944aacd150d60af8977de962113ead859Felix Gabriel Mance#include "http_log.h" /* For errors detected in basic auth common
e05e1babc9a0edf2ebd39713d5c44fd0a035d6daFelix Gabriel Mance * support code... */
e05e1babc9a0edf2ebd39713d5c44fd0a035d6daFelix Gabriel Mance#include "apr_date.h" /* For apr_date_parse_http and APR_DATE_BAD */
431571057e88a650a974adec93ea4bb5173b6213Felix Gabriel Mance/* New Apache routine to map status codes into array indicies
7c2291b25eadfb81c4850bf7ea92a3168f547fa9Felix Gabriel Mance * e.g. 100 -> 0, 101 -> 1, 200 -> 2 ...
e05e1babc9a0edf2ebd39713d5c44fd0a035d6daFelix Gabriel Mance * The number of status lines must equal the value of RESPONSE_CODES (httpd.h)
e05e1babc9a0edf2ebd39713d5c44fd0a035d6daFelix Gabriel Mance * and must be listed in order.
#ifdef UTS21
int ka_sent = 0;
|| r->header_only
&& !wimpy
if (ka_sent) {
left));
if (!wimpy) {
const char *etag;
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;
int methnum)
return APR_SUCCESS;
int *methnum;
return M_INVALID;
return *methnum;
return M_INVALID;
return cur_method_number++;
the "cocom" parsing/compilation toolkit. It is an optimized lookup
switch (len)
switch (method[0])
return UNKNOWN_METHOD;
switch (method[0])
return UNKNOWN_METHOD;
return UNKNOWN_METHOD;
switch (method[0])
return UNKNOWN_METHOD;
return UNKNOWN_METHOD;
return UNKNOWN_METHOD;
switch (method[0])
return UNKNOWN_METHOD;
switch (method[0])
return UNKNOWN_METHOD;
return UNKNOWN_METHOD;
* something like a mod_http_methods.c, complete with config stuff.
return which;
return *methnum;
return M_INVALID;
const void *key;
void *val;
return key;
return NULL;
static long get_chunk_size(char *);
typedef struct http_filter_ctx {
} state;
int eos_sent;
} http_ctx_t;
apr_bucket *e;
if (!ctx) {
if (!f->r->proxyreq) {
if (tenc) {
else if (lenp) {
++pos;
APR_BRIGADE_INSERT_TAIL(b, e);
return APR_SUCCESS;
char *tmp;
f->c->bucket_alloc);
APR_BLOCK_READ, 0);
return rv;
f->r->pool,
f->c->bucket_alloc);
ap_get_mime_headers(f->r);
APR_BRIGADE_INSERT_TAIL(b, e);
return APR_SUCCESS;
APR_BRIGADE_INSERT_TAIL(b, e);
return APR_SUCCESS;
case BODY_NONE:
case BODY_LENGTH:
APR_BRIGADE_INSERT_TAIL(b, e);
return APR_SUCCESS;
case BODY_CHUNK:
APR_BLOCK_READ, 0);
return rv;
APR_BLOCK_READ, 0);
return rv;
f->c->bucket_alloc);
ap_get_mime_headers(f->r);
APR_BRIGADE_INSERT_TAIL(b, e);
return APR_SUCCESS;
return rv;
f->r->pool,
f->c->bucket_alloc);
return APR_SUCCESS;
int i, pos;
return LEVEL_500;
return pos;
typedef struct header_struct {
* In other words, don't change this one without checking table_do in alloc.c.
char *headfield;
char *next;
*next = 0;
const char **protocol)
if (r->assbackwards) {
if (!r->status_line) {
const char *protocol)
char *date;
char *tmp;
const char *server;
if (r->assbackwards) {
const char *protocol;
char *list;
const void *key;
void *val;
return list;
int rv;
return DECLINED;
while (r->prev) {
r = r->prev;
return rv;
h.bb = b;
apr_table_do((int (*) (void *, const char *, const char *))
return DONE;
if (r->assbackwards) {
return DECLINED;
return OK;
* consisting of comma/space-separated tokens.
char *start;
char **strpp;
start = e;
++i, ++strpp) {
if (!ct) {
typedef struct header_filter_ctx {
int headers_sent;
request_rec *r = f->r;
const char *clheader;
const char *protocol;
apr_bucket *e;
if (r->header_only) {
if (!ctx) {
return OK;
APR_BRIGADE_FOREACH(e, b) {
return AP_FILTER_ERROR;
if (r->assbackwards) {
r->headers_out);
fixup_vary(r);
ap_set_keepalive(r);
if (r->chunked) {
if (r->content_encoding) {
r->content_encoding);
if (r->header_only
(void *) &h, r->headers_out,
NULL);
if (r->header_only) {
return OK;
if (r->chunked) {
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;
#ifdef AP_DEBUG
&core_module);
return OK;
static long get_chunk_size(char *b)
long chunksize = 0;
int xvalue = 0;
return chunksize;
apr_bucket *b;
const char *tempbuf;
&core_module);
total = 0;
&& !APR_BUCKET_IS_EOS(b)) {
old = b;
b = APR_BUCKET_NEXT(b);
return total;
return OK;
seen_eos = 0;
return rv;
return HTTP_BAD_REQUEST;
const char *data;
return HTTP_BAD_REQUEST;
} while (!seen_eos);
return OK;
const char *prefix,
const char *key,
const char *suffix)
return result;
request_rec *r,
const char *location)
switch (status) {
case HTTP_MOVED_PERMANENTLY:
case HTTP_MOVED_TEMPORARILY:
case HTTP_TEMPORARY_REDIRECT:
return(apr_pstrcat(p,
NULL));
case HTTP_SEE_OTHER:
return(apr_pstrcat(p,
NULL));
case HTTP_USE_PROXY:
return(apr_pstrcat(p,
NULL));
case HTTP_UNAUTHORIZED:
case HTTP_BAD_REQUEST:
return(add_optional_notes(r,
case HTTP_FORBIDDEN:
return(apr_pstrcat(p,
NULL));
case HTTP_NOT_FOUND:
return(apr_pstrcat(p,
NULL));
case HTTP_METHOD_NOT_ALLOWED:
return(apr_pstrcat(p,
NULL));
case HTTP_NOT_ACCEPTABLE:
NULL);
case HTTP_MULTIPLE_CHOICES:
case HTTP_LENGTH_REQUIRED:
r->method,
NULL);
case HTTP_PRECONDITION_FAILED:
return(apr_pstrcat(p,
NULL));
case HTTP_NOT_IMPLEMENTED:
NULL);
case HTTP_BAD_GATEWAY:
case HTTP_VARIANT_ALSO_VARIES:
return(apr_pstrcat(p,
NULL));
case HTTP_REQUEST_TIME_OUT:
case HTTP_GONE:
return(apr_pstrcat(p,
NULL));
return(apr_pstrcat(p,
r->method,
NULL));
case HTTP_EXPECTATION_FAILED:
return(apr_pstrcat(p,
NULL));
case HTTP_LOCKED:
case HTTP_FAILED_DEPENDENCY:
case HTTP_SERVICE_UNAVAILABLE:
case HTTP_GATEWAY_TIME_OUT:
case HTTP_NOT_EXTENDED:
return(apr_pstrcat(p,
NULL));
char *custom_response;
r->eos_sent = 0;
if (!r->assbackwards) {
r->clength = 0;
if (r->header_only) {
r = r->prev;
const char *h1;
NULL);
NULL);
if (recursive_error) {
return ml;
char **imethods;
char **omethods;
const char *mname,
int mnum),
void *rec,
const char *mname,
int mnum),
int methnum;
char **methods;
int methnum;
const char **xmethod;
char **methods;
const char *method)
int methnum;
char **methods;
l->method_mask = 0;
int printing = 0;
if (next_digit) {
else if (printing) {
} while (shift);
return next;
char *weak;
char *etag;
char *next;
&core_module);
weak_len = 0;
if (weak) {
while (*weak) {
bits_added = 0;
if (bits_added != 0) {
if (bits_added != 0) {
if (weak) {
while (*weak) {
return etag;
char *etag;
int vlv_weak;
if (!r->vlist_validator) {
if (vlv_weak) {
vlv++;
if (!dash) {
dash++;
if (*dash) {
if (*start < 0) {
*start = 0;
typedef struct byterange_ctx {
int num_ranges;
char *boundary;
char *bound_head;
* 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;
request_rec *r = f->r;
apr_bucket *e;
char *current;
int found = 0;
if (!ctx) {
if (num_ranges == 0) {
NULL);
return APR_SUCCESS;
&range_end))) {
char *ts;
c->bucket_alloc);
const char *str;
if (found == 0) {
char *end;
const char *range;
const char *if_range;
const char *match;
const char *ct;
int num_ranges;
if (r->assbackwards) {
* send multipart/x-byteranges instead of multipart/byteranges for
return num_ranges;