changeset 293:ec3c049681fd

nginx-0.0.3-2004-03-19-08:25:53 import
author Igor Sysoev <igor@sysoev.ru>
date Fri, 19 Mar 2004 05:25:53 +0000
parents a472bfb778b3
children 5cfd65b8b0a7
files src/event/ngx_event_pipe.c src/http/modules/ngx_http_index_handler.c src/http/modules/proxy/ngx_http_proxy_upstream.c src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_request.c src/http/ngx_http_request.h src/http/ngx_http_request_body.c src/http/ngx_http_special_response.c src/os/unix/ngx_process_cycle.c
diffstat 10 files changed, 179 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -254,7 +254,6 @@ int ngx_event_pipe_read_upstream(ngx_eve
                 p->upstream_eof = 1;
                 break;
             }
-
         }
 
         p->read_length += n;
@@ -269,7 +268,7 @@ int ngx_event_pipe_read_upstream(ngx_eve
             if (n >= size) {
                 cl->hunk->last = cl->hunk->end;
 
-/* STUB */ cl->hunk->num = p->num++;
+                /* STUB */ cl->hunk->num = p->num++;
 
                 if (p->input_filter(p, cl->hunk) == NGX_ERROR) {
                     return NGX_ABORT;
@@ -288,7 +287,9 @@ int ngx_event_pipe_read_upstream(ngx_eve
     }
 
     if ((p->upstream_eof || p->upstream_error) && p->free_raw_hunks) {
-/* STUB */ p->free_raw_hunks->hunk->num = p->num++;
+
+        /* STUB */ p->free_raw_hunks->hunk->num = p->num++;
+
         if (p->input_filter(p, p->free_raw_hunks->hunk) == NGX_ERROR) {
             return NGX_ABORT;
         }
@@ -326,9 +327,39 @@ int ngx_event_pipe_write_to_downstream(n
             return ngx_event_pipe_drain_chains(p);
         }
 
-        if ((p->upstream_eof || p->upstream_error || p->upstream_done)
-            && p->out == NULL && p->in == NULL)
-        {
+        if (p->upstream_eof || p->upstream_error || p->upstream_done) {
+
+            /* pass the p->out and p->in chains to the output filter */
+
+            if (p->out) {
+                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
+                               "pipe write downstream flush out");
+
+                if (p->output_filter(p->output_ctx, p->out) == NGX_ERROR) {
+                    p->downstream_error = 1;
+                    return ngx_event_pipe_drain_chains(p);
+                }
+
+                p->out = NULL;
+            }
+
+            if (p->in) {
+                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
+                               "pipe write downstream flush in");
+
+                if (p->output_filter(p->output_ctx, p->in) == NGX_ERROR) {
+                    p->downstream_error = 1;
+                    return ngx_event_pipe_drain_chains(p);
+                }
+
+                p->in = NULL;
+            }
+
+            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
+                           "pipe write downstream done");
+
+            /* TODO: free unused hunks */
+
             p->downstream_done = 1;
             break;
         }
@@ -338,8 +369,9 @@ int ngx_event_pipe_write_to_downstream(n
         }
 
         /*
-         * bsize is the busy hunks size
-         * to_write is the size of data that to be written
+         * bsize is the size of the busy hunks,
+         * to_write is the size of data in these hunks that
+         * would be written to a socket
          */
 
         bsize = 0;
@@ -390,25 +422,24 @@ int ngx_event_pipe_write_to_downstream(n
         }
 
         if (out == NULL) {
+
             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
-                           "pipe busy hunk data: %d", to_write);
+                           "pipe busy hunk data to write: %d", to_write);
 
             if (!(p->upstream_blocked && to_write)) {
                 break;
             }
 
-            /*
-             * if the upstream is blocked and there are the busy hunks
-             * to write then write these hunks
-             */
         }
 
+        /*
+         * if the upstream is blocked and there are the busy hunks
+         * to write then write these hunks
+         */
+
         if (p->output_filter(p->output_ctx, out) == NGX_ERROR) {
             p->downstream_error = 1;
-
-            /* handle the downstream error at the begin of a cycle */
-
-            continue;
+            return ngx_event_pipe_drain_chains(p);
         }
 
         ngx_chain_update_chains(&p->free, &p->busy, &out, p->tag);
