платная доработка nginx

Sergey Bochenkov bachan at j3qq4.org
Tue Jan 27 15:30:43 MSK 2009


Я, конечно, не знаток, но как тут уже сказали, эта фича порождает много
философских вопросов, а с технической точки зрения никаких сложностей
вроде бы нет.

Например, прилагаемый патч должен (если я ничего не забыл) решать вашу проблему.
Патч для 0.7.32 версии.


* Dmitry Alekhin <dmitry at ivoho.com> [2009-01-23 04:19:27 +0300]:

> Всем привет,
> 
> Какое то время назад я поднимал тему о возможности обработки virtual include-ов не GET а POST методом, в случае вызова 
> 'родительского' html-я c SSI  POST-ом. 
> 
> Тема как то затухла, и стало непонятно, толи это невозможно из за архитектуры nginx , то ли просто никому кроме меня не нужно.
> Прошу прощения что пишу в список рассылки, но я готов оплатить разумную стоимость разработки патча для nginx если это возможно.
> Думаю, квалифицированных разработчиков под nginx - в данном списке рассылке тусуется больше всего.
> Сам Игорь молчит :)
> 
> Спасибо,
> 
> Дмитрий
> 
> PS - Почта для связи dmitry at ivoho.com
> 

-------------- next part --------------
--- src/http/modules/ngx_http_static_module.c	2009-01-16 16:53:08.000000000 +0300
+++ src/http/modules/ngx_http_static_module.c	2009-01-27 15:11:15.274859288 +0300
@@ -10,6 +10,7 @@
 
 
 static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r);
+static void ngx_http_static_body_handler(ngx_http_request_t *r);
 static ngx_int_t ngx_http_static_init(ngx_conf_t *cf);
 
 
@@ -44,8 +45,8 @@
 };
 
 
-static ngx_int_t
-ngx_http_static_handler(ngx_http_request_t *r)
+static void
+ngx_http_static_body_handler(ngx_http_request_t *r)
 {
     u_char                    *last, *location;
     size_t                     root, len;
@@ -54,23 +55,10 @@
     ngx_uint_t                 level;
     ngx_log_t                 *log;
     ngx_buf_t                 *b;
-    ngx_chain_t                out;
+    ngx_chain_t                out, *cl, **ll;
     ngx_open_file_info_t       of;
     ngx_http_core_loc_conf_t  *clcf;
 
-    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) {
-        return NGX_HTTP_NOT_ALLOWED;
-    }
-
-    if (r->uri.data[r->uri.len - 1] == '/') {
-        return NGX_DECLINED;
-    }
-
-    /* TODO: Win32 */
-    if (r->zero_in_uri) {
-        return NGX_DECLINED;
-    }
-
     log = r->connection->log;
 
     /*
@@ -80,7 +68,8 @@
 
     last = ngx_http_map_uri_to_path(r, &path, &root, 0);
     if (last == NULL) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return;
     }
 
     path.len = last - path.data;
@@ -104,7 +93,8 @@
         switch (of.err) {
 
         case 0:
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
 
         case NGX_ENOENT:
         case NGX_ENOTDIR:
@@ -132,7 +122,8 @@
                           ngx_open_file_n " \"%s\" failed", path.data);
         }
 
-        return rc;
+        ngx_http_finalize_request(r, rc);
+        return;
     }
 
     r->root_tested = !r->error_page;
@@ -145,7 +136,8 @@
 
         r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t));
         if (r->headers_out.location == NULL) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
         }
 
         len = r->uri.len + 1;
@@ -162,7 +154,8 @@
 
             location = ngx_pnalloc(r->pool, len);
             if (location == NULL) {
-                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+                ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return;
             }
 
             last = ngx_copy(location, r->uri.data, r->uri.len);
@@ -183,7 +176,8 @@
         r->headers_out.location->value.len = len;
         r->headers_out.location->value.data = location;
 
-        return NGX_HTTP_MOVED_PERMANENTLY;
+        ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
+        return;
     }
 
 #if !(NGX_WIN32) /* the not regular files are probably Unix specific */
