protocol.c revision b02dfdb611f84136664b3c05e4d4d704aeabbf63
d29201dd5328b88140ce050100693c501852657dChristian Maeder/* Licensed to the Apache Software Foundation (ASF) under one or more
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder * contributor license agreements. See the NOTICE file distributed with
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder * this work for additional information regarding copyright ownership.
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder * The ASF licenses this file to You under the Apache License, Version 2.0
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder * (the "License"); you may not use this file except in compliance with
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu * the License. You may obtain a copy of the License at
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder * http://www.apache.org/licenses/LICENSE-2.0
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder * Unless required by applicable law or agreed to in writing, software
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder * distributed under the License is distributed on an "AS IS" BASIS,
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder * See the License for the specific language governing permissions and
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder * limitations under the License.
f876a858a3644fa16b793afb4692cf353fa13762Christian Maeder * protocol.c --- routines which directly communicate with the client.
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder * Code originally by Rob McCool; much redone by Robert S. Thau
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder * and the Apache Software Foundation.
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder#include "http_log.h" /* For errors detected in basic auth common
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder * support code... */
722e8a91f69209ba0e99bf799c4989801d78cf16Christian Maeder/* we know core's module_index is 0 */
722e8a91f69209ba0e99bf799c4989801d78cf16Christian Maeder#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian MaederAP_DECLARE_DATA ap_filter_rec_t *ap_old_write_func = NULL;
21b18016469e574bd145ad07c7b0f02839677cc3Christian Maeder/* Patterns to match in ap_make_content_type() */
21b18016469e574bd145ad07c7b0f02839677cc3Christian Maederstatic const char *needcset[] = {
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maederstatic const apr_strmatch_pattern **needcset_patterns;
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maederstatic const apr_strmatch_pattern *charset_pattern;
62d8627183cce49c052386186ad69c95b1aa3953Christian MaederAP_DECLARE(void) ap_setup_make_content_type(apr_pool_t *pool)
62d8627183cce49c052386186ad69c95b1aa3953Christian Maeder for (i = 0; needcset[i]; i++) {
f876a858a3644fa16b793afb4692cf353fa13762Christian Maeder needcset_patterns = (const apr_strmatch_pattern **)
f876a858a3644fa16b793afb4692cf353fa13762Christian Maeder apr_palloc(pool, (i + 1) * sizeof(apr_strmatch_pattern *));
f876a858a3644fa16b793afb4692cf353fa13762Christian Maeder for (i = 0; needcset[i]; i++) {
c72f409b411e817f42a1c18f49cf9b8190d51ea3Christian Maeder needcset_patterns[i] = apr_strmatch_precompile(pool, needcset[i], 0);
c72f409b411e817f42a1c18f49cf9b8190d51ea3Christian Maeder charset_pattern = apr_strmatch_precompile(pool, "charset=", 0);
a608d5645ae434cdb7a1555057007301072f447eChristian Maeder * Builds the content-type that should be sent to the client from the
03db3efebb43c12041915cb7ffcc172b191208f9Christian Maeder * content-type specified. The following rules are followed:
94b9f4ce450f9508dcb30b129529d635234c52c3Christian Maeder * - if type is NULL or "", return NULL (do not set content-type).
2b470a98ae13b1a87d53f64c3188c8ea77600d99Christian Maeder * - if charset adding is disabled, stop processing and return type.
2b470a98ae13b1a87d53f64c3188c8ea77600d99Christian Maeder * - then, if there are no parameters on type, add the default charset
2b470a98ae13b1a87d53f64c3188c8ea77600d99Christian Maeder * - return type
f876a858a3644fa16b793afb4692cf353fa13762Christian MaederAP_DECLARE(const char *)ap_make_content_type(request_rec *r, const char *type)
return NULL;
return type;
return type;
return type;
apr_bucket *e;
if (last_char)
APR_BLOCK_READ, 0);
return rv;
return APR_EGENERAL;
e = APR_BUCKET_NEXT(e))
const char *str;
if (APR_BUCKET_IS_EOS(e)) {
return rv;
if (len == 0) {
if (bytes_handled > 0) {
return APR_ENOSPC;
if (do_alloc) {
char *new_buffer;
*s = new_buffer;
last_char--;
const char *str;
return rv;
if (APR_BUCKET_IS_EOS(e)) {
return rv;
c = *str;
if (bytes_handled >= n) {
*read = n;
return APR_ENOSPC;
char *tmp;
if (do_alloc) {
return rv;
char *new_buffer;
*s = new_buffer;
return APR_EINVAL;
return APR_SUCCESS;
return rv;
char *tmp_s = s;
return (int)len;
++uri ;
* This will prevent "http://www.wherever.com/..\..\/" from
const char *ll;
const char *uri;
const char *pro;
int num_blank_lines = 0;
if (max_blank_lines <= 0) {
if (APLOGrtrace5(r)) {
r->method);
if (ll[0]) {
r->assbackwards = 0;
const char *value)
return LOG_NAME_MAX_LEN;
char *field;
char *value;
int fields_read = 0;
char *tmp_field;
int folded = 0;
char *fold_buf;
alloc_len = 0;
if (len == 0) {
if (!folded) {
request_rec *r;
apr_pool_t *p;
const char *expect;
int access_status;
r->pool = p;
r->read_length = 0;
ap_send_error_response(r, 0);
goto traceout;
goto traceout;
r = NULL;
goto traceout;
if (!r->assbackwards) {
ap_send_error_response(r, 0);
goto traceout;
if (r->header_only) {
r->uri);
r->header_only = 0;
ap_send_error_response(r, 0);
goto traceout;
ap_send_error_response(r, 0);
goto traceout;
r = NULL;
goto traceout;
ap_send_error_response(r, 0);
goto traceout;
AP_READ_REQUEST_SUCCESS((uintptr_t)r, (char *)r->method, (char *)r->uri, (char *)r->server->defn_name, r->status);
const request_rec *r)
apr_bucket *b;
(void) ap_discard_request_body(r);
if (!r->eos_sent) {
if (type) {
return DECLINED;
if (!ap_auth_name(r)) {
return HTTP_INTERNAL_SERVER_ERROR;
if (!auth_line) {
return HTTP_UNAUTHORIZED;
return HTTP_UNAUTHORIZED;
auth_line++;
*pw = t;
return OK;
struct content_length_ctx {
ap_filter_t *f,
request_rec *r = f->r;
apr_bucket *e;
int eos = 0;
if (!ctx) {
e = APR_BRIGADE_FIRST(b);
while (e != APR_BRIGADE_SENTINEL(b)) {
if (APR_BUCKET_IS_EOS(e)) {
const char *ignored;
if (e != APR_BRIGADE_FIRST(b)) {
return rv;
e = APR_BRIGADE_FIRST(b);
return rv;
e = APR_BUCKET_NEXT(e);
return rv;
#if APR_HAS_MMAP
request_rec *r,
apr_bucket *b;
ap_filter_t *f;
if (f == NULL) {
f = r->output_filters;
ap_filter_t *f;
if (len == 0)
return APR_SUCCESS;
f = insert_old_write_filter(r);
if (f != r->output_filters) {
return rv;
char c2 = (char)c;
return nbyte;
struct ap_vrprintf_data {
request_rec *r;
char *buff;
* vformatter needs to write into buff and buff.curpos > buff.endpos */
return APR_SUCCESS;
vd.r = r;
written += n;
return written;
if (s == NULL)
return written;
apr_bucket *b;
ap_filter_t *f;
f = insert_old_write_filter(r);
if (!r->assbackwards) {
typedef struct hdr_ptr {
ap_filter_t *f;
} hdr_ptr;
hdr_ptr x;
if (send_headers) {
(const request_rec *r), (r), 0)