changeset 162:96993d4d5067

nginx-0.0.1-2003-10-28-00:01:00 import
author Igor Sysoev <igor@sysoev.ru>
date Mon, 27 Oct 2003 21:01:00 +0000
parents 88abd07d9f62
children fb61ba77beba
files src/core/ngx_alloc.h src/core/ngx_hunk.h src/core/ngx_output_chain.c src/event/ngx_event_connect.c src/http/modules/proxy/ngx_http_proxy_handler.c src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_request.h src/http/ngx_http_request_body.c src/http/ngx_http_special_response.c
diffstat 10 files changed, 182 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/ngx_alloc.h
+++ b/src/core/ngx_alloc.h
@@ -17,6 +17,8 @@
 
 #define ngx_test_null(p, alloc, rc)  if ((p = alloc) == NULL) { return rc; }
 
+#define ngx_is_null(p, alloc)   if ((p = alloc) == NULL)
+
 
 typedef struct ngx_pool_large_s  ngx_pool_large_t;
 
--- a/src/core/ngx_hunk.h
+++ b/src/core/ngx_hunk.h
@@ -84,7 +84,6 @@ typedef struct {
     unsigned                     sendfile;
     unsigned                     need_in_memory;
     unsigned                     need_in_temp;
-    unsigned                     copy_chain;
 
     ngx_pool_t                  *pool;
     int                          hunks;
@@ -96,6 +95,14 @@ typedef struct {
 } ngx_output_chain_ctx_t;
 
 
+typedef struct {
+    ngx_chain_t                 *out;
+    ngx_chain_t                **last;
+    ngx_connection_t            *connection;
+    ngx_pool_t                  *pool;
+} ngx_chain_write_ctx_t;
+
+
 #define NGX_CHAIN_ERROR     (ngx_chain_t *) NGX_ERROR
 
 
@@ -144,6 +151,8 @@ ngx_hunk_t *ngx_create_temp_hunk(ngx_poo
 
 
 int ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in);
+int ngx_chain_write(void *data, ngx_chain_t *in);
+
 int ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain, ngx_chain_t *in);
 void ngx_chain_update_chains(ngx_chain_t **free, ngx_chain_t **busy,
                              ngx_chain_t **out, ngx_hunk_tag_t tag);
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -1,6 +1,7 @@
 
 #include <ngx_config.h>
 #include <ngx_core.h>
+#include <ngx_event.h>
 
 
 #define NGX_NONE      1
@@ -30,8 +31,7 @@ int ngx_output_chain(ngx_output_chain_ct
             return ctx->output_filter(ctx->output_ctx, in);
         }
 
