changeset 9:6f58641241bb

nginx-0.0.1-2002-09-07-14:14:25 import
author Igor Sysoev <igor@sysoev.ru>
date Sat, 07 Sep 2002 10:14:25 +0000
parents 708f8bb772ec
children 4f3879d9b6f6
files src/core/ngx_log.c src/event/ngx_event.h src/event/ngx_event_write.c src/http/ngx_http.c src/http/ngx_http.h src/http/ngx_http_event.c src/http/ngx_http_modules.c src/http/ngx_http_output_filter.c src/http/ngx_http_output_filter.h src/http/ngx_http_parse.c src/http/ngx_http_write_filter.c src/http/ngx_http_write_filter.h src/os/unix/ngx_files.c src/os/unix/ngx_sendv.c src/os/unix/ngx_sendv.h src/os/win32/ngx_sendv.c src/os/win32/ngx_sendv.h
diffstat 17 files changed, 246 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -84,6 +84,7 @@ void ngx_log_error_core(int level, ngx_l
     errstr[len + 1] = '\0';
 
     fputs(errstr, stderr);
+    fflush(stderr);
 }
 
 #if !(HAVE_VARIADIC_MACROS)
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -106,6 +106,9 @@ NGX_AIO_EVENT              overlapped, a
 
 #ifndef HAVE_CLEAR_EVENT
 #define HAVE_CLEAR_EVENT   1
+#endif
+
+#if (HAVE_CLEAR_EVENT)
 #define NGX_CLEAR_EVENT    EV_CLEAR
 #endif
 
--- a/src/event/ngx_event_write.c
+++ b/src/event/ngx_event_write.c
@@ -98,23 +98,20 @@ ngx_chain_t *ngx_event_write(ngx_connect
                                   (ngx_iovec_t *) trailer->elts, trailer->nelts,
                                   &sent, c->log);
             } else {
-                size_t sendv_sent;
+                rc = ngx_sendv(c, (ngx_iovec_t *) header->elts,
+                               header->nelts);
 
-                sendv_sent = 0;
-                rc = ngx_sendv(c->fd, (ngx_iovec_t *) header->elts,
-                               header->nelts, &sendv_sent);
-                sent = sendv_sent;
+                sent = rc > 0 ? rc: 0;
+
                 ngx_log_debug(c->log, "sendv: " QD_FMT _ sent);
             }
 #if (HAVE_MAX_SENDFILE_IOVEC)
         }
 #endif
-        /* save sent for logging */
+        if (rc == NGX_ERROR)
+            return (ngx_chain_t *) NGX_ERROR;
 
