mirror of
https://github.com/nginx/nginx.git
synced 2024-12-18 15:47:47 +08:00
nginx-0.0.1-2003-10-17-00:19:16 import
This commit is contained in:
parent
e4aabac04e
commit
d404c97163
@ -36,11 +36,11 @@ typedef struct ngx_connection_s ngx_connection_t;
|
|||||||
#define NGX_OK 0
|
#define NGX_OK 0
|
||||||
#define NGX_ERROR -1
|
#define NGX_ERROR -1
|
||||||
#define NGX_AGAIN -2
|
#define NGX_AGAIN -2
|
||||||
|
#define NGX_DONE -3
|
||||||
#define NGX_DECLINED -4
|
#define NGX_DECLINED -4
|
||||||
#define NGX_ABORT -5
|
#define NGX_ABORT -5
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define NGX_DONE -3
|
|
||||||
#define NGX_BUSY -3
|
#define NGX_BUSY -3
|
||||||
#define NGX_ALERT -5
|
#define NGX_ALERT -5
|
||||||
*/
|
*/
|
||||||
|
@ -85,9 +85,9 @@ typedef struct {
|
|||||||
(h->type == (h->type & (NGX_HUNK_FLUSH|NGX_HUNK_LAST)))
|
(h->type == (h->type & (NGX_HUNK_FLUSH|NGX_HUNK_LAST)))
|
||||||
|
|
||||||
|
|
||||||
#define nxg_hunk_size(h) \
|
#define ngx_hunk_size(h) \
|
||||||
(h->type & NGX_HUNK_IN_MEMORY) ? h->last - h->pos: \
|
((h->type & NGX_HUNK_IN_MEMORY) ? h->last - h->pos: \
|
||||||
(size_t) h->file_last - h->file_pos
|
(size_t) (h->file_last - h->file_pos))
|
||||||
|
|
||||||
|
|
||||||
ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,
|
ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,
|
||||||
@ -108,14 +108,13 @@ ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,
|
|||||||
#define ngx_alloc_ce_and_set_hunk ngx_add_hunk_to_chain
|
#define ngx_alloc_ce_and_set_hunk ngx_add_hunk_to_chain
|
||||||
|
|
||||||
|
|
||||||
#define ngx_chain_add_ce(ngx_chain_t *chain, ngx_chain_t **last, \
|
#define ngx_chain_add_ce(chain, last, ce) \
|
||||||
ngx_chain_t *ce) \
|
|
||||||
if (chain) { \
|
if (chain) { \
|
||||||
last->next = ce; \
|
*last = ce; \
|
||||||
} else { \
|
} else { \
|
||||||
chain = ce; \
|
chain = ce; \
|
||||||
} \
|
} \
|
||||||
last = ce;
|
last = &ce->next
|
||||||
|
|
||||||
|
|
||||||
int ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **ch, ngx_chain_t *in);
|
int ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **ch, ngx_chain_t *in);
|
||||||
|
@ -89,7 +89,7 @@ ngx_module_t *ngx_modules[] = {
|
|||||||
/* &ngx_http_ssi_filter_module, */
|
/* &ngx_http_ssi_filter_module, */
|
||||||
&ngx_http_charset_filter_module,
|
&ngx_http_charset_filter_module,
|
||||||
|
|
||||||
/* &ngx_http_static_module, */
|
&ngx_http_static_module,
|
||||||
&ngx_http_index_module,
|
&ngx_http_index_module,
|
||||||
&ngx_http_proxy_module,
|
&ngx_http_proxy_module,
|
||||||
|
|
||||||
|
@ -220,6 +220,8 @@ int ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
|||||||
return NGX_AGAIN;
|
return NGX_AGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wev->ready = 1;
|
||||||
|
|
||||||
if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
|
if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -4,21 +4,27 @@
|
|||||||
#include <ngx_event.h>
|
#include <ngx_event.h>
|
||||||
#include <ngx_event_proxy.h>
|
#include <ngx_event_proxy.h>
|
||||||
|
|
||||||
|
static int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_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);
|
||||||
|
|
||||||
|
|
||||||
int ngx_event_proxy_read_upstream(ngx_event_proxy_t *p)
|
int ngx_event_proxy_read_upstream(ngx_event_proxy_t *p)
|
||||||
{
|
{
|
||||||
int n, rc, size;
|
int n, rc, size;
|
||||||
ngx_hunk_t *h, *nh;
|
ngx_hunk_t *h;
|
||||||
ngx_chain_t *chain, *rest, *ce, *next;
|
ngx_chain_t *chain, *ce, *te;
|
||||||
|
|
||||||
rest = NULL;
|
|
||||||
|
|
||||||
p->upstream_level++;
|
p->upstream_level++;
|
||||||
|
|
||||||
ngx_log_debug(p->log, "read upstream");
|
ngx_log_debug(p->log, "read upstream: %d" _ p->upstream->read->ready);
|
||||||
|
|
||||||
for ( ;; ) {
|
|
||||||
|
|
||||||
|
while (p->preread_hunks
|
||||||
|
|| (p->upstream->read->ready && !p->upstream_done))
|
||||||
|
{
|
||||||
if (p->preread_hunks) {
|
if (p->preread_hunks) {
|
||||||
|
|
||||||
/* use the pre-read hunks if they exist */
|
/* use the pre-read hunks if they exist */
|
||||||
@ -27,7 +33,7 @@ ngx_log_debug(p->log, "read upstream");
|
|||||||
p->preread_hunks = NULL;
|
p->preread_hunks = NULL;
|
||||||
n = p->preread_size;
|
n = p->preread_size;
|
||||||
|
|
||||||
ngx_log_debug(p->log, "preread: %d" _ n);
|
ngx_log_debug(p->log, "preread: %d" _ n);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -46,24 +52,14 @@ ngx_log_debug(p->log, "preread: %d" _ n);
|
|||||||
"readv() failed");
|
"readv() failed");
|
||||||
p->upstream_error = 1;
|
p->upstream_error = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
} else if (p->upstream->read->eof
|
} else if (p->upstream->read->eof
|
||||||
&& p->upstream->read->available == 0) {
|
&& p->upstream->read->available == 0) {
|
||||||
p->upstream_eof = 1;
|
p->upstream_eof = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((p->upstream_eof || p->upstream_error)
|
|
||||||
&& p->free_raw_hunk)
|
|
||||||
{
|
|
||||||
if (p->input_filter(p->input_data, p->free_raw_hunk->hunk)
|
|
||||||
== NGX_ERROR) {
|
|
||||||
return NGX_ABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: p->free_raw_hunk->next can be free()ed */
|
|
||||||
p->free_raw_hunk = p->free_raw_hunk->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -74,23 +70,18 @@ ngx_log_debug(p->log, "preread: %d" _ n);
|
|||||||
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 hunk: %08X:%d" _ chain->hunk _
|
|
||||||
chain->hunk->end - chain->hunk->last);
|
|
||||||
|
|
||||||
} else if (p->hunks < p->bufs.num) {
|
} else if (p->hunks < p->bufs.num) {
|
||||||
|
|
||||||
/* allocate a new hunk if it's still allowed */
|
/* allocate a new hunk if it's still allowed */
|
||||||
|
|
||||||
ngx_test_null(h, ngx_create_temp_hunk(p->pool,
|
ngx_test_null(h, ngx_create_temp_hunk(p->pool,
|
||||||
p->bufs.size, 20, 20);
|
p->bufs.size, 0, 0),
|
||||||
NGX_ABORT);
|
NGX_ABORT);
|
||||||
p->hunks++;
|
p->hunks++;
|
||||||
|
|
||||||
ngx_alloc_ce_and_set_hunk(te, h, p->pool, NGX_ABORT);
|
ngx_alloc_ce_and_set_hunk(te, h, p->pool, NGX_ABORT);
|
||||||
chain = te;
|
chain = te;
|
||||||
|
|
||||||
ngx_log_debug(p->log, "new hunk: %08X" _ chain->hunk);
|
|
||||||
|
|
||||||
} else if (!p->cachable && p->downstream->write->ready) {
|
} else if (!p->cachable && p->downstream->write->ready) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -98,7 +89,7 @@ ngx_log_debug(p->log, "new hunk: %08X" _ chain->hunk);
|
|||||||
* 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;
|
||||||
|
|
||||||
@ -111,7 +102,7 @@ ngx_log_debug(p->log, "downstream ready");
|
|||||||
|
|
||||||
rc = ngx_event_proxy_write_chain_to_temp_file(p);
|
rc = ngx_event_proxy_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);
|
||||||
|
|
||||||
if (rc == NGX_AGAIN) {
|
if (rc == NGX_AGAIN) {
|
||||||
if (ngx_event_flags & NGX_USE_LEVEL_EVENT
|
if (ngx_event_flags & NGX_USE_LEVEL_EVENT
|
||||||
@ -133,21 +124,18 @@ ngx_log_debug(p->log, "temp offset: %d" _ p->temp_offset);
|
|||||||
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, "new file hunk: %08X:%d" _ chain->hunk _
|
|
||||||
chain->hunk->end - chain->hunk->last);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* if there're no hunks to read in then disable a level event */
|
/* if there're no hunks to read in then disable a level event */
|
||||||
|
|
||||||
ngx_log_debug(p->log, "no hunks to read in");
|
ngx_log_debug(p->log, "no hunks to read in");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = ngx_recv_chain(p->upstream, chain);
|
n = ngx_recv_chain(p->upstream, chain);
|
||||||
|
|
||||||
ngx_log_debug(p->log, "recv_chain: %d" _ n);
|
ngx_log_debug(p->log, "recv_chain: %d" _ n);
|
||||||
|
|
||||||
if (n == NGX_ERROR) {
|
if (n == NGX_ERROR) {
|
||||||
p->upstream_error = 1;
|
p->upstream_error = 1;
|
||||||
@ -159,10 +147,7 @@ ngx_log_debug(p->log, "recv_chain: %d" _ n);
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
THINK
|
p->free_raw_hunks = chain;
|
||||||
if (chain->hunk->shadow == NULL) {
|
|
||||||
p->free_hunks = chain;
|
|
||||||
}
|
|
||||||
p->upstream_eof = 1;
|
p->upstream_eof = 1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -172,180 +157,41 @@ ngx_log_debug(p->log, "recv_chain: %d" _ n);
|
|||||||
|
|
||||||
for (ce = chain; ce && n > 0; ce = ce->next) {
|
for (ce = chain; ce && n > 0; ce = ce->next) {
|
||||||
|
|
||||||
size = ce->hunk->end - ce->hunk->last;
|
ngx_remove_shadow_links(ce->hunk);
|
||||||
|
|
||||||
if (n >= size) {
|
|
||||||
ce->hunk->last = ce->hunk->end;
|
|
||||||
|
|
||||||
if (p->input_filter(p->input_data, ce->hunk) == NGX_ERROR) {
|
|
||||||
return NGX_ABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
n -= size;
|
|
||||||
|
|
||||||
} else if (p->upstream_eof || p->upstream_error) {
|
|
||||||
|
|
||||||
if (p->input_filter(p->input_data, ce->hunk) == NGX_ERROR) {
|
|
||||||
return NGX_ABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ce->hunk->last += n;
|
|
||||||
n = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
next = ce->next;
|
|
||||||
ce->next = NULL;
|
|
||||||
|
|
||||||
if (ce->hunk->shadow) {
|
|
||||||
for (h = ce->hunk->shadow;
|
|
||||||
(h->type & NGX_HUNK_LAST_SHADOW) == 0;
|
|
||||||
h = nh)
|
|
||||||
{
|
|
||||||
nh = h->shadow;
|
|
||||||
h->shadow = NULL;
|
|
||||||
h->type &= ~(NGX_HUNK_TEMP
|
|
||||||
|NGX_HUNK_IN_MEMORY
|
|
||||||
|NGX_HUNK_RECYCLED);
|
|
||||||
}
|
|
||||||
|
|
||||||
h->shadow = NULL;
|
|
||||||
h->type &= ~(NGX_HUNK_TEMP
|
|
||||||
|NGX_HUNK_IN_MEMORY
|
|
||||||
|NGX_HUNK_RECYCLED
|
|
||||||
|NGX_HUNK_LAST_SHADOW);
|
|
||||||
ce->hunk->shadow = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = ce->hunk->end - ce->hunk->last;
|
size = ce->hunk->end - ce->hunk->last;
|
||||||
|
|
||||||
if (n >= size) {
|
if (n >= size) {
|
||||||
ce->hunk->last = ce->hunk->end;
|
ce->hunk->last = ce->hunk->end;
|
||||||
|
|
||||||
if (p->read_hunks) {
|
if (p->input_filter(p, ce->hunk) == NGX_ERROR) {
|
||||||
p->last_read_hunk->next = ce;
|
return NGX_ABORT;
|
||||||
|
|
||||||
} else {
|
|
||||||
p->read_hunks = ce;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p->last_read_hunk = ce;
|
|
||||||
|
|
||||||
n -= size;
|
n -= size;
|
||||||
|
|
||||||
|
chain = ce->next;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ce->hunk->last += n;
|
ce->hunk->last += n;
|
||||||
p->free_hunks = ce;
|
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chain == p->free_hunks) {
|
p->free_raw_hunks = chain;
|
||||||
chain = NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
if ((p->upstream_eof || p->upstream_error) && p->free_raw_hunks) {
|
||||||
* the input filter i.e. that moves HTTP/1.1 chunks
|
if (p->input_filter(p, p->free_raw_hunks->hunk) == NGX_ERROR) {
|
||||||
* from a read chain to an incoming chain
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (p->input_filter(p, chain) == NGX_ERROR) {
|
|
||||||
return NGX_ABORT;
|
return NGX_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug(p->log, "rest chain: %08X" _ ce);
|
/* TODO: p->free_raw_hunk->next can be free()ed */
|
||||||
|
p->free_raw_hunks = p->free_raw_hunks->next;
|
||||||
/*
|
|
||||||
* if the rest hunks are file hunks then move them to a file chain
|
|
||||||
* otherwise add them to a free chain
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (rest) {
|
|
||||||
if (rest->hunk->shadow) {
|
|
||||||
p->file_hunks = rest;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (p->free_hunks) {
|
|
||||||
p->free_hunks->next = rest;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
p->free_hunks = rest;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_log_debug(p->log, "eof: %d" _ p->upstream_eof);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if there's the end of upstream response then move
|
|
||||||
* the partially filled hunk from a free chain to an incoming chain
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (p->upstream_eof) {
|
|
||||||
if (p->free_hunks
|
|
||||||
&& p->free_hunks->hunk->pos < p->free_hunks->hunk->last)
|
|
||||||
{
|
|
||||||
|
|
||||||
#if (NGX_EVENT_COPY_FILTER)
|
|
||||||
|
|
||||||
if (p->input_filter(p, NULL) == NGX_ERROR) {
|
|
||||||
return NGX_ABORT;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (p->input_filter) {
|
|
||||||
if (p->input_filter(p, NULL) == NGX_ERROR) {
|
|
||||||
return NGX_ABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ce = p->free_hunks;
|
|
||||||
|
|
||||||
if (p->in_hunks) {
|
|
||||||
p->last_in_hunk->next = ce;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
p->in_hunks = ce;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->last_in_hunk = ce;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->free_hunks = ce->next;
|
|
||||||
ce->next = NULL;
|
|
||||||
|
|
||||||
#endif /* NGX_EVENT_COPY_FILTER */
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* free the unneeded hunks */
|
|
||||||
|
|
||||||
for (ce = p->free_hunks; ce; ce = ce->next) {
|
|
||||||
ngx_free_hunk(p->pool, ce->hunk);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (p->in_hunks) {
|
|
||||||
p->last_in_hunk->hunk->type |= NGX_HUNK_LAST;
|
|
||||||
|
|
||||||
} else if (p->out_hunks) {
|
|
||||||
p->last_out_hunk->hunk->type |= NGX_HUNK_LAST;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->cachable) {
|
if (p->cachable) {
|
||||||
if (p->in_hunks) {
|
if (p->in) {
|
||||||
rc = ngx_event_proxy_write_chain_to_temp_file(p);
|
rc = ngx_event_proxy_write_chain_to_temp_file(p);
|
||||||
|
|
||||||
if (rc != NGX_OK) {
|
if (rc != NGX_OK) {
|
||||||
@ -353,13 +199,13 @@ ngx_log_debug(p->log, "eof: %d" _ p->upstream_eof);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->out_hunks && p->downstream->write->ready) {
|
if (p->out && p->downstream->write->ready) {
|
||||||
if (ngx_event_proxy_write_to_downstream(p) == NGX_ABORT) {
|
if (ngx_event_proxy_write_to_downstream(p) == NGX_ABORT) {
|
||||||
return NGX_ABORT;
|
return NGX_ABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((p->out_hunks || p->in_hunks) && p->downstream->write->ready) {
|
} else if ((p->out || p->in) && p->downstream->write->ready) {
|
||||||
if (ngx_event_proxy_write_to_downstream(p) == NGX_ABORT) {
|
if (ngx_event_proxy_write_to_downstream(p) == NGX_ABORT) {
|
||||||
return NGX_ABORT;
|
return NGX_ABORT;
|
||||||
}
|
}
|
||||||
@ -375,25 +221,22 @@ ngx_log_debug(p->log, "upstream level: %d" _ p->upstream_level);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->upstream_eof) {
|
return NGX_OK;
|
||||||
return NGX_OK;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return NGX_AGAIN;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p)
|
int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p)
|
||||||
{
|
{
|
||||||
ngx_chain_t *out, *ce;
|
int rc;
|
||||||
|
ngx_hunk_t *h;
|
||||||
|
ngx_chain_t *out, *ce, *te;
|
||||||
|
|
||||||
while (p->downstream->write->ready) {
|
while (p->downstream->write->ready) {
|
||||||
|
|
||||||
if (p->out) {
|
if (p->out) {
|
||||||
out = p->out;
|
out = p->out;
|
||||||
|
|
||||||
if (p->busy_len + ngx_hunk_size(out->hunk)) > p->max_busy_len) {
|
if (p->busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,7 +246,7 @@ int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p)
|
|||||||
} else if (!p->cachable && p->in) {
|
} else if (!p->cachable && p->in) {
|
||||||
out = p->in;
|
out = p->in;
|
||||||
|
|
||||||
if (p->busy_len + ngx_hunk_size(out->hunk)) > p->max_busy_len) {
|
if (p->busy_len + ngx_hunk_size(out->hunk) > p->max_busy_len) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,9 +258,9 @@ int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p)
|
|||||||
|
|
||||||
out->next = NULL;
|
out->next = NULL;
|
||||||
|
|
||||||
rc = p->output_filter(p->output_data, out->hunk);
|
rc = p->output_filter(p->output_ctx, out->hunk);
|
||||||
|
|
||||||
ngx_chain_update_chains(p->free, p->busy, out);
|
ngx_chain_update_chains(&p->free, &p->busy, &out);
|
||||||
|
|
||||||
/* calculate p->busy_len */
|
/* calculate p->busy_len */
|
||||||
|
|
||||||
@ -435,14 +278,14 @@ int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p)
|
|||||||
h->shadow = NULL;
|
h->shadow = NULL;
|
||||||
ngx_alloc_ce_and_set_hunk(te, ce->hunk->shadow, p->pool,
|
ngx_alloc_ce_and_set_hunk(te, ce->hunk->shadow, p->pool,
|
||||||
NGX_ABORT);
|
NGX_ABORT);
|
||||||
ngx_add_after_partially_filled_hunk(p->free_raw_hunks, te);
|
ngx_add_after_partially_filled_hunk(&p->free_raw_hunks, te);
|
||||||
|
|
||||||
ce->hunk->type &= ~NGX_HUNK_LAST_SHADOW;
|
ce->hunk->type &= ~NGX_HUNK_LAST_SHADOW;
|
||||||
}
|
}
|
||||||
ce->hunk->shadow = NULL;
|
ce->hunk->shadow = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->upstream.read->ready)
|
if (p->upstream->read->ready) {
|
||||||
if (ngx_event_proxy_read_upstream(p) == NGX_ERROR) {
|
if (ngx_event_proxy_read_upstream(p) == NGX_ERROR) {
|
||||||
return NGX_ABORT;
|
return NGX_ABORT;
|
||||||
}
|
}
|
||||||
@ -450,7 +293,8 @@ int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (p->downstream_level == 0) {
|
if (p->downstream_level == 0) {
|
||||||
if (ngx_handler_write_event(p->downstream->write) == NGX_ERROR) {
|
if (ngx_handle_write_event(p->downstream->write,
|
||||||
|
/* TODO: lowat */ 0) == NGX_ERROR) {
|
||||||
return NGX_ABORT;
|
return NGX_ABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,13 +307,13 @@ int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p)
|
static int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p)
|
||||||
{
|
{
|
||||||
int rc, size;
|
int rc, size;
|
||||||
ngx_hunk_t *h;
|
ngx_hunk_t *h;
|
||||||
ngx_chain_t *entry, *next, *saved_in, *saved_read;
|
ngx_chain_t *ce, *next, *in, **last;
|
||||||
|
|
||||||
ngx_log_debug(p->log, "write to file");
|
ngx_log_debug(p->log, "write to file");
|
||||||
|
|
||||||
if (p->temp_file->fd == NGX_INVALID_FILE) {
|
if (p->temp_file->fd == NGX_INVALID_FILE) {
|
||||||
rc = ngx_create_temp_file(p->temp_file, p->temp_path, p->pool,
|
rc = ngx_create_temp_file(p->temp_file, p->temp_path, p->pool,
|
||||||
@ -483,86 +327,59 @@ ngx_log_debug(p->log, "write to file");
|
|||||||
return NGX_AGAIN;
|
return NGX_AGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->cachable == 0 && p->temp_file_warn) {
|
if (!p->cachable && p->temp_file_warn) {
|
||||||
ngx_log_error(NGX_LOG_WARN, p->log, 0, p->temp_file_warn);
|
ngx_log_error(NGX_LOG_WARN, p->log, 0, p->temp_file_warn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->cachable == 0) {
|
if (!p->cachable) {
|
||||||
|
|
||||||
entry = p->read_hunks;
|
|
||||||
size = 0;
|
size = 0;
|
||||||
|
ce = p->in;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
size += entry->hunk->last - entry->hunk->pos;
|
size += ce->hunk->last - ce->hunk->pos;
|
||||||
if (size >= p->temp_file_write_size) {
|
if (size >= p->temp_file_write_size) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
entry = entry->next;
|
ce = ce->next;
|
||||||
|
|
||||||
} while (entry);
|
} while (ce);
|
||||||
|
|
||||||
saved_read = entry->next;
|
in = ce->next;
|
||||||
entry->next = NULL;
|
last = &ce->next;
|
||||||
|
ce->next = NULL;
|
||||||
if (saved_read) {
|
|
||||||
for (entry = p->in_hunks; entry->next; entry = entry->next) {
|
|
||||||
if (entry->next->hunk->shadow == saved_read->hunk) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
saved_in = entry->next;
|
|
||||||
entry->next = NULL;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
saved_in = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
saved_read = NULL;
|
in = NULL;
|
||||||
saved_in = NULL;
|
last = &p->in;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_write_chain_to_file(p->temp_file, p->in_hunks, p->temp_offset,
|
if (ngx_write_chain_to_file(p->temp_file, p->in, p->temp_offset,
|
||||||
p->pool) == NGX_ERROR) {
|
p->pool) == NGX_ERROR) {
|
||||||
return NGX_ABORT;
|
return NGX_ABORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (entry = p->in_hunks; entry; entry = next) {
|
for (ce = p->in; ce; ce = next) {
|
||||||
next = entry->next;
|
next = ce->next;
|
||||||
entry->next = NULL;
|
ce->next = NULL;
|
||||||
|
|
||||||
h = entry->hunk;
|
h = ce->hunk;
|
||||||
h->type |= NGX_HUNK_FILE;
|
h->type |= NGX_HUNK_FILE;
|
||||||
h->file = p->temp_file;
|
h->file = p->temp_file;
|
||||||
h->file_pos = p->temp_offset;
|
h->file_pos = p->temp_offset;
|
||||||
p->temp_offset += h->last - h->pos;
|
p->temp_offset += h->last - h->pos;
|
||||||
h->file_last = p->temp_offset;
|
h->file_last = p->temp_offset;
|
||||||
|
|
||||||
ngx_log_debug(p->log, "event proxy file hunk: %08X:%08X" _ h _ h->shadow);
|
|
||||||
|
|
||||||
if (h->type & NGX_HUNK_LAST_SHADOW) {
|
if (h->type & NGX_HUNK_LAST_SHADOW) {
|
||||||
#if 0
|
|
||||||
h->shadow->last = h->shadow->pos;
|
|
||||||
#else
|
|
||||||
h->shadow->last = h->shadow->pos = h->shadow->start;
|
h->shadow->last = h->shadow->pos = h->shadow->start;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->out_hunks) {
|
ngx_chain_add_ce(p->out, p->last_out, ce);
|
||||||
p->last_out_hunk->next = entry;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
p->out_hunks = entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->last_out_hunk = entry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p->file_hunks = p->read_hunks;
|
p->in = in;
|
||||||
|
p->last_in = last;
|
||||||
p->read_hunks = saved_read;
|
|
||||||
p->in_hunks = saved_in;
|
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
@ -593,22 +410,44 @@ int ngx_event_proxy_copy_input_filter(ngx_event_proxy_t *p, ngx_hunk_t *hunk)
|
|||||||
hunk->shadow = h;
|
hunk->shadow = h;
|
||||||
|
|
||||||
ngx_alloc_ce_and_set_hunk(ce, h, p->pool, NGX_ERROR);
|
ngx_alloc_ce_and_set_hunk(ce, h, p->pool, NGX_ERROR);
|
||||||
ngx_chain_add_ce(p->in_hunk, p->last_in_hunk, ce);
|
ngx_chain_add_ce(p->in, p->last_in, ce);
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngx_inline static void ngx_remove_shadow_links(ngx_chain_t *ce)
|
ngx_inline static void ngx_remove_shadow_links(ngx_hunk_t *hunk)
|
||||||
{
|
{
|
||||||
for (
|
ngx_hunk_t *h, *next;
|
||||||
|
|
||||||
|
if (hunk->shadow == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
h = hunk->shadow;
|
||||||
|
|
||||||
|
while (!(h->type & NGX_HUNK_LAST_SHADOW)) {
|
||||||
|
next = h->shadow;
|
||||||
|
h->type &= ~(NGX_HUNK_TEMP|NGX_HUNK_IN_MEMORY|NGX_HUNK_RECYCLED);
|
||||||
|
h->shadow = NULL;
|
||||||
|
h = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
h->type &= ~(NGX_HUNK_TEMP
|
||||||
|
|NGX_HUNK_IN_MEMORY
|
||||||
|
|NGX_HUNK_RECYCLED
|
||||||
|
|NGX_HUNK_LAST_SHADOW);
|
||||||
|
h->shadow = NULL;
|
||||||
|
|
||||||
|
hunk->shadow = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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_hunk_t *s;
|
ngx_hunk_t *s;
|
||||||
|
ngx_chain_t *ce, **le;
|
||||||
|
|
||||||
if (h->shadow == NULL) {
|
if (h->shadow == NULL) {
|
||||||
return;
|
return;
|
||||||
@ -635,15 +474,20 @@ ngx_inline static void ngx_remove_shadow_free_raw_hunk(ngx_chain_t **free;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
if (chain->hunk->pos != chain->hunk->last) {
|
if (*chain == NULL) {
|
||||||
ce->next = chain->next;
|
*chain = ce;
|
||||||
chain->next = ce;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*chain)->hunk->pos != (*chain)->hunk->last) {
|
||||||
|
ce->next = (*chain)->next;
|
||||||
|
(*chain)->next = ce;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ce->next = chain;
|
ce->next = (*chain);
|
||||||
chain = ce;
|
(*chain) = ce;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,40 +10,37 @@
|
|||||||
typedef struct ngx_event_proxy_s ngx_event_proxy_t;
|
typedef struct ngx_event_proxy_s ngx_event_proxy_t;
|
||||||
|
|
||||||
typedef int (*ngx_event_proxy_input_filter_pt)(ngx_event_proxy_t *p,
|
typedef int (*ngx_event_proxy_input_filter_pt)(ngx_event_proxy_t *p,
|
||||||
ngx_chain_t *chain);
|
ngx_hunk_t *hunk);
|
||||||
typedef int (*ngx_event_proxy_output_filter_pt)(void *data, ngx_hunk_t *hunk);
|
typedef int (*ngx_event_proxy_output_filter_pt)(void *data, ngx_hunk_t *hunk);
|
||||||
|
|
||||||
|
|
||||||
struct ngx_event_proxy_s {
|
struct ngx_event_proxy_s {
|
||||||
ngx_chain_t *read_hunks;
|
ngx_chain_t *free_raw_hunks;
|
||||||
ngx_chain_t *last_read_hunk;
|
ngx_chain_t *in;
|
||||||
|
ngx_chain_t **last_in;
|
||||||
|
|
||||||
ngx_chain_t *file_hunks;
|
ngx_chain_t *out;
|
||||||
|
ngx_chain_t **last_out;
|
||||||
|
|
||||||
ngx_chain_t *in_hunks;
|
ngx_chain_t *free;
|
||||||
ngx_chain_t *last_in_hunk;
|
ngx_chain_t *busy;
|
||||||
|
|
||||||
ngx_chain_t *out_hunks;
|
/*
|
||||||
ngx_chain_t *last_out_hunk;
|
* the input filter i.e. that moves HTTP/1.1 chunks
|
||||||
|
* from the raw hunks to an incoming chain
|
||||||
|
*/
|
||||||
|
|
||||||
ngx_chain_t *free_hunks;
|
ngx_event_proxy_input_filter_pt input_filter;
|
||||||
#if 0
|
void *input_ctx;
|
||||||
ngx_chain_t *last_free_hunk;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ngx_hunk_t *busy_hunk;
|
ngx_event_proxy_output_filter_pt output_filter;
|
||||||
|
void *output_ctx;
|
||||||
ngx_event_proxy_input_filter_pt input_filter;
|
|
||||||
void *input_data;
|
|
||||||
|
|
||||||
ngx_event_proxy_output_filter_pt output_filter;
|
|
||||||
void *output_data;
|
|
||||||
|
|
||||||
unsigned cachable:1;
|
unsigned cachable:1;
|
||||||
unsigned block_upstream:1;
|
unsigned upstream_done:1;
|
||||||
unsigned upstream_eof:1;
|
unsigned upstream_eof:1;
|
||||||
unsigned upstream_error:1;
|
unsigned upstream_error:1;
|
||||||
unsigned downstream_eof:1;
|
unsigned downstream_done:1;
|
||||||
unsigned downstream_error:1;
|
unsigned downstream_error:1;
|
||||||
|
|
||||||
int upstream_level;
|
int upstream_level;
|
||||||
@ -52,6 +49,9 @@ struct ngx_event_proxy_s {
|
|||||||
int hunks;
|
int hunks;
|
||||||
ngx_bufs_t bufs;
|
ngx_bufs_t bufs;
|
||||||
|
|
||||||
|
size_t busy_len;
|
||||||
|
size_t max_busy_len;
|
||||||
|
|
||||||
off_t temp_offset;
|
off_t temp_offset;
|
||||||
off_t max_temp_file_size;
|
off_t max_temp_file_size;
|
||||||
int temp_file_write_size;
|
int temp_file_write_size;
|
||||||
@ -63,9 +63,6 @@ struct ngx_event_proxy_s {
|
|||||||
ngx_log_t *log;
|
ngx_log_t *log;
|
||||||
|
|
||||||
ngx_chain_t *preread_hunks;
|
ngx_chain_t *preread_hunks;
|
||||||
#if 0
|
|
||||||
ngx_chain_t *last_preread_hunk;
|
|
||||||
#endif
|
|
||||||
int preread_size;
|
int preread_size;
|
||||||
|
|
||||||
ngx_file_t *temp_file;
|
ngx_file_t *temp_file;
|
||||||
@ -76,7 +73,7 @@ struct ngx_event_proxy_s {
|
|||||||
|
|
||||||
int ngx_event_proxy_read_upstream(ngx_event_proxy_t *p);
|
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_proxy_write_to_downstream(ngx_event_proxy_t *p);
|
||||||
int ngx_event_proxy_copy_input_filter(ngx_event_proxy_t *p, ngx_chain_t *chain);
|
int ngx_event_proxy_copy_input_filter(ngx_event_proxy_t *p, ngx_hunk_t *hunk);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _NGX_EVENT_PROXY_H_INCLUDED_ */
|
#endif /* _NGX_EVENT_PROXY_H_INCLUDED_ */
|
||||||
|
@ -79,7 +79,7 @@ ngx_module_t ngx_http_index_module = {
|
|||||||
|
|
||||||
int ngx_http_index_handler(ngx_http_request_t *r)
|
int ngx_http_index_handler(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
int i, rc, test_dir, path_not_found;
|
int rc;
|
||||||
char *name, *file;
|
char *name, *file;
|
||||||
ngx_str_t redirect, *index;
|
ngx_str_t redirect, *index;
|
||||||
ngx_err_t err;
|
ngx_err_t err;
|
||||||
@ -132,7 +132,7 @@ int ngx_http_index_handler(ngx_http_request_t *r)
|
|||||||
|
|
||||||
fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN);
|
fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN);
|
||||||
|
|
||||||
if (fd == NGX_AGAIN) {
|
if (fd == (ngx_fd_t) NGX_AGAIN) {
|
||||||
return NGX_AGAIN;
|
return NGX_AGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,188 @@
|
|||||||
#include <ngx_http.h>
|
#include <ngx_http.h>
|
||||||
|
|
||||||
|
|
||||||
int ngx_http_static_handler(ngx_http_request_t *r)
|
static int ngx_http_static_handler(ngx_http_request_t *r);
|
||||||
|
static int ngx_http_static_init(ngx_cycle_t *cycle);
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_command_t ngx_http_static_commands[] = {
|
||||||
|
|
||||||
|
ngx_null_command
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ngx_http_module_t ngx_http_static_module_ctx = {
|
||||||
|
NULL, /* create main configuration */
|
||||||
|
NULL, /* init main configuration */
|
||||||
|
|
||||||
|
NULL, /* create server configuration */
|
||||||
|
NULL, /* merge server configuration */
|
||||||
|
|
||||||
|
NULL, /* create location configuration */
|
||||||
|
NULL /* merge location configuration */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ngx_module_t ngx_http_static_module = {
|
||||||
|
NGX_MODULE,
|
||||||
|
&ngx_http_static_module_ctx, /* module context */
|
||||||
|
ngx_http_static_commands, /* module directives */
|
||||||
|
NGX_HTTP_MODULE, /* module type */
|
||||||
|
ngx_http_static_init, /* init module */
|
||||||
|
NULL /* init child */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int ngx_http_static_translate_handler(ngx_http_request_t *r)
|
||||||
|
{
|
||||||
|
char *location, *last;
|
||||||
|
ngx_err_t err;
|
||||||
|
ngx_table_elt_t *h;
|
||||||
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
|
||||||
|
if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
|
||||||
|
return NGX_HTTP_NOT_ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||||
|
|
||||||
|
if (r->uri.data[r->uri.len - 1] == '/') {
|
||||||
|
if (r->path.data == NULL) {
|
||||||
|
ngx_test_null(r->path.data,
|
||||||
|
ngx_palloc(r->pool,
|
||||||
|
clcf->doc_root.len + r->uri.len),
|
||||||
|
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||||
|
|
||||||
|
ngx_cpystrn(ngx_cpymem(r->path.data, clcf->doc_root.data,
|
||||||
|
clcf->doc_root.len),
|
||||||
|
r->uri.data, r->uri.len + 1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
r->path.data[r->path.len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||||
|
"directory index of \"%s\" is forbidden", r->path.data);
|
||||||
|
|
||||||
|
return NGX_HTTP_FORBIDDEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "+ 2" is for trailing '/' in redirect and '\0' */
|
||||||
|
ngx_test_null(r->file.name.data,
|
||||||
|
ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len + 2),
|
||||||
|
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||||
|
|
||||||
|
location = ngx_cpymem(r->file.name.data, clcf->doc_root.data,
|
||||||
|
clcf->doc_root.len),
|
||||||
|
|
||||||
|
last = ngx_cpystrn(location, r->uri.data, r->uri.len + 1);
|
||||||
|
|
||||||
|
ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);
|
||||||
|
|
||||||
|
#if (WIN9X)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There is no way to open a file or a directory in Win9X with
|
||||||
|
* one syscall: Win9X has no FILE_FLAG_BACKUP_SEMANTICS flag.
|
||||||
|
* so we need to check its type before the opening
|
||||||
|
*/
|
||||||
|
|
||||||
|
r->file.info.dwFileAttributes = GetFileAttributes(r->file.name.data);
|
||||||
|
if (r->file.info.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
|
||||||
|
err = ngx_errno;
|
||||||
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
|
||||||
|
ngx_file_type_n " \"%s\" failed", r->file.name.data);
|
||||||
|
|
||||||
|
if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
|
||||||
|
return NGX_HTTP_NOT_FOUND;
|
||||||
|
|
||||||
|
} else if (err == NGX_EACCES) {
|
||||||
|
return NGX_HTTP_FORBIDDEN;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (r->file.fd == NGX_INVALID_FILE) {
|
||||||
|
r->file.fd = ngx_open_file(r->file.name.data,
|
||||||
|
NGX_FILE_RDONLY, NGX_FILE_OPEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->file.fd == NGX_INVALID_FILE) {
|
||||||
|
err = ngx_errno;
|
||||||
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
|
||||||
|
ngx_open_file_n " \"%s\" failed", r->file.name.data);
|
||||||
|
|
||||||
|
if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
|
||||||
|
return NGX_HTTP_NOT_FOUND;
|
||||||
|
|
||||||
|
} else if (err == NGX_EACCES) {
|
||||||
|
return NGX_HTTP_FORBIDDEN;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_log_debug(r->connection->log, "FILE: %d" _ r->file.fd);
|
||||||
|
|
||||||
|
if (!r->file.info_valid) {
|
||||||
|
if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) {
|
||||||
|
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
|
||||||
|
ngx_stat_fd_n " \"%s\" failed", r->file.name.data);
|
||||||
|
|
||||||
|
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
|
||||||
|
ngx_close_file_n " \"%s\" failed",
|
||||||
|
r->file.name.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
r->file.fd = NGX_INVALID_FILE;
|
||||||
|
|
||||||
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->file.info_valid = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ngx_is_dir(r->file.info)) {
|
||||||
|
ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
|
||||||
|
|
||||||
|
#if !(WIN9X)
|
||||||
|
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
|
||||||
|
ngx_close_file_n " \"%s\" failed", r->file.name.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
r->file.fd = NGX_INVALID_FILE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ngx_test_null(h, ngx_push_table(r->headers_out.headers),
|
||||||
|
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||||
|
|
||||||
|
*last++ = '/';
|
||||||
|
*last = '\0';
|
||||||
|
h->key.len = 8;
|
||||||
|
h->key.data = "Location" ;
|
||||||
|
h->value.len = last - location;
|
||||||
|
h->value.data = location;
|
||||||
|
r->headers_out.location = h;
|
||||||
|
|
||||||
|
return NGX_HTTP_MOVED_PERMANENTLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->content_handler = ngx_http_static_handler;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ngx_http_static_handler(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
int rc, key, i;
|
int rc, key, i;
|
||||||
ngx_log_e level;
|
ngx_log_e level;
|
||||||
@ -20,10 +201,6 @@ int ngx_http_static_handler(ngx_http_request_t *r)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
|
|
||||||
return NGX_HTTP_NOT_ALLOWED;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = r->connection->log->data;
|
ctx = r->connection->log->data;
|
||||||
ctx->action = "sending response";
|
ctx->action = "sending response";
|
||||||
|
|
||||||
@ -142,3 +319,22 @@ int ngx_http_static_handler(ngx_http_request_t *r)
|
|||||||
|
|
||||||
return ngx_http_output_filter(r, h);
|
return ngx_http_output_filter(r, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ngx_http_static_init(ngx_cycle_t *cycle)
|
||||||
|
{
|
||||||
|
ngx_http_handler_pt *h;
|
||||||
|
ngx_http_conf_ctx_t *ctx;
|
||||||
|
ngx_http_core_main_conf_t *cmcf;
|
||||||
|
|
||||||
|
ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index];
|
||||||
|
cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
|
||||||
|
|
||||||
|
ngx_test_null(h, ngx_push_array(
|
||||||
|
&cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers),
|
||||||
|
NGX_ERROR);
|
||||||
|
*h = ngx_http_static_translate_handler;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,8 @@ static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev);
|
|||||||
static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev);
|
static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev);
|
||||||
static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *);
|
static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *);
|
||||||
static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p);
|
static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p);
|
||||||
static void ngx_http_proxy_process_upstream_body(ngx_event_t *rev);
|
static void ngx_http_proxy_process_upstream(ngx_event_t *rev);
|
||||||
|
static void ngx_http_proxy_process_downstream(ngx_event_t *wev);
|
||||||
|
|
||||||
static int ngx_http_proxy_parse_status_line(ngx_http_proxy_ctx_t *p);
|
static int ngx_http_proxy_parse_status_line(ngx_http_proxy_ctx_t *p);
|
||||||
static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p);
|
static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p);
|
||||||
@ -27,8 +28,21 @@ static void ngx_http_proxy_close_connection(ngx_connection_t *c);
|
|||||||
static int ngx_http_proxy_init(ngx_cycle_t *cycle);
|
static int ngx_http_proxy_init(ngx_cycle_t *cycle);
|
||||||
static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf);
|
static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf);
|
||||||
|
|
||||||
|
static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
|
void *conf);
|
||||||
|
static char *ngx_http_proxy_parse_upstream(ngx_str_t *url,
|
||||||
|
ngx_http_proxy_upstream_t *u);
|
||||||
|
|
||||||
|
|
||||||
static ngx_command_t ngx_http_proxy_commands[] = {
|
static ngx_command_t ngx_http_proxy_commands[] = {
|
||||||
|
|
||||||
|
{ngx_string("proxy_pass"),
|
||||||
|
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||||
|
ngx_http_proxy_set_pass,
|
||||||
|
NGX_HTTP_LOC_CONF_OFFSET,
|
||||||
|
0,
|
||||||
|
NULL},
|
||||||
|
|
||||||
ngx_null_command
|
ngx_null_command
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -54,7 +68,7 @@ ngx_module_t ngx_http_proxy_module = {
|
|||||||
&ngx_http_proxy_module_ctx, /* module context */
|
&ngx_http_proxy_module_ctx, /* module context */
|
||||||
ngx_http_proxy_commands, /* module directives */
|
ngx_http_proxy_commands, /* module directives */
|
||||||
NGX_HTTP_MODULE, /* module type */
|
NGX_HTTP_MODULE, /* module type */
|
||||||
ngx_http_proxy_init, /* init module */
|
NULL, /* init module */
|
||||||
NULL /* init child */
|
NULL /* init child */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,22 +113,9 @@ static char conn_close_header[] = "Connection: close" CRLF;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int ngx_http_proxy_translate_handler(ngx_http_request_t *r)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
r->handler = ngx_http_proxy_handler;
|
|
||||||
return NGX_OK;
|
|
||||||
#else
|
|
||||||
return NGX_DECLINED;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int ngx_http_proxy_handler(ngx_http_request_t *r)
|
static int ngx_http_proxy_handler(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
int rc;
|
ngx_http_proxy_ctx_t *p;
|
||||||
ngx_http_proxy_ctx_t *p;
|
|
||||||
ngx_http_proxy_loc_conf_t *lcf;
|
|
||||||
|
|
||||||
ngx_http_create_ctx(r, p, ngx_http_proxy_module,
|
ngx_http_create_ctx(r, p, ngx_http_proxy_module,
|
||||||
sizeof(ngx_http_proxy_ctx_t),
|
sizeof(ngx_http_proxy_ctx_t),
|
||||||
@ -126,6 +127,8 @@ static int ngx_http_proxy_handler(ngx_http_request_t *r)
|
|||||||
|
|
||||||
p->request = r;
|
p->request = r;
|
||||||
p->method = r->method;
|
p->method = r->method;
|
||||||
|
|
||||||
|
/* TODO: from lcf->upstream */
|
||||||
p->uri.data = "/";
|
p->uri.data = "/";
|
||||||
p->uri.len = 1;
|
p->uri.len = 1;
|
||||||
p->location_len = 1;
|
p->location_len = 1;
|
||||||
@ -144,7 +147,7 @@ static int ngx_http_proxy_handler(ngx_http_request_t *r)
|
|||||||
|
|
||||||
ngx_http_proxy_send_request(p);
|
ngx_http_proxy_send_request(p);
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -580,7 +583,6 @@ static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev)
|
|||||||
|
|
||||||
static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *p)
|
static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *p)
|
||||||
{
|
{
|
||||||
int event;
|
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
ngx_event_t *rev;
|
ngx_event_t *rev;
|
||||||
|
|
||||||
@ -589,7 +591,10 @@ static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *p)
|
|||||||
n = p->header_in->last - p->header_in->pos;
|
n = p->header_in->last - p->header_in->pos;
|
||||||
|
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
|
#if 0
|
||||||
|
/* TODO THINK */
|
||||||
rev->ready = 0;
|
rev->ready = 0;
|
||||||
|
#endif
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,11 +705,12 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ep->input_filter = ngx_event_proxy_copy_input_filter;
|
||||||
ep->output_filter = (ngx_event_proxy_output_filter_pt)
|
ep->output_filter = (ngx_event_proxy_output_filter_pt)
|
||||||
ngx_http_output_filter;
|
ngx_http_output_filter;
|
||||||
ep->output_data = r;
|
ep->output_ctx = r;
|
||||||
ep->block_size = p->lcf->block_size;
|
ep->bufs = p->lcf->bufs;
|
||||||
ep->max_block_size = p->lcf->max_block_size;
|
ep->max_busy_len = p->lcf->max_busy_len;
|
||||||
ep->upstream = p->upstream.connection;
|
ep->upstream = p->upstream.connection;
|
||||||
ep->downstream = r->connection;
|
ep->downstream = r->connection;
|
||||||
ep->pool = r->pool;
|
ep->pool = r->pool;
|
||||||
@ -742,16 +748,18 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
|
|||||||
lcx->action = "reading an upstream";
|
lcx->action = "reading an upstream";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ngx_event_proxy_read_upstream(ep);
|
|
||||||
|
|
||||||
p->upstream.connection->read->event_handler =
|
p->upstream.connection->read->event_handler =
|
||||||
ngx_http_proxy_process_upstream_body;
|
ngx_http_proxy_process_upstream;
|
||||||
|
r->connection->write->event_handler =
|
||||||
|
ngx_http_proxy_process_downstream;
|
||||||
|
|
||||||
|
ngx_http_proxy_process_upstream(p->upstream.connection->read);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ngx_http_proxy_process_upstream_body(ngx_event_t *rev)
|
static void ngx_http_proxy_process_upstream(ngx_event_t *rev)
|
||||||
{
|
{
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
ngx_http_proxy_ctx_t *p;
|
ngx_http_proxy_ctx_t *p;
|
||||||
@ -759,25 +767,58 @@ static void ngx_http_proxy_process_upstream_body(ngx_event_t *rev)
|
|||||||
c = rev->data;
|
c = rev->data;
|
||||||
p = c->data;
|
p = c->data;
|
||||||
|
|
||||||
ngx_log_debug(rev->log, "http proxy process upstream body");
|
ngx_log_debug(rev->log, "http proxy process upstream");
|
||||||
|
|
||||||
if (rev->timedout) {
|
if (rev->timedout) {
|
||||||
ngx_http_proxy_close_connection(p->upstream.connection);
|
ngx_http_proxy_close_connection(c);
|
||||||
p->upstream.connection = NULL;
|
p->upstream.connection = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_event_proxy_read_upstream(p->event_proxy);
|
if (ngx_event_proxy_read_upstream(p->event_proxy) == NGX_ABORT) {
|
||||||
|
ngx_http_proxy_finalize_request(p, 0);
|
||||||
if (p->event_proxy->upstream_eof) {
|
|
||||||
ngx_http_proxy_close_connection(p->upstream.connection);
|
|
||||||
p->upstream.connection = NULL;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->event_proxy->upstream_error) {
|
if (p->event_proxy->upstream_eof
|
||||||
ngx_http_proxy_close_connection(p->upstream.connection);
|
|| p->event_proxy->upstream_error
|
||||||
p->upstream.connection = NULL;
|
|| p->event_proxy->upstream_done)
|
||||||
|
{
|
||||||
|
ngx_http_proxy_finalize_request(p, ngx_http_send_last(p->request));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ngx_http_proxy_process_downstream(ngx_event_t *wev)
|
||||||
|
{
|
||||||
|
ngx_connection_t *c;
|
||||||
|
ngx_http_proxy_ctx_t *p;
|
||||||
|
|
||||||
|
c = wev->data;
|
||||||
|
p = c->data;
|
||||||
|
|
||||||
|
ngx_log_debug(wev->log, "http proxy process downstream");
|
||||||
|
|
||||||
|
if (wev->timedout) {
|
||||||
|
ngx_http_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_event_proxy_write_to_downstream(p->event_proxy) == NGX_ABORT) {
|
||||||
|
ngx_http_proxy_finalize_request(p, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->event_proxy->downstream_done) {
|
||||||
|
ngx_http_proxy_finalize_request(p, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->event_proxy->downstream_error) {
|
||||||
|
ngx_http_close_connection(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1076,25 +1117,6 @@ static size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ngx_http_proxy_init(ngx_cycle_t *cycle)
|
|
||||||
{
|
|
||||||
ngx_http_handler_pt *h;
|
|
||||||
ngx_http_conf_ctx_t *ctx;
|
|
||||||
ngx_http_core_main_conf_t *cmcf;
|
|
||||||
|
|
||||||
ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index];
|
|
||||||
cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
|
|
||||||
|
|
||||||
ngx_test_null(h, ngx_push_array(
|
|
||||||
&cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers),
|
|
||||||
NGX_ERROR);
|
|
||||||
|
|
||||||
*h = ngx_http_proxy_translate_handler;
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -1121,8 +1143,9 @@ static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
|||||||
conf->header_size = 4096;
|
conf->header_size = 4096;
|
||||||
conf->read_timeout = 30000;
|
conf->read_timeout = 30000;
|
||||||
|
|
||||||
conf->block_size = 4096;
|
conf->bufs.num = 10;
|
||||||
conf->max_block_size = 4096 * 3;
|
conf->bufs.size = 4096;
|
||||||
|
conf->max_busy_len = 8192 + 4096;
|
||||||
conf->max_temp_file_size = 4096 * 5;
|
conf->max_temp_file_size = 4096 * 5;
|
||||||
conf->temp_file_write_size = 4096 * 2;
|
conf->temp_file_write_size = 4096 * 2;
|
||||||
|
|
||||||
@ -1147,3 +1170,206 @@ static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
|||||||
|
|
||||||
return conf;
|
return conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
|
void *conf)
|
||||||
|
{
|
||||||
|
ngx_http_proxy_loc_conf_t *lcf = conf;
|
||||||
|
|
||||||
|
int i, len;
|
||||||
|
char *err, *host;
|
||||||
|
ngx_str_t *value;
|
||||||
|
struct hostent *h;
|
||||||
|
u_int32_t addr;
|
||||||
|
ngx_http_conf_ctx_t *ctx;
|
||||||
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
|
||||||
|
|
||||||
|
value = cf->args->elts;
|
||||||
|
|
||||||
|
if (ngx_strncasecmp(value[1].data, "http://", 7) != 0) {
|
||||||
|
return "invalid URL prefix";
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_test_null(lcf->upstream,
|
||||||
|
ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_upstream_t)),
|
||||||
|
NGX_CONF_ERROR);
|
||||||
|
|
||||||
|
value[1].data += 7;
|
||||||
|
value[1].len -= 7;
|
||||||
|
|
||||||
|
err = ngx_http_proxy_parse_upstream(&value[1], lcf->upstream);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_test_null(host, ngx_palloc(cf->pool, lcf->upstream->host.len + 1),
|
||||||
|
NGX_CONF_ERROR);
|
||||||
|
ngx_cpystrn(host, lcf->upstream->host.data, lcf->upstream->host.len + 1);
|
||||||
|
|
||||||
|
addr = inet_addr(host);
|
||||||
|
|
||||||
|
if (addr == INADDR_NONE) {
|
||||||
|
h = gethostbyname(host);
|
||||||
|
|
||||||
|
if (h == NULL || h->h_addr_list[0] == NULL) {
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "host %s not found", host);
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
|
||||||
|
|
||||||
|
/* MP: ngx_shared_palloc() */
|
||||||
|
|
||||||
|
ngx_test_null(lcf->peers,
|
||||||
|
ngx_pcalloc(cf->pool,
|
||||||
|
sizeof(ngx_peers_t)
|
||||||
|
+ sizeof(ngx_peer_t) * (i - 1)),
|
||||||
|
NGX_CONF_ERROR);
|
||||||
|
|
||||||
|
lcf->peers->number = i;
|
||||||
|
|
||||||
|
for (i = 0; h->h_addr_list[i] != NULL; i++) {
|
||||||
|
lcf->peers->peers[i].host.data = host;
|
||||||
|
lcf->peers->peers[i].host.len = lcf->upstream->host.len;
|
||||||
|
lcf->peers->peers[i].addr = *(u_int32_t *)(h->h_addr_list[i]);
|
||||||
|
lcf->peers->peers[i].port = lcf->upstream->port;
|
||||||
|
|
||||||
|
len = INET_ADDRSTRLEN + lcf->upstream->port_text.len + 1;
|
||||||
|
ngx_test_null(lcf->peers->peers[i].addr_port_text.data,
|
||||||
|
ngx_palloc(cf->pool, len),
|
||||||
|
NGX_CONF_ERROR);
|
||||||
|
|
||||||
|
len = ngx_inet_ntop(AF_INET,
|
||||||
|
(char *) &lcf->peers->peers[i].addr,
|
||||||
|
lcf->peers->peers[i].addr_port_text.data,
|
||||||
|
len);
|
||||||
|
|
||||||
|
lcf->peers->peers[i].addr_port_text.data[len++] = ':';
|
||||||
|
|
||||||
|
ngx_cpystrn(lcf->peers->peers[i].addr_port_text.data + len,
|
||||||
|
lcf->upstream->port_text.data,
|
||||||
|
lcf->upstream->port_text.len + 1);
|
||||||
|
|
||||||
|
lcf->peers->peers[i].addr_port_text.len =
|
||||||
|
len + lcf->upstream->port_text.len + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* MP: ngx_shared_palloc() */
|
||||||
|
|
||||||
|
ngx_test_null(lcf->peers, ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)),
|
||||||
|
NGX_CONF_ERROR);
|
||||||
|
|
||||||
|
lcf->peers->number = 1;
|
||||||
|
|
||||||
|
lcf->peers->peers[0].host.data = host;
|
||||||
|
lcf->peers->peers[0].host.len = lcf->upstream->host.len;
|
||||||
|
lcf->peers->peers[0].addr = addr;
|
||||||
|
lcf->peers->peers[0].port = lcf->upstream->port;
|
||||||
|
|
||||||
|
len = lcf->upstream->host.len + lcf->upstream->port_text.len + 1;
|
||||||
|
|
||||||
|
ngx_test_null(lcf->peers->peers[0].addr_port_text.data,
|
||||||
|
ngx_palloc(cf->pool, len + 1),
|
||||||
|
NGX_CONF_ERROR);
|
||||||
|
|
||||||
|
len = lcf->upstream->host.len;
|
||||||
|
|
||||||
|
ngx_memcpy(lcf->peers->peers[0].addr_port_text.data,
|
||||||
|
lcf->upstream->host.data, len);
|
||||||
|
|
||||||
|
lcf->peers->peers[0].addr_port_text.data[len++] = ':';
|
||||||
|
|
||||||
|
ngx_cpystrn(lcf->peers->peers[0].addr_port_text.data + len,
|
||||||
|
lcf->upstream->port_text.data,
|
||||||
|
lcf->upstream->port_text.len + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = cf->ctx;
|
||||||
|
clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
|
||||||
|
lcf->upstream->location = &clcf->name;
|
||||||
|
clcf->handler = ngx_http_proxy_handler;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *ngx_http_proxy_parse_upstream(ngx_str_t *url,
|
||||||
|
ngx_http_proxy_upstream_t *u)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (url->data[0] == ':' || url->data[0] == '/') {
|
||||||
|
return "invalid upstream URL";
|
||||||
|
}
|
||||||
|
|
||||||
|
u->host.data = url->data;
|
||||||
|
u->host_header.data = url->data;
|
||||||
|
|
||||||
|
for (i = 1; i < url->len; i++) {
|
||||||
|
if (url->data[i] == ':') {
|
||||||
|
u->port_text.data = &url->data[i] + 1;
|
||||||
|
u->host.len = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url->data[i] == '/') {
|
||||||
|
u->uri.data = &url->data[i];
|
||||||
|
u->uri.len = url->len - i;
|
||||||
|
u->host_header.len = i;
|
||||||
|
|
||||||
|
if (u->host.len == 0) {
|
||||||
|
u->host.len = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u->port_text.data == NULL) {
|
||||||
|
u->port = htons(80);
|
||||||
|
u->port_text.len = 2;
|
||||||
|
u->port_text.data = "80";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u->port_text.len = &url->data[i] - u->port_text.data;
|
||||||
|
|
||||||
|
if (u->port_text.len > 0) {
|
||||||
|
u->port = ngx_atoi(u->port_text.data, u->port_text.len);
|
||||||
|
if (u->port > 0) {
|
||||||
|
u->port = htons((u_short) u->port);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "invalid port in upstream URL";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u->host.len == 0) {
|
||||||
|
u->host.len = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
u->host_header.len = i;
|
||||||
|
|
||||||
|
u->uri.data = "/";
|
||||||
|
u->uri.len = 1;
|
||||||
|
|
||||||
|
if (u->port_text.data == NULL) {
|
||||||
|
u->port = htons(80);
|
||||||
|
u->port_text.len = 2;
|
||||||
|
u->port_text.data = "80";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u->port_text.len = &url->data[i] - u->port_text.data;
|
||||||
|
|
||||||
|
if (u->port_text.len > 0) {
|
||||||
|
u->port = ngx_atoi(u->port_text.data, u->port_text.len);
|
||||||
|
if (u->port > 0) {
|
||||||
|
u->port = htons((u_short) u->port);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "invalid port in upstream URL";
|
||||||
|
}
|
||||||
|
@ -9,21 +9,33 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_msec_t connect_timeout;
|
ngx_str_t host;
|
||||||
ngx_msec_t send_timeout;
|
ngx_str_t uri;
|
||||||
ssize_t header_size;
|
ngx_str_t *location;
|
||||||
ngx_msec_t read_timeout;
|
ngx_str_t host_header;
|
||||||
|
ngx_str_t port_text;
|
||||||
|
int port;
|
||||||
|
} ngx_http_proxy_upstream_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_msec_t connect_timeout;
|
||||||
|
ngx_msec_t send_timeout;
|
||||||
|
ssize_t header_size;
|
||||||
|
ngx_msec_t read_timeout;
|
||||||
|
|
||||||
|
ngx_bufs_t bufs;
|
||||||
|
|
||||||
/* STUB */
|
/* STUB */
|
||||||
int block_size;
|
int max_busy_len;
|
||||||
int max_block_size;
|
int max_temp_file_size;
|
||||||
int max_temp_file_size;
|
int temp_file_write_size;
|
||||||
int temp_file_write_size;
|
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
ngx_path_t *temp_path;
|
ngx_path_t *temp_path;
|
||||||
|
|
||||||
ngx_peers_t *peers;
|
ngx_http_proxy_upstream_t *upstream;
|
||||||
|
ngx_peers_t *peers;
|
||||||
} ngx_http_proxy_loc_conf_t;
|
} ngx_http_proxy_loc_conf_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,9 +6,6 @@
|
|||||||
#include <nginx.h>
|
#include <nginx.h>
|
||||||
|
|
||||||
|
|
||||||
/* STUB */
|
|
||||||
int ngx_http_static_handler(ngx_http_request_t *r);
|
|
||||||
/**/
|
|
||||||
|
|
||||||
static void ngx_http_phase_event_handler(ngx_event_t *rev);
|
static void ngx_http_phase_event_handler(ngx_event_t *rev);
|
||||||
static void ngx_http_run_phases(ngx_http_request_t *r);
|
static void ngx_http_run_phases(ngx_http_request_t *r);
|
||||||
@ -304,7 +301,6 @@ static void ngx_http_run_phases(ngx_http_request_t *r)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: no handlers found ? */
|
|
||||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -346,164 +342,20 @@ ngx_log_debug(r->connection->log, "rc: %d" _ rc);
|
|||||||
|
|
||||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||||
|
|
||||||
if ((ngx_io.flags & NGX_IO_SENDFILE) == 0 || clcf->sendfile == 0) {
|
if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) {
|
||||||
r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
|
r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ngx_http_core_translate_handler(ngx_http_request_t *r)
|
|
||||||
{
|
|
||||||
char *location, *last;
|
|
||||||
ngx_err_t err;
|
|
||||||
ngx_table_elt_t *h;
|
|
||||||
ngx_http_core_srv_conf_t *cscf;
|
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
|
||||||
|
|
||||||
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
|
||||||
|
* the translation phase
|
||||||
|
*/
|
||||||
|
|
||||||
r->content_handler = clcf->handler;
|
r->content_handler = clcf->handler;
|
||||||
return NGX_OK;
|
r->phase++;
|
||||||
}
|
}
|
||||||
|
|
||||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
|
||||||
|
|
||||||
if (r->uri.data[r->uri.len - 1] == '/') {
|
|
||||||
if (r->path.data == NULL) {
|
|
||||||
ngx_test_null(r->path.data,
|
|
||||||
ngx_palloc(r->pool,
|
|
||||||
clcf->doc_root.len + r->uri.len),
|
|
||||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
||||||
|
|
||||||
ngx_cpystrn(ngx_cpymem(r->path.data, clcf->doc_root.data,
|
|
||||||
clcf->doc_root.len),
|
|
||||||
r->uri.data, r->uri.len + 1);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
r->path.data[r->path.len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
|
||||||
"directory index of \"%s\" is forbidden", r->path.data);
|
|
||||||
|
|
||||||
return NGX_HTTP_FORBIDDEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* "+ 2" is for trailing '/' in redirect and '\0' */
|
|
||||||
ngx_test_null(r->file.name.data,
|
|
||||||
ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len + 2),
|
|
||||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
||||||
|
|
||||||
location = ngx_cpymem(r->file.name.data, clcf->doc_root.data,
|
|
||||||
clcf->doc_root.len),
|
|
||||||
|
|
||||||
last = ngx_cpystrn(location, r->uri.data, r->uri.len + 1);
|
|
||||||
|
|
||||||
ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);
|
|
||||||
|
|
||||||
#if (WIN9X)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There is no way to open a file or a directory in Win9X with
|
|
||||||
* one syscall: Win9X has no FILE_FLAG_BACKUP_SEMANTICS flag.
|
|
||||||
* so we need to check its type before the opening
|
|
||||||
*/
|
|
||||||
|
|
||||||
r->file.info.dwFileAttributes = GetFileAttributes(r->file.name.data);
|
|
||||||
if (r->file.info.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
|
|
||||||
err = ngx_errno;
|
|
||||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
|
|
||||||
ngx_file_type_n " \"%s\" failed", r->file.name.data);
|
|
||||||
|
|
||||||
if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
|
|
||||||
return NGX_HTTP_NOT_FOUND;
|
|
||||||
|
|
||||||
} else if (err == NGX_EACCES) {
|
|
||||||
return NGX_HTTP_FORBIDDEN;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (r->file.fd == NGX_INVALID_FILE) {
|
|
||||||
r->file.fd = ngx_open_file(r->file.name.data,
|
|
||||||
NGX_FILE_RDONLY, NGX_FILE_OPEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r->file.fd == NGX_INVALID_FILE) {
|
|
||||||
err = ngx_errno;
|
|
||||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
|
|
||||||
ngx_open_file_n " \"%s\" failed", r->file.name.data);
|
|
||||||
|
|
||||||
if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
|
|
||||||
return NGX_HTTP_NOT_FOUND;
|
|
||||||
|
|
||||||
} else if (err == NGX_EACCES) {
|
|
||||||
return NGX_HTTP_FORBIDDEN;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_log_debug(r->connection->log, "FILE: %d" _ r->file.fd);
|
|
||||||
|
|
||||||
if (!r->file.info_valid) {
|
|
||||||
if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) {
|
|
||||||
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
|
|
||||||
ngx_stat_fd_n " \"%s\" failed", r->file.name.data);
|
|
||||||
|
|
||||||
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
|
|
||||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
|
|
||||||
ngx_close_file_n " \"%s\" failed",
|
|
||||||
r->file.name.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
r->file.fd = NGX_INVALID_FILE;
|
|
||||||
|
|
||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
r->file.info_valid = 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ngx_is_dir(r->file.info)) {
|
|
||||||
ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
|
|
||||||
|
|
||||||
#if !(WIN9X)
|
|
||||||
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
|
|
||||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
|
|
||||||
ngx_close_file_n " \"%s\" failed", r->file.name.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
r->file.fd = NGX_INVALID_FILE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* BROKEN: need to include server name */
|
|
||||||
|
|
||||||
ngx_test_null(h, ngx_push_table(r->headers_out.headers),
|
|
||||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
|
||||||
|
|
||||||
*last++ = '/';
|
|
||||||
*last = '\0';
|
|
||||||
h->key.len = 8;
|
|
||||||
h->key.data = "Location" ;
|
|
||||||
h->value.len = last - location;
|
|
||||||
h->value.data = location;
|
|
||||||
r->headers_out.location = h;
|
|
||||||
|
|
||||||
return NGX_HTTP_MOVED_PERMANENTLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
r->content_handler = ngx_http_static_handler;
|
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,18 +461,15 @@ int ngx_http_delay_handler(ngx_http_request_t *r)
|
|||||||
|
|
||||||
static int ngx_http_core_init(ngx_cycle_t *cycle)
|
static int ngx_http_core_init(ngx_cycle_t *cycle)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
ngx_http_handler_pt *h;
|
ngx_http_handler_pt *h;
|
||||||
|
#endif
|
||||||
ngx_http_conf_ctx_t *ctx;
|
ngx_http_conf_ctx_t *ctx;
|
||||||
ngx_http_core_main_conf_t *cmcf;
|
ngx_http_core_main_conf_t *cmcf;
|
||||||
|
|
||||||
ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index];
|
ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index];
|
||||||
cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
|
cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
|
||||||
|
|
||||||
ngx_test_null(h, ngx_push_array(
|
|
||||||
&cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers),
|
|
||||||
NGX_ERROR);
|
|
||||||
*h = ngx_http_core_translate_handler;
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
ngx_test_null(h, ngx_push_array(
|
ngx_test_null(h, ngx_push_array(
|
||||||
&cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers),
|
&cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers),
|
||||||
|
@ -765,7 +765,7 @@ 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");
|
||||||
|
|
||||||
if (r->main || r->closed) {
|
if (rc == NGX_DONE || r->main || r->closed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,11 +163,11 @@ int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
|
|||||||
|
|
||||||
} else if (error < NGX_HTTP_INTERNAL_SERVER_ERROR) {
|
} else if (error < NGX_HTTP_INTERNAL_SERVER_ERROR) {
|
||||||
/* 4XX */
|
/* 4XX */
|
||||||
err = error - NGX_HTTP_BAD_REQUEST + 4;
|
err = error - NGX_HTTP_BAD_REQUEST + 3;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* 5XX */
|
/* 5XX */
|
||||||
err = error - NGX_HTTP_INTERNAL_SERVER_ERROR + 4 + 17;
|
err = error - NGX_HTTP_INTERNAL_SERVER_ERROR + 3 + 17;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->keepalive != 0) {
|
if (r->keepalive != 0) {
|
||||||
|
@ -22,8 +22,8 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
|
|||||||
|
|
||||||
if (rev->available == 0) {
|
if (rev->available == 0) {
|
||||||
if (rev->eof) {
|
if (rev->eof) {
|
||||||
|
rev->ready = 0;
|
||||||
if (rev->error) {
|
if (rev->error) {
|
||||||
rev->ready = 0;
|
|
||||||
ngx_set_socket_errno(rev->error);
|
ngx_set_socket_errno(rev->error);
|
||||||
return ngx_unix_recv_error(rev, rev->error);
|
return ngx_unix_recv_error(rev, rev->error);
|
||||||
}
|
}
|
||||||
@ -44,7 +44,10 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
|
|||||||
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
|
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
|
||||||
rev->available -= n;
|
rev->available -= n;
|
||||||
if (rev->available <= 0) {
|
if (rev->available <= 0) {
|
||||||
rev->ready = 0;
|
if (!rev->eof) {
|
||||||
|
rev->ready = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (rev->available < 0) {
|
if (rev->available < 0) {
|
||||||
rev->available = 0;
|
rev->available = 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user