SSI in static POST

Igor Sysoev is at rambler-co.ru
Thu Mar 5 00:29:10 MSK 2009


Прилагаемый патч для 0.7.39 разрешает POST в статический файл с последующей
обработкой POST'а в SSI. Первый include, которому необходимо тело POST,
должен иметь параметр wait="yes". Если кому-то это нужно, пусть тестирует:
в 0.7 я пока это включать не хочу.


-- 
Игорь Сысоев
http://sysoev.ru
-------------- next part --------------
Index: src/http/ngx_http_request.c
===================================================================
--- src/http/ngx_http_request.c	(revision 1864)
+++ src/http/ngx_http_request.c	(working copy)
@@ -2225,6 +2225,19 @@
         r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
         ngx_add_timer(rev, clcf->lingering_timeout);
         return;
+
+    } else {
+
+        r->expect_tested = 1;
+
+        if (ngx_http_discard_request_body(r) != NGX_OK) {
+            ngx_http_close_connection(c);
+            return;
+        }
+
+        if (r->discard_body) {
+            return;
+        }
     }
 
     c->log->action = "closing request";
Index: src/http/ngx_http_core_module.c
===================================================================
--- src/http/ngx_http_core_module.c	(revision 1864)
+++ src/http/ngx_http_core_module.c	(working copy)
@@ -686,9 +686,6 @@
 };
 
 
-static ngx_str_t  ngx_http_core_get_method = { 3, (u_char *) "GET " };
-
-
 void
 ngx_http_handler(ngx_http_request_t *r)
 {
@@ -2019,9 +2016,7 @@
     ngx_http_clear_accept_ranges(sr);
     ngx_http_clear_last_modified(sr);
 
-    sr->request_body = r->request_body;
-
-    sr->method = NGX_HTTP_GET;
+    sr->method = r->method;
     sr->http_version = r->http_version;
 
     sr->request_line = r->request_line;
@@ -2039,7 +2034,7 @@
     sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;
 
     sr->unparsed_uri = r->unparsed_uri;
-    sr->method_name = ngx_http_core_get_method;
+    sr->method_name = r->method_name;
     sr->http_protocol = r->http_protocol;
 
     if (ngx_http_set_exten(sr) != NGX_OK) {
Index: src/http/ngx_http_upstream.c
===================================================================
--- src/http/ngx_http_upstream.c	(revision 1864)
+++ src/http/ngx_http_upstream.c	(working copy)
@@ -356,8 +356,8 @@
         }
     }
 