@@ -192,21 +186,36 @@
         ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
                       "\"%s\" is not a regular file", path.data);
 
-        return NGX_HTTP_NOT_FOUND;
+        ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
+        return;
     }
 
 #endif
 
-    if (r->method & NGX_HTTP_POST) {
-        return NGX_HTTP_NOT_ALLOWED;
-    }
+    ll = &r->request_body->bufs;
+    cl = *ll;
 
-    rc = ngx_http_discard_request_body(r);
+    for (; cl; cl = cl->next) {
+        b = ngx_alloc_buf(r->pool);
+        if (b == NULL) {
+            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
+        }
 
-    if (rc != NGX_OK) {
-        return rc;
+        ngx_memcpy(b, cl->buf, sizeof(ngx_buf_t));
+
+        *ll = ngx_alloc_chain_link(r->pool);
+        if (*ll == NULL) {
+            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
+        }
+
+        (*ll)->buf = b;
+        ll = &(*ll)->next;
     }
 
+    *ll = NULL;
+
     log->action = "sending response to client";
 
     r->headers_out.status = NGX_HTTP_OK;
@@ -214,11 +223,13 @@
     r->headers_out.last_modified_time = of.mtime;
 
     if (ngx_http_set_content_type(r) != NGX_OK) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return;
     }
 
     if (r != r->main && of.size == 0) {
-        return ngx_http_send_header(r);
+        ngx_http_finalize_request(r, ngx_http_send_header(r));
+        return;
     }
 
     r->allow_ranges = 1;
@@ -227,18 +238,21 @@
 
     b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
     if (b == NULL) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return;
     }
 
     b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
     if (b->file == NULL) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return;
     }
 
     rc = ngx_http_send_header(r);
 
     if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
-        return rc;
+        ngx_http_finalize_request(r, rc);
+        return;
     }
 
     b->file_pos = 0;
@@ -256,7 +270,44 @@
     out.buf = b;
     out.next = NULL;
 
-    return ngx_http_output_filter(r, &out);
+    ngx_http_finalize_request(r, ngx_http_output_filter(r, &out));
+    return;
+}
+
+
+static ngx_int_t
+ngx_http_static_handler(ngx_http_request_t *r)
+{
+    ngx_int_t rc;
+
+    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) {
+        return NGX_HTTP_NOT_ALLOWED;
+    }
+
+    if (r->uri.data[r->uri.len - 1] == '/') {
+        return NGX_DECLINED;
+    }
+
+    /* TODO: Win32 */
+    if (r->zero_in_uri) {
+        return NGX_DECLINED;
+    }
+
+    if (!(r->method & NGX_HTTP_POST)) {
+        rc = ngx_http_discard_request_body(r);
+
+        if (rc != NGX_OK) {
+            return rc;
+        }
+    }
+
+    rc = ngx_http_read_client_request_body(r, ngx_http_static_body_handler);
+
+    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
+        return rc;
+    }
+
+    return NGX_DONE;
 }
 
 
--- src/http/ngx_http_core_module.c	2009-01-21 15:11:22.000000000 +0300
+++ src/http/ngx_http_core_module.c	2009-01-27 11:56:38.538741816 +0300
@@ -685,7 +685,7 @@
 };
 
 
-static ngx_str_t  ngx_http_core_get_method = { 3, (u_char *) "GET " };
+/* static ngx_str_t  ngx_http_core_get_method = { 3, (u_char *) "GET " }; */
 
 
 void
@@ -2020,7 +2020,7 @@
 
     sr->request_body = r->request_body;
 
-    sr->method = NGX_HTTP_GET;
+    sr->method = r->method; /* NGX_HTTP_GET; */
     sr->http_version = r->http_version;
 
     sr->request_line = r->request_line;
@@ -2038,7 +2038,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; /* ngx_http_core_get_method; */
     sr->http_protocol = r->http_protocol;
 
     if (ngx_http_set_exten(sr) != NGX_OK) {


More information about the nginx-ru mailing list