--- a/src/http/modules/ngx_http_index_handler.c
+++ b/src/http/modules/ngx_http_index_handler.c
@@ -21,7 +21,7 @@ typedef struct {
 } ngx_http_index_ctx_t;
 
 
-#define NGX_HTTP_DEFAULT_INDEX   (u_char *) "index.html"
+#define NGX_HTTP_DEFAULT_INDEX   "index.html"
 
 
 static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
@@ -98,7 +98,6 @@ ngx_module_t  ngx_http_index_module = {
 int ngx_http_index_handler(ngx_http_request_t *r)
 {
     u_char                     *name;
-    size_t                      len;
     ngx_fd_t                    fd;
     ngx_int_t                   rc;
     ngx_str_t                  *index;
@@ -161,18 +160,38 @@ int ngx_http_index_handler(ngx_http_requ
 
 #endif
 
-        len = clcf->root.len + r->uri.len + ilcf->max_index_len;
-        if (!(ctx->path.data = ngx_palloc(r->pool, len))) {
+        ctx->path.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len
+                                             + ilcf->max_index_len
+                                             - clcf->alias * clcf->name.len);
+        if (ctx->path.data == NULL) {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
 
         ctx->redirect.data = ngx_cpymem(ctx->path.data, clcf->root.data,
                                         clcf->root.len);
-        ctx->last = ngx_cpystrn(ctx->redirect.data, r->uri.data,
-                                r->uri.len + 1);
-        ctx->path.len = ctx->last - ctx->path.data;
+
+        if (clcf->alias) {
+            ctx->last = ngx_cpystrn(ctx->redirect.data,
+                                    r->uri.data + clcf->name.len,
+                                    r->uri.len + 1 - clcf->name.len);
+
+            /*
+             * aliases usually have trailling "/",
+             * set it in the start of the possible redirect
+             */
+
+            if (*ctx->redirect.data != '/') {
+                ctx->redirect.data--; 
+            }
+
+        } else {
+            ctx->last = ngx_cpystrn(ctx->redirect.data, r->uri.data,
+                                    r->uri.len + 1);
+        }
     }
 
+    ctx->path.len = ctx->last - ctx->path.data;
+
     index = ilcf->indices.elts;
     for (/* void */; ctx->index < ilcf->indices.nelts; ctx->index++) {
 
@@ -398,7 +417,7 @@ static char *ngx_http_index_merge_loc_co
 
         ngx_test_null(index, ngx_push_array(&conf->indices), NGX_CONF_ERROR);
         index->len = sizeof(NGX_HTTP_DEFAULT_INDEX) - 1;
-        index->data = NGX_HTTP_DEFAULT_INDEX;
+        index->data = (u_char *) NGX_HTTP_DEFAULT_INDEX;
         conf->max_index_len = sizeof(NGX_HTTP_DEFAULT_INDEX);
 
         return NGX_CONF_OK;
--- a/src/http/modules/proxy/ngx_http_proxy_upstream.c
+++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c
@@ -85,8 +85,8 @@ int ngx_http_proxy_request_upstream(ngx_
             return NGX_DONE;
         }
 
-        if (rc == NGX_ERROR) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        if (rc >= NGX_HTTP_SPECIAL_RESPONSE || rc == NGX_ERROR) {
+            return rc;
         }
     }
 
@@ -1243,8 +1243,8 @@ static void ngx_http_proxy_process_body(
 #endif
 
         if (ep->upstream_done || ep->upstream_eof || ep->upstream_error) {
-            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
-                           "http proxy upstream exit");
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, 0,
+                           "http proxy upstream exit: " PTR_FMT, ep->out);
             ngx_http_busy_unlock(p->lcf->busy_lock, &p->busy_lock);
             ngx_http_proxy_finalize_request(p, 0);
             return;
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -142,6 +142,13 @@ static ngx_command_t  ngx_http_core_comm
       0,
       NULL },
 
+    { ngx_string("client_max_body_size"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_size_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_core_loc_conf_t, client_max_body_size),
+      NULL },
+
     { ngx_string("client_body_timeout"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_msec_slot,
@@ -1147,6 +1154,7 @@ static void *ngx_http_core_create_loc_co
 
     */
 
+    lcf->client_max_body_size = NGX_CONF_UNSET_SIZE;
     lcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
     lcf->sendfile = NGX_CONF_UNSET;
     lcf->tcp_nopush = NGX_CONF_UNSET;
@@ -1225,6 +1233,8 @@ static char *ngx_http_core_merge_loc_con
     ngx_conf_merge_str_value(conf->default_type,
                              prev->default_type, "text/plain");
 
+    ngx_conf_merge_size_value(conf->client_max_body_size,
+                              prev->client_max_body_size, 10 * 1024 * 1024);
     ngx_conf_merge_msec_value(conf->client_body_timeout,
                               prev->client_body_timeout, 60000);
     ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -121,6 +121,7 @@ typedef struct {
     ngx_array_t  *types;
     ngx_str_t     default_type;
 
+    size_t        client_max_body_size;    /* client_max_body_size */
     size_t        send_lowat;              /* send_lowat */
     size_t        discarded_buffer_size;   /* discarded_buffer_size */
 
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -38,7 +38,8 @@ static char *client_header_errors[] = {
     "client %s sent invalid header, URL: %s",
     "client %s sent too long header line, URL: %s",
     "client %s sent HTTP/1.1 request without \"Host\" header, URL: %s",
-    "client %s sent invalid \"Content-Length\" header, URL: %s"
+    "client %s sent invalid \"Content-Length\" header, URL: %s",
+    "client %s wanted to send too large body: " SIZE_T_FMT " bytes, URL: %s"
 };
 
 
@@ -847,6 +848,21 @@ static ngx_int_t ngx_http_process_reques
         if (r->headers_in.content_length_n == NGX_ERROR) {
             return NGX_HTTP_PARSE_INVALID_CL_HEADER;
         }
+
+        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "http cl: " SIZE_T_FMT " max: " SIZE_T_FMT,
+                       r->headers_in.content_length_n,
+                       clcf->client_max_body_size);
+
+        if (clcf->client_max_body_size
+            && clcf->client_max_body_size
+                                     < (size_t) r->headers_in.content_length_n)
+        {
+            return NGX_HTTP_PARSE_ENTITY_TOO_LARGE;
+        }
+
     }
 
     if (r->headers_in.connection) {
@@ -884,8 +900,8 @@ void ngx_http_finalize_request(ngx_http_
         return;
     }
 
-    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "http finalize request");
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http finalize request: %d", rc);
 
     if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
 
@@ -1590,9 +1606,19 @@ static void ngx_http_client_error(ngx_ht
     r->connection->log->handler = NULL;
 
     if (ctx->url) {
-        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+        if (client_error == NGX_HTTP_PARSE_ENTITY_TOO_LARGE) {
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                    client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR],
+                    ctx->client, r->headers_in.content_length_n, ctx->url);
+
+            error = NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
+            r->lingering_close = 1;
+
+        } else {
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                     client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR],
                     ctx->client, ctx->url);
+        }
 
     } else {
         if (error == NGX_HTTP_REQUEST_URI_TOO_LARGE) {
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -30,6 +30,7 @@
 #define NGX_HTTP_PARSE_TOO_LONG_HEADER     15
 #define NGX_HTTP_PARSE_NO_HOST_HEADER      16
 #define NGX_HTTP_PARSE_INVALID_CL_HEADER   17
+#define NGX_HTTP_PARSE_ENTITY_TOO_LARGE    18
 
 
 #define NGX_HTTP_OK                        200
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -6,11 +6,13 @@
 
 
 static void ngx_http_read_client_request_body_handler(ngx_event_t *rev);
+static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r);
 
 
 ngx_int_t ngx_http_read_client_request_body(ngx_http_request_t *r,
                                             size_t request_buffer_size)
 {
+    ngx_int_t     rc;
     ssize_t       size;
     ngx_hunk_t   *h;
     ngx_chain_t  *cl;
@@ -48,11 +50,6 @@ ngx_int_t ngx_http_read_client_request_b
     ngx_test_null(r->request_body_hunk, ngx_create_temp_hunk(r->pool, size),
                   NGX_ERROR);
 
-    r->connection->read->event_handler =
-                                     ngx_http_read_client_request_body_handler;
-
-    ngx_http_read_client_request_body_handler(r->connection->read);
-
     ngx_alloc_link_and_set_hunk(cl, r->request_body_hunk, r->pool,
                                 NGX_ERROR);
 
@@ -63,25 +60,39 @@ ngx_int_t ngx_http_read_client_request_b
         r->request_hunks = cl;
     }
 
-    if (r->request_body_len) {
-        return NGX_AGAIN;
-    }
+    r->connection->read->event_handler =
+                                     ngx_http_read_client_request_body_handler;
 
-    return NGX_OK;
+    return ngx_http_do_read_client_request_body(r);
 }
 
 
 static void ngx_http_read_client_request_body_handler(ngx_event_t *rev)
 {
+    ngx_int_t            rc;
+    ngx_connection_t    *c;
+    ngx_http_request_t  *r;
+
+    c = rev->data;
+    r = c->data;
+
+    rc = ngx_http_do_read_client_request_body(r);
+
+    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
+        ngx_http_finalize_request(r, rc);
+    }
+}
+
+
+static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r)
+{
     size_t                     size;
     ssize_t                    n;
     ngx_hunk_t                *h;
     ngx_connection_t          *c;
-    ngx_http_request_t        *r;
     ngx_http_core_loc_conf_t  *clcf;
 
-    c = rev->data;
-    r = c->data;
+    c = r->connection;
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http read client request body");
@@ -95,8 +106,7 @@ static void ngx_http_read_client_request
             /* TODO: n == 0 or not complete and level event */
 
             if (n == NGX_ERROR) {
-                ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-                return;
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
             }
 
             r->temp_file->offset += n;
@@ -113,15 +123,18 @@ static void ngx_http_read_client_request
 
         n = ngx_recv(c, r->request_body_hunk->last, size);
 
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "http client request body recv " SIZE_T_FMT, n);
+
         if (n == NGX_AGAIN) {
             clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-            ngx_add_timer(rev, clcf->client_body_timeout);
+            ngx_add_timer(c->read, clcf->client_body_timeout);
 
-            if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
-                ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
             }
 
