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

📄 protocol.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 4 页
字号:
                tmp_field = last_field + last_len - 1;                while (tmp_field > value                       && (*tmp_field == ' ' || *tmp_field == '\t')) {                    *tmp_field-- = '\0';                }                apr_table_addn(r->headers_in, last_field, value);                                /* reset the alloc_len so that we'll allocate a new                 * buffer if we have to do any more folding: we can't                 * use the previous buffer because its contents are                 * now part of r->headers_in                 */                alloc_len = 0;            } /* end if current line is not a continuation starting with tab */        }        /* Found a blank line, stop. */        if (len == 0) {            break;        }        /* Keep track of this line so that we can parse it on         * the next loop iteration.  (In the folded case, last_field         * has been updated already.)         */        if (!folded) {            last_field = field;            last_len = len;        }    }    apr_table_compress(r->headers_in, APR_OVERLAP_TABLES_MERGE);}AP_DECLARE(void) ap_get_mime_headers(request_rec *r){    apr_bucket_brigade *tmp_bb;    tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);    ap_get_mime_headers_core(r, tmp_bb);    apr_brigade_destroy(tmp_bb);}request_rec *ap_read_request(conn_rec *conn){    request_rec *r;    apr_pool_t *p;    const char *expect;    int access_status;    apr_bucket_brigade *tmp_bb;    apr_pool_create(&p, conn->pool);    apr_pool_tag(p, "request");    r = apr_pcalloc(p, sizeof(request_rec));    r->pool            = p;    r->connection      = conn;    r->server          = conn->base_server;    r->user            = NULL;    r->ap_auth_type    = NULL;    r->allowed_methods = ap_make_method_list(p, 2);    r->headers_in      = apr_table_make(r->pool, 25);    r->subprocess_env  = apr_table_make(r->pool, 25);    r->headers_out     = apr_table_make(r->pool, 12);    r->err_headers_out = apr_table_make(r->pool, 5);    r->notes           = apr_table_make(r->pool, 5);    r->request_config  = ap_create_request_config(r->pool);    /* Must be set before we run create request hook */    r->proto_output_filters = conn->output_filters;    r->output_filters  = r->proto_output_filters;    r->proto_input_filters = conn->input_filters;    r->input_filters   = r->proto_input_filters;    ap_run_create_request(r);    r->per_dir_config  = r->server->lookup_defaults;    r->sent_bodyct     = 0;                      /* bytect isn't for body */    r->read_length     = 0;    r->read_body       = REQUEST_NO_BODY;    r->status          = HTTP_REQUEST_TIME_OUT;  /* Until we get a request */    r->the_request     = NULL;    tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);    /* Get the request... */    if (!read_request_line(r, tmp_bb)) {        if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                          "request failed: URI too long (longer than %d)", r->server->limit_req_line);            ap_send_error_response(r, 0);            ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);            ap_run_log_transaction(r);            apr_brigade_destroy(tmp_bb);            return r;        }        apr_brigade_destroy(tmp_bb);        return NULL;    }    if (!r->assbackwards) {        ap_get_mime_headers_core(r, tmp_bb);        if (r->status != HTTP_REQUEST_TIME_OUT) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                          "request failed: error reading the headers");            ap_send_error_response(r, 0);            ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);            ap_run_log_transaction(r);            apr_brigade_destroy(tmp_bb);            return r;        }    }    else {        if (r->header_only) {            /*             * Client asked for headers only with HTTP/0.9, which doesn't send             * headers! Have to dink things just to make sure the error message             * comes through...             */            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                          "client sent invalid HTTP/0.9 request: HEAD %s",                          r->uri);            r->header_only = 0;            r->status = HTTP_BAD_REQUEST;            ap_send_error_response(r, 0);            ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);            ap_run_log_transaction(r);            apr_brigade_destroy(tmp_bb);            return r;        }    }    apr_brigade_destroy(tmp_bb);    r->status = HTTP_OK;                         /* Until further notice. */    /* update what we think the virtual host is based on the headers we've     * now read. may update status.     */    ap_update_vhost_from_headers(r);    /* we may have switched to another server */    r->per_dir_config = r->server->lookup_defaults;    if ((!r->hostname && (r->proto_num >= HTTP_VERSION(1, 1)))        || ((r->proto_num == HTTP_VERSION(1, 1))            && !apr_table_get(r->headers_in, "Host"))) {        /*         * Client sent us an HTTP/1.1 or later request without telling us the         * hostname, either with a full URL or a Host: header. We therefore         * need to (as per the 1.1 spec) send an error.  As a special case,         * HTTP/1.1 mentions twice (S9, S14.23) that a request MUST contain         * a Host: header, and the server MUST respond with 400 if it doesn't.         */        r->status = HTTP_BAD_REQUEST;        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                      "client sent HTTP/1.1 request without hostname "                      "(see RFC2616 section 14.23): %s", r->uri);    }    if (r->status != HTTP_OK) {        ap_send_error_response(r, 0);        ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);        ap_run_log_transaction(r);        return r;    }    if (((expect = apr_table_get(r->headers_in, "Expect")) != NULL)        && (expect[0] != '\0')) {        /*         * The Expect header field was added to HTTP/1.1 after RFC 2068         * as a means to signal when a 100 response is desired and,         * unfortunately, to signal a poor man's mandatory extension that         * the server must understand or return 417 Expectation Failed.         */        if (strcasecmp(expect, "100-continue") == 0) {            r->expecting_100 = 1;        }        else {            r->status = HTTP_EXPECTATION_FAILED;            ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,                          "client sent an unrecognized expectation value of "                          "Expect: %s", expect);            ap_send_error_response(r, 0);            ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);            ap_run_log_transaction(r);            return r;        }    }    ap_add_input_filter_handle(ap_http_input_filter_handle,                               NULL, r, r->connection);    if ((access_status = ap_run_post_read_request(r))) {        ap_die(access_status, r);        ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r);        ap_run_log_transaction(r);        return NULL;    }    return r;}/* * A couple of other functions which initialize some of the fields of * a request structure, as appropriate for adjuncts of one kind or another * to a request in progress.  Best here, rather than elsewhere, since * *someone* has to set the protocol-specific fields... */AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew,                                         const request_rec *r){    rnew->the_request     = r->the_request;  /* Keep original request-line */    rnew->assbackwards    = 1;   /* Don't send headers from this. */    rnew->no_local_copy   = 1;   /* Don't try to send HTTP_NOT_MODIFIED for a                                  * fragment. */    rnew->method          = "GET";    rnew->method_number   = M_GET;    rnew->protocol        = "INCLUDED";    rnew->status          = HTTP_OK;    rnew->headers_in      = r->headers_in;    rnew->subprocess_env  = apr_table_copy(rnew->pool, r->subprocess_env);    rnew->headers_out     = apr_table_make(rnew->pool, 5);    rnew->err_headers_out = apr_table_make(rnew->pool, 5);    rnew->notes           = apr_table_make(rnew->pool, 5);    rnew->expecting_100   = r->expecting_100;    rnew->read_length     = r->read_length;    rnew->read_body       = REQUEST_NO_BODY;    rnew->main = (request_rec *) r;}static void end_output_stream(request_rec *r){    conn_rec *c = r->connection;    apr_bucket_brigade *bb;    apr_bucket *b;    bb = apr_brigade_create(r->pool, c->bucket_alloc);    b = apr_bucket_eos_create(c->bucket_alloc);    APR_BRIGADE_INSERT_TAIL(bb, b);    ap_pass_brigade(r->output_filters, bb);}AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub){    /* tell the filter chain there is no more content coming */    if (!sub->eos_sent) {        end_output_stream(sub);    }}/* finalize_request_protocol is called at completion of sending the * response.  Its sole purpose is to send the terminating protocol * information for any wrappers around the response message body * (i.e., transfer encodings).  It should have been named finalize_response. */AP_DECLARE(void) ap_finalize_request_protocol(request_rec *r){    (void) ap_discard_request_body(r);    /* tell the filter chain there is no more content coming */    if (!r->eos_sent) {        end_output_stream(r);    }}/* * Support for the Basic authentication protocol, and a bit for Digest. */AP_DECLARE(void) ap_note_auth_failure(request_rec *r){    const char *type = ap_auth_type(r);    if (type) {        if (!strcasecmp(type, "Basic"))            ap_note_basic_auth_failure(r);        else if (!strcasecmp(type, "Digest"))            ap_note_digest_auth_failure(r);    }    else {        ap_log_rerror(APLOG_MARK, APLOG_ERR,                      0, r, "need AuthType to note auth failure: %s", r->uri);    }}AP_DECLARE(void) ap_note_basic_auth_failure(request_rec *r){    const char *type = ap_auth_type(r);    /* if there is no AuthType configure or it is something other than     * Basic, let ap_note_auth_failure() deal with it     */    if (!type || strcasecmp(type, "Basic"))        ap_note_auth_failure(r);    else        apr_table_setn(r->err_headers_out,                       (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"                                                       : "WWW-Authenticate",                       apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r),                                   "\"", NULL));}AP_DECLARE(void) ap_note_digest_auth_failure(request_rec *r){    apr_table_setn(r->err_headers_out,                   (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"                                                   : "WWW-Authenticate",                   /* need APR_TIME_T_FMT_HEX */                   apr_psprintf(r->pool, "Digest realm=\"%s\", nonce=\"%llx\"",                                ap_auth_name(r), r->request_time));}AP_DECLARE(int) ap_get_basic_auth_pw(request_rec *r, const char **pw){    const char *auth_line = apr_table_get(r->headers_in,                                          (PROXYREQ_PROXY == r->proxyreq)                                              ? "Proxy-Authorization"                                              : "Authorization");    const char *t;    if (!(t = ap_auth_type(r)) || strcasecmp(t, "Basic"))        return DECLINED;    if (!ap_auth_name(r)) {        ap_log_rerror(APLOG_MARK, APLOG_ERR,                      0, r, "need AuthName: %s", r->uri);        return HTTP_INTERNAL_SERVER_ERROR;    }    if (!auth_line) {        ap_note_basic_auth_failure(r);        return HTTP_UNAUTHORIZED;    }    if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) {        /* Client tried to authenticate using wrong auth scheme */        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                      "client used wrong authentication scheme: %s", r->uri);        ap_note_basic_auth_failure(r);        return HTTP_UNAUTHORIZED;    }    while (*auth_line == ' ' || *auth_line == '\t') {        auth_line++;    }    t = ap_pbase64decode(r->pool, auth_line);    r->user = ap_getword_nulls (r->pool, &t, ':');    r->ap_auth_type = "Basic";    *pw = t;    return OK;}struct content_length_ctx {    int data_sent;  /* true if the C-L filter has already sent at                     * least one bucket on to the next output filter                     * for this request                     */};/* This filter computes the content length, but it also computes the number * of bytes sent to the client.  This means that this filter will always run * through all of the buckets in all brigades */AP_CORE_DECLARE_NONSTD(apr_status_t) ap_content_length_filter(    ap_filter_t *f,    apr_bucket_brigade *b){    request_rec *r = f->r;    struct content_length_ctx *ctx;    apr_bucket *e;    int eos = 0;

⌨️ 快捷键说明

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