nginx-0.0.1-2003-10-12-20:49:16 import

This commit is contained in:
Igor Sysoev 2003-10-12 16:49:16 +00:00
parent b3e73d869e
commit 0a280a3fc0
34 changed files with 565 additions and 550 deletions

View File

@ -688,7 +688,6 @@ static void ngx_clean_old_cycles(ngx_event_t *ev)
ngx_add_timer(ev, 30000);
} else {
ngx_cleaner_event.timer_set = 0;
ngx_destroy_pool(ngx_temp_pool);
ngx_temp_pool = NULL;
ngx_old_cycles.nelts = 0;

View File

@ -38,8 +38,8 @@ extern ngx_module_t ngx_http_not_modified_filter_module;
extern ngx_module_t ngx_http_range_filter_module;
extern ngx_module_t ngx_http_charset_filter_module;
extern ngx_module_t ngx_http_index_module;
extern ngx_module_t ngx_http_static_module;
extern ngx_module_t ngx_http_index_module;
extern ngx_module_t ngx_http_proxy_module;
extern ngx_module_t ngx_http_log_module;
@ -89,8 +89,8 @@ ngx_module_t *ngx_modules[] = {
/* &ngx_http_ssi_filter_module, */
&ngx_http_charset_filter_module,
&ngx_http_index_module,
/* &ngx_http_static_module, */
&ngx_http_index_module,
&ngx_http_proxy_module,
&ngx_http_log_module,

View File

@ -68,7 +68,7 @@ static int ngx_aio_init(ngx_cycle_t *cycle)
ngx_io = ngx_os_aio;
ngx_event_flags = NGX_HAVE_AIO_EVENT|NGX_USE_AIO_EVENT;
ngx_event_flags = NGX_USE_AIO_EVENT;
ngx_event_actions = ngx_aio_module_ctx.actions;

View File

@ -173,7 +173,7 @@ ngx_log_debug(cycle->log, "EV: %d" _ dpcf->events);
ngx_event_actions = ngx_devpoll_module_ctx.actions;
ngx_event_flags = NGX_HAVE_LEVEL_EVENT|NGX_USE_LEVEL_EVENT;
ngx_event_flags = NGX_USE_LEVEL_EVENT;
return NGX_OK;
}

View File

@ -105,7 +105,7 @@ static int ngx_iocp_init(ngx_cycle_t *cycle)
ngx_event_actions = ngx_iocp_module_ctx.actions;
ngx_event_flags = NGX_HAVE_AIO_EVENT|NGX_HAVE_IOCP_EVENT;
ngx_event_flags = NGX_USE_AIO_EVENT|NGX_USE_IOCP_EVENT;
return NGX_OK;
}

View File

@ -151,10 +151,9 @@ ngx_log_debug(cycle->log, "EV: %d" _ kcf->events);
ngx_event_actions = ngx_kqueue_module_ctx.actions;
ngx_event_flags = NGX_HAVE_LEVEL_EVENT
|NGX_HAVE_ONESHOT_EVENT
ngx_event_flags = NGX_USE_ONESHOT_EVENT
#if (HAVE_CLEAR_EVENT)
|NGX_HAVE_CLEAR_EVENT
|NGX_USE_CLEAR_EVENT
#else
|NGX_USE_LEVEL_EVENT
#endif
@ -238,9 +237,11 @@ static int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
return NGX_OK;
}
/* when the file descriptor is closed a kqueue automatically deletes
its filters so we do not need to delete explicity the event
before the closing the file descriptor */
/*
* when the file descriptor is closed a kqueue automatically deletes
* its filters so we do not need to delete explicity the event
* before the closing the file descriptor.
*/
if (flags & NGX_CLOSE_EVENT) {
return NGX_OK;
@ -427,13 +428,17 @@ static int ngx_kqueue_process_events(ngx_log_t *log)
if (ev->oneshot && ev->timer_set) {
ngx_del_timer(ev);
ev->timer_set = 0;
}
/* fall through */
ev->ready = 1;
ev->event_handler(ev);
break;
case EVFILT_AIO:
ev->ready = 1;
ev->active = 0;
ev->event_handler(ev);

View File

@ -109,9 +109,7 @@ static int ngx_poll_init(ngx_cycle_t *cycle)
ngx_event_actions = ngx_poll_module_ctx.actions;
ngx_event_flags = NGX_HAVE_LEVEL_EVENT
|NGX_HAVE_ONESHOT_EVENT
|NGX_USE_LEVEL_EVENT;
ngx_event_flags = NGX_USE_LEVEL_EVENT|NGX_USE_ONESHOT_EVENT;
return NGX_OK;
}
@ -364,7 +362,6 @@ static int ngx_poll_process_events(ngx_log_t *log)
if (ev->oneshot) {
if (ev->timer_set) {
ngx_del_timer(ev);
ev->timer_set = 0;
}
if (ev->write) {

View File

@ -108,9 +108,7 @@ static int ngx_select_init(ngx_cycle_t *cycle)
ngx_event_actions = ngx_select_module_ctx.actions;
ngx_event_flags = NGX_HAVE_LEVEL_EVENT
|NGX_HAVE_ONESHOT_EVENT
|NGX_USE_LEVEL_EVENT;
ngx_event_flags = NGX_USE_LEVEL_EVENT|NGX_USE_ONESHOT_EVENT;
#if (WIN32)
max_read = max_write = 0;
@ -401,7 +399,6 @@ static int ngx_select_process_events(ngx_log_t *log)
if (ev->oneshot) {
if (ev->timer_set) {
ngx_del_timer(ev);
ev->timer_set = 0;
}
if (ev->write) {

View File

@ -224,7 +224,7 @@ ngx_log_debug(cycle->log, "TYPE: %d" _ ecf->use);
/* required by poll */
wev->index = NGX_INVALID_INDEX;
if ((ngx_event_flags & NGX_HAVE_IOCP_EVENT) == 0) {
if ((ngx_event_flags & NGX_USE_IOCP_EVENT) == 0) {
if (s[i].remain) {
if (ngx_del_event(&cycle->old_cycle->read_events[fd],
@ -238,7 +238,7 @@ ngx_log_debug(cycle->log, "TYPE: %d" _ ecf->use);
#if (WIN32)
if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
rev->event_handler = &ngx_event_acceptex;
if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) {

View File

@ -24,9 +24,6 @@ struct ngx_event_s {
void *data;
void (*event_handler)(ngx_event_t *ev);
#if 0
int (*close_handler)(ngx_event_t *ev);
#endif
void *context;
char *action;
@ -35,9 +32,6 @@ struct ngx_event_s {
ngx_event_t *prev; /* queue in mutex(), aio_read(), aio_write() */
ngx_event_t *next; /* */
#if 0
int (*timer_handler)(ngx_event_t *ev);
#endif
ngx_event_t *timer_prev;
ngx_event_t *timer_next;
@ -61,17 +55,26 @@ struct ngx_event_s {
#endif
unsigned write:1;
unsigned instance:1; /* used to detect stale events in kqueue,
rt signals and epoll */
/* used to detect stale events in kqueue, rt signals and epoll */
unsigned instance:1;
/*
* event was passed or would be passed to a kernel;
* the posted aio operation.
*/
unsigned active:1;
/* ready event; the complete aio operation */
unsigned ready:1;
unsigned timedout:1;
unsigned blocked:1;
unsigned timer_set:1;
#if 1
unsigned blocked:1;
#endif
unsigned delayed:1;
unsigned process:1;
unsigned read_discarded:1;
unsigned ignore_econnreset:1;
@ -156,50 +159,68 @@ typedef struct {
} ngx_event_actions_t;
/* The event filter requires to read/write the whole data -
select, poll, /dev/poll, kqueue. */
#define NGX_HAVE_LEVEL_EVENT 0x00000001
/*
* The event filter requires to read/write the whole data -
* select, poll, /dev/poll, kqueue.
*/
#define NGX_USE_LEVEL_EVENT 0x00000001
/* The event filter is deleted after a notification without an additional
syscall - select, poll, kqueue. */
#define NGX_HAVE_ONESHOT_EVENT 0x00000002
/*
* The event filter is deleted after a notification without an additional
* syscall - select, poll, kqueue.
*/
#define NGX_USE_ONESHOT_EVENT 0x00000002
/* The event filter notifies only the changes and an initial level - kqueue */
#define NGX_HAVE_CLEAR_EVENT 0x00000004
/*
* The event filter notifies only the changes and an initial level - kqueue.
*/
#define NGX_USE_CLEAR_EVENT 0x00000004
/* The event filter has kqueue features - the eof flag, errno,
available data, etc */
#define NGX_HAVE_KQUEUE_EVENT 0x00000008
/*
* The event filter has kqueue features - the eof flag, errno,
* available data, etc
*/
#define NGX_HAVE_KQUEUE_EVENT 0x00000008
/* The event filter supports low water mark - kqueue's NOTE_LOWAT.
kqueue in FreeBSD 4.1-4.2 has no NOTE_LOWAT so we need a separate flag */
#define NGX_HAVE_LOWAT_EVENT 0x00000010
/*
* The event filter supports low water mark - kqueue's NOTE_LOWAT.
* kqueue in FreeBSD 4.1-4.2 has no NOTE_LOWAT so we need a separate flag.
*/
#define NGX_HAVE_LOWAT_EVENT 0x00000010
/* The event filter notifies only the changes (the edges)
but not an initial level - epoll */
#define NGX_HAVE_EDGE_EVENT 0x00000020
/*
* The event filter notifies only the changes (the edges)
* but not an initial level - epoll.
*/
#define NGX_USE_EDGE_EVENT 0x00000020
/* No need to add or delete the event filters - rt signals */
#define NGX_HAVE_SIGIO_EVENT 0x00000040
/*
* No need to add or delete the event filters - rt signals.
*/
#define NGX_USE_SIGIO_EVENT 0x00000040
/* No need to add or delete the event filters - overlapped, aio_read, aioread */
#define NGX_HAVE_AIO_EVENT 0x00000080
/*
* No need to add or delete the event filters - overlapped, aio_read,
* aioread, io_submit.
*/
#define NGX_USE_AIO_EVENT 0x00000080
/* Need to add socket or handle only once - i/o completion port.
It also requires HAVE_AIO_EVENT and NGX_HAVE_AIO_EVENT to be set */
#define NGX_HAVE_IOCP_EVENT 0x00000100
/*
* Need to add socket or handle only once - i/o completion port.
* It also requires HAVE_AIO_EVENT and NGX_HAVE_AIO_EVENT to be set.
*/
#define NGX_USE_IOCP_EVENT 0x00000100
#define NGX_USE_LEVEL_EVENT 0x00010000
#define NGX_USE_AIO_EVENT 0x00020000
/* 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
/dev/poll: we need to flush POLLREMOVE event before closing file */
/*
* The event filter is deleted before the 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
* /dev/poll: we need to flush POLLREMOVE event before closing file
*/
#define NGX_CLOSE_EVENT 1
@ -209,10 +230,12 @@ typedef struct {
#define NGX_READ_EVENT EVFILT_READ
#define NGX_WRITE_EVENT EVFILT_WRITE
/* 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 */
/*
* 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
@ -383,14 +406,14 @@ void ngx_worker(ngx_cycle_t *cycle);
ngx_inline static int ngx_handle_read_event(ngx_event_t *rev)
{
if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) {
if (ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_EDGE_EVENT)) {
/* aio, iocp, epoll */
return NGX_OK;
}
if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) {
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
/* kqueue */
@ -426,16 +449,41 @@ ngx_inline static int ngx_handle_read_event(ngx_event_t *rev)
}
ngx_inline static int ngx_handle_level_read_event(ngx_event_t *rev)
{
if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
if (!rev->active && !rev->ready) {
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT)
== NGX_ERROR) {
return NGX_ERROR;
}
return NGX_OK;
}
if (rev->active && rev->ready) {
if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
return NGX_ERROR;
}
return NGX_OK;
}
}
return NGX_OK;
}
ngx_inline static int ngx_handle_write_event(ngx_event_t *wev, int lowat)
{
if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) {
if (ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_EDGE_EVENT)) {
/* aio, iocp, epoll */
return NGX_OK;
}
if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) {
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
/* kqueue */
@ -478,6 +526,30 @@ ngx_inline static int ngx_handle_write_event(ngx_event_t *wev, int lowat)
}
ngx_inline static int ngx_handle_level_write_event(ngx_event_t *wev)
{
if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
if (!wev->active && !wev->ready) {
if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
== NGX_ERROR) {
return NGX_ERROR;
}
return NGX_OK;
}
if (wev->active && wev->ready) {
if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
return NGX_ERROR;
}
return NGX_OK;
}
}
return NGX_OK;
}
/* ***************************** */

View File

@ -20,12 +20,10 @@ int ngx_event_close_connection(ngx_event_t *ev)
if (c->read->timer_set) {
ngx_del_timer(c->read);
c->read->timer_set = 0;
}
if (c->write->timer_set) {
ngx_del_timer(c->write);
c->write->timer_set = 0;
}
ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);

View File

@ -202,7 +202,7 @@ int ngx_event_connect_peer(ngx_peer_connection_t *pc)
/* TODO: epoll, aio, iocp */
if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) { /* kqueue */
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { /* kqueue */
event = NGX_CLEAR_EVENT;
} else { /* select, poll, /dev/poll */

View File

@ -584,7 +584,7 @@ ngx_log_debug(p->log, "downstream level: %d" _ p->downstream_level);
int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p)
{
int i, rc, size;
int rc, size;
ngx_hunk_t *h;
ngx_chain_t *entry, *next, *saved_in, *saved_read;

View File

@ -4,7 +4,7 @@
#include <ngx_event.h>
/* in multithreaded enviroment all timer operations must be
/* TODO: in multithreaded enviroment all timer operations must be
protected by the single mutex */
@ -70,11 +70,18 @@ void ngx_event_timer_done(ngx_cycle_t *cycle)
void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
{
ngx_event_t *e, *queue;
#if (NGX_DEBUG_EVENT)
ngx_connection_t *c;
#endif
if (ev->timer_set) {
ngx_del_timer(ev);
}
#if (NGX_DEBUG_EVENT)
ngx_connection_t *c = ev->data;
ngx_log_debug(ev->log, "set timer: %d:%d, slot: %d" _
c->fd _ timer _ ngx_timer_cur_queue);
c = ev->data;
ngx_log_debug(ev->log, "set timer: %d:%d:%d, slot: %d" _
c->fd _ ev->write _ timer _ ngx_timer_cur_queue);
#endif
if (ev->timer_next || ev->timer_prev) {
@ -107,6 +114,10 @@ void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
e->timer_prev->timer_next = ev;
e->timer_prev = ev;
ev->timer_set = 1;
return;
}
@ -129,9 +140,9 @@ int ngx_event_find_timer(void)
if (timer == NGX_MAX_MSEC) {
return 0;
} else {
return timer;
}
return timer;
}
@ -190,6 +201,10 @@ void ngx_event_expire_timers(ngx_msec_t timer)
timer += ngx_temp_timer_queue.timer_next->timer_delta;
ev = ngx_temp_timer_queue.timer_next;
#if (NGX_DEBUG_EVENT)
ngx_log_debug(ev->log, "process temp timer queue");
#endif
ngx_del_timer(ev);
ngx_add_timer(ev, timer);
}

View File

@ -19,7 +19,7 @@ ngx_inline static void ngx_event_del_timer(ngx_event_t *ev)
{
#if (NGX_DEBUG_EVENT)
ngx_connection_t *c = ev->data;
ngx_log_debug(ev->log, "del timer: %d" _ c->fd);
ngx_log_debug(ev->log, "del timer: %d:%d" _ c->fd _ ev->write);
#endif
if (!ev->timer_next || !ev->timer_prev) {
@ -40,6 +40,8 @@ ngx_inline static void ngx_event_del_timer(ngx_event_t *ev)
if (ev->timer_prev) {
ev->timer_prev = NULL;
}
ev->timer_set = 0;
}

View File

@ -23,7 +23,7 @@ typedef struct {
ngx_hunk_t *out_hunk;
int hunks;
int length;
off_t length;
void *alloc;
unsigned flush:4;
@ -90,7 +90,9 @@ ngx_module_t ngx_http_gzip_filter_module = {
};
static char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 };
static char gzheader[10] = { 0x1f,
(char) 0x8b, /* suppress MSVC warning */
Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 };
#if (HAVE_LITTLE_ENDIAN)
@ -197,7 +199,7 @@ static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
#if 0
ngx_test_null(ctx->alloc, ngx_alloc(200K, r->log), NGX_ERROR);
#else
ctx->alloc = (void *) ~NULL;
ctx->alloc = (void *) -1;
#endif
rc = deflateInit2(&ctx->zstream, /**/ 1, Z_DEFLATED,

View File

@ -10,10 +10,20 @@ typedef struct {
} ngx_http_index_conf_t;
typedef struct {
int index;
unsigned tested:1;
} ngx_http_index_ctx_t;
#define NGX_HTTP_DEFAULT_INDEX "index.html"
static int ngx_http_index_test_dir(ngx_http_request_t *r);
static int ngx_http_index_test_dir(ngx_http_request_t *r,
ngx_http_index_ctx_t *ctx);
static int ngx_http_index_error(ngx_http_request_t *r,
ngx_http_index_ctx_t *ctx, ngx_err_t err);
static int ngx_http_index_init(ngx_cycle_t *cycle);
static void *ngx_http_index_create_conf(ngx_conf_t *cf);
static char *ngx_http_index_merge_conf(ngx_conf_t *cf,
@ -58,14 +68,14 @@ ngx_module_t ngx_http_index_module = {
/*
Try to open the first index file before the directory existence test
because the valid requests should be many more than invalid ones.
If open() failed then stat() should be more quickly because some data
is already cached in the kernel.
Besides Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR).
Unix has ENOTDIR error, although it less helpfull - it shows only
that path contains the usual file in place of the directory.
*/
* Try to open the first index file before the test of the directory existence
* because the valid requests should be many more than invalid ones.
* If open() failed then stat() should be more quickly because some data
* is already cached in the kernel.
* Besides Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR).
* Unix has ENOTDIR error, although it less helpfull - it shows only
* that path contains the usual file in place of the directory.
*/
int ngx_http_index_handler(ngx_http_request_t *r)
{
@ -74,38 +84,58 @@ int ngx_http_index_handler(ngx_http_request_t *r)
ngx_str_t redirect, *index;
ngx_err_t err;
ngx_fd_t fd;
ngx_http_index_ctx_t *ctx;
ngx_http_index_conf_t *icf;
ngx_http_core_loc_conf_t *clcf;
if (r->uri.data[r->uri.len - 1] != '/') {
return NGX_DECLINED;
}
ctx = ngx_http_get_module_ctx(r, ngx_http_index_module);
if (ctx == NULL) {
ngx_http_create_ctx(r, ctx, ngx_http_index_module,
sizeof(ngx_http_index_ctx_t),
NGX_HTTP_INTERNAL_SERVER_ERROR);
}
icf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
ngx_test_null(r->path.data,
ngx_palloc(r->pool,
clcf->doc_root.len + r->uri.len
+ icf->max_index_len),
NGX_HTTP_INTERNAL_SERVER_ERROR);
if (r->path.data == NULL) {
r->path_allocated = clcf->doc_root.len + r->uri.len
+ icf->max_index_len;
ngx_test_null(r->path.data,
ngx_palloc(r->pool, r->path_allocated),
NGX_HTTP_INTERNAL_SERVER_ERROR);
redirect.data = ngx_cpymem(r->path.data, clcf->doc_root.data,
clcf->doc_root.len);
file = ngx_cpystrn(redirect.data, r->uri.data, r->uri.len + 1);
r->path.len = file - r->path.data;
redirect.data = ngx_cpymem(r->path.data, clcf->doc_root.data,
clcf->doc_root.len);
file = ngx_cpystrn(redirect.data, r->uri.data, r->uri.len + 1);
r->path.len = file - r->path.data;
test_dir = 1;
path_not_found = 1;
} else{
redirect.data = r->path.data + r->path.len;
file = redirect.data + r->uri.len;
}
index = icf->indices.elts;
for (i = 0; i < icf->indices.nelts; i++) {
for (/* void */; ctx->index < icf->indices.nelts; ctx->index++) {
if (index[i].data[0] != '/') {
ngx_memcpy(file, index[i].data, index[i].len + 1);
name = r->path.data;
if (index[ctx->index].data[0] == '/') {
name = index[ctx->index].data;
} else {
name = index[i].data;
ngx_memcpy(file, index[ctx->index].data, index[ctx->index].len + 1);
name = r->path.data;
}
fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN);
if (fd == NGX_AGAIN) {
return NGX_AGAIN;
}
if (fd == NGX_INVALID_FILE) {
err = ngx_errno;
@ -113,25 +143,20 @@ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err,
"DEBUG: " ngx_open_file_n " %s failed", name);
if (err == NGX_ENOTDIR) {
path_not_found = 1;
return ngx_http_index_error(r, ctx, err);
} else if (err == NGX_EACCES) {
r->path_err = err;
return NGX_HTTP_FORBIDDEN;
return ngx_http_index_error(r, ctx, err);
}
if (test_dir) {
if (path_not_found) {
r->path_err = err;
return NGX_HTTP_NOT_FOUND;
}
if (!ctx->tested) {
rc = ngx_http_index_test_dir(r, ctx);
rc = ngx_http_index_test_dir(r);
if (rc != NGX_OK) {
return rc;
}
test_dir = 0;
ctx->tested = 1;
}
if (err == NGX_ENOENT) {
@ -147,14 +172,15 @@ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err,
r->file.name.data = name;
r->file.fd = fd;
if (index[i].data[0] == '/') {
r->file.name.len = index[i].len;
redirect.len = index[i].len;
redirect.data = index[i].data;
if (index[ctx->index].data[0] == '/') {
r->file.name.len = index[ctx->index].len;
redirect.len = index[ctx->index].len;
redirect.data = index[ctx->index].data;
} else {
redirect.len = r->uri.len + index[i].len;
r->file.name.len = clcf->doc_root.len + r->uri.len + index[i].len;
redirect.len = r->uri.len + index[ctx->index].len;
r->file.name.len = clcf->doc_root.len + r->uri.len
+ index[ctx->index].len;
}
return ngx_http_internal_redirect(r, &redirect, NULL);
@ -164,29 +190,26 @@ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err,
}
static int ngx_http_index_test_dir(ngx_http_request_t *r)
static int ngx_http_index_test_dir(ngx_http_request_t *r,
ngx_http_index_ctx_t *ctx)
{
ngx_err_t err;
r->path.data[r->path.len - 1] = '\0';
r->path.data[r->path.len] = '\0';
ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data);
#if 0
if (r->path_err == NGX_EACCES) {
return NGX_HTTP_FORBIDDEN;
}
#endif
if (ngx_file_type(r->path.data, &r->file.info) == -1) {
r->path_err = ngx_errno;
err = ngx_errno;
if (r->path_err == NGX_ENOENT) {
if (err == NGX_ENOENT) {
r->path.data[r->path.len - 1] = '/';
return NGX_HTTP_NOT_FOUND;
return ngx_http_index_error(r, ctx, err);
}
ngx_log_error(NGX_LOG_CRIT, r->connection->log, r->path_err,
ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
ngx_file_type_n " %s failed", r->path.data);
return NGX_HTTP_INTERNAL_SERVER_ERROR;
@ -196,10 +219,26 @@ ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data);
if (ngx_is_dir(r->file.info)) {
return NGX_OK;
} else {
return NGX_HTTP_NOT_FOUND;
}
/* THINK: not reached ??? */
return ngx_http_index_error(r, ctx, 0);
}
static int ngx_http_index_error(ngx_http_request_t *r,
ngx_http_index_ctx_t *ctx, ngx_err_t err)
{
if (err == NGX_EACCES) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
"\"%s\" is forbidden", r->path.data);
return NGX_HTTP_FORBIDDEN;
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
"\"%s\" is not found", r->path.data);
return NGX_HTTP_NOT_FOUND;
}
@ -212,8 +251,9 @@ static int ngx_http_index_init(ngx_cycle_t *cycle)
ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index];
cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
ngx_test_null(h, ngx_push_array(&cmcf->index_handlers), NGX_ERROR);
ngx_test_null(h, ngx_push_array(
&cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers),
NGX_ERROR);
*h = ngx_http_index_handler;
return NGX_OK;

View File

@ -292,10 +292,8 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
if (chain) {
ngx_add_timer(c->write, p->lcf->send_timeout);
c->write->timer_set = 1;
} else {
c->write->timer_set = 0;
/* TODO: del event */
}
@ -376,7 +374,6 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
/* rc == NGX_AGAIN */
ngx_add_timer(c->write, p->lcf->connect_timeout);
c->write->timer_set = 1;
return;
}
@ -600,29 +597,11 @@ static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *p)
p->header_in->end - p->header_in->last);
if (n == NGX_AGAIN) {
if (rev->timer_set) {
ngx_del_timer(rev);
} else {
rev->timer_set = 1;
}
ngx_add_timer(rev, p->lcf->read_timeout);
if (!rev->active) {
if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) {
/* kqueue */
event = NGX_CLEAR_EVENT;
} else {
/* select, poll, /dev/poll */
event = NGX_LEVEL_EVENT;
}
if (ngx_add_event(rev, NGX_READ_EVENT, event) == NGX_ERROR) {
ngx_http_proxy_finalize_request(p,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return NGX_ERROR;
}
if (ngx_handle_read_event(rev) == NGX_ERROR) {
ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
return NGX_ERROR;
}
return NGX_AGAIN;
@ -1052,12 +1031,10 @@ static void ngx_http_proxy_close_connection(ngx_connection_t *c)
if (c->read->timer_set) {
ngx_del_timer(c->read);
c->read->timer_set = 0;
}
if (c->write->timer_set) {
ngx_del_timer(c->write);
c->write->timer_set = 0;
}
/* TODO: move connection to the connection pool */

View File

@ -201,7 +201,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
/* init list of the handlers */
/* init lists of the handlers */
ngx_init_array(cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers,
cf->cycle->pool, 10, sizeof(ngx_http_handler_pt),
@ -219,10 +219,6 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].type = NGX_OK;
ngx_init_array(cmcf->index_handlers, cf->cycle->pool,
3, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR);
/* create the lists of the ports, the addresses and the server names
to allow quickly find the server core module configuration at run-time */

View File

@ -8,12 +8,11 @@
/* STUB */
int ngx_http_static_handler(ngx_http_request_t *r);
/**/
static void ngx_http_phase_event_handler(ngx_event_t *rev);
static void ngx_http_run_phases(ngx_http_request_t *r);
static int ngx_http_core_index_handler(ngx_http_request_t *r);
static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf);
@ -221,9 +220,6 @@ void ngx_http_handler(ngx_http_request_t *r)
r->connection->write->event_handler = ngx_http_phase_event_handler;
r->phase = 0;
r->phase_handler = 0;
ngx_http_run_phases(r);
return;
@ -238,6 +234,8 @@ static void ngx_http_phase_event_handler(ngx_event_t *ev)
c = ev->data;
r = c->data;
ngx_log_debug(ev->log, "phase event handler");
ngx_http_run_phases(r);
return;
@ -263,6 +261,10 @@ static void ngx_http_run_phases(ngx_http_request_t *r)
{
rc = h[r->phase_handler](r);
if (r->closed) {
return;
}
if (rc == NGX_DECLINED) {
continue;
}
@ -370,8 +372,24 @@ int ngx_http_core_translate_handler(ngx_http_request_t *r)
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
if (r->uri.data[r->uri.len - 1] == '/') {
r->content_handler = ngx_http_core_index_handler;
return NGX_OK;
if (r->path.data == NULL) {
ngx_test_null(r->path.data,
ngx_palloc(r->pool,
clcf->doc_root.len + r->uri.len),
NGX_HTTP_INTERNAL_SERVER_ERROR);
ngx_cpystrn(ngx_cpymem(r->path.data, clcf->doc_root.data,
clcf->doc_root.len),
r->uri.data, r->uri.len + 1);
} else {
r->path.data[r->path.len] = '\0';
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"directory index of \"%s\" is forbidden", r->path.data);
return NGX_HTTP_FORBIDDEN;
}
/* "+ 2" is for trailing '/' in redirect and '\0' */
@ -388,9 +406,11 @@ ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);
#if (WIN9X)
/* There is no way to open a file or a directory in Win9X with
one syscall: Win9X has no FILE_FLAG_BACKUP_SEMANTICS flag.
so we need to check its type before the opening */
/*
* 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) {
@ -488,42 +508,6 @@ ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
}
static int ngx_http_core_index_handler(ngx_http_request_t *r)
{
int i, rc;
ngx_http_handler_pt *h;
ngx_http_core_main_conf_t *cmcf;
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
h = cmcf->index_handlers.elts;
for (i = cmcf->index_handlers.nelts; i > 0; /* void */) {
rc = h[--i](r);
if (rc != NGX_DECLINED) {
if (rc == NGX_HTTP_NOT_FOUND) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, r->path_err,
"\"%s\" is not found", r->path.data);
}
if (rc == NGX_HTTP_FORBIDDEN) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, r->path_err,
"\"%s\" is forbidden", r->path.data);
}
return rc;
}
}
r->path.data[r->path.len] = '\0';
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"directory index of \"%s\" is forbidden", r->path.data);
return NGX_HTTP_FORBIDDEN;
}
int ngx_http_send_header(ngx_http_request_t *r)
{
return (*ngx_http_top_header_filter)(r);
@ -591,12 +575,38 @@ int ngx_http_internal_redirect(ngx_http_request_t *r,
}
}
/* clear the modules contexts */
ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
r->phase = 0;
r->phase_handler = 0;
ngx_http_handler(r);
return NGX_OK;
}
#if 1 /* STUB: test the delay http handler */
int ngx_http_delay_handler(ngx_http_request_t *r)
{
static int on;
if (on++ == 0) {
ngx_log_debug(r->connection->log, "SET http delay");
ngx_add_timer(r->connection->write, 10000);
return NGX_AGAIN;
}
r->connection->write->timedout = 0;
ngx_log_debug(r->connection->log, "RESET http delay");
return NGX_DECLINED;
}
#endif
static int ngx_http_core_init(ngx_cycle_t *cycle)
{
ngx_http_handler_pt *h;
@ -609,9 +619,15 @@ static int ngx_http_core_init(ngx_cycle_t *cycle)
ngx_test_null(h, ngx_push_array(
&cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers),
NGX_ERROR);
*h = ngx_http_core_translate_handler;
#if 0
ngx_test_null(h, ngx_push_array(
&cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers),
NGX_ERROR);
*h = ngx_http_delay_handler;
#endif
return NGX_OK;
}