-            return;
+            return NGX_AGAIN;
         }
 
         if (n == 0) {
@@ -130,8 +143,7 @@ static void ngx_http_read_client_request
         }
 
         if (n == 0 || n == NGX_ERROR) {
-            ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
-            return;
+            return NGX_HTTP_BAD_REQUEST;
         }
 
         r->request_body_hunk->last += n;
@@ -142,8 +154,12 @@ static void ngx_http_read_client_request
         }
     }
 
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http client request body left " SIZE_T_FMT,
+                   r->request_body_len);
+
     if (r->request_body_len) {
-        return;
+        return NGX_AGAIN;
     }
 
     if (r->temp_file->file.fd != NGX_INVALID_FILE) {
@@ -156,14 +172,12 @@ static void ngx_http_read_client_request
         /* TODO: n == 0 or not complete and level event */
 
         if (n == NGX_ERROR) {
-            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-            return;
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
 
         h = ngx_calloc_hunk(r->pool);
         if (h == NULL) {
-            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-            return;
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
 
         h->type = NGX_HUNK_FILE;
@@ -180,4 +194,6 @@ static void ngx_http_read_client_request
     }
 
     r->request_body_handler(r->data);
+
+    return NGX_OK;
 }
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -204,8 +204,6 @@ int ngx_http_special_response_handler(ng
     if (r->lingering_close == 1) {
         switch (error) {
             case NGX_HTTP_BAD_REQUEST:
-            case NGX_HTTP_REQUEST_URI_TOO_LARGE:
-            case NGX_HTTP_INTERNAL_SERVER_ERROR:
                 r->lingering_close = 0;
         }
     }
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -38,24 +38,26 @@ void ngx_master_process_cycle(ngx_cycle_
     ngx_msec_t         delay;
     ngx_core_conf_t   *ccf;
 
-    sigemptyset(&set);
-    sigaddset(&set, SIGCHLD);
-    sigaddset(&set, SIGALRM);
-    sigaddset(&set, SIGINT);
-    sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
-    sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
-    sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
-    sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
-    sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
-    sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));
+    if (ngx_process == NGX_PROCESS_MASTER) {
+        sigemptyset(&set);
+        sigaddset(&set, SIGCHLD);
+        sigaddset(&set, SIGALRM);
+        sigaddset(&set, SIGINT);
+        sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
+        sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
+        sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
+        sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
+        sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
+        sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));
 
-    if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
-        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
-                      "sigprocmask() failed");
+        if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
+            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+                          "sigprocmask() failed");
+        }
+
+        sigemptyset(&set);
     }
 
-    sigemptyset(&set);
-
     ngx_setproctitle("master process");
 
     ngx_new_binary = 0;