nginx-0.0.1-2003-03-20-19:09:44 import

This commit is contained in:
Igor Sysoev 2003-03-20 16:09:44 +00:00
parent 90ace68b69
commit dc479b4d98
27 changed files with 1338 additions and 710 deletions

View File

@ -6,7 +6,7 @@
#define NGX_ERROR -1
#define NGX_DONE NGX_ERROR
#define NGX_AGAIN -2
#define NGX_WAITING -3
#define NGX_BUSY -3
#define NGX_DECLINED -4
#define NGX_ALERT -5

View File

@ -1,5 +1,6 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_string.h>
@ -19,3 +20,72 @@ char *ngx_cpystrn(char *dst, char *src, size_t n)
return dst;
}
int ngx_atoi(char *line, size_t n)
{
int value;
for (value = 0; n--; line++) {
if (*line < '0' || *line > '9') {
return NGX_ERROR;
}
value = value * 10 + (*line - '0');
}
return value;
}
#if 0
char *ngx_psprintf(ngx_pool_t *p, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
while (*fmt) {
switch(*fmt++) {
case '%':
switch(*fmt++) {
case 's':
s = va_arg(args, char *);
n += ngx_strlen(s);
break;
default:
n++;
}
default:
n++;
}
}
str = ngx_palloc(p, n);
va_start(args, fmt);
for (i = 0; i < n; i++) {
switch(*fmt++) {
case '%':
switch(*fmt++) {
case 's':
s = va_arg(args, char *);
while (str[i++] = s);
break;
default:
n++;
}
default:
str[i] = *fmt;
}
}
len += ngx_vsnprintf(errstr + len, sizeof(errstr) - len - 1, fmt, args);
va_end(args);
}
#endif

View File

@ -49,6 +49,7 @@ typedef struct {
#define ngx_cpymem(dst, src, n) memcpy(dst, src, n) + n
char *ngx_cpystrn(char *dst, char *src, size_t n);
int ngx_atoi(char *line, size_t n);
#endif /* _NGX_STRING_H_INCLUDED_ */

View File

@ -236,6 +236,7 @@ int ngx_devpoll_process_events(ngx_log_t *log)
if ((int) timer != INFTIM) {
gettimeofday(&tv, NULL);
delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta;
ngx_event_expire_timers(delta);
} else {
if (events == 0) {
@ -305,9 +306,5 @@ int ngx_devpoll_process_events(ngx_log_t *log)
}
}
if ((int) timer != INFTIM) {
ngx_event_expire_timers(delta);
}
return NGX_OK;
}

View File

@ -110,6 +110,7 @@ int ngx_iocp_process_events(ngx_log_t *log)
if (timer != INFINITE) {
delta = ngx_msec() - delta;
ngx_event_expire_timers(delta);
}
if (ovlp) {
@ -118,6 +119,7 @@ int ngx_iocp_process_events(ngx_log_t *log)
ngx_log_debug(log, "iocp ev: %08x" _ ev);
if (ev == e) {
/* it's not AcceptEx() completion */
ev->ready = 1;
ev->available = bytes;
}
@ -129,9 +131,5 @@ ngx_log_debug(log, "iocp ev: %08x" _ ev->event_handler);
}
}
if (timer != INFINITE) {
ngx_event_expire_timers(delta);
}
return NGX_OK;
}

View File

