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

📄 proxy_http.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 2 页
字号:
         */        ap_table_mergen(req_hdrs, "X-Forwarded-For", r->connection->remote_ip);        /* Add X-Forwarded-Host: so that upstream knows what the         * original request hostname was.         */        if ((buf = ap_table_get(r->headers_in, "Host"))) {            ap_table_mergen(req_hdrs, "X-Forwarded-Host", buf);        }        /* Add X-Forwarded-Server: so that upstream knows what the         * name of this proxy server is (if there are more than one)         * XXX: This duplicates Via: - do we strictly need it?         */        ap_table_mergen(req_hdrs, "X-Forwarded-Server", r->server->server_hostname);    }     /* we don't yet support keepalives - but we will soon, I promise!      * XXX: This introduces various HTTP Request vulnerabilies if not     * properly implemented.  Before changing this .. be certain to     * add a hard-close of the connection if the T-E and C-L headers     * are both present, or the C-L header is malformed.     */    ap_table_set(req_hdrs, "Connection", "close");    reqhdrs_arr = ap_table_elts(req_hdrs);    reqhdrs_elts = (table_entry *)reqhdrs_arr->elts;    for (i = 0; i < reqhdrs_arr->nelts; i++) {        if (reqhdrs_elts[i].key == NULL || reqhdrs_elts[i].val == NULL        /*         * Clear out hop-by-hop request headers not to send: RFC2616 13.5.1         * says we should strip these headers:         */            || !strcasecmp(reqhdrs_elts[i].key, "Host") /* Already sent */            || !strcasecmp(reqhdrs_elts[i].key, "Keep-Alive")            || !strcasecmp(reqhdrs_elts[i].key, "TE")            || !strcasecmp(reqhdrs_elts[i].key, "Trailer")            || !strcasecmp(reqhdrs_elts[i].key, "Transfer-Encoding")            || !strcasecmp(reqhdrs_elts[i].key, "Upgrade")        /*         * XXX: @@@ FIXME: "Proxy-Authorization" should *only* be suppressed         * if THIS server requested the authentication, not when a frontend         * proxy requested it!         *          * The solution to this problem is probably to strip out the         * Proxy-Authorisation header in the authorisation code itself, not         * here. This saves us having to signal somehow whether this request         * was authenticated or not.         */            || !strcasecmp(reqhdrs_elts[i].key, "Proxy-Authorization"))            continue;        ap_bvputs(f, reqhdrs_elts[i].key, ": ", reqhdrs_elts[i].val, CRLF, NULL);    }    /* the obligatory empty line to mark the end of the headers */    ap_bputs(CRLF, f);    /* and flush the above away */    ap_bflush(f);    /* and kill the send timeout */    ap_kill_timeout(r);    /* read the request data, and pass it to the backend.     * we might encounter a stray 100-continue reponse from a PUT or POST,     * if this happens we ignore the 100 continue status line and read the     * response again.     */    {        /* send the request data, if any. */        ap_hard_timeout("proxy receive request data", r);        if (ap_should_client_block(r)) {            while ((i = ap_get_client_block(r, buffer, sizeof buffer)) > 0) {                ap_reset_timeout(r);                ap_bwrite(f, buffer, i);            }        }        ap_bflush(f);        ap_kill_timeout(r);        /* then, read a response line */        ap_hard_timeout("proxy receive response status line", r);        result = ap_proxy_read_response_line(f, r, buffer, sizeof(buffer)-1, &backasswards, &major, &minor);        ap_kill_timeout(r);        /* trap any errors */        if (result != OK) {            ap_bclose(f);            return result;        }        /* if this response was 100-continue, a stray response has been caught.         * read the line again for the real response         */        if (r->status == 100) {            ap_hard_timeout("proxy receive response status line", r);            result = ap_proxy_read_response_line(f, r, buffer, sizeof(buffer)-1, &backasswards, &major, &minor);            ap_kill_timeout(r);            /* trap any errors */            if (result != OK) {                ap_bclose(f);                return result;            }        }    }    /*     * We have our response status line from the convoluted code above,     * now we read the headers to continue.     */    ap_hard_timeout("proxy receive response headers", r);    /*     * Is it an HTTP/1 response? Do some sanity checks on the response. (This     * is buggy if we ever see an HTTP/1.10)     */    if (backasswards == 0) {        /* read the response headers. */        /* N.B. for HTTP/1.0 clients, we have to fold line-wrapped headers */        /* Also, take care with headers with multiple occurences. */        resp_hdrs = ap_proxy_read_headers(r, buffer, sizeof(buffer), f);        if (resp_hdrs == NULL) {            ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, r->server,                         "proxy: Bad HTTP/%d.%d header returned by %s (%s)",                         major, minor, r->uri, r->method);            resp_hdrs = ap_make_table(p, 20);            nocache = 1;        /* do not cache this broken file */        }        /* handle Via header in the response */        if (conf->viaopt != via_off && conf->viaopt != via_block) {            /* Create a "Via:" response header entry and merge it */            i = ap_get_server_port(r);            if (ap_is_default_port(i, r)) {                strcpy(portstr, "");            }            else {                ap_snprintf(portstr, sizeof portstr, ":%d", i);            }            ap_table_mergen((table *)resp_hdrs, "Via",                            (conf->viaopt == via_full)                            ? ap_psprintf(p, "%d.%d %s%s (%s)",                                          major, minor,                                          ap_get_server_name(r), portstr,                                          SERVER_BASEVERSION)                            : ap_psprintf(p, "%d.%d %s%s",                                          major, minor,                                          ap_get_server_name(r), portstr)                );        }        /* is this content chunked? */        chunked = ap_table_get(resp_hdrs, "Transfer-Encoding");        if (chunked && (strcasecmp(chunked, "chunked") != 0)) {            ap_kill_timeout(r);            return ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool,                                 "Unsupported Transfer-Encoding ", chunked,                                 " from remote server", NULL));        }        /* strip hop-by-hop headers defined by Connection and RFC2616 */        ap_proxy_clear_connection(p, resp_hdrs);        content_length = ap_table_get(resp_hdrs, "Content-Length");        if (content_length != NULL) {            if (chunked) {                /* XXX: We would unset keep-alive here, to the proxy                 * origin server, for safety's sake but we aren't using                 * keep-alives (we force Connection: close  above)                 */                nocache = 1;        /* do not cache this suspect file */                ap_table_unset(resp_hdrs, "Content-Length");            }            else {                char *len_end;                errno = 0;                c->len = ap_strtol(content_length, &len_end, 10);                if (errno || (c->len < 0) || (len_end && *len_end)) {                    ap_kill_timeout(r);                    return ap_proxyerror(r, HTTP_BAD_GATEWAY,                                          "Invalid Content-Length from remote"                                         " server");                }	    }        }    }    else {        /* an http/0.9 response */        /* no headers */        resp_hdrs = ap_make_table(p, 20);    }    ap_kill_timeout(r);    /*     * HTTP/1.1 requires us to accept 3 types of dates, but only generate one     * type     */    /*     * we SET the dates here, obliterating possible multiple dates, as only     * one of each date makes sense in each response.     */    if ((datestr = ap_table_get(resp_hdrs, "Date")) != NULL)        ap_table_set(resp_hdrs, "Date", ap_proxy_date_canon(p, datestr));    if ((datestr = ap_table_get(resp_hdrs, "Last-Modified")) != NULL)        ap_table_set(resp_hdrs, "Last-Modified", ap_proxy_date_canon(p, datestr));    if ((datestr = ap_table_get(resp_hdrs, "Expires")) != NULL)        ap_table_set(resp_hdrs, "Expires", ap_proxy_date_canon(p, datestr));    /* handle the ProxyPassReverse mappings */    if ((urlstr = ap_table_get(resp_hdrs, "Location")) != NULL)        ap_table_set(resp_hdrs, "Location", proxy_location_reverse_map(r, urlstr));    if ((urlstr = ap_table_get(resp_hdrs, "URI")) != NULL)        ap_table_set(resp_hdrs, "URI", proxy_location_reverse_map(r, urlstr));    if ((urlstr = ap_table_get(resp_hdrs, "Content-Location")) != NULL)        ap_table_set(resp_hdrs, "Content-Location", proxy_location_reverse_map(r, urlstr));/* check if NoCache directive on this host */    if (nocache == 0) {        for (i = 0; i < conf->nocaches->nelts; i++) {            if (destaddr.s_addr == ncent[i].addr.s_addr ||                (ncent[i].name != NULL &&                 (ncent[i].name[0] == '*' ||                  strstr(desthost, ncent[i].name) != NULL))) {                nocache = 1;                break;            }        }        /*         * update the cache file, possibly even fulfilling the request if it         * turns out a conditional allowed us to serve the object from the         * cache...         */        i = ap_proxy_cache_update(c, resp_hdrs, !backasswards, nocache);        if (i != DECLINED) {            ap_bclose(f);            return i;        }        /* write status line and headers to the cache file */        ap_proxy_write_headers(c, ap_pstrcat(p, "HTTP/1.1 ", r->status_line, NULL), resp_hdrs);    }    /* Setup the headers for our client from upstreams response-headers */    ap_proxy_table_replace(r->headers_out, resp_hdrs);    /* Add X-Cache header - be careful not to obliterate any upstream headers */    ap_table_mergen(r->headers_out, "X-Cache",                    ap_pstrcat(r->pool, "MISS from ",                               ap_get_server_name(r), NULL));    /* The Content-Type of this response is the upstream one. */    r->content_type = ap_table_get(r->headers_out, "Content-Type");    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Content-Type: %s", r->content_type);    /* finally output the headers to the client */    ap_send_http_header(r);    /*     * Is it an HTTP/0.9 respose? If so, send the extra data we read from     * upstream as the start of the reponse to client     *//* FIXME: This code is broken: we try and write a buffer and length that * were never intelligently initialised. Rather have a bit of broken protocol * handling for now than broken code. *//*    if (backasswards) {        ap_hard_timeout("proxy send assbackward", r);        ap_bwrite(r->connection->client, buffer, len);        if (c != NULL && c->fp != NULL && ap_bwrite(c->fp, buffer, len) != len) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,                      "proxy: error writing extra data to %s", c->tempfile);            c = ap_proxy_cache_error(c);        }        ap_kill_timeout(r);    }*/#ifdef CHARSET_EBCDIC    /*     * What we read/write after the header should not be modified (i.e., the     * cache copy is ASCII, not EBCDIC, even for text/html)     */    r->ebcdic.conv_in = r->ebcdic.conv_out = 0;    ap_bsetflag(f, B_ASCII2EBCDIC | B_EBCDIC2ASCII, 0);    ap_bsetflag(r->connection->client, B_ASCII2EBCDIC | B_EBCDIC2ASCII, 0);#endif/* send body *//* if header only, then cache will be NULL *//* HTTP/1.0 tells us to read to EOF, rather than content-length bytes *//* XXX CHANGEME: We want to eventually support keepalives, which means * we must read content-length bytes... */    if (!r->header_only) {/* we need to set this for ap_proxy_send_fb()... */        c->cache_completion = conf->cache.cache_completion;/* XXX CHECKME: c->len should be the expected content length, or -1 if the * content length is not known. We need to make 100% sure c->len is always * set correctly before we get here to correctly do keepalive. */        ap_proxy_send_fb(f, r, c, c->len, 0, chunked != NULL,                          conf->io_buffer_size);    }    /* ap_proxy_send_fb() closes the socket f for us */    ap_proxy_cache_tidy(c);    ap_proxy_garbage_coll(r);    return OK;}

⌨️ 快捷键说明

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