⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 http_request.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * http_request.c: functions to get and process requests * * Rob McCool 3/21/93 * * Thoroughly revamped by rst for Apache.  NB this file reads * best from the bottom up. * */#include "apr_strings.h"#include "apr_file_io.h"#include "apr_fnmatch.h"#define APR_WANT_STRFUNC#include "apr_want.h"#define CORE_PRIVATE#include "ap_config.h"#include "httpd.h"#include "http_config.h"#include "http_request.h"#include "http_core.h"#include "http_protocol.h"#include "http_log.h"#include "http_main.h"#include "util_filter.h"#include "util_charset.h"#include "scoreboard.h"#include "mod_core.h"#if APR_HAVE_STDARG_H#include <stdarg.h>#endif/***************************************************************** * * Mainline request processing... *//* XXX A cleaner and faster way to do this might be to pass the request_rec * down the filter chain as a parameter.  It would need to change for * subrequest vs. main request filters; perhaps the subrequest filter could * make the switch. */static void update_r_in_filters(ap_filter_t *f,                                request_rec *from,                                request_rec *to){    while (f) {        if (f->r == from) {            f->r = to;        }        f = f->next;    }}AP_DECLARE(void) ap_die(int type, request_rec *r){    int error_index = ap_index_of_response(type);    char *custom_response = ap_response_code_string(r, error_index);    int recursive_error = 0;    request_rec *r_1st_err = r;    if (type == AP_FILTER_ERROR) {        ap_filter_t *next;        /*         * Check if we still have the ap_http_header_filter in place. If         * this is the case we should not ignore AP_FILTER_ERROR here because         * it means that we have not sent any response at all and never         * will. This is bad. Sent an internal server error instead.         */        next = r->output_filters;        while (next && (next->frec != ap_http_header_filter_handle)) {               next = next->next;        }        /*         * If next != NULL then we left the while above because of         * next->frec == ap_http_header_filter         */        if (next) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                          "Custom error page caused AP_FILTER_ERROR");            type = HTTP_INTERNAL_SERVER_ERROR;        }        else {            return;        }    }    if (type == DONE) {        ap_finalize_request_protocol(r);        return;    }    /*     * The following takes care of Apache redirects to custom response URLs     * Note that if we are already dealing with the response to some other     * error condition, we just report on the original error, and give up on     * any attempt to handle the other thing "intelligently"...     */    if (r->status != HTTP_OK) {        recursive_error = type;        while (r_1st_err->prev && (r_1st_err->prev->status != HTTP_OK))            r_1st_err = r_1st_err->prev;  /* Get back to original error */        if (r_1st_err != r) {            /* The recursive error was caused by an ErrorDocument specifying             * an internal redirect to a bad URI.  ap_internal_redirect has             * changed the filter chains to point to the ErrorDocument's             * request_rec.  Back out those changes so we can safely use the             * original failing request_rec to send the canned error message.             *             * ap_send_error_response gets rid of existing resource filters             * on the output side, so we can skip those.             */            update_r_in_filters(r_1st_err->proto_output_filters, r, r_1st_err);            update_r_in_filters(r_1st_err->input_filters, r, r_1st_err);        }        custom_response = NULL; /* Do NOT retry the custom thing! */    }    r->status = type;    /*     * This test is done here so that none of the auth modules needs to know     * about proxy authentication.  They treat it like normal auth, and then     * we tweak the status.     */    if (HTTP_UNAUTHORIZED == r->status && PROXYREQ_PROXY == r->proxyreq) {        r->status = HTTP_PROXY_AUTHENTICATION_REQUIRED;    }    /* If we don't want to keep the connection, make sure we mark that the     * connection is not eligible for keepalive.  If we want to keep the     * connection, be sure that the request body (if any) has been read.     */    if (ap_status_drops_connection(r->status)) {        r->connection->keepalive = AP_CONN_CLOSE;    }    /*     * Two types of custom redirects --- plain text, and URLs. Plain text has     * a leading '"', so the URL code, here, is triggered on its absence     */    if (custom_response && custom_response[0] != '"') {        if (ap_is_url(custom_response)) {            /*             * The URL isn't local, so lets drop through the rest of this             * apache code, and continue with the usual REDIRECT handler.             * But note that the client will ultimately see the wrong             * status...             */            r->status = HTTP_MOVED_TEMPORARILY;            apr_table_setn(r->headers_out, "Location", custom_response);        }        else if (custom_response[0] == '/') {            const char *error_notes;            r->no_local_copy = 1;       /* Do NOT send HTTP_NOT_MODIFIED for                                         * error documents! */            /*             * This redirect needs to be a GET no matter what the original             * method was.             */            apr_table_setn(r->subprocess_env, "REQUEST_METHOD", r->method);            /*             * Provide a special method for modules to communicate             * more informative (than the plain canned) messages to us.             * Propagate them to ErrorDocuments via the ERROR_NOTES variable:             */            if ((error_notes = apr_table_get(r->notes,                                             "error-notes")) != NULL) {                apr_table_setn(r->subprocess_env, "ERROR_NOTES", error_notes);            }            r->method = apr_pstrdup(r->pool, "GET");            r->method_number = M_GET;            ap_internal_redirect(custom_response, r);            return;        }        else {            /*             * Dumb user has given us a bad url to redirect to --- fake up             * dying with a recursive server error...             */            recursive_error = HTTP_INTERNAL_SERVER_ERROR;            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                        "Invalid error redirection directive: %s",                        custom_response);        }    }    ap_send_error_response(r_1st_err, recursive_error);}static void check_pipeline_flush(request_rec *r){    apr_bucket *e;    apr_bucket_brigade *bb;    conn_rec *c = r->connection;    /* ### if would be nice if we could PEEK without a brigade. that would       ### allow us to defer creation of the brigade to when we actually       ### need to send a FLUSH. */    bb = apr_brigade_create(r->pool, c->bucket_alloc);    /* Flush the filter contents if:     *     *   1) the connection will be closed     *   2) there isn't a request ready to be read     */    /* ### shouldn't this read from the connection input filters? */    /* ### is zero correct? that means "read one line" */    if (r->connection->keepalive != AP_CONN_CLOSE) {        if (ap_get_brigade(r->input_filters, bb, AP_MODE_EATCRLF,                       APR_NONBLOCK_READ, 0) != APR_SUCCESS) {            c->data_in_input_filters = 0;  /* we got APR_EOF or an error */        }        else {            c->data_in_input_filters = 1;            return;    /* don't flush */        }    }        e = apr_bucket_flush_create(c->bucket_alloc);        /* We just send directly to the connection based filters.  At         * this point, we know that we have seen all of the data         * (request finalization sent an EOS bucket, which empties all         * of the request filters). We just want to flush the buckets         * if something hasn't been sent to the network yet.         */        APR_BRIGADE_INSERT_HEAD(bb, e);        ap_pass_brigade(r->connection->output_filters, bb);}void ap_process_request(request_rec *r){    int access_status;    /* Give quick handlers a shot at serving the request on the fast     * path, bypassing all of the other Apache hooks.     *     * This hook was added to enable serving files out of a URI keyed     * content cache ( e.g., Mike Abbott's Quick Shortcut Cache,     * described here: http://oss.sgi.com/projects/apache/mod_qsc.html )     *     * It may have other uses as well, such as routing requests directly to     * content handlers that have the ability to grok HTTP and do their     * own access checking, etc (e.g. servlet engines).     *     * Use this hook with extreme care and only if you know what you are     * doing.     */    if (ap_extended_status)        ap_time_process_request(r->connection->sbh, START_PREQUEST);    access_status = ap_run_quick_handler(r, 0);  /* Not a look-up request */    if (access_status == DECLINED) {        access_status = ap_process_request_internal(r);        if (access_status == OK) {            access_status = ap_invoke_handler(r);        }    }    if (access_status == DONE) {        /* e.g., something not in storage like TRACE */        access_status = OK;    }    if (access_status == OK) {        ap_finalize_request_protocol(r);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -