]> git.kaiwu.me - nginx.git/commitdiff
nginx-0.0.1-2003-10-09-11:00:45 import
authorIgor Sysoev <igor@sysoev.ru>
Thu, 9 Oct 2003 07:00:45 +0000 (07:00 +0000)
committerIgor Sysoev <igor@sysoev.ru>
Thu, 9 Oct 2003 07:00:45 +0000 (07:00 +0000)
src/core/ngx_hunk.h
src/http/modules/ngx_http_not_modified_filter.c
src/http/modules/ngx_http_static_handler.c
src/http/ngx_http.h
src/http/ngx_http_output_filter.c
src/http/ngx_http_request.c [moved from src/http/ngx_http_event.c with 98% similarity]
src/http/ngx_http_special_response.c
src/http/ngx_http_write_filter.c
src/os/unix/ngx_freebsd_init.c
src/os/unix/ngx_freebsd_sendfile_chain.c

index 0d03164fcd003657eec16dd91c871090bfb68824..ef47508bba002fcd8d075f2040402b13644c8ab4 100644 (file)
@@ -75,6 +75,14 @@ typedef struct {
 
 #define ngx_hunk_in_memory_only(h)                                           \
          ((h->type & (NGX_HUNK_IN_MEMORY|NGX_HUNK_FILE)) == NGX_HUNK_IN_MEMORY)
+/*
+    ((h->type & (NGX_HUNK_TEMP|NGX_HUNK_MEMORY|NGX_HUNK_MMAP|NGX_HUNK_FILE)) \
+                  == (h->type & (NGX_HUNK_TEMP|NGX_HUNK_MEMORY|NGX_HUNK_MMAP)))
+
+*/
+
+#define ngx_hunk_special(h)                                                  \
+        (h->type == (h->type & (NGX_HUNK_FLUSH|NGX_HUNK_LAST)))
 
 
 ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,
index ab22fa682324979770c3f16401fcba0bcfa02362..f1ccd4456ea9553a2230eb931edfb74ef93ab571 100644 (file)
@@ -39,7 +39,7 @@ static int ngx_http_not_modified_header_filter(ngx_http_request_t *r)
 
     if (r->headers_out.status != NGX_HTTP_OK
         || r->headers_in.if_modified_since == NULL
-        || r->headers_out.last_modified_time == NULL)
+        || r->headers_out.last_modified_time == -1)
     {
         return next_header_filter(r);
     }
@@ -50,7 +50,7 @@ static int ngx_http_not_modified_header_filter(ngx_http_request_t *r)
     ngx_log_debug(r->connection->log, "%d %d" _
                   ims _ r->headers_out.last_modified_time);
 
-    /* I think that the date equality is correcter */
+    /* I think that the equality of the dates is correcter */
 
     if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) {
         r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
index 8ea6a0a00c47fc9bb17032034f1bd75faa782292..784f3de4d040a29143063de563857b05acbe42b0 100644 (file)
@@ -118,6 +118,7 @@ int ngx_http_static_handler(ngx_http_request_t *r)
     }
 
     /* we need to allocate all before the header would be sent */
+
     ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)),
                   NGX_HTTP_INTERNAL_SERVER_ERROR);
 
@@ -132,18 +133,28 @@ int ngx_http_static_handler(ngx_http_request_t *r)
     }
 
     if (r->header_only) {
+        ngx_http_finalize_request(r, rc);
+
+#if 0
         if (rc == NGX_AGAIN) {
             ngx_http_set_write_handler(r);
 
         } else {
             ngx_http_finalize_request(r, 0);
         }
+#endif
 
         return NGX_OK;
     }
 
 
-    h->type = NGX_HUNK_FILE|NGX_HUNK_LAST;
+#if 0
+    h->type = r->main ? NGX_HUNK_FILE : NGX_HUNK_FILE|NGX_HUNK_LAST;
+#else
+    h->type = NGX_HUNK_FILE;
+#endif
+
+
     h->file_pos = 0;
     h->file_last = ngx_file_size(r->file.info);
 
@@ -152,6 +163,9 @@ int ngx_http_static_handler(ngx_http_request_t *r)
 
     rc = ngx_http_output_filter(r, h);
 
+    ngx_http_finalize_request(r, rc);
+
+#if 0
     if (r->main == NULL) {
         if (rc == NGX_AGAIN) {
             ngx_http_set_write_handler(r);
@@ -160,6 +174,7 @@ int ngx_http_static_handler(ngx_http_request_t *r)
             ngx_http_finalize_request(r, 0);
         }
     }
+#endif
 
     return NGX_OK;
 }