@ -110,6 +110,13 @@ int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
ev->active = 1;
ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0;
/* The event addition or change should be always passed to a kernel
because there can be case when event was passed to a kernel then
added again to the change_list and then deleted from the change_list
by ngx_kqueue_del_event() so the first event still remains in a kernel */
#if 0
if (nchanges > 0
&& ev->index < nchanges
&& change_list[ev->index].udata == ev)
@ -118,12 +125,17 @@ int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
ngx_connection_t *c = (ngx_connection_t *) ev->data;
ngx_log_debug(ev->log, "kqueue add event: %d: ft:%d" _ c->fd _ event);
#endif
/* if the event is still not passed to a kernel we change it */
change_list[ev->index].filter = event;
change_list[ev->index].flags = flags;
return NGX_OK;
}
#endif
return ngx_kqueue_set_event(ev, event, EV_ADD | flags);
}
@ -142,6 +154,9 @@ int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
ngx_connection_t *c = (ngx_connection_t *) ev->data;
ngx_log_debug(ev->log, "kqueue del event: %d: ft:%d" _ c->fd _ event);
#endif
/* if the event is still not passed to a kernel we will not pass it */
if (ev->index < --nchanges) {
e = (ngx_event_t *) change_list[nchanges].udata;
change_list[ev->index] = change_list[nchanges];
@ -151,6 +166,9 @@ int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
return NGX_OK;
}
/* when a socket is closed kqueue automatically deletes its filters
so we do not need to delete a event explicity before a socket closing */
if (flags & NGX_CLOSE_EVENT) {
return NGX_OK;
}
@ -257,6 +275,11 @@ int ngx_kqueue_process_events(ngx_log_t *log)
gettimeofday(&tv, NULL);
delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta;
/* Expired timers must be deleted before the events processing
because the new timers can be added during the processing */
ngx_event_expire_timers(delta);
} else {
if (events == 0) {
ngx_log_error(NGX_LOG_ALERT, log, 0,
@ -295,6 +318,9 @@ int ngx_kqueue_process_events(ngx_log_t *log)
ev = (ngx_event_t *) event_list[i].udata;
/* It's a stale event from a socket
that was just closed in this iteration */
if (!ev->active) {
continue;
}
@ -303,6 +329,29 @@ int ngx_kqueue_process_events(ngx_log_t *log)
case EVFILT_READ:
case EVFILT_WRITE:
if (ev->first) {
if (nchanges > 0
&& ev->index < nchanges
&& change_list[ev->index].udata == ev) {
/* It's a stale event from a socket that was just closed
in this iteration and during processing another socket
was opened with the same number by accept() or socket()
and its event has been added the event to the change_list
but has not been passed to a kernel. Nevertheless
there's small chance that ngx_kqueue_set_event() has
flushed the new event if the change_list was filled up.
In this very rare case we would get EAGAIN while
a reading or a writing */
continue;
} else {
ev->first = 0;
}
}
ev->available = event_list[i].data;
if (event_list[i].flags & EV_EOF) {
@ -332,9 +381,5 @@ int ngx_kqueue_process_events(ngx_log_t *log)
}
}
if (timer) {
ngx_event_expire_timers(delta);
}
return NGX_OK;
}

View File

@ -175,6 +175,7 @@ int ngx_poll_process_events(ngx_log_t *log)
if ((int) timer != INFTIM) {
delta = ngx_msec() - delta;
ngx_event_expire_timers(delta);
} else {
if (ready == 0) {
@ -259,9 +260,5 @@ int ngx_poll_process_events(ngx_log_t *log)
ngx_log_error(NGX_LOG_ALERT, log, 0, "poll ready != events");
}
if ((int) timer != INFTIM) {
ngx_event_expire_timers(delta);
}
return NGX_OK;
}

View File

@ -243,6 +243,7 @@ int ngx_select_process_events(ngx_log_t *log)
if (timer) {
delta = ngx_msec() - delta;
ngx_event_expire_timers(delta);
} else {
if (ready == 0) {
@ -312,9 +313,5 @@ int ngx_select_process_events(ngx_log_t *log)
ngx_log_error(NGX_LOG_ALERT, log, 0, "select ready != events");
}
if (timer) {
ngx_event_expire_timers(delta);
}
return NGX_OK;
}

View File

@ -63,6 +63,7 @@ struct ngx_event_s {
#endif
unsigned write:1;
unsigned first:1;
unsigned active:1;
unsigned ready:1;
unsigned timedout:1;
@ -179,8 +180,8 @@ typedef struct {
#define NGX_USE_LEVEL_EVENT 0x00010000
/* Event filter is deleted before closing file. Has no meaning
for select, poll, epoll.
/* Event filter is deleted before closing file.
Has no meaning for select, poll, epoll.
kqueue: kqueue deletes event filters for file that closed
so we need only to delete filters in user-level batch array
@ -193,16 +194,24 @@ typedef struct {
#define NGX_READ_EVENT EVFILT_READ
#define NGX_WRITE_EVENT EVFILT_WRITE
#define NGX_ENABLE_EVENT EV_ENABLE
#define NGX_DISABLE_EVENT EV_DISABLE
/* NGX_CLOSE_EVENT is the module flag and it would not go into a kernel
so we need to choose the value that would not interfere with any existent
and future flags. kqueue has such values - EV_FLAG1, EV_EOF and EV_ERROR.
They are reserved and cleared on a kernel entrance */
#undef NGX_CLOSE_EVENT
#define NGX_CLOSE_EVENT EV_FLAG1
#define NGX_LEVEL_EVENT 0
#define NGX_ONESHOT_EVENT EV_ONESHOT
#define NGX_CLEAR_EVENT EV_CLEAR
#ifndef HAVE_CLEAR_EVENT
#define HAVE_CLEAR_EVENT 1
#endif
#if (HAVE_CLEAR_EVENT)
#define NGX_CLEAR_EVENT EV_CLEAR
#endif
#elif (HAVE_POLL) || (HAVE_DEVPOLL)

View File

@ -117,6 +117,7 @@ int ngx_event_accept(ngx_event_t *ev)
c->fd = s;
c->unexpected_eof = 1;
wev->write = 1;
rev->first = wev->first = 1;
#if (HAVE_AIO_EVENT)
if (!(ngx_event_flags & NGX_HAVE_AIO_EVENT)) {

View File

@ -104,6 +104,7 @@ int ngx_event_post_acceptex(ngx_listen_t *ls, int n)
c->unexpected_eof = 1;
wev->write = 1;
rev->first = wev->first = 1;
c->handler = ls->handler;
rev->event_handler = ngx_event_acceptex;

View File

@ -8,18 +8,13 @@
ssize_t ngx_event_recv_core(ngx_connection_t *c, char *buf, size_t size)
{
int n;
ngx_err_t err;
ngx_event_t *ev;
ssize_t n;
ngx_err_t err;
ngx_event_t *ev;
ev = c->read;
if (ev->timedout) {
ngx_set_socket_errno(NGX_ETIMEDOUT);
ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, "recv() failed");
return NGX_ERROR;
}
/* DEBUG */
#if (HAVE_KQUEUE)
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
ngx_log_debug(c->log, "ngx_event_recv: eof:%d, avail:%d, err:%d" _
@ -30,54 +25,32 @@ ssize_t ngx_event_recv_core(ngx_connection_t *c, char *buf, size_t size)
#if (USE_KQUEUE)
if (ev->eof && ev->available == 0) {
if (ev->error) {
ngx_set_socket_errno(ev->error);
if (ev->error == NGX_ECONNRESET && ev->ignore_econnreset) {
return 0;
}
ngx_log_error(NGX_LOG_ERR, c->log, ev->error,
"recv() failed");
return NGX_ERROR;
}
return 0;
}
#elif (HAVE_KQUEUE)
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
if (ev->eof && ev->available == 0) {
if (ev->error) {
ngx_set_socket_errno(ev->error);
if (ev->error == NGX_ECONNRESET && ev->ignore_econnreset) {
return 0;
}
ngx_log_error(NGX_LOG_ERR, c->log, ev->error,
"recv() failed");
return NGX_ERROR;
}
if (ev->error == 0) {
return 0;
}
ngx_set_socket_errno(ev->error);
err = ev->error;
n = -1;
} else {
n = ngx_recv(c->fd, buf, size, 0);
if (n == -1) {
err = ngx_socket_errno;
}
}
#endif
n = ngx_recv(c->fd, buf, size, 0);
if (n == -1) {
err = ngx_socket_errno;
ev->ready = 0;
if (ev->error == NGX_ECONNRESET && ev->ignore_econnreset) {
if (err == NGX_ECONNRESET && ev->ignore_econnreset) {
return 0;
}
if (err == NGX_EAGAIN) {
ngx_log_error(NGX_LOG_INFO, c->log, err, "recv() returns EAGAIN");
ngx_log_error(NGX_LOG_INFO, c->log, err, "recv() returned EAGAIN");
return NGX_AGAIN;
}
@ -85,17 +58,90 @@ ssize_t ngx_event_recv_core(ngx_connection_t *c, char *buf, size_t size)
return NGX_ERROR;
}
#if (USE_KQUEUE)
ev->available -= n;
if (ev->available == 0) {
ev->ready = 0;
}
return n;
#elif (HAVE_KQUEUE)
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
ev->available -= n;
if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT)
&& ev->eof && ev->available == 0) {
if (ev->error == 0) {
return 0;
}
ngx_set_socket_errno(ev->error);
err = ev->error;
n = -1;
} else {
n = ngx_recv(c->fd, buf, size, 0);
ngx_log_debug(c->log, "ngx_event_recv: read:%d:%d" _ n _ size);
if (n == -1) {
err = ngx_socket_errno;
}
}
#endif
if (n == -1) {
ev->ready = 0;
if (err == NGX_ECONNRESET && ev->ignore_econnreset) {
return 0;
}
if (err == NGX_EAGAIN) {
ngx_log_error(NGX_LOG_INFO, c->log, err, "recv() returned EAGAIN");
return NGX_AGAIN;
}
ngx_log_error(NGX_LOG_ERR, c->log, err, "recv() failed");
return NGX_ERROR;
}
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
ev->available -= n;
if (ev->available == 0) {
ev->ready = 0;
}
} else if ((size_t) n < size) {
ev->ready = 0;
}
return n;
#else /* not kqueue */
n = ngx_recv(c->fd, buf, size, 0);
if (n == -1) {
err = ngx_socket_errno;
ev->ready = 0;
if (err == NGX_ECONNRESET && ev->ignore_econnreset) {
return 0;
}
if (err == NGX_EAGAIN) {
ngx_log_error(NGX_LOG_INFO, c->log, err, "recv() returned EAGAIN");
return NGX_AGAIN;
}
ngx_log_error(NGX_LOG_ERR, c->log, err, "recv() failed");
return NGX_ERROR;
}
if ((size_t) n < size) {
ev->ready = 0;
}
return n;
#endif
}

View File

@ -14,47 +14,8 @@
#include <ngx_http_event_proxy_handler.h>
static ngx_command_t ngx_http_proxy_commands[] = {
{ngx_string("proxy_large_header"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_proxy_loc_conf_t, large_header)},
{ngx_null_string, 0, NULL, 0, 0}
};
static ngx_http_module_t ngx_http_proxy_module_ctx = {
NGX_HTTP_MODULE,
NULL, /* create server config */
NULL, /* init server config */
NULL, /* create location config */
NULL, /* merge location config */
NULL, /* translate handler */
NULL, /* output header filter */
NULL, /* next output header filter */
NULL, /* output body filter */
NULL /* next output body filter */
};
ngx_module_t ngx_http_proxy_module = {
0, /* module index */
&ngx_http_proxy_module_ctx, /* module context */
ngx_http_proxy_commands, /* module directives */
NGX_HTTP_MODULE_TYPE, /* module type */
NULL /* init module */
};
static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r);
static int ngx_http_proxy_connect(ngx_http_request_t *r,
static int ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p,
struct sockaddr_in *addr,
char *addr_text);
static int ngx_http_proxy_send_request(ngx_event_t *ev);
@ -70,7 +31,48 @@ static int ngx_http_proxy_write_to_client(ngx_event_t *ev);
static int ngx_read_http_proxy_status_line(ngx_http_proxy_ctx_t *ctx);
static char conn_close[] = "Connection: close" CRLF;
static ngx_command_t ngx_http_proxy_commands[] = {
{ngx_string("proxy_large_header"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_proxy_loc_conf_t, large_header)},
{ngx_null_string, 0, NULL, 0, 0}
};
static ngx_http_module_t ngx_http_proxy_module_ctx = {
NULL, /* create server config */
NULL, /* init server config */
NULL, /* create location config */
NULL, /* merge location config */
NULL /* init filters */
};
ngx_module_t ngx_http_proxy_module = {
0, /* module index */
&ngx_http_proxy_module_ctx, /* module context */
ngx_http_proxy_commands, /* module directives */
NGX_HTTP_MODULE_TYPE, /* module type */
NULL /* init module */
};
static ngx_str_t http_methods[] = {
ngx_string("GET "),
ngx_string("HEAD "),
ngx_string("POST ")
};
static char http_version[] = " HTTP/1.0" CRLF;
static char host_header[] = "Host: ";
static char conn_close_header[] = "Connection: close" CRLF;
/* AF_INET only */
@ -78,32 +80,57 @@ static char conn_close[] = "Connection: close" CRLF;
int ngx_http_proxy_handler(ngx_http_request_t *r)
{
struct sockaddr_in addr;
ngx_chain_t *chain;
ngx_http_proxy_ctx_t *p;
struct sockaddr_in addr;
ngx_chain_t *chain;
ngx_http_proxy_ctx_t *p;
ngx_http_log_ctx_t *hcx;
ngx_http_proxy_log_ctx_t *lcx;
p = (ngx_http_proxy_ctx_t *)
ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx);
ngx_http_get_module_ctx(r, ngx_http_proxy_module);
if (p == NULL) {
ngx_http_create_ctx(r, p, ngx_http_proxy_module_ctx,
ngx_http_create_ctx(r, p, ngx_http_proxy_module,
sizeof(ngx_http_proxy_ctx_t),
NGX_HTTP_INTERNAL_SERVER_ERROR);
}
p->request = r;
ngx_test_null(p->log, ngx_palloc(r->pool, sizeof(ngx_log_t)),
NGX_HTTP_INTERNAL_SERVER_ERROR);
ngx_memcpy(p->log, r->connection->log, sizeof(ngx_log_t));
ngx_test_null(lcx, ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_log_ctx_t)),
NGX_HTTP_INTERNAL_SERVER_ERROR);
p->log->data = lcx;
hcx = r->connection->log->data;
lcx->client = hcx->client;
/*
if (!resolved) {
return ngx_dns_resolve(name, handler, p, r->pool, p->log);
}
*/
chain = ngx_http_proxy_create_request(r);
if (chain == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
/* TODO: duplicate hunks and chain if there is backend farm */
p->out = chain;
ngx_memzero(&addr, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
#if 0
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
#else
addr.sin_addr.s_addr = inet_addr("192.168.10.2");
#endif
addr.sin_port = htons(9000);
return ngx_http_proxy_connect(r, &addr, "connecting to 127.0.0.1:9000");
return ngx_http_proxy_connect(p, &addr, "connecting to 127.0.0.1:9000");
}
@ -125,7 +152,7 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r)
/* TODO: Host length */
/* "Connection: close\r\n" */
len += sizeof(conn_close) - 1;
len += sizeof(conn_close_header) - 1;
header = (ngx_table_elt_t *) r->headers_in.headers->elts;
for (i = 0; i < r->headers_in.headers->nelts; i++) {
@ -146,16 +173,54 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r)
ngx_test_null(hunk, ngx_create_temp_hunk(r->pool, len, 0, 0), NULL);
ngx_add_hunk_to_chain(chain, hunk, r->pool, NULL);
/* STUB: "method p->url HTTP/1.0" */
#if 0
/* the request line */
ngx_memcpy(hunk->last, http_methods[p->method - 1].data,
http_methods[p->method - 1].len);
hunk->last += http_methods[p->method - 1].len;
ngx_memcpy(hunk->last, p->uri_start.data, p->uri_start.len);
hunk->last += p->uri_start.len;
ngx_memcpy(hunk->last, p->uri_rest.data, p->uri_rest.len);
hunk->last += p->uri_rest.len;
if (r->args) {
*(hunk->last++) = '?';
ngx_memcpy(hunk->last, r->uri_args.data, r->uri_args.len);
hunk->last += r->uri_args.len;
}
ngx_memcpy(hunk->last, http_version, sizeof(http_version) - 1);
hunk->last += sizeof(http_version) - 1;
/* the 'Host' header */
ngx_memcpy(hunk->last, host_header, sizeof(host_header) - 1);
hunk->last += sizeof(host_header) - 1;
ngx_memcpy(hunk->last, p->host.data, p->host.len);
hunk->last += p->host.len;
*(hunk->last++) = CR; *(hunk->last++) = LF;
/* the 'Connection: close' header */
ngx_memcpy(hunk->last, conn_close_header, sizeof(conn_close_header) - 1);
hunk->last += sizeof(conn_close_header) - 1;
#else
ngx_memcpy(hunk->last, r->request_line.data, r->request_line.len);
hunk->last += r->request_line.len;
*(hunk->last++) = CR; *(hunk->last++) = LF;
/* TODO: Host header */
ngx_memcpy(hunk->last, conn_close_header, sizeof(conn_close_header) - 1);
hunk->last += sizeof(conn_close_header) - 1;
ngx_memcpy(hunk->last, conn_close, sizeof(conn_close) - 1);
hunk->last += sizeof(conn_close) - 1;
#endif
for (i = 0; i < r->headers_in.headers->nelts; i++) {
if (&header[i] == r->headers_in.host) {
@ -190,7 +255,197 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r)
}
static int ngx_http_proxy_connect(ngx_http_request_t *r,
#if 0
client_read()
if (!ev->write) {
if error close upstream ?
else block it
}
static int ngx_http_proxy_process_upstream(ngx_event_t *ev)
{
again = 0;
do {
if (p->state_write_upstream_handler ==
ngx_http_proxy_connect_to_upstream) {
if (!get_cached_connection())
get_next_upstream(p);
}
if (ev->write) {
/* ngx_http_proxy_connect_to_upstream()
ngx_http_proxy_send_request() */
rc = p->state_write_upstream_handler(p);
} else {
/* ngx_http_proxy_read_response() */
rc = p->state_read_upstream_handler(p);
}
if (rc == NGX_BUSY || rc == NGX_AGAIN || rc == NGX_OK) {
return rc;
}
if (rc == NGX_ERROR) {
return ngx_http_proxy_finalize_request(p,
NGX_HTTP_INTERNAL_SERVER_ERROR);
}
/* This NGX_HTTP_INTERNAL_SERVER_ERROR is sent by an upstream */
if (rc == NGX_HTTP_BAD_GATEWAY || rc == NGX_HTTP_GATEWAY_TIME_OUT
|| (rc == NGX_HTTP_INTERNAL_SERVER_ERROR && lcf->retry_500)
{
ngx_http_close_connection(ev);
if (p->upstream->amount > 1) {
/* Here is the race condition on SMP machine
when the upstreams are shared between threads or processes
but it's not serious */
p->upstream->upstreams[p->cur_upstream].fails++;
}
p->upstreams--;
if (p->upstreams == 0) {
return ngx_http_proxy_finalize_request(p, rc);
}
p->cur_upstream++;
if (p->cur_upstream > p->upstream->amount) {
p->cur_upstream = 0;
}
p->state_read_upstream_handler = ignore;
p->state_write_upstream_handler =
ngx_http_proxy_connect_to_upstream;
again = 1;
}
if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
???
}
} while (again);
return NGX_BUSY;
}
static int ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p)
{
ngx_socket_t s;
ngx_connection_t *c;
ngx_http_log_ctx_t *lcx;
lcx = p->log->data;
lcx->action = "connecting to an upstream";
lcx->upstream = p->upstream.data;
p->log->handler = ngx_http_proxy_log_error;
s = ngx_socket(AF_INET, SOCK_STREAM, IPPROTO_IP, 0);
if (s == -1) {
ngx_log_error(NGX_LOG_ALERT, p->log, ngx_socket_errno,
ngx_socket_n " failed");
return NGX_ERROR;
}
if (lcf->rcvbuf) {
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
(const void *) &rcvbuf, sizeof(int)) == -1) {
ngx_log_error(NGX_LOG_ALERT, p->log, ngx_socket_errno,
"setsockopt(SO_RCVBUF) failed");
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, p->log, ngx_socket_errno,
ngx_close_socket_n " failed");
}
return NGX_ERROR;
}
}
if (ngx_nonblocking(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, p->log, ngx_socket_errno,
ngx_nonblocking_n " failed");
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, p->log, ngx_socket_errno,
ngx_close_socket_n " failed");
}
return NGX_ERROR;
}
rc = connect(s, (struct sockaddr *) p->addr, sizeof(struct sockaddr_in));
if (rc == -1) {
err = ngx_socket_errno;
if (err != NGX_EINPROGRESS) {
ngx_log_error(NGX_LOG_CRIT, p->log, err, "connect() failed");
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, p->log, ngx_socket_errno,
ngx_close_socket_n " failed");
}
return NGX_HTTP_BAD_GATEWAY;
}
}
c = &ngx_connections[s];
rev = &ngx_read_events[s];
wev = &ngx_write_events[s];
ngx_memzero(rev, sizeof(ngx_event_t));
ngx_memzero(wev, sizeof(ngx_event_t));
ngx_memzero(c, sizeof(ngx_connection_t));
rev->index = wev->index = NGX_INVALID_INDEX;
rev->data = wev->data = c;
c->read = rev;
c->write = wev;
rev->first = wev->first = 1;
c->data = p->request;
p->connection = c;
c->fd = s;
rev->log = wev->log = c->log = p->log;
ngx_test_null(c->pool, ngx_create_pool(lcf->conn_pool_size, p->log),
NGX_ERROR);
}
#if 0
connect_upstream()
get next upstream
init connect to upstream
if error return error
if ok send_request();
if inprogress p->state_handler = send_request, return busy
send_request()
if timeout inc fail counter
p->state_handler = connect_upstream, return 504
#endif
#endif
static int ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p,
struct sockaddr_in *addr,
char *addr_text)
{
@ -201,7 +456,7 @@ static int ngx_http_proxy_connect(ngx_http_request_t *r,
ngx_connection_t *c, *pc;
ngx_http_log_ctx_t *ctx;
c = r->connection;
c = p->request->connection;
ctx = c->log->data;
ctx->action = addr_text;
@ -253,7 +508,7 @@ static int ngx_http_proxy_connect(ngx_http_request_t *r,
ngx_close_socket_n " failed");
}
return NGX_HTTP_INTERNAL_SERVER_ERROR;
return NGX_HTTP_BAD_GATEWAY;
}
}
@ -265,16 +520,21 @@ static int ngx_http_proxy_connect(ngx_http_request_t *r,
ngx_memzero(wev, sizeof(ngx_event_t));
ngx_memzero(pc, sizeof(ngx_connection_t));
rev->index = wev->index = NGX_INVALID_INDEX;
rev->data = wev->data = pc;
pc->read = rev;
pc->write = wev;
pc->data = r;
pc->data = p->request;;
p->connection = pc;
pc->fd = s;
pc->servers = c->servers;
pc->log = rev->log = wev->log = c->log;
ngx_test_null(pc->log, ngx_palloc(c->pool, sizeof(ngx_log_t)), NGX_OK);
ngx_memcpy(pc->log, c->log, sizeof(ngx_log_t));
rev->log = wev->log = pc->log;
ngx_test_null(pc->pool,
ngx_create_pool(/* STUB */ 1024 /**/, pc->log),
@ -282,6 +542,8 @@ static int ngx_http_proxy_connect(ngx_http_request_t *r,
wev->event_handler = ngx_http_proxy_send_request;
rev->event_handler = ngx_http_proxy_init_response;
rev->close_handler = wev->close_handler = ngx_event_close_connection;
#if (USE_KQUEUE)
@ -314,18 +576,25 @@ static int ngx_http_proxy_connect(ngx_http_request_t *r,
/* TODO: aio, iocp */
/* The connection is in a progress */
if (rc == -1) {
/* TODO: oneshot */
if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
/* The connection has been established */
if (rc == 0) {
wev->write = 1;
wev->ready = 1;
return ngx_http_proxy_send_request(wev);
}
wev->write = 1;
wev->ready = 1;
/* The connection is in a progress */
return ngx_http_proxy_send_request(wev);
/* TODO: oneshot */
if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
wev->timer_set = 1;
ngx_add_timer(wev, /* STUB: lcf->connect_timeout */ 10000);
return NGX_BUSY;
}
@ -339,7 +608,11 @@ static int ngx_http_proxy_send_request(ngx_event_t *ev)
c = (ngx_connection_t *) ev->data;
r = (ngx_http_request_t *) c->data;
p = (ngx_http_proxy_ctx_t *)
ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx);
ngx_http_get_module_ctx(r, ngx_http_proxy_module);
if (ev->timedout) {
return ngx_http_proxy_error(r, p, NGX_HTTP_GATEWAY_TIME_OUT);
}
chain = ngx_write_chain(c, p->out, 0);
if (chain == (ngx_chain_t *) -1) {
@ -348,7 +621,7 @@ static int ngx_http_proxy_send_request(ngx_event_t *ev)
p->out = chain;
return NGX_WAITING;
return NGX_BUSY;
}
@ -368,7 +641,7 @@ static int ngx_http_proxy_init_response(ngx_event_t *ev)
}
p = (ngx_http_proxy_ctx_t *)
ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx);
ngx_http_get_module_ctx(r, ngx_http_proxy_module);
ngx_test_null(p->header_in,
ngx_create_temp_hunk(r->pool,
@ -407,7 +680,7 @@ static int ngx_http_proxy_read_response_header(ngx_event_t *ev)
c = (ngx_connection_t *) ev->data;
r = (ngx_http_request_t *) c->data;
p = (ngx_http_proxy_ctx_t *)
ngx_http_get_module_ctx(r, ngx_http_proxy_module);
ngx_http_get_module_ctx(r, ngx_http_proxy_module);
if (ev->timedout) {
return ngx_http_proxy_error(r, p, NGX_HTTP_GATEWAY_TIME_OUT);
@ -516,7 +789,7 @@ static int ngx_http_proxy_read_response_header(ngx_event_t *ev)
return ngx_http_proxy_read_response_body(ev);
}
return NGX_WAITING;
return NGX_BUSY;
}
@ -575,7 +848,7 @@ static int ngx_http_proxy_read_response_body(ngx_event_t *ev)
c = (ngx_connection_t *) ev->data;
r = (ngx_http_request_t *) c->data;
p = (ngx_http_proxy_ctx_t *)
ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx);
ngx_http_get_module_ctx(r, ngx_http_proxy_module);
if (p->hunks.nelts > 0) {
h = ((ngx_hunk_t **) p->hunks.elts)[p->hunks.nelts - 1];
@ -631,7 +904,7 @@ static int ngx_http_proxy_read_response_body(ngx_event_t *ev)
ngx_log_debug(c->log, "READ:%d" _ n);
if (n == NGX_AGAIN) {
return NGX_WAITING;
return NGX_BUSY;
}
if (n == NGX_ERROR) {
@ -660,7 +933,7 @@ static int ngx_http_proxy_read_response_body(ngx_event_t *ev)
return ngx_http_proxy_write_to_client(c->write);
}
/* STUB */ return NGX_WAITING;
/* STUB */ return NGX_BUSY;
}
@ -675,7 +948,7 @@ static int ngx_http_proxy_write_to_client(ngx_event_t *ev)
c = (ngx_connection_t *) ev->data;
r = (ngx_http_request_t *) c->data;
p = (ngx_http_proxy_ctx_t *)
ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx);
ngx_http_get_module_ctx(r, ngx_http_proxy_module);
do {
h = ((ngx_hunk_t **) p->hunks.elts)[p->hunk_n];
@ -706,6 +979,17 @@ static int ngx_http_proxy_error(ngx_http_request_t *r, ngx_http_proxy_ctx_t *p,
}
static size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len)
{
ngx_http_proxy_log_ctx_t *lcx = (ngx_http_proxy_log_ctx_t *) data;
return ngx_snprintf(buf, len,
" while %s, upstream: %s, client: %s, URL: %s",
lcx->action, lcx->upstream, lcx->client, lcx->url);
}
static int ngx_read_http_proxy_status_line(ngx_http_proxy_ctx_t *ctx)
{
char ch;
@ -864,3 +1148,106 @@ static int ngx_read_http_proxy_status_line(ngx_http_proxy_ctx_t *ctx)
return NGX_AGAIN;
}
}
#if 0
static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd,
char *conf)
{
ngx_http_proxy_conf_t *lcf = (ngx_http_proxy_conf_t *) conf;
char *url;
ngx_str_t *value;
ngx_http_proxy_pass_t *pass;
value = (ngx_str_t *) cf->args->elts;
url = value[1].data;
ngx_test_null(pass, ngx_push_array(lcf->proxy_pass), NGX_CONF_ERROR);
if (ngx_strncasecmp(url, "http://", 7) == 0) {
"invalid prefix in URL %s", url;
}
err = ngx_http_proxy_parse_upstream(url, u);
if (err) {
"%s %s", err, url;
}
h = ngx_gethostbyname(cmd->pool, u->host);
return NULL;
}
#endif
static char *ngx_http_proxy_parse_upstream(ngx_str_t *url,
ngx_http_proxy_upstream_url_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_name.data = &url->data[i];
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_name.data == NULL) {
return NULL;
}
u->port_name.len = &url->data[i] - u->port_name.data;
if (u->port_name.len > 0) {
u->port = ngx_atoi(u->port_name.data, u->port_name.len);
if (u->port > 0) {
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_name.data == NULL) {
return NULL;
}
u->port_name.len = &url->data[i] - u->port_name.data;
if (u->port_name.len > 0) {
u->port = ngx_atoi(u->port_name.data, u->port_name.len);
if (u->port > 0) {
return NULL;
}
}
return "invalid port in upstream URL";
}