-        if (rc == NGX_ERROR)
-            return (ngx_chain_t *) -1;
-
-        c->sent = sent;
+        c->sent += sent;
         flush -= sent;
 
         for (ch = in; ch; ch = ch->next) {
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -28,6 +28,7 @@ int ngx_http_init(ngx_pool_t *pool, ngx_
 #else
     ngx_http_server.doc_root = "/home/is/work/xml/site-1.0.0/html";
 #endif
+    ngx_http_server.doc_root = "html";
     ngx_http_server.doc_root_len = strlen(ngx_http_server.doc_root) + 1;
 
 
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -36,12 +36,6 @@
 #define NGX_HTTP_DIRECTORY_HANDLER  1
 
 
-typedef struct {
-    void *ctx;   /* STUB */
-} ngx_http_module_t;
-
-/* STUB */
-#define ngx_get_module_ctx(r, module)  (module)->ctx
 
 typedef struct {
     char          *doc_root;
@@ -82,6 +76,10 @@ struct ngx_http_request_s {
     char  *location;
     ngx_fd_t  fd;
 
+    void  **ctx;
+    void  **loc_conf;
+    void  **srv_conf;
+
     ngx_pool_t  *pool;
     ngx_hunk_t  *header_in;
 
@@ -140,6 +138,18 @@ typedef struct {
 } ngx_http_log_ctx_t;
 
 
+typedef struct {
+    int    index;
+} ngx_http_module_t;
+
+#define NGX_HTTP_MODULE  0
+
+#define ngx_get_module_loc_conf(r, module)  r->loc_conf[module.index]
+#define ngx_get_module_ctx(r, module)  r->ctx[module.index]
+
+
+
+/* STUB */
 #define NGX_INDEX "index.html"
 
 
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_event.c
@@ -361,6 +361,7 @@ static int ngx_http_discarded_read(ngx_e
 static int ngx_http_handler(ngx_http_request_t *r)
 {
     int  rc;
+    ngx_msec_t  timeout;
 
     ngx_del_timer(r->connection->read);
     r->header_timeout = 1;
@@ -393,7 +394,16 @@ static int ngx_http_handler(ngx_http_req
             return ngx_http_close_request(r);
         }
 
-        ngx_add_timer(r->connection->write, 5000);
+        if (r->connection->sent > 0) {
+            ngx_log_debug(r->connection->log, "sent: " QD_FMT _
+                          r->connection->sent);
+            timeout = (ngx_msec_t) (r->connection->sent * 10);
+            ngx_log_debug(r->connection->log, "timeout: %d" _ timeout);
+            ngx_add_timer(r->connection->write, timeout);
+
+        } else {
+            ngx_add_timer(r->connection->write, 10000);
+        }
 
         r->connection->write->event_handler = ngx_http_writer;
         return rc;
@@ -488,6 +498,8 @@ static int ngx_http_writer(ngx_event_t *
     c = (ngx_connection_t *) ev->data;
     r = (ngx_http_request_t *) c->data;
 
+    c->sent = 0;
+
     rc = ngx_http_output_filter(r, NULL);
 
     ngx_log_debug(ev->log, "output_filter: %d" _ rc);
new file mode 100644
--- /dev/null
+++ b/src/http/ngx_http_modules.c
@@ -0,0 +1,7 @@
+
+extern ngx_http_module_t ngx_http_output_filter_module;
+
+ngx_http_module_t *ngx_http_modules[] = {
+    ngx_http_output_filter_module,
+    NULL
+};
--- a/src/http/ngx_http_output_filter.c
+++ b/src/http/ngx_http_output_filter.c
@@ -8,67 +8,78 @@
 #include <ngx_http_output_filter.h>
 
 
-/* STUB */
-int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in);
-
+static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src);
+static int ngx_http_output_filter_init(
+            int (*next_filter)(ngx_http_request_t *r, ngx_chain_t *ch));
+static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool);
+static void *ngx_http_output_filter_set_hunk_size(ngx_pool_t *pool, void *conf,
+                                                  char *size);
 
 
-static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src);
+ngx_http_module_t  ngx_http_output_filter_module = {
+    NGX_HTTP_MODULE
+};
 
-ngx_http_module_t  ngx_http_output_filter_module;
 
+static int (*ngx_http_output_next_filter)(ngx_http_request_t *r,
+                                          ngx_chain_t *ch);
 
 /* STUB */
-static ngx_http_output_filter_ctx_t module_ctx;
+int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *ch);
 
-void ngx_http_output_filter_init()
+int ngx_http_output_filter_stub_init(ngx_pool_t *pool, void *loc_conf)
 {
-     module_ctx.hunk_size = 32 * 1024;
-     module_ctx.out.hunk = NULL;
-     module_ctx.out.next = NULL;
-     module_ctx.next_filter = ngx_http_write_filter;
+    ngx_http_output_filter_conf_t *conf;
 
-     ngx_http_output_filter_module.ctx = &module_ctx;
+    ngx_http_output_filter_init(ngx_http_write_filter);
+    conf = ngx_http_output_filter_create_conf(pool);
+    ngx_http_output_filter_set_hunk_size(pool, conf, "32");
+
+    loc_conf = conf;
 }
 /* */
 
 
-/*
-    flags NGX_HUNK_RECYCLED, NGX_HUNK_FLUSH, NGX_HUNK_LAST
-*/
-
 int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
 {
-    int      rc, first;
+    int      rc, once;
     size_t   size;
     ssize_t  n;
     ngx_chain_t  *ce;
     ngx_http_output_filter_ctx_t  *ctx;
+    ngx_http_output_filter_conf_t *conf;
 
     ctx = (ngx_http_output_filter_ctx_t *)
-                              ngx_get_module_ctx(r->main ? r->main : r,
-                                               &ngx_http_output_filter_module);
+                            ngx_get_module_ctx(r->main ? r->main : r,
+                                                ngx_http_output_filter_module);
+
+    if (ctx == NULL) {
+        ngx_test_null(ctx,
+                    ngx_pcalloc(r->pool, sizeof(ngx_http_output_filter_ctx_t)),
+                    NGX_ERROR);
+
+        ctx->next_filter = ngx_http_output_next_filter;
+    }
+
+    ngx_log_debug(r->connection->log, "HUNK: x%x CTX-IN: x%x CTX->HUNK: x%x" _
+                  hunk _ ctx->in _ ctx->hunk);
 
     if (hunk && (hunk->type & NGX_HUNK_LAST))
         ctx->last = 1;
 
-    first = 1;
-
-    while (first || ctx->in) {
+    for (once = 1; once || ctx->in; once--) {
 
          /* input chain is not empty */
         if (ctx->in) {
 
             /* add hunk to input chain */
-            if (first && hunk) {
+            if (once && hunk) {
                 for (ce = ctx->in; ce->next; ce = ce->next)
                     /* void */ ;
 
                 ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR);
             }
 
-            first = 0;
-
             /* our hunk is still busy */
             if (ctx->hunk->pos.mem < ctx->hunk->last.mem) {
                 rc = ctx->next_filter(r, NULL);
@@ -122,8 +133,6 @@ int ngx_http_output_filter(ngx_http_requ
         /* input chain is empty */
         } else {
 
-            first = 0;
-
             if (hunk == NULL) {
                 rc = ctx->next_filter(r, NULL);
 
@@ -147,12 +156,17 @@ int ngx_http_output_filter(ngx_http_requ
                         if (ctx->hunk == NULL) {
 
                             if (hunk->type & NGX_HUNK_LAST) {
+
+                                conf = (ngx_http_output_filter_conf_t *)
+                                 ngx_get_module_loc_conf(r->main ? r->main : r,
+                                                ngx_http_output_filter_module);
+
                                 size = hunk->last.mem - hunk->pos.mem;
-                                if (size > ctx->hunk_size)
-                                    size = ctx->hunk_size;
+                                if (size > conf->hunk_size)
+                                    size = conf->hunk_size;
 
                             } else {
-                                size = ctx->hunk_size;
+                                size = conf->hunk_size;
                             }
 
                             ngx_test_null(ctx->hunk,
@@ -251,3 +265,36 @@ static int ngx_http_output_filter_copy_h
 
     return NGX_OK;
 }
+
+
+static int ngx_http_output_filter_init(
+            int (*next_filter)(ngx_http_request_t *r, ngx_chain_t *ch))
+{
+    ngx_http_output_next_filter = next_filter;
+
+    return NGX_OK;
+}
+
+static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool)
+{
+    ngx_http_output_filter_conf_t *conf;
+
+    ngx_test_null(conf,
+                  ngx_pcalloc(pool, sizeof(ngx_http_output_filter_conf_t)),
+                  NULL);
+
+    conf->hunk_size = 16384;
+}
+
+static void *ngx_http_output_filter_set_hunk_size(ngx_pool_t *pool, void *conf,
+                                                  char *size)
+{
+    ngx_http_output_filter_conf_t *cf = (ngx_http_output_filter_conf_t *) conf;
+
+    cf->hunk_size = atoi(size);
+    if (cf->hunk_size <= 0)
+        return "Error";
+
+    cf->hunk_size *= 1024;
+    return NULL;
+}
--- a/src/http/ngx_http_output_filter.h
+++ b/src/http/ngx_http_output_filter.h
@@ -2,19 +2,28 @@
 #define _NGX_HTTP_OUTPUT_FILTER_H_INCLUDED_
 
 
-#include <ngx_core.h>
+#include <ngx_hunk.h>
+#include <ngx_http.h>
+
 
 #define NGX_HTTP_FILTER_NEED_IN_MEMORY  1
 #define NGX_HTTP_FILTER_NEED_TEMP       2
 
+
+typedef struct {
+    size_t        hunk_size;
+} ngx_http_output_filter_conf_t;
+
 typedef struct {
     int         (*next_filter)(ngx_http_request_t *r, ngx_chain_t *ch);
     ngx_hunk_t   *hunk;
     ngx_chain_t  *in;
     ngx_chain_t   out;
-    size_t        hunk_size;
     unsigned      last;
 } ngx_http_output_filter_ctx_t;
 
 
+int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk);
+
+
 #endif /* _NGX_HTTP_OUTPUT_FILTER_H_INCLUDED_ */
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -32,7 +32,7 @@ printf("\nstate: %d, pos: %x, end: %x, c
        state, p, r->header_in->last, ch, p);
 */
 
-        /* GCC compiles switch as jump table */
+        /* GCC 2.95.2 and VC 6.0 compiles switch as jump table */
 
         switch (state) {
 
--- a/src/http/ngx_http_write_filter.c
+++ b/src/http/ngx_http_write_filter.c
@@ -1,27 +1,19 @@
 
 #include <ngx_config.h>
-
+#include <ngx_core.h>
 #include <ngx_hunk.h>
 #include <ngx_event_write.h>
 #include <ngx_http.h>
 #include <ngx_http_output_filter.h>
-
 #include <ngx_http_write_filter.h>
 
 
-ngx_http_module_t  ngx_http_write_filter_module;
+ngx_http_module_t  ngx_http_write_filter_module = {
+    NGX_HTTP_MODULE
+};
 
 
 /* STUB */
-static ngx_http_write_filter_ctx_t module_ctx;
-
-void ngx_http_write_filter_init()
-{
-     module_ctx.buffer_output = 10240;
-     module_ctx.out = NULL;
-
-     ngx_http_write_filter_module.ctx = &module_ctx;
-}
 /* */
 
 
@@ -31,10 +23,17 @@ int ngx_http_write_filter(ngx_http_reque
     off_t  size, flush;
     ngx_chain_t  *ch, **prev, *chain;
     ngx_http_write_filter_ctx_t  *ctx;
+    ngx_http_write_filter_conf_t *conf;
+
 
     ctx = (ngx_http_write_filter_ctx_t *)
                               ngx_get_module_ctx(r->main ? r->main : r,
-                                                 &ngx_http_write_filter_module);
+                                                 ngx_http_write_filter_module);
+    if (ctx == NULL)
+        ngx_test_null(ctx,
+                      ngx_pcalloc(r->pool, sizeof(ngx_http_write_filter_ctx_t)),
+                      NGX_ERROR);
+
     size = flush = 0;
     last = 0;
     prev = &ctx->out;
@@ -76,7 +75,11 @@ int ngx_http_write_filter(ngx_http_reque
             last = 1;
     }
 
-    if (!last && flush == 0 && size < ctx->buffer_output)
+    conf = (ngx_http_write_filter_conf_t *)
+                   ngx_get_module_loc_conf(r->main ? r->main : r,
+                                                ngx_http_write_filter_module);
+
+    if (!last && flush == 0 && size < conf->buffer_output)
         return NGX_OK;
 
     chain = ngx_event_write(r->connection, ctx->out, flush);
@@ -89,3 +92,29 @@ int ngx_http_write_filter(ngx_http_reque
 
     return (chain ? NGX_AGAIN : NGX_OK);
 }
+
+
+static void *ngx_http_write_filter_create_conf(ngx_pool_t *pool)
+{
+    ngx_http_write_filter_conf_t *conf;
+
+    ngx_test_null(conf,
+                  ngx_pcalloc(pool, sizeof(ngx_http_write_filter_conf_t)),
+                  NULL);
+
+    conf->buffer_output = 16384;
+}
+
+static void *ngx_http_write_filter_set_hunk_size(ngx_pool_t *pool, void *conf,
+                                                  char *size)
+{
+    ngx_http_write_filter_conf_t *cf = (ngx_http_write_filter_conf_t *) conf;
+
+    cf->buffer_output = atoi(size);
+    if (cf->buffer_output <= 0)
+        return "Error";
+
+    cf->buffer_output *= 1024;
+    return NULL;
+}
+
--- a/src/http/ngx_http_write_filter.h
+++ b/src/http/ngx_http_write_filter.h
@@ -2,11 +2,19 @@
 #define _NGX_HTTP_WRITE_FILTER_H_INCLUDED_
 
 
+#include <ngx_hunk.h>
+#include <ngx_http.h>
+
+
+typedef struct {
+    size_t        buffer_output;
+} ngx_http_write_filter_conf_t;
+
 typedef struct {
     ngx_chain_t  *out;
-    size_t        buffer_output;
 } ngx_http_write_filter_ctx_t;
 
+
 int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in);
 
 
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -10,8 +10,10 @@ ssize_t ngx_read_file(ngx_file_t *file, 
 
     n = pread(file->fd, buf, size, offset);
 
-    if (n == NGX_ERROR)
+    if (n == -1) {
         ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "read() failed");
+        return NGX_ERROR;
+    }
 
     return n;
 }
--- a/src/os/unix/ngx_sendv.c
+++ b/src/os/unix/ngx_sendv.c
@@ -1,18 +1,28 @@
 
 #include <ngx_core.h>
 #include <ngx_types.h>
-#include <ngx_socket.h>
+#include <ngx_errno.h>
+#include <ngx_connection.h>
+#include <ngx_log.h>
 #include <ngx_sendv.h>
 
-ssize_t ngx_sendv(ngx_socket_t s, ngx_iovec_t *iovec, int n, size_t *sent)
+ssize_t ngx_sendv(ngx_connection_t *c, ngx_iovec_t *iovec, int n)
 {
      ssize_t rc;
+     ngx_err_t err;
 
-     rc = writev(s, iovec, n);
+     rc = writev(c->fd, iovec, n);
 
-     if (rc == -1)
+     if (rc == -1) {
+         err = ngx_socket_errno;
+         if (err == NGX_EAGAIN) {
+             ngx_log_error(NGX_LOG_INFO, c->log, err, "sendv() eagain");
+             return NGX_AGAIN;
+         }
+
+         ngx_log_error(NGX_LOG_ERR, c->log, err, "sendv() failed");
          return NGX_ERROR;
+     }
 
-     *sent = rc;
-     return NGX_OK;
+     return rc;
 }
--- a/src/os/unix/ngx_sendv.h
+++ b/src/os/unix/ngx_sendv.h
@@ -3,13 +3,13 @@
 
 
 #include <ngx_types.h>
-#include <ngx_socket.h>
+#include <ngx_connection.h>
 
 typedef struct iovec  ngx_iovec_t;
 #define ngx_iov_base  iov_base
 #define ngx_iov_len   iov_len
 
-ssize_t ngx_sendv(ngx_socket_t s, ngx_iovec_t *iovec, int n, size_t *sent);
+ssize_t ngx_sendv(ngx_connection_t *c, ngx_iovec_t *iovec, int n);
 
 
 #endif /* _NGX_SENDV_H_INCLUDED_ */
new file mode 100644
--- /dev/null
+++ b/src/os/win32/ngx_sendv.c
@@ -0,0 +1,34 @@
+
+#include <ngx_core.h>
+#include <ngx_types.h>
+#include <ngx_errno.h>
+#include <ngx_connection.h>
+#include <ngx_log.h>
+#include <ngx_sendv.h>
+
+ssize_t ngx_sendv(ngx_connection_t *c, ngx_iovec_t *iovec, int n)
+{
+     int        rc;
+     size_t     sent;
+     ngx_err_t  err;
+
+     ngx_log_debug(c->log, "WSASend() start");
+
+     rc = WSASend(c->fd, iovec, n, &sent, 0, NULL, NULL);
+
+     ngx_log_debug(c->log, "WSASend() done");
+
+     if (rc == -1) {
+         err = ngx_socket_errno;
+
+         if (err == NGX_EAGAIN) {
+             ngx_log_error(NGX_LOG_INFO, c->log, err, "WSASend() eagain");
+             return NGX_AGAIN;
+         }
+
+         ngx_log_error(NGX_LOG_ERR, c->log, err, "WSASend() failed");
+         return NGX_ERROR;
+     }
+
+     return sent;
+}
--- a/src/os/win32/ngx_sendv.h
+++ b/src/os/win32/ngx_sendv.h
@@ -3,12 +3,13 @@
 
 
 #include <ngx_config.h>
+#include <ngx_connection.h>
 
 typedef WSABUF        ngx_iovec_t;
 #define ngx_iov_base  buf
 #define ngx_iov_len   len
 
-#define ngx_sendv(s, iovec, n, sent)  WSASend(s, iovec, n, sent, 0, NULL, NULL)
+ssize_t ngx_sendv(ngx_connection_t *c, ngx_iovec_t *iovec, int n);
 
 
 #endif /* _NGX_SENDV_H_INCLUDED_ */