index 4cdd4c608cb053c2d64913ea5e2cc924654880db..3cdd120c5ad36baee8c4d566264a4c011d1e217e 100644 (file)
@@ -54,6 +54,7 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int error);
 void ngx_http_set_write_handler(ngx_http_request_t *r);
 
 
+int ngx_http_send_last(ngx_http_request_t *r);
 void ngx_http_close_request(ngx_http_request_t *r, int error);
 void ngx_http_close_connection(ngx_connection_t *c);
 
index 06120769f7e01d06902f4922c144ca0127648b10..6de920215a004667785b4b28000fd32d7798426d 100644 (file)
@@ -72,10 +72,11 @@ ngx_module_t  ngx_http_output_filter_module = {
 #define ngx_next_filter  (*ngx_http_top_body_filter)
 
 #define need_to_copy(r, hunk)                                             \
-            (((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY)                \
-               && (hunk->type & NGX_HUNK_IN_MEMORY) == 0)                 \
-             || ((r->filter & NGX_HTTP_FILTER_NEED_TEMP)                  \
-                  && (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP))))
+            (!ngx_hunk_special(hunk)                                      \
+             && (((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY)            \
+                   && (hunk->type & NGX_HUNK_IN_MEMORY) == 0)             \
+                 || ((r->filter & NGX_HTTP_FILTER_NEED_TEMP)              \
+                  && (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP)))))
 
 
 
@@ -201,6 +202,8 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
             *ctx->last_out = ce;
             ctx->last_out = &ce->next;
             ctx->hunk = NULL;
+
+            break;
         }
 
         if (ctx->out == NULL && last != NGX_NONE) {
similarity index 98%
rename from src/http/ngx_http_event.c
rename to src/http/ngx_http_request.c
index ea81207645fafb971ebc310e94117fd885da4741..0f66b0d4085073e9041524a6e35d26347259cc7c 100644 (file)
@@ -785,6 +785,10 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int error)
     int           rc;
     ngx_event_t  *rev, *wev;
 
+    if (r->main) {
+        return;
+    }
+
     rc = error;
 
     if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
@@ -813,9 +817,25 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int error)
             return;
         }
 
+#if 1
+        return;
+#endif
+
     } else if (rc == NGX_ERROR) {
         r->keepalive = 0;
         r->lingering_close = 0;
+
+    } else {
+        if (ngx_http_send_last(r) == NGX_ERROR) {
+            ngx_http_close_request(r, 0);
+            ngx_http_close_connection(r->connection);
+            return;
+        }
+
+        if (rc == NGX_AGAIN) {
+            ngx_http_set_write_handler(r);
+            return;
+        }
     }
 
     rev = r->connection->read;
@@ -840,6 +860,8 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int error)
         ngx_http_close_request(r, 0);
         ngx_http_close_connection(r->connection);
     }
+
+    return;
 }
 
 
@@ -887,6 +909,8 @@ void ngx_http_set_write_handler(ngx_http_request_t *r)
         ngx_http_close_request(r, 0);
         ngx_http_close_connection(r->connection);
     }
+
+    return;
 }
 
 
@@ -951,6 +975,8 @@ static void ngx_http_writer(ngx_event_t *wev)
         ngx_http_close_request(r, 0);
         ngx_http_close_connection(r->connection);
     }
+
+    return;
 }
 
 
@@ -1046,6 +1072,8 @@ static void ngx_http_read_discarded_body_event(ngx_event_t *rev)
         ngx_http_close_request(r, rc);
         ngx_http_close_connection(c);
     }
+
+    return;
 }
 
 
@@ -1385,6 +1413,17 @@ static void ngx_http_empty_handler(ngx_event_t *wev)
 }
 
 
+int ngx_http_send_last(ngx_http_request_t *r)
+{
+    ngx_hunk_t  *h;
+
+    ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
+    h->type = NGX_HUNK_LAST;
+
+    return ngx_http_output_filter(r, h);
+}
+
+
 void ngx_http_close_request(ngx_http_request_t *r, int error)
 {
     ngx_http_log_ctx_t  *ctx;
index 9e3bb9ae33b7b78423568bf9b3d41e5f6e7db8aa..7362116542878af648b9e632b1b0ad4c3cb3a0ca 100644 (file)
@@ -199,15 +199,19 @@ int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
     }
 
     rc = ngx_http_send_header(r);
+
     if (rc == NGX_ERROR) {
         return NGX_ERROR;
     }
 
     if (r->header_only) {
+        ngx_http_finalize_request(r, rc);
+#if 0
         if (rc == NGX_AGAIN) {
             ngx_http_set_write_handler(r);
             return NGX_AGAIN;
         }
+#endif
 
         return NGX_OK;
     }
