Задержка при обращении из скрипта.

Igor Sysoev is at rambler-co.ru
Tue Jun 24 18:58:19 MSD 2008


On Tue, Jun 24, 2008 at 01:42:58PM +0400, Igor Sysoev wrote:

> On Tue, Jun 24, 2008 at 01:33:10PM +0400, nobody wrote:
> 
> > У нас сложилась такая ситуация:
> > Есть некий демон, который слушает http, перед ним стоит nginx, который
> > проксирует запросы на этот демон. При обращении к страничке из
> > перлового скрипта, ответ приходит сразу и ничего не тормозит. Когда
> > обращаемся curl'ом из php скрипта, происходит задержка в 1.5-2 сек.
> > Причину это задержки выяснить самим пока не удалось.
> > На сервере используется ssl и верификация клиентских сертификатов. Её
> > отключение ничего не даёт. Сертификаты у скриптов одинаковые.
> > 
> > В атаче дебаг лог от сервера.
> 
> Задержка из-за
> 
> 2008/06/24 13:17:36 [debug] 3340#0: *780 http header: "Expect: 100-continue"
> 
> nginx не поддерживает Expect, из-за этого и задержка.
> 
> Попробуйте запускать "curl -H Expect: ..."

Патч для поддержки expect.


-- 
Игорь Сысоев
http://sysoev.ru
-------------- next part --------------
Index: src/http/ngx_http_request.c
===================================================================
--- src/http/ngx_http_request.c	(revision 1383)
+++ src/http/ngx_http_request.c	(working copy)
@@ -106,6 +106,10 @@
                  offsetof(ngx_http_headers_in_t, transfer_encoding),
                  ngx_http_process_header_line },
 
+    { ngx_string("Expect"),
+                 offsetof(ngx_http_headers_in_t, expect),
+                 ngx_http_process_unique_header_line },
+
 #if (NGX_HTTP_GZIP)
     { ngx_string("Accept-Encoding"),
                  offsetof(ngx_http_headers_in_t, accept_encoding),
Index: src/http/ngx_http_core_module.c
===================================================================
--- src/http/ngx_http_core_module.c	(revision 1383)
+++ src/http/ngx_http_core_module.c	(working copy)
@@ -25,6 +25,7 @@
 static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r);
 static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r,
     ngx_http_location_tree_node_t *node);
+static ngx_int_t ngx_http_core_send_continue(ngx_http_request_t *r);
 
 static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
 static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
@@ -771,7 +772,7 @@
 {
     u_char                    *p;
     size_t                     len;
-    ngx_int_t                  rc;
+    ngx_int_t                  rc, expect;
     ngx_http_core_loc_conf_t  *clcf;
 
     r->content_handler = NULL;
@@ -815,6 +816,15 @@
         return NGX_OK;
     }
 
