mirror of
https://github.com/nginx/nginx.git
synced 2024-12-20 06:03:31 -06:00
nginx-0.0.1-2003-02-11-19:42:23 import
This commit is contained in:
parent
1e7ec9dcd2
commit
0a9d145c66
@ -55,6 +55,8 @@ struct ngx_hunk_s {
|
||||
ngx_file_t *file;
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef struct ngx_chain_s ngx_chain_t;
|
||||
struct ngx_chain_s {
|
||||
ngx_hunk_t *hunk;
|
||||
@ -62,6 +64,9 @@ struct ngx_chain_s {
|
||||
};
|
||||
|
||||
|
||||
#define NGX_CHAIN_ERROR (ngx_chain_t *) NGX_ERROR
|
||||
|
||||
|
||||
ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,
|
||||
int before, int after);
|
||||
|
||||
|
@ -141,6 +141,8 @@ int ngx_http_static_handler(ngx_http_request_t *r)
|
||||
if (r->header_only)
|
||||
return rc;
|
||||
|
||||
#if 0
|
||||
|
||||
h->type = NGX_HUNK_FILE|NGX_HUNK_LAST;
|
||||
h->pos.file = 0;
|
||||
h->last.file = ngx_file_size(r->file.info);
|
||||
@ -152,5 +154,42 @@ int ngx_http_static_handler(ngx_http_request_t *r)
|
||||
|
||||
ngx_log_debug(r->connection->log, "0 output_filter: %d" _ rc);
|
||||
|
||||
#else
|
||||
|
||||
#define BLK 10000
|
||||
|
||||
{
|
||||
int i, s;
|
||||
s = ngx_file_size(r->file.info);
|
||||
|
||||
for (i = 0; i < s; i += BLK) {
|
||||
ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)),
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
|
||||
ngx_test_null(h->file, ngx_pcalloc(r->pool, sizeof(ngx_file_t)),
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
|
||||
h->type = NGX_HUNK_FILE;
|
||||
if (s - i <= BLK) {
|
||||
h->type |= NGX_HUNK_LAST;
|
||||
}
|
||||
|
||||
h->pos.file = i;
|
||||
h->last.file = i + BLK;
|
||||
if (h->last.file > s) {
|
||||
h->last.file = s;
|
||||
}
|
||||
|
||||
h->file->fd = r->file.fd;
|
||||
h->file->log = r->connection->log;
|
||||
|
||||
rc = ngx_http_output_filter(r, h);
|
||||
|
||||
ngx_log_debug(r->connection->log, "0 output_filter: %d" _ rc);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -57,7 +57,6 @@ ngx_module_t ngx_http_output_filter_module = {
|
||||
};
|
||||
|
||||
|
||||
#if 1
|
||||
|
||||
#define next_filter ngx_http_output_filter_module_ctx.next_output_body_filter
|
||||
|
||||
@ -67,6 +66,7 @@ ngx_module_t ngx_http_output_filter_module = {
|
||||
|| ((r->filter & NGX_HTTP_FILTER_NEED_TEMP) \
|
||||
&& (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP))))
|
||||
|
||||
|
||||
int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||
{
|
||||
int rc;
|
||||
@ -84,8 +84,9 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||
sizeof(ngx_http_output_filter_ctx_t));
|
||||
}
|
||||
|
||||
/* the incoming chain ctx->in is empty */
|
||||
if (ctx->in == NULL) {
|
||||
/* the short path for the case when the chain ctx->incoming is empty
|
||||
and there is no hunk or the hunk does not require the copy */
|
||||
if (ctx->incoming == NULL) {
|
||||
|
||||
if (hunk == NULL) {
|
||||
return next_filter(r, NULL);
|
||||
@ -98,91 +99,53 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||
|
||||
return next_filter(r, &ctx->out);
|
||||
}
|
||||
}
|
||||
|
||||
/* we need to copy the incoming hunk to our hunk */
|
||||
/* add the incoming hunk to the chain ctx->incoming */
|
||||
if (hunk) {
|
||||
|
||||
/* allocate ctx->hunk if it's needed */
|
||||
if (ctx->hunk == NULL) {
|
||||
/* the output of the only hunk is common case so we have
|
||||
special chain entry ctx->in for it */
|
||||
if (ctx->incoming == NULL) {
|
||||
ctx->in.hunk = hunk;
|
||||
ctx->in.next = NULL;
|
||||
ctx->incoming = &ctx->in;
|
||||
|
||||
conf = (ngx_http_output_filter_conf_t *)
|
||||
ngx_http_get_module_loc_conf(r->main ? r->main : r,
|
||||
ngx_http_output_filter_module);
|
||||
} else {
|
||||
for (ce = ctx->incoming; ce->next; ce = ce->next) {
|
||||
/* void */ ;
|
||||
}
|
||||
|
||||
if (hunk->type & NGX_HUNK_LAST) {
|
||||
size = hunk->last.mem - hunk->pos.mem;
|
||||
if (size > conf->hunk_size) {
|
||||
size = conf->hunk_size;
|
||||
}
|
||||
ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/* allocate our hunk if it's needed */
|
||||
if (ctx->hunk == NULL) {
|
||||
|
||||
conf = (ngx_http_output_filter_conf_t *)
|
||||
ngx_http_get_module_loc_conf(r->main ? r->main : r,
|
||||
ngx_http_output_filter_module);
|
||||
|
||||
if (hunk->type & NGX_HUNK_LAST) {
|
||||
size = hunk->last.mem - hunk->pos.mem;
|
||||
if (size > conf->hunk_size) {
|
||||
size = conf->hunk_size;
|
||||
}
|
||||
|
||||
ngx_test_null(ctx->hunk,
|
||||
ngx_create_temp_hunk(r->pool, size, 50, 50),
|
||||
NGX_ERROR);
|
||||
|
||||
ctx->hunk->type |= NGX_HUNK_RECYCLED;
|
||||
} else {
|
||||
size = conf->hunk_size;
|
||||
}
|
||||
|
||||
/* copy the incoming hunk or its part to our hunk
|
||||
and pass it to the next filter */
|
||||
ngx_test_null(ctx->hunk,
|
||||
ngx_create_temp_hunk(r->pool, size, 50, 50),
|
||||
NGX_ERROR);
|
||||
|
||||
do {
|
||||
rc = ngx_http_output_filter_copy_hunk(ctx->hunk, hunk);
|
||||
ctx->hunk->type |= NGX_HUNK_RECYCLED;
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if (NGX_FILE_AIO_READ)
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
/* add the incoming hunk to the incoming chain */
|
||||
ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, NGX_ERROR);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
ctx->out.hunk = ctx->hunk;
|
||||
ctx->out.next = NULL;
|
||||
|
||||
rc = next_filter(r, &ctx->out);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
/* add the incoming hunk to the incoming chain */
|
||||
ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, NGX_ERROR);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* NGX_OK */
|
||||
|
||||
/* set our hunk free */
|
||||
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
|
||||
|
||||
/* repeat until we will have copied the whole incoming hunk */
|
||||
} while (hunk->pos.mem < hunk->last.mem);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
/* the incoming chain ctx->in is not empty */
|
||||
|
||||
/* add the incoming hunk to the incoming chain */
|
||||
if (hunk) {
|
||||
for (ce = ctx->in; ce->next; ce = ce->next) {
|
||||
/* void */ ;
|
||||
}
|
||||
|
||||
ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR);
|
||||
}
|
||||
|
||||
/* our hunk is still busy */
|
||||
if (ctx->hunk->pos.mem < ctx->hunk->last.mem) {
|
||||
} else if (ctx->hunk->pos.mem < ctx->hunk->last.mem) {
|
||||
rc = next_filter(r, NULL);
|
||||
|
||||
if (rc == NGX_ERROR || rc == NGX_AGAIN) {
|
||||
@ -190,6 +153,8 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||
}
|
||||
|
||||
/* NGX_OK */
|
||||
|
||||
/* set our hunk free */
|
||||
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
|
||||
}
|
||||
|
||||
@ -197,10 +162,10 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||
pe = NULL;
|
||||
#endif
|
||||
|
||||
/* process the incoming chain ctx->in */
|
||||
/* process the chain ctx->incoming */
|
||||
do {
|
||||
/* find the hunks that do not need to be copied ... */
|
||||
for (ce = ctx->in; ce; ce = ce->next) {
|
||||
for (ce = ctx->incoming; ce; ce = ce->next) {
|
||||
if (need_to_copy(r, ce->hunk)) {
|
||||
break;
|
||||
}
|
||||
@ -208,11 +173,11 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||
}
|
||||
|
||||
/* ... and pass them to the next filter */
|
||||
if (ctx->in != ce) {
|
||||
if (ctx->incoming != ce) {
|
||||
|
||||
ctx->out.hunk = ctx->in->hunk;
|
||||
ctx->out.next = ctx->in->next;
|
||||
ctx->in = ce;
|
||||
ctx->out.hunk = ctx->incoming->hunk;
|
||||
ctx->out.next = ctx->incoming->next;
|
||||
ctx->incoming = ce;
|
||||
pe->next = NULL;
|
||||
|
||||
rc = next_filter(r, &ctx->out);
|
||||
@ -222,16 +187,16 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||
}
|
||||
|
||||
/* NGX_OK */
|
||||
if (ctx->in == NULL) {
|
||||
if (ctx->incoming == NULL) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* copy the first hunk or its part from the incoming chain ctx->in
|
||||
/* copy the first hunk or its part from the chain ctx->incoming
|
||||
to our hunk and pass it to the next filter */
|
||||
do {
|
||||
rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk);
|
||||
rc = ngx_http_output_filter_copy_hunk(ctx->hunk,
|
||||
ctx->incoming->hunk);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return rc;
|
||||
@ -259,243 +224,19 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
|
||||
|
||||
/* repeat until we will have copied the whole first hunk from
|
||||
the incoming chain ctx->in */
|
||||
} while (ctx->in->hunk->pos.mem < ctx->in->hunk->last.mem);
|
||||
the chain ctx->incoming */
|
||||
} while (ctx->incoming->hunk->pos.mem < ctx->incoming->hunk->last.mem);
|
||||
|
||||
/* delete the completed hunk from the incoming chain */
|
||||
ctx->in = ctx->in->next;
|
||||
ctx->incoming = ctx->incoming->next;
|
||||
|
||||
/* repeat until we will have processed the whole incoming chain ctx->in */
|
||||
} while (ctx->in);
|
||||
/* repeat until we will have processed the whole chain ctx->incoming */
|
||||
} while (ctx->incoming);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||
{
|
||||
int rc, once;
|
||||
u_int flags;
|
||||
size_t size;
|
||||
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_http_get_module_ctx(r->main ? r->main : r,
|
||||
ngx_http_output_filter_module);
|
||||
|
||||
if (ctx == NULL) {
|
||||
ngx_http_create_ctx(r, ctx, ngx_http_output_filter_module,
|
||||
sizeof(ngx_http_output_filter_ctx_t));
|
||||
}
|
||||
|
||||
if (hunk && (hunk->type & NGX_HUNK_LAST)) {
|
||||
ctx->last = 1;
|
||||
}
|
||||
|
||||
#if (NGX_SUPPRESS_WARN)
|
||||
rc = NGX_ALERT;
|
||||
#endif
|
||||
|
||||
for (once = 1; once || ctx->in; once = 0) {
|
||||
|
||||
/* input chain is not empty */
|
||||
if (ctx->in) {
|
||||
|
||||
/* add hunk to input chain */
|
||||
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);
|
||||
}
|
||||
|
||||
/* our hunk is still busy */
|
||||
if (ctx->hunk->pos.mem < ctx->hunk->last.mem) {
|
||||
rc = ngx_http_output_filter_module_ctx.
|
||||
next_output_body_filter(r, NULL);
|
||||
|
||||
/* our hunk is free */
|
||||
} else {
|
||||
ctx->out.hunk = ctx->hunk;
|
||||
|
||||
/* XXX: should we check hunk type before copy it ? */
|
||||
rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk);
|
||||
#if (NGX_FILE_AIO_READ)
|
||||
if (rc == NGX_AGAIN) {
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
if (rc == NGX_ERROR) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* NGX_OK */
|
||||
|
||||
/* whole hunk is copied so we send to next filter chain part
|
||||
up to next hunk that need to be copied */
|
||||
if (ctx->in->hunk->pos.mem == ctx->in->hunk->last.mem) {
|
||||
ctx->out.next = ctx->in->next;
|
||||
|
||||
for (ce = ctx->in->next; ce; ce = ce->next) {
|
||||
if (ce->hunk->type & NGX_HUNK_FILE) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ce->hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP))
|
||||
&& (r->filter & NGX_HTTP_FILTER_NEED_TEMP))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->out.next = ce;
|
||||
|
||||
} else {
|
||||
ctx->out.next = NULL;
|
||||
}
|
||||
|
||||
rc = ngx_http_output_filter_module_ctx.
|
||||
next_output_body_filter(r, &ctx->out);
|
||||
}
|
||||
|
||||
/* delete completed hunks from input chain */
|
||||
for (ce = ctx->in; ce; ce = ce->next) {
|
||||
if (ce->hunk->pos.file == ce->hunk->last.file) {
|
||||
ctx->in = ce->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == NGX_OK && ctx->hunk) {
|
||||
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
|
||||
} else {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* input chain is empty */
|
||||
} else {
|
||||
|
||||
if (hunk == NULL) {
|
||||
rc = ngx_http_output_filter_module_ctx.
|
||||
next_output_body_filter(r, NULL);
|
||||
|
||||
} else {
|
||||
|
||||
/* we need to copy hunk to our hunk */
|
||||
if (((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY)
|
||||
&& (hunk->type & NGX_HUNK_FILE))
|
||||
|| ((r->filter & NGX_HTTP_FILTER_NEED_TEMP)
|
||||
&& (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP)))
|
||||
) {
|
||||
|
||||
/* out hunk is still busy */
|
||||
if (ctx->hunk && ctx->hunk->pos.mem < ctx->hunk->last.mem) {
|
||||
ngx_add_hunk_to_chain(ctx->in, hunk, r->pool,
|
||||
NGX_ERROR);
|
||||
|
||||
rc = ngx_http_output_filter_module_ctx.
|
||||
next_output_body_filter(r, NULL);
|
||||
|
||||
} else {
|
||||
if (ctx->hunk == NULL) {
|
||||
|
||||
conf = (ngx_http_output_filter_conf_t *)
|
||||
ngx_http_get_module_loc_conf(
|
||||
r->main ? r->main : r,
|
||||
ngx_http_output_filter_module);
|
||||
|
||||
if (hunk->type & NGX_HUNK_LAST) {
|
||||
size = hunk->last.mem - hunk->pos.mem;
|
||||
if (size > conf->hunk_size) {
|
||||
size = conf->hunk_size;
|
||||
}
|
||||
|
||||
} else {
|
||||
size = conf->hunk_size;
|
||||
}
|
||||
|
||||
ngx_test_null(ctx->hunk,
|
||||
ngx_create_temp_hunk(r->pool, size,
|
||||
50, 50),
|
||||
NGX_ERROR);
|
||||
ctx->hunk->type |= NGX_HUNK_RECYCLED;
|
||||
|
||||
rc = ngx_http_output_filter_copy_hunk(ctx->hunk,
|
||||
hunk);
|
||||
#if (NGX_FILE_AIO_READ)
|
||||
if (rc == NGX_AGAIN) {
|
||||
/* add hunk to input chain */
|
||||
ngx_add_hunk_to_chain(ctx->in, hunk, r->pool,
|
||||
NGX_ERROR);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
if (rc == NGX_ERROR) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (hunk->pos.mem < hunk->last.mem) {
|
||||
ngx_add_hunk_to_chain(ctx->in, hunk, r->pool,
|
||||
NGX_ERROR);
|
||||
}
|
||||
|
||||
ctx->out.hunk = ctx->hunk;
|
||||
ctx->out.next = NULL;
|
||||
|
||||
rc = ngx_http_output_filter_module_ctx.
|
||||
next_output_body_filter(r, &ctx->out);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
ctx->out.hunk = hunk;
|
||||
ctx->out.next = NULL;
|
||||
|
||||
rc = ngx_http_output_filter_module_ctx.
|
||||
next_output_body_filter(r, &ctx->out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set free our hunk if operation has completed */
|
||||
if (rc == NGX_OK && ctx->hunk) {
|
||||
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
|
||||
}
|
||||
}
|
||||
|
||||
#if (NGX_SUPPRESS_WARN)
|
||||
if (rc == NGX_ALERT) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
"ngx_http_output_filter: rc == NGX_ALERT");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rc == NGX_OK && ctx->last) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
if (ctx->hunk) { /* XXX: double upper code ? */
|
||||
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
|
||||
}
|
||||
#if (NGX_LEVEL_EVENT)
|
||||
ngx_del_event(r->connection->write, NGX_WRITE_EVENT);
|
||||
#endif
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src)
|
||||
{
|
||||
ssize_t n, size;
|
||||
@ -510,16 +251,23 @@ static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src)
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
return n;
|
||||
}
|
||||
|
||||
#if (NGX_FILE_AIO_READ)
|
||||
} else if (n == NGX_AGAIN) {
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} else {
|
||||
ngx_assert((n == size), /* void */ ; , src->file->log,
|
||||
ngx_read_file_n " reads only %d of %d" _
|
||||
n _ size);
|
||||
if (n != size) {
|
||||
ngx_log_error(NGX_LOG_ALERT, src->file->log, 0,
|
||||
ngx_read_file_n " reads only %d of %d from file",
|
||||
n, size);
|
||||
if (n == 0) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
src->pos.mem += n;
|
||||
|
@ -18,9 +18,10 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_hunk_t *hunk;
|
||||
ngx_chain_t *in;
|
||||
ngx_chain_t out;
|
||||
ngx_hunk_t *hunk; /* the temporary hunk to copy */
|
||||
ngx_chain_t *incoming;
|
||||
ngx_chain_t in; /* one chain entry for input */
|
||||
ngx_chain_t out; /* one chain entry for output */
|
||||
} ngx_http_output_filter_ctx_t;
|
||||
|
||||
|
||||
|
@ -57,9 +57,9 @@ ngx_module_t ngx_http_write_filter_module = {
|
||||
|
||||
int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
{
|
||||
int last;
|
||||
off_t size, flush;
|
||||
ngx_chain_t *ch, **prev, *chain;
|
||||
int last;
|
||||
off_t size, flush;
|
||||
ngx_chain_t *ce, **le, *chain;
|
||||
ngx_http_write_filter_ctx_t *ctx;
|
||||
ngx_http_write_filter_conf_t *conf;
|
||||
|
||||
@ -74,51 +74,51 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
|
||||
size = flush = 0;
|
||||
last = 0;
|
||||
prev = &ctx->out;
|
||||
le = &ctx->out;
|
||||
|
||||
/* find size, flush point and last link of saved chain */
|
||||
for (ch = ctx->out; ch; ch = ch->next) {
|
||||
prev = &ch->next;
|
||||
size += ch->hunk->last.file - ch->hunk->pos.file;
|
||||
/* find the size, the flush point and the last entry of saved chain */
|
||||
for (ce = ctx->out; ce; ce = ce->next) {
|
||||
le = &ce->next;
|
||||
size += ce->hunk->last.file - ce->hunk->pos.file;
|
||||
|
||||
#if (NGX_DEBUG_WRITE_FILTER)
|
||||
#if (NGX_DEBUG_WRITE_FILTER0)
|
||||
ngx_log_debug(r->connection->log, "write filter: old chunk: %x "
|
||||
QX_FMT " " QD_FMT _
|
||||
ch->hunk->type _ ch->hunk->pos.file _
|
||||
ch->hunk->last.file - ch->hunk->pos.file);
|
||||
ce->hunk->type _ ce->hunk->pos.file _
|
||||
ce->hunk->last.file - ce->hunk->pos.file);
|
||||
#endif
|
||||
|
||||
if (ch->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
|
||||
if (ce->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
|
||||
flush = size;
|
||||
}
|
||||
|
||||
if (ch->hunk->type & NGX_HUNK_LAST) {
|
||||
if (ce->hunk->type & NGX_HUNK_LAST) {
|
||||
last = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* add new chain to existent one */
|
||||
/* add the new chain to the existent one */
|
||||
for (/* void */; in; in = in->next) {
|
||||
ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), NGX_ERROR);
|
||||
ngx_test_null(ce, ngx_palloc(r->pool, sizeof(ngx_chain_t)), NGX_ERROR);
|
||||
|
||||
ch->hunk = in->hunk;
|
||||
ch->next = NULL;
|
||||
*prev = ch;
|
||||
prev = &ch->next;
|
||||
size += ch->hunk->last.file - ch->hunk->pos.file;
|
||||
ce->hunk = in->hunk;
|
||||
ce->next = NULL;
|
||||
*le = ce;
|
||||
le = &ce->next;
|
||||
size += ce->hunk->last.file - ce->hunk->pos.file;
|
||||
|
||||
#if (NGX_DEBUG_WRITE_FILTER)
|
||||
ngx_log_debug(r->connection->log, "write filter: new chunk: %x "
|
||||
#if (NGX_DEBUG_WRITE_FILTER0)
|
||||
ngx_log_debug(r->connection->log, "write filter: new hunk: %x "
|
||||
QX_FMT " " QD_FMT _
|
||||
ch->hunk->type _ ch->hunk->pos.file _
|
||||
ch->hunk->last.file - ch->hunk->pos.file);
|
||||
ce->hunk->type _ ce->hunk->pos.file _
|
||||
ce->hunk->last.file - ce->hunk->pos.file);
|
||||
#endif
|
||||
|
||||
if (ch->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
|
||||
if (ce->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
|
||||
flush = size;
|
||||
}
|
||||
|
||||
if (ch->hunk->type & NGX_HUNK_LAST) {
|
||||
if (ce->hunk->type & NGX_HUNK_LAST) {
|
||||
last = 1;
|
||||
}
|
||||
}
|
||||
@ -127,25 +127,35 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
ngx_http_get_module_loc_conf(r->main ? r->main : r,
|
||||
ngx_http_write_filter_module);
|
||||
|
||||
#if (NGX_DEBUG_WRITE_FILTER)
|
||||
#if (NGX_DEBUG_WRITE_FILTER0)
|
||||
ngx_log_debug(r->connection->log, "write filter: last:%d flush:%d" _
|
||||
last _ flush);
|
||||
#endif
|
||||
|
||||
/* avoid the output if there is no last hunk, no flush point and
|
||||
size of the hunks is smaller then 'write_buffer' */
|
||||
if (!last && flush == 0 && size < conf->buffer_output) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
chain = ngx_event_write(r->connection, ctx->out, flush);
|
||||
if (chain == (ngx_chain_t *) -1) {
|
||||
|
||||
#if (NGX_DEBUG_WRITE_FILTER)
|
||||
ngx_log_debug(r->connection->log, "write filter %x" _ chain);
|
||||
#endif
|
||||
|
||||
if (chain == NGX_CHAIN_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ctx->out = chain;
|
||||
|
||||
ngx_log_debug(r->connection->log, "write filter %x" _ chain);
|
||||
if (chain == NULL) {
|
||||
return NGX_OK;
|
||||
|
||||
return (chain ? NGX_AGAIN : NGX_OK);
|
||||
} else {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user