mirror of
https://github.com/nginx/nginx.git
synced 2025-01-19 01:42:58 +08:00
nginx-0.0.1-2003-10-22-11:05:29 import
This commit is contained in:
parent
419f9aceb4
commit
5bf3d25d69
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
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;
|
||||
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);
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,14 +370,15 @@ ngx_log_debug(r->connection->log, "rc: %d" _ rc);
|
||||
}
|
||||
}
|
||||
|
||||
wcf = ngx_http_get_module_loc_conf(r, ngx_http_write_filter_module);
|
||||
|
||||
if (!(ngx_io.flags & NGX_IO_SENDFILE) || !wcf->sendfile) {
|
||||
r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
|
||||
}
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) {
|
||||
r->sendfile = 0;
|
||||
|
||||
} else {
|
||||
r->sendfile = 1;
|
||||
}
|
||||
|
||||
if (clcf->handler) {
|
||||
/*
|
||||
* if the location already has content handler then skip
|
||||
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -5,6 +5,11 @@
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user