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

📄 http_request.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed 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 "mod_core.h"#include "scoreboard.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) {        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){    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. */    apr_bucket_brigade *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 ||         ap_get_brigade(r->input_filters, bb, AP_MODE_EATCRLF,                        APR_NONBLOCK_READ, 0) != APR_SUCCESS) {        apr_bucket *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);    }    else {        ap_die(access_status, r);    }        /*     * We want to flush the last packet if this isn't a pipelining connection     * *before* we start into logging.  Suppose that the logging causes a DNS     * lookup to occur, which may have a high latency.  If we hold off on     * this packet, then it'll appear like the link is stalled when really     * it's the application that's stalled.     */    check_pipeline_flush(r);

⌨️ 快捷键说明

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