www-apache-bugdb mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Patrick ASTY <pa...@micronet.fr>
Subject mod_proxy/6760: PATCH to enable Keep-Alive for mod_proxy
Date Mon, 30 Oct 2000 05:46:28 GMT

>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 <apbugs@Apache.Org> 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!     ]
 
 


Mime
View raw message