changeset 77:57c2e18d3572

nginx-0.0.1-2003-04-17-21:59:35 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 17 Apr 2003 17:59:35 +0000
parents 6127d7075471
children 9f81437e0ad3
files src/event/ngx_event.h src/event/ngx_event_proxy.c src/event/ngx_event_proxy.h src/event/ngx_event_timer.c src/http/modules/proxy/ngx_http_event_proxy_handler.c src/http/modules/proxy/ngx_http_event_proxy_handler.h src/http/ngx_http_event.c src/http/ngx_http_write_filter.c
diffstat 8 files changed, 152 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -69,6 +69,7 @@ struct ngx_event_s {
     unsigned         timedout:1;
     unsigned         blocked:1;
     unsigned         timer_set:1;
+    unsigned         delayed:1;
 
     unsigned         process:1;
     unsigned         read_discarded:1;
--- a/src/event/ngx_event_proxy.c
+++ b/src/event/ngx_event_proxy.c
@@ -31,71 +31,92 @@ ngx_log_debug(p->log, "read upstream");
 
     for ( ;; ) {
 
-        /* use the free hunks if they exist */
+        /* use the pre-read hunks if they exist */
+
+        if (p->preread_hunks) {
+            chain = p->preread_hunks;
+            p->preread_hunks = NULL;
+            n = p->preread_size;
 
-        if (p->free_hunks) {
-            chain = p->free_hunks;
-            p->free_hunks = NULL;
+        } else {
+
+            /* use the free hunks if they exist */
+
+            if (p->free_hunks) {
+                chain = p->free_hunks;
+                p->free_hunks = NULL;
 
 ngx_log_debug(p->log, "free hunk: %08X:%d" _ chain->hunk _
               chain->hunk->end - chain->hunk->last);
 
-        /* allocate a new hunk if it's still allowed */
-
-        } else if (p->allocated < p->max_block_size) {
-            ngx_test_null(h,
-                          ngx_create_temp_hunk(p->pool, p->block_size, 20, 20),
-                          NGX_ERROR);
+            /* allocate a new hunk if it's still allowed */
 
-            p->allocated += p->block_size;
+            } else if (p->allocated < p->max_block_size) {
+                ngx_test_null(h,
+                              ngx_create_temp_hunk(p->pool,
+                                                   p->block_size, 20, 20),
+                              NGX_ERROR);
 
-            ngx_test_null(temp, ngx_alloc_chain_entry(p->pool), NGX_ERROR);
-            temp->hunk = h;
-            temp->next = NULL;
-            chain = temp;
+                p->allocated += p->block_size;
+
+                ngx_test_null(temp, ngx_alloc_chain_entry(p->pool), NGX_ERROR);
+                temp->hunk = h;
+                temp->next = NULL;
+                chain = temp;
 
 ngx_log_debug(p->log, "new hunk: %08X" _ chain->hunk);
 
-        /* use the shadow hunks if they exist */
+            /* use the shadow hunks if they exist */
 
-        } else if (p->shadow_hunks) {
-            chain = p->shadow_hunks;
-            p->shadow_hunks = NULL;
+            } else if (p->shadow_hunks) {
+                chain = p->shadow_hunks;
+                p->shadow_hunks = NULL;
 
 ngx_log_debug(p->log, "shadow hunk: %08X" _ chain->hunk _
               chain->hunk->end - chain->hunk->last);
 
-        /* if it's allowed then save the incoming hunks to a temporary file,
-           move the saved hunks to a shadow chain,
-           and add the file hunks to an outgoing chain */
+            /* if the hunks is not needed to be saved in a cache and
+               a downstream is ready then write the hunks to a downstream */
+
+            } else if (p->cachable == 0 && p->downstream->write->ready) {
+
+                rc = ngx_event_proxy_write_to_downstream(p);
 
-        } else if (p->temp_offset < p->max_temp_size) {
-            rc = ngx_event_proxy_write_chain_to_temp_file(p);
+                continue;
+
+            /* if it's allowed then save the incoming hunks
+               to a temporary file, move the saved hunks to a shadow chain,
+               and add the file hunks to an outgoing chain */
+
+            } else if (p->temp_offset < p->max_temp_file_size) {
+                rc = ngx_event_proxy_write_chain_to_temp_file(p);
 
 ngx_log_debug(p->log, "temp offset: %d" _ p->temp_offset);
 
-            if (rc != NGX_OK) {
-                return rc;
-            }
+                if (rc != NGX_OK) {
+                    return rc;
+                }
 
-            chain = p->shadow_hunks;
-            p->shadow_hunks = NULL;
+                chain = p->shadow_hunks;
+                p->shadow_hunks = NULL;
 
 ngx_log_debug(p->log, "new shadow hunk: %08X:%d" _ chain->hunk _
               chain->hunk->end - chain->hunk->last);
 
-        /* if there're no hunks to read in then disable a level event */
+            /* if there're no hunks to read in then disable a level event */
 
-        } else {
-            if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
-                p->block_upstream = 1;
+            } else {
+                if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
+                    p->block_upstream = 1;
+                }
+    
+                break;
             }
 
-            break;
+            n = ngx_recv_chain(p->upstream, chain);
+
         }
 
-        n = ngx_recv_chain(p->upstream, chain);
-
 ngx_log_debug(p->log, "recv_chain: %d" _ n);
 
         if (n == NGX_ERROR) {
@@ -112,7 +133,7 @@ ngx_log_debug(p->log, "recv_chain: %d" _
                 p->upstream->read->blocked = 0;
             }
 
-            return NGX_AGAIN;
+            break;
         }
 
         if (n == 0) {
@@ -179,7 +200,7 @@ ngx_log_debug(p->log, "recv_chain: %d" _
                 ngx_test_null(h, ngx_alloc_hunk(p->pool), NGX_ERROR);
                 ngx_memcpy(h, entry->hunk, sizeof(ngx_hunk_t));
                 h->shadow = entry->hunk;
-                h->type |= NGX_HUNK_LAST_SHADOW;
+                h->type |= NGX_HUNK_LAST_SHADOW|NGX_HUNK_RECYCLED;
                 entry->hunk->shadow = h;
 
                 ngx_test_null(temp, ngx_alloc_chain_entry(p->pool),
@@ -307,12 +328,12 @@ ngx_log_debug(p->log, "eof: %d block: %d
             }
         }
 
-        if (p->out_hunks && p->client->write->ready) {
-            rc = ngx_event_proxy_write_to_client(p);
+        if (p->out_hunks && p->downstream->write->ready) {
+            rc = ngx_event_proxy_write_to_downstream(p);
         }
 
-    } else if ((p->out_hunks || p->in_hunks) && p->client->write->ready) {
-        rc = ngx_event_proxy_write_to_client(p);
+    } else if ((p->out_hunks || p->in_hunks) && p->downstream->write->ready) {
+        rc = ngx_event_proxy_write_to_downstream(p);
     }
 
     p->level--;
@@ -336,13 +357,13 @@ ngx_log_debug(p->log, "level: %d" _ p->l
 }
 
 
-int ngx_event_proxy_write_to_client(ngx_event_proxy_t *p)
+int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p)
 {
     int           rc;
     ngx_hunk_t   *h;
     ngx_chain_t  *entry;
 
-ngx_log_debug(p->log, "write to client");
+ngx_log_debug(p->log, "write to downstream");
 
     h = p->busy_hunk;
 
@@ -491,7 +512,7 @@ ngx_log_debug(p->log, "write to file");
 
         do {
             size += entry->hunk->last - entry->hunk->pos;
-            if (size >= p->file_block_size) {
+            if (size >= p->temp_file_write_size) {
                 break;
             }
             entry = entry->next;
@@ -538,7 +559,11 @@ ngx_log_debug(p->log, "write to file");
 ngx_log_debug(p->log, "event proxy file hunk: %08X:%08X" _ h _ h->shadow);
 
         if (h->type & NGX_HUNK_LAST_SHADOW) {
+#if 0
             h->shadow->last = h->shadow->pos;
+#else
+            h->shadow->last = h->shadow->pos = h->shadow->start;
+#endif
         }
 
         if (p->out_hunks) {
@@ -591,7 +616,7 @@ static int ngx_event_proxy_copy_input_fi
         ngx_test_null(h, ngx_alloc_hunk(p->pool), NGX_ERROR);
         ngx_memcpy(h, entry->hunk, sizeof(ngx_hunk_t));
         h->shadow = entry->hunk;
-        h->type |= NGX_HUNK_LAST_SHADOW;
+        h->type |= NGX_HUNK_LAST_SHADOW|NGX_HUNK_RECYCLED;
         entry->hunk->shadow = h;
 
         ngx_test_null(temp, ngx_alloc_chain_entry(p->pool), NGX_ERROR);
--- a/src/event/ngx_event_proxy.h
+++ b/src/event/ngx_event_proxy.h
@@ -20,12 +20,20 @@ typedef int (*ngx_event_proxy_output_fil
 struct ngx_event_proxy_s {
     ngx_chain_t       *read_hunks;
     ngx_chain_t       *last_read_hunk;
+
+    ngx_chain_t       *shadow_hunks;
+
     ngx_chain_t       *in_hunks;
     ngx_chain_t       *last_in_hunk;
-    ngx_chain_t       *shadow_hunks;
+
     ngx_chain_t       *out_hunks;
     ngx_chain_t       *last_out_hunk;
+
     ngx_chain_t       *free_hunks;
+#if 0
+    ngx_chain_t       *last_free_hunk;
+#endif
+
     ngx_hunk_t        *busy_hunk;
 
     ngx_event_proxy_input_filter_pt   input_filter;
@@ -38,8 +46,8 @@ struct ngx_event_proxy_s {
     unsigned           block_upstream:1;
     unsigned           upstream_eof:1;
     unsigned           upstream_error:1;
-    unsigned           client_eof:1;
-    unsigned           client_error:1;
+    unsigned           downstream_eof:1;
+    unsigned           downstream_error:1;
 
     int                level;
 
@@ -48,15 +56,21 @@ struct ngx_event_proxy_s {
     int                max_block_size;
 
     off_t              temp_offset;
-    off_t              max_temp_size;
-    int                file_block_size;
+    off_t              max_temp_file_size;
+    int                temp_file_write_size;
 
     ngx_connection_t  *upstream;
-    ngx_connection_t  *client;
+    ngx_connection_t  *downstream;
 
     ngx_pool_t        *pool;
     ngx_log_t         *log;
 
+    ngx_chain_t       *preread_hunks;
+#if 0
+    ngx_chain_t       *last_preread_hunk;
+#endif
+    int                preread_size;
+
     ngx_file_t        *temp_file;
     ngx_path_t        *temp_path;
     int                number;
@@ -66,7 +80,7 @@ struct ngx_event_proxy_s {
 
 
 int ngx_event_proxy_read_upstream(ngx_event_proxy_t *p);
-int ngx_event_proxy_write_to_client(ngx_event_proxy_t *p);
+int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p);
 int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p);
 
 
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -129,7 +129,15 @@ void ngx_event_expire_timers(ngx_msec_t 
             delta -= ev->timer_delta;
 
             ngx_del_timer(ev);
-            ev->timedout = 1;
+            if (ev->delayed) {
+                ev->delayed = 0;
+                if (ev->ready == 0) {
+                    continue;
+                }
+
+            } else {
+                ev->timedout = 1;
+            }
 
             if (ev->event_handler(ev) == NGX_ERROR) {
                 ev->close_handler(ev);
--- a/src/http/modules/proxy/ngx_http_event_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_event_proxy_handler.c
@@ -721,6 +721,11 @@ static int ngx_http_proxy_init_upstream(
     r = p->request;
 
     ngx_test_null(p->header_in,
+                  ngx_create_temp_hunk(r->pool, p->lcf->header_size, 0, 0),
+                  NGX_ERROR);
+
+#if 0
+    ngx_test_null(p->header_in,
                   ngx_create_temp_hunk(r->pool,
                                        p->lcf->header_size
                                                   - sizeof(ngx_cache_header_t),
@@ -729,6 +734,7 @@ static int ngx_http_proxy_init_upstream(
                   NGX_ERROR);
 
     p->header_in->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
+#endif
 
 #if 0
     ngx_test_null(p->headers_in,
@@ -757,6 +763,7 @@ static int ngx_http_proxy_read_upstream_
 {
     int                  i, n, rc;
     ngx_event_t         *rev;
+    ngx_chain_t         *temp;
     ngx_table_elt_t     *ch, *ph;
     ngx_event_proxy_t   *ep;
     ngx_http_request_t  *r;
@@ -846,7 +853,9 @@ static int ngx_http_proxy_read_upstream_
         rc = ngx_http_send_header(r);
 
 #if 1
+#if 0
         rc = ngx_http_output_filter(r, p->header_in);
+#endif
 
         ngx_test_null(ep, ngx_pcalloc(r->pool, sizeof(ngx_event_proxy_t)),
                       NGX_ERROR);
@@ -856,9 +865,8 @@ static int ngx_http_proxy_read_upstream_
         ep->output_data = r;
         ep->block_size = p->lcf->block_size;
         ep->max_block_size = p->lcf->max_block_size;
-        ep->file_block_size = p->lcf->file_block_size;
         ep->upstream = p->connection;
-        ep->client = r->connection;
+        ep->downstream = r->connection;
         ep->pool = r->pool;
         ep->log = p->log;
         ep->temp_path = p->lcf->temp_path;
@@ -871,10 +879,21 @@ static int ngx_http_proxy_read_upstream_
         ep->number = 10;
         ep->random = 5;
 
-        ep->max_temp_size = p->lcf->max_temp_file_size;
+        ep->max_temp_file_size = p->lcf->max_temp_file_size;
+        ep->temp_file_write_size = p->lcf->temp_file_write_size;
         ep->temp_file_warn = "an upstream response is buffered "
                              "to a temporary file";
 
+        ngx_test_null(ep->preread_hunks, ngx_alloc_chain_entry(r->pool),
+                      NGX_ERROR);
+        ep->preread_hunks->hunk = p->header_in;
+        ep->preread_hunks->next = NULL;
+#if 0
+        ep->last_preread_hunk = ep->preread_hunks;
+#endif
+
+        ep->preread_size = p->header_in->last - p->header_in->pos;
+
         p->event_proxy = ep;
 
         lcx = p->log->data;
@@ -1100,7 +1119,7 @@ static int ngx_http_proxy_read_upstream_
 
 static int ngx_http_proxy_write_upstream_body(ngx_http_proxy_ctx_t *p)
 {
-    return ngx_event_proxy_write_to_client(p->event_proxy);
+    return ngx_event_proxy_write_to_downstream(p->event_proxy);
 }
 
 
@@ -1762,18 +1781,18 @@ static void *ngx_http_proxy_create_loc_c
     conf->connect_timeout = 10000;
     conf->send_timeout = 10000;
     conf->read_timeout = 10000;
-    conf->header_size = 1024;
-
-#if 0
+    conf->header_size = 2048;
+
+#if 1
     conf->block_size = 4096;
     conf->max_block_size = 4096 * 3;
     conf->max_temp_file_size = 4096 * 5;
-    conf->file_block_size = 4096 * 2;
+    conf->temp_file_write_size = 4096 * 2;
 #else
     conf->block_size = 2048;
     conf->max_block_size = 4096 * 6;
     conf->max_temp_file_size = 4096 * 5;
-    conf->file_block_size = 4096 * 5;
+    conf->temp_file_write_size = 4096 * 5;
 #endif
 
     ngx_test_null(conf->temp_path, ngx_pcalloc(pool, sizeof(ngx_path_t)), NULL);
--- a/src/http/modules/proxy/ngx_http_event_proxy_handler.h
+++ b/src/http/modules/proxy/ngx_http_event_proxy_handler.h
@@ -72,7 +72,7 @@ typedef struct {
     int   block_size;
     int   max_block_size;
     int   max_temp_file_size;
-    int   file_block_size;
+    int   temp_file_write_size;
 
     ngx_path_t  *temp_path;
     int   temp_file_warn;
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_event.c
@@ -183,6 +183,7 @@ static int ngx_http_init_request(ngx_eve
 static int ngx_http_process_request(ngx_event_t *rev)
 {
     int                  n, rc;
+    ngx_event_t         *wev;
     ngx_connection_t    *c;
     ngx_http_request_t  *r;
     ngx_http_log_ctx_t  *lcx;
@@ -260,9 +261,16 @@ static int ngx_http_process_request(ngx_
             return ngx_http_finalize_request(r, rc);
         }
 
-        lcx = r->connection->log->data;
+        lcx = c->log->data;
         lcx->action = "processing client request";
 
+#if 0
+        wev = c->write;
+        ngx_add_timer(wev, 5000);
+        wev->delayed = 1;
+        wev->timer_set = 1;
+#endif
+
         rc = ngx_http_handler(r);
 
         /* a handler does its own processing */
@@ -657,13 +665,18 @@ int ngx_http_finalize_request(ngx_http_r
     /* NGX_AGAIN: a handler has done its work
                   but the transfer is still not completed */
 
+    wev = r->connection->write;
+    wev->event_handler = ngx_http_writer;
+
+    if (wev->delayed && wev->ready) {
+        return NGX_AGAIN;
+    }
+
     lcf = (ngx_http_core_loc_conf_t *)
                         ngx_http_get_module_loc_conf(r->main ? r->main : r,
                                                      ngx_http_core_module_ctx);
-    wev = r->connection->write;
-    wev->event_handler = ngx_http_writer;
+    ngx_add_timer(wev, lcf->send_timeout);
     wev->timer_set = 1;
-    ngx_add_timer(wev, lcf->send_timeout);
 
 #if (USE_KQUEUE)
 
--- a/src/http/ngx_http_write_filter.c
+++ b/src/http/ngx_http_write_filter.c
@@ -134,6 +134,10 @@ int ngx_http_write_filter(ngx_http_reque
         return NGX_OK;
     }
 
+    if (r->connection->write->delayed) {
+        return NGX_AGAIN;
+    }
+
     chain = ngx_write_chain(r->connection, ctx->out, flush);
 
 #if (NGX_DEBUG_WRITE_FILTER)