http_request.c revision 64ff08a7a6515306d78e725cef4b220bf0675e8f
97a9a944b5887e91042b019776c41d5dd74557aferikabele/* Licensed to the Apache Software Foundation (ASF) under one or more
97a9a944b5887e91042b019776c41d5dd74557aferikabele * contributor license agreements. See the NOTICE file distributed with
97a9a944b5887e91042b019776c41d5dd74557aferikabele * this work for additional information regarding copyright ownership.
a945f35eff8b6a88009ce73de6d4c862ce58de3cslive * The ASF licenses this file to You under the Apache License, Version 2.0
a945f35eff8b6a88009ce73de6d4c862ce58de3cslive * (the "License"); you may not use this file except in compliance with
a945f35eff8b6a88009ce73de6d4c862ce58de3cslive * the License. You may obtain a copy of the License at
fe64b2ba25510d8c9dba5560a2d537763566cf40nd *
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * http://www.apache.org/licenses/LICENSE-2.0
fe64b2ba25510d8c9dba5560a2d537763566cf40nd *
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * Unless required by applicable law or agreed to in writing, software
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * distributed under the License is distributed on an "AS IS" BASIS,
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * See the License for the specific language governing permissions and
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * limitations under the License.
fe64b2ba25510d8c9dba5560a2d537763566cf40nd */
52fff662005b1866a3ff09bb6c902800c5cc6dedjerenkrantz
fe64b2ba25510d8c9dba5560a2d537763566cf40nd/*
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * http_request.c: functions to get and process requests
fe64b2ba25510d8c9dba5560a2d537763566cf40nd *
4b5981e276e93df97c34e4da05ca5cf8bbd937dand * Rob McCool 3/21/93
fe64b2ba25510d8c9dba5560a2d537763566cf40nd *
a63f0ab647ad2ab72efc9bea7a66e24e9ebc5cc2nd * Thoroughly revamped by rst for Apache. NB this file reads
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd * best from the bottom up.
ad74a0524a06bfe11b7de9e3b4ce7233ab3bd3f7nd *
4aa805f8500255bc52a4c03259fe46df10a1d07cyoshiki */
dfb59c684345700bf9186b8d44936f8b1ba082ffgryzor
ecc5150d35c0dc5ee5119c2717e6660fa331abbftakashi#include "apr_strings.h"
ecc5150d35c0dc5ee5119c2717e6660fa331abbftakashi#include "apr_file_io.h"
3b3b7fc78d1f5bfc2769903375050048ff41ff26nd#include "apr_fnmatch.h"
fe64b2ba25510d8c9dba5560a2d537763566cf40nd
fe64b2ba25510d8c9dba5560a2d537763566cf40nd#define APR_WANT_STRFUNC
fe64b2ba25510d8c9dba5560a2d537763566cf40nd#include "apr_want.h"
fe64b2ba25510d8c9dba5560a2d537763566cf40nd
fe64b2ba25510d8c9dba5560a2d537763566cf40nd#include "ap_config.h"
fe64b2ba25510d8c9dba5560a2d537763566cf40nd#include "httpd.h"
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna#include "http_config.h"
fe64b2ba25510d8c9dba5560a2d537763566cf40nd#include "http_request.h"
117c1f888a14e73cdd821dc6c23eb0411144a41cnd#include "http_core.h"
117c1f888a14e73cdd821dc6c23eb0411144a41cnd#include "http_protocol.h"
58699879a562774640b95e9eedfd891f336e38c2nd#include "http_log.h"
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd#include "http_main.h"
117c1f888a14e73cdd821dc6c23eb0411144a41cnd#include "util_filter.h"
117c1f888a14e73cdd821dc6c23eb0411144a41cnd#include "util_charset.h"
117c1f888a14e73cdd821dc6c23eb0411144a41cnd#include "scoreboard.h"
117c1f888a14e73cdd821dc6c23eb0411144a41cnd
9597f440430d8c876dd64f5f78066804650a18ecnoodl#include "mod_core.h"
117c1f888a14e73cdd821dc6c23eb0411144a41cnd
117c1f888a14e73cdd821dc6c23eb0411144a41cnd#if APR_HAVE_STDARG_H
117c1f888a14e73cdd821dc6c23eb0411144a41cnd#include <stdarg.h>
117c1f888a14e73cdd821dc6c23eb0411144a41cnd#endif
5f86589186bcc15ee13e288a9d73acbeab2409fbdpejesh
117c1f888a14e73cdd821dc6c23eb0411144a41cnd/*****************************************************************
117c1f888a14e73cdd821dc6c23eb0411144a41cnd *
117c1f888a14e73cdd821dc6c23eb0411144a41cnd * Mainline request processing...
117c1f888a14e73cdd821dc6c23eb0411144a41cnd */
117c1f888a14e73cdd821dc6c23eb0411144a41cnd
117c1f888a14e73cdd821dc6c23eb0411144a41cnd/* XXX A cleaner and faster way to do this might be to pass the request_rec
117c1f888a14e73cdd821dc6c23eb0411144a41cnd * down the filter chain as a parameter. It would need to change for
3cc4ff86e6cc4cfd7d4ccfc58dedff599091444bnoodl * subrequest vs. main request filters; perhaps the subrequest filter could
117c1f888a14e73cdd821dc6c23eb0411144a41cnd * make the switch.
117c1f888a14e73cdd821dc6c23eb0411144a41cnd */
117c1f888a14e73cdd821dc6c23eb0411144a41cndstatic void update_r_in_filters(ap_filter_t *f,
117c1f888a14e73cdd821dc6c23eb0411144a41cnd request_rec *from,
117c1f888a14e73cdd821dc6c23eb0411144a41cnd request_rec *to)
117c1f888a14e73cdd821dc6c23eb0411144a41cnd{
117c1f888a14e73cdd821dc6c23eb0411144a41cnd while (f) {
6c45910d5394acbc3f20ab3f2615d9ed2b4e6533nd if (f->r == from) {
117c1f888a14e73cdd821dc6c23eb0411144a41cnd f->r = to;
117c1f888a14e73cdd821dc6c23eb0411144a41cnd }
117c1f888a14e73cdd821dc6c23eb0411144a41cnd f = f->next;
117c1f888a14e73cdd821dc6c23eb0411144a41cnd }
117c1f888a14e73cdd821dc6c23eb0411144a41cnd}
117c1f888a14e73cdd821dc6c23eb0411144a41cnd
117c1f888a14e73cdd821dc6c23eb0411144a41cndAP_DECLARE(void) ap_die(int type, request_rec *r)
117c1f888a14e73cdd821dc6c23eb0411144a41cnd{
117c1f888a14e73cdd821dc6c23eb0411144a41cnd int error_index = ap_index_of_response(type);
709e3a21ba73b8433462959cd56c773454b34441trawick char *custom_response = ap_response_code_string(r, error_index);
117c1f888a14e73cdd821dc6c23eb0411144a41cnd int recursive_error = 0;
117c1f888a14e73cdd821dc6c23eb0411144a41cnd request_rec *r_1st_err = r;
117c1f888a14e73cdd821dc6c23eb0411144a41cnd
117c1f888a14e73cdd821dc6c23eb0411144a41cnd if (type == AP_FILTER_ERROR) {
117c1f888a14e73cdd821dc6c23eb0411144a41cnd ap_filter_t *next;
117c1f888a14e73cdd821dc6c23eb0411144a41cnd
117c1f888a14e73cdd821dc6c23eb0411144a41cnd /*
117c1f888a14e73cdd821dc6c23eb0411144a41cnd * Check if we still have the ap_http_header_filter in place. If
117c1f888a14e73cdd821dc6c23eb0411144a41cnd * this is the case we should not ignore AP_FILTER_ERROR here because
117c1f888a14e73cdd821dc6c23eb0411144a41cnd * it means that we have not sent any response at all and never
117c1f888a14e73cdd821dc6c23eb0411144a41cnd * will. This is bad. Sent an internal server error instead.
117c1f888a14e73cdd821dc6c23eb0411144a41cnd */
117c1f888a14e73cdd821dc6c23eb0411144a41cnd next = r->output_filters;
117c1f888a14e73cdd821dc6c23eb0411144a41cnd while (next && (next->frec != ap_http_header_filter_handle)) {
117c1f888a14e73cdd821dc6c23eb0411144a41cnd next = next->next;
117c1f888a14e73cdd821dc6c23eb0411144a41cnd }
117c1f888a14e73cdd821dc6c23eb0411144a41cnd
b00fe3c3354db01001b8eddfd9b88441380f837dwrowe /*
117c1f888a14e73cdd821dc6c23eb0411144a41cnd * If next != NULL then we left the while above because of
a38b5f73e7f0f3b8726fb47d27b145f37036ead0jim * next->frec == ap_http_header_filter
117c1f888a14e73cdd821dc6c23eb0411144a41cnd */
fe64b2ba25510d8c9dba5560a2d537763566cf40nd if (next) {
fe64b2ba25510d8c9dba5560a2d537763566cf40nd ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
fe64b2ba25510d8c9dba5560a2d537763566cf40nd "Custom error page caused AP_FILTER_ERROR");
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna type = HTTP_INTERNAL_SERVER_ERROR;
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna }
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna else {
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna return;
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna }
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna }
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna if (type == DONE) {
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe ap_finalize_request_protocol(r);
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe return;
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna }
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna /*
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna * The following takes care of Apache redirects to custom response URLs
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna * Note that if we are already dealing with the response to some other
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna * error condition, we just report on the original error, and give up on
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe * any attempt to handle the other thing "intelligently"...
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe */
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe if (r->status != HTTP_OK) {
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe recursive_error = type;
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe while (r_1st_err->prev && (r_1st_err->prev->status != HTTP_OK))
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe r_1st_err = r_1st_err->prev; /* Get back to original error */
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna if (r_1st_err != r) {
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna /* The recursive error was caused by an ErrorDocument specifying
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna * an internal redirect to a bad URI. ap_internal_redirect has
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna * changed the filter chains to point to the ErrorDocument's
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna * request_rec. Back out those changes so we can safely use the
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna * original failing request_rec to send the canned error message.
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna *
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna * ap_send_error_response gets rid of existing resource filters
90efa9f1730742d874edb5a7803adce11c9f08eanoodl * on the output side, so we can skip those.
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna */
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna update_r_in_filters(r_1st_err->proto_output_filters, r, r_1st_err);
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna update_r_in_filters(r_1st_err->input_filters, r, r_1st_err);
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna }
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna custom_response = NULL; /* Do NOT retry the custom thing! */
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna }
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna r->status = type;
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna /*
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna * This test is done here so that none of the auth modules needs to know
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna * about proxy authentication. They treat it like normal auth, and then
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna * we tweak the status.
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna */
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna if (HTTP_UNAUTHORIZED == r->status && PROXYREQ_PROXY == r->proxyreq) {
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna r->status = HTTP_PROXY_AUTHENTICATION_REQUIRED;
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna }
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe /* If we don't want to keep the connection, make sure we mark that the
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe * connection is not eligible for keepalive. If we want to keep the
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe * connection, be sure that the request body (if any) has been read.
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe */
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe if (ap_status_drops_connection(r->status)) {
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe r->connection->keepalive = AP_CONN_CLOSE;
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe }
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe /*
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe * Two types of custom redirects --- plain text, and URLs. Plain text has
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe * a leading '"', so the URL code, here, is triggered on its absence
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe */
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe if (custom_response && custom_response[0] != '"') {
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe if (ap_is_url(custom_response)) {
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe /*
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe * The URL isn't local, so lets drop through the rest of this
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe * apache code, and continue with the usual REDIRECT handler.
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe * But note that the client will ultimately see the wrong
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe * status...
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe */
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna r->status = HTTP_MOVED_TEMPORARILY;
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna apr_table_setn(r->headers_out, "Location", custom_response);
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna }
fe64b2ba25510d8c9dba5560a2d537763566cf40nd else if (custom_response[0] == '/') {
fe64b2ba25510d8c9dba5560a2d537763566cf40nd const char *error_notes;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd r->no_local_copy = 1; /* Do NOT send HTTP_NOT_MODIFIED for
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * error documents! */
fe64b2ba25510d8c9dba5560a2d537763566cf40nd /*
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * This redirect needs to be a GET no matter what the original
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * method was.
fe64b2ba25510d8c9dba5560a2d537763566cf40nd */
fe64b2ba25510d8c9dba5560a2d537763566cf40nd apr_table_setn(r->subprocess_env, "REQUEST_METHOD", r->method);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd
c985aca104389df30d6ec0a637ce0ccaac904362nd /*
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * Provide a special method for modules to communicate
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * more informative (than the plain canned) messages to us.
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * Propagate them to ErrorDocuments via the ERROR_NOTES variable:
06ba4a61654b3763ad65f52283832ebf058fdf1cslive */
06ba4a61654b3763ad65f52283832ebf058fdf1cslive if ((error_notes = apr_table_get(r->notes,
06ba4a61654b3763ad65f52283832ebf058fdf1cslive "error-notes")) != NULL) {
fb77c505254b6e9c925e23e734463e87574f8f40kess apr_table_setn(r->subprocess_env, "ERROR_NOTES", error_notes);
fb77c505254b6e9c925e23e734463e87574f8f40kess }
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->method = apr_pstrdup(r->pool, "GET");
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->method_number = M_GET;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive ap_internal_redirect(custom_response, r);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive return;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive }
06ba4a61654b3763ad65f52283832ebf058fdf1cslive else {
fb77c505254b6e9c925e23e734463e87574f8f40kess /*
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * Dumb user has given us a bad url to redirect to --- fake up
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * dying with a recursive server error...
06ba4a61654b3763ad65f52283832ebf058fdf1cslive */
06ba4a61654b3763ad65f52283832ebf058fdf1cslive recursive_error = HTTP_INTERNAL_SERVER_ERROR;
fb77c505254b6e9c925e23e734463e87574f8f40kess ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
06ba4a61654b3763ad65f52283832ebf058fdf1cslive "Invalid error redirection directive: %s",
06ba4a61654b3763ad65f52283832ebf058fdf1cslive custom_response);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive }
06ba4a61654b3763ad65f52283832ebf058fdf1cslive }
06ba4a61654b3763ad65f52283832ebf058fdf1cslive ap_send_error_response(r_1st_err, recursive_error);
fb77c505254b6e9c925e23e734463e87574f8f40kess}
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
06ba4a61654b3763ad65f52283832ebf058fdf1cslivestatic void check_pipeline(conn_rec *c)
06ba4a61654b3763ad65f52283832ebf058fdf1cslive{
fb77c505254b6e9c925e23e734463e87574f8f40kess if (c->keepalive != AP_CONN_CLOSE) {
fb77c505254b6e9c925e23e734463e87574f8f40kess apr_status_t rv;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive apr_bucket_brigade *bb = apr_brigade_create(c->pool, c->bucket_alloc);
fb77c505254b6e9c925e23e734463e87574f8f40kess
bc4b55ec8f31569d606d5680d50189a355bcd7a6rbowen rv = ap_get_brigade(c->input_filters, bb, AP_MODE_SPECULATIVE,
fb77c505254b6e9c925e23e734463e87574f8f40kess APR_NONBLOCK_READ, 1);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive if (rv != APR_SUCCESS || APR_BRIGADE_EMPTY(bb)) {
06ba4a61654b3763ad65f52283832ebf058fdf1cslive /*
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * Error or empty brigade: There is no data present in the input
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * filter
fb77c505254b6e9c925e23e734463e87574f8f40kess */
fb77c505254b6e9c925e23e734463e87574f8f40kess c->data_in_input_filters = 0;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive }
fb77c505254b6e9c925e23e734463e87574f8f40kess else {
fb77c505254b6e9c925e23e734463e87574f8f40kess c->data_in_input_filters = 1;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive }
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd apr_brigade_destroy(bb);
130d299c4b2b15be45532a176604c71fdc7bea5bnd }
130d299c4b2b15be45532a176604c71fdc7bea5bnd}
130d299c4b2b15be45532a176604c71fdc7bea5bnd
130d299c4b2b15be45532a176604c71fdc7bea5bnd
130d299c4b2b15be45532a176604c71fdc7bea5bndvoid ap_process_request_after_handler(request_rec *r)
ef8e89e090461194ecadd31e8796a2c51e0531a2kess{
130d299c4b2b15be45532a176604c71fdc7bea5bnd apr_bucket_brigade *bb;
130d299c4b2b15be45532a176604c71fdc7bea5bnd apr_bucket *b;
130d299c4b2b15be45532a176604c71fdc7bea5bnd conn_rec *c = r->connection;
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd
fe64b2ba25510d8c9dba5560a2d537763566cf40nd /* Send an EOR bucket through the output filter chain. When
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * this bucket is destroyed, the request will be logged and
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * its pool will be freed
fe64b2ba25510d8c9dba5560a2d537763566cf40nd */
fe64b2ba25510d8c9dba5560a2d537763566cf40nd bb = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd b = ap_bucket_eor_create(r->connection->bucket_alloc, r);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd APR_BRIGADE_INSERT_HEAD(bb, b);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd
fe64b2ba25510d8c9dba5560a2d537763566cf40nd ap_pass_brigade(r->connection->output_filters, bb);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd
fe64b2ba25510d8c9dba5560a2d537763566cf40nd /* From here onward, it is no longer safe to reference r
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * or r->pool, because r->pool may have been destroyed
313bb560bc5c323cfd40c9cad7335b4b8e060aedkess * already by the EOR bucket's cleanup function.
ff797e743eb73c1d45b08158aa6b288c2d0c46eeslive */
ff797e743eb73c1d45b08158aa6b288c2d0c46eeslive
6b64034fa2a644ba291c484c0c01c7df5b8d982ckess c->cs->state = CONN_STATE_WRITE_COMPLETION;
6b64034fa2a644ba291c484c0c01c7df5b8d982ckess check_pipeline(c);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, r->status);
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd if (ap_extended_status) {
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd ap_time_process_request(c->sbh, STOP_PREQUEST);
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd }
06ba4a61654b3763ad65f52283832ebf058fdf1cslive}
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
06ba4a61654b3763ad65f52283832ebf058fdf1cslivevoid ap_process_async_request(request_rec *r)
06ba4a61654b3763ad65f52283832ebf058fdf1cslive{
06ba4a61654b3763ad65f52283832ebf058fdf1cslive conn_rec *c = r->connection;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive int access_status;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
130d299c4b2b15be45532a176604c71fdc7bea5bnd /* Give quick handlers a shot at serving the request on the fast
130d299c4b2b15be45532a176604c71fdc7bea5bnd * path, bypassing all of the other Apache hooks.
130d299c4b2b15be45532a176604c71fdc7bea5bnd *
130d299c4b2b15be45532a176604c71fdc7bea5bnd * This hook was added to enable serving files out of a URI keyed
130d299c4b2b15be45532a176604c71fdc7bea5bnd * content cache ( e.g., Mike Abbott's Quick Shortcut Cache,
130d299c4b2b15be45532a176604c71fdc7bea5bnd * described here: http://oss.sgi.com/projects/apache/mod_qsc.html )
130d299c4b2b15be45532a176604c71fdc7bea5bnd *
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * It may have other uses as well, such as routing requests directly to
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * content handlers that have the ability to grok HTTP and do their
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * own access checking, etc (e.g. servlet engines).
fe64b2ba25510d8c9dba5560a2d537763566cf40nd *
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * Use this hook with extreme care and only if you know what you are
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * doing.
fe64b2ba25510d8c9dba5560a2d537763566cf40nd */
fe64b2ba25510d8c9dba5560a2d537763566cf40nd AP_PROCESS_REQUEST_ENTRY((uintptr_t)r, r->uri);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd if (ap_extended_status) {
fe64b2ba25510d8c9dba5560a2d537763566cf40nd ap_time_process_request(r->connection->sbh, START_PREQUEST);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd }
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd
627c978514c54179736d152923478be7c8707f9bnd apr_thread_mutex_create(&r->invoke_mtx, APR_THREAD_MUTEX_DEFAULT, r->pool);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd apr_thread_mutex_lock(r->invoke_mtx);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd access_status = ap_run_quick_handler(r, 0); /* Not a look-up request */
fe64b2ba25510d8c9dba5560a2d537763566cf40nd if (access_status == DECLINED) {
fe64b2ba25510d8c9dba5560a2d537763566cf40nd access_status = ap_process_request_internal(r);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd if (access_status == OK) {
fe64b2ba25510d8c9dba5560a2d537763566cf40nd access_status = ap_invoke_handler(r);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd }
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd }
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd if (access_status == SUSPENDED) {
888b616027180cc8aaa4d2bee5ecc6acec175bc5nd /* TODO: Should move these steps into a generic function, so modules
b95ae799514ad86a15610ad75808d7065e9847c9kess * working on a suspended request can also call _ENTRY again.
888b616027180cc8aaa4d2bee5ecc6acec175bc5nd */
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, access_status);
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd if (ap_extended_status) {
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd ap_time_process_request(c->sbh, STOP_PREQUEST);
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd }
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd c->cs->state = CONN_STATE_SUSPENDED;
604c89126c27104f659d7a51b0113e3bd435faf8fielding apr_thread_mutex_unlock(r->invoke_mtx);
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd return;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive }
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd apr_thread_mutex_unlock(r->invoke_mtx);
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd if (access_status == DONE) {
fe64b2ba25510d8c9dba5560a2d537763566cf40nd /* e.g., something not in storage like TRACE */
888b616027180cc8aaa4d2bee5ecc6acec175bc5nd access_status = OK;
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd }
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd if (access_status == OK) {
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd ap_finalize_request_protocol(r);
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd }
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd else {
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd r->status = HTTP_OK;
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd ap_die(access_status, r);
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd }
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd ap_process_request_after_handler(r);
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd}
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd
5224ff8eae5156a05f676f1dad8add2e2f2efe1dndvoid ap_process_request(request_rec *r)
fe64b2ba25510d8c9dba5560a2d537763566cf40nd{
fe64b2ba25510d8c9dba5560a2d537763566cf40nd apr_bucket_brigade *bb;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd apr_bucket *b;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd conn_rec *c = r->connection;
604c89126c27104f659d7a51b0113e3bd435faf8fielding apr_status_t rv;
fb77c505254b6e9c925e23e734463e87574f8f40kess
604c89126c27104f659d7a51b0113e3bd435faf8fielding ap_process_async_request(r);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd
fe64b2ba25510d8c9dba5560a2d537763566cf40nd if (!c->data_in_input_filters) {
fe64b2ba25510d8c9dba5560a2d537763566cf40nd bb = apr_brigade_create(c->pool, c->bucket_alloc);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd b = apr_bucket_flush_create(c->bucket_alloc);
6fe26506780e73be2a412d758af77fafdf03291and APR_BRIGADE_INSERT_HEAD(bb, b);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd rv = ap_pass_brigade(c->output_filters, bb);
58699879a562774640b95e9eedfd891f336e38c2nd if (APR_STATUS_IS_TIMEUP(rv)) {
604c89126c27104f659d7a51b0113e3bd435faf8fielding /*
6fe26506780e73be2a412d758af77fafdf03291and * Notice a timeout as an error message. This might be
6fe26506780e73be2a412d758af77fafdf03291and * valuable for detecting clients with broken network
58699879a562774640b95e9eedfd891f336e38c2nd * connections or possible DoS attacks.
fb77c505254b6e9c925e23e734463e87574f8f40kess *
fb77c505254b6e9c925e23e734463e87574f8f40kess * It is still save to use r / r->pool here as the eor bucket
fb77c505254b6e9c925e23e734463e87574f8f40kess * could not have been destroyed in the event of a timeout.
fb77c505254b6e9c925e23e734463e87574f8f40kess */
fb77c505254b6e9c925e23e734463e87574f8f40kess ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
58699879a562774640b95e9eedfd891f336e38c2nd "Timeout while writing data for URI %s to the"
58699879a562774640b95e9eedfd891f336e38c2nd " client", r->unparsed_uri);
58699879a562774640b95e9eedfd891f336e38c2nd }
58699879a562774640b95e9eedfd891f336e38c2nd }
58699879a562774640b95e9eedfd891f336e38c2nd if (ap_extended_status) {
6b64034fa2a644ba291c484c0c01c7df5b8d982ckess ap_time_process_request(c->sbh, STOP_PREQUEST);
6b64034fa2a644ba291c484c0c01c7df5b8d982ckess }
58699879a562774640b95e9eedfd891f336e38c2nd}
6b64034fa2a644ba291c484c0c01c7df5b8d982ckess
58699879a562774640b95e9eedfd891f336e38c2ndstatic apr_table_t *rename_original_env(apr_pool_t *p, apr_table_t *t)
58699879a562774640b95e9eedfd891f336e38c2nd{
fb77c505254b6e9c925e23e734463e87574f8f40kess const apr_array_header_t *env_arr = apr_table_elts(t);
fb77c505254b6e9c925e23e734463e87574f8f40kess const apr_table_entry_t *elts = (const apr_table_entry_t *) env_arr->elts;
fb77c505254b6e9c925e23e734463e87574f8f40kess apr_table_t *new = apr_table_make(p, env_arr->nalloc);
58699879a562774640b95e9eedfd891f336e38c2nd int i;
58699879a562774640b95e9eedfd891f336e38c2nd
58699879a562774640b95e9eedfd891f336e38c2nd for (i = 0; i < env_arr->nelts; ++i) {
58699879a562774640b95e9eedfd891f336e38c2nd if (!elts[i].key)
58699879a562774640b95e9eedfd891f336e38c2nd continue;
58699879a562774640b95e9eedfd891f336e38c2nd apr_table_setn(new, apr_pstrcat(p, "REDIRECT_", elts[i].key, NULL),
58699879a562774640b95e9eedfd891f336e38c2nd elts[i].val);
58699879a562774640b95e9eedfd891f336e38c2nd }
58699879a562774640b95e9eedfd891f336e38c2nd
58699879a562774640b95e9eedfd891f336e38c2nd return new;
313bb560bc5c323cfd40c9cad7335b4b8e060aedkess}
4a7affccb2f1f5b94cab395e1bf3825aed715ebcnd
9b5e2c5e769dc678a1aca06df75c32022b2f1492trawickstatic request_rec *internal_internal_redirect(const char *new_uri,
604c89126c27104f659d7a51b0113e3bd435faf8fielding request_rec *r) {
604c89126c27104f659d7a51b0113e3bd435faf8fielding int access_status;
604c89126c27104f659d7a51b0113e3bd435faf8fielding request_rec *new;
604c89126c27104f659d7a51b0113e3bd435faf8fielding
4a7affccb2f1f5b94cab395e1bf3825aed715ebcnd if (ap_is_recursion_limit_exceeded(r)) {
4a7affccb2f1f5b94cab395e1bf3825aed715ebcnd ap_die(HTTP_INTERNAL_SERVER_ERROR, r);
4a7affccb2f1f5b94cab395e1bf3825aed715ebcnd return NULL;
58699879a562774640b95e9eedfd891f336e38c2nd }
fe64b2ba25510d8c9dba5560a2d537763566cf40nd
fe64b2ba25510d8c9dba5560a2d537763566cf40nd new = (request_rec *) apr_pcalloc(r->pool, sizeof(request_rec));
fe64b2ba25510d8c9dba5560a2d537763566cf40nd
fe64b2ba25510d8c9dba5560a2d537763566cf40nd new->connection = r->connection;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd new->server = r->server;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd new->pool = r->pool;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd
fe64b2ba25510d8c9dba5560a2d537763566cf40nd /*
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * A whole lot of this really ought to be shared with http_protocol.c...
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd * another missing cleanup. It's particularly inappropriate to be
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd * setting header_only, etc., here.
9583adab6bc4b3758e41963c905d9dad9f067131nd */
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd new->method = r->method;
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd new->method_number = r->method_number;
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd new->allowed_methods = ap_make_method_list(new->pool, 2);
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd ap_parse_uri(new, new_uri);
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd new->request_config = ap_create_request_config(r->pool);
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd new->per_dir_config = r->server->lookup_defaults;
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd new->prev = r;
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd r->next = new;
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd /* Must have prev and next pointers set before calling create_request
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd * hook.
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd */
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd ap_run_create_request(new);
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd
9b5e2c5e769dc678a1aca06df75c32022b2f1492trawick /* Inherit the rest of the protocol info... */
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd new->the_request = r->the_request;
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd new->allowed = r->allowed;
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd new->status = r->status;
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd new->assbackwards = r->assbackwards;
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd new->header_only = r->header_only;
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd new->protocol = r->protocol;
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd new->proto_num = r->proto_num;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd new->hostname = r->hostname;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd new->request_time = r->request_time;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd new->main = r->main;
627c978514c54179736d152923478be7c8707f9bnd
fb77c505254b6e9c925e23e734463e87574f8f40kess new->headers_in = r->headers_in;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd new->headers_out = apr_table_make(r->pool, 12);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd new->err_headers_out = r->err_headers_out;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd new->subprocess_env = rename_original_env(r->pool, r->subprocess_env);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd new->notes = apr_table_make(r->pool, 5);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd new->allowed_methods = ap_make_method_list(new->pool, 2);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd
fb77c505254b6e9c925e23e734463e87574f8f40kess new->htaccess = r->htaccess;
fb77c505254b6e9c925e23e734463e87574f8f40kess new->no_cache = r->no_cache;
fb77c505254b6e9c925e23e734463e87574f8f40kess new->expecting_100 = r->expecting_100;
6b64034fa2a644ba291c484c0c01c7df5b8d982ckess new->no_local_copy = r->no_local_copy;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive new->read_length = r->read_length; /* We can only read it once */
313bb560bc5c323cfd40c9cad7335b4b8e060aedkess new->vlist_validator = r->vlist_validator;
10673857794a4b3d9568ca2d983722a87ed352f1rbowen
fb77c505254b6e9c925e23e734463e87574f8f40kess new->proto_output_filters = r->proto_output_filters;
ed0dae472b518c553c923a86fb4322d4c50d86a6nd new->proto_input_filters = r->proto_input_filters;
ed0dae472b518c553c923a86fb4322d4c50d86a6nd
10673857794a4b3d9568ca2d983722a87ed352f1rbowen new->output_filters = new->proto_output_filters;
10673857794a4b3d9568ca2d983722a87ed352f1rbowen new->input_filters = new->proto_input_filters;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
fb77c505254b6e9c925e23e734463e87574f8f40kess if (new->main) {
fb77c505254b6e9c925e23e734463e87574f8f40kess /* Add back the subrequest filter, which we lost when
fb77c505254b6e9c925e23e734463e87574f8f40kess * we set output_filters to include only the protocol
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * output filters from the original request.
06ba4a61654b3763ad65f52283832ebf058fdf1cslive */
06ba4a61654b3763ad65f52283832ebf058fdf1cslive ap_add_output_filter_handle(ap_subreq_core_filter_handle,
fb77c505254b6e9c925e23e734463e87574f8f40kess NULL, new, new->connection);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive }
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd
06ba4a61654b3763ad65f52283832ebf058fdf1cslive update_r_in_filters(new->input_filters, r, new);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive update_r_in_filters(new->output_filters, r, new);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
06ba4a61654b3763ad65f52283832ebf058fdf1cslive apr_table_setn(new->subprocess_env, "REDIRECT_STATUS",
06ba4a61654b3763ad65f52283832ebf058fdf1cslive apr_itoa(r->pool, r->status));
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
06ba4a61654b3763ad65f52283832ebf058fdf1cslive /*
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz * XXX: hmm. This is because mod_setenvif and mod_unique_id really need
1f53e295ebd19aed1767d12da7abfab9936c148cjerenkrantz * to do their thing on internal redirects as well. Perhaps this is a
cb3a1082aec4b3b4f4ed238c93c3cc54933a7f0end * misnamed function.
9335f6d807d76d60e54af4ededdebebddb3e3d13noodl */
9335f6d807d76d60e54af4ededdebebddb3e3d13noodl if ((access_status = ap_run_post_read_request(new))) {
06ba4a61654b3763ad65f52283832ebf058fdf1cslive ap_die(access_status, new);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive return NULL;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive }
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
604c89126c27104f659d7a51b0113e3bd435faf8fielding return new;
604c89126c27104f659d7a51b0113e3bd435faf8fielding}
604c89126c27104f659d7a51b0113e3bd435faf8fielding
604c89126c27104f659d7a51b0113e3bd435faf8fielding/* XXX: Is this function is so bogus and fragile that we deep-6 it? */
604c89126c27104f659d7a51b0113e3bd435faf8fieldingAP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r)
604c89126c27104f659d7a51b0113e3bd435faf8fielding{
604c89126c27104f659d7a51b0113e3bd435faf8fielding /* We need to tell POOL_DEBUG that we're guaranteeing that rr->pool
604c89126c27104f659d7a51b0113e3bd435faf8fielding * will exist as long as r->pool. Otherwise we run into troubles because
604c89126c27104f659d7a51b0113e3bd435faf8fielding * some values in this request will be allocated in r->pool, and others in
909ce17e2bd0faef7b1c294f2307f009793fd493nd * rr->pool.
909ce17e2bd0faef7b1c294f2307f009793fd493nd */
909ce17e2bd0faef7b1c294f2307f009793fd493nd apr_pool_join(r->pool, rr->pool);
909ce17e2bd0faef7b1c294f2307f009793fd493nd r->proxyreq = rr->proxyreq;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->no_cache = (r->no_cache && rr->no_cache);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->no_local_copy = (r->no_local_copy && rr->no_local_copy);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->mtime = rr->mtime;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->uri = rr->uri;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->filename = rr->filename;
97a9a944b5887e91042b019776c41d5dd74557aferikabele r->canonical_filename = rr->canonical_filename;
97a9a944b5887e91042b019776c41d5dd74557aferikabele r->path_info = rr->path_info;
97a9a944b5887e91042b019776c41d5dd74557aferikabele r->args = rr->args;
97a9a944b5887e91042b019776c41d5dd74557aferikabele r->finfo = rr->finfo;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->handler = rr->handler;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive ap_set_content_type(r, rr->content_type);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->content_encoding = rr->content_encoding;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->content_languages = rr->content_languages;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->per_dir_config = rr->per_dir_config;
cb3a1082aec4b3b4f4ed238c93c3cc54933a7f0end /* copy output headers from subrequest, but leave negotiation headers */
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->notes = apr_table_overlay(r->pool, rr->notes, r->notes);
8e31885fc494b603e0650113dde9e29d1b1d2602maczniak r->headers_out = apr_table_overlay(r->pool, rr->headers_out,
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->headers_out);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->err_headers_out = apr_table_overlay(r->pool, rr->err_headers_out,
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->err_headers_out);
97a9a944b5887e91042b019776c41d5dd74557aferikabele r->subprocess_env = apr_table_overlay(r->pool, rr->subprocess_env,
8e31885fc494b603e0650113dde9e29d1b1d2602maczniak r->subprocess_env);
8e31885fc494b603e0650113dde9e29d1b1d2602maczniak
f23fb63b05f89f47d7a3099491f2c68dcce432e9kess r->output_filters = rr->output_filters;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive r->input_filters = rr->input_filters;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
06ba4a61654b3763ad65f52283832ebf058fdf1cslive /* If any filters pointed at the now-defunct rr, we must point them
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * at our "new" instance of r. In particular, some of rr's structures
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd * will now be bogus (say rr->headers_out). If a filter tried to modify
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd * their f->r structure when it is pointing to rr, the real request_rec
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd * will not get updated. Fix that here.
fe64b2ba25510d8c9dba5560a2d537763566cf40nd */
ed0dae472b518c553c923a86fb4322d4c50d86a6nd update_r_in_filters(r->input_filters, rr, r);
ed0dae472b518c553c923a86fb4322d4c50d86a6nd update_r_in_filters(r->output_filters, rr, r);
ed0dae472b518c553c923a86fb4322d4c50d86a6nd
ed0dae472b518c553c923a86fb4322d4c50d86a6nd if (r->main) {
da637bcae7b6e150470e701af29da5604a34a17erbowen ap_add_output_filter_handle(ap_subreq_core_filter_handle,
da637bcae7b6e150470e701af29da5604a34a17erbowen NULL, r, r->connection);
da637bcae7b6e150470e701af29da5604a34a17erbowen }
da637bcae7b6e150470e701af29da5604a34a17erbowen else {
da637bcae7b6e150470e701af29da5604a34a17erbowen /*
da637bcae7b6e150470e701af29da5604a34a17erbowen * We need to check if we now have the SUBREQ_CORE filter in our filter
da637bcae7b6e150470e701af29da5604a34a17erbowen * chain. If this is the case we need to remove it since we are NO
da637bcae7b6e150470e701af29da5604a34a17erbowen * subrequest. But we need to keep in mind that the SUBREQ_CORE filter
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * does not necessarily need to be the first filter in our chain. So we
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * need to go through the chain. But we only need to walk up the chain
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * until the proto_output_filters as the SUBREQ_CORE filter is below the
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * protocol filters.
fe64b2ba25510d8c9dba5560a2d537763566cf40nd */
fe64b2ba25510d8c9dba5560a2d537763566cf40nd ap_filter_t *next;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd
fe64b2ba25510d8c9dba5560a2d537763566cf40nd next = r->output_filters;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd while (next && (next->frec != ap_subreq_core_filter_handle)
fe64b2ba25510d8c9dba5560a2d537763566cf40nd && (next != r->proto_output_filters)) {
fb77c505254b6e9c925e23e734463e87574f8f40kess next = next->next;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd }
fb77c505254b6e9c925e23e734463e87574f8f40kess if (next && (next->frec == ap_subreq_core_filter_handle)) {
fe64b2ba25510d8c9dba5560a2d537763566cf40nd ap_remove_output_filter(next);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd }
fe64b2ba25510d8c9dba5560a2d537763566cf40nd }
fe64b2ba25510d8c9dba5560a2d537763566cf40nd}
c985aca104389df30d6ec0a637ce0ccaac904362nd
fe64b2ba25510d8c9dba5560a2d537763566cf40ndAP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r)
70ada6b79498c38ab85985a3d30ee11248ce897byoshiki{
fb77c505254b6e9c925e23e734463e87574f8f40kess request_rec *new = internal_internal_redirect(new_uri, r);
fb77c505254b6e9c925e23e734463e87574f8f40kess int access_status;
313bb560bc5c323cfd40c9cad7335b4b8e060aedkess
313bb560bc5c323cfd40c9cad7335b4b8e060aedkess AP_INTERNAL_REDIRECT(r->uri, new_uri);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd
fe64b2ba25510d8c9dba5560a2d537763566cf40nd /* ap_die was already called, if an error occured */
fe64b2ba25510d8c9dba5560a2d537763566cf40nd if (!new) {
fe64b2ba25510d8c9dba5560a2d537763566cf40nd return;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd }
627c978514c54179736d152923478be7c8707f9bnd
fe64b2ba25510d8c9dba5560a2d537763566cf40nd access_status = ap_run_quick_handler(new, 0); /* Not a look-up request */
fb77c505254b6e9c925e23e734463e87574f8f40kess if (access_status == DECLINED) {
fb77c505254b6e9c925e23e734463e87574f8f40kess access_status = ap_process_request_internal(new);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd if (access_status == OK) {
fe64b2ba25510d8c9dba5560a2d537763566cf40nd access_status = ap_invoke_handler(new);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd }
fe64b2ba25510d8c9dba5560a2d537763566cf40nd }
fe64b2ba25510d8c9dba5560a2d537763566cf40nd if (access_status == OK) {
06ba4a61654b3763ad65f52283832ebf058fdf1cslive ap_finalize_request_protocol(new);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive }
5bb5fba250bf526bc51d13b25378d54acb93c1cbnoodl else {
06ba4a61654b3763ad65f52283832ebf058fdf1cslive ap_die(access_status, new);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive }
06ba4a61654b3763ad65f52283832ebf058fdf1cslive}
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
06ba4a61654b3763ad65f52283832ebf058fdf1cslive/* This function is designed for things like actions or CGI scripts, when
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * using AddHandler, and you want to preserve the content type across
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * an internal redirect.
06ba4a61654b3763ad65f52283832ebf058fdf1cslive */
06ba4a61654b3763ad65f52283832ebf058fdf1csliveAP_DECLARE(void) ap_internal_redirect_handler(const char *new_uri, request_rec *r)
06ba4a61654b3763ad65f52283832ebf058fdf1cslive{
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd int access_status;
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd request_rec *new = internal_internal_redirect(new_uri, r);
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd /* ap_die was already called, if an error occured */
06ba4a61654b3763ad65f52283832ebf058fdf1cslive if (!new) {
06ba4a61654b3763ad65f52283832ebf058fdf1cslive return;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive }
06ba4a61654b3763ad65f52283832ebf058fdf1cslive
06ba4a61654b3763ad65f52283832ebf058fdf1cslive if (r->handler)
06ba4a61654b3763ad65f52283832ebf058fdf1cslive ap_set_content_type(new, r->content_type);
fb77c505254b6e9c925e23e734463e87574f8f40kess access_status = ap_process_request_internal(new);
fb77c505254b6e9c925e23e734463e87574f8f40kess if (access_status == OK) {
fb77c505254b6e9c925e23e734463e87574f8f40kess if ((access_status = ap_invoke_handler(new)) != 0) {
fe64b2ba25510d8c9dba5560a2d537763566cf40nd ap_die(access_status, new);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd return;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd }
fe64b2ba25510d8c9dba5560a2d537763566cf40nd ap_finalize_request_protocol(new);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd }
604c89126c27104f659d7a51b0113e3bd435faf8fielding else {
604c89126c27104f659d7a51b0113e3bd435faf8fielding ap_die(access_status, new);
604c89126c27104f659d7a51b0113e3bd435faf8fielding }
604c89126c27104f659d7a51b0113e3bd435faf8fielding}
604c89126c27104f659d7a51b0113e3bd435faf8fielding
604c89126c27104f659d7a51b0113e3bd435faf8fieldingAP_DECLARE(void) ap_allow_methods(request_rec *r, int reset, ...)
604c89126c27104f659d7a51b0113e3bd435faf8fielding{
fe64b2ba25510d8c9dba5560a2d537763566cf40nd const char *method;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd va_list methods;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd
fe64b2ba25510d8c9dba5560a2d537763566cf40nd /*
604c89126c27104f659d7a51b0113e3bd435faf8fielding * Get rid of any current settings if requested; not just the
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * well-known methods but any extensions as well.
604c89126c27104f659d7a51b0113e3bd435faf8fielding */
604c89126c27104f659d7a51b0113e3bd435faf8fielding if (reset) {
604c89126c27104f659d7a51b0113e3bd435faf8fielding ap_clear_method_list(r->allowed_methods);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive }
22265f1724519886e2a2b5e0ebd61477506b7379noodl
22265f1724519886e2a2b5e0ebd61477506b7379noodl va_start(methods, reset);
22265f1724519886e2a2b5e0ebd61477506b7379noodl while ((method = va_arg(methods, const char *)) != NULL) {
22265f1724519886e2a2b5e0ebd61477506b7379noodl ap_method_list_add(r->allowed_methods, method);
604c89126c27104f659d7a51b0113e3bd435faf8fielding }
604c89126c27104f659d7a51b0113e3bd435faf8fielding va_end(methods);
604c89126c27104f659d7a51b0113e3bd435faf8fielding}
604c89126c27104f659d7a51b0113e3bd435faf8fielding
604c89126c27104f659d7a51b0113e3bd435faf8fieldingAP_DECLARE(void) ap_allow_standard_methods(request_rec *r, int reset, ...)
604c89126c27104f659d7a51b0113e3bd435faf8fielding{
604c89126c27104f659d7a51b0113e3bd435faf8fielding int method;
604c89126c27104f659d7a51b0113e3bd435faf8fielding va_list methods;
604c89126c27104f659d7a51b0113e3bd435faf8fielding apr_int64_t mask;
604c89126c27104f659d7a51b0113e3bd435faf8fielding
fe64b2ba25510d8c9dba5560a2d537763566cf40nd /*
9597f440430d8c876dd64f5f78066804650a18ecnoodl * Get rid of any current settings if requested; not just the
9597f440430d8c876dd64f5f78066804650a18ecnoodl * well-known methods but any extensions as well.
9597f440430d8c876dd64f5f78066804650a18ecnoodl */
9597f440430d8c876dd64f5f78066804650a18ecnoodl if (reset) {
9597f440430d8c876dd64f5f78066804650a18ecnoodl ap_clear_method_list(r->allowed_methods);
9597f440430d8c876dd64f5f78066804650a18ecnoodl }
9597f440430d8c876dd64f5f78066804650a18ecnoodl
9597f440430d8c876dd64f5f78066804650a18ecnoodl mask = 0;
9597f440430d8c876dd64f5f78066804650a18ecnoodl va_start(methods, reset);
9597f440430d8c876dd64f5f78066804650a18ecnoodl while ((method = va_arg(methods, int)) != -1) {
1d980e5489836e977ba59b419e27b0ec875c4bd3takashi mask |= (AP_METHOD_BIT << method);
9597f440430d8c876dd64f5f78066804650a18ecnoodl }
9597f440430d8c876dd64f5f78066804650a18ecnoodl va_end(methods);
9597f440430d8c876dd64f5f78066804650a18ecnoodl
fe64b2ba25510d8c9dba5560a2d537763566cf40nd r->allowed_methods->method_mask |= mask;
fe64b2ba25510d8c9dba5560a2d537763566cf40nd}
fe64b2ba25510d8c9dba5560a2d537763566cf40nd