View File

@ -121,7 +121,10 @@ static int ngx_http_header_filter(ngx_http_request_t *r)
} else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) {
/* 3XX */
status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 8;
r->header_only = 1;
if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) {
r->header_only = 1;
}
} else if (r->headers_out.status < NGX_HTTP_INTERNAL_SERVER_ERROR) {
/* 4XX */

View File

@ -22,7 +22,8 @@ static void ngx_http_set_lingering_close(ngx_http_request_t *r);
static void ngx_http_lingering_close_handler(ngx_event_t *ev);
static void ngx_http_empty_handler(ngx_event_t *wev);
static void ngx_http_header_parse_error(ngx_http_request_t *r, int parse_err);
static void ngx_http_header_parse_error(ngx_http_request_t *r,
int parse_err, int error);
static size_t ngx_http_log_error(void *data, char *buf, size_t len);
@ -65,7 +66,6 @@ static ngx_http_header_t headers_in[] = {
void ngx_http_init_connection(ngx_connection_t *c)
{
int event;
ngx_event_t *rev;
ngx_http_log_ctx_t *lctx;
@ -104,9 +104,8 @@ void ngx_http_init_connection(ngx_connection_t *c)
}
ngx_add_timer(rev, c->listening->post_accept_timeout);
rev->timer_set = 1;
if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) {
if (ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_EDGE_EVENT)) {
/* aio, iocp, epoll */
ngx_http_init_request(rev);
return;
@ -116,25 +115,6 @@ void ngx_http_init_connection(ngx_connection_t *c)
ngx_http_close_connection(c);
return;
}
#if 0
if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) {
/* kqueue */
event = NGX_CLEAR_EVENT;
} else {
/* select, poll, /dev/poll */
event = NGX_LEVEL_EVENT;
}
if (ngx_add_event(rev, NGX_READ_EVENT, event) == NGX_ERROR) {
ngx_http_close_connection(c);
}
#endif
return;
}
@ -153,10 +133,16 @@ static void ngx_http_init_request(ngx_event_t *rev)
c = rev->data;
r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t));
if (r == NULL) {
ngx_http_close_connection(c);
return;
if (c->data) {
r = c->data;
ngx_memzero(r, sizeof(ngx_http_request_t));
} else {
r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t));
if (r == NULL) {
ngx_http_close_connection(c);
return;
}
}
/* find the server configuration for the address:port */
@ -315,8 +301,8 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
r->request_line.data = r->request_start;
r->request_line.data[r->request_line.len] = '\0';
ngx_http_header_parse_error(r, NGX_HTTP_PARSE_INVALID_REQUEST);
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
ngx_http_header_parse_error(r, NGX_HTTP_PARSE_INVALID_REQUEST,
NGX_HTTP_BAD_REQUEST);
return;
}
@ -328,8 +314,8 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
{
/* no space for "\r\n" at the end of the header */
ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI);
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
NGX_HTTP_REQUEST_URI_TOO_LARGE);
return;
}
@ -459,8 +445,7 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
/* there was error while a request line parsing */
ngx_http_header_parse_error(r, rc);
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST);
return;
}
@ -469,11 +454,13 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
if (r->header_in->last == r->header_in->end) {
/* If it's a pipelined request and a request line is not complete
then we need to copy it to the start of the r->header_in hunk.
We need to copy it here only if the large client headers
are enabled otherwise a request line had been already copied
to the start of the r->header_in hunk in ngx_http_set_keepalive() */
/*
* If it's a pipelined request and a request line is not complete
* then we need to copy it to the start of the r->header_in hunk.
* We need to copy it here only if the large client headers
* are enabled otherwise a request line had been already copied
* to the start of the r->header_in hunk in ngx_http_set_keepalive().
*/
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
@ -481,9 +468,8 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
offset = r->request_start - r->header_in->start;
if (offset == 0) {
ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI);
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
NGX_HTTP_REQUEST_URI_TOO_LARGE);
return;
}
@ -504,8 +490,8 @@ static void ngx_http_process_request_line(ngx_event_t *rev)
}
} else {
ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI);
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_URI,
NGX_HTTP_REQUEST_URI_TOO_LARGE);
}
}
@ -651,8 +637,8 @@ static void ngx_http_process_request_headers(ngx_event_t *rev)
} else {
if (r->http_version > NGX_HTTP_VERSION_10) {
ngx_http_header_parse_error(r,
NGX_HTTP_PARSE_NO_HOST_HEADER);
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
NGX_HTTP_PARSE_NO_HOST_HEADER,
NGX_HTTP_BAD_REQUEST);
return;
}
r->headers_in.host_name_len = 0;
@ -662,16 +648,20 @@ static void ngx_http_process_request_headers(ngx_event_t *rev)
r->headers_in.content_length_n =
ngx_atoi(r->headers_in.content_length->value.data,
r->headers_in.content_length->value.len);
if (r->headers_in.content_length_n == NGX_ERROR) {
ngx_http_header_parse_error(r,
NGX_HTTP_PARSE_INVALID_CL_HEADER);
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
NGX_HTTP_PARSE_INVALID_CL_HEADER,
NGX_HTTP_BAD_REQUEST);
return;
}
}
if (r->header_timeout_set) {
ngx_del_timer(rev);
}
rev->event_handler = ngx_http_block_read;
c->write->event_handler = ngx_http_writer;
ngx_http_handler(r);
return;
@ -679,9 +669,7 @@ static void ngx_http_process_request_headers(ngx_event_t *rev)
/* there was error while a header line parsing */
ngx_http_header_parse_error(r, rc);
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
ngx_http_header_parse_error(r, rc, NGX_HTTP_BAD_REQUEST);
return;
}
@ -697,8 +685,8 @@ static void ngx_http_process_request_headers(ngx_event_t *rev)
if (offset == 0) {
ngx_http_header_parse_error(r,
NGX_HTTP_PARSE_TOO_LONG_HEADER);
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
NGX_HTTP_PARSE_TOO_LONG_HEADER,
NGX_HTTP_BAD_REQUEST);
return;
}
@ -713,8 +701,8 @@ static void ngx_http_process_request_headers(ngx_event_t *rev)
r->header_end -= offset;
} else {
ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER);
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
ngx_http_header_parse_error(r, NGX_HTTP_PARSE_TOO_LONG_HEADER,
NGX_HTTP_BAD_REQUEST);
return;
}
}
@ -724,7 +712,6 @@ static void ngx_http_process_request_headers(ngx_event_t *rev)
static ssize_t ngx_http_read_request_header(ngx_http_request_t *r)
{
int event;
ssize_t n;
ngx_event_t *rev;
ngx_http_core_srv_conf_t *cscf;
@ -743,14 +730,7 @@ static ssize_t ngx_http_read_request_header(ngx_http_request_t *r)
if (n == NGX_AGAIN) {
if (!r->header_timeout_set) {
if (rev->timer_set) {
ngx_del_timer(rev);
} else {
rev->timer_set = 1;
}
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
ngx_add_timer(rev, cscf->client_header_timeout);
r->header_timeout_set = 1;
}
@ -761,25 +741,6 @@ static ssize_t ngx_http_read_request_header(ngx_http_request_t *r)
return NGX_ERROR;
}
#if 0
if (!rev->active) {
if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) {
/* kqueue */
event = NGX_CLEAR_EVENT;
} else {
/* select, poll, /dev/poll */
event = NGX_LEVEL_EVENT;
}
if (ngx_add_event(rev, NGX_READ_EVENT, event) == NGX_ERROR) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
ngx_http_close_connection(r->connection);
return NGX_ERROR;
}
}
#endif
return NGX_AGAIN;
}
@ -802,7 +763,7 @@ static ssize_t ngx_http_read_request_header(ngx_http_request_t *r)
void ngx_http_finalize_request(ngx_http_request_t *r, int rc)
{
ngx_event_t *rev, *wev;
ngx_log_debug(r->connection->log, "finalize http request");
if (r->main || r->closed) {
return;
@ -810,16 +771,12 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int rc)
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
rev = r->connection->read;
if (rev->timer_set) {
ngx_del_timer(rev);
rev->timer_set = 0;
if (r->connection->read->timer_set) {
ngx_del_timer(r->connection->read);
}
wev = r->connection->write;
if (wev->timer_set) {
ngx_del_timer(wev);
wev->timer_set = 0;
if (r->connection->write->timer_set) {
ngx_del_timer(r->connection->write);
}
ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));
@ -836,16 +793,12 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int rc)
return;
}
rev = r->connection->read;
if (rev->timer_set) {
ngx_del_timer(rev);
rev->timer_set = 0;
if (r->connection->read->timer_set) {
ngx_del_timer(r->connection->read);
}
wev = r->connection->write;
if (wev->timer_set) {
ngx_del_timer(wev);
wev->timer_set = 0;
if (r->connection->write->timer_set) {
ngx_del_timer(r->connection->write);
}
if (r->keepalive != 0) {
@ -865,7 +818,6 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int rc)
static void ngx_http_set_write_handler(ngx_http_request_t *r)
{
int event;
ngx_event_t *wev;
ngx_http_core_loc_conf_t *clcf;
@ -879,44 +831,12 @@ static void ngx_http_set_write_handler(ngx_http_request_t *r)
clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
ngx_http_core_module);
ngx_add_timer(wev, clcf->send_timeout);
wev->timer_set = 1;
if (ngx_handle_write_event(wev, clcf->send_lowat) == NGX_ERROR) {
ngx_http_close_request(r, 0);
ngx_http_close_connection(r->connection);
}
#if 0
if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) {
/* aio, iocp, epoll */
return;
}
#if (HAVE_LOWAT_EVENT) /* kqueue's NOTE_LOWAT */
if (ngx_event_flags & NGX_HAVE_LOWAT_EVENT) {
wev->lowat = clcf->send_lowat;
}
#endif
if (ngx_event_flags & NGX_HAVE_CLEAR_EVENT) {
/* kqueue */
event = NGX_CLEAR_EVENT;
} else {
/* select, poll, /dev/poll */
event = NGX_LEVEL_EVENT;
}
if (ngx_add_event(wev, NGX_WRITE_EVENT, event) == NGX_ERROR) {
ngx_http_close_request(r, 0);
ngx_http_close_connection(r->connection);
}
#endif
return;
}
@ -924,7 +844,6 @@ static void ngx_http_set_write_handler(ngx_http_request_t *r)
void ngx_http_writer(ngx_event_t *wev)
{
int rc;
ngx_event_t *rev;
ngx_connection_t *c;
ngx_http_request_t *r;
ngx_http_core_loc_conf_t *clcf;
@ -937,53 +856,23 @@ void ngx_http_writer(ngx_event_t *wev)
ngx_log_debug(c->log, "writer output filter: %d" _ rc);
if (rc == NGX_AGAIN) {
clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
ngx_http_core_module);
if (wev->timer_set) {
ngx_del_timer(wev);
} else {
wev->timer_set = 1;
if (!wev->ready) {
clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
ngx_http_core_module);
ngx_add_timer(wev, clcf->send_timeout);
}
ngx_add_timer(wev, clcf->send_timeout);
if (ngx_handle_level_write_event(wev) == NGX_ERROR) {
ngx_http_close_request(r, 0);
ngx_http_close_connection(r->connection);
}
return;
}
if (rc == NGX_ERROR) {
ngx_http_close_request(r, 0);
ngx_http_close_connection(c);
return;
}
/* rc == NGX_OK */
ngx_log_debug(c->log, "http writer done");
rev = r->connection->read;
if (rev->timer_set) {
ngx_del_timer(rev);
rev->timer_set = 0;
}
if (wev->timer_set) {
ngx_del_timer(wev);
wev->timer_set = 0;
}
if (r->keepalive != 0) {
ngx_http_set_keepalive(r);
} else if (r->lingering_close) {
ngx_http_set_lingering_close(r);
} else {
ngx_http_close_request(r, 0);
ngx_http_close_connection(r->connection);
}
return;
ngx_http_finalize_request(r, rc);
}
@ -996,22 +885,15 @@ static void ngx_http_block_read(ngx_event_t *rev)
/* aio does not call this handler */
if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
/* select, poll, /dev/poll */
rev->blocked = 1;
if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && rev->active) {
if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
c = (ngx_connection_t *) rev->data;
r = (ngx_http_request_t *) c->data;
c = rev->data;
r = c->data;
ngx_http_close_request(r, 0);
ngx_http_close_connection(c);
}
}
/* kqueue, epoll */
return;
}
@ -1027,39 +909,33 @@ int ngx_http_discard_body(ngx_http_request_t *r)
if (rev->timer_set) {
ngx_del_timer(rev);
rev->timer_set = 0;
}
if (r->headers_in.content_length_n > 0) {
if (r->headers_in.content_length_n <= 0) {
return NGX_OK;
}
size = r->header_in->last - r->header_in->pos;
size = r->header_in->last - r->header_in->pos;
if (size) {
if (r->headers_in.content_length_n > size) {
r->headers_in.content_length_n -= size;
if (size) {
if (r->headers_in.content_length_n > size) {
r->headers_in.content_length_n -= size;
} else {
r->header_in->pos += r->headers_in.content_length_n;
r->headers_in.content_length_n = 0;
return NGX_OK;
}
}
rev->event_handler = ngx_http_read_discarded_body_event;
if (rev->blocked) {
if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT)
== NGX_ERROR) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
}
rev->blocked = 0;
return ngx_http_read_discarded_body(r);
} else {
r->header_in->pos += r->headers_in.content_length_n;
r->headers_in.content_length_n = 0;
return NGX_OK;
}
}
rev->event_handler = ngx_http_read_discarded_body_event;
if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
return ngx_http_read_discarded_body(r);
return NGX_OK;
}
@ -1075,12 +951,18 @@ static void ngx_http_read_discarded_body_event(ngx_event_t *rev)
rc = ngx_http_read_discarded_body(r);
if (rc == NGX_AGAIN) {
if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
ngx_http_close_request(r, rc);
ngx_http_close_connection(c);
return;
}
}
if (rc != NGX_OK) {
ngx_http_close_request(r, rc);
ngx_http_close_connection(c);
}
return;
}
@ -1091,6 +973,10 @@ static int ngx_http_read_discarded_body(ngx_http_request_t *r)
ngx_log_debug(r->connection->log, "http read discarded body");
if (r->headers_in.content_length_n == 0) {
return NGX_OK;
}
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (r->discarded_buffer == NULL) {
@ -1101,6 +987,7 @@ static int ngx_http_read_discarded_body(ngx_http_request_t *r)
}
size = r->headers_in.content_length_n;
if (size > clcf->discarded_buffer_size) {
size = clcf->discarded_buffer_size;
}
@ -1111,7 +998,7 @@ static int ngx_http_read_discarded_body(ngx_http_request_t *r)
}
if (n == NGX_AGAIN) {
return NGX_OK;
return NGX_AGAIN;
}
r->headers_in.content_length_n -= n;
@ -1122,7 +1009,7 @@ static int ngx_http_read_discarded_body(ngx_http_request_t *r)
static void ngx_http_set_keepalive(ngx_http_request_t *r)
{
int len, blocked;
int len;
ngx_hunk_t *h;
ngx_event_t *rev, *wev;
ngx_connection_t *c;
@ -1139,39 +1026,26 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r)
ctx->action = "closing request";
ngx_http_close_request(r, 0);
if (rev->timer_set) {
ngx_del_timer(rev);
} else {
rev->timer_set = 1;
}
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
ngx_add_timer(rev, clcf->keepalive_timeout);
if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) {
ngx_http_close_connection(c);
return;
}
blocked = 1;
rev->blocked = 0;
} else {
blocked = 0;
if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
ngx_http_close_connection(c);
return;
}
h = c->buffer;
/* pipelined request */
if (h->pos < h->last) {
/* We do not know here whether a pipelined request is complete
so if the large client headers are not enabled
we need to copy the data to the start of c->buffer.
This copy should be rare because clients that support
pipelined requests (Mozilla 1.x, Opera 6.x) are still rare */
/* Pipelined request.
*
* We do not know here whether a pipelined request is complete
* so if the large client headers are not enabled
* we need to copy the data to the start of c->buffer.
* This copy should be rare because clients that support
* pipelined requests (Mozilla 1.x, Opera 6.x+) are still rare.
*/
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
@ -1195,16 +1069,12 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r)
h->pos = h->last = h->start;
rev->event_handler = ngx_http_keepalive_handler;
wev = c->write;
wev->event_handler = ngx_http_empty_handler;
if (wev->active) {
if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
ngx_http_close_connection(c);
return;
}
} else if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) == 0) {
wev->event_handler = ngx_http_empty_handler;
if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && wev->active) {
if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
ngx_http_close_connection(c);
return;
}
}
@ -1220,7 +1090,7 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r)
c->tcp_nopush = 0;
}
if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) || blocked) {
if (rev->ready || (ngx_event_flags & NGX_USE_AIO_EVENT)) {
ngx_http_keepalive_handler(rev);
}
}
@ -1228,7 +1098,7 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r)
static void ngx_http_keepalive_handler(ngx_event_t *rev)
{
ssize_t n;
ssize_t n;
ngx_connection_t *c;
ngx_http_log_ctx_t *lctx;
@ -1241,8 +1111,10 @@ static void ngx_http_keepalive_handler(ngx_event_t *rev)
return;
}
/* MSIE closes a keepalive connection with RST flag
so we ignore ECONNRESET here */
/*
* MSIE closes a keepalive connection with RST flag
* so we ignore ECONNRESET here.
*/
rev->ignore_econnreset = 1;
ngx_set_socket_errno(0);
@ -1278,46 +1150,35 @@ static void ngx_http_keepalive_handler(ngx_event_t *rev)
static void ngx_http_set_lingering_close(ngx_http_request_t *r)
{
ngx_event_t *rev;
ngx_event_t *rev, *wev;
ngx_connection_t *c;
ngx_http_core_loc_conf_t *clcf;
c = r->connection;
rev = c->read;
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
r->lingering_time = ngx_time() + clcf->lingering_time / 1000;
rev = c->read;
rev->event_handler = ngx_http_lingering_close_handler;
if (rev->timer_set) {
ngx_del_timer(rev);
} else {
rev->timer_set = 1;
}
r->lingering_time = ngx_time() + clcf->lingering_time / 1000;
ngx_add_timer(rev, clcf->lingering_timeout);
if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) {
if (ngx_handle_level_read_event(rev) == NGX_ERROR) {
ngx_http_close_request(r, 0);
ngx_http_close_connection(c);
return;
}
wev = c->write;
wev->event_handler = ngx_http_empty_handler;
if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && wev->active) {
if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
ngx_http_close_request(r, 0);
ngx_http_close_connection(c);
return;
}
rev->blocked = 0;
}
if (c->write->active) {
if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
if (ngx_del_event(c->write, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
ngx_http_close_request(r, 0);
ngx_http_close_connection(c);
return;
}
} else if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) == 0) {
c->write->event_handler = ngx_http_empty_handler;
}
}
if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
@ -1328,7 +1189,7 @@ static void ngx_http_set_lingering_close(ngx_http_request_t *r)
return;
}
if (rev->ready || (ngx_event_flags & NGX_HAVE_AIO_EVENT)) {
if (rev->ready || (ngx_event_flags & NGX_USE_AIO_EVENT)) {
ngx_http_lingering_close_handler(rev);
}
}
@ -1401,11 +1262,6 @@ static void ngx_http_lingering_close_handler(ngx_event_t *rev)
timer = clcf->lingering_timeout;
}
if (rev->timer_set) {
ngx_del_timer(rev);
} else {
rev->timer_set = 1;
}
ngx_add_timer(rev, timer);
return;
@ -1414,7 +1270,7 @@ static void ngx_http_lingering_close_handler(ngx_event_t *rev)
static void ngx_http_empty_handler(ngx_event_t *wev)
{
ngx_log_debug(wev->log, "http empty handler");
ngx_log_debug(wev->log, "http EMPTY handler");
return;
}
@ -1457,7 +1313,7 @@ void ngx_http_close_request(ngx_http_request_t *r, int error)
}
/* ctx->url was allocated from r->pool */
ctx = (ngx_http_log_ctx_t *) r->connection->log->data;
ctx = r->connection->log->data;
ctx->url = NULL;
ngx_destroy_pool(r->pool);
@ -1479,12 +1335,10 @@ void ngx_http_close_connection(ngx_connection_t *c)
if (c->read->timer_set) {
ngx_del_timer(c->read);
c->read->timer_set = 0;
}
if (c->write->timer_set) {
ngx_del_timer(c->write);
c->write->timer_set = 0;
}
if (ngx_del_conn) {
@ -1513,7 +1367,8 @@ void ngx_http_close_connection(ngx_connection_t *c)
}
static void ngx_http_header_parse_error(ngx_http_request_t *r, int parse_err)
static void ngx_http_header_parse_error(ngx_http_request_t *r,
int parse_err, int error)
{
ngx_http_log_ctx_t *ctx;
@ -1532,6 +1387,8 @@ static void ngx_http_header_parse_error(ngx_http_request_t *r, int parse_err)
}
r->connection->log->handler = ngx_http_log_error;
ngx_http_finalize_request(r, error);
}

