mirror of
https://github.com/nginx/nginx.git
synced 2025-06-07 17:52:38 +08:00
nginx-0.0.1-2003-10-21-20:49:56 import
This commit is contained in:
parent
9760a1336f
commit
419f9aceb4
@ -147,18 +147,6 @@ void ngx_chain_update_chains(ngx_chain_t **free, ngx_chain_t **busy,
|
|||||||
if (ngx_hunk_size((*busy)->hunk) > 0) {
|
if (ngx_hunk_size((*busy)->hunk) > 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
if ((*busy)->hunk->type & NGX_HUNK_IN_MEMORY) {
|
|
||||||
if ((*busy)->hunk->pos != (*busy)->hunk->last) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if ((*busy)->hunk->file_pos != (*busy)->hunk->file_last) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (HAVE_WRITE_ZEROCOPY)
|
#if (HAVE_WRITE_ZEROCOPY)
|
||||||
if ((*busy)->hunk->type & NGX_HUNK_ZEROCOPY_BUSY) {
|
if ((*busy)->hunk->type & NGX_HUNK_ZEROCOPY_BUSY) {
|
||||||
|
@ -2,29 +2,33 @@
|
|||||||
#include <ngx_config.h>
|
#include <ngx_config.h>
|
||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
#include <ngx_event.h>
|
#include <ngx_event.h>
|
||||||
#include <ngx_event_proxy.h>
|
#include <ngx_event_pipe.h>
|
||||||
|
|
||||||
static int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p);
|
|
||||||
|
static int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p);
|
||||||
|
static 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);
|
||||||
ngx_inline static void ngx_remove_shadow_links(ngx_hunk_t *hunk);
|
ngx_inline static void ngx_remove_shadow_links(ngx_hunk_t *hunk);
|
||||||
ngx_inline static void ngx_remove_shadow_free_raw_hunk(ngx_chain_t **free,
|
ngx_inline static void ngx_remove_shadow_free_raw_hunk(ngx_chain_t **free,
|
||||||
ngx_hunk_t *h);
|
ngx_hunk_t *h);
|
||||||
ngx_inline static void ngx_add_after_partially_filled_hunk(ngx_chain_t **chain,
|
ngx_inline static void ngx_add_after_partially_filled_hunk(ngx_chain_t **chain,
|
||||||
ngx_chain_t *ce);
|
ngx_chain_t *ce);
|
||||||
static int ngx_drain_chains(ngx_event_proxy_t *p);
|
static int ngx_drain_chains(ngx_event_pipe_t *p);
|
||||||
|
|
||||||
|
|
||||||
int ngx_event_proxy(ngx_event_proxy_t *p, int do_write)
|
int ngx_event_pipe(ngx_event_pipe_t *p, int do_write)
|
||||||
{
|
{
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
if (do_write) {
|
if (do_write) {
|
||||||
if (ngx_event_proxy_write_to_downstream(p) == NGX_ABORT) {
|
if (ngx_event_pipe_write_to_downstream(p) == NGX_ABORT) {
|
||||||
return NGX_ABORT;
|
return NGX_ABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p->read = 0;
|
p->read = 0;
|
||||||
|
|
||||||
if (ngx_event_proxy_read_upstream(p) == NGX_ABORT) {
|
if (ngx_event_pipe_read_upstream(p) == NGX_ABORT) {
|
||||||
return NGX_ABORT;
|
return NGX_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +52,7 @@ int ngx_event_proxy(ngx_event_proxy_t *p, int do_write)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ngx_event_proxy_read_upstream(ngx_event_proxy_t *p)
|
int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
|
||||||
{
|
{
|
||||||
int n, rc, size;
|
int n, rc, size;
|
||||||
ngx_hunk_t *h;
|
ngx_hunk_t *h;
|
||||||
@ -116,7 +120,6 @@ int ngx_event_proxy_read_upstream(ngx_event_proxy_t *p)
|
|||||||
|
|
||||||
chain = p->free_raw_hunks;
|
chain = p->free_raw_hunks;
|
||||||
p->free_raw_hunks = NULL;
|
p->free_raw_hunks = NULL;
|
||||||
ngx_log_debug(p->log, "FREE: %08X:%d" _ chain->hunk->pos _ chain->hunk->end - chain->hunk->last);
|
|
||||||
|
|
||||||
} else if (p->hunks < p->bufs.num) {
|
} else if (p->hunks < p->bufs.num) {
|
||||||
|
|
||||||
@ -133,22 +136,22 @@ ngx_log_debug(p->log, "FREE: %08X:%d" _ chain->hunk->pos _ chain->hunk->end - ch
|
|||||||
} else if (!p->cachable && p->downstream->write->ready) {
|
} else if (!p->cachable && p->downstream->write->ready) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the hunks are not needed to be saved in a cache and
|
* if the hunks are not needed to be saved in a cache and
|
||||||
* a downstream is ready then write the hunks to a downstream.
|
* a downstream is ready then write the hunks to a downstream
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ngx_log_debug(p->log, "downstream ready");
|
ngx_log_debug(p->log, "downstream ready");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} else if (p->temp_offset < p->max_temp_file_size) {
|
} else if (p->cachable || p->temp_offset < p->max_temp_file_size) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If it's allowed then save some hunks from r->in
|
* if it's allowed then save some hunks from r->in
|
||||||
* to a temporary file, and add them to a r->out chain.
|
* to a temporary file, and add them to a r->out chain
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rc = ngx_event_proxy_write_chain_to_temp_file(p);
|
rc = ngx_event_pipe_write_chain_to_temp_file(p);
|
||||||
|
|
||||||
ngx_log_debug(p->log, "temp offset: %d" _ p->temp_offset);
|
ngx_log_debug(p->log, "temp offset: %d" _ p->temp_offset);
|
||||||
|
|
||||||
@ -223,9 +226,7 @@ ngx_log_debug(p->log, "FREE: %08X:%d" _ chain->hunk->pos _ chain->hunk->end - ch
|
|||||||
ce = ce->next;
|
ce = ce->next;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ngx_log_debug(p->log, "PART: %08X:%d:%d" _ ce->hunk->pos _ ce->hunk->last - ce->hunk->pos _ n);
|
|
||||||
ce->hunk->last += n;
|
ce->hunk->last += n;
|
||||||
ngx_log_debug(p->log, "PART: %08X:%d" _ ce->hunk->pos _ ce->hunk->end - ce->hunk->last);
|
|
||||||
n = 0;
|
n = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,7 +244,7 @@ ngx_log_debug(p->log, "PART: %08X:%d" _ ce->hunk->pos _ ce->hunk->end - ce->hunk
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (p->cachable && p->in) {
|
if (p->cachable && p->in) {
|
||||||
if (ngx_event_proxy_write_chain_to_temp_file(p) == NGX_ABORT) {
|
if (ngx_event_pipe_write_chain_to_temp_file(p) == NGX_ABORT) {
|
||||||
return NGX_ABORT;
|
return NGX_ABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,11 +253,11 @@ ngx_log_debug(p->log, "PART: %08X:%d" _ ce->hunk->pos _ ce->hunk->end - ce->hunk
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p)
|
int ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
|
||||||
{
|
{
|
||||||
size_t busy_len;
|
size_t busy_len;
|
||||||
ngx_hunk_t *h;
|
ngx_hunk_t *h;
|
||||||
ngx_chain_t *out, *ce, *te;
|
ngx_chain_t *out, **le, *ce, *te;
|
||||||
|
|
||||||
ngx_log_debug(p->log, "write downstream: %d" _ p->downstream->write->ready);
|
ngx_log_debug(p->log, "write downstream: %d" _ p->downstream->write->ready);
|
||||||
|
|
||||||
@ -285,38 +286,47 @@ int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out = NULL;
|
||||||
|
le = NULL;
|
||||||
|
|
||||||
if (p->out) {
|
for ( ;; ) {
|
||||||
out = p->out;
|
if (p->out) {
|
||||||
|
ce = p->out;
|
||||||
|
|
||||||
if (!(p->upstream_eof || p->upstream_error || p->upstream_done)
|
if (!(p->upstream_eof || p->upstream_error || p->upstream_done)
|
||||||
&& (busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len))
|
&& (busy_len + ngx_hunk_size(ce->hunk) > p->max_busy_len))
|
||||||
{
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->out = p->out->next;
|
||||||
|
ngx_remove_shadow_free_raw_hunk(&p->free_raw_hunks, ce->hunk);
|
||||||
|
|
||||||
|
} else if (!p->cachable && p->in) {
|
||||||
|
ce = p->in;
|
||||||
|
|
||||||
|
if (!(p->upstream_eof || p->upstream_error || p->upstream_done)
|
||||||
|
&& (busy_len + ngx_hunk_size(ce->hunk) > p->max_busy_len))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->in = p->in->next;
|
||||||
|
|
||||||
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->out = p->out->next;
|
busy_len += ngx_hunk_size(ce->hunk);
|
||||||
ngx_remove_shadow_free_raw_hunk(&p->free_raw_hunks, out->hunk);
|
ce->next = NULL;
|
||||||
|
ngx_chain_add_ce(out, le, ce);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (!p->cachable && p->in) {
|
if (out == NULL) {
|
||||||
out = p->in;
|
|
||||||
|
|
||||||
if (!(p->upstream_eof || p->upstream_error || p->upstream_done)
|
|
||||||
&& (busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->in = p->in->next;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out->next = NULL;
|
if (p->output_filter(p->output_ctx, out) == NGX_ERROR) {
|
||||||
|
|
||||||
|
|
||||||
if (p->output_filter(p->output_ctx, out->hunk) == NGX_ERROR) {
|
|
||||||
p->downstream_error = 1;
|
p->downstream_error = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -326,7 +336,6 @@ int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p)
|
|||||||
/* add the free shadow raw hunks to p->free_raw_hunks */
|
/* add the free shadow raw hunks to p->free_raw_hunks */
|
||||||
|
|
||||||
for (ce = p->free; ce; ce = ce->next) {
|
for (ce = p->free; ce; ce = ce->next) {
|
||||||
ngx_log_debug(p->log, "SHADOW %08X" _ ce->hunk->shadow);
|
|
||||||
if (ce->hunk->type & NGX_HUNK_LAST_SHADOW) {
|
if (ce->hunk->type & NGX_HUNK_LAST_SHADOW) {
|
||||||
h = ce->hunk->shadow;
|
h = ce->hunk->shadow;
|
||||||
/* THINK NEEDED ??? */ h->pos = h->last = h->start;
|
/* THINK NEEDED ??? */ h->pos = h->last = h->start;
|
||||||
@ -334,31 +343,21 @@ ngx_log_debug(p->log, "SHADOW %08X" _ ce->hunk->shadow);
|
|||||||
ngx_alloc_ce_and_set_hunk(te, h, p->pool, NGX_ABORT);
|
ngx_alloc_ce_and_set_hunk(te, h, p->pool, NGX_ABORT);
|
||||||
ngx_add_after_partially_filled_hunk(&p->free_raw_hunks, te);
|
ngx_add_after_partially_filled_hunk(&p->free_raw_hunks, te);
|
||||||
|
|
||||||
ngx_log_debug(p->log, "RAW %08X" _ h->pos);
|
|
||||||
|
|
||||||
ce->hunk->type &= ~NGX_HUNK_LAST_SHADOW;
|
ce->hunk->type &= ~NGX_HUNK_LAST_SHADOW;
|
||||||
}
|
}
|
||||||
ce->hunk->shadow = NULL;
|
ce->hunk->shadow = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug(p->log, "STATE %d:%d:%d:%X:%X" _
|
|
||||||
p->upstream_eof _
|
|
||||||
p->upstream_error _
|
|
||||||
p->upstream_done _
|
|
||||||
p->in _
|
|
||||||
p->out
|
|
||||||
);
|
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_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, hunk_size;
|
||||||
ngx_hunk_t *h;
|
ngx_hunk_t *h;
|
||||||
ngx_chain_t *ce, *te, *next, *in, **le, **last_free;
|
ngx_chain_t *ce, *te, *next, *out, **le, **last_free;
|
||||||
|
|
||||||
ngx_log_debug(p->log, "write to file");
|
ngx_log_debug(p->log, "write to file");
|
||||||
|
|
||||||
@ -379,6 +378,8 @@ static int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out = p->in;
|
||||||
|
|
||||||
if (!p->cachable) {
|
if (!p->cachable) {
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
@ -407,21 +408,21 @@ ngx_log_debug(p->log, "hunk size: %d" _ hunk_size);
|
|||||||
ngx_log_debug(p->log, "size: %d" _ size);
|
ngx_log_debug(p->log, "size: %d" _ size);
|
||||||
|
|
||||||
if (ce) {
|
if (ce) {
|
||||||
in = ce;
|
p->in = ce;
|
||||||
*le = NULL;
|
*le = NULL;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
in = NULL;
|
p->in = NULL;
|
||||||
p->last_in = &p->in;
|
p->last_in = &p->in;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
in = NULL;
|
p->in = NULL;
|
||||||
p->last_in = &p->in;
|
p->last_in = &p->in;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_write_chain_to_file(p->temp_file, p->in, p->temp_offset,
|
if (ngx_write_chain_to_file(p->temp_file, out, p->temp_offset,
|
||||||
p->pool) == NGX_ERROR) {
|
p->pool) == NGX_ERROR) {
|
||||||
return NGX_ABORT;
|
return NGX_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,7 +433,7 @@ ngx_log_debug(p->log, "size: %d" _ size);
|
|||||||
/* void */
|
/* void */
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ce = p->in; ce; ce = next) {
|
for (ce = out; ce; ce = next) {
|
||||||
next = ce->next;
|
next = ce->next;
|
||||||
ce->next = NULL;
|
ce->next = NULL;
|
||||||
|
|
||||||
@ -453,15 +454,13 @@ ngx_log_debug(p->log, "size: %d" _ size);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p->in = in;
|
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* the copy input filter */
|
/* the copy input filter */
|
||||||
|
|
||||||
int ngx_event_proxy_copy_input_filter(ngx_event_proxy_t *p, ngx_hunk_t *hunk)
|
int ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_hunk_t *hunk)
|
||||||
{
|
{
|
||||||
ngx_hunk_t *h;
|
ngx_hunk_t *h;
|
||||||
ngx_chain_t *ce;
|
ngx_chain_t *ce;
|
||||||
@ -567,7 +566,7 @@ ngx_inline static void ngx_add_after_partially_filled_hunk(ngx_chain_t **chain,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ngx_drain_chains(ngx_event_proxy_t *p)
|
static int ngx_drain_chains(ngx_event_pipe_t *p)
|
||||||
{
|
{
|
||||||
ngx_hunk_t *h;
|
ngx_hunk_t *h;
|
||||||
ngx_chain_t *ce, *te;
|
ngx_chain_t *ce, *te;
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef _NGX_EVENT_PROXY_H_INCLUDED_
|
#ifndef _NGX_EVENT_PIPE_H_INCLUDED_
|
||||||
#define _NGX_EVENT_PROXY_H_INCLUDED_
|
#define _NGX_EVENT_PIPE_H_INCLUDED_
|
||||||
|
|
||||||
|
|
||||||
#include <ngx_config.h>
|
#include <ngx_config.h>
|
||||||
@ -7,14 +7,14 @@
|
|||||||
#include <ngx_event.h>
|
#include <ngx_event.h>
|
||||||
|
|
||||||
|
|
||||||
typedef struct ngx_event_proxy_s ngx_event_proxy_t;
|
typedef struct ngx_event_pipe_s ngx_event_pipe_t;
|
||||||
|
|
||||||
typedef int (*ngx_event_proxy_input_filter_pt)(ngx_event_proxy_t *p,
|
typedef int (*ngx_event_pipe_input_filter_pt)(ngx_event_pipe_t *p,
|
||||||
ngx_hunk_t *hunk);
|
ngx_hunk_t *hunk);
|
||||||
typedef int (*ngx_event_proxy_output_filter_pt)(void *data, ngx_hunk_t *hunk);
|
typedef int (*ngx_event_pipe_output_filter_pt)(void *data, ngx_chain_t *chain);
|
||||||
|
|
||||||
|
|
||||||
struct ngx_event_proxy_s {
|
struct ngx_event_pipe_s {
|
||||||
ngx_chain_t *free_raw_hunks;
|
ngx_chain_t *free_raw_hunks;
|
||||||
ngx_chain_t *in;
|
ngx_chain_t *in;
|
||||||
ngx_chain_t **last_in;
|
ngx_chain_t **last_in;
|
||||||
@ -30,10 +30,10 @@ struct ngx_event_proxy_s {
|
|||||||
* from the raw hunks to an incoming chain
|
* from the raw hunks to an incoming chain
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ngx_event_proxy_input_filter_pt input_filter;
|
ngx_event_pipe_input_filter_pt input_filter;
|
||||||
void *input_ctx;
|
void *input_ctx;
|
||||||
|
|
||||||
ngx_event_proxy_output_filter_pt output_filter;
|
ngx_event_pipe_output_filter_pt output_filter;
|
||||||
void *output_ctx;
|
void *output_ctx;
|
||||||
|
|
||||||
unsigned read:1;
|
unsigned read:1;
|
||||||
@ -68,12 +68,8 @@ struct ngx_event_proxy_s {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int ngx_event_proxy(ngx_event_proxy_t *p, int do_write);
|
int ngx_event_pipe(ngx_event_pipe_t *p, int do_write);
|
||||||
int ngx_event_proxy_copy_input_filter(ngx_event_proxy_t *p, ngx_hunk_t *hunk);
|
int ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_hunk_t *hunk);
|
||||||
|
|
||||||
/* STUB */
|
|
||||||
int ngx_event_proxy_read_upstream(ngx_event_proxy_t *p);
|
|
||||||
int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _NGX_EVENT_PROXY_H_INCLUDED_ */
|
#endif /* _NGX_EVENT_PIPE_H_INCLUDED_ */
|
@ -39,7 +39,7 @@ static int ngx_http_chunked_header_filter(ngx_http_request_t *r)
|
|||||||
return next_header_filter(r);
|
return next_header_filter(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->headers_out.content_length == -1) {
|
if (r->headers_out.content_length_n == -1) {
|
||||||
if (r->http_version < NGX_HTTP_VERSION_11) {
|
if (r->http_version < NGX_HTTP_VERSION_11) {
|
||||||
r->keepalive = 0;
|
r->keepalive = 0;
|
||||||
|
|
||||||
|
@ -157,8 +157,9 @@ static int ngx_http_gzip_header_filter(ngx_http_request_t *r)
|
|||||||
r->headers_out.content_encoding->value.len = 4;
|
r->headers_out.content_encoding->value.len = 4;
|
||||||
r->headers_out.content_encoding->value.data = "gzip";
|
r->headers_out.content_encoding->value.data = "gzip";
|
||||||
|
|
||||||
ctx->length = r->headers_out.content_length;
|
ctx->length = r->headers_out.content_length_n;
|
||||||
r->headers_out.content_length = -1;
|
r->headers_out.content_length_n = -1;
|
||||||
|
r->headers_out.content_length = NULL;
|
||||||
r->filter |= NGX_HTTP_FILTER_NEED_IN_MEMORY;
|
r->filter |= NGX_HTTP_FILTER_NEED_IN_MEMORY;
|
||||||
|
|
||||||
return next_header_filter(r);
|
return next_header_filter(r);
|
||||||
|
@ -54,7 +54,8 @@ static int ngx_http_not_modified_header_filter(ngx_http_request_t *r)
|
|||||||
|
|
||||||
if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) {
|
if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) {
|
||||||
r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
|
r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
|
||||||
r->headers_out.content_length = -1;
|
r->headers_out.content_length_n = -1;
|
||||||
|
r->headers_out.content_length = NULL;
|
||||||
r->headers_out.content_type->key.len = 0;
|
r->headers_out.content_type->key.len = 0;
|
||||||
r->headers_out.content_type = NULL;
|
r->headers_out.content_type = NULL;
|
||||||
r->headers_out.accept_ranges->key.len = 0;
|
r->headers_out.accept_ranges->key.len = 0;
|
||||||
|
@ -49,7 +49,7 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||||||
if (r->main
|
if (r->main
|
||||||
|| r->http_version < NGX_HTTP_VERSION_10
|
|| r->http_version < NGX_HTTP_VERSION_10
|
||||||
|| r->headers_out.status != NGX_HTTP_OK
|
|| r->headers_out.status != NGX_HTTP_OK
|
||||||
|| r->headers_out.content_length == -1
|
|| r->headers_out.content_length_n == -1
|
||||||
/* STUB: we currently support ranges for file hunks only */
|
/* STUB: we currently support ranges for file hunks only */
|
||||||
|| r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY)
|
|| r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY)
|
||||||
{
|
{
|
||||||
@ -103,7 +103,7 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start >= r->headers_out.content_length) {
|
if (start >= r->headers_out.content_length_n) {
|
||||||
rc = NGX_HTTP_RANGE_NOT_SATISFIABLE;
|
rc = NGX_HTTP_RANGE_NOT_SATISFIABLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||||||
ngx_test_null(range, ngx_push_array(&r->headers_out.ranges),
|
ngx_test_null(range, ngx_push_array(&r->headers_out.ranges),
|
||||||
NGX_ERROR);
|
NGX_ERROR);
|
||||||
range->start = start;
|
range->start = start;
|
||||||
range->end = r->headers_out.content_length;
|
range->end = r->headers_out.content_length_n;
|
||||||
|
|
||||||
if (*p++ == ',') {
|
if (*p++ == ',') {
|
||||||
continue;
|
continue;
|
||||||
@ -139,7 +139,7 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end >= r->headers_out.content_length || start >= end) {
|
if (end >= r->headers_out.content_length_n || start >= end) {
|
||||||
rc = NGX_HTTP_RANGE_NOT_SATISFIABLE;
|
rc = NGX_HTTP_RANGE_NOT_SATISFIABLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -170,9 +170,10 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||||||
r->headers_out.content_range->value.len =
|
r->headers_out.content_range->value.len =
|
||||||
ngx_snprintf(r->headers_out.content_range->value.data,
|
ngx_snprintf(r->headers_out.content_range->value.data,
|
||||||
8 + 20 + 1, "bytes */" OFF_FMT,
|
8 + 20 + 1, "bytes */" OFF_FMT,
|
||||||
r->headers_out.content_length);
|
r->headers_out.content_length_n);
|
||||||
|
|
||||||
r->headers_out.content_length = -1;
|
r->headers_out.content_length_n = -1;
|
||||||
|
r->headers_out.content_length = NULL;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@ -193,9 +194,9 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||||||
6 + 20 + 1 + 20 + 1 + 20 + 1,
|
6 + 20 + 1 + 20 + 1 + 20 + 1,
|
||||||
"bytes " OFF_FMT "-" OFF_FMT "/" OFF_FMT,
|
"bytes " OFF_FMT "-" OFF_FMT "/" OFF_FMT,
|
||||||
range->start, range->end - 1,
|
range->start, range->end - 1,
|
||||||
r->headers_out.content_length);
|
r->headers_out.content_length_n);
|
||||||
|
|
||||||
r->headers_out.content_length = range->end - range->start;
|
r->headers_out.content_length_n = range->end - range->start;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -267,13 +268,14 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||||||
20 + 1 + 20 + 1 + 20 + 5,
|
20 + 1 + 20 + 1 + 20 + 5,
|
||||||
OFF_FMT "-" OFF_FMT "/" OFF_FMT CRLF CRLF,
|
OFF_FMT "-" OFF_FMT "/" OFF_FMT CRLF CRLF,
|
||||||
range[i].start, range[i].end - 1,
|
range[i].start, range[i].end - 1,
|
||||||
r->headers_out.content_length);
|
r->headers_out.content_length_n);
|
||||||
|
|
||||||
len += ctx->boundary_header.len + range[i].content_range.len
|
len += ctx->boundary_header.len + range[i].content_range.len
|
||||||
+ (size_t) (range[i].end - range[i].start);
|
+ (size_t) (range[i].end - range[i].start);
|
||||||
}
|
}
|
||||||
|
|
||||||
r->headers_out.content_length = len;
|
r->headers_out.content_length_n = len;
|
||||||
|
r->headers_out.content_length = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +191,7 @@ static int ngx_http_static_handler(ngx_http_request_t *r)
|
|||||||
ngx_log_e level;
|
ngx_log_e level;
|
||||||
ngx_err_t err;
|
ngx_err_t err;
|
||||||
ngx_hunk_t *h;
|
ngx_hunk_t *h;
|
||||||
|
ngx_chain_t out;
|
||||||
ngx_http_type_t *type;
|
ngx_http_type_t *type;
|
||||||
ngx_http_log_ctx_t *ctx;
|
ngx_http_log_ctx_t *ctx;
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
@ -257,7 +258,7 @@ static int ngx_http_static_handler(ngx_http_request_t *r)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
r->headers_out.status = NGX_HTTP_OK;
|
r->headers_out.status = NGX_HTTP_OK;
|
||||||
r->headers_out.content_length = ngx_file_size(r->file.info);
|
r->headers_out.content_length_n = ngx_file_size(r->file.info);
|
||||||
r->headers_out.last_modified_time = ngx_file_mtime(r->file.info);
|
r->headers_out.last_modified_time = ngx_file_mtime(r->file.info);
|
||||||
|
|
||||||
ngx_test_null(r->headers_out.content_type,
|
ngx_test_null(r->headers_out.content_type,
|
||||||
@ -317,7 +318,10 @@ static int ngx_http_static_handler(ngx_http_request_t *r)
|
|||||||
h->file->fd = r->file.fd;
|
h->file->fd = r->file.fd;
|
||||||
h->file->log = r->connection->log;
|
h->file->log = r->connection->log;
|
||||||
|
|
||||||
return ngx_http_output_filter(r, h);
|
out.hunk = h;
|
||||||
|
out.next = NULL;
|
||||||
|
|
||||||
|
return ngx_http_output_filter(r, &out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
#include <ngx_config.h>
|
#include <ngx_config.h>
|
||||||
#include <ngx_core.h>
|
#include <ngx_core.h>
|
||||||
#include <ngx_event.h>
|
#include <ngx_event.h>
|
||||||
/* STUB */ #include <ngx_event_connect.h>
|
#include <ngx_event_connect.h>
|
||||||
/* STUB */ #include <ngx_event_proxy.h>
|
#include <ngx_event_pipe.h>
|
||||||
#include <ngx_http.h>
|
#include <ngx_http.h>
|
||||||
#include <ngx_http_proxy_handler.h>
|
#include <ngx_http_proxy_handler.h>
|
||||||
|
|
||||||
@ -632,12 +632,13 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
|
|||||||
{
|
{
|
||||||
int rc, i;
|
int rc, i;
|
||||||
ngx_table_elt_t *ch, *ph;
|
ngx_table_elt_t *ch, *ph;
|
||||||
ngx_event_proxy_t *ep;
|
ngx_event_pipe_t *ep;
|
||||||
ngx_http_request_t *r;
|
ngx_http_request_t *r;
|
||||||
|
|
||||||
r = p->request;
|
r = p->request;
|
||||||
|
|
||||||
r->headers_out.content_length = -1;
|
r->headers_out.content_length_n = -1;
|
||||||
|
r->headers_out.content_length = NULL;
|
||||||
|
|
||||||
/* copy an upstream header to r->headers_out */
|
/* copy an upstream header to r->headers_out */
|
||||||
|
|
||||||
@ -655,13 +656,6 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (&ph[i] == p->headers_in.content_length) {
|
|
||||||
r->headers_out.content_length =
|
|
||||||
ngx_atoi(p->headers_in.content_length->value.data,
|
|
||||||
p->headers_in.content_length->value.len);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ch = ngx_push_table(r->headers_out.headers);
|
ch = ngx_push_table(r->headers_out.headers);
|
||||||
if (ch == NULL) {
|
if (ch == NULL) {
|
||||||
ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||||
@ -675,6 +669,14 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
|
|||||||
r->headers_out.content_type->key.len = 0;
|
r->headers_out.content_type->key.len = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (&ph[i] == p->headers_in.content_length) {
|
||||||
|
r->headers_out.content_length_n =
|
||||||
|
ngx_atoi(p->headers_in.content_length->value.data,
|
||||||
|
p->headers_in.content_length->value.len);
|
||||||
|
r->headers_out.content_length = ch;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* STUB */
|
/* STUB */
|
||||||
@ -700,14 +702,14 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
|
|||||||
|
|
||||||
p->header_sent = 1;
|
p->header_sent = 1;
|
||||||
|
|
||||||
ep = ngx_pcalloc(r->pool, sizeof(ngx_event_proxy_t));
|
ep = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
|
||||||
if (ep == NULL) {
|
if (ep == NULL) {
|
||||||
ngx_http_proxy_finalize_request(p, 0);
|
ngx_http_proxy_finalize_request(p, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ep->input_filter = ngx_event_proxy_copy_input_filter;
|
ep->input_filter = ngx_event_pipe_copy_input_filter;
|
||||||
ep->output_filter = (ngx_event_proxy_output_filter_pt)
|
ep->output_filter = (ngx_event_pipe_output_filter_pt)
|
||||||
ngx_http_output_filter;
|
ngx_http_output_filter;
|
||||||
ep->output_ctx = r;
|
ep->output_ctx = r;
|
||||||
ep->bufs = p->lcf->bufs;
|
ep->bufs = p->lcf->bufs;
|
||||||
@ -743,14 +745,17 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
|
|||||||
ep->preread_size = p->header_in->last - p->header_in->pos;
|
ep->preread_size = p->header_in->last - p->header_in->pos;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* event_proxy would do p->header_in->last += ep->preread_size
|
* event_pipe would do p->header_in->last += ep->preread_size
|
||||||
* as these bytes were read.
|
* as though these bytes were read.
|
||||||
*/
|
*/
|
||||||
p->header_in->last = p->header_in->pos;
|
p->header_in->last = p->header_in->pos;
|
||||||
|
|
||||||
/* STUB */ ep->cachable = 0;
|
/* STUB */ ep->cachable = 1;
|
||||||
|
#if 0
|
||||||
|
ep->max_temp_file_size = 1000000000;
|
||||||
|
#endif
|
||||||
|
|
||||||
p->event_proxy = ep;
|
p->event_pipe = ep;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
lcx = p->log->data;
|
lcx = p->log->data;
|
||||||
@ -771,7 +776,7 @@ static void ngx_http_proxy_process_body(ngx_event_t *ev)
|
|||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
ngx_http_request_t *r;
|
ngx_http_request_t *r;
|
||||||
ngx_http_proxy_ctx_t *p;
|
ngx_http_proxy_ctx_t *p;
|
||||||
ngx_event_proxy_t *ep;
|
ngx_event_pipe_t *ep;
|
||||||
|
|
||||||
c = ev->data;
|
c = ev->data;
|
||||||
|
|
||||||
@ -786,7 +791,7 @@ static void ngx_http_proxy_process_body(ngx_event_t *ev)
|
|||||||
r = p->request;
|
r = p->request;
|
||||||
}
|
}
|
||||||
|
|
||||||
ep = p->event_proxy;
|
ep = p->event_pipe;
|
||||||
|
|
||||||
if (ev->timedout) {
|
if (ev->timedout) {
|
||||||
if (ev->write) {
|
if (ev->write) {
|
||||||
@ -797,7 +802,7 @@ static void ngx_http_proxy_process_body(ngx_event_t *ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (ngx_event_proxy(ep, ev->write) == NGX_ABORT) {
|
if (ngx_event_pipe(ep, ev->write) == NGX_ABORT) {
|
||||||
ngx_http_proxy_finalize_request(p, 0);
|
ngx_http_proxy_finalize_request(p, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1159,14 +1164,14 @@ static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
|||||||
|
|
||||||
conf->bufs.num = 10;
|
conf->bufs.num = 10;
|
||||||
conf->bufs.size = 4096;
|
conf->bufs.size = 4096;
|
||||||
conf->max_busy_len = 8192 + 4096;
|
conf->max_busy_len = 8192;
|
||||||
|
|
||||||
|
|
||||||
/* CHECK in _init conf->max_temp_size >= conf->bufs.size !!! */
|
/* CHECK in _init conf->max_temp_size >= conf->bufs.size !!! */
|
||||||
conf->max_temp_file_size = 4096 * 6;
|
conf->max_temp_file_size = 4096 * 6;
|
||||||
|
|
||||||
|
|
||||||
conf->temp_file_write_size = 4096 * 2;
|
conf->temp_file_write_size = 4096 * 1;
|
||||||
|
|
||||||
ngx_test_null(conf->temp_path, ngx_pcalloc(cf->pool, sizeof(ngx_path_t)),
|
ngx_test_null(conf->temp_path, ngx_pcalloc(cf->pool, sizeof(ngx_path_t)),
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -48,6 +48,8 @@ typedef struct {
|
|||||||
ngx_table_elt_t *last_modified;
|
ngx_table_elt_t *last_modified;
|
||||||
ngx_table_elt_t *accept_ranges;
|
ngx_table_elt_t *accept_ranges;
|
||||||
|
|
||||||
|
off_t content_length_n;
|
||||||
|
|
||||||
ngx_table_t *headers;
|
ngx_table_t *headers;
|
||||||
} ngx_http_proxy_headers_in_t;
|
} ngx_http_proxy_headers_in_t;
|
||||||
|
|
||||||
@ -74,7 +76,7 @@ struct ngx_http_proxy_ctx_s {
|
|||||||
int location_len;
|
int location_len;
|
||||||
ngx_str_t host_header;
|
ngx_str_t host_header;
|
||||||
|
|
||||||
ngx_event_proxy_t *event_proxy;
|
ngx_event_pipe_t *event_pipe;
|
||||||
|
|
||||||
unsigned accel:1;
|
unsigned accel:1;
|
||||||
unsigned cachable:1;
|
unsigned cachable:1;
|
||||||
|
@ -130,13 +130,6 @@ static ngx_command_t ngx_http_core_commands[] = {
|
|||||||
offsetof(ngx_http_core_loc_conf_t, doc_root),
|
offsetof(ngx_http_core_loc_conf_t, doc_root),
|
||||||
NULL},
|
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_string("send_timeout"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_msec_slot,
|
ngx_conf_set_msec_slot,
|
||||||
@ -207,15 +200,22 @@ void ngx_http_handler(ngx_http_request_t *r)
|
|||||||
lcx = r->connection->log->data;
|
lcx = r->connection->log->data;
|
||||||
lcx->action = NULL;
|
lcx->action = NULL;
|
||||||
|
|
||||||
/* STUB */
|
switch (r->headers_in.connection_type) {
|
||||||
r->keepalive = 1;
|
case 0:
|
||||||
if (r->headers_in.connection) {
|
if (r->http_version > NGX_HTTP_VERSION_10) {
|
||||||
if (r->headers_in.connection->value.len == 5
|
r->keepalive = 1;
|
||||||
&& ngx_strcasecmp(r->headers_in.connection->value.data, "close")
|
} else {
|
||||||
== 0)
|
|
||||||
{
|
|
||||||
r->keepalive = 0;
|
r->keepalive = 0;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NGX_HTTP_CONNECTION_CLOSE:
|
||||||
|
r->keepalive = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NGX_HTTP_CONNECTION_KEEP_ALIVE:
|
||||||
|
r->keepalive = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -331,9 +331,10 @@ static void ngx_http_run_phases(ngx_http_request_t *r)
|
|||||||
|
|
||||||
int ngx_http_find_location_config(ngx_http_request_t *r)
|
int ngx_http_find_location_config(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
int i, rc;
|
int i, rc;
|
||||||
ngx_http_core_loc_conf_t *clcf, **clcfp;
|
ngx_http_core_loc_conf_t *clcf, **clcfp;
|
||||||
ngx_http_core_srv_conf_t *cscf;
|
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);
|
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||||
|
|
||||||
@ -363,12 +364,14 @@ ngx_log_debug(r->connection->log, "rc: %d" _ rc);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
wcf = ngx_http_get_module_loc_conf(r, ngx_http_write_filter_module);
|
||||||
|
|
||||||
if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) {
|
if (!(ngx_io.flags & NGX_IO_SENDFILE) || !wcf->sendfile) {
|
||||||
r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
|
r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||||
|
|
||||||
if (clcf->handler) {
|
if (clcf->handler) {
|
||||||
/*
|
/*
|
||||||
* if the location already has content handler then skip
|
* if the location already has content handler then skip
|
||||||
@ -825,8 +828,6 @@ static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf)
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
lcf->sendfile = NGX_CONF_UNSET;
|
|
||||||
|
|
||||||
lcf->send_timeout = NGX_CONF_UNSET;
|
lcf->send_timeout = NGX_CONF_UNSET;
|
||||||
lcf->discarded_buffer_size = NGX_CONF_UNSET;
|
lcf->discarded_buffer_size = NGX_CONF_UNSET;
|
||||||
lcf->keepalive_timeout = NGX_CONF_UNSET;
|
lcf->keepalive_timeout = NGX_CONF_UNSET;
|
||||||
@ -895,7 +896,6 @@ static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
|
|||||||
ngx_conf_merge_str_value(conf->default_type,
|
ngx_conf_merge_str_value(conf->default_type,
|
||||||
prev->default_type, "text/plain");
|
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_msec_value(conf->send_timeout, prev->send_timeout, 10000);
|
||||||
ngx_conf_merge_size_value(conf->discarded_buffer_size,
|
ngx_conf_merge_size_value(conf->discarded_buffer_size,
|
||||||
prev->discarded_buffer_size, 1500);
|
prev->discarded_buffer_size, 1500);
|
||||||
|
@ -110,7 +110,6 @@ typedef struct {
|
|||||||
ngx_array_t *types;
|
ngx_array_t *types;
|
||||||
ngx_str_t default_type;
|
ngx_str_t default_type;
|
||||||
|
|
||||||
int sendfile; /* sendfile */
|
|
||||||
ngx_msec_t send_timeout; /* send_timeout */
|
ngx_msec_t send_timeout; /* send_timeout */
|
||||||
ssize_t send_lowat; /* send_lowat */
|
ssize_t send_lowat; /* send_lowat */
|
||||||
ssize_t discarded_buffer_size; /* discarded_buffer_size */
|
ssize_t discarded_buffer_size; /* discarded_buffer_size */
|
||||||
|
@ -7,12 +7,20 @@
|
|||||||
#define NGX_HTTP_FILTER_NEED_TEMP 4
|
#define NGX_HTTP_FILTER_NEED_TEMP 4
|
||||||
|
|
||||||
|
|
||||||
int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk);
|
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);
|
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_header_filter) (ngx_http_request_t *r);
|
||||||
extern int (*ngx_http_top_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
|
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_ */
|
#endif /* _NGX_HTTP_FILTER_H_INCLUDED_ */
|
||||||
|
@ -159,9 +159,11 @@ static int ngx_http_header_filter(ngx_http_request_t *r)
|
|||||||
len += 15 + r->headers_out.content_range->value.len + 2;
|
len += 15 + r->headers_out.content_range->value.len + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->headers_out.content_length >= 0) {
|
if (r->headers_out.content_length == NULL) {
|
||||||
/* "Content-Length: ... \r\n", 2^64 is 20 characters */
|
if (r->headers_out.content_length_n >= 0) {
|
||||||
len += 48;
|
/* "Content-Length: ... \r\n", 2^64 is 20 characters */
|
||||||
|
len += 48;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->headers_out.content_type && r->headers_out.content_type->value.len) {
|
if (r->headers_out.content_type && r->headers_out.content_type->value.len) {
|
||||||
@ -260,11 +262,13 @@ static int ngx_http_header_filter(ngx_http_request_t *r)
|
|||||||
*(h->last++) = CR; *(h->last++) = LF;
|
*(h->last++) = CR; *(h->last++) = LF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 2^64 is 20 characters */
|
if (r->headers_out.content_length == NULL) {
|
||||||
if (r->headers_out.content_length >= 0) {
|
/* 2^64 is 20 characters */
|
||||||
h->last += ngx_snprintf(h->last, 49,
|
if (r->headers_out.content_length_n >= 0) {
|
||||||
"Content-Length: " OFF_FMT CRLF,
|
h->last += ngx_snprintf(h->last, 49,
|
||||||
r->headers_out.content_length);
|
"Content-Length: " OFF_FMT CRLF,
|
||||||
|
r->headers_out.content_length_n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->headers_out.content_type && r->headers_out.content_type->value.len) {
|
if (r->headers_out.content_type && r->headers_out.content_type->value.len) {
|
||||||
|
@ -84,11 +84,11 @@ ngx_module_t ngx_http_output_filter_module = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
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_chain_t *in)
|
||||||
{
|
{
|
||||||
int rc, last;
|
int rc, last;
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
ngx_chain_t out, *ce, **le;
|
ngx_chain_t *ce;
|
||||||
ngx_http_output_filter_ctx_t *ctx;
|
ngx_http_output_filter_ctx_t *ctx;
|
||||||
ngx_http_output_filter_conf_t *conf;
|
ngx_http_output_filter_conf_t *conf;
|
||||||
|
|
||||||
@ -103,33 +103,27 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* the short path for the case when the chain ctx->in is empty
|
* the short path for the case when the chain ctx->in is empty
|
||||||
* and there's no hunk or the hunk does not require the copy
|
* and the incoming chain is empty too or it has the single hunk
|
||||||
|
* that does not require the copy
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ctx->in == NULL) {
|
if (ctx->in == NULL) {
|
||||||
|
|
||||||
if (hunk == NULL) {
|
if (in == NULL) {
|
||||||
return ngx_next_filter(r, NULL);
|
return ngx_next_filter(r, in);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!need_to_copy(r, hunk)) {
|
if (in->next == NULL && (!need_to_copy(r, in->hunk))) {
|
||||||
out.hunk = hunk;
|
return ngx_next_filter(r, in);
|
||||||
out.next = NULL;
|
|
||||||
return ngx_next_filter(r, &out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add the incoming hunk to the chain ctx->in */
|
/* add the incoming hunk to the chain ctx->in */
|
||||||
|
|
||||||
if (hunk) {
|
if (in) {
|
||||||
le = &ctx->in;
|
if (ngx_chain_add_copy(r->pool, &ctx->in, in) == NGX_ERROR) {
|
||||||
|
return NGX_ERROR;
|
||||||
for (ce = ctx->in; ce; ce = ce->next) {
|
|
||||||
le = &ce->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_add_hunk_to_chain(ce, hunk, r->pool, NGX_ERROR);
|
|
||||||
*le = ce;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
conf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
|
conf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
|
||||||
|
@ -9,6 +9,7 @@ static void ngx_http_init_request(ngx_event_t *ev);
|
|||||||
static void ngx_http_process_request_line(ngx_event_t *rev);
|
static void ngx_http_process_request_line(ngx_event_t *rev);
|
||||||
static void ngx_http_process_request_headers(ngx_event_t *rev);
|
static void ngx_http_process_request_headers(ngx_event_t *rev);
|
||||||
static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
|
static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
|
||||||
|
static int ngx_http_process_request_header(ngx_http_request_t *r);
|
||||||
|
|
||||||
static void ngx_http_set_write_handler(ngx_http_request_t *r);
|
static void ngx_http_set_write_handler(ngx_http_request_t *r);
|
||||||
|
|
||||||
@ -256,7 +257,8 @@ ngx_log_debug(rev->log, "IN: %08x" _ in_port);
|
|||||||
r->file.fd = NGX_INVALID_FILE;
|
r->file.fd = NGX_INVALID_FILE;
|
||||||
|
|
||||||
r->headers_in.content_length_n = -1;
|
r->headers_in.content_length_n = -1;
|
||||||
r->headers_out.content_length = -1;
|
r->headers_in.keep_alive_n = -1;
|
||||||
|
r->headers_out.content_length_n = -1;
|
||||||
r->headers_out.last_modified_time = -1;
|
r->headers_out.last_modified_time = -1;
|
||||||
|
|
||||||
rev->event_handler = ngx_http_process_request_line;
|
rev->event_handler = ngx_http_process_request_line;
|
||||||
@ -503,14 +505,11 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
|
|||||||
static void ngx_http_process_request_headers(ngx_event_t *rev)
|
static void ngx_http_process_request_headers(ngx_event_t *rev)
|
||||||
{
|
{
|
||||||
int rc, i, offset;
|
int rc, i, offset;
|
||||||
size_t len;
|
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
ngx_table_elt_t *h;
|
ngx_table_elt_t *h;
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
ngx_http_request_t *r;
|
ngx_http_request_t *r;
|
||||||
ngx_http_server_name_t *name;
|
|
||||||
ngx_http_core_srv_conf_t *cscf;
|
ngx_http_core_srv_conf_t *cscf;
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
|
||||||
|
|
||||||
c = rev->data;
|
c = rev->data;
|
||||||
r = c->data;
|
r = c->data;
|
||||||
@ -604,59 +603,11 @@ static void ngx_http_process_request_headers(ngx_event_t *rev)
|
|||||||
|
|
||||||
ngx_log_debug(r->connection->log, "HTTP header done");
|
ngx_log_debug(r->connection->log, "HTTP header done");
|
||||||
|
|
||||||
if (r->headers_in.host) {
|
rc = ngx_http_process_request_header(r);
|
||||||
for (len = 0; len < r->headers_in.host->value.len; len++) {
|
|
||||||
if (r->headers_in.host->value.data[len] == ':') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r->headers_in.host_name_len = len;
|
|
||||||
|
|
||||||
/* find the name based server configuration */
|
if (rc != NGX_OK) {
|
||||||
|
ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST);
|
||||||
name = r->virtual_names->elts;
|
return;
|
||||||
for (i = 0; i < r->virtual_names->nelts; i++) {
|
|
||||||
if (r->headers_in.host_name_len != name[i].name.len) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ngx_strncasecmp(r->headers_in.host->value.data,
|
|
||||||
name[i].name.data,
|
|
||||||
r->headers_in.host_name_len) == 0)
|
|
||||||
{
|
|
||||||
r->srv_conf = name[i].core_srv_conf->ctx->srv_conf;
|
|
||||||
r->loc_conf = name[i].core_srv_conf->ctx->loc_conf;
|
|
||||||
|
|
||||||
clcf = ngx_http_get_module_loc_conf(r,
|
|
||||||
ngx_http_core_module);
|
|
||||||
c->log->file = clcf->err_log->file;
|
|
||||||
c->log->log_level = clcf->err_log->log_level;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (r->http_version > NGX_HTTP_VERSION_10) {
|
|
||||||
ngx_http_header_parse_error(r,
|
|
||||||
NGX_HTTP_PARSE_NO_HOST_HEADER,
|
|
||||||
NGX_HTTP_BAD_REQUEST);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
r->headers_in.host_name_len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->headers_in.content_length) {
|
|
||||||
r->headers_in.content_length_n =
|
|
||||||
ngx_atoi(r->headers_in.content_length->value.data,
|
|
||||||
r->headers_in.content_length->value.len);
|
|
||||||
|
|
||||||
if (r->headers_in.content_length_n == NGX_ERROR) {
|
|
||||||
ngx_http_header_parse_error(r,
|
|
||||||
NGX_HTTP_PARSE_INVALID_CL_HEADER,
|
|
||||||
NGX_HTTP_BAD_REQUEST);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->header_timeout_set) {
|
if (r->header_timeout_set) {
|
||||||
@ -766,6 +717,86 @@ static ssize_t ngx_http_read_request_header(ngx_http_request_t *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ngx_http_process_request_header(ngx_http_request_t *r)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
size_t len;
|
||||||
|
ngx_http_server_name_t *name;
|
||||||
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
|
||||||
|
if (r->headers_in.host) {
|
||||||
|
for (len = 0; len < r->headers_in.host->value.len; len++) {
|
||||||
|
if (r->headers_in.host->value.data[len] == ':') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r->headers_in.host_name_len = len;
|
||||||
|
|
||||||
|
/* find the name based server configuration */
|
||||||
|
|
||||||
|
name = r->virtual_names->elts;
|
||||||
|
for (i = 0; i < r->virtual_names->nelts; i++) {
|
||||||
|
if (r->headers_in.host_name_len != name[i].name.len) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_strncasecmp(r->headers_in.host->value.data,
|
||||||
|
name[i].name.data,
|
||||||
|
r->headers_in.host_name_len) == 0)
|
||||||
|
{
|
||||||
|
r->srv_conf = name[i].core_srv_conf->ctx->srv_conf;
|
||||||
|
r->loc_conf = name[i].core_srv_conf->ctx->loc_conf;
|
||||||
|
|
||||||
|
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||||
|
r->connection->log->file = clcf->err_log->file;
|
||||||
|
r->connection->log->log_level = clcf->err_log->log_level;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (r->http_version > NGX_HTTP_VERSION_10) {
|
||||||
|
return NGX_HTTP_PARSE_NO_HOST_HEADER;
|
||||||
|
}
|
||||||
|
r->headers_in.host_name_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->headers_in.content_length) {
|
||||||
|
r->headers_in.content_length_n =
|
||||||
|
ngx_atoi(r->headers_in.content_length->value.data,
|
||||||
|
r->headers_in.content_length->value.len);
|
||||||
|
|
||||||
|
if (r->headers_in.content_length_n == NGX_ERROR) {
|
||||||
|
return NGX_HTTP_PARSE_INVALID_CL_HEADER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->headers_in.connection) {
|
||||||
|
if (r->headers_in.connection->value.len == 5
|
||||||
|
&& ngx_strcasecmp(r->headers_in.connection->value.data, "close")
|
||||||
|
== 0)
|
||||||
|
{
|
||||||
|
r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
|
||||||
|
|
||||||
|
} else if (r->headers_in.connection->value.len == 10
|
||||||
|
&& ngx_strcasecmp(r->headers_in.connection->value.data,
|
||||||
|
"keep-alive") == 0)
|
||||||
|
{
|
||||||
|
r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
|
||||||
|
|
||||||
|
if (r->headers_in.keep_alive) {
|
||||||
|
r->headers_in.keep_alive_n =
|
||||||
|
ngx_atoi(r->headers_in.keep_alive->value.data,
|
||||||
|
r->headers_in.keep_alive->value.len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ngx_http_finalize_request(ngx_http_request_t *r, int rc)
|
void ngx_http_finalize_request(ngx_http_request_t *r, int rc)
|
||||||
{
|
{
|
||||||
ngx_log_debug(r->connection->log, "finalize http request");
|
ngx_log_debug(r->connection->log, "finalize http request");
|
||||||
@ -1283,12 +1314,15 @@ static void ngx_http_empty_handler(ngx_event_t *wev)
|
|||||||
|
|
||||||
int ngx_http_send_last(ngx_http_request_t *r)
|
int ngx_http_send_last(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
ngx_hunk_t *h;
|
ngx_hunk_t *h;
|
||||||
|
ngx_chain_t out;
|
||||||
|
|
||||||
ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
|
ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
|
||||||
h->type = NGX_HUNK_LAST;
|
h->type = NGX_HUNK_LAST;
|
||||||
|
out.hunk = h;
|
||||||
|
out.next = NULL;
|
||||||
|
|
||||||
return ngx_http_output_filter(r, h);
|
return ngx_http_output_filter(r, &out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,11 +10,11 @@
|
|||||||
#define NGX_HTTP_HEAD 2
|
#define NGX_HTTP_HEAD 2
|
||||||
#define NGX_HTTP_POST 3
|
#define NGX_HTTP_POST 3
|
||||||
|
|
||||||
#define NGX_HTTP_CONN_CLOSE 0
|
#define NGX_HTTP_CONNECTION_CLOSE 1
|
||||||
#define NGX_HTTP_CONN_KEEP_ALIVE 1
|
#define NGX_HTTP_CONNECTION_KEEP_ALIVE 2
|
||||||
|
|
||||||
|
|
||||||
#define NGX_NONE 1
|
#define NGX_NONE 1
|
||||||
|
|
||||||
|
|
||||||
#define NGX_HTTP_PARSE_HEADER_DONE 1
|
#define NGX_HTTP_PARSE_HEADER_DONE 1
|
||||||
@ -63,9 +63,6 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t host_name_len;
|
|
||||||
ssize_t content_length_n;
|
|
||||||
|
|
||||||
ngx_table_elt_t *host;
|
ngx_table_elt_t *host;
|
||||||
ngx_table_elt_t *connection;
|
ngx_table_elt_t *connection;
|
||||||
ngx_table_elt_t *if_modified_since;
|
ngx_table_elt_t *if_modified_since;
|
||||||
@ -77,6 +74,11 @@ typedef struct {
|
|||||||
ngx_table_elt_t *user_agent;
|
ngx_table_elt_t *user_agent;
|
||||||
ngx_table_elt_t *keep_alive;
|
ngx_table_elt_t *keep_alive;
|
||||||
|
|
||||||
|
size_t host_name_len;
|
||||||
|
ssize_t content_length_n;
|
||||||
|
size_t connection_type;
|
||||||
|
ssize_t keep_alive_n;
|
||||||
|
|
||||||
ngx_table_t *headers;
|
ngx_table_t *headers;
|
||||||
} ngx_http_headers_in_t;
|
} ngx_http_headers_in_t;
|
||||||
|
|
||||||
@ -107,6 +109,7 @@ typedef struct {
|
|||||||
ngx_table_elt_t *server;
|
ngx_table_elt_t *server;
|
||||||
ngx_table_elt_t *date;
|
ngx_table_elt_t *date;
|
||||||
ngx_table_elt_t *content_type;
|
ngx_table_elt_t *content_type;
|
||||||
|
ngx_table_elt_t *content_length;
|
||||||
ngx_table_elt_t *content_encoding;
|
ngx_table_elt_t *content_encoding;
|
||||||
ngx_table_elt_t *location;
|
ngx_table_elt_t *location;
|
||||||
ngx_table_elt_t *last_modified;
|
ngx_table_elt_t *last_modified;
|
||||||
@ -118,7 +121,7 @@ typedef struct {
|
|||||||
|
|
||||||
ngx_table_t *headers;
|
ngx_table_t *headers;
|
||||||
|
|
||||||
off_t content_length;
|
off_t content_length_n;
|
||||||
char *etag;
|
char *etag;
|
||||||
time_t date_time;
|
time_t date_time;
|
||||||
time_t last_modified_time;
|
time_t last_modified_time;
|
||||||
|
@ -152,8 +152,9 @@ static ngx_str_t error_pages[] = {
|
|||||||
|
|
||||||
int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
|
int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
|
||||||
{
|
{
|
||||||
int err, rc;
|
int err, rc;
|
||||||
ngx_hunk_t *h;
|
ngx_hunk_t *h;
|
||||||
|
ngx_chain_t *out, **le, *ce;
|
||||||
|
|
||||||
r->headers_out.status = error;
|
r->headers_out.status = error;
|
||||||
|
|
||||||
@ -189,9 +190,9 @@ int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (error_pages[err].len) {
|
if (error_pages[err].len) {
|
||||||
r->headers_out.content_length = error_pages[err].len
|
r->headers_out.content_length_n = error_pages[err].len
|
||||||
+ sizeof(error_tail) - 1
|
+ sizeof(error_tail) - 1
|
||||||
+ sizeof(msie_stub) - 1;
|
+ sizeof(msie_stub) - 1;
|
||||||
|
|
||||||
ngx_test_null(r->headers_out.content_type,
|
ngx_test_null(r->headers_out.content_type,
|
||||||
ngx_push_table(r->headers_out.headers),
|
ngx_push_table(r->headers_out.headers),
|
||||||
@ -203,7 +204,8 @@ int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
|
|||||||
r->headers_out.content_type->value.data = "text/html";
|
r->headers_out.content_type->value.data = "text/html";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
r->headers_out.content_length = -1;
|
r->headers_out.content_length_n = -1;
|
||||||
|
r->headers_out.content_length = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ngx_http_send_header(r);
|
rc = ngx_http_send_header(r);
|
||||||
@ -216,41 +218,42 @@ int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
|
|||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
|
out = NULL;
|
||||||
|
le = NULL;
|
||||||
|
|
||||||
|
ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
|
||||||
h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
|
h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
|
||||||
h->pos = error_pages[err].data;
|
h->pos = error_pages[err].data;
|
||||||
h->last = error_pages[err].data + error_pages[err].len;
|
h->last = error_pages[err].data + error_pages[err].len;
|
||||||
|
|
||||||
if (ngx_http_output_filter(r, h) == NGX_ERROR) {
|
ngx_alloc_ce_and_set_hunk(ce, h, r->pool, NGX_ERROR);
|
||||||
return NGX_ERROR;
|
ngx_chain_add_ce(out, le, ce);
|
||||||
}
|
|
||||||
|
|
||||||
ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
|
ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
|
||||||
|
|
||||||
h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
|
h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
|
||||||
h->pos = error_tail;
|
h->pos = error_tail;
|
||||||
h->last = error_tail + sizeof(error_tail) - 1;
|
h->last = error_tail + sizeof(error_tail) - 1;
|
||||||
|
|
||||||
|
ngx_alloc_ce_and_set_hunk(ce, h, r->pool, NGX_ERROR);
|
||||||
|
ngx_chain_add_ce(out, le, ce);
|
||||||
|
|
||||||
if (/* STUB: "msie_padding on/off" */ 1
|
if (/* STUB: "msie_padding on/off" */ 1
|
||||||
&& r->http_version >= NGX_HTTP_VERSION_10
|
&& r->http_version >= NGX_HTTP_VERSION_10
|
||||||
&& error >= NGX_HTTP_BAD_REQUEST
|
&& error >= NGX_HTTP_BAD_REQUEST
|
||||||
&& error != NGX_HTTP_REQUEST_URI_TOO_LARGE
|
&& error != NGX_HTTP_REQUEST_URI_TOO_LARGE
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (ngx_http_output_filter(r, h) == NGX_ERROR) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
|
ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
|
||||||
|
|
||||||
h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
|
h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
|
||||||
h->pos = msie_stub;
|
h->pos = msie_stub;
|
||||||
h->last = msie_stub + sizeof(msie_stub) - 1;
|
h->last = msie_stub + sizeof(msie_stub) - 1;
|
||||||
|
|
||||||
|
ngx_alloc_ce_and_set_hunk(ce, h, r->pool, NGX_ERROR);
|
||||||
|
ngx_chain_add_ce(out, le, ce);
|
||||||
}
|
}
|
||||||
|
|
||||||
h->type |= NGX_HUNK_LAST;
|
h->type |= NGX_HUNK_LAST;
|
||||||
|
|
||||||
return ngx_http_output_filter(r, h);
|
return ngx_http_output_filter(r, out);
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,6 @@
|
|||||||
#include <ngx_http.h>
|
#include <ngx_http.h>
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ssize_t buffer_output;
|
|
||||||
} ngx_http_write_filter_conf_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_chain_t *out;
|
ngx_chain_t *out;
|
||||||
} ngx_http_write_filter_ctx_t;
|
} ngx_http_write_filter_ctx_t;
|
||||||
@ -23,6 +18,13 @@ static int ngx_http_write_filter_init(ngx_cycle_t *cycle);
|
|||||||
|
|
||||||
static ngx_command_t ngx_http_write_filter_commands[] = {
|
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_string("buffer_output"),
|
||||||
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_size_slot,
|
ngx_conf_set_size_slot,
|
||||||
@ -81,36 +83,7 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||||||
for (ce = ctx->out; ce; ce = ce->next) {
|
for (ce = ctx->out; ce; ce = ce->next) {
|
||||||
le = &ce->next;
|
le = &ce->next;
|
||||||
|
|
||||||
if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
|
size += ngx_hunk_size(ce->hunk);
|
||||||
size += ce->hunk->last - ce->hunk->pos;
|
|
||||||
} else {
|
|
||||||
size += ce->hunk->file_last - ce->hunk->file_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ce->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
|
|
||||||
flush = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ce->hunk->type & NGX_HUNK_LAST) {
|
|
||||||
last = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add the new chain to the existent one */
|
|
||||||
|
|
||||||
for (/* void */; in; in = in->next) {
|
|
||||||
ngx_test_null(ce, ngx_alloc_chain_entry(r->pool), NGX_ERROR);
|
|
||||||
|
|
||||||
ce->hunk = in->hunk;
|
|
||||||
ce->next = NULL;
|
|
||||||
*le = ce;
|
|
||||||
le = &ce->next;
|
|
||||||
|
|
||||||
if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
|
|
||||||
size += ce->hunk->last - ce->hunk->pos;
|
|
||||||
} else {
|
|
||||||
size += ce->hunk->file_last - ce->hunk->file_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ce->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
|
if (ce->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
|
||||||
flush = size;
|
flush = size;
|
||||||
@ -124,6 +97,31 @@ 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,
|
conf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
|
||||||
ngx_http_write_filter_module);
|
ngx_http_write_filter_module);
|
||||||
|
|
||||||
|
/* add the new chain to the existent one */
|
||||||
|
|
||||||
|
for (/* void */; in; in = in->next) {
|
||||||
|
ngx_test_null(ce, ngx_alloc_chain_entry(r->pool), NGX_ERROR);
|
||||||
|
|
||||||
|
ce->hunk = in->hunk;
|
||||||
|
ce->next = NULL;
|
||||||
|
*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)) {
|
||||||
|
flush = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ce->hunk->type & NGX_HUNK_LAST) {
|
||||||
|
last = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if (NGX_DEBUG_WRITE_FILTER)
|
#if (NGX_DEBUG_WRITE_FILTER)
|
||||||
ngx_log_debug(r->connection->log,
|
ngx_log_debug(r->connection->log,
|
||||||
"write filter: last:%d flush:%qd size:%qd" _
|
"write filter: last:%d flush:%qd size:%qd" _
|
||||||
@ -176,6 +174,7 @@ static void *ngx_http_write_filter_create_conf(ngx_conf_t *cf)
|
|||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
conf->buffer_output = NGX_CONF_UNSET;
|
conf->buffer_output = NGX_CONF_UNSET;
|
||||||
|
conf->sendfile = NGX_CONF_UNSET;
|
||||||
|
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
@ -188,6 +187,7 @@ static char *ngx_http_write_filter_merge_conf(ngx_conf_t *cf,
|
|||||||
ngx_http_write_filter_conf_t *conf = child;
|
ngx_http_write_filter_conf_t *conf = child;
|
||||||
|
|
||||||
ngx_conf_merge_size_value(conf->buffer_output, prev->buffer_output, 1460);
|
ngx_conf_merge_size_value(conf->buffer_output, prev->buffer_output, 1460);
|
||||||
|
ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -154,6 +154,11 @@ ngx_log_debug(c->log, "NOPUSH");
|
|||||||
hdtr.trailers = (struct iovec *) trailer.elts;
|
hdtr.trailers = (struct iovec *) trailer.elts;
|
||||||
hdtr.trl_cnt = trailer.nelts;
|
hdtr.trl_cnt = trailer.nelts;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the old sendfile() "nbytes bug":
|
||||||
|
* http://www.freebsd.org/cgi/query-pr.cgi?pr=33771
|
||||||
|
*/
|
||||||
|
|
||||||
if (ngx_freebsd_sendfile_nbytes_bug == 0) {
|
if (ngx_freebsd_sendfile_nbytes_bug == 0) {
|
||||||
hsize = 0;
|
hsize = 0;
|
||||||
}
|
}
|
||||||
@ -194,7 +199,6 @@ ngx_log_debug(c->log, "NOPUSH");
|
|||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
err = ngx_errno;
|
err = ngx_errno;
|
||||||
if (err == NGX_EAGAIN) {
|
if (err == NGX_EAGAIN) {
|
||||||
eagain = 1;
|
|
||||||
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN");
|
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN");
|
||||||
|
|
||||||
} else if (err == NGX_EINTR) {
|
} else if (err == NGX_EINTR) {
|
||||||
@ -256,6 +260,11 @@ ngx_log_debug(c->log, "NOPUSH");
|
|||||||
in = ce;
|
in = ce;
|
||||||
|
|
||||||
if (eagain) {
|
if (eagain) {
|
||||||
|
/*
|
||||||
|
* sendfile() can return EAGAIN even if it has sent
|
||||||
|
* a whole file part and successive sendfile() would
|
||||||
|
* return EAGAIN right away and would not send anything.
|
||||||
|
*/
|
||||||
c->write->ready = 0;
|
c->write->ready = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user