changeset 2474:6175f886ddfb stable-0.6

r2420, r2421, r2435, r2436, r2437 merge: *) send "100 Continue" for HTTP/1.1 only *) do not send "100 Continue" for subrequests *) send "100 Continue" just before reading request body *) set send() slot for POSIX systems
author Igor Sysoev <igor@sysoev.ru>
date Mon, 26 Jan 2009 15:22:24 +0000
parents afba93b8bf06
children 774d6ed89c56
files src/http/ngx_http_core_module.c src/http/ngx_http_request_body.c src/http/ngx_http_special_response.c src/os/unix/ngx_posix_init.c
diffstat 4 files changed, 64 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -30,7 +30,6 @@ typedef struct {
 
 static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r,
     ngx_array_t *locations, ngx_uint_t regex_start, size_t len);
-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);
@@ -786,7 +785,7 @@ ngx_http_core_find_config_phase(ngx_http
 {
     u_char                    *p;
     size_t                     len;
-    ngx_int_t                  rc, expect;
+    ngx_int_t                  rc;
     ngx_http_core_loc_conf_t  *clcf;
     ngx_http_core_srv_conf_t  *cscf;
 
@@ -833,15 +832,6 @@ ngx_http_core_find_config_phase(ngx_http
         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_HTTP_LOCATION_AUTO_REDIRECT) {
         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
         if (r->headers_out.location == NULL) {
@@ -1261,45 +1251,6 @@ ngx_http_core_find_location(ngx_http_req
 }
 
 
-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_OK;
-    }
-
-    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)
 {
@@ -1861,6 +1812,7 @@ ngx_http_subrequest(ngx_http_request_t *
     sr->fast_subrequest = 1;
 
     sr->discard_body = r->discard_body;
+    sr->expect_tested = 1;
     sr->main_filter_need_in_memory = r->main_filter_need_in_memory;
 
     sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -16,6 +16,7 @@ static ngx_int_t ngx_http_write_request_
     ngx_chain_t *body);
 static void ngx_http_read_discarded_request_body_handler(ngx_http_request_t *r);
 static ngx_int_t ngx_http_read_discarded_request_body(ngx_http_request_t *r);
+static ngx_int_t ngx_http_test_expect(ngx_http_request_t *r);
 
 
 /*
@@ -42,6 +43,10 @@ ngx_http_read_client_request_body(ngx_ht
         return NGX_OK;
     }
 
+    if (ngx_http_test_expect(r) != NGX_OK) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
     rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
     if (rb == NULL) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -434,6 +439,10 @@ ngx_http_discard_request_body(ngx_http_r
         return NGX_OK;
     }
 
+    if (ngx_http_test_expect(r) != NGX_OK) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
     rev = r->connection->read;
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http set discard body");
@@ -582,3 +591,45 @@ ngx_http_read_discarded_request_body(ngx
 
     return NGX_AGAIN;
 }
+
+
+static ngx_int_t
+ngx_http_test_expect(ngx_http_request_t *r)
+{
+    ngx_int_t   n;
+    ngx_str_t  *expect;
+
+    if (r->expect_tested
+        || r->headers_in.expect == NULL
+        || r->http_version < NGX_HTTP_VERSION_11)
+    {
+        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_OK;
+    }
+
+    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_ERROR;
+}
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -378,6 +378,8 @@ ngx_http_special_response_handler(ngx_ht
         }
     }
 
+    r->expect_tested = 1;
+
     if (ngx_http_discard_request_body(r) != NGX_OK) {
         error = NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
@@ -430,11 +432,18 @@ static ngx_int_t
 ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
 {
     u_char                     ch, *p, *last;
+    ngx_int_t                  overwrite;
     ngx_str_t                 *uri, *args, u, a;
     ngx_table_elt_t           *location;
     ngx_http_core_loc_conf_t  *clcf;
 
-    r->err_status = err_page->overwrite;
+    overwrite = err_page->overwrite;
+
+    if (overwrite && overwrite != NGX_HTTP_OK) {
+        r->expect_tested = 1;
+    }
+
+    r->err_status = overwrite;
 
     r->zero_in_uri = 0;
 
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -22,7 +22,7 @@ ngx_os_io_t ngx_os_io = {
     ngx_unix_recv,
     ngx_readv_chain,
     ngx_udp_unix_recv,
-    NULL,
+    ngx_unix_send,
     ngx_writev_chain,
     0
 };