diff src/http/ngx_http_core_module.c @ 380:3ce4580ae286 NGINX_0_6_34

nginx 0.6.34 *) Change: now the EAGAIN error returned by connect() is not considered as temporary error. *) Change: now the "gzip_vary" directive turned on issues a "Vary: Accept-Encoding" header line for uncompressed responses too. *) Feature: the "expires" directive supports daily time. *) Feature: the "Expect" request header line support. *) Feature: now the "rewrite" directive does a redirect automatically if the "https://" protocol is used. *) Bugfix: the "listen" directive parameters such as "backlog", "rcvbuf", etc. were not set, if a default server was not the first one. *) Bugfix: the "log_not_found" directive did not work for index files tests. *) Bugfix: now if FastCGI server sends a "Location" header line without status line, then nginx uses 302 status code. Thanks to Maxim Dounin. *) Bugfix: the ngx_http_flv_module did not support several values in a query string. *) Bugfix: when a request to a directory was redirected with the slash added, nginx dropped a query string from the original request.
author Igor Sysoev <http://sysoev.ru>
date Thu, 27 Nov 2008 00:00:00 +0300
parents d13234035cad
children e9979466be2f
line wrap: on
line diff
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -30,6 +30,7 @@ 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);
@@ -785,7 +786,7 @@ ngx_http_core_find_config_phase(ngx_http
 {
     u_char                    *p;
     size_t                     len;
-    ngx_int_t                  rc;
+    ngx_int_t                  rc, expect;
     ngx_http_core_loc_conf_t  *clcf;
     ngx_http_core_srv_conf_t  *cscf;
 
@@ -832,6 +833,14 @@ 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);
@@ -1252,6 +1261,45 @@ 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)
 {