View File

@ -157,6 +157,8 @@ struct ngx_http_request_s {
ngx_str_t args;
ngx_str_t exten;
ngx_str_t unparsed_uri;
ngx_str_t path;
int path_allocated;
ngx_http_request_t *main;
@ -172,9 +174,6 @@ struct ngx_http_request_s {
char *discarded_buffer;
ngx_str_t path;
int path_err;
/* URI is not started with '/' - "GET http://" */
unsigned unusual_uri:1;
/* URI with "/.", "%" and on Win32 with "//" */

View File

@ -22,6 +22,14 @@ static char msie_stub[] =
;
static char error_301_page[] =
"<html>" CRLF
"<head><title>301 Moved Permanently</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
"<center><h1>301 Moved Permanently</h1></center>" CRLF
;
static char error_302_page[] =
"<html>" CRLF
"<head><title>302 Found</title></head>" CRLF
@ -111,8 +119,8 @@ static char error_504_page[] =
static ngx_str_t error_pages[] = {
ngx_null_string, /* 300 */
ngx_null_string, /* 301 */
/* ngx_null_string, */ /* 300 */
ngx_string(error_301_page),
ngx_string(error_302_page),
ngx_null_string, /* 303 */
@ -224,7 +232,11 @@ int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
h->pos = error_tail;
h->last = error_tail + sizeof(error_tail) - 1;
if (/* STUB: "msie_padding on/off" */ 1) {
if (/* STUB: "msie_padding on/off" */ 1
&& r->http_version >= NGX_HTTP_VERSION_10
&& error >= NGX_HTTP_BAD_REQUEST)
{
if (ngx_http_output_filter(r, h) == NGX_ERROR) {
return NGX_ERROR;
}

View File

@ -139,7 +139,7 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
return NGX_OK;
}
if (!r->connection->write->ready || r->connection->write->delayed) {
if (r->connection->write->delayed) {
return NGX_AGAIN;
}
@ -161,10 +161,9 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
if (chain == NULL) {
return NGX_OK;
} else {
return NGX_AGAIN;
}
return NGX_AGAIN;
}

View File

@ -109,6 +109,7 @@ ngx_log_debug(ev->log, "aio: aiocb: %08x" _ &ev->aiocb);
return NGX_ERROR;
}
ev->active = 0;
ngx_log_debug(ev->log, "aio_write: %d" _ rc);
return rc;

View File

@ -1,6 +1,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
#include <ngx_aio.h>
@ -17,10 +18,18 @@ ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in)
ce = in;
while (ce) {
/* we can post the single aio operation only */
if (c->write->active) {
return ce;
}
buf = prev = ce->hunk->pos;
size = 0;
/* coalesce the neighbouring chain entries */
while (ce && prev == ce->hunk->pos) {
size += ce->hunk->last - ce->hunk->pos;
prev = ce->hunk->last;
@ -33,35 +42,33 @@ ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in)
ngx_log_debug(c->log, "aio_write rc: %d" _ rc);
#endif
if (rc == NGX_ERROR) {
return NGX_CHAIN_ERROR;
}
if (rc > 0) {
sent += rc;
c->sent += rc;
}
} else if (rc == NGX_ERROR) {
return NGX_CHAIN_ERROR;
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "aio_write sent: " OFF_FMT _ c->sent);
#endif
for (ce = in; ce; ce = ce->next) {
if (sent >= ce->hunk->last - ce->hunk->pos) {
sent -= ce->hunk->last - ce->hunk->pos;
ce->hunk->pos = ce->hunk->last;
continue;
}
ce->hunk->pos += sent;
} else if (rc == NGX_AGAIN) {
break;
}
}
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "aio_write sent: " OFF_FMT _ c->sent);
#endif
for (ce = in; ce; ce = ce->next) {
if (sent >= ce->hunk->last - ce->hunk->pos) {
sent -= ce->hunk->last - ce->hunk->pos;
ce->hunk->pos = ce->hunk->last;
continue;
}
ce->hunk->pos += sent;
break;
}
return ce;
}

