--- ./modules/proxy/mod_proxy.c.orig	2006-07-28 10:29:49.000000000 +0200
+++ ./modules/proxy/mod_proxy.c	2006-09-21 09:26:51.000000000 +0200
@@ -58,6 +58,9 @@
     do {                             \
         (w)->timeout              = (c)->timeout;               \
         (w)->timeout_set          = (c)->timeout_set;           \
+        (w)->connect_timeout      = (c)->connect_timeout;       \
+        (w)->connect_timeout_set  = (c)->connect_timeout_set;   \
+        (w)->force_close          = (c)->force_close;           \
         (w)->recv_buffer_size     = (c)->recv_buffer_size;      \
         (w)->recv_buffer_size_set = (c)->recv_buffer_size_set;  \
         (w)->io_buffer_size       = (c)->io_buffer_size;        \
@@ -145,6 +148,25 @@
         worker->timeout = apr_time_from_sec(ival);
         worker->timeout_set = 1;
     }
+    else if (!strcasecmp(key, "connecttimeout")) {
+        /* Connection timeout in milliseconds.
+         * Defaults to server timeout.
+         */
+        ival = atoi(val);
+        if (ival < 1)
+            return "Connection timeout must be at least one millisecond";
+        worker->connect_timeout = (apr_interval_time_t) (ival * 1000);
+        worker->connect_timeout_set = 1;
+    }
+    else if (!strcasecmp(key,"forceclose")) {
+	/* Do not reuse backend connections */
+       if (!strcasecmp(val, "on"))
+           worker->force_close = 1;
+       else if (!strcasecmp(val, "off"))
+           worker->sticky_force = 0;
+       else
+           return "forceclose must be On|Off";
+    }
     else if (!strcasecmp(key, "iobuffersize")) {
         long s = atol(val);
         worker->io_buffer_size = ((s > AP_IOBUFSIZE) ? s : AP_IOBUFSIZE);
@@ -258,6 +279,14 @@
          * PHPSESSIONID, etc..,
          */
         balancer->sticky = apr_pstrdup(p, val);
+	balancer->sticky_case = 0;
+    } else if (!strcasecmp(key, "stickycasesession")) {
+        /* Balancer sticky session name.
+         * Set to something like JSESSIONID or
+         * PHPSESSIONID, etc..,
+         */
+        balancer->sticky = apr_pstrdup(p, val);
+	balancer->sticky_case = 1;
     }
     else if (!strcasecmp(key, "nofailover")) {
         /* If set to 'on' the session will break
@@ -847,6 +876,9 @@
     ps->preserve_host = 0;
     ps->timeout = 0;
     ps->timeout_set = 0;
+    ps->connect_timeout = 0;
+    ps->connect_timeout_set = 0;
+    ps->force_close = 0;
     ps->badopt = bad_error;
     ps->badopt_set = 0;
     ps->pool = p;
@@ -880,6 +912,7 @@
     ps->error_override = (overrides->error_override_set == 0) ? base->error_override : overrides->error_override;
     ps->preserve_host = (overrides->preserve_host_set == 0) ? base->preserve_host : overrides->preserve_host;
     ps->timeout= (overrides->timeout_set == 0) ? base->timeout : overrides->timeout;
+    ps->connect_timeout= (overrides->connect_timeout_set == 0) ? base->connect_timeout : overrides->connect_timeout;
     ps->badopt = (overrides->badopt_set == 0) ? base->badopt : overrides->badopt;
     ps->proxy_status = (overrides->proxy_status_set == 0) ? base->proxy_status : overrides->proxy_status;
     ps->pool = p;
@@ -1349,6 +1382,23 @@
 }
 
 static const char*
+    set_proxy_connect_timeout(cmd_parms *parms, void *dummy, const char *arg)
+{
+    proxy_server_conf *psf =
+    ap_get_module_config(parms->server->module_config, &proxy_module);
+    int timeout;
+
+    timeout=atoi(arg);
+    if (timeout<1) {
+        return "Proxy Connect Timeout must be at least 1 second.";
+    }
+    psf->connect_timeout_set=1;
+    psf->connect_timeout=apr_time_from_sec(timeout);
+
+    return NULL;
+}
+
+static const char*
     set_via_opt(cmd_parms *parms, void *dummy, const char *arg)
 {
     proxy_server_conf *psf =
@@ -1691,6 +1741,9 @@
     AP_INIT_TAKE1("ProxyTimeout", set_proxy_timeout, NULL, RSRC_CONF,
      "Set the timeout (in seconds) for a proxied connection. "
      "This overrides the server timeout"),
+    AP_INIT_TAKE1("ProxyConnectTimeout", set_proxy_connect_timeout, NULL, RSRC_CONF,
+     "Set the connection timeout (in milliseconds) for a proxied connection. "
+     "This overrides the server timeout"),
     AP_INIT_TAKE1("ProxyBadHeader", set_bad_opt, NULL, RSRC_CONF,
      "How to handle bad header line in response: IsError | Ignore | StartBody"),
     AP_INIT_RAW_ARGS("BalancerMember", add_member, NULL, RSRC_CONF|ACCESS_CONF,
--- ./modules/proxy/mod_proxy.h.orig	2006-07-28 10:30:37.000000000 +0200
+++ ./modules/proxy/mod_proxy.h	2006-09-13 17:58:45.000000000 +0200
@@ -169,6 +169,9 @@
     int preserve_host_set;
     apr_interval_time_t timeout;
     char timeout_set;
+    apr_interval_time_t connect_timeout;
+    char connect_timeout_set;
+    int force_close;
     enum {
       bad_error,
       bad_ignore,
@@ -289,6 +292,9 @@
                                  * may be available while exceeding the soft limit */
     apr_interval_time_t timeout; /* connection timeout */
     char                timeout_set;
+    apr_interval_time_t connect_timeout; /* connection timeout */
+    char                connect_timeout_set;
+    int 		force_close; /* discard backend connection after use */
     apr_interval_time_t acquire; /* acquire timeout when the maximum number of connections is exceeded */
     char                acquire_set;
     apr_size_t          recv_buffer_size;
@@ -323,6 +329,7 @@
     apr_array_header_t *workers; /* array of proxy_workers */
     const char *name;            /* name of the load balancer */
     const char *sticky;          /* sticky session identifier */
+    int		sticky_case;	 /* Ignore case when looking for sticky */
     int         sticky_force;    /* Disable failover for sticky sessions */
     apr_interval_time_t timeout; /* Timeout for waiting on free connection */
     int                 max_attempts; /* Number of attempts before failing */
--- ./modules/proxy/mod_proxy_ajp.c.orig	2006-09-18 22:01:53.000000000 +0200
+++ ./modules/proxy/mod_proxy_ajp.c	2006-09-13 17:52:48.000000000 +0200
@@ -510,7 +510,7 @@
     }
 
     backend->is_ssl = 0;
