mirror of
https://github.com/nginx/nginx.git
synced 2024-12-20 14:13:33 -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;
|
ngx_file_t *file;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct ngx_chain_s ngx_chain_t;
|
typedef struct ngx_chain_s ngx_chain_t;
|
||||||
struct ngx_chain_s {
|
struct ngx_chain_s {
|
||||||
ngx_hunk_t *hunk;
|
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,
|
ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,
|
||||||
int before, int after);
|
int before, int after);
|
||||||
|
|
||||||
|
@ -141,6 +141,8 @@ int ngx_http_static_handler(ngx_http_request_t *r)
|
|||||||
if (r->header_only)
|
if (r->header_only)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
h->type = NGX_HUNK_FILE|NGX_HUNK_LAST;
|
h->type = NGX_HUNK_FILE|NGX_HUNK_LAST;
|
||||||
h->pos.file = 0;
|
h->pos.file = 0;
|
||||||
h->last.file = ngx_file_size(r->file.info);
|
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);
|
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;
|
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
|
#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) \
|
|| ((r->filter & NGX_HTTP_FILTER_NEED_TEMP) \
|
||||||
&& (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP))))
|
&& (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP))))
|
||||||
|
|
||||||
|
|
||||||
int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||||
{
|
{
|
||||||
int rc;
|
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));
|
sizeof(ngx_http_output_filter_ctx_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the incoming chain ctx->in is empty */
|
/* the short path for the case when the chain ctx->incoming is empty
|
||||||
if (ctx->in == NULL) {
|
and there is no hunk or the hunk does not require the copy */
|
||||||
|
if (ctx->incoming == NULL) {
|
||||||
|
|
||||||
if (hunk == NULL) {
|
if (hunk == NULL) {
|
||||||
return next_filter(r, NULL);
|
return next_filter(r, NULL);
|
||||||
@ -98,10 +99,28 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
|||||||
|
|
||||||
return next_filter(r, &ctx->out);
|
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 */
|
/* 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;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for (ce = ctx->incoming; ce->next; ce = ce->next) {
|
||||||
|
/* void */ ;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate our hunk if it's needed */
|
||||||
if (ctx->hunk == NULL) {
|
if (ctx->hunk == NULL) {
|
||||||
|
|
||||||
conf = (ngx_http_output_filter_conf_t *)
|
conf = (ngx_http_output_filter_conf_t *)
|
||||||
@ -123,66 +142,10 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
|||||||
NGX_ERROR);
|
NGX_ERROR);
|
||||||
|
|
||||||
ctx->hunk->type |= NGX_HUNK_RECYCLED;
|
ctx->hunk->type |= NGX_HUNK_RECYCLED;
|
||||||
}
|
|
||||||
|
|
||||||
/* copy the incoming hunk or its part to our hunk
|
|
||||||
and pass it to the next filter */
|
|
||||||
|
|
||||||
do {
|
|
||||||
rc = ngx_http_output_filter_copy_hunk(ctx->hunk, hunk);
|
|
||||||
|
|
||||||
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 */
|
/* 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);
|
rc = next_filter(r, NULL);
|
||||||
|
|
||||||
if (rc == NGX_ERROR || rc == NGX_AGAIN) {
|
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 */
|
/* NGX_OK */
|
||||||
|
|
||||||
|
/* set our hunk free */
|
||||||
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
|
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;
|
pe = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* process the incoming chain ctx->in */
|
/* process the chain ctx->incoming */
|
||||||
do {
|
do {
|
||||||
/* find the hunks that do not need to be copied ... */
|
/* 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)) {
|
if (need_to_copy(r, ce->hunk)) {
|
||||||
break;
|
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 */
|
/* ... and pass them to the next filter */
|
||||||
if (ctx->in != ce) {
|
if (ctx->incoming != ce) {
|
||||||
|
|
||||||
ctx->out.hunk = ctx->in->hunk;
|
ctx->out.hunk = ctx->incoming->hunk;
|
||||||
ctx->out.next = ctx->in->next;
|
ctx->out.next = ctx->incoming->next;
|
||||||
ctx->in = ce;
|
ctx->incoming = ce;
|
||||||
pe->next = NULL;
|
pe->next = NULL;
|
||||||
|
|
||||||
rc = next_filter(r, &ctx->out);
|
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 */
|
/* NGX_OK */
|
||||||
if (ctx->in == NULL) {
|
if (ctx->incoming == NULL) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* copy the first hunk or its part from the chain ctx->incoming
|
||||||
/* copy the first hunk or its part from the incoming chain ctx->in
|
|
||||||
to our hunk and pass it to the next filter */
|
to our hunk and pass it to the next filter */
|
||||||
do {
|
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) {
|
if (rc == NGX_ERROR) {
|
||||||
return rc;
|
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;
|
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
|
||||||
|
|
||||||
/* repeat until we will have copied the whole first hunk from
|
/* repeat until we will have copied the whole first hunk from
|
||||||
the incoming chain ctx->in */
|
the chain ctx->incoming */
|
||||||
} while (ctx->in->hunk->pos.mem < ctx->in->hunk->last.mem);
|
} while (ctx->incoming->hunk->pos.mem < ctx->incoming->hunk->last.mem);
|
||||||
|
|
||||||
/* delete the completed hunk from the incoming chain */
|
/* 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 */
|
/* repeat until we will have processed the whole chain ctx->incoming */
|
||||||
} while (ctx->in);
|
} while (ctx->incoming);
|
||||||
|
|
||||||
return NGX_OK;
|
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)
|
static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src)
|
||||||
{
|
{
|
||||||
ssize_t n, size;
|
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) {
|
if (n == NGX_ERROR) {
|
||||||
return n;
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
#if (NGX_FILE_AIO_READ)
|
#if (NGX_FILE_AIO_READ)
|
||||||
} else if (n == NGX_AGAIN) {
|
|
||||||
|
if (n == NGX_AGAIN) {
|
||||||
return n;
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} else {
|
if (n != size) {
|
||||||
ngx_assert((n == size), /* void */ ; , src->file->log,
|
ngx_log_error(NGX_LOG_ALERT, src->file->log, 0,
|
||||||
ngx_read_file_n " reads only %d of %d" _
|
ngx_read_file_n " reads only %d of %d from file",
|
||||||
n _ size);
|
n, size);
|
||||||
|
if (n == 0) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
src->pos.mem += n;
|
src->pos.mem += n;
|
||||||
|
@ -18,9 +18,10 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_hunk_t *hunk;
|
ngx_hunk_t *hunk; /* the temporary hunk to copy */
|
||||||
ngx_chain_t *in;
|
ngx_chain_t *incoming;
|
||||||
ngx_chain_t out;
|
ngx_chain_t in; /* one chain entry for input */
|
||||||
|
ngx_chain_t out; /* one chain entry for output */
|
||||||
} ngx_http_output_filter_ctx_t;
|
} ngx_http_output_filter_ctx_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||||||
{
|
{
|
||||||
int last;
|
int last;
|
||||||
off_t size, flush;
|
off_t size, flush;
|
||||||
ngx_chain_t *ch, **prev, *chain;
|
ngx_chain_t *ce, **le, *chain;
|
||||||
ngx_http_write_filter_ctx_t *ctx;
|
ngx_http_write_filter_ctx_t *ctx;
|
||||||
ngx_http_write_filter_conf_t *conf;
|
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;
|
size = flush = 0;
|
||||||
last = 0;
|
last = 0;
|
||||||
prev = &ctx->out;
|
le = &ctx->out;
|
||||||
|
|
||||||
/* find size, flush point and last link of saved chain */
|
/* find the size, the flush point and the last entry of saved chain */
|
||||||
for (ch = ctx->out; ch; ch = ch->next) {
|
for (ce = ctx->out; ce; ce = ce->next) {
|
||||||
prev = &ch->next;
|
le = &ce->next;
|
||||||
size += ch->hunk->last.file - ch->hunk->pos.file;
|
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 "
|
ngx_log_debug(r->connection->log, "write filter: old chunk: %x "
|
||||||
QX_FMT " " QD_FMT _
|
QX_FMT " " QD_FMT _
|
||||||
ch->hunk->type _ ch->hunk->pos.file _
|
ce->hunk->type _ ce->hunk->pos.file _
|
||||||
ch->hunk->last.file - ch->hunk->pos.file);
|
ce->hunk->last.file - ce->hunk->pos.file);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ch->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
|
if (ce->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
|
||||||
flush = size;
|
flush = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch->hunk->type & NGX_HUNK_LAST) {
|
if (ce->hunk->type & NGX_HUNK_LAST) {
|
||||||
last = 1;
|
last = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add new chain to existent one */
|
/* add the new chain to the existent one */
|
||||||
for (/* void */; in; in = in->next) {
|
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;
|
ce->hunk = in->hunk;
|
||||||
ch->next = NULL;
|
ce->next = NULL;
|
||||||
*prev = ch;
|
*le = ce;
|
||||||
prev = &ch->next;
|
le = &ce->next;
|
||||||
size += ch->hunk->last.file - ch->hunk->pos.file;
|
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: new chunk: %x "
|
ngx_log_debug(r->connection->log, "write filter: new hunk: %x "
|
||||||
QX_FMT " " QD_FMT _
|
QX_FMT " " QD_FMT _
|
||||||
ch->hunk->type _ ch->hunk->pos.file _
|
ce->hunk->type _ ce->hunk->pos.file _
|
||||||
ch->hunk->last.file - ch->hunk->pos.file);
|
ce->hunk->last.file - ce->hunk->pos.file);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ch->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
|
if (ce->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
|
||||||
flush = size;
|
flush = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch->hunk->type & NGX_HUNK_LAST) {
|
if (ce->hunk->type & NGX_HUNK_LAST) {
|
||||||
last = 1;
|
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_get_module_loc_conf(r->main ? r->main : r,
|
||||||
ngx_http_write_filter_module);
|
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" _
|
ngx_log_debug(r->connection->log, "write filter: last:%d flush:%d" _
|
||||||
last _ flush);
|
last _ flush);
|
||||||
#endif
|
#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) {
|
if (!last && flush == 0 && size < conf->buffer_output) {
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
chain = ngx_event_write(r->connection, ctx->out, flush);
|
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;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->out = chain;
|
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