-        if (!ctx->copy_chain
-            && in->next == NULL
+        if (in->next == NULL
             && (!ngx_output_chain_need_to_copy(ctx, in->hunk)))
         {
             return ctx->output_filter(ctx->output_ctx, in);
@@ -250,3 +250,31 @@ ngx_log_debug(src->file->log, "READ: %qd
 
     return NGX_OK;
 }
+
+
+int ngx_chain_write(void *data, ngx_chain_t *in)
+{
+    ngx_chain_write_ctx_t *ctx = data;
+
+    ngx_chain_t  *cl;
+
+
+    for (/* void */; in; in = in->next) {
+        ngx_alloc_link_and_set_hunk(cl, in->hunk, ctx->pool, NGX_ERROR);
+        *ctx->last = cl;
+        ctx->last = &cl->next;
+    }
+
+    ctx->out = ngx_write_chain(ctx->connection, ctx->out);
+
+    if (ctx->out == NGX_CHAIN_ERROR) {
+        return NGX_ERROR;
+    }
+
+    if (ctx->out == NULL) {
+        ctx->last = &ctx->out;
+        return NGX_OK;
+    }
+
+    return NGX_AGAIN;
+}
--- a/src/event/ngx_event_connect.c
+++ b/src/event/ngx_event_connect.c
@@ -189,7 +189,7 @@ ngx_log_debug(pc->log, "CONNECT: %s" _ p
     if (rc == -1) {
         err = ngx_socket_errno;
         if (err != NGX_EINPROGRESS) {
-            ngx_log_error(NGX_LOG_CRIT, pc->log, err, "connect() failed");
+            ngx_log_error(NGX_LOG_ERR, pc->log, err, "connect() failed");
 
             if (ngx_close_socket(s) == -1) {
                 ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
@@ -211,6 +211,10 @@ ngx_log_debug(pc->log, "CONNECT: %s" _ p
         event = NGX_LEVEL_EVENT;
     }
 
+    if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
     if (rc == -1) {
 
         /* NGX_EINPROGRESS */
@@ -224,10 +228,6 @@ ngx_log_debug(pc->log, "CONNECT: %s" _ p
 
     wev->ready = 1;
 
-    if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
-        return NGX_ERROR;
-    }
-
     return NGX_OK;
 }
 
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -175,7 +175,6 @@ static char connection_close_header[] = 
 
 static int ngx_http_proxy_handler(ngx_http_request_t *r)
 {
-    int                    rc;
     ngx_http_proxy_ctx_t  *p;
 
     ngx_http_create_ctx(r, p, ngx_http_proxy_module,
@@ -208,11 +207,9 @@ static int ngx_http_proxy_handler(ngx_ht
         r->request_body_handler = ngx_http_proxy_init_request;
         r->data = p;
 
-        rc = ngx_http_read_client_request_body(r, p->lcf->request_buffer_size);
+        ngx_http_read_client_request_body(r, p->lcf->request_buffer_size);
 
-        if (rc != NGX_OK) {
-            return rc;
-        }
+        return NGX_DONE;
     }
 
     ngx_http_proxy_init_request(p);
@@ -227,16 +224,31 @@ static void ngx_http_proxy_init_request(
 
     ngx_chain_t             *cl;
     ngx_http_request_t      *r;
-    ngx_output_chain_ctx_t  *ctx;
+    ngx_output_chain_ctx_t  *out_ctx;
+    ngx_chain_write_ctx_t   *write_ctx;
 
 
     r = p->request;
 
+ngx_log_debug(r->connection->log, "timer_set: %d" _
+              r->connection->read->timer_set);
+
+    if (r->connection->read->timer_set) {
+        ngx_del_timer(r->connection->read);
+    }
+
+    ngx_is_null(cl, ngx_http_proxy_create_request(p)) {
+        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        return;
+    }
+
+#if 0
     cl = ngx_http_proxy_create_request(p);
     if (cl == NULL) {
         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
         return;
     }
+#endif
 
     if (r->request_hunks) {
         cl->next = r->request_hunks;
@@ -251,28 +263,36 @@ static void ngx_http_proxy_init_request(
     r->connection->log->handler = ngx_http_proxy_log_error;
     p->action = "connecting to upstream";
 
-    ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t));
-    if (ctx == NULL) {
+    out_ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t));
+    if (out_ctx == NULL) {
         ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
     }
 
-    p->output_chain_ctx = ctx;
+    p->output_chain_ctx = out_ctx;
 
     if (r->request_body_hunk) {
-        ctx->free = ngx_alloc_chain_link(r->pool);
-        if (ctx->free == NULL) {
+        out_ctx->free = ngx_alloc_chain_link(r->pool);
+        if (out_ctx->free == NULL) {
             ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
         }
-        ctx->free->hunk = r->request_body_hunk;
-        ctx->free->next = NULL;
+        out_ctx->free->hunk = r->request_body_hunk;
+        out_ctx->free->next = NULL;
     }
 
-    ctx->sendfile = r->sendfile;
-    ctx->copy_chain = 1;
-    ctx->pool = r->pool;
-    ctx->bufs.num = 1;
-    ctx->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module;
-    ctx->output_filter = (ngx_output_chain_filter_pt) ngx_write_chain;
+    out_ctx->sendfile = r->sendfile;
+    out_ctx->pool = r->pool;
+    out_ctx->bufs.num = 1;
+    out_ctx->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module;
+    out_ctx->output_filter = (ngx_output_chain_filter_pt) ngx_chain_write;
+
+    write_ctx = ngx_pcalloc(r->pool, sizeof(ngx_chain_write_ctx_t));
+    if (write_ctx == NULL) {
+        ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
+    }
+
+    out_ctx->output_ctx = write_ctx;
+    write_ctx->pool = r->pool;
+    write_ctx->last = &write_ctx->out;
 
     ngx_http_proxy_send_request(p);
 }
@@ -418,15 +438,19 @@ static void ngx_http_proxy_send_request(
     int                      rc;
     ngx_chain_t             *cl;
     ngx_connection_t        *c;
+    ngx_chain_write_ctx_t   *ctx;
 
     c = p->upstream.connection;
 
     for ( ;; ) {
 
         if (c) {
-            p->output_chain_ctx->output_ctx = c;
+            p->action = "sending request to upstream";
+            ctx = p->output_chain_ctx->output_ctx;
+            ctx->connection = c;
             rc = ngx_output_chain(p->output_chain_ctx,
-                                  p->request->request_hunks);
+                                  !p->request_sent ? p->request->request_hunks:
+                                                     NULL);
 
             if (rc != NGX_ERROR) {
                 p->request_sent = 1;
@@ -438,8 +462,23 @@ static void ngx_http_proxy_send_request(
                 if (rc == NGX_AGAIN) {
                     ngx_add_timer(c->write, p->lcf->send_timeout);
 
+                    if (ngx_handle_write_event(c->write, /* STUB: lowat */ 0)
+                                                                == NGX_ERROR)
+                    {
+                        ngx_http_proxy_finalize_request(p,
+                                               NGX_HTTP_INTERNAL_SERVER_ERROR);
+                        return;
+                    }
+
                 } else {
-                    /* TODO: del event */
+
+                    /* rc == NGX_OK */
+
+                    if (ngx_handle_level_write_event(c->write) == NGX_ERROR) {
+                        ngx_http_proxy_finalize_request(p,
+                                               NGX_HTTP_INTERNAL_SERVER_ERROR);
+                        return;
+                    }
 
                     if (c->tcp_nopush) {
                         if (ngx_tcp_push(c->fd) == NGX_ERROR) {
@@ -462,6 +501,8 @@ static void ngx_http_proxy_send_request(
         }
 
         for ( ;; ) {
+            p->action = "connecting to upstream";
+
             rc = ngx_event_connect_peer(&p->upstream);
 
             if (rc == NGX_ERROR) {
@@ -1245,6 +1286,9 @@ ngx_log_debug(p->request->connection->lo
 
 static void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc)
 {
+    ngx_log_debug(p->request->connection->log,
+                  "finalize http proxy request");
+
     if (p->upstream.connection) {
         ngx_http_proxy_close_connection(p->upstream.connection);
         p->upstream.connection = NULL;
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -130,6 +130,13 @@ static ngx_command_t  ngx_http_core_comm
      offsetof(ngx_http_core_loc_conf_t, doc_root),
      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,
+     NGX_HTTP_LOC_CONF_OFFSET,
+     offsetof(ngx_http_core_loc_conf_t, client_body_timeout),
+     NULL},
+
     {ngx_string("sendfile"),
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
      ngx_conf_set_flag_slot,
@@ -842,6 +849,7 @@ static void *ngx_http_core_create_loc_co
 
     */
 
+    lcf->client_body_timeout = NGX_CONF_UNSET;
     lcf->sendfile = NGX_CONF_UNSET;
     lcf->send_timeout = NGX_CONF_UNSET;
     lcf->discarded_buffer_size = NGX_CONF_UNSET;
@@ -913,6 +921,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_msec_value(conf->client_body_timeout,
+                              prev->client_body_timeout, 10000);
     ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
     ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 10000);
     ngx_conf_merge_size_value(conf->discarded_buffer_size,
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -110,6 +110,7 @@ typedef struct {
     ngx_array_t  *types;
     ngx_str_t     default_type;
 
+    ngx_msec_t    client_body_timeout;     /* client_body_timeout */
     int           sendfile;                /* sendfile */
     ngx_msec_t    send_timeout;            /* send_timeout */
     ssize_t       send_lowat;              /* send_lowat */
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -32,27 +32,28 @@
 #define NGX_HTTP_PARSE_INVALID_CL_HEADER  17
 
 
-#define NGX_HTTP_OK                     200
-#define NGX_HTTP_PARTIAL_CONTENT        206
+#define NGX_HTTP_OK                        200
+#define NGX_HTTP_PARTIAL_CONTENT           206
 
-#define NGX_HTTP_SPECIAL_RESPONSE       300
-#define NGX_HTTP_MOVED_PERMANENTLY      301
-#define NGX_HTTP_MOVED_TEMPORARILY      302
-#define NGX_HTTP_NOT_MODIFIED           304
+#define NGX_HTTP_SPECIAL_RESPONSE          300
+#define NGX_HTTP_MOVED_PERMANENTLY         301
+#define NGX_HTTP_MOVED_TEMPORARILY         302
+#define NGX_HTTP_NOT_MODIFIED              304
 
-#define NGX_HTTP_BAD_REQUEST            400
-#define NGX_HTTP_FORBIDDEN              403
-#define NGX_HTTP_NOT_FOUND              404
-#define NGX_HTTP_NOT_ALLOWED            405
-#define NGX_HTTP_REQUEST_TIME_OUT       408
-#define NGX_HTTP_REQUEST_URI_TOO_LARGE  414
-#define NGX_HTTP_RANGE_NOT_SATISFIABLE  416
+#define NGX_HTTP_BAD_REQUEST               400
+#define NGX_HTTP_FORBIDDEN                 403
+#define NGX_HTTP_NOT_FOUND                 404
+#define NGX_HTTP_NOT_ALLOWED               405
+#define NGX_HTTP_REQUEST_TIME_OUT          408
+#define NGX_HTTP_REQUEST_ENTITY_TOO_LARGE  413
+#define NGX_HTTP_REQUEST_URI_TOO_LARGE     414
+#define NGX_HTTP_RANGE_NOT_SATISFIABLE     416
 
-#define NGX_HTTP_INTERNAL_SERVER_ERROR  500
-#define NGX_HTTP_NOT_IMPLEMENTED        501
-#define NGX_HTTP_BAD_GATEWAY            502
-#define NGX_HTTP_SERVICE_UNAVAILABLE    503
-#define NGX_HTTP_GATEWAY_TIME_OUT       504
+#define NGX_HTTP_INTERNAL_SERVER_ERROR     500
+#define NGX_HTTP_NOT_IMPLEMENTED           501
+#define NGX_HTTP_BAD_GATEWAY               502
+#define NGX_HTTP_SERVICE_UNAVAILABLE       503
+#define NGX_HTTP_GATEWAY_TIME_OUT          504
 
 
 
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -30,8 +30,11 @@ int ngx_http_read_client_request_body(ng
 
         if (size >= r->headers_in.content_length_n) {
             r->header_in->pos += r->headers_in.content_length_n;
+
             return NGX_OK;
         }
+
+        r->header_in->pos = r->header_in->last;
     }
 
     r->request_body_len = r->headers_in.content_length_n - size;
@@ -73,10 +76,11 @@ int ngx_http_read_client_request_body(ng
 
 static void ngx_http_read_client_request_body_handler(ngx_event_t *rev)
 {
-    ssize_t              n, size;
-    ngx_hunk_t          *h;
-    ngx_connection_t    *c;
-    ngx_http_request_t  *r;
+    ssize_t                    n, size;
+    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;
@@ -87,6 +91,11 @@ static void ngx_http_read_client_request
                                                         r->request_hunks);
         /* TODO: n == 0 or not complete and level event */
 
+        if (n == NGX_ERROR) {
+            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
+        }
+
         r->request_body_hunk->pos = r->request_body_hunk->start;
         r->request_body_hunk->last = r->request_body_hunk->start;
     }
@@ -100,6 +109,9 @@ static void ngx_http_read_client_request
     n = ngx_recv(c, r->request_body_hunk->last, size);
 
     if (n == NGX_AGAIN) {
+        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+        ngx_add_timer(rev, clcf->client_body_timeout);
+
         if (ngx_handle_read_event(rev) == NGX_ERROR) {
             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
         }
@@ -132,6 +144,10 @@ static void ngx_http_read_client_request
                                                         r->request_hunks);
         /* TODO: n == 0 or not complete and level event */
 
+        if (n == NGX_ERROR) {
+            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return;
+        }
 
         h = ngx_calloc_hunk(r->pool);
         if (h == NULL) {
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -78,6 +78,14 @@ static char error_408_page[] =
 ;
 
 
+static char error_413_page[] =
+"<html>" CRLF
+"<head><title>413 Request Entity Too Large</title></head>" CRLF
+"<body bgcolor=\"white\">" CRLF
+"<center><h1>413 Request Entity Too Large</h1></center>" CRLF
+;
+
+
 static char error_414_page[] =
 "<html>" CRLF
 "<head><title>414 Request-URI Too Large</title></head>" CRLF
@@ -110,6 +118,14 @@ static char error_502_page[] =
 ;
 
 
+static char error_503_page[] =
+"<html>" CRLF
+"<head><title>503 Service Temporarily Unavailable</title></head>" CRLF
+"<body bgcolor=\"white\">" CRLF
+"<center><h1>503 Service Temporarily Unavailable</h1></center>" CRLF
+;
+
+
 static char error_504_page[] =
 "<html>" CRLF
 "<head><title>504 Gateway Time-out</title></head>" CRLF
@@ -137,7 +153,7 @@ static ngx_str_t error_pages[] = {
     ngx_null_string,             /* 410 */
     ngx_null_string,             /* 411 */
     ngx_null_string,             /* 412 */
-    ngx_null_string,             /* 413 */
+    ngx_string(error_413_page),
     ngx_string(error_414_page),
     ngx_null_string,             /* 415 */
     ngx_string(error_416_page),
@@ -145,7 +161,7 @@ static ngx_str_t error_pages[] = {
     ngx_string(error_500_page),
     ngx_null_string,             /* 501 */
     ngx_string(error_502_page),
-    ngx_null_string,             /* 503 */
+    ngx_string(error_503_page),
     ngx_string(error_504_page)
 };
 
@@ -181,6 +197,7 @@ int ngx_http_special_response_handler(ng
     if (r->keepalive != 0) {
         switch (error) {
             case NGX_HTTP_BAD_REQUEST:
+            case NGX_HTTP_REQUEST_ENTITY_TOO_LARGE:
             case NGX_HTTP_REQUEST_URI_TOO_LARGE:
             case NGX_HTTP_INTERNAL_SERVER_ERROR:
                 r->keepalive = 0;