Keep-alive and Safari

Igor Sysoev igor at sysoev.ru
Thu Nov 25 21:18:31 MSK 2010


On Thu, Nov 25, 2010 at 07:32:05PM +0300, Maxim Dounin wrote:

> Hello!
> 
> On Thu, Nov 25, 2010 at 07:09:31PM +0300, Igor Sysoev wrote:
> 
> > On Thu, Nov 25, 2010 at 04:49:52PM +0100, Jan Andersson wrote:
> > 
> > > Hi,
> > > regading:
> > > 
> > > >> I also founded NGIX disabled keep-alive for safari.
> > > >> 
> > > >> I am not sure exact reason of this.
> > > > 
> > > > http://nginx.org/pipermail/nginx/2010-October/023131.html
> > > 
> > > I still beleive it would be great if there was an option to enable keep-alive for Safari.
> > > Not all sites need this work-a-round...
> > 
> > The attached patch introduces
> >    safari_keepalive  on|off;
> > directive. The default value is "off".
> > It will be included in next 0.9.0.
> 
> I would like to see something more general, e.g.
> 
> keepalive_disable safari msie6;
> keepalive_disable off;
> 
> This should be helpfull for servers without POST's at all, and 
> looks much more extendable.

You are right. The attached patch introduces
   keepalive_disable  safari  msie6;   # default
   keepalive_disable  none;            # turn off


-- 
Igor Sysoev
http://sysoev.ru/en/
-------------- next part --------------
Index: src/http/ngx_http_core_module.c
===================================================================
--- src/http/ngx_http_core_module.c	(revision 3111)
+++ src/http/ngx_http_core_module.c	(working copy)
@@ -133,6 +133,14 @@
 };
 
 
+static ngx_conf_enum_t  ngx_http_core_keepalive_disable[] = {
+    { ngx_string("none"), NGX_HTTP_KEEPALIVE_DISABLE_NONE },
+    { ngx_string("msie6"), NGX_HTTP_KEEPALIVE_DISABLE_MSIE6 },
+    { ngx_string("safari"), NGX_HTTP_KEEPALIVE_DISABLE_SAFARI },
+    { ngx_null_string, 0 }
+};
+
+
 static ngx_path_init_t  ngx_http_client_temp_path = {
     ngx_string(NGX_HTTP_CLIENT_TEMP_PATH), { 0, 0, 0 }
 };
@@ -494,6 +502,13 @@
       offsetof(ngx_http_core_loc_conf_t, keepalive_requests),
       NULL },
 
+    { ngx_string("keepalive_disable"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_enum_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_core_loc_conf_t, keepalive_disable),
+      &ngx_http_core_keepalive_disable },
+
     { ngx_string("satisfy"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_enum_slot,
@@ -790,26 +805,6 @@
             break;
         }
 
-        if (r->keepalive) {
-
-            if (r->headers_in.msie6) {
-                if (r->method == NGX_HTTP_POST) {
-                    /*
-                     * MSIE may wait for some time if an response for
-                     * a POST request was sent over a keepalive connection
-                     */
-                    r->keepalive = 0;
-                }
-
-            } else if (r->headers_in.safari) {
-                /*
-                 * Safari may send a POST request to a closed keepalive
-                 * connection and stalls for some time
-                 */
-                r->keepalive = 0;
-            }
-        }
-
         if (r->headers_in.content_length_n > 0) {
             r->lingering_close = 1;
 
@@ -1432,6 +1427,28 @@
 
         } else if (r->connection->requests >= clcf->keepalive_requests) {
             r->keepalive = 0;
+
+        } else if (r->headers_in.msie6
+                   && r->method == NGX_HTTP_POST
+                   && (clcf->keepalive_disable
+                       & NGX_HTTP_KEEPALIVE_DISABLE_MSIE6))
+        {
+            /*
+             * MSIE may wait for some time if an response for
+             * a POST request was sent over a keepalive connection
+             */
+            r->keepalive = 0;
+
+        } else if (r->headers_in.safari
+                   && (clcf->keepalive_disable
+                       & NGX_HTTP_KEEPALIVE_DISABLE_SAFARI))
+        {
+            /*
+             * Safari may send a POST request to a closed keepalive
+             * connection and stalls for some time, see
+             *     https://bugs.webkit.org/show_bug.cgi?id=5760
+             */
+            r->keepalive = 0;
         }
     }
 
@@ -3061,6 +3078,7 @@
     clcf->client_max_body_size = NGX_CONF_UNSET;
     clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
     clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
+    clcf->keepalive_disable = NGX_CONF_UNSET_UINT;
     clcf->satisfy = NGX_CONF_UNSET_UINT;
     clcf->if_modified_since = NGX_CONF_UNSET_UINT;
     clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
@@ -3261,6 +3279,9 @@
     ngx_conf_merge_msec_value(conf->client_body_timeout,
                               prev->client_body_timeout, 60000);
 
+    ngx_conf_merge_uint_value(conf->keepalive_disable, prev->keepalive_disable,
+                              NGX_HTTP_KEEPALIVE_DISABLE_MSIE6
+                              |NGX_HTTP_KEEPALIVE_DISABLE_SAFARI);
     ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy,
                               NGX_HTTP_SATISFY_ALL);
     ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
Index: src/http/ngx_http_core_module.h
===================================================================
--- src/http/ngx_http_core_module.h	(revision 3111)
+++ src/http/ngx_http_core_module.h	(working copy)
@@ -38,6 +38,11 @@
 #define NGX_HTTP_IMS_BEFORE             2
 
 
+#define NGX_HTTP_KEEPALIVE_DISABLE_NONE    0x0002
+#define NGX_HTTP_KEEPALIVE_DISABLE_MSIE6   0x0004
+#define NGX_HTTP_KEEPALIVE_DISABLE_SAFARI  0x0008
+
+
 typedef struct ngx_http_location_tree_node_s  ngx_http_location_tree_node_t;
 typedef struct ngx_http_core_loc_conf_s  ngx_http_core_loc_conf_t;
 
@@ -349,6 +354,7 @@
     time_t        keepalive_header;        /* keepalive_timeout */
 
     ngx_uint_t    keepalive_requests;      /* keepalive_requests */
+    ngx_uint_t    keepalive_disable;       /* keepalive_disable */
     ngx_uint_t    satisfy;                 /* satisfy */
     ngx_uint_t    if_modified_since;       /* if_modified_since */
     ngx_uint_t    client_body_in_file_only; /* client_body_in_file_only */


More information about the nginx mailing list