View File

@ -20,6 +20,41 @@ typedef struct {
} ngx_http_proxy_loc_conf_t;
typedef struct {
ngx_str_t host;
ngx_str_t uri;
ngx_str_t host_header;
ngx_str_t port_name;
int port;
} ngx_http_proxy_upstream_url_t;
typedef struct {
struct sockaddr_in;
ngx_str_t name;
time_t access;
int fails;
} ngx_http_proxy_upstream_t;
typedef struct {
int amount;
ngx_http_proxy_upstream_t *upstreams;
} ngx_http_proxy_upstream_farm_t;
#if 0
/* location /one/ { proxy_pass http://localhost:9000/two/; } */
typedef struct {
/* "/one/" */
/* "http://localhost:9000/two/" */
/* "/two/" */
*upstream_farm;
} ngx_http_proxy_pass_t;
#endif
typedef struct ngx_http_proxy_ctx_s ngx_http_proxy_ctx_t;
struct ngx_http_proxy_ctx_s {
@ -30,9 +65,16 @@ struct ngx_http_proxy_ctx_s {
int hunk_n;
ngx_connection_t *connection;
ngx_connection_t *connection;
ngx_http_request_t *request;
ngx_http_proxy_headers_in_t *headers_in;
ngx_http_proxy_upstream_farm_t *upstream;
int cur_upstream;
int upstreams;
ngx_log_t *log;
ngx_hunk_t *header_in;
int state;
int status;
@ -43,6 +85,14 @@ struct ngx_http_proxy_ctx_s {
};
typedef struct {
char *action;
char *upstream;
char *client;
char *url;
} ngx_http_proxy_log_ctx_t;
extern ngx_module_t ngx_http_proxy_module;

View File

@ -35,20 +35,13 @@ static ngx_command_t ngx_http_index_commands[] = {
ngx_http_module_t ngx_http_index_module_ctx = {
NGX_HTTP_MODULE,
NULL, /* create server config */
NULL, /* init server config */
ngx_http_index_create_conf, /* create location config */
ngx_http_index_merge_conf, /* merge location config */
NULL, /* translate handler */
NULL, /* output header filter */
NULL, /* next output header filter */
NULL, /* output body filter */
NULL, /* next output body filter */
NULL /* init filters */
};
@ -288,18 +281,18 @@ static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child)
static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
char *conf)
{
ngx_http_index_conf_t *icf = (ngx_http_index_conf_t *) conf;
ngx_http_index_conf_t *lcf = (ngx_http_index_conf_t *) conf;
int i;
ngx_str_t *index, *value;
value = (ngx_str_t *) cf->args->elts;
for (i = 1; i < cf->args->nelts; i++) {
ngx_test_null(index, ngx_push_array(icf->indices), NGX_CONF_ERROR);
ngx_test_null(index, ngx_push_array(lcf->indices), NGX_CONF_ERROR);
index->len = value[i].len;
index->data = value[i].data;
if (icf->max_index_len < index->len) {
icf->max_index_len = index->len;
if (lcf->max_index_len < index->len) {
lcf->max_index_len = index->len;
}
}

View File

@ -5,6 +5,7 @@
#include <ngx_alloc.h>
#include <ngx_time.h>
#include <ngx_http.h>
#include <ngx_http_config.h>
ngx_http_module_t ngx_http_log_module;

View File

@ -5,25 +5,13 @@
#include <ngx_file.h>
#include <ngx_hunk.h>
#include <ngx_http.h>
#include <ngx_http_config.h>
#include <ngx_http_output_filter.h>
ngx_http_module_t ngx_http_static_module;
#if 0
/* STUB */
static ngx_http_static_ctx_t module_ctx;
void ngx_http_static_init()
{
module_ctx.out = NULL;
ngx_http_static_module.ctx = &module_ctx;
}
/* */
#endif
int ngx_http_static_handler(ngx_http_request_t *r)
{
int rc;

View File

@ -28,6 +28,7 @@ int ngx_http_large_client_header = 1;
int ngx_http_url_in_error_log = 1;
ngx_array_t ngx_http_translate_handlers;
ngx_array_t ngx_http_index_handlers;
@ -61,13 +62,12 @@ ngx_module_t ngx_http_module = {
static void ngx_http_init_filters(ngx_pool_t *pool, ngx_module_t **modules)
{
int i;
ngx_http_module_t *module;
int (*ohf)(ngx_http_request_t *r);
int (*obf)(ngx_http_request_t *r, ngx_chain_t *ch);
int i;
ngx_http_module_t *module;
ngx_http_conf_filter_t cf;
ohf = NULL;
obf = NULL;
cf.output_header_filter = NULL;
cf.output_body_filter = NULL;
for (i = 0; modules[i]; i++) {
if (modules[i]->type != NGX_HTTP_MODULE_TYPE) {
@ -76,18 +76,12 @@ static void ngx_http_init_filters(ngx_pool_t *pool, ngx_module_t **modules)
module = (ngx_http_module_t *) modules[i]->ctx;
if (module->output_header_filter) {
module->next_output_header_filter = ohf;
ohf = module->output_header_filter;
}
if (module->output_body_filter) {
module->next_output_body_filter = obf;
obf = module->output_body_filter;
if (module->init_filters) {
module->init_filters(pool, &cf);
}
}
ngx_http_top_header_filter = ohf;
ngx_http_top_header_filter = cf.output_header_filter;
}
@ -119,10 +113,6 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
continue;
}
/* STUB */
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
module->index = ngx_http_max_module;
ngx_modules[i]->index = ngx_http_max_module++;
}
@ -139,7 +129,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
if (module->create_loc_conf) {
ngx_test_null(ctx->loc_conf[module->index],
ngx_test_null(ctx->loc_conf[ngx_modules[i]->index],
module->create_loc_conf(cf->pool),
NGX_CONF_ERROR);
}
@ -173,6 +163,9 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
/**/
#endif
ngx_init_array(ngx_http_translate_handlers,
cf->pool, 10, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR);
ngx_init_array(ngx_http_index_handlers,
cf->pool, 3, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR);

View File

@ -38,14 +38,18 @@
#define NGX_HTTP_OK 200
#define NGX_HTTP_SPECIAL_RESPONSE 300
#define NGX_HTTP_MOVED_PERMANENTLY 301
#define NGX_HTTP_MOVED_TEMPORARILY 302
#define NGX_HTTP_NOT_MODIFIED 304
#define NGX_HTTP_BAD_REQUEST 400
#define NGX_HTTP_FORBIDDEN 403
#define NGX_HTTP_NOT_FOUND 404
#define NGX_HTTP_REQUEST_TIME_OUT 408
#define NGX_HTTP_REQUEST_URI_TOO_LARGE 414
#define NGX_HTTP_INTERNAL_SERVER_ERROR 500
#define NGX_HTTP_NOT_IMPLEMENTED 501
#define NGX_HTTP_BAD_GATEWAY 502
@ -59,9 +63,8 @@
typedef struct {
size_t len;
char *data;
int offset;
ngx_str_t name;
int offset;
} ngx_http_header_t;
@ -71,9 +74,10 @@ typedef struct {
ngx_table_elt_t *host;
ngx_table_elt_t *connection;
ngx_table_elt_t *if_modified_since;
ngx_table_elt_t *user_agent;
ngx_table_elt_t *accept_encoding;
ngx_table_elt_t *user_agent;
ngx_table_t *headers;
} ngx_http_headers_in_t;
@ -101,34 +105,34 @@ typedef struct {
typedef struct ngx_http_request_s ngx_http_request_t;
struct ngx_http_request_s {
ngx_file_t file;
ngx_connection_t *connection;
void **ctx;
void **srv_conf;
void **loc_conf;
void **ctx;
void **srv_conf;
void **loc_conf;
ngx_pool_t *pool;
ngx_hunk_t *header_in;
ngx_file_t file;
ngx_pool_t *pool;
ngx_hunk_t *header_in;
ngx_http_headers_in_t headers_in;
ngx_http_headers_out_t headers_out;
int (*handler)(ngx_http_request_t *r);
int method;
time_t lingering_time;
int http_version;
int http_major;
int http_minor;
int method;
int http_version;
int http_major;
int http_minor;
ngx_str_t request_line;
ngx_str_t uri;
ngx_str_t exten;
ngx_http_request_t *main;
ngx_connection_t *connection;
ngx_str_t request_line;
ngx_str_t uri;
ngx_str_t args;
ngx_str_t exten;
ngx_http_request_t *main;
u_int in_addr;
@ -192,32 +196,6 @@ typedef int (*ngx_http_output_body_filter_p)
(ngx_http_request_t *r, ngx_chain_t *chain);
typedef struct {
int index;
void *(*create_srv_conf)(ngx_pool_t *p);
char *(*init_srv_conf)(ngx_pool_t *p, void *conf);
void *(*create_loc_conf)(ngx_pool_t *p);
char *(*merge_loc_conf)(ngx_pool_t *p, void *prev, void *conf);
int (*translate_handler)(ngx_http_request_t *r);
int (*output_header_filter) (ngx_http_request_t *r);
int (*next_output_header_filter) (ngx_http_request_t *r);
int (*output_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
int (*next_output_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
} ngx_http_module_t;
#define NGX_HTTP_MODULE 0x80000000
#define NGX_HTTP_MODULE_TYPE 0x50545448 /* "HTTP" */
#define ngx_http_get_module_srv_conf(r, module) r->srv_conf[module.index]
#define ngx_http_get_module_loc_conf(r, module) r->loc_conf[module.index]
#define ngx_http_get_module_ctx(r, module) r->ctx[module.index]
#define ngx_http_create_ctx(r, cx, module, size, error) \
@ -243,7 +221,7 @@ int ngx_http_handler(ngx_http_request_t *r);
int ngx_http_send_header(ngx_http_request_t *r);
int ngx_http_special_response(ngx_http_request_t *r, int error);
int ngx_http_special_response_handler(ngx_http_request_t *r, int error);
time_t ngx_http_parse_time(char *value, size_t len);
@ -269,12 +247,10 @@ extern int ngx_http_discarded_buffer_size;
extern int ngx_http_url_in_error_log;
extern ngx_array_t ngx_http_translate_handlers;
extern ngx_array_t ngx_http_index_handlers;
extern ngx_http_module_t *ngx_http_modules[];
/* STUB */
int ngx_http_log_handler(ngx_http_request_t *r);
/**/

View File

@ -12,14 +12,39 @@ typedef struct {
} ngx_http_conf_ctx_t;
typedef struct {
int (*output_header_filter) (ngx_http_request_t *r);
int (*output_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
} ngx_http_conf_filter_t;
typedef struct {
void *(*create_srv_conf)(ngx_pool_t *p);
char *(*init_srv_conf)(ngx_pool_t *p, void *conf);
void *(*create_loc_conf)(ngx_pool_t *p);
char *(*merge_loc_conf)(ngx_pool_t *p, void *prev, void *conf);
void (*init_filters) (ngx_pool_t *p, ngx_http_conf_filter_t *cf);
} ngx_http_module_t;
#define NGX_HTTP_MODULE_TYPE 0x50545448 /* "HTTP" */
#define NGX_HTTP_MAIN_CONF 0x1000000
#define NGX_HTTP_SRV_CONF 0x2000000
#define NGX_HTTP_LOC_CONF 0x6000000
#define NGX_HTTP_SRV_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, srv_conf)
#define NGX_HTTP_LOC_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, loc_conf)
#define ngx_http_get_module_srv_conf(r, module) r->srv_conf[module.index]
#define ngx_http_get_module_loc_conf(r, module) r->loc_conf[module.index]
int ngx_http_config_modules(ngx_pool_t *pool, ngx_module_t **modules);
@ -28,8 +53,5 @@ extern ngx_module_t ngx_http_module;
extern int (*ngx_http_top_header_filter) (ngx_http_request_t *r);
extern void **ngx_srv_conf;
extern void **ngx_loc_conf;
#endif /* _NGX_HTTP_CONFIG_H_INCLUDED_ */

View File

@ -19,12 +19,15 @@ int ngx_http_proxy_handler(ngx_http_request_t *r);
static int ngx_http_core_index_handler(ngx_http_request_t *r);
static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy);
static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd,
char *dummy);
static int ngx_http_core_init(ngx_pool_t *pool);
static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool);
static char *ngx_http_core_init_srv_conf(ngx_pool_t *pool, void *conf);
static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool);
static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy);
static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd,
char *dummy);
static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
@ -108,24 +111,18 @@ static ngx_command_t ngx_http_core_commands[] = {
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, lingering_timeout)},
{ngx_string(""), 0, NULL, 0, 0}
{ngx_null_string, 0, NULL, 0, 0}
};
ngx_http_module_t ngx_http_core_module_ctx = {
NGX_HTTP_MODULE,
ngx_http_core_create_srv_conf, /* create server config */
ngx_http_core_init_srv_conf, /* init server config */
ngx_http_core_create_loc_conf, /* create location config */
NULL, /* merge location config */
ngx_http_core_translate_handler, /* translate handler */
NULL, /* output header filter */
NULL, /* next output header filter */
NULL, /* output body filter */
NULL /* next output body filter */
NULL /* init filters */
};
@ -134,13 +131,14 @@ ngx_module_t ngx_http_core_module = {
&ngx_http_core_module_ctx, /* module context */
ngx_http_core_commands, /* module directives */
NGX_HTTP_MODULE_TYPE, /* module type */
NULL /* init module */
ngx_http_core_init /* init module */
};
int ngx_http_handler(ngx_http_request_t *r)
{
int rc, a, n, i;
ngx_http_handler_pt *h;
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx;
ngx_http_in_port_t *in_port;
@ -149,8 +147,8 @@ int ngx_http_handler(ngx_http_request_t *r)
r->connection->unexpected_eof = 0;
r->keepalive = 1;
r->lingering_close = 1;
r->keepalive = 0;
#if 1
r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
@ -213,34 +211,25 @@ ngx_log_debug(r->connection->log, "srv_conf: %0x" _ r->srv_conf);
ngx_log_debug(r->connection->log, "loc_conf: %0x" _ r->loc_conf);
/* run translation phase */
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
h = (ngx_http_handler_pt *) ngx_http_translate_handlers.elts;
for (i = 0; i < ngx_http_translate_handlers.nelts; i++) {
rc = h[i](r);
if (rc == NGX_DECLINED) {
continue;
}
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
if (module->translate_handler == NULL) {
continue;
}
rc = module->translate_handler(r);
if (rc == NGX_OK) {
break;
}
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
return ngx_http_special_response(r, rc);
return rc;
}
}
rc = r->handler(r);
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
return ngx_http_special_response(r, rc);
}
return rc;
return r->handler(r);
}
@ -252,27 +241,27 @@ int ngx_http_core_translate_handler(ngx_http_request_t *r)
ngx_table_elt_t *h;
ngx_http_server_name_t *s_name;
ngx_http_core_srv_conf_t *scf;
ngx_http_core_loc_conf_t **lcf, *loc_conf;
ngx_http_core_loc_conf_t *lcf, **plcf;
scf = (ngx_http_core_srv_conf_t *)
ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx);
ngx_http_get_module_srv_conf(r, ngx_http_core_module);
/* find location config */
lcf = (ngx_http_core_loc_conf_t **) scf->locations.elts;
plcf = (ngx_http_core_loc_conf_t **) scf->locations.elts;
for (i = 0; i < scf->locations.nelts; i++) {
ngx_log_debug(r->connection->log, "trans: %s" _ lcf[i]->name.data);
if (r->uri.len < lcf[i]->name.len) {
ngx_log_debug(r->connection->log, "trans: %s" _ plcf[i]->name.data);
if (r->uri.len < plcf[i]->name.len) {
continue;
}
rc = ngx_strncmp(r->uri.data, lcf[i]->name.data, lcf[i]->name.len);
rc = ngx_strncmp(r->uri.data, plcf[i]->name.data, plcf[i]->name.len);
if (rc < 0) {
break;
}
if (rc == 0) {
r->loc_conf = lcf[i]->loc_conf;
r->loc_conf = plcf[i]->loc_conf;
}
}
@ -286,10 +275,10 @@ ngx_log_debug(r->connection->log, "trans: %s" _ lcf[i]->name.data);
return NGX_OK;
}
loc_conf = (ngx_http_core_loc_conf_t *)
ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
lcf = (ngx_http_core_loc_conf_t *)
ngx_http_get_module_loc_conf(r, ngx_http_core_module);
ngx_log_debug(r->connection->log, "doc_root: %08x" _ &loc_conf->doc_root);
ngx_log_debug(r->connection->log, "doc_root: %08x" _ &lcf->doc_root);
s_name = (ngx_http_server_name_t *) scf->server_names.elts;
@ -314,14 +303,14 @@ ngx_log_debug(r->connection->log, "doc_root: %08x" _ &loc_conf->doc_root);
port_len = (r->port != 80) ? r->port_name.len : 0;
/* "+ 7" is "http://" */
if (loc_conf->doc_root.len > 7 + s_name[0].name.len + port_len) {
len = loc_conf->doc_root.len;
if (lcf->doc_root.len > 7 + s_name[0].name.len + port_len) {
len = lcf->doc_root.len;
f_offset = 0;
l_offset = len - (7 + s_name[0].name.len + port_len);
} else {
len = 7 + s_name[0].name.len + port_len;
f_offset = len - loc_conf->doc_root.len;
f_offset = len - lcf->doc_root.len;
l_offset = 0;
}
@ -334,8 +323,8 @@ ngx_log_debug(r->connection->log, "doc_root: %08x" _ &loc_conf->doc_root);
r->file.name.data = buf + f_offset;
location = buf + l_offset;
last = ngx_cpystrn(ngx_cpystrn(r->file.name.data, loc_conf->doc_root.data,
loc_conf->doc_root.len + 1),
last = ngx_cpystrn(ngx_cpystrn(r->file.name.data, lcf->doc_root.data,
lcf->doc_root.len + 1),
r->uri.data, r->uri.len + 1);
r->file.name.len = last - r->file.name.data;
@ -344,9 +333,9 @@ ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);
#if (WIN9X)
/* There is no way to open file or directory in Win9X with
one syscall: Win9X has not FILE_FLAG_BACKUP_SEMANTICS flag.
so we need to check its type before opening */
/* 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) {
@ -451,7 +440,7 @@ ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
return NGX_HTTP_MOVED_PERMANENTLY;
}
/* TODO: r->handler = loc_conf->default_handler; */
/* TODO: r->handler = lcf->default_handler; */
/* STUB */ r->handler = ngx_http_static_handler;
return NGX_OK;
@ -503,7 +492,7 @@ int ngx_http_redirect(ngx_http_request_t *r, int redirect)
/* log request */
return ngx_http_close_request(r);
return ngx_http_close_request(r, 0);
}
@ -514,17 +503,20 @@ int ngx_http_error(ngx_http_request_t *r, int error)
/* log request */
ngx_http_special_response(r, error);
return ngx_http_close_request(r);
ngx_http_special_response_handler(r, error);
return ngx_http_close_request(r, 0);
}
int ngx_http_close_request(ngx_http_request_t *r)
int ngx_http_close_request(ngx_http_request_t *r, int error)
{
ngx_connection_t *c;
ngx_http_log_ctx_t *ctx;
c = r->connection;
if (error) {
r->headers_out.status = error;
}
ngx_http_log_handler(r);
@ -573,14 +565,26 @@ int ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t uri)
}
static int ngx_http_core_init(ngx_pool_t *pool)
{
ngx_http_handler_pt *h;
ngx_test_null(h, ngx_push_array(&ngx_http_translate_handlers), NGX_ERROR);
*h = ngx_http_core_translate_handler;
return NGX_OK;
}
static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
{
int i, j;
char *rv;
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *prev;
ngx_http_core_srv_conf_t *scf;
ngx_http_core_loc_conf_t **lcf;
int i, j;
char *rv;
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *prev;
ngx_http_core_srv_conf_t *scf;
ngx_http_core_loc_conf_t **plcf;
ngx_test_null(ctx,
ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
@ -604,13 +608,13 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
if (module->create_srv_conf) {
ngx_test_null(ctx->srv_conf[module->index],
ngx_test_null(ctx->srv_conf[ngx_modules[i]->index],
module->create_srv_conf(cf->pool),
NGX_CONF_ERROR);
}
if (module->create_loc_conf) {
ngx_test_null(ctx->loc_conf[module->index],
ngx_test_null(ctx->loc_conf[ngx_modules[i]->index],
module->create_loc_conf(cf->pool),
NGX_CONF_ERROR);
}
@ -625,10 +629,10 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
return rv;
scf = ctx->srv_conf[ngx_http_core_module_ctx.index];
scf = ctx->srv_conf[ngx_http_core_module.index];
scf->ctx = ctx;
lcf = (ngx_http_core_loc_conf_t **)scf->locations.elts;
plcf = (ngx_http_core_loc_conf_t **)scf->locations.elts;
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) {
@ -639,7 +643,7 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
if (module->init_srv_conf) {
if (module->init_srv_conf(cf->pool,
ctx->srv_conf[module->index])
ctx->srv_conf[ngx_modules[i]->index])
== NGX_CONF_ERROR) {
return NGX_CONF_ERROR;
}
@ -647,16 +651,16 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
if (module->merge_loc_conf) {
if (module->merge_loc_conf(cf->pool,
prev->loc_conf[module->index],
ctx->loc_conf[module->index])
prev->loc_conf[ngx_modules[i]->index],
ctx->loc_conf[ngx_modules[i]->index])
== NGX_CONF_ERROR) {
return NGX_CONF_ERROR;
}
for (j = 0; j < scf->locations.nelts; j++) {
if (module->merge_loc_conf(cf->pool,
ctx->loc_conf[module->index],
lcf[j]->loc_conf[module->index])
ctx->loc_conf[ngx_modules[i]->index],
plcf[j]->loc_conf[ngx_modules[i]->index])
== NGX_CONF_ERROR) {
return NGX_CONF_ERROR;
}
@ -676,7 +680,7 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *prev;
ngx_http_core_srv_conf_t *scf;
ngx_http_core_loc_conf_t *lcf, **loc;
ngx_http_core_loc_conf_t *lcf, **plcf;
ngx_test_null(ctx,
ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
@ -697,7 +701,7 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
module = (ngx_http_module_t *) ngx_modules[i]->ctx;
if (module->create_loc_conf) {
ngx_test_null(ctx->loc_conf[module->index],
ngx_test_null(ctx->loc_conf[ngx_modules[i]->index],
module->create_loc_conf(cf->pool),
NGX_CONF_ERROR);
}
@ -712,8 +716,8 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy)
scf = (ngx_http_core_srv_conf_t *)
ctx->srv_conf[ngx_http_core_module.index];
ngx_test_null(loc, ngx_push_array(&scf->locations), NGX_CONF_ERROR);
*loc = lcf;
ngx_test_null(plcf, ngx_push_array(&scf->locations), NGX_CONF_ERROR);
*plcf = lcf;
cf->ctx = ctx;
rv = ngx_conf_parse(cf, NULL);
@ -789,7 +793,7 @@ static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool)
lcf->doc_root.len = 4;
lcf->doc_root.data = "html";
lcf->send_timeout = 10;
lcf->send_timeout = 10000;
lcf->discarded_buffer_size = 1500;
lcf->lingering_time = 30000;
lcf->lingering_timeout = 5000;

View File

@ -57,12 +57,13 @@ typedef struct {
void **loc_conf; /* pointer to modules loc_conf,
used in translation handler */
ngx_str_t doc_root; /* 'root' */
ngx_str_t doc_root; /* root */
time_t send_timeout; /* 'send_timeout' */
size_t discarded_buffer_size; /* 'discarded_buffer_size */
time_t lingering_time; /* 'lingering_time */
ngx_msec_t lingering_timeout; /* 'lingering_timeout */
time_t send_timeout; /* send_timeout */
size_t send_lowat; /* send_lowa */
size_t discarded_buffer_size; /* discarded_buffer_size */
time_t lingering_time; /* lingering_time */
ngx_msec_t lingering_timeout; /* lingering_timeout */
} ngx_http_core_loc_conf_t;
@ -87,7 +88,9 @@ int ngx_http_core_translate_handler(ngx_http_request_t *r);
int ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t uri);
int ngx_http_error(ngx_http_request_t *r, int error);
int ngx_http_close_request(ngx_http_request_t *r);
int ngx_http_finalize_request(ngx_http_request_t *r, int error);
int ngx_http_close_request(ngx_http_request_t *r, int error);
#endif /* _NGX_HTTP_CORE_H_INCLUDED_ */

File diff suppressed because it is too large Load Diff

View File

@ -10,26 +10,23 @@
#include <ngx_conf_file.h>
#include <ngx_http.h>
#include <ngx_http_config.h>
#include <ngx_http_write_filter.h>
static void ngx_http_header_filter_init(ngx_pool_t *pool,
ngx_http_conf_filter_t *cf);
static int ngx_http_header_filter(ngx_http_request_t *r);
ngx_http_module_t ngx_http_header_filter_module_ctx = {
NGX_HTTP_MODULE,
NULL, /* create server config */
NULL, /* init server config */
NULL, /* create location config */
NULL, /* merge location config */
NULL, /* translate handler */
ngx_http_header_filter, /* output header filter */
NULL, /* next output header filter */
NULL, /* output body filter */
NULL /* next output body filter */
ngx_http_header_filter_init /* init filters */
};
@ -295,3 +292,10 @@ static int ngx_http_header_filter(ngx_http_request_t *r)
return ngx_http_write_filter(r, ch);
}
static void ngx_http_header_filter_init(ngx_pool_t *pool,
ngx_http_conf_filter_t *cf)
{
cf->output_header_filter = ngx_http_header_filter;
}

View File

@ -16,6 +16,8 @@ static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src);
static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool);
static char *ngx_http_output_filter_merge_conf(ngx_pool_t *pool,
void *parent, void *child);
static void ngx_http_output_filter_init(ngx_pool_t *pool,
ngx_http_conf_filter_t *cf);
static ngx_command_t ngx_http_output_filter_commands[] = {
@ -31,20 +33,13 @@ static ngx_command_t ngx_http_output_filter_commands[] = {
static ngx_http_module_t ngx_http_output_filter_module_ctx = {
NGX_HTTP_MODULE,
NULL, /* create server config */
NULL, /* init server config */
ngx_http_output_filter_create_conf, /* create location config */
ngx_http_output_filter_merge_conf, /* merge location config */
NULL, /* translate handler */
NULL, /* output header filter */
NULL, /* next output header filter */
(int (*)(ngx_http_request_t *, ngx_chain_t *))
ngx_http_output_filter, /* output body filter */
NULL /* next output body filter */
ngx_http_output_filter_init /* output body filter */
};
@ -58,7 +53,12 @@ ngx_module_t ngx_http_output_filter_module = {
static int (*next_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
#if 0
#define next_filter ngx_http_output_filter_module_ctx.next_output_body_filter
#endif
#define need_to_copy(r, hunk) \
(((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY) \
@ -300,6 +300,14 @@ static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src)
}
static void ngx_http_output_filter_init(ngx_pool_t *pool,
ngx_http_conf_filter_t *cf)
{
next_filter = cf->output_body_filter;
cf->output_body_filter = NULL;
}
static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool)
{
ngx_http_output_filter_conf_t *conf;

View File

@ -39,6 +39,14 @@ static char error_404_page[] =
;
static char error_408_page[] =
"<html>" CRLF
"<head><title>408 Request Time-out</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>408 Request Time-out</h1></center>" CRLF
;
static char error_414_page[] =
"<html>" CRLF
"<head><title>414 Request-URI Too Large</title></head>" CRLF
@ -55,35 +63,54 @@ static char error_500_page[] =
;
static char error_502_page[] =
"<html>" CRLF
"<head><title>502 Bad Gateway</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>502 Bad Gateway</h1></center>" CRLF
;
static char error_504_page[] =
"<html>" CRLF
"<head><title>504 Gateway Time-out</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>504 Gateway Time-out</h1></center>" CRLF
;
static ngx_str_t error_pages[] = {
{ 0, NULL}, /* 301 */
{ 0, NULL}, /* 302 */
{ 0, NULL}, /* 303 */
{ 0, NULL}, /* 304 */
ngx_null_string, /* 301 */
ngx_null_string, /* 302 */
ngx_null_string, /* 303 */
{ sizeof(error_400_page) - 1, error_400_page },
{ 0, NULL}, /* 401 */
{ 0, NULL}, /* 402 */
{ sizeof(error_403_page) - 1, error_403_page },
{ sizeof(error_404_page) - 1, error_404_page },
{ 0, NULL}, /* 405 */
{ 0, NULL}, /* 406 */
{ 0, NULL}, /* 407 */
{ 0, NULL}, /* 408 */
{ 0, NULL}, /* 409 */
{ 0, NULL}, /* 410 */
{ 0, NULL}, /* 411 */
{ 0, NULL}, /* 412 */
{ 0, NULL}, /* 413 */
{ sizeof(error_414_page) - 1, error_414_page },
{ 0, NULL}, /* 415 */
{ 0, NULL}, /* 416 */
ngx_string(error_400_page),
ngx_null_string, /* 401 */
ngx_null_string, /* 402 */
ngx_string(error_403_page),
ngx_string(error_404_page),
ngx_null_string, /* 405 */
ngx_null_string, /* 406 */
ngx_null_string, /* 407 */
ngx_string(error_408_page),
ngx_null_string, /* 409 */
ngx_null_string, /* 410 */
ngx_null_string, /* 411 */
ngx_null_string, /* 412 */
ngx_null_string, /* 413 */
ngx_string(error_414_page),
ngx_null_string, /* 415 */
ngx_null_string, /* 416 */
{ sizeof(error_500_page) - 1, error_500_page }
ngx_string(error_500_page),
ngx_null_string, /* 501 */
ngx_string(error_502_page),
ngx_null_string, /* 503 */
ngx_string(error_504_page)
};
int ngx_http_special_response(ngx_http_request_t *r, int error)
int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
{
int err, len;
ngx_hunk_t *message, *tail;
@ -96,10 +123,10 @@ int ngx_http_special_response(ngx_http_request_t *r, int error)
err = error - NGX_HTTP_MOVED_PERMANENTLY;
} else if (error < NGX_HTTP_INTERNAL_SERVER_ERROR) {
err = error - NGX_HTTP_BAD_REQUEST + 4;
err = error - NGX_HTTP_BAD_REQUEST + 3;
} else {
err = error - NGX_HTTP_INTERNAL_SERVER_ERROR + 4 + 17;
err = error - NGX_HTTP_INTERNAL_SERVER_ERROR + 3 + 17;
}
if (r->keepalive != 0) {

View File

@ -16,6 +16,8 @@
static void *ngx_http_write_filter_create_conf(ngx_pool_t *pool);
static char *ngx_http_write_filter_merge_conf(ngx_pool_t *pool,
void *parent, void *child);
static void ngx_http_write_filter_init(ngx_pool_t *pool,
ngx_http_conf_filter_t *cf);
static ngx_command_t ngx_http_write_filter_commands[] = {
@ -31,19 +33,13 @@ static ngx_command_t ngx_http_write_filter_commands[] = {
ngx_http_module_t ngx_http_write_filter_module_ctx = {
NGX_HTTP_MODULE,
NULL, /* create server config */
NULL, /* init server config */
ngx_http_write_filter_create_conf, /* create location config */
ngx_http_write_filter_merge_conf, /* merge location config */
NULL, /* translate handler */
NULL, /* output header filter */
NULL, /* next output header filter */
ngx_http_write_filter, /* output body filter */
NULL, /* next output body filter */
ngx_http_write_filter_init /* init filters */
};
@ -156,6 +152,13 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
static void ngx_http_write_filter_init(ngx_pool_t *pool,
ngx_http_conf_filter_t *cf)
{
cf->output_body_filter = ngx_http_write_filter;
}
static void *ngx_http_write_filter_create_conf(ngx_pool_t *pool)
{
ngx_http_write_filter_conf_t *conf;