+    if (r->headers_in.expect) {
+        expect = ngx_http_core_send_continue(r);
+
+        if (expect != NGX_OK) {
+            ngx_http_finalize_request(r, expect);
+            return NGX_OK;
+        }
+    }
+
     if (rc == NGX_DONE) {
         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
         if (r->headers_out.location == NULL) {
@@ -1244,6 +1254,45 @@
 }
 
 
+static ngx_int_t
+ngx_http_core_send_continue(ngx_http_request_t *r)
+{
+    ngx_int_t   n;
+    ngx_str_t  *expect;
+
+    if (r->expect_tested) {
+        return NGX_OK;
+    }
+
+    r->expect_tested = 1;
+
+    expect = &r->headers_in.expect->value;
+
+    if (expect->len != sizeof("100-continue") - 1
+        || ngx_strncasecmp(expect->data, (u_char *) "100-continue",
+                           sizeof("100-continue") - 1)
+           != 0)
+    {
+        return NGX_HTTP_EXPECTATION_FAILED;
+    }
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "send 100 Continue");
+
+    n = r->connection->send(r->connection,
+                            (u_char *) "HTTP/1.1 100 Continue" CRLF CRLF,
+                            sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1);
+
+    if (n == sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1) {
+        return NGX_OK;
+    }
+
+    /* we assume that such small packet should be send successfully */
+
+    return NGX_HTTP_INTERNAL_SERVER_ERROR;
+}
+
+
 ngx_int_t
 ngx_http_set_content_type(ngx_http_request_t *r)
 {
Index: src/http/ngx_http_request.h
===================================================================
--- src/http/ngx_http_request.h	(revision 1383)
+++ src/http/ngx_http_request.h	(working copy)
@@ -83,6 +83,7 @@
 #define NGX_HTTP_REQUEST_URI_TOO_LARGE     414
 #define NGX_HTTP_UNSUPPORTED_MEDIA_TYPE    415
 #define NGX_HTTP_RANGE_NOT_SATISFIABLE     416
+#define NGX_HTTP_EXPECTATION_FAILED        417
 
 
 /* Our own HTTP codes */
@@ -171,6 +172,7 @@
     ngx_table_elt_t                  *if_range;
 
     ngx_table_elt_t                  *transfer_encoding;
+    ngx_table_elt_t                  *expect;
 
 #if (NGX_HTTP_GZIP)
     ngx_table_elt_t                  *accept_encoding;
@@ -467,6 +469,7 @@
     unsigned                          request_complete:1;
     unsigned                          request_output:1;
     unsigned                          header_sent:1;
+    unsigned                          expect_tested:1;
     unsigned                          done:1;
     unsigned                          utf8:1;
 
Index: src/http/ngx_http_special_response.c
===================================================================
--- src/http/ngx_http_special_response.c	(revision 1383)
+++ src/http/ngx_http_special_response.c	(working copy)
@@ -193,6 +193,14 @@
 ;
 
 
+static char ngx_http_error_417_page[] =
+"<html>" CRLF
+"<head><title>417 Expectation Failed</title></head>" CRLF
+"<body bgcolor=\"white\">" CRLF
+"<center><h1>417 Expectation Failed</h1></center>" CRLF
+;
+
+
 static char ngx_http_error_495_page[] =
 "<html>" CRLF
 "<head><title>400 The SSL certificate error</title></head>"
@@ -301,8 +309,9 @@
     ngx_string(ngx_http_error_414_page),
     ngx_string(ngx_http_error_415_page),
     ngx_string(ngx_http_error_416_page),
+    ngx_string(ngx_http_error_417_page),
 
-#define NGX_HTTP_LEVEL_400  17
+#define NGX_HTTP_LEVEL_400  18
 
     ngx_string(ngx_http_error_495_page), /* 495, https certificate error */
     ngx_string(ngx_http_error_496_page), /* 496, https no certificate */
Index: src/http/ngx_http_header_filter_module.c
===================================================================
--- src/http/ngx_http_header_filter_module.c	(revision 1383)
+++ src/http/ngx_http_header_filter_module.c	(working copy)
@@ -96,8 +96,8 @@
                        */
     ngx_string("415 Unsupported Media Type"),
     ngx_string("416 Requested Range Not Satisfiable"),
+    ngx_string("417 Expectation Failed"),
 
-    /* ngx_null_string, */  /* "417 Expectation Failed" */
     /* ngx_null_string, */  /* "418 unused" */
     /* ngx_null_string, */  /* "419 unused" */
     /* ngx_null_string, */  /* "420 unused" */
@@ -106,7 +106,7 @@
     /* ngx_null_string, */  /* "423 Locked" */
     /* ngx_null_string, */  /* "424 Failed Dependency" */
 
-#define NGX_HTTP_LEVEL_400  17
+#define NGX_HTTP_LEVEL_400  18
 
     ngx_string("500 Internal Server Error"),
     ngx_string("501 Method Not Implemented"),
Index: src/http/modules/ngx_http_proxy_module.c
===================================================================
--- src/http/modules/ngx_http_proxy_module.c	(revision 1383)
+++ src/http/modules/ngx_http_proxy_module.c	(working copy)
@@ -402,6 +402,7 @@
     { ngx_string("Host"), ngx_string("$proxy_host") },
     { ngx_string("Connection"), ngx_string("close") },
     { ngx_string("Keep-Alive"), ngx_string("") },
+    { ngx_string("Expect"), ngx_string("") },
     { ngx_null_string, ngx_null_string }
 };
 


More information about the nginx-ru mailing list