mirror of
https://github.com/nginx/nginx.git
synced 2024-12-20 06:03:31 -06:00
nginx-0.0.1-2003-03-20-19:09:44 import
This commit is contained in:
parent
90ace68b69
commit
dc479b4d98
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
|
@ -8,18 +8,13 @@
|
||||
|
||||
ssize_t ngx_event_recv_core(ngx_connection_t *c, char *buf, size_t size)
|
||||
{
|
||||
int n;
|
||||
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) {
|
||||
|
||||
if (ev->error == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ngx_set_socket_errno(ev->error);
|
||||
err = ev->error;
|
||||
n = -1;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} else {
|
||||
n = ngx_recv(c->fd, buf, size, 0);
|
||||
|
||||
if (n == -1) {
|
||||
err = ngx_socket_errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (ev->error == NGX_ECONNRESET && ev->ignore_econnreset) {
|
||||
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() 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;
|
||||
}
|
||||
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -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 */
|
||||
@ -81,29 +83,54 @@ int ngx_http_proxy_handler(ngx_http_request_t *r)
|
||||
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);
|
||||
}
|
||||
|
||||
/* The connection is in a progress */
|
||||
|
||||
/* 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,
|
||||
@ -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";
|
||||
}
|
||||
|
@ -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 {
|
||||
@ -31,8 +66,15 @@ struct ngx_http_proxy_ctx_s {
|
||||
int hunk_n;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
||||
@ -63,11 +64,10 @@ 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);
|
||||
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);
|
||||
|
||||
|
@ -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,8 +63,7 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
size_t len;
|
||||
char *data;
|
||||
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,12 +105,14 @@ 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;
|
||||
|
||||
ngx_file_t file;
|
||||
|
||||
ngx_pool_t *pool;
|
||||
ngx_hunk_t *header_in;
|
||||
|
||||
@ -115,21 +121,19 @@ struct ngx_http_request_s {
|
||||
|
||||
int (*handler)(ngx_http_request_t *r);
|
||||
|
||||
int method;
|
||||
|
||||
time_t lingering_time;
|
||||
|
||||
int method;
|
||||
int http_version;
|
||||
int http_major;
|
||||
int http_minor;
|
||||
|
||||
ngx_str_t request_line;
|
||||
ngx_str_t uri;
|
||||
ngx_str_t args;
|
||||
ngx_str_t exten;
|
||||
ngx_http_request_t *main;
|
||||
|
||||
ngx_connection_t *connection;
|
||||
|
||||
u_int in_addr;
|
||||
|
||||
int port;
|
||||
@ -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);
|
||||
/**/
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
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,6 +565,18 @@ 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;
|
||||
@ -580,7 +584,7 @@ static char *ngx_server_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;
|
||||
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;
|
||||
|
@ -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
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user