-    backend->close_on_recycle = 0;
+    backend->close_on_recycle = worker->force_close;
 
     /* Step One: Determine Who To Connect To */
     status = ap_proxy_determine_connection(p, r, conf, worker, backend,
--- ./modules/proxy/mod_proxy_balancer.c.orig	2006-07-28 10:28:04.000000000 +0200
+++ ./modules/proxy/mod_proxy_balancer.c	2006-07-28 11:50:51.000000000 +0200
@@ -107,12 +107,16 @@
 /* Retrieve the parameter with the given name
  * Something like 'JSESSIONID=12345...N'
  */
+
+#define STRSTR(url,name,ignorecase) (ignorecase == 0 ? strstr(url,name) : strcasestr(url,name))
+
 static char *get_path_param(apr_pool_t *pool, char *url,
-                            const char *name)
+                            const char *name, int ignorecase)
 {
     char *path = NULL;
 
-    for (path = strstr(url, name); path; path = strstr(path + 1, name)) {
+
+    for (path = STRSTR(url, name, ignorecase); path; path = STRSTR(path + 1, name, ignorecase)) {
         path += strlen(name);
         if (*path == '=') {
             /*
@@ -131,14 +135,14 @@
     return NULL;
 }
 
-static char *get_cookie_param(request_rec *r, const char *name)
+static char *get_cookie_param(request_rec *r, const char *name, int ignorecase)
 {
     const char *cookies;
     const char *start_cookie;
 
     if ((cookies = apr_table_get(r->headers_in, "Cookie"))) {
-        for (start_cookie = ap_strstr_c(cookies, name); start_cookie;
-             start_cookie = ap_strstr_c(start_cookie + 1, name)) {
+        for (start_cookie = STRSTR(cookies, name, ignorecase); start_cookie;
+             start_cookie = STRSTR(start_cookie + 1, name, ignorecase)) {
             if (start_cookie == cookies ||
                 start_cookie[-1] == ';' ||
                 start_cookie[-1] == ',' ||
@@ -192,9 +196,9 @@
     if (!balancer->sticky)
         return NULL;
     /* Try to find the sticky route inside url */
-    *route = get_path_param(r->pool, *url, balancer->sticky);
+    *route = get_path_param(r->pool, *url, balancer->sticky, balancer->sticky_case);
     if (!*route)
-        *route = get_cookie_param(r, balancer->sticky);
+        *route = get_cookie_param(r, balancer->sticky, balancer->sticky_case);
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                             "proxy: BALANCER: Found value %s for "
                             "stickysession %s", *route, balancer->sticky);
--- ./modules/proxy/mod_proxy_http.c.orig	2006-09-13 17:54:35.000000000 +0200
+++ ./modules/proxy/mod_proxy_http.c	2006-09-13 17:56:59.000000000 +0200
@@ -1678,6 +1678,8 @@
      */
     if (is_ssl)
         backend->close_on_recycle = 1;
+    else
+	backend->close_on_recycle = worker->force_close;
 
     /* Step One: Determine Who To Connect To */
     if ((status = ap_proxy_determine_connection(p, r, conf, worker, backend,
--- ./modules/proxy/proxy_util.c.orig	2006-09-18 22:03:03.000000000 +0200
+++ ./modules/proxy/proxy_util.c	2006-09-14 18:25:17.000000000 +0200
@@ -1472,7 +1472,7 @@
 #endif
 
         /* Set a timeout on the socket */
-        if (conf->timeout_set == 1) {
+	if (conf->timeout_set == 1) {
             apr_socket_timeout_set(*newsock, conf->timeout);
         }
         else {
@@ -2027,12 +2027,16 @@
 #endif
 
         /* Set a timeout on the socket */
-        if (worker->timeout_set == 1) {
+	if (worker->connect_timeout_set == 1) {
+	    apr_socket_timeout_set(newsock, worker->connect_timeout);
+	}
+	else if (worker->timeout_set == 1) {
             apr_socket_timeout_set(newsock, worker->timeout);
         }
         else {
              apr_socket_timeout_set(newsock, s->timeout);
         }
+
         /* Set a keepalive option */
         if (worker->keepalive) {
             if ((rv = apr_socket_opt_set(newsock,
@@ -2064,6 +2068,14 @@
 
         conn->sock   = newsock;
         connected    = 1;
+
+        /* Set a timeout on the socket */
+        if (worker->timeout_set == 1) {
+            apr_socket_timeout_set(newsock, worker->timeout);
+        }
+        else {
+             apr_socket_timeout_set(newsock, s->timeout);
+        }
     }
     /*
      * Put the entire worker to error state if
