Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2003-10-09 11:00:45 +0400
committerIgor Sysoev <igor@sysoev.ru>2003-10-09 11:00:45 +0400
commit1342d9cc29de7b6509a44a49cd66d1038d1e6d26 (patch)
tree618ccc0244627bece991abd6a49b354b417e1a21 /src
parent3ae32483cd9315aef5066e2a06411e9ffb8a5560 (diff)
nginx-0.0.1-2003-10-09-11:00:45 import
Diffstat (limited to 'src')
-rw-r--r--src/core/ngx_hunk.h8
-rw-r--r--src/http/modules/ngx_http_not_modified_filter.c4
-rw-r--r--src/http/modules/ngx_http_static_handler.c17
-rw-r--r--src/http/ngx_http.h1
-rw-r--r--src/http/ngx_http_output_filter.c11
-rw-r--r--src/http/ngx_http_request.c (renamed from src/http/ngx_http_event.c)39
-rw-r--r--src/http/ngx_http_special_response.c8
-rw-r--r--src/http/ngx_http_write_filter.c8
-rw-r--r--src/os/unix/ngx_freebsd_init.c24
-rw-r--r--src/os/unix/ngx_freebsd_sendfile_chain.c115
10 files changed, 177 insertions, 58 deletions
diff --git a/src/core/ngx_hunk.h b/src/core/ngx_hunk.h
index 0d03164fc..ef47508bb 100644
--- a/src/core/ngx_hunk.h
+++ b/src/core/ngx_hunk.h
@@ -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,
diff --git a/src/http/modules/ngx_http_not_modified_filter.c b/src/http/modules/ngx_http_not_modified_filter.c
index ab22fa682..f1ccd4456 100644
--- a/src/http/modules/ngx_http_not_modified_filter.c
+++ b/src/http/modules/ngx_http_not_modified_filter.c
@@ -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;
diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c
index 8ea6a0a00..784f3de4d 100644
--- a/src/http/modules/ngx_http_static_handler.c
+++ b/src/http/modules/ngx_http_static_handler.c
@@ -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;
}
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index 4cdd4c608..3cdd120c5 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -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);
diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c
index 06120769f..6de920215 100644
--- a/src/http/ngx_http_output_filter.c
+++ b/src/http/ngx_http_output_filter.c
@@ -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) {
diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_request.c
index ea8120764..0f66b0d40 100644
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_request.c
@@ -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;
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 9e3bb9ae3..736211654 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -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;
diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c
index 26c632c62..3f43875bc 100644
--- a/src/http/ngx_http_write_filter.c
+++ b/src/http/ngx_http_write_filter.c
@@ -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;
}
diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c
index 6eae456ed..ec4924e57 100644
--- a/src/os/unix/ngx_freebsd_init.c
+++ b/src/os/unix/ngx_freebsd_init.c
@@ -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
diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c
index a3c813e38..fa690237a 100644
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -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;
}