View File

@ -19,8 +19,13 @@ ngx_os_io_t ngx_os_io = {
ngx_unix_recv,
ngx_readv_chain,
NULL,
#if (HAVE_FREEBSD_SENDFILE)
ngx_freebsd_sendfile_chain,
NGX_HAVE_SENDFILE|NGX_HAVE_ZEROCOPY
#else
ngx_writev_chain,
NULL
#endif
};

View File

@ -34,6 +34,10 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
ngx_hunk_t *file;
ngx_chain_t *ce, *tail;
if (!c->write->ready) {
return in;
}
do {
ce = in;
file = NULL;

View File

@ -43,8 +43,11 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
if (n >= 0) {
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
rev->available -= n;
if (rev->available == 0) {
if (rev->available <= 0) {
rev->ready = 0;
if (rev->available < 0) {
rev->available = 0;
}
}
return n;

View File

@ -1,6 +1,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
@ -13,6 +14,10 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
ngx_array_t iovecs;
ngx_chain_t *ce;
if (!c->write->ready) {
return in;
}
ngx_init_array(iovecs, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
prev = NULL;

View File

@ -36,4 +36,8 @@
#endif
/* STUB */
#define HAVE_LITTLE_ENDIAN 1
#endif /* _NGX_WIN32_CONFIG_H_INCLUDED_ */

View File

@ -17,12 +17,12 @@ ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size)
rev = c->read;
bytes = 0;
if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) && rev->ready) {
if ((ngx_event_flags & NGX_USE_AIO_EVENT) && rev->ready) {
rev->ready = 0;
/* the overlapped WSARecv() completed */
if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
if (rev->ovlp.error) {
ngx_log_error(NGX_LOG_ERR, c->log, rev->ovlp.error,
"WSARecv() failed");
@ -44,7 +44,7 @@ ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size)
return bytes;
}
if (ngx_event_flags & NGX_HAVE_AIO_EVENT) {
if (ngx_event_flags & NGX_USE_AIO_EVENT) {
ovlp = (LPWSAOVERLAPPED) &c->read->ovlp;
ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
@ -75,7 +75,7 @@ ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size)
}
}
if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
/*
* If a socket was bound with I/O completion port

View File

@ -65,8 +65,8 @@ non-block
wev = c->write;
if (((ngx_event_flags & NGX_HAVE_AIO_EVENT) && !wev->ready)
|| ((ngx_event_flags & NGX_HAVE_AIO_EVENT) == 0))
if (((ngx_event_flags & NGX_USE_AIO_EVENT) && !wev->ready)
|| ((ngx_event_flags & NGX_USE_AIO_EVENT) == 0))
{
/*
* WSABUFs must be 4-byte aligned otherwise
@ -94,7 +94,7 @@ non-block
}
}
if (ngx_event_flags & NGX_HAVE_AIO_EVENT) {
if (ngx_event_flags & NGX_USE_AIO_EVENT) {
ovlp = (LPWSAOVERLAPPED) &c->write->ovlp;
ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
@ -120,7 +120,7 @@ non-block
} else {
if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
/*
* If a socket was bound with I/O completion port then
@ -133,7 +133,7 @@ non-block
}
} else {
if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
wev->ready = 0;
/* the overlapped WSASend() completed */