@@ -248,12 +252,16 @@ int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
 
     rc = ngx_http_output_filter(r, h);
 
+    ngx_http_finalize_request(r, rc);
+
+#if 0
     if (r->main == NULL) {
         if (rc == NGX_AGAIN) {
             ngx_http_set_write_handler(r);
             return NGX_AGAIN;
         }
     }
+#endif
 
     return NGX_OK;
 
index 26c632c6244df9b8a85feb78955dd5091d2b5a64..3f43875bcc32a65d9f4bd7addc37931b1145c3e6 100644 (file)
@@ -130,14 +130,16 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
                   last _ flush _ size);
 #endif
 
-    /* avoid the output if there is no last hunk, no flush point and
-       size of the hunks is smaller then "buffer_output" */
+    /*
+     * avoid the output if there is no last hunk, no flush point and
+     * size of the hunks is smaller then "buffer_output"
+     */
 
     if (!last && flush == 0 && size < conf->buffer_output) {
         return NGX_OK;
     }
 
-    if (r->connection->write->delayed) {
+    if (!r->connection->write->ready || r->connection->write->delayed) {
         return NGX_AGAIN;
     }
 
index 6eae456ed318a4e9987abdd03375a3d1514ab973..ec4924e573b00f5308e35d883eb527c36cf7292b 100644 (file)
@@ -93,26 +93,30 @@ int ngx_os_init(ngx_log_t *log)
 
 #if (HAVE_FREEBSD_SENDFILE)
 
-    /* The determination of the sendfile() nbytes bug is complex enough.
-       There're two sendfile() syscalls: a new 393 has no bug while
-       an old 336 has the bug in some versions and has not in others.
-       Besides libc_r wrapper also emulates the bug in some versions.
-       There's no way to say exactly if a given FreeBSD version has bug.
-       Here is the algorithm that works at least for RELEASEs
-       and for syscalls only (not libc_r wrapper). */
-
-    /* detect the new sendfile() version available at the compile time
-       to allow an old binary to run correctly on an updated FreeBSD system. */
+    /*
+     * The determination of the sendfile() nbytes bug is complex enough.
+     * There're two sendfile() syscalls: a new 393 has no bug while
+     * an old 336 has the bug in some versions and has not in others.
+     * Besides libc_r wrapper also emulates the bug in some versions.
+     * There's no way to say exactly if a given FreeBSD version has the bug.
+     * Here is the algorithm that works at least for RELEASEs
+     * and for syscalls only (not libc_r wrapper).
+     *
+     * We detect the new sendfile() version available at the compile time
+     * to allow an old binary to run correctly on an updated FreeBSD system.
+     */
 
 #if (__FreeBSD__ == 4 && __FreeBSD_version >= 460102) \
     || __FreeBSD_version == 460002 || __FreeBSD_version >= 500039
 
     /* a new syscall without the bug */
+
     ngx_freebsd_sendfile_nbytes_bug = 0;
 
 #else
 
     /* an old syscall that can have the bug */
+
     ngx_freebsd_sendfile_nbytes_bug = 1;
 
 #endif
index a3c813e38231cd4385c7920a095f476b60c2a6ec..fa690237ad37e12bc51d18c46c8abc159640e13d 100644 (file)
@@ -1,23 +1,24 @@
 
 #include <ngx_config.h>
 #include <ngx_core.h>
+#include <ngx_event.h>
 #include <ngx_freebsd_init.h>
 
 
 /*
  sendfile() often sends 4K pages over ethernet in 3 packets: 2x1460 and 1176
  or in 6 packets: 5x1460 and 892.  Besides although sendfile() allows
  to pass the header and the trailer it never sends the header or the trailer
  with the part of the file in one packet.  So we use TCP_NOPUSH (similar
  to Linux's TCP_CORK) to postpone the sending - it not only sends the header
  and the first part of the file in one packet but also sends 4K pages
  in the full packets.
-
  Until FreeBSD 4.5 the turning TCP_NOPUSH off does not not flush
  the pending data that less than MSS and the data sent with 5 second delay.
  So we use TCP_NOPUSH on FreeBSD prior to 4.5 only if the connection
  is not needed not keepalive.
-*/
* sendfile() often sends 4K pages over ethernet in 3 packets: 2x1460 and 1176
* or in 6 packets: 5x1460 and 892.  Besides although sendfile() allows
* to pass the header and the trailer it never sends the header or the trailer
* with the part of the file in one packet.  So we use TCP_NOPUSH (similar
* to Linux's TCP_CORK) to postpone the sending - it not only sends the header
* and the first part of the file in one packet but also sends 4K pages
* in the full packets.
+ *
* Until FreeBSD 4.5 the turning TCP_NOPUSH off does not not flush
* the pending data that less than MSS and the data sent with 5 second delay.
* So we use TCP_NOPUSH on FreeBSD prior to 4.5 only if the connection
* is not needed to be keepalive.
+ */
 
 
 ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
@@ -47,12 +48,23 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
                        NGX_CHAIN_ERROR);
 
         /* create the header iovec */
-        if (ngx_hunk_in_memory_only(ce->hunk)) {
+
+#if 0
+        if (ngx_hunk_in_memory_only(ce->hunk) || ngx_hunk_special(ce->hunk)) {
+#endif
             prev = NULL;
             iov = NULL;
 
             /* create the iovec and coalesce the neighbouring chain entries */
-            while (ce && ngx_hunk_in_memory_only(ce->hunk)) {
+
+            for ( /* void */; ce; ce = ce->next) {
+                if (ngx_hunk_special(ce->hunk)) {
+                    continue;
+                }
+
+                if (!ngx_hunk_in_memory_only(ce->hunk)) {
+                    break;
+                }
 
                 if (prev == ce->hunk->pos) {
                     iov->iov_len += ce->hunk->last - ce->hunk->pos;
@@ -67,24 +79,39 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
                 }
 
                 hsize += ce->hunk->last - ce->hunk->pos;
-
-                ce = ce->next;
             }
+#if 0
         }
+#endif
 
         /* TODO: coalesce the neighbouring file hunks */
+
         if (ce && (ce->hunk->type & NGX_HUNK_FILE)) {
             file = ce->hunk;
             ce = ce->next;
         }
 
         /* create the trailer iovec */
-        if (ce && ngx_hunk_in_memory_only(ce->hunk)) {
+
+#if 0
+        if (ce
+            && (ngx_hunk_in_memory_only(ce->hunk)
+                || ngx_hunk_special(ce->hunk)))
+        {
+#endif
             prev = NULL;
             iov = NULL;
 
             /* create the iovec and coalesce the neighbouring chain entries */
-            while (ce && ngx_hunk_in_memory_only(ce->hunk)) {
+
+            for ( /* void */; ce; ce = ce->next) {
+                if (ngx_hunk_special(ce->hunk)) {
+                    continue;
+                }
+
+                if (!ngx_hunk_in_memory_only(ce->hunk)) {
+                    break;
+                }
 
                 if (prev == ce->hunk->pos) {
                     iov->iov_len += ce->hunk->last - ce->hunk->pos;
@@ -97,10 +124,10 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
                     iov->iov_len = ce->hunk->last - ce->hunk->pos;
                     prev = ce->hunk->last;
                 }
-
-                ce = ce->next;
             }
+#if 0
         }
+#endif
 
         tail = ce;
 
@@ -155,28 +182,36 @@ ngx_log_debug(c->log, "NOPUSH");
 #endif
 
         } else {
-            rc = writev(c->fd, (struct iovec *) header.elts, header.nelts);
-
-            if (rc == -1) {
-                err = ngx_errno;
-                if (err == NGX_EAGAIN) {
-                    ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN");
-
-                } else if (err == NGX_EINTR) {
-                    eintr = 1;
-                    ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR");
-
-                } else {
-                    ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed");
-                    return NGX_CHAIN_ERROR;
+            if (hsize) {
+                rc = writev(c->fd, (struct iovec *) header.elts, header.nelts);
+
+                if (rc == -1) {
+                    err = ngx_errno;
+                    if (err == NGX_EAGAIN) {
+                        ngx_log_error(NGX_LOG_INFO, c->log, err,
+                                      "writev() EAGAIN");
+
+                    } else if (err == NGX_EINTR) {
+                        eintr = 1;
+                        ngx_log_error(NGX_LOG_INFO, c->log, err,
+                                      "writev() EINTR");
+
+                    } else {
+                        ngx_log_error(NGX_LOG_CRIT, c->log, err,
+                                      "writev() failed");
+                        return NGX_CHAIN_ERROR;
+                    }
                 }
-            }
 
-            sent = rc > 0 ? rc : 0;
+                sent = rc > 0 ? rc : 0;
 
 #if (NGX_DEBUG_WRITE_CHAIN)
-            ngx_log_debug(c->log, "writev: %qd" _ sent);
+                ngx_log_debug(c->log, "writev: %qd" _ sent);
 #endif
+
+            } else {
+                sent = 0;
+            }
         }
 
         c->sent += sent;
@@ -221,5 +256,9 @@ ngx_log_debug(c->log, "NOPUSH");
 
     } while ((tail && tail == ce) || eintr);
 
+    if (ce) {
+        c->write->ready = 0;
+    }
+
     return ce;
 }