changeset 73:4534060fde92

nginx-0.0.1-2003-04-10-19:08:54 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 10 Apr 2003 15:08:54 +0000
parents 66de3f065886
children 17ab1af8c3dd
files src/core/ngx_hunk.h src/http/modules/proxy/ngx_http_event_proxy_handler.c src/os/unix/ngx_files.c src/os/unix/ngx_recv_chain.c
diffstat 4 files changed, 169 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/ngx_hunk.h
+++ b/src/core/ngx_hunk.h
@@ -91,8 +91,4 @@ ngx_hunk_t *ngx_create_temp_hunk(ngx_poo
             } while (0);
 
 
-
-
-
-
 #endif /* _NGX_CHUNK_H_INCLUDED_ */
--- a/src/http/modules/proxy/ngx_http_event_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_event_proxy_handler.c
@@ -822,11 +822,17 @@ static int ngx_http_proxy_read_upstream_
             r->headers_out.date = p->headers_in.date;
         }
 
+        /* TODO: look "Content-Length" */
+        p->block_size = p->lcf->block_size;
+
         r->headers_out.status = p->status;
 
-        /* STUB */ r->header_only = 1;
+        rc = ngx_http_send_header(r);
 
-        rc = ngx_http_send_header(r);
+        /* STUB */
+        p->header_in->type |= NGX_HUNK_LAST;
+        rc = ngx_http_output_filter(r, p->header_in);
+        ngx_http_proxy_finalize_request(p, NGX_OK);
 
         /* STUB */ return NGX_DONE;
     }
@@ -1024,25 +1030,106 @@ static int ngx_http_proxy_process_upstre
 
 static int ngx_http_proxy_read_upstream_body(ngx_event_t *rev)
 {
+    ngx_hunk_t            *h;
+    ngx_chain_t           *chain, ce;
+    ngx_connection_t      *c;
+    ngx_http_request_t    *r;
+    ngx_http_proxy_ctx_t  *p;
+
+    c = (ngx_connection_t *) rev->data;
+    r = (ngx_http_request_t *) c->data;
+    p = (ngx_http_proxy_ctx_t *)
+                         ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx);
+
+    ce.next = NULL;
+
     do {
-        if (free) {
-            buf = get
-        else if (kqueue and eof) {
-            buf = &buf;
-            size = 0;
-        else if (p->cur_hunks < p->nhunks)
-            palloc
-            p->cur_hunks++;
-        else
-            write first
-            add file hunk to out
+
+#if (USE_KQUEUE)
+
+        if (ev->eof && ev->available == 0) {
+            break;
+        }
+
+#elif (HAVE_KQUEUE)
+
+        if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT
+            && ev->eof && ev->available == 0)
+        {
+            break;
         }
 
-        n = ngx_event_recv(c, buf, size);
+#endif
+
+        if (p->free_hunks) {
+            chain = p->free_hunks;
+
+        } else if (p->allocated < p->lcf->max_block_size) {
+            ngx_test_null(h,
+                          ngx_create_temp_hunk(r->pool, p->block_size, 50, 50),
+                          NGX_ERROR);
+
+            p->allocated += p->block_size;
+            ce.hunk = h;
+            chain = &ce;
+
+        } else {
+            if (p->temp_fd == NGX_INVALID_FILE) {
+                rc = ngx_create_temp_file(p->temp_file, r->cachable);
+
+                if (rc != NGX_OK) {
+                    return rc;
+                }
+
+                if (p->lcf->temp_file_warn) {
+                    ngx_log_error(NGX_LOG_WARN, p->log, 0,
+                                  "an upstream response is buffered "
+                                  "to a temporary file");
+                }
+            }
+
+            n = ngx_write_chain_to_file(p->temp_file, p->in_hunks,
+                                        p->temp_offset);
+
+            if (n == NGX_ERROR) {
+                return NGX_ERROR;
+            }
+
+            ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)),
+                          NGX_ERROR);
+
+            h->type = NGX_HUNK_FILE
+                      |NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP|NGX_HUNK_RECYCLED;
+
+            h->file_pos = p->temp_offset;
+            p->temp_offset += n;
+            h->file_last = p->temp_offset;
+
+            h->file->fd = p->temp_file.fd;
+            h->file->log = p->log;
+
+            h->pos = p->in_hunks->hunk->pos;
+            h->last = p->in_hunks->hunk->last;
+            h->start = p->in_hunks->hunk->start;
+            h->end = p->in_hunks->hunk->end;
+            h->pre_start = p->in_hunks->hunk->pre_start;
+            h->post_end = p->in_hunks->hunk->post_end;
+
+            ngx_add_hunk_to_chain(p->last_out_hunk, h, r->pool, NGX_ERROR);
+
+            ce.hunk = p->in_hunks->next;
+            p->in_hunks = p->in_hunks->next;
+            chain = &ce;
+        }
+
+        n = ngx_recv_chain(c, chain);
+
+        h->last += n;
+        left = hunk->end - hunk->last;
 
     } while (n > 0 && left == 0);
 
-    if (out && p->request->connection->write->ready) {
+    if (p->out_hunks && p->request->connection->write->ready) {
         ngx_http_proxy_write_upstream_body(p->request->connection->write);
     }
 }
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -12,7 +12,7 @@ ssize_t ngx_read_file(ngx_file_t *file, 
     n = pread(file->fd, buf, size, offset);
 
     if (n == -1) {
-        ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "read() failed");
+        ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "pread() failed");
         return NGX_ERROR;
     }
 
@@ -21,6 +21,30 @@ ssize_t ngx_read_file(ngx_file_t *file, 
     return n;
 }
 
+
+ssize_t ngx_write_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
+{
+    ssize_t n;
+
+    n = pwrite(file->fd, buf, size, offset);
+
+    if (n == -1) {
+        ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "pwrite() failed");
+        return NGX_ERROR;
+    }
+
+    if (n != size) {
+        ngx_log_error(NGX_LOG_ERR, file->log, 0,
+                      "pwrite() has written only %d of %d", n, size);
+        return NGX_ERROR;
+    }
+
+    file->offset += n;
+
+    return n;
+}
+
+
 #if 0
 
 ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
new file mode 100644
--- /dev/null
+++ b/src/os/unix/ngx_recv_chain.c
@@ -0,0 +1,42 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_errno.h>
+#include <ngx_log.h>
+#include <ngx_connection.h>
+
+
+ssize_t ngx_recv_chain(ngx_connection_t *c, ngx_chain_t *ce)
+{
+    int              n;
+    struct iovec   *iov;
+    ngx_err_t       err;
+    ngx_array_t     io;
+
+    ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_ERROR);
+
+    while (ce) {
+        ngx_test_null(iov, ngx_push_array(&io), NGX_ERROR);
+        iov->iov_base = ce->hunk->pos;
+        iov->iov_len = ce->hunk->last - ce->hunk->pos;
+        ce = ce->next;
+    }
+
+    n = readv(c->fd, (struct iovec *) io.elts, io.nelts);
+
+    ngx_destroy_array(&io);
+
+    if (n == -1) {
+        c->read->ready = 0;
+
+        if (err == NGX_EAGAIN) {
+            ngx_log_error(NGX_LOG_INFO, c->log, err, "readv() returned EAGAIN");
+            return NGX_AGAIN;
+        }
+
+        ngx_log_error(NGX_LOG_ERR, c->log, err, "readv() failed");
+        return NGX_ERROR;
+    }
+
+    return n;
+}