mirror of
https://github.com/nginx/nginx.git
synced 2025-06-07 01:12:40 +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) {
|
||||
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 ((*busy)->hunk->type & NGX_HUNK_ZEROCOPY_BUSY) {
|
||||
|
@ -2,29 +2,33 @@
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.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_free_raw_hunk(ngx_chain_t **free,
|
||||
ngx_hunk_t *h);
|
||||
ngx_inline static void ngx_add_after_partially_filled_hunk(ngx_chain_t **chain,
|
||||
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 ( ;; ) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
p->read = 0;
|
||||
|
||||
if (ngx_event_proxy_read_upstream(p) == NGX_ABORT) {
|
||||
if (ngx_event_pipe_read_upstream(p) == 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;
|
||||
ngx_hunk_t *h;
|
||||
@ -116,7 +120,6 @@ int ngx_event_proxy_read_upstream(ngx_event_proxy_t *p)
|
||||
|
||||
chain = p->free_raw_hunks;
|
||||
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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
/*
|
||||
* If the hunks are not needed to be saved in a cache and
|
||||
* a downstream is ready then write the hunks to a downstream.
|
||||
* if the hunks are not needed to be saved in a cache and
|
||||
* a downstream is ready then write the hunks to a downstream
|
||||
*/
|
||||
|
||||
ngx_log_debug(p->log, "downstream ready");
|
||||
|
||||
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
|
||||
* to a temporary file, and add them to a r->out chain.
|
||||
* if it's allowed then save some hunks from r->in
|
||||
* 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);
|
||||
|
||||
@ -223,9 +226,7 @@ ngx_log_debug(p->log, "FREE: %08X:%d" _ chain->hunk->pos _ chain->hunk->end - ch
|
||||
ce = ce->next;
|
||||
|
||||
} else {
|
||||
ngx_log_debug(p->log, "PART: %08X:%d:%d" _ ce->hunk->pos _ ce->hunk->last - ce->hunk->pos _ n);
|
||||
ce->hunk->last += n;
|
||||
ngx_log_debug(p->log, "PART: %08X:%d" _ ce->hunk->pos _ ce->hunk->end - ce->hunk->last);
|
||||
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 (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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
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);
|
||||
|
||||
@ -285,38 +286,47 @@ int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p)
|
||||
}
|
||||
}
|
||||
|
||||
out = NULL;
|
||||
le = NULL;
|
||||
|
||||
if (p->out) {
|
||||
out = p->out;
|
||||
for ( ;; ) {
|
||||
if (p->out) {
|
||||
ce = p->out;
|
||||
|
||||
if (!(p->upstream_eof || p->upstream_error || p->upstream_done)
|
||||
&& (busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len))
|
||||
{
|
||||
if (!(p->upstream_eof || p->upstream_error || p->upstream_done)
|
||||
&& (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;
|
||||
}
|
||||
|
||||
p->out = p->out->next;
|
||||
ngx_remove_shadow_free_raw_hunk(&p->free_raw_hunks, out->hunk);
|
||||
busy_len += ngx_hunk_size(ce->hunk);
|
||||
ce->next = NULL;
|
||||
ngx_chain_add_ce(out, le, ce);
|
||||
}
|
||||
|
||||
} else if (!p->cachable && p->in) {
|
||||
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 {
|
||||
if (out == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
out->next = NULL;
|
||||
|
||||
|
||||
if (p->output_filter(p->output_ctx, out->hunk) == NGX_ERROR) {
|
||||
if (p->output_filter(p->output_ctx, out) == NGX_ERROR) {
|
||||
p->downstream_error = 1;
|
||||
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 */
|
||||
|
||||
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) {
|
||||
h = ce->hunk->shadow;
|
||||
/* 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_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->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;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
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");
|
||||
|
||||
@ -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) {
|
||||
|
||||
size = 0;
|
||||
@ -407,21 +408,21 @@ ngx_log_debug(p->log, "hunk size: %d" _ hunk_size);
|
||||
ngx_log_debug(p->log, "size: %d" _ size);
|
||||
|
||||
if (ce) {
|
||||
in = ce;
|
||||
p->in = ce;
|
||||
*le = NULL;
|
||||
|
||||
} else {
|
||||
in = NULL;
|
||||
p->in = NULL;
|
||||
p->last_in = &p->in;
|
||||
}
|
||||
|
||||
} else {
|
||||
in = NULL;
|
||||
p->in = NULL;
|
||||
p->last_in = &p->in;
|
||||
}
|
||||
|
||||
if (ngx_write_chain_to_file(p->temp_file, p->in, p->temp_offset,
|
||||
p->pool) == NGX_ERROR) {
|
||||
if (ngx_write_chain_to_file(p->temp_file, out, p->temp_offset,
|
||||
p->pool) == NGX_ERROR) {
|
||||
return NGX_ABORT;
|
||||
}
|
||||
|
||||
@ -432,7 +433,7 @@ ngx_log_debug(p->log, "size: %d" _ size);
|
||||
/* void */
|
||||
}
|
||||
|
||||
for (ce = p->in; ce; ce = next) {
|
||||
for (ce = out; ce; ce = next) {
|
||||
next = ce->next;
|
||||
ce->next = NULL;
|
||||
|
||||
@ -453,15 +454,13 @@ ngx_log_debug(p->log, "size: %d" _ size);
|
||||
}
|
||||
}
|
||||
|
||||
p->in = in;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
/* 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_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_chain_t *ce, *te;
|
@ -1,5 +1,5 @@
|
||||
#ifndef _NGX_EVENT_PROXY_H_INCLUDED_
|
||||
#define _NGX_EVENT_PROXY_H_INCLUDED_
|
||||
#ifndef _NGX_EVENT_PIPE_H_INCLUDED_
|
||||
#define _NGX_EVENT_PIPE_H_INCLUDED_
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
@ -7,14 +7,14 @@
|
||||
#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,
|
||||
ngx_hunk_t *hunk);
|
||||
typedef int (*ngx_event_proxy_output_filter_pt)(void *data, ngx_hunk_t *hunk);
|
||||
typedef int (*ngx_event_pipe_input_filter_pt)(ngx_event_pipe_t *p,
|
||||
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 *in;
|
||||
ngx_chain_t **last_in;
|
||||
@ -30,10 +30,10 @@ struct ngx_event_proxy_s {
|
||||
* 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;
|
||||
|
||||
ngx_event_proxy_output_filter_pt output_filter;
|
||||
ngx_event_pipe_output_filter_pt output_filter;
|
||||
void *output_ctx;
|
||||
|
||||
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_proxy_copy_input_filter(ngx_event_proxy_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);
|
||||
int ngx_event_pipe(ngx_event_pipe_t *p, int do_write);
|
||||
int ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_hunk_t *hunk);
|
||||
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
if (r->headers_out.content_length == -1) {
|
||||
if (r->headers_out.content_length_n == -1) {
|
||||
if (r->http_version < NGX_HTTP_VERSION_11) {
|
||||
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.data = "gzip";
|
||||
|
||||
ctx->length = r->headers_out.content_length;
|
||||
r->headers_out.content_length = -1;
|
||||
ctx->length = r->headers_out.content_length_n;
|
||||
r->headers_out.content_length_n = -1;
|
||||
r->headers_out.content_length = NULL;
|
||||
r->filter |= NGX_HTTP_FILTER_NEED_IN_MEMORY;
|
||||
|
||||
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) {
|
||||
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 = NULL;
|
||||
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
|
||||
|| r->http_version < NGX_HTTP_VERSION_10
|
||||
|| 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 */
|
||||
|| 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;
|
||||
}
|
||||
|
||||
if (start >= r->headers_out.content_length) {
|
||||
if (start >= r->headers_out.content_length_n) {
|
||||
rc = NGX_HTTP_RANGE_NOT_SATISFIABLE;
|
||||
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_ERROR);
|
||||
range->start = start;
|
||||
range->end = r->headers_out.content_length;
|
||||
range->end = r->headers_out.content_length_n;
|
||||
|
||||
if (*p++ == ',') {
|
||||
continue;
|
||||
@ -139,7 +139,7 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
|
||||
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;
|
||||
break;
|
||||
}
|
||||
@ -170,9 +170,10 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
|
||||
r->headers_out.content_range->value.len =
|
||||
ngx_snprintf(r->headers_out.content_range->value.data,
|
||||
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;
|
||||
|
||||
@ -193,9 +194,9 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
|
||||
6 + 20 + 1 + 20 + 1 + 20 + 1,
|
||||
"bytes " OFF_FMT "-" OFF_FMT "/" OFF_FMT,
|
||||
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 {
|
||||
|
||||
@ -267,13 +268,14 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
|
||||
20 + 1 + 20 + 1 + 20 + 5,
|
||||
OFF_FMT "-" OFF_FMT "/" OFF_FMT CRLF CRLF,
|
||||
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
|
||||
+ (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_err_t err;
|
||||
ngx_hunk_t *h;
|
||||
ngx_chain_t out;
|
||||
ngx_http_type_t *type;
|
||||
ngx_http_log_ctx_t *ctx;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
@ -257,7 +258,7 @@ static int ngx_http_static_handler(ngx_http_request_t *r)
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
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->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_core.h>
|
||||
#include <ngx_event.h>
|
||||
/* STUB */ #include <ngx_event_connect.h>
|
||||
/* STUB */ #include <ngx_event_proxy.h>
|
||||
#include <ngx_event_connect.h>
|
||||
#include <ngx_event_pipe.h>
|
||||
#include <ngx_http.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;
|
||||
ngx_table_elt_t *ch, *ph;
|
||||
ngx_event_proxy_t *ep;
|
||||
ngx_event_pipe_t *ep;
|
||||
ngx_http_request_t *r;
|
||||
|
||||
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 */
|
||||
|
||||
@ -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);
|
||||
if (ch == NULL) {
|
||||
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;
|
||||
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 */
|
||||
@ -700,14 +702,14 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
|
||||
|
||||
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) {
|
||||
ngx_http_proxy_finalize_request(p, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
ep->input_filter = ngx_event_proxy_copy_input_filter;
|
||||
ep->output_filter = (ngx_event_proxy_output_filter_pt)
|
||||
ep->input_filter = ngx_event_pipe_copy_input_filter;
|
||||
ep->output_filter = (ngx_event_pipe_output_filter_pt)
|
||||
ngx_http_output_filter;
|
||||
ep->output_ctx = r;
|
||||
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;
|
||||
|
||||
/*
|
||||
* event_proxy would do p->header_in->last += ep->preread_size
|
||||
* as these bytes were read.
|
||||
* event_pipe would do p->header_in->last += ep->preread_size
|
||||
* as though these bytes were read.
|
||||
*/
|
||||
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
|
||||
lcx = p->log->data;
|
||||
@ -771,7 +776,7 @@ static void ngx_http_proxy_process_body(ngx_event_t *ev)
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_proxy_ctx_t *p;
|
||||
ngx_event_proxy_t *ep;
|
||||
ngx_event_pipe_t *ep;
|
||||
|
||||
c = ev->data;
|
||||
|
||||
@ -786,7 +791,7 @@ static void ngx_http_proxy_process_body(ngx_event_t *ev)
|
||||
r = p->request;
|
||||
}
|
||||
|
||||
ep = p->event_proxy;
|
||||
ep = p->event_pipe;
|
||||
|
||||
if (ev->timedout) {
|
||||
if (ev->write) {
|
||||
@ -797,7 +802,7 @@ static void ngx_http_proxy_process_body(ngx_event_t *ev)
|
||||
}
|
||||
|
||||
} 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);
|
||||
return;
|
||||
}
|
||||
@ -1159,14 +1164,14 @@ static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
||||
|
||||
conf->bufs.num = 10;
|
||||
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 !!! */
|
||||
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)),
|
||||
NULL);
|
||||
|
@ -48,6 +48,8 @@ typedef struct {
|
||||
ngx_table_elt_t *last_modified;
|
||||
ngx_table_elt_t *accept_ranges;
|
||||
|
||||
off_t content_length_n;
|
||||
|
||||
ngx_table_t *headers;
|
||||
} ngx_http_proxy_headers_in_t;
|
||||
|
||||
@ -74,7 +76,7 @@ struct ngx_http_proxy_ctx_s {
|
||||
int location_len;
|
||||
ngx_str_t host_header;
|
||||
|
||||
ngx_event_proxy_t *event_proxy;
|
||||
ngx_event_pipe_t *event_pipe;
|
||||
|
||||
unsigned accel: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),
|
||||
NULL},
|
||||
|
||||
{ngx_string("sendfile"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_core_loc_conf_t, sendfile),
|
||||
NULL},
|
||||
|
||||
{ngx_string("send_timeout"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
@ -207,15 +200,22 @@ void ngx_http_handler(ngx_http_request_t *r)
|
||||
lcx = r->connection->log->data;
|
||||
lcx->action = NULL;
|
||||
|
||||
/* STUB */
|
||||
r->keepalive = 1;
|
||||
if (r->headers_in.connection) {
|
||||
if (r->headers_in.connection->value.len == 5
|
||||
&& ngx_strcasecmp(r->headers_in.connection->value.data, "close")
|
||||
== 0)
|
||||
{
|
||||
switch (r->headers_in.connection_type) {
|
||||
case 0:
|
||||
if (r->http_version > NGX_HTTP_VERSION_10) {
|
||||
r->keepalive = 1;
|
||||
} else {
|
||||
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
|
||||
@ -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 i, rc;
|
||||
ngx_http_core_loc_conf_t *clcf, **clcfp;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
int i, rc;
|
||||
ngx_http_core_loc_conf_t *clcf, **clcfp;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
ngx_http_write_filter_conf_t *wcf;
|
||||
|
||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (clcf->handler) {
|
||||
/*
|
||||
* 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->discarded_buffer_size = 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,
|
||||
prev->default_type, "text/plain");
|
||||
|
||||
ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
|
||||
ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 10000);
|
||||
ngx_conf_merge_size_value(conf->discarded_buffer_size,
|
||||
prev->discarded_buffer_size, 1500);
|
||||
|
@ -110,7 +110,6 @@ typedef struct {
|
||||
ngx_array_t *types;
|
||||
ngx_str_t default_type;
|
||||
|
||||
int sendfile; /* sendfile */
|
||||
ngx_msec_t send_timeout; /* send_timeout */
|
||||
ssize_t send_lowat; /* send_lowat */
|
||||
ssize_t discarded_buffer_size; /* discarded_buffer_size */
|
||||
|
@ -7,12 +7,20 @@
|
||||
#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);
|
||||
|
||||
|
||||
extern int (*ngx_http_top_header_filter) (ngx_http_request_t *r);
|
||||
extern int (*ngx_http_top_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
|
||||
|
||||
extern ngx_module_t ngx_http_write_filter_module;
|
||||
|
||||
|
||||
#endif /* _NGX_HTTP_FILTER_H_INCLUDED_ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
if (r->headers_out.content_length >= 0) {
|
||||
/* "Content-Length: ... \r\n", 2^64 is 20 characters */
|
||||
len += 48;
|
||||
if (r->headers_out.content_length == NULL) {
|
||||
if (r->headers_out.content_length_n >= 0) {
|
||||
/* "Content-Length: ... \r\n", 2^64 is 20 characters */
|
||||
len += 48;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 2^64 is 20 characters */
|
||||
if (r->headers_out.content_length >= 0) {
|
||||
h->last += ngx_snprintf(h->last, 49,
|
||||
"Content-Length: " OFF_FMT CRLF,
|
||||
r->headers_out.content_length);
|
||||
if (r->headers_out.content_length == NULL) {
|
||||
/* 2^64 is 20 characters */
|
||||
if (r->headers_out.content_length_n >= 0) {
|
||||
h->last += ngx_snprintf(h->last, 49,
|
||||
"Content-Length: " OFF_FMT CRLF,
|
||||
r->headers_out.content_length_n);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
ssize_t size;
|
||||
ngx_chain_t out, *ce, **le;
|
||||
ngx_chain_t *ce;
|
||||
ngx_http_output_filter_ctx_t *ctx;
|
||||
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
|
||||
* 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 (hunk == NULL) {
|
||||
return ngx_next_filter(r, NULL);
|
||||
if (in == NULL) {
|
||||
return ngx_next_filter(r, in);
|
||||
}
|
||||
|
||||
if (!need_to_copy(r, hunk)) {
|
||||
out.hunk = hunk;
|
||||
out.next = NULL;
|
||||
return ngx_next_filter(r, &out);
|
||||
if (in->next == NULL && (!need_to_copy(r, in->hunk))) {
|
||||
return ngx_next_filter(r, in);
|
||||
}
|
||||
}
|
||||
|
||||
/* add the incoming hunk to the chain ctx->in */
|
||||
|
||||
if (hunk) {
|
||||
le = &ctx->in;
|
||||
|
||||
for (ce = ctx->in; ce; ce = ce->next) {
|
||||
le = &ce->next;
|
||||
if (in) {
|
||||
if (ngx_chain_add_copy(r->pool, &ctx->in, in) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -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_headers(ngx_event_t *rev);
|
||||
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);
|
||||
|
||||
@ -256,7 +257,8 @@ ngx_log_debug(rev->log, "IN: %08x" _ in_port);
|
||||
r->file.fd = NGX_INVALID_FILE;
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
int rc, i, offset;
|
||||
size_t len;
|
||||
ssize_t n;
|
||||
ngx_table_elt_t *h;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_server_name_t *name;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
c = rev->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");
|
||||
|
||||
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;
|
||||
rc = ngx_http_process_request_header(r);
|
||||
|
||||
/* 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);
|
||||
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 (rc != NGX_OK) {
|
||||
ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
ngx_hunk_t *h;
|
||||
ngx_hunk_t *h;
|
||||
ngx_chain_t out;
|
||||
|
||||
ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
|
||||
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_POST 3
|
||||
|
||||
#define NGX_HTTP_CONN_CLOSE 0
|
||||
#define NGX_HTTP_CONN_KEEP_ALIVE 1
|
||||
#define NGX_HTTP_CONNECTION_CLOSE 1
|
||||
#define NGX_HTTP_CONNECTION_KEEP_ALIVE 2
|
||||
|
||||
|
||||
#define NGX_NONE 1
|
||||
#define NGX_NONE 1
|
||||
|
||||
|
||||
#define NGX_HTTP_PARSE_HEADER_DONE 1
|
||||
@ -63,9 +63,6 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
size_t host_name_len;
|
||||
ssize_t content_length_n;
|
||||
|
||||
ngx_table_elt_t *host;
|
||||
ngx_table_elt_t *connection;
|
||||
ngx_table_elt_t *if_modified_since;
|
||||
@ -77,6 +74,11 @@ typedef struct {
|
||||
ngx_table_elt_t *user_agent;
|
||||
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_http_headers_in_t;
|
||||
|
||||
@ -107,6 +109,7 @@ typedef struct {
|
||||
ngx_table_elt_t *server;
|
||||
ngx_table_elt_t *date;
|
||||
ngx_table_elt_t *content_type;
|
||||
ngx_table_elt_t *content_length;
|
||||
ngx_table_elt_t *content_encoding;
|
||||
ngx_table_elt_t *location;
|
||||
ngx_table_elt_t *last_modified;
|
||||
@ -118,7 +121,7 @@ typedef struct {
|
||||
|
||||
ngx_table_t *headers;
|
||||
|
||||
off_t content_length;
|
||||
off_t content_length_n;
|
||||
char *etag;
|
||||
time_t date_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 err, rc;
|
||||
ngx_hunk_t *h;
|
||||
int err, rc;
|
||||
ngx_hunk_t *h;
|
||||
ngx_chain_t *out, **le, *ce;
|
||||
|
||||
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) {
|
||||
r->headers_out.content_length = error_pages[err].len
|
||||
+ sizeof(error_tail) - 1
|
||||
+ sizeof(msie_stub) - 1;
|
||||
r->headers_out.content_length_n = error_pages[err].len
|
||||
+ sizeof(error_tail) - 1
|
||||
+ sizeof(msie_stub) - 1;
|
||||
|
||||
ngx_test_null(r->headers_out.content_type,
|
||||
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";
|
||||
|
||||
} 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);
|
||||
@ -216,41 +218,42 @@ int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
|
||||
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->pos = error_pages[err].data;
|
||||
h->last = error_pages[err].data + error_pages[err].len;
|
||||
|
||||
if (ngx_http_output_filter(r, h) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
ngx_alloc_ce_and_set_hunk(ce, h, r->pool, NGX_ERROR);
|
||||
ngx_chain_add_ce(out, le, ce);
|
||||
|
||||
|
||||
ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
|
||||
|
||||
h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
|
||||
h->pos = error_tail;
|
||||
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
|
||||
&& r->http_version >= NGX_HTTP_VERSION_10
|
||||
&& error >= NGX_HTTP_BAD_REQUEST
|
||||
&& 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);
|
||||
|
||||
h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
|
||||
h->pos = msie_stub;
|
||||
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;
|
||||
|
||||
return ngx_http_output_filter(r, h);
|
||||
return ngx_http_output_filter(r, out);
|
||||
}
|
||||
|
@ -5,11 +5,6 @@
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
ssize_t buffer_output;
|
||||
} ngx_http_write_filter_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_chain_t *out;
|
||||
} ngx_http_write_filter_ctx_t;
|
||||
@ -23,6 +18,13 @@ static int ngx_http_write_filter_init(ngx_cycle_t *cycle);
|
||||
|
||||
static ngx_command_t ngx_http_write_filter_commands[] = {
|
||||
|
||||
{ngx_string("sendfile"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_write_filter_conf_t, sendfile),
|
||||
NULL},
|
||||
|
||||
{ngx_string("buffer_output"),
|
||||
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
@ -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) {
|
||||
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)) {
|
||||
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;
|
||||
}
|
||||
size += ngx_hunk_size(ce->hunk);
|
||||
|
||||
if (ce->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) {
|
||||
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,
|
||||
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)
|
||||
ngx_log_debug(r->connection->log,
|
||||
"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);
|
||||
|
||||
conf->buffer_output = NGX_CONF_UNSET;
|
||||
conf->sendfile = NGX_CONF_UNSET;
|
||||
|
||||
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_conf_merge_size_value(conf->buffer_output, prev->buffer_output, 1460);
|
||||
ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -154,6 +154,11 @@ ngx_log_debug(c->log, "NOPUSH");
|
||||
hdtr.trailers = (struct iovec *) trailer.elts;
|
||||
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) {
|
||||
hsize = 0;
|
||||
}
|
||||
@ -194,7 +199,6 @@ ngx_log_debug(c->log, "NOPUSH");
|
||||
if (rc == -1) {
|
||||
err = ngx_errno;
|
||||
if (err == NGX_EAGAIN) {
|
||||
eagain = 1;
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN");
|
||||
|
||||
} else if (err == NGX_EINTR) {
|
||||
@ -256,6 +260,11 @@ ngx_log_debug(c->log, "NOPUSH");
|
||||
in = ce;
|
||||
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user