aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2003-10-22 07:05:29 +0000
committerIgor Sysoev <igor@sysoev.ru>2003-10-22 07:05:29 +0000
commit5bf3d25d69ecdbccaa98beeb089a7a6850529b89 (patch)
tree1bc211941faf078f87f79bea1f2703e3190483fa
parent419f9aceb4d994c2f7f51400f59fb2da0ed666d4 (diff)
downloadnginx-5bf3d25d69ecdbccaa98beeb089a7a6850529b89.tar.gz
nginx-5bf3d25d69ecdbccaa98beeb089a7a6850529b89.zip
nginx-0.0.1-2003-10-22-11:05:29 import
-rw-r--r--src/core/ngx_hunk.c6
-rw-r--r--src/core/ngx_hunk.h31
-rw-r--r--src/event/ngx_event_pipe.c64
-rw-r--r--src/event/ngx_event_pipe.h6
-rw-r--r--src/http/modules/ngx_http_gzip_filter.c5
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_handler.c32
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_handler.h3
-rw-r--r--src/http/ngx_http_core_module.c21
-rw-r--r--src/http/ngx_http_core_module.h1
-rw-r--r--src/http/ngx_http_filter.h8
-rw-r--r--src/http/ngx_http_output_filter.c21
-rw-r--r--src/http/ngx_http_request.h3
-rw-r--r--src/http/ngx_http_write_filter.c24
-rw-r--r--src/os/unix/ngx_files.c10
-rw-r--r--src/os/unix/ngx_freebsd_sendfile_chain.c2
15 files changed, 154 insertions, 83 deletions
diff --git a/src/core/ngx_hunk.c b/src/core/ngx_hunk.c
index 6bed8c566..cd218307d 100644
--- a/src/core/ngx_hunk.c
+++ b/src/core/ngx_hunk.c
@@ -125,7 +125,7 @@ int ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **ch, ngx_chain_t *in)
void ngx_chain_update_chains(ngx_chain_t **free, ngx_chain_t **busy,
- ngx_chain_t **out)
+ ngx_chain_t **out, ngx_hunk_tag_t tag)
{
ngx_chain_t *te;
@@ -154,9 +154,7 @@ void ngx_chain_update_chains(ngx_chain_t **free, ngx_chain_t **busy,
}
#endif
- /* TODO: change to hunk->tag */
-
- if (!((*busy)->hunk->type & NGX_HUNK_TEMP)) {
+ if ((*busy)->hunk->tag != tag) {
*busy = (*busy)->next;
continue;
}
diff --git a/src/core/ngx_hunk.h b/src/core/ngx_hunk.h
index 3a10076cc..940241be7 100644
--- a/src/core/ngx_hunk.h
+++ b/src/core/ngx_hunk.h
@@ -34,25 +34,28 @@
/* last hunk */
#define NGX_HUNK_LAST 0x2000
#define NGX_HUNK_LAST_SHADOW 0x4000
+#define NGX_HUNK_TEMP_FILE 0x8000
+typedef void * ngx_hunk_tag_t;
typedef struct ngx_hunk_s ngx_hunk_t;
struct ngx_hunk_s {
- char *pos;
- char *last;
- off_t file_pos;
- off_t file_last;
-
- int type;
- char *start; /* start of hunk */
- char *end; /* end of hunk */
- char *pre_start; /* start of pre-allocated hunk */
- char *post_end; /* end of post-allocated hunk */
- int tag;
- ngx_file_t *file;
- ngx_hunk_t *shadow;
+ char *pos;
+ char *last;
+ off_t file_pos;
+ off_t file_last;
+
+ int type;
+ char *start; /* start of hunk */
+ char *end; /* end of hunk */
+ char *pre_start; /* start of pre-allocated hunk */
+ char *post_end; /* end of post-allocated hunk */
+ ngx_hunk_tag_t tag;
+ ngx_file_t *file;
+ ngx_hunk_t *shadow;
+ /* STUB */ int num;
};
@@ -119,7 +122,7 @@ ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,
int ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **ch, ngx_chain_t *in);
void ngx_chain_update_chains(ngx_chain_t **free, ngx_chain_t **busy,
- ngx_chain_t **out);
+ ngx_chain_t **out, ngx_hunk_tag_t tag);
diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
index fdaba3f7d..10a954c95 100644
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -27,12 +27,13 @@ int ngx_event_pipe(ngx_event_pipe_t *p, int do_write)
}
p->read = 0;
+ p->upstream_blocked = 0;
if (ngx_event_pipe_read_upstream(p) == NGX_ABORT) {
return NGX_ABORT;
}
- if (!p->read) {
+ if (!p->read && !p->upstream_blocked) {
break;
}
@@ -140,6 +141,8 @@ int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
* a downstream is ready then write the hunks to a downstream
*/
+ p->upstream_blocked = 1;
+
ngx_log_debug(p->log, "downstream ready");
break;
@@ -184,6 +187,8 @@ int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
break;
}
+ ngx_log_debug(p->log, "HUNK_FREE: %d" _ chain->hunk->num);
+
n = ngx_recv_chain(p->upstream, chain);
ngx_log_debug(p->log, "recv_chain: %d" _ n);
@@ -218,6 +223,8 @@ int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
if (n >= size) {
ce->hunk->last = ce->hunk->end;
+ /* STUB */ ce->hunk->num = p->num++;
+
if (p->input_filter(p, ce->hunk) == NGX_ERROR) {
return NGX_ABORT;
}
@@ -235,6 +242,7 @@ int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
}
if ((p->upstream_eof || p->upstream_error) && p->free_raw_hunks) {
+ /* STUB */ p->free_raw_hunks->hunk->num = p->num++;
if (p->input_filter(p, p->free_raw_hunks->hunk) == NGX_ERROR) {
return NGX_ABORT;
}
@@ -302,6 +310,8 @@ int ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
p->out = p->out->next;
ngx_remove_shadow_free_raw_hunk(&p->free_raw_hunks, ce->hunk);
+ngx_log_debug(p->log, "HUNK OUT: %d %x" _ ce->hunk->num _ ce->hunk->type);
+
} else if (!p->cachable && p->in) {
ce = p->in;
@@ -313,6 +323,8 @@ int ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
p->in = p->in->next;
+ngx_log_debug(p->log, "HUNK IN: %d" _ ce->hunk->num);
+
} else {
break;
}
@@ -323,22 +335,32 @@ int ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
}
if (out == NULL) {
- break;
+ ngx_log_debug(p->log, "no hunks to write BUSY: %d" _ busy_len);
+
+ if (!p->upstream_blocked || busy_len == 0) {
+ break;
+ }
+
+ /* if the upstream is blocked then write the busy hunks */
}
if (p->output_filter(p->output_ctx, out) == NGX_ERROR) {
p->downstream_error = 1;
+
+ /* handle the downstream error at the begin of the cycle. */
+
continue;
}
- ngx_chain_update_chains(&p->free, &p->busy, &out);
-
- /* add the free shadow raw hunks to p->free_raw_hunks */
+ ngx_chain_update_chains(&p->free, &p->busy, &out, p->tag);
for (ce = p->free; ce; ce = ce->next) {
+
+ /* add the free shadow raw hunk to p->free_raw_hunks */
+
if (ce->hunk->type & NGX_HUNK_LAST_SHADOW) {
h = ce->hunk->shadow;
- /* THINK NEEDED ??? */ h->pos = h->last = h->start;
+ h->pos = h->last = h->start;
h->shadow = NULL;
ngx_alloc_ce_and_set_hunk(te, h, p->pool, NGX_ABORT);
ngx_add_after_partially_filled_hunk(&p->free_raw_hunks, te);
@@ -346,6 +368,15 @@ int ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
ce->hunk->type &= ~NGX_HUNK_LAST_SHADOW;
}
ce->hunk->shadow = NULL;
+
+ if (p->cyclic_temp_file && (ce->hunk->type & NGX_HUNK_TEMP_FILE)) {
+
+ /* reset p->temp_offset if all hunks had been sent */
+
+ if (ce->hunk->file_last == p->temp_offset) {
+ p->temp_offset = 0;
+ }
+ }
}
}
@@ -355,7 +386,7 @@ int ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
static int ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p)
{
- int rc, size, hunk_size;
+ int rc, size, hsize;
ngx_hunk_t *h;
ngx_chain_t *ce, *te, *next, *out, **le, **last_free;
@@ -389,17 +420,17 @@ static int ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p)
ngx_log_debug(p->log, "offset: %d" _ p->temp_offset);
do {
- hunk_size = ce->hunk->last - ce->hunk->pos;
+ hsize = ce->hunk->last - ce->hunk->pos;
-ngx_log_debug(p->log, "hunk size: %d" _ hunk_size);
+ngx_log_debug(p->log, "hunk size: %d" _ hsize);
- if ((size + hunk_size > p->temp_file_write_size)
- || (p->temp_offset + hunk_size > p->max_temp_file_size))
+ if ((size + hsize > p->temp_file_write_size)
+ || (p->temp_offset + size + hsize > p->max_temp_file_size))
{
break;
}
- size += hunk_size;
+ size += hsize;
le = &ce->next;
ce = ce->next;
@@ -438,12 +469,17 @@ ngx_log_debug(p->log, "size: %d" _ size);
ce->next = NULL;
h = ce->hunk;
- h->type |= NGX_HUNK_FILE;
h->file = p->temp_file;
h->file_pos = p->temp_offset;
p->temp_offset += h->last - h->pos;
h->file_last = p->temp_offset;
+ if (p->cachable) {
+ h->type |= NGX_HUNK_FILE;
+ } else {
+ h->type |= NGX_HUNK_FILE|NGX_HUNK_TEMP_FILE;
+ }
+
ngx_chain_add_ce(p->out, p->last_out, ce);
if (h->type & NGX_HUNK_LAST_SHADOW) {
@@ -479,10 +515,12 @@ int ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_hunk_t *hunk)
ngx_memcpy(h, hunk, sizeof(ngx_hunk_t));
h->shadow = hunk;
+ h->tag = p->tag;
h->type |= NGX_HUNK_LAST_SHADOW|NGX_HUNK_RECYCLED;
hunk->shadow = h;
ngx_alloc_ce_and_set_hunk(ce, h, p->pool, NGX_ERROR);
+ngx_log_debug(p->log, "HUNK %d" _ h->num);
ngx_chain_add_ce(p->in, p->last_in, ce);
return NGX_OK;
diff --git a/src/event/ngx_event_pipe.h b/src/event/ngx_event_pipe.h
index aef80de03..a928145f4 100644
--- a/src/event/ngx_event_pipe.h
+++ b/src/event/ngx_event_pipe.h
@@ -39,13 +39,16 @@ struct ngx_event_pipe_s {
unsigned read:1;
unsigned cachable:1;
unsigned upstream_done:1;
- unsigned upstream_eof:1;
unsigned upstream_error:1;
+ unsigned upstream_eof:1;
+ unsigned upstream_blocked:1;
unsigned downstream_done:1;
unsigned downstream_error:1;
+ unsigned cyclic_temp_file:1;
int hunks;
ngx_bufs_t bufs;
+ ngx_hunk_tag_t tag;
size_t max_busy_len;
@@ -65,6 +68,7 @@ struct ngx_event_pipe_s {
ngx_file_t *temp_file;
ngx_path_t *temp_path;
char *temp_file_warn;
+ /* STUB */ int num;
};
diff --git a/src/http/modules/ngx_http_gzip_filter.c b/src/http/modules/ngx_http_gzip_filter.c
index df360b80b..5b8cebb4b 100644
--- a/src/http/modules/ngx_http_gzip_filter.c
+++ b/src/http/modules/ngx_http_gzip_filter.c
@@ -287,6 +287,8 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
ngx_create_temp_hunk(r->pool, conf->bufs.size,
0, 0),
ngx_http_gzip_error(ctx));
+ ctx->out_hunk->tag = (ngx_hunk_tag_t)
+ &ngx_http_gzip_filter_module;
ctx->out_hunk->type |= NGX_HUNK_RECYCLED;
ctx->hunks++;
@@ -417,7 +419,8 @@ ngx_log_debug(r->connection->log, "DEFLATE(): %08x %08x %d %d %d" _
return ngx_http_gzip_error(ctx);
}
- ngx_chain_update_chains(&ctx->free, &ctx->busy, &ctx->out);
+ ngx_chain_update_chains(&ctx->free, &ctx->busy, &ctx->out,
+ (ngx_hunk_tag_t) &ngx_http_gzip_filter_module);
ctx->last_out = &ctx->out;
}
}
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c
index eefa1f886..e3157d8e6 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -410,6 +410,7 @@ static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev)
ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
+ p->header_in->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module;
}
n = ngx_http_proxy_read_upstream_header(p);
@@ -712,6 +713,7 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
ep->output_filter = (ngx_event_pipe_output_filter_pt)
ngx_http_output_filter;
ep->output_ctx = r;
+ ep->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module;
ep->bufs = p->lcf->bufs;
ep->max_busy_len = p->lcf->max_busy_len;
ep->upstream = p->upstream.connection;
@@ -720,7 +722,7 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
ep->log = r->connection->log;
ep->temp_path = p->lcf->temp_path;
- ep->temp_file = ngx_palloc(r->pool, sizeof(ngx_file_t));
+ ep->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
if (ep->temp_file == NULL) {
ngx_http_proxy_finalize_request(p, 0);
return;
@@ -750,10 +752,23 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
*/
p->header_in->last = p->header_in->pos;
- /* STUB */ ep->cachable = 1;
-#if 0
- ep->max_temp_file_size = 1000000000;
-#endif
+ /* STUB */ ep->cachable = 0;
+
+ if (p->lcf->cyclic_temp_file) {
+
+ /*
+ * we need to disable the use of sendfile() if we use cyclic temp file
+ * because the writing a new data can interfere with sendfile
+ * that uses the same kernel file pages
+ */
+
+ ep->cyclic_temp_file = 1;
+ r->sendfile = 0;
+
+ } else {
+ ep->cyclic_temp_file = 0;
+ r->sendfile = 1;
+ }
p->event_pipe = ep;
@@ -1162,16 +1177,17 @@ static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
conf->header_size = 4096;
conf->read_timeout = 30000;
- conf->bufs.num = 10;
+ conf->bufs.num = 5;
conf->bufs.size = 4096;
conf->max_busy_len = 8192;
/* CHECK in _init conf->max_temp_size >= conf->bufs.size !!! */
- conf->max_temp_file_size = 4096 * 6;
+ conf->max_temp_file_size = 4096 * 3;
- conf->temp_file_write_size = 4096 * 1;
+ conf->temp_file_write_size = 4096 * 2;
+ conf->cyclic_temp_file= 1;
ngx_test_null(conf->temp_path, ngx_pcalloc(cf->pool, sizeof(ngx_path_t)),
NULL);
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h
index fe6ca23b7..597c309ff 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.h
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.h
@@ -26,10 +26,11 @@ typedef struct {
ngx_bufs_t bufs;
- /* STUB */
+ /* STUB names */
int max_busy_len;
int max_temp_file_size;
int temp_file_write_size;
+ int cyclic_temp_file;
/* */
ngx_path_t *temp_path;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 73d089574..601568377 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -130,6 +130,13 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_loc_conf_t, doc_root),
NULL},
+ {ngx_string("sendfile"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, sendfile),
+ NULL},
+
{ngx_string("send_timeout"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
@@ -334,7 +341,6 @@ int ngx_http_find_location_config(ngx_http_request_t *r)
int i, rc;
ngx_http_core_loc_conf_t *clcf, **clcfp;
ngx_http_core_srv_conf_t *cscf;
- ngx_http_write_filter_conf_t *wcf;
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
@@ -364,13 +370,14 @@ ngx_log_debug(r->connection->log, "rc: %d" _ rc);
}
}
- wcf = ngx_http_get_module_loc_conf(r, ngx_http_write_filter_module);
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- if (!(ngx_io.flags & NGX_IO_SENDFILE) || !wcf->sendfile) {
- r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
- }
+ if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) {
+ r->sendfile = 0;
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+ } else {
+ r->sendfile = 1;
+ }
if (clcf->handler) {
/*
@@ -828,6 +835,7 @@ static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf)
*/
+ lcf->sendfile = NGX_CONF_UNSET;
lcf->send_timeout = NGX_CONF_UNSET;
lcf->discarded_buffer_size = NGX_CONF_UNSET;
lcf->keepalive_timeout = NGX_CONF_UNSET;
@@ -896,6 +904,7 @@ static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
ngx_conf_merge_str_value(conf->default_type,
prev->default_type, "text/plain");
+ ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 10000);
ngx_conf_merge_size_value(conf->discarded_buffer_size,
prev->discarded_buffer_size, 1500);
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index f6048f036..9cc979145 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -110,6 +110,7 @@ typedef struct {
ngx_array_t *types;
ngx_str_t default_type;
+ int sendfile; /* sendfile */
ngx_msec_t send_timeout; /* send_timeout */
ssize_t send_lowat; /* send_lowat */
ssize_t discarded_buffer_size; /* discarded_buffer_size */
diff --git a/src/http/ngx_http_filter.h b/src/http/ngx_http_filter.h
index 7792bb9e7..343afd04b 100644
--- a/src/http/ngx_http_filter.h
+++ b/src/http/ngx_http_filter.h
@@ -7,12 +7,6 @@
#define NGX_HTTP_FILTER_NEED_TEMP 4
-typedef struct {
- ssize_t buffer_output;
- int sendfile;
-} ngx_http_write_filter_conf_t;
-
-
int ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in);
int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in);
@@ -20,7 +14,5 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in);
extern int (*ngx_http_top_header_filter) (ngx_http_request_t *r);
extern int (*ngx_http_top_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
-extern ngx_module_t ngx_http_write_filter_module;
-
#endif /* _NGX_HTTP_FILTER_H_INCLUDED_ */
diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c
index ae95de843..061798e3d 100644
--- a/src/http/ngx_http_output_filter.c
+++ b/src/http/ngx_http_output_filter.c
@@ -32,7 +32,8 @@ typedef struct {
} ngx_http_output_filter_ctx_t;
-static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src);
+static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src,
+ int sendfile);
static void *ngx_http_output_filter_create_conf(ngx_conf_t *cf);
static char *ngx_http_output_filter_merge_conf(ngx_conf_t *cf,
void *parent, void *child);
@@ -77,7 +78,8 @@ ngx_module_t ngx_http_output_filter_module = {
#define need_to_copy(r, hunk) \
(!ngx_hunk_special(hunk) \
- && (((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY) \
+ && (!r->sendfile \
+ || ((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)))))
@@ -162,6 +164,8 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
ngx_create_temp_hunk(r->pool, conf->bufs.size,
0, 0),
NGX_ERROR);
+ ctx->hunk->tag = (ngx_hunk_tag_t)
+ &ngx_http_output_filter_module;
ctx->hunk->type |= NGX_HUNK_RECYCLED;
ctx->hunks++;
@@ -170,7 +174,8 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
}
- rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk);
+ rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk,
+ r->sendfile);
if (rc == NGX_ERROR) {
return rc;
@@ -215,13 +220,15 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
last = ngx_next_filter(r, ctx->out);
- ngx_chain_update_chains(&ctx->free, &ctx->busy, &ctx->out);
+ ngx_chain_update_chains(&ctx->free, &ctx->busy, &ctx->out,
+ (ngx_hunk_tag_t) &ngx_http_output_filter_module);
ctx->last_out = &ctx->out;
}
}
-static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src)
+static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src,
+ int sendfile)
{
ssize_t n, size;
@@ -279,6 +286,10 @@ ngx_log_debug(src->file->log, "READ: %qd:%qd %X:%X %X:%X" _
src->file_pos += n;
dst->last += n;
+ if (!sendfile) {
+ dst->type &= ~NGX_HUNK_FILE;
+ }
+
if ((src->type & NGX_HUNK_LAST) && src->file_pos == src->file_last) {
dst->type |= NGX_HUNK_LAST;
}
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 887afd937..913a0367e 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -190,6 +190,9 @@ struct ngx_http_request_s {
#endif
unsigned pipeline:1;
+ /* can we use sendfile ? */
+ unsigned sendfile:1;
+
unsigned chunked:1;
unsigned header_only:1;
unsigned keepalive:1;
diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c
index 4032c7f52..109a9f43b 100644
--- a/src/http/ngx_http_write_filter.c
+++ b/src/http/ngx_http_write_filter.c
@@ -6,6 +6,11 @@
typedef struct {
+ ssize_t buffer_output;
+} ngx_http_write_filter_conf_t;
+
+
+typedef struct {
ngx_chain_t *out;
} ngx_http_write_filter_ctx_t;
@@ -18,13 +23,6 @@ static int ngx_http_write_filter_init(ngx_cycle_t *cycle);
static ngx_command_t ngx_http_write_filter_commands[] = {
- {ngx_string("sendfile"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_write_filter_conf_t, sendfile),
- NULL},
-
{ngx_string("buffer_output"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_size_slot,
@@ -94,9 +92,6 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
}
- conf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
- ngx_http_write_filter_module);
-
/* add the new chain to the existent one */
for (/* void */; in; in = in->next) {
@@ -107,10 +102,6 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
*le = ce;
le = &ce->next;
- if (!(ngx_io.flags & NGX_IO_SENDFILE) || !conf->sendfile) {
- ce->hunk->type &= ~NGX_HUNK_FILE;
- }
-
size += ngx_hunk_size(ce->hunk);
if (ce->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
@@ -128,6 +119,9 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
last _ flush _ size);
#endif
+ conf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
+ ngx_http_write_filter_module);
+
/*
* avoid the output if there is no last hunk, no flush point and
* size of the hunks is smaller then "buffer_output"
@@ -174,7 +168,6 @@ static void *ngx_http_write_filter_create_conf(ngx_conf_t *cf)
NULL);
conf->buffer_output = NGX_CONF_UNSET;
- conf->sendfile = NGX_CONF_UNSET;
return conf;
}
@@ -187,7 +180,6 @@ static char *ngx_http_write_filter_merge_conf(ngx_conf_t *cf,
ngx_http_write_filter_conf_t *conf = child;
ngx_conf_merge_size_value(conf->buffer_output, prev->buffer_output, 1460);
- ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
return NULL;
}
diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c
index 9ed378dd2..adafc17cf 100644
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -77,15 +77,15 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
ce = ce->next;
}
- if (lseek(file->fd, offset, SEEK_SET) == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
- return NGX_ERROR;
+ if (file->offset != offset) {
+ if (lseek(file->fd, offset, SEEK_SET) == -1) {
+ ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "lseek() failed");
+ return NGX_ERROR;
+ }
}
n = writev(file->fd, (struct iovec *) io.elts, io.nelts);
- ngx_destroy_array(&io);
-
if (n == -1) {
ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "writev() failed");
return NGX_ERROR;
diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c
index 1632424ce..093265a33 100644
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -83,9 +83,9 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
if (ce && (ce->hunk->type & NGX_HUNK_FILE)) {
file = ce->hunk;
- ce = ce->next;
fsize = (size_t) (file->file_last - file->file_pos);
fprev = file->file_last;
+ ce = ce->next;
/* coalesce the neighbouring file hunks */