-    if (r->request_body) {
-        u->request_bufs = r->request_body->bufs;
+    if (r->main->request_body) {
+        u->request_bufs = r->main->request_body->bufs;
     }
 
     if (u->create_request(r) != NGX_OK) {
@@ -720,9 +720,10 @@
 static void
 ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
 {
-    ngx_int_t          rc;
-    ngx_time_t        *tp;
-    ngx_connection_t  *c;
+    ngx_int_t                 rc;
+    ngx_time_t               *tp;
+    ngx_connection_t         *c;
+    ngx_http_request_body_t  *rb;
 
     r->connection->log->action = "connecting to upstream";
 
@@ -804,14 +805,14 @@
         }
     }
 
-    if (r->request_body
-        && r->request_body->buf
-        && r->request_body->temp_file
-        && r == r->main)
-    {
+    rb = r->main->request_body;
+
+    if (r == r->main && rb && rb->buf && rb->temp_file) {
+
         /*
-         * the r->request_body->buf can be reused for one request only,
-         * the subrequests should allocate their own temporay bufs
+         * the r->main->request_body->buf can be reused in ngx_output_chain()
+         * for reading file in single request only, therefore
+         * subrequests should allocate their own temporary bufs
          */
 
         u->output.free = ngx_alloc_chain_link(r->pool);
@@ -821,13 +822,13 @@
             return;
         }
 
-        u->output.free->buf = r->request_body->buf;
+        u->output.free->buf = rb->buf;
         u->output.free->next = NULL;
         u->output.allocated = 1;
 
-        r->request_body->buf->pos = r->request_body->buf->start;
-        r->request_body->buf->last = r->request_body->buf->start;
-        r->request_body->buf->tag = u->output.tag;
+        rb->buf->pos = rb->buf->start;
+        rb->buf->last = rb->buf->start;
+        rb->buf->tag = u->output.tag;
     }
 
     u->request_sent = 0;
@@ -948,8 +949,8 @@
 
     /* reinit the subrequest's ngx_output_chain() context */
 
-    if (r->request_body && r->request_body->temp_file
-        && r != r->main && u->output.buf)
+    if (r != r->main && u->output.buf
+        && r->main->request_body && r->main->request_body->temp_file)
     {
         u->output.free = ngx_alloc_chain_link(r->pool);
         if (u->output.free == NULL) {
@@ -1639,6 +1640,7 @@
     ngx_connection_t          *c;
     ngx_pool_cleanup_t        *cl;
     ngx_pool_cleanup_file_t   *clf;
+    ngx_http_request_body_t   *rb;
     ngx_http_core_loc_conf_t  *clcf;
 
     rc = ngx_http_send_header(r);
@@ -1650,15 +1652,19 @@
 
     u->header_sent = 1;
 
-    if (r->request_body && r->request_body->temp_file) {
+    rb = r->main->request_body;
+
+    if (rb && rb->temp_file) {
+
         for (cl = r->pool->cleanup; cl; cl = cl->next) {
+
             if (cl->handler == ngx_pool_cleanup_file) {
                 clf = cl->data;
 
-                if (clf->fd == r->request_body->temp_file->file.fd) {
+                if (clf->fd == rb->temp_file->file.fd) {
                     cl->handler(clf);
                     cl->handler = NULL;
-                    r->request_body->temp_file->file.fd = NGX_INVALID_FILE;
+                    rb->temp_file->file.fd = NGX_INVALID_FILE;
                     break;
                 }
             }
Index: src/http/ngx_http_request_body.c
===================================================================
--- src/http/ngx_http_request_body.c	(revision 1864)
+++ src/http/ngx_http_request_body.c	(working copy)
@@ -20,7 +20,7 @@
 
 /*
  * on completion ngx_http_read_client_request_body() adds to
- * r->request_body->bufs one or two bufs:
+ * r->main->request_body->bufs one or two bufs:
  *    *) one memory buf that was preread in r->header_in;
  *    *) one memory or file buf that contains the rest of the body
  */
@@ -34,44 +34,47 @@
     ngx_buf_t                 *b;
     ngx_chain_t               *cl, **next;
     ngx_temp_file_t           *tf;
+    ngx_http_request_t        *mr;
     ngx_http_request_body_t   *rb;
     ngx_http_core_loc_conf_t  *clcf;
 
-    if (r->request_body || r->discard_body) {
+    mr = r->main;
+
+    if (mr->request_body || mr->discard_body) {
         post_handler(r);
         return NGX_OK;
     }
 
-    if (ngx_http_test_expect(r) != NGX_OK) {
+    if (ngx_http_test_expect(mr) != NGX_OK) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
+    rb = ngx_pcalloc(mr->pool, sizeof(ngx_http_request_body_t));
     if (rb == NULL) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    r->request_body = rb;
+    mr->request_body = rb;
 
-    if (r->headers_in.content_length_n < 0) {
+    if (mr->headers_in.content_length_n < 0) {
         post_handler(r);
         return NGX_OK;
     }
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
-    if (r->headers_in.content_length_n == 0) {
+    if (mr->headers_in.content_length_n == 0) {
 
         if (r->request_body_in_file_only) {
-            tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
+            tf = ngx_pcalloc(mr->pool, sizeof(ngx_temp_file_t));
             if (tf == NULL) {
                 return NGX_HTTP_INTERNAL_SERVER_ERROR;
             }
 
             tf->file.fd = NGX_INVALID_FILE;
-            tf->file.log = r->connection->log;
+            tf->file.log = mr->connection->log;
             tf->path = clcf->client_body_temp_path;
-            tf->pool = r->pool;
+            tf->pool = mr->pool;
             tf->warn = "a client request body is buffered to a temporary file";
             tf->log_level = r->request_body_file_log_level;
             tf->persistent = r->request_body_in_persistent_file;
@@ -106,27 +109,27 @@
      *     rb->rest = 0;
      */
 
-    preread = r->header_in->last - r->header_in->pos;
+    preread = mr->header_in->last - mr->header_in->pos;
 
     if (preread) {
 
         /* there is the pre-read part of the request body */
 
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mr->connection->log, 0,
                        "http client request body preread %uz", preread);
 
-        b = ngx_calloc_buf(r->pool);
+        b = ngx_calloc_buf(mr->pool);
         if (b == NULL) {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
 
         b->temporary = 1;
-        b->start = r->header_in->pos;
-        b->pos = r->header_in->pos;
-        b->last = r->header_in->last;
-        b->end = r->header_in->end;
+        b->start = mr->header_in->pos;
+        b->pos = mr->header_in->pos;
+        b->last = mr->header_in->last;
+        b->end = mr->header_in->end;
 
-        rb->bufs = ngx_alloc_chain_link(r->pool);
+        rb->bufs = ngx_alloc_chain_link(mr->pool);
         if (rb->bufs == NULL) {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
@@ -136,15 +139,15 @@
 
         rb->buf = b;
 
-        if ((off_t) preread >= r->headers_in.content_length_n) {
+        if ((off_t) preread >= mr->headers_in.content_length_n) {
 
             /* the whole request body was pre-read */
 
-            r->header_in->pos += (size_t) r->headers_in.content_length_n;
-            r->request_length += r->headers_in.content_length_n;
+            mr->header_in->pos += (size_t) mr->headers_in.content_length_n;
+            mr->request_length += mr->headers_in.content_length_n;
 
-            if (r->request_body_in_file_only) {
-                if (ngx_http_write_request_body(r, rb->bufs) != NGX_OK) {
+            if (mr->request_body_in_file_only) {
+                if (ngx_http_write_request_body(mr, rb->bufs) != NGX_OK) {
                     return NGX_HTTP_INTERNAL_SERVER_ERROR;
                 }
             }
@@ -158,11 +161,11 @@
          * to not consider the body as pipelined request in
          * ngx_http_set_keepalive()
          */
-        r->header_in->pos = r->header_in->last;
+        mr->header_in->pos = mr->header_in->last;
 
-        r->request_length += preread;
+        mr->request_length += preread;
 
-        rb->rest = r->headers_in.content_length_n - preread;
+        rb->rest = mr->headers_in.content_length_n - preread;
 
         if (rb->rest <= (off_t) (b->end - b->last)) {
 
@@ -179,7 +182,7 @@
 
     } else {
         b = NULL;
-        rb->rest = r->headers_in.content_length_n;
+        rb->rest = mr->headers_in.content_length_n;
         next = &rb->bufs;
     }
 
@@ -200,12 +203,12 @@
         b = NULL;
     }
 
-    rb->buf = ngx_create_temp_buf(r->pool, size);
+    rb->buf = ngx_create_temp_buf(mr->pool, size);
     if (rb->buf == NULL) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    cl = ngx_alloc_chain_link(r->pool);
+    cl = ngx_alloc_chain_link(mr->pool);
     if (cl == NULL) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
@@ -250,7 +253,7 @@
     rc = ngx_http_do_read_client_request_body(r);
 
     if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
-        ngx_http_finalize_request(r, rc);
+        ngx_http_finalize_request(r->main, rc);
     }
 }
 
@@ -262,11 +265,13 @@
     ssize_t                    n;
     ngx_buf_t                 *b;
     ngx_connection_t          *c;
+    ngx_http_request_t        *mr;
     ngx_http_request_body_t   *rb;
     ngx_http_core_loc_conf_t  *clcf;
 
     c = r->connection;
-    rb = r->request_body;
+    mr = r->main;
+    rb = mr->request_body;
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http read client request body");
@@ -275,7 +280,7 @@
         for ( ;; ) {
             if (rb->buf->last == rb->buf->end) {
 
-                if (ngx_http_write_request_body(r, rb->to_write) != NGX_OK) {
+                if (ngx_http_write_request_body(mr, rb->to_write) != NGX_OK) {
                     return NGX_HTTP_INTERNAL_SERVER_ERROR;
                 }
 
@@ -310,7 +315,7 @@
 
             rb->buf->last += n;
             rb->rest -= n;
-            r->request_length += n;
+            mr->request_length += n;
 
             if (rb->rest == 0) {
                 break;
@@ -348,7 +353,7 @@
 
         /* save the last part */
 
-        if (ngx_http_write_request_body(r, rb->to_write) != NGX_OK) {
+        if (ngx_http_write_request_body(mr, rb->to_write) != NGX_OK) {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
 
Index: src/http/ngx_http_variables.c
===================================================================
--- src/http/ngx_http_variables.c	(revision 1864)
+++ src/http/ngx_http_variables.c	(working copy)
@@ -1481,17 +1481,21 @@
 ngx_http_variable_request_body_file(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
 {
-    if (r->request_body == NULL || r->request_body->temp_file == NULL) {
+    ngx_http_request_body_t  *rb;
+
+    rb = r->request_body;
+
+    if (rb == NULL || rb->temp_file == NULL) {
         v->not_found = 1;
 
         return NGX_OK;
     }
 
-    v->len = r->request_body->temp_file->file.name.len;
+    v->len = rb->temp_file->file.name.len;
     v->valid = 1;
     v->no_cacheable = 0;
     v->not_found = 0;
-    v->data = r->request_body->temp_file->file.name.data;
+    v->data = rb->temp_file->file.name.data;
 
     return NGX_OK;
 }
Index: src/http/modules/ngx_http_dav_module.c
===================================================================
--- src/http/modules/ngx_http_dav_module.c	(revision 1864)
+++ src/http/modules/ngx_http_dav_module.c	(working copy)
@@ -220,7 +220,7 @@
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http put filename: \"%s\"", path.data);
 
-    temp = &r->request_body->temp_file->file.name;
+    temp = &r->main->request_body->temp_file->file.name;
 
     if (ngx_file_info(path.data, &fi) == -1) {
         status = NGX_HTTP_CREATED;
@@ -259,7 +259,7 @@
 
         if (date != NGX_ERROR) {
             ext.time = date;
-            ext.fd = r->request_body->temp_file->file.fd;
+            ext.fd = r->main->request_body->temp_file->file.fd;
         }
     }
 
Index: src/http/modules/ngx_http_static_module.c
===================================================================
--- src/http/modules/ngx_http_static_module.c	(revision 1864)
+++ src/http/modules/ngx_http_static_module.c	(working copy)
@@ -197,14 +197,13 @@
 
 #endif
 
-    if (r->method & NGX_HTTP_POST) {
-        return NGX_HTTP_NOT_ALLOWED;
-    }
+    if (r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD)) {
 
-    rc = ngx_http_discard_request_body(r);
+        rc = ngx_http_discard_request_body(r);
 
-    if (rc != NGX_OK) {
-        return rc;
+        if (rc != NGX_OK) {
+            return rc;
+        }
     }
 
     log->action = "sending response to client";
Index: src/http/modules/perl/nginx.xs
===================================================================
--- src/http/modules/perl/nginx.xs	(revision 1864)
+++ src/http/modules/perl/nginx.xs	(working copy)
@@ -384,25 +384,25 @@
     CODE:
 
     dXSTARG;
-    ngx_http_request_t  *r;
-    size_t               len;
+    ngx_http_request_t       *r;
+    ngx_http_request_body_t  *rb;
+    size_t                    len;
 
     ngx_http_perl_set_request(r);
 
-    if (r->request_body == NULL
-        || r->request_body->temp_file
-        || r->request_body->bufs == NULL)
-    {
+    rb = r->main->request_body;
+
+    if (rb == NULL || rb->temp_file || rb->bufs == NULL) {
         XSRETURN_UNDEF;
     }
 
-    len = r->request_body->bufs->buf->last - r->request_body->bufs->buf->pos;
+    len = rb->bufs->buf->last - rb->bufs->buf->pos;
 
     if (len == 0) {
         XSRETURN_UNDEF;
     }
 
-    ngx_http_perl_set_targ(r->request_body->bufs->buf->pos, len);
+    ngx_http_perl_set_targ(rb->bufs->buf->pos, len);
 
     ST(0) = TARG;
 
@@ -412,16 +412,19 @@
     CODE:
 
     dXSTARG;
-    ngx_http_request_t  *r;
+    ngx_http_request_t       *r;
+    ngx_http_request_body_t  *rb;
 
     ngx_http_perl_set_request(r);
 
-    if (r->request_body == NULL || r->request_body->temp_file == NULL) {
+    rb = r->main->request_body;
+
+    if (rb == NULL || rb->temp_file == NULL) {
         XSRETURN_UNDEF;
     }
 
-    ngx_http_perl_set_targ(r->request_body->temp_file->file.name.data,
-                           r->request_body->temp_file->file.name.len);
+    ngx_http_perl_set_targ(rb->temp_file->file.name.data,
+                           rb->temp_file->file.name.len);
 
     ST(0) = TARG;
 


More information about the nginx-ru mailing list