Received: (qmail 89446 invoked by uid 501); 30 Oct 2000 05:46:28 -0000 Message-Id: <20001030054628.89445.qmail@locus.apache.org> Date: 30 Oct 2000 05:46:28 -0000 From: Patrick ASTY Reply-To: pasty@micronet.fr To: submit@bugz.apache.org Subject: PATCH to enable Keep-Alive for mod_proxy X-Send-Pr-Version: 3.110 >Number: 6760 >Category: mod_proxy >Synopsis: PATCH to enable Keep-Alive for mod_proxy >Confidential: no >Severity: serious >Priority: medium >Responsible: apache >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: apache >Arrival-Date: Sun Oct 29 21:50:00 PST 2000 >Closed-Date: >Last-Modified: >Originator: pasty@micronet.fr >Release: 1.3.12, 1.3.14 >Organization: apache >Environment: All (but only really tested on Linux and Solaris) >Description: Keep-Alive is not supported by mod_proxy. Following a patch to enable it, for reverse-proxy only; also available at: http://persoweb.francenet.fr/~pasty/ap_proxy_ka/ >How-To-Repeat: % telnet apache_reverse_proxy port GET / HTTP/1.1 Host: the_host Connection: keep-alive ...response... % >Fix: *** ./src/modules/proxy/proxy_util.c.orig Sat Oct 7 18:20:01 2000 --- ./src/modules/proxy/proxy_util.c Mon Oct 30 06:18:21 2000 *************** *** 64,69 **** --- 64,135 ---- #include "util_uri.h" #include "util_date.h" /* get ap_checkmask() decl. */ + /* + * Same as ap_set_keepalive, but: + * + * r->headers_out => headers_out (from args) + * ap_table_get(r->headers_in, "Connection") + * => conn_in (from args) + * ap_table_get(r->headers_in, "Via") + * => via_in (from args) + */ + int ap_proxy_keepalive(request_rec *r, char *conn_in, char *via_in, + table *headers_out) + { + int ka_sent = 0; + int wimpy = ap_find_token(r->pool, + ap_table_get(headers_out, "Connection"), "close"); + const char *conn = conn_in; + + if ((r->connection->keepalive != -1) && + ((r->status == HTTP_NOT_MODIFIED) || + (r->status == HTTP_NO_CONTENT) || + r->header_only || + ap_table_get(headers_out, "Content-Length") || + ap_find_last_token(r->pool, + ap_table_get(headers_out, "Transfer-Encoding"), + "chunked") || + ((r->proto_num >= HTTP_VERSION(1,1)) && + (r->chunked = 1))) && /* THIS CODE IS CORRECT, see comment above. */ + r->server->keep_alive && + (r->server->keep_alive_timeout > 0) && + ((r->server->keep_alive_max == 0) || + (r->server->keep_alive_max > r->connection->keepalives)) && + !ap_status_drops_connection(r->status) && + !wimpy && + !ap_find_token(r->pool, conn, "close") && + (!ap_table_get(r->subprocess_env, "nokeepalive") || + via_in) && + ((ka_sent = ap_find_token(r->pool, conn, "keep-alive")) || + (r->proto_num >= HTTP_VERSION(1,1))) + ) { + int left = r->server->keep_alive_max - r->connection->keepalives; + + r->connection->keepalive = 1; + r->connection->keepalives++; + + if (ka_sent) { + if (r->server->keep_alive_max) + ap_table_setn(headers_out, "Keep-Alive", + ap_psprintf(r->pool, "timeout=%d, max=%d", + r->server->keep_alive_timeout, left)); + else + ap_table_setn(headers_out, "Keep-Alive", + ap_psprintf(r->pool, "timeout=%d", + r->server->keep_alive_timeout)); + ap_table_mergen(headers_out, "Connection", "Keep-Alive"); + } + return 1; + } + + if (!wimpy) + ap_table_mergen(headers_out, "Connection", "close"); + + r->connection->keepalive = 0; + + return 0; + } + static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r); static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r); static int proxy_match_hostname(struct dirconn_entry *This, request_rec *r); *************** *** 1270,1275 **** --- 1336,1344 ---- return 1; if (!parm->req->assbackwards) ap_rvputs(parm->req, key, ": ", value, CRLF, NULL); + /* Don't cache some headers */ + if (strcmp (key, "Keep-Alive") == 0 || strcmp (key, "Connection") == 0) + return 1; if (parm->cache != NULL && parm->cache->fp != NULL && ap_bvputs(parm->cache->fp, key, ": ", value, CRLF, NULL) == -1) { ap_log_rerror(APLOG_MARK, APLOG_ERR, parm->cache->req, *** ./src/modules/proxy/proxy_cache.c.orig Thu Sep 28 15:32:39 2000 --- ./src/modules/proxy/proxy_cache.c Mon Oct 30 06:36:53 2000 *************** *** 710,715 **** --- 710,717 ---- void *sconf = r->server->module_config; proxy_server_conf *pconf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); + const char *conn_in = ap_table_get(r->headers_in, "Connection"); + const char *via_in = ap_table_get(r->headers_in, "Via"); c = ap_pcalloc(r->pool, sizeof(cache_req)); *cr = c; *************** *** 805,810 **** --- 807,815 ---- Explain0("Local copy modified, send it"); r->status_line = strchr(c->resp_line, ' ') + 1; r->status = c->status; + /* for reverse-proxy, also check for keep-alive */ + if (r->proxyreq == PROXY_PASS) + ap_proxy_keepalive (r, conn_in, via_in, c->hdrs); if (!r->assbackwards) { ap_soft_timeout("proxy send headers", r); ap_proxy_send_headers(r, c->resp_line, c->hdrs); *************** *** 812,817 **** --- 817,825 ---- } ap_bsetopt(r->connection->client, BO_BYTECT, &zero); r->sent_bodyct = 1; + /* keepalive may chunk the request... */ + if (r->chunked) + ap_bsetflag(r->connection->client, B_CHUNK, 1); if (!r->header_only) ap_proxy_send_fb(cachefp, r, NULL); ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR)); *** ./src/modules/proxy/proxy_http.c.orig Tue Feb 29 15:24:27 2000 --- ./src/modules/proxy/proxy_http.c Mon Oct 30 06:35:30 2000 *************** *** 196,201 **** --- 196,203 ---- struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts; struct nocache_entry *ncent = (struct nocache_entry *) conf->nocaches->elts; int nocache = 0; + const char *conn_in = ap_table_get(r->headers_in, "Connection"); + const char *via_in = ap_table_get(r->headers_in, "Via"); memset(&server, '\0', sizeof(server)); server.sin_family = AF_INET; *************** *** 469,474 **** --- 471,484 ---- if ((datestr = ap_table_get(resp_hdrs, "URI")) != NULL) ap_table_set(resp_hdrs, "URI", proxy_location_reverse_map(r, datestr)); + /* for reverse-proxy, also check for keep-alive */ + if (r->proxyreq == PROXY_PASS) + ap_proxy_keepalive (r, conn_in, via_in, resp_hdrs); + if (r->chunked) { + ap_table_mergen(resp_hdrs, "Transfer-Encoding", "chunked"); + ap_table_unset(resp_hdrs, "Content-Length"); + } + /* check if NoCache directive on this host */ for (i = 0; i < conf->nocaches->nelts; i++) { if ((ncent[i].name != NULL && strstr(desthost, ncent[i].name) != NULL) *************** *** 527,532 **** --- 537,546 ---- ap_bsetflag(f, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0); ap_bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0); #endif + + /* keepalive may chunk the request... */ + if (r->chunked) + ap_bsetflag(r->connection->client, B_CHUNK, 1); /* send body */ /* if header only, then cache will be NULL */ >Release-Note: >Audit-Trail: >Unformatted: [In order for any reply to be added to the PR database, you need] [to include in the Cc line and make sure the] [subject line starts with the report component and number, with ] [or without any 'Re:' prefixes (such as "general/1098:" or ] ["Re: general/1098:"). If the subject doesn't match this ] [pattern, your message will be misfiled and ignored. The ] ["apbugs" address is not added to the Cc line of messages from ] [the database automatically because of the potential for mail ] [loops. If you do not include this Cc, your reply may be ig- ] [nored unless you are responding to an explicit request from a ] [developer. Reply only with text; DO NOT SEND ATTACHMENTS! ]