nginx-0.0.1-2002-12-15-09:25:09 import
diff --git a/src/core/nginx.c b/src/core/nginx.c
index b33ce29..e654e7e 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -32,6 +32,8 @@
ngx_pool_t *ngx_pool;
+int ngx_connection_counter;
+
ngx_array_t *ngx_listening_sockets;
@@ -43,7 +45,9 @@
ngx_pool = ngx_create_pool(16 * 1024, &ngx_log);
/* */
+#if !(WIN32)
ngx_set_signals(&ngx_log);
+#endif
ngx_init_sockets(&ngx_log);
@@ -73,6 +77,7 @@
return 0;
}
+#if !(WIN32)
static void ngx_set_signals(ngx_log_t *log)
{
struct sigaction sa;
@@ -86,6 +91,7 @@
exit(1);
}
}
+#endif
static void ngx_open_listening_sockets(ngx_log_t *log)
{
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 30562c0..94d678f 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -5,4 +5,7 @@
#define NGINX_VER "nginx/0.0.1"
+extern int ngx_connection_counter;
+
+
#endif /* _NGINX_H_INCLUDED_ */
diff --git a/src/core/ngx_alloc.c b/src/core/ngx_alloc.c
index 67adfcb..36ad505 100644
--- a/src/core/ngx_alloc.c
+++ b/src/core/ngx_alloc.c
@@ -3,6 +3,7 @@
#include <ngx_errno.h>
#include <ngx_log.h>
+#include <ngx_string.h>
#include <ngx_alloc.h>
@@ -15,7 +16,7 @@
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
"malloc() %d bytes failed", size);
- ngx_log_debug(log, "malloc: %x:%d" _ p _ size);
+ ngx_log_debug(log, "malloc: %08x:%d" _ p _ size);
return p;
}
@@ -52,12 +53,12 @@
ngx_pool_large_t *l;
for (l = pool->large; l; l = l->next) {
- ngx_log_debug(pool->log, "free: %x" _ l->alloc);
+ ngx_log_debug(pool->log, "free: %08x" _ l->alloc);
free(l->alloc);
}
for (p = pool, n = pool->next; /* void */; p = n, n = n->next) {
- ngx_log_debug(pool->log, "free: %x" _ p);
+ ngx_log_debug(pool->log, "free: %08x" _ p);
free(p);
if (n == NULL)
@@ -74,9 +75,10 @@
if (size <= NGX_MAX_ALLOC_FROM_POOL) {
for (p = pool, n = pool->next; /* void */; p = n, n = n->next) {
- if ((size_t) (p->end - p->last) >= size) {
- m = p->last;
- p->last += size;
+ if ((size_t) (p->end - ngx_align(p->last)) >= size) {
+ m = ngx_align(p->last);
+ p->last = ngx_align(p->last);
+ p->last += size ;
return m;
}
diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h
index f7223fa..09f73eb 100644
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -12,6 +12,13 @@
#define FD_SETSIZE 1024
+/* auto_conf */
+#define NGX_ALIGN (4 - 1)
+#define NGX_ALIGN_TYPE unsigned
+
+#define ngx_align(p) (char *) (((NGX_ALIGN_TYPE) p + NGX_ALIGN) & ~NGX_ALIGN)
+
+
#ifdef _WIN32
#define WIN32 1
@@ -25,9 +32,6 @@
#define ngx_inline __inline
-#define ngx_memzero ZeroMemory
-
-#define ngx_close_socket closesocket
#ifndef HAVE_INHERITED_NONBLOCK
#define HAVE_INHERITED_NONBLOCK 1
@@ -66,9 +70,6 @@
#define ngx_inline inline
-#define ngx_memzero bzero
-
-#define ngx_close_socket close
#endif /* POSIX */
diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h
index b486f4b..0ff09ff 100644
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -44,6 +44,8 @@
ngx_hunk_t *buffer;
unsigned int post_accept_timeout;
+ int number;
+
unsigned unexpected_eof:1;
};
diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h
index 0d68386..d32c89b 100644
--- a/src/core/ngx_file.h
+++ b/src/core/ngx_file.h
@@ -4,12 +4,18 @@
#include <ngx_files.h>
#include <ngx_log.h>
+#include <ngx_string.h>
typedef struct ngx_file_s ngx_file_t;
struct ngx_file_s {
- ngx_fd_t fd;
- ngx_log_t *log;
+ ngx_fd_t fd;
+ ngx_str_t name;
+ ngx_file_info_t info;
+
+ ngx_log_t *log;
+
+ unsigned info_valid:1;
};
diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c
new file mode 100644
index 0000000..aba990b
--- /dev/null
+++ b/src/core/ngx_inet.c
@@ -0,0 +1,18 @@
+
+#include <ngx_config.h>
+#include <ngx_string.h>
+#include <ngx_inet.h>
+
+
+size_t ngx_inet_ntop(int family, char *addr, char *text, size_t len)
+{
+ if (family != AF_INET)
+ return 0;
+
+ return ngx_snprintf(text, len > INET_ADDRSTRLEN ? INET_ADDRSTRLEN : len,
+ "%u.%u.%u.%u",
+ (unsigned char) addr[0],
+ (unsigned char) addr[1],
+ (unsigned char) addr[2],
+ (unsigned char) addr[3]);
+}
diff --git a/src/core/ngx_inet.h b/src/core/ngx_inet.h
new file mode 100644
index 0000000..0766d1f
--- /dev/null
+++ b/src/core/ngx_inet.h
@@ -0,0 +1,8 @@
+#ifndef _NGX_INET_H_INCLUDED_
+#define _NGX_INET_H_INCLUDED_
+
+
+size_t ngx_inet_ntop(int family, char *addr, char *text, size_t len);
+
+
+#endif /* _NGX_INET_H_INCLUDED_ */
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index de9b14b..ddfdacc 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -6,17 +6,24 @@
typedef struct {
- int len;
- char *data;
+ size_t len;
+ char *data;
} ngx_str_t;
#if (WIN32)
+
+#define ngx_memzero ZeroMemory
+
+#define strcasecmp stricmp
+
#define ngx_snprintf _snprintf
#define ngx_vsnprintf _vsnprintf
#else
+#define ngx_memzero bzero
+
#define ngx_snprintf snprintf
#define ngx_vsnprintf vsnprintf
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index 3b65f80..4e82162 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -16,12 +16,14 @@
#endif
-
+/* should be per-thread */
static int kq;
static struct kevent *change_list, *event_list;
static int nchanges, nevents;
static ngx_event_t timer_queue;
+/* */
+
int ngx_kqueue_init(int max_connections, ngx_log_t *log)
{
@@ -53,6 +55,7 @@
return NGX_OK;
}
+
int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
{
ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0;
@@ -60,22 +63,33 @@
return ngx_kqueue_set_event(ev, event, EV_ADD | flags);
}
-int ngx_kqueue_del_event(ngx_event_t *ev, int event)
+
+int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
{
ngx_event_t *e;
- if (ev->index <= nchanges && change_list[ev->index].udata == ev) {
- change_list[ev->index] = change_list[nchanges];
- e = (ngx_event_t *) change_list[ev->index].udata;
- e->index = ev->index;
- nchanges--;
+ if (ev->index < nchanges && change_list[ev->index].udata == ev) {
+
+ ngx_connection_t *cn = (ngx_connection_t *) ev->data;
+ ngx_log_debug(ev->log, "kqueue del event: %d: ft:%d" _
+ cn->fd _ event);
+
+ if (ev->index < --nchanges) {
+ e = (ngx_event_t *) change_list[nchanges].udata;
+ change_list[ev->index] = change_list[nchanges];
+ e->index = ev->index;
+ }
return NGX_OK;
}
+ if (flags & NGX_CLOSE_EVENT)
+ return NGX_OK;
+
return ngx_kqueue_set_event(ev, event, EV_DELETE);
}
+
int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
{
struct timespec ts = { 0, 0 };
@@ -110,13 +124,18 @@
return NGX_OK;
}
+
int ngx_kqueue_process_events(ngx_log_t *log)
{
int events, i;
- u_int timer = 0, delta = 0;
+ u_int timer, delta;
ngx_event_t *ev;
struct timeval tv;
- struct timespec ts, *tp = NULL;
+ struct timespec ts, *tp;
+
+ timer = 0;
+ delta = 0;
+ tp = NULL;
if (timer_queue.timer_next != &timer_queue) {
timer = timer_queue.timer_next->timer_delta;
@@ -212,6 +231,7 @@
return NGX_OK;
}
+
void ngx_kqueue_add_timer(ngx_event_t *ev, ngx_msec_t timer)
{
ngx_event_t *e;
diff --git a/src/event/modules/ngx_kqueue_module.h b/src/event/modules/ngx_kqueue_module.h
index ce2aacd..c561920 100644
--- a/src/event/modules/ngx_kqueue_module.h
+++ b/src/event/modules/ngx_kqueue_module.h
@@ -8,7 +8,7 @@
int ngx_kqueue_init(int max_connections, ngx_log_t *log);
int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags);
-int ngx_kqueue_del_event(ngx_event_t *ev, int event);
+int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags);
int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags);
void ngx_kqueue_add_timer(ngx_event_t *ev, ngx_msec_t timer);
int ngx_kqueue_process_events(ngx_log_t *log);
diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c
index 54a5f7e..c87c592 100644
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -8,24 +8,26 @@
#include <ngx_event.h>
#include <ngx_select_module.h>
-static fd_set master_read_fd_set;
-static fd_set master_write_fd_set;
-static fd_set work_read_fd_set;
-static fd_set work_write_fd_set;
+
+/* should be per-thread */
+static fd_set master_read_fd_set;
+static fd_set master_write_fd_set;
+static fd_set work_read_fd_set;
+static fd_set work_write_fd_set;
#if (WIN32)
-static int max_read;
-static int max_write;
+static int max_read;
+static int max_write;
#else
-static int max_fd;
+static int max_fd;
#endif
-static int nevents;
+static int nevents;
static ngx_event_t **event_index;
static ngx_event_t **ready_index;
static ngx_event_t timer_queue;
-
+/* */
static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event,
ngx_log_t *log);
@@ -121,12 +123,15 @@
return NGX_OK;
}
-int ngx_select_del_event(ngx_event_t *ev, int event)
+int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags)
{
ngx_connection_t *c;
c = (ngx_connection_t *) ev->data;
- ngx_log_debug(c->log, "del event: %d" _ c->fd);
+ if (ev->index == NGX_INVALID_INDEX)
+ return NGX_OK;
+
+ ngx_log_debug(c->log, "del event: %d, %d" _ c->fd _ event);
#if (WIN32)
if (event == NGX_READ_EVENT) {
@@ -148,13 +153,13 @@
max_fd = -1;
#endif
- nevents--;
-
- if (ev->index < nevents) {
+ if (ev->index < --nevents) {
event_index[ev->index] = event_index[nevents];
event_index[ev->index]->index = ev->index;
}
+ ev->index = NGX_INVALID_INDEX;
+
return NGX_OK;
}
@@ -162,7 +167,7 @@
{
int i, ready, found, nready;
u_int timer, delta;
- ngx_event_t *ev, *nx;
+ ngx_event_t *ev;
ngx_connection_t *c;
struct timeval tv, *tp;
@@ -195,6 +200,15 @@
}
#endif
+#if 1
+ /* DEBUG */
+ for (i = 0; i < nevents; i++) {
+ ev = event_index[i];
+ c = (ngx_connection_t *) ev->data;
+ ngx_log_debug(log, "select: %d" _ c->fd);
+ }
+#endif
+
ngx_log_debug(log, "select timer: %d" _ timer);
#if (WIN32)
@@ -222,17 +236,17 @@
if (timer) {
if (delta >= timer) {
- for (ev = timer_queue.timer_next;
- ev != &timer_queue && delta >= ev->timer_delta;
- /* void */)
- {
+ for ( ;; ) {
+ ev = timer_queue.timer_next;
+
+ if (ev == &timer_queue || delta < ev->timer_delta)
+ break;
+
delta -= ev->timer_delta;
- nx = ev->timer_next;
ngx_del_timer(ev);
ev->timedout = 1;
- if (ev->event_handler(ev) == -1)
+ if (ev->event_handler(ev) == NGX_ERROR)
ev->close_handler(ev);
- ev = nx;
}
} else {
@@ -249,15 +263,13 @@
if (ev->write) {
if (FD_ISSET(c->fd, &work_write_fd_set)) {
- ngx_log_debug(log, "select write %d" _
- c->fd);
+ ngx_log_debug(log, "select write %d" _ c->fd);
found = 1;
}
} else {
if (FD_ISSET(c->fd, &work_read_fd_set)) {
- ngx_log_debug(log, "select read %d" _
- c->fd);
+ ngx_log_debug(log, "select read %d" _ c->fd);
found = 1;
}
}
@@ -274,13 +286,14 @@
if (ev->oneshot) {
ngx_del_timer(ev);
+
if (ev->write)
- ngx_select_del_event(ev, NGX_WRITE_EVENT);
+ ngx_select_del_event(ev, NGX_WRITE_EVENT, 0);
else
- ngx_select_del_event(ev, NGX_READ_EVENT);
+ ngx_select_del_event(ev, NGX_READ_EVENT, 0);
}
- if (ev->event_handler(ev) == -1)
+ if (ev->event_handler(ev) == NGX_ERROR)
ev->close_handler(ev);
ready--;
diff --git a/src/event/modules/ngx_select_module.h b/src/event/modules/ngx_select_module.h
index e2583d7..7460790 100644
--- a/src/event/modules/ngx_select_module.h
+++ b/src/event/modules/ngx_select_module.h
@@ -8,7 +8,7 @@
int ngx_select_init(int max_connections, ngx_log_t *log);
int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags);
-int ngx_select_del_event(ngx_event_t *ev, int event);
+int ngx_select_del_event(ngx_event_t *ev, int event, u_int flags);
int ngx_select_set_event(ngx_event_t *ev, int filter, u_int flags);
void ngx_select_add_timer(ngx_event_t *ev, ngx_msec_t timer);
int ngx_select_process_events(ngx_log_t *log);
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 8e918f0..2d68af2 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -21,7 +21,7 @@
#if !(USE_KQUEUE)
-#if 0
+#if 1
ngx_event_type_e ngx_event_type = NGX_SELECT_EVENT;
#else
ngx_event_type_e ngx_event_type = NGX_KQUEUE_EVENT;
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 866911c..db2dc59 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -10,6 +10,8 @@
#include <ngx_alloc.h>
#include <ngx_array.h>
+#define NGX_INVALID_INDEX 0x80000000
+
typedef struct ngx_event_s ngx_event_t;
struct ngx_event_s {
@@ -79,7 +81,7 @@
typedef struct {
int (*add)(ngx_event_t *ev, int event, u_int flags);
- int (*del)(ngx_event_t *ev, int event);
+ int (*del)(ngx_event_t *ev, int event, u_int flags);
void (*timer)(ngx_event_t *ev, ngx_msec_t timer);
int (*process)(ngx_log_t *log);
int (*read)(ngx_event_t *ev, char *buf, size_t size);
@@ -96,8 +98,12 @@
NGX_CLEAR_EVENT kqueue
NGX_AIO_EVENT overlapped, aio_read, aioread
no need to add or delete events
+
+NGX_CLOSE_EVENT kqueue: kqueue deletes events for file that closed
*/
+#define NGX_CLOSE_EVENT 1
+
#if (HAVE_KQUEUE)
#define NGX_READ_EVENT EVFILT_READ
@@ -124,15 +130,12 @@
#endif
-
#if (USE_KQUEUE)
#define ngx_init_events ngx_kqueue_init
#define ngx_process_events ngx_kqueue_process_events
-#define ngx_kqueue_add_event(ev, event) \
- ngx_kqueue_set_event(ev, event, EV_ADD | flags)
-#define ngx_kqueue_del_event(ev, event) \
- ngx_kqueue_set_event(ev, event, EV_DELETE)
+#define ngx_add_event ngx_kqueue_add_event
+#define ngx_del_event ngx_kqueue_add_event
#define ngx_add_timer ngx_kqueue_add_timer
#define ngx_event_recv ngx_event_recv_core
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index ef6f85e..9954080 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -1,4 +1,6 @@
+#include <nginx.h>
+
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_types.h>
@@ -11,11 +13,12 @@
int ngx_event_accept(ngx_event_t *ev)
{
- ngx_err_t err;
- ngx_socket_t s;
- struct sockaddr_in addr;
- int addrlen = sizeof(struct sockaddr_in);
- ngx_connection_t *cn = (ngx_connection_t *) ev->data;
+ ngx_err_t err;
+ ngx_socket_t s;
+ ngx_event_t *rev, *wev;
+ ngx_connection_t *c, *ac;
+
+ ac = (ngx_connection_t *) ev->data;
ngx_log_debug(ev->log, "ngx_event_accept: accept ready: %d" _
ev->available);
@@ -23,69 +26,73 @@
ev->ready = 0;
do {
- if ((s = accept(cn->fd, cn->sockaddr, &cn->socklen)) == -1) {
+ if ((s = accept(ac->fd, ac->sockaddr, &ac->socklen)) == -1) {
err = ngx_socket_errno;
if (err == NGX_EAGAIN) {
ngx_log_error(NGX_LOG_INFO, ev->log, err,
"ngx_event_accept: EAGAIN while accept %s",
- cn->addr_text);
+ ac->addr_text);
return NGX_OK;
}
ngx_log_error(NGX_LOG_ERR, ev->log, err,
- "ngx_event_accept: accept %s failed", cn->addr_text);
+ "ngx_event_accept: accept %s failed", ac->addr_text);
/* if we return NGX_ERROR listen socket would be closed */
return NGX_OK;
}
- ngx_log_debug(ev->log, "ngx_event_accept: accept: %d" _ s);
-
#if !(HAVE_INHERITED_NONBLOCK)
if (ngx_nonblocking(s) == -1)
ngx_log_error(NGX_LOG_ERR, log, ngx_socket_errno,
ngx_nonblocking_n "failed");
#endif
- ngx_memzero(&ngx_read_events[s], sizeof(ngx_event_t));
- ngx_memzero(&ngx_write_events[s], sizeof(ngx_event_t));
- ngx_memzero(&ngx_connections[s], sizeof(ngx_connection_t));
+ rev = &ngx_read_events[s];
+ wev = &ngx_write_events[s];
+ c = &ngx_connections[s];
- ngx_connections[s].sockaddr = cn->sockaddr;
- ngx_connections[s].family = cn->family;
- ngx_connections[s].socklen = cn->socklen;
- ngx_connections[s].addr = cn->addr;
- ngx_connections[s].addr_text.len = cn->addr_text.len;
- ngx_connections[s].post_accept_timeout = cn->post_accept_timeout;
+ ngx_memzero(rev, sizeof(ngx_event_t));
+ ngx_memzero(wev, sizeof(ngx_event_t));
+ ngx_memzero(c, sizeof(ngx_connection_t));
- ngx_read_events[s].data = ngx_write_events[s].data
- = &ngx_connections[s];
- ngx_connections[s].read = &ngx_read_events[s];
- ngx_connections[s].write = &ngx_write_events[s];
+ c->sockaddr = ac->sockaddr;
+ c->family = ac->family;
+ c->socklen = ac->socklen;
+ c->addr = ac->addr;
+ c->addr_text.len = ac->addr_text.len;
+ c->post_accept_timeout = ac->post_accept_timeout;
- ngx_connections[s].fd = s;
- ngx_connections[s].unexpected_eof = 1;
- ngx_write_events[s].write = 1;
- ngx_write_events[s].ready = 1;
+ rev->index = wev->index = NGX_INVALID_INDEX;
- ngx_write_events[s].timer = ngx_read_events[s].timer = 10000;
+ rev->data = wev->data = c;
+ c->read = rev;
+ c->write = wev;
- ngx_write_events[s].timer_handler =
- ngx_read_events[s].timer_handler = ngx_event_close_connection;
+ c->fd = s;
+ c->unexpected_eof = 1;
+ wev->write = 1;
+ wev->ready = 1;
- ngx_write_events[s].close_handler =
- ngx_read_events[s].close_handler = ngx_event_close_connection;
+ wev->timer = rev->timer = 10000;
+ wev->timer_handler = rev->timer_handler = ngx_event_close_connection;
+ wev->close_handler = rev->close_handler = ngx_event_close_connection;
- ngx_connections[s].server = cn->server;
- ngx_connections[s].servers = cn->servers;
- ngx_connections[s].log =
- ngx_read_events[s].log = ngx_write_events[s].log = ev->log;
+ c->server = ac->server;
+ c->servers = ac->servers;
+ c->log = rev->log = wev->log = ev->log;
+
+ /* STUB: x86: SP: xadd, MT: lock xadd, MP: lock xadd, shared */
+ c->number = ngx_connection_counter++;
+
+ ngx_log_debug(ev->log, "ngx_event_accept: accept: %d, %d" _
+ s _ c->number);
#if (HAVE_DEFERRED_ACCEPT)
if (ev->accept_filter)
- ngx_read_events[s].ready = 1;
+ rev->ready = 1;
#endif
- cn->handler(&ngx_connections[s]);
+ ac->handler(c);
#if (HAVE_KQUEUE)
#if !(USE_KQUEUE)
diff --git a/src/event/ngx_event_close.c b/src/event/ngx_event_close.c
index 0e3fe20..66a3693 100644
--- a/src/event/ngx_event_close.c
+++ b/src/event/ngx_event_close.c
@@ -11,21 +11,20 @@
int rc;
ngx_connection_t *c = (ngx_connection_t *) ev->data;
+ ngx_log_debug(c->log, "CLOSE: %d" _ c->fd);
+
ngx_assert((c->fd != -1), return NGX_ERROR, c->log,
"ngx_event_close: already closed");
ngx_destroy_pool(c->pool);
+ ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
+ ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
+
if ((rc = ngx_close_socket(c->fd)) == -1)
ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno,
"ngx_event_close: close failed");
- if (c->read->next)
- ngx_del_event(c->read, NGX_READ_EVENT);
-
- if (c->write->next)
- ngx_del_event(c->write, NGX_WRITE_EVENT);
-
c->fd = -1;
return rc;
diff --git a/src/event/ngx_event_write.c b/src/event/ngx_event_write.c
index ccbb157..5de80d3 100644
--- a/src/event/ngx_event_write.c
+++ b/src/event/ngx_event_write.c
@@ -98,8 +98,7 @@
(ngx_iovec_t *) trailer->elts, trailer->nelts,
&sent, c->log);
} else {
- rc = ngx_sendv(c, (ngx_iovec_t *) header->elts,
- header->nelts);
+ rc = ngx_sendv(c, (ngx_iovec_t *) header->elts, header->nelts);
sent = rc > 0 ? rc: 0;
diff --git a/src/http/modules/ngx_http_event_proxy_handler.c b/src/http/modules/ngx_http_event_proxy_handler.c
index af35468..d7d6178 100644
--- a/src/http/modules/ngx_http_event_proxy_handler.c
+++ b/src/http/modules/ngx_http_event_proxy_handler.c
@@ -309,7 +309,9 @@
if (n == 0) {
ngx_log_debug(c->log, "CLOSE proxy");
- ngx_del_event(ev, NGX_READ_EVENT);
+#if 0
+ ngx_del_event(ev, NGX_READ_EVENT, NGX_CLOSE_EVENT);
+#endif
ngx_event_close_connection(ev);
p->hunk_n = 0;
@@ -439,7 +441,9 @@
if (n == 0) {
ngx_log_debug(c->log, "CLOSE proxy");
- ngx_del_event(ev, NGX_READ_EVENT);
+#if 0
+ ngx_del_event(ev, NGX_READ_EVENT, NGX_CLOSE_EVENT);
+#endif
ngx_event_close_connection(ev);
p->hunk_n = 0;
diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c
index b6e0adb..1948795 100644
--- a/src/http/modules/ngx_http_index_handler.c
+++ b/src/http/modules/ngx_http_index_handler.c
@@ -16,7 +16,16 @@
static char *ngx_http_index_set_index(ngx_pool_t *p, void *conf,
ngx_str_t *value);
-static ngx_command_t ngx_http_index_commands[];
+
+static ngx_command_t ngx_http_index_commands[] = {
+
+ {"index", ngx_http_index_set_index, NULL,
+ NGX_HTTP_LOC_CONF, NGX_CONF_ITERATE,
+ "set index files"},
+
+ {NULL}
+
+};
ngx_http_module_t ngx_http_index_module = {
@@ -33,17 +42,6 @@
};
-static ngx_command_t ngx_http_index_commands[] = {
-
- {"index", ngx_http_index_set_index, NULL,
- NGX_HTTP_LOC_CONF, NGX_CONF_ITERATE,
- "set index files"},
-
- {NULL}
-
-};
-
-
int ngx_http_index_handler(ngx_http_request_t *r)
{
int i;
@@ -71,10 +69,14 @@
ngx_memcpy(file, index[i].data, index[i].len + 1);
fd = ngx_open_file(name, NGX_FILE_RDONLY);
- if (fd == -1) {
+ if (fd == NGX_INVALID_FILE) {
err = ngx_errno;
if (err == NGX_ENOENT)
continue;
+#if (WIN32)
+ if (err == ERROR_PATH_NOT_FOUND)
+ continue;
+#endif
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
ngx_open_file_n " %s failed", name);
@@ -82,9 +84,9 @@
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- r->filename.len = r->server->doc_root_len + r->uri.len + index[i].len;
- r->filename.data = name;
- r->fd = fd;
+ r->file.name.len = r->server->doc_root_len + r->uri.len + index[i].len;
+ r->file.name.data = name;
+ r->file.fd = fd;
loc.len = r->uri.len + index[i].len;
return ngx_http_internal_redirect(r, loc);
diff --git a/src/http/modules/ngx_http_log_handler.c b/src/http/modules/ngx_http_log_handler.c
new file mode 100644
index 0000000..56ea841
--- /dev/null
+++ b/src/http/modules/ngx_http_log_handler.c
@@ -0,0 +1,79 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_string.h>
+#include <ngx_alloc.h>
+#include <ngx_time.h>
+#include <ngx_http.h>
+
+
+ngx_http_module_t ngx_http_log_module;
+
+
+static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+
+int ngx_http_log_handler(ngx_http_request_t *r)
+{
+ size_t len;
+ char *line, *p;
+ ngx_tm_t tm;
+
+#if (WIN32)
+ len = 2 + 22 + 3 + 20 + 5 + 20 + 2;
+#else
+ len = 2 + 22 + 3 + 20 + 5 + 20 + 1;
+#endif
+
+ len += r->connection->addr_text.len;
+ len += r->request_line.len;
+
+
+ ngx_test_null(line, ngx_palloc(r->pool, len), NGX_ERROR);
+ p = line;
+
+ ngx_memcpy(p, r->connection->addr_text.data, r->connection->addr_text.len);
+ p += r->connection->addr_text.len;
+
+ *p++ = ' ';
+
+ ngx_localtime(&tm);
+
+ *p++ = '[';
+ p += ngx_snprintf(p, 21, "%02d/%s/%d:%02d:%02d:%02d",
+ tm.ngx_tm_mday, months[tm.ngx_tm_mon],
+ tm.ngx_tm_year + 1900,
+ tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec);
+
+ *p++ = ']';
+
+ *p++ = ' ';
+
+ *p++ = '"';
+ ngx_memcpy(p, r->request_line.data, r->request_line.len);
+ p += r->request_line.len;
+ *p++ = '"';
+
+ *p++ = ' ';
+
+ p += ngx_snprintf(p, 4, "%d", r->headers_out.status);
+
+ *p++ = ' ';
+
+ p += ngx_snprintf(p, 21, QD_FMT, r->connection->sent);
+
+ *p++ = ' ';
+
+ p += ngx_snprintf(p, 21, "%u", r->connection->number);
+
+#if (WIN32)
+ *p++ = CR; *p++ = LF;
+#else
+ *p++ = LF;
+#endif
+
+ write(1, line, len);
+
+ return NGX_OK;
+}
diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c
index cded5f0..56f24cd 100644
--- a/src/http/modules/ngx_http_static_handler.c
+++ b/src/http/modules/ngx_http_static_handler.c
@@ -24,51 +24,84 @@
int ngx_http_static_handler(ngx_http_request_t *r)
{
- int rc;
+ int rc;
+ ngx_err_t err;
ngx_hunk_t *h;
ngx_http_log_ctx_t *ctx;
-/*
+#if 0
ngx_http_event_static_handler_loc_conf_t *cf;
cf = (ngx_http_event_static_handler_loc_conf_t *)
ngx_get_module_loc_conf(r, &ngx_http_event_static_handler_module);
-*/
+#endif
ngx_http_discard_body(r);
ctx = r->connection->log->data;
ctx->action = "sending response";
- if (r->fd != -1)
- r->fd = ngx_open_file(r->filename.data, NGX_FILE_RDONLY);
+ if (r->file.fd == NGX_INVALID_FILE)
+ r->file.fd = ngx_open_file(r->file.name.data, NGX_FILE_RDONLY);
- if (r->fd == -1) {
+ if (r->file.fd == NGX_INVALID_FILE) {
+ err = ngx_errno;
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
"ngx_http_static_handler: "
- ngx_open_file_n " %s failed", r->filename.data);
+ ngx_open_file_n " %s failed", r->file.name.data);
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ if (err == NGX_ENOENT)
+ return NGX_HTTP_NOT_FOUND;
+#if (WIN32)
+ else if (err == ERROR_PATH_NOT_FOUND)
+ return NGX_HTTP_NOT_FOUND;
+#endif
+ else
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- if (ngx_stat_fd(r->fd, &r->fileinfo) == -1) {
+ if (!r->file.info_valid) {
+ if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
+ "ngx_http_static_handler: "
+ ngx_stat_fd_n " %s failed", r->file.name.data);
+
+ if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR)
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
+ "ngx_http_static_handler: "
+ ngx_close_file_n " %s failed", r->file.name.data);
+
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ r->file.info_valid = 1;
+ }
+
+#if !(WIN32) /* it's probably Unix specific */
+
+ if (!ngx_is_file(r->file.info)) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
"ngx_http_static_handler: "
- ngx_stat_fd_n " %s failed", r->filename.data);
+ "%s is not regular file", r->file.name.data);
- /* close fd */
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR)
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
+ "ngx_http_static_handler: "
+ ngx_close_file_n " %s failed", r->file.name.data);
+
+ return NGX_HTTP_NOT_FOUND;
}
+#endif
+
r->headers_out.status = NGX_HTTP_OK;
- r->headers_out.content_length = ngx_file_size(r->fileinfo);
-/*
- r->headers_out.last_modified = ngx_file_mtime(r->fileinfo);
-*/
+ r->headers_out.content_length = ngx_file_size(r->file.info);
+ r->headers_out.last_modified_time = ngx_file_mtime(r->file.info);
ngx_test_null(r->headers_out.content_type,
ngx_push_table(r->headers_out.headers),
NGX_HTTP_INTERNAL_SERVER_ERROR);
+
r->headers_out.content_type->key.len = 12;
r->headers_out.content_type->key.data = "Content-Type";
@@ -90,83 +123,29 @@
r->headers_out.content_type->value.len = 25;
r->headers_out.content_type->value.data = "text/html; charset=koi8-r";
}
+ /**/
- /* STUB */
- rc = ngx_http_header_filter(r);
-/*
- rc = ngx_send_http_header(r);
-*/
- if (r->header_only)
- return rc;
-
- /* TODO: NGX_HTTP_INTERNAL_SERVER_ERROR is too late */
-
- /* STUB */
+ /* we need to allocate them before header would be sent */
ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)),
NGX_HTTP_INTERNAL_SERVER_ERROR);
- h->type = NGX_HUNK_FILE|NGX_HUNK_LAST;
- h->pos.file = 0;
- h->last.file = ngx_file_size(r->fileinfo);
-
- /* STUB */
ngx_test_null(h->file, ngx_pcalloc(r->pool, sizeof(ngx_file_t)),
NGX_HTTP_INTERNAL_SERVER_ERROR);
- h->file->fd = r->fd;
+
+ rc = ngx_http_send_header(r);
+ if (r->header_only)
+ return rc;
+
+ h->type = NGX_HUNK_FILE|NGX_HUNK_LAST;
+ h->pos.file = 0;
+ h->last.file = ngx_file_size(r->file.info);
+
+ h->file->fd = r->file.fd;
h->file->log = r->connection->log;
rc = ngx_http_output_filter(r, h);
+
ngx_log_debug(r->connection->log, "0 output_filter: %d" _ rc);
+
return rc;
}
-
-#if 0
-
-static void *ngx_create_index_config()
-{
- ngx_http_index_handler_loc_conf_t *cf;
-
- ngx_check_null(cf, ngx_alloc(p, sizeof(ngx_http_index_handler_loc_conf)),
- NULL);
-
- cf->indices = ngx_create_array(p, sizeof(ngx_http_index_t), 5);
- if (cf->indices == NULL)
- return NULL;
-
- cf->max_index_len = 0;
-
- return cf;
-}
-
-static void *ngx_merge_index_config()
-{
- if (p->indices->nelts > 0) {
-
- copy and check dups
-
- if (c->max_index_len < c->max_index_len)
- c->max_index_len < c->max_index_len);
- }
-}
-
-static void *ngx_set_index()
-{
- if (*conf == NULL) {
- cf = ngx_create_index_conf();
- if (cf == NULL)
- return "can not create config";
- }
-
- while (args) {
- index = ngx_push_array(cf->indices);
- index->name = arg;
- index->len = ngx_strlen(arg) + 1;
-
- if (cf->max_index_len < index->len)
- cf->max_index_len = index->len;
- }
-
- *conf = cf;
-}
-
-#endif
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index 0f60fe6..ed7ca92 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -32,11 +32,13 @@
#define NGX_HTTP_OK 200
#define NGX_HTTP_SPECIAL_RESPONSE 300
-#define NGX_HTTP_MOVED_PERMANENTLY 302
+#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_NOT_FOUND 404
#define NGX_HTTP_REQUEST_URI_TOO_LARGE 414
-#define NGX_HTTP_INTERNAL_SERVER_ERROR 503
+#define NGX_HTTP_INTERNAL_SERVER_ERROR 500
#define NGX_HTTP_STATIC_HANDLER 0
@@ -59,21 +61,25 @@
time_t lingering_time;
} ngx_http_server_t;
+
typedef struct {
int len;
char *data;
int offset;
} ngx_http_header_t;
+
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_t *headers;
} ngx_http_headers_in_t;
+
typedef struct {
int status;
ngx_str_t status_line;
@@ -93,12 +99,18 @@
time_t last_modified_time;
} ngx_http_headers_out_t;
+
typedef struct ngx_http_request_s ngx_http_request_t;
struct ngx_http_request_s {
- ngx_str_t filename;
+ ngx_file_t file;
+#if 0
+ ngx_str_t filename;
+ ngx_file_info_t fileinfo;
ngx_fd_t fd;
+ int filename_len;
+#endif
void **ctx;
void **loc_conf;
@@ -110,11 +122,8 @@
ngx_http_headers_in_t headers_in;
ngx_http_headers_out_t headers_out;
- int filename_len;
int (*handler)(ngx_http_request_t *r);
- ngx_file_info_t fileinfo;
-
int method;
time_t lingering_time;
@@ -146,7 +155,7 @@
unsigned header_only:1;
unsigned unusual_uri:1; /* URI is not started with '/' - "GET http://" */
- unsigned complex_uri:1; /* URI with "./" or with "//" */
+ unsigned complex_uri:1; /* URI with "/." or with "//" (WIN32) */
int state;
char *uri_start;
@@ -163,6 +172,7 @@
#endif
};
+
typedef struct {
char *action;
char *client;
@@ -181,10 +191,20 @@
int (*translate_handler)(ngx_http_request_t *r);
- int (*init_output_body_filter)(int (**next_filter)
+ int (*output_header_filter) (ngx_http_request_t *r);
+ int (*next_output_header_filter) (ngx_http_request_t *r);
+
+ int (*output_body_filter)();
+ int (*next_output_body_filter)
+ (ngx_http_request_t *r, ngx_chain_t *ch);
+
+#if 0
+ int (*next_output_body_filter)(int (**next_filter)
(ngx_http_request_t *r, ngx_chain_t *ch));
+#endif
} ngx_http_module_t;
+
#define NGX_HTTP_MODULE 0
#define ngx_get_module_loc_conf(r, module) r->loc_conf[module.index]
@@ -204,10 +224,14 @@
/* STUB */
int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log);
+/**/
int ngx_http_init_connection(ngx_connection_t *c);
+int ngx_http_discard_body(ngx_http_request_t *r);
+
+
extern int ngx_max_module;
extern ngx_http_module_t *ngx_http_modules[];
diff --git a/src/http/ngx_http_config.c b/src/http/ngx_http_config.c
index 36037c6..f298bd1 100644
--- a/src/http/ngx_http_config.c
+++ b/src/http/ngx_http_config.c
@@ -9,6 +9,8 @@
int ngx_max_module;
+int (*ngx_http_top_header_filter) (ngx_http_request_t *r);
+
/* STUB: gobal srv and loc conf */
void **ngx_srv_conf;
void **ngx_loc_conf;
@@ -53,13 +55,27 @@
int ngx_http_init_filters(ngx_pool_t *pool, ngx_http_module_t **modules)
{
int i;
- int (*filter)(ngx_http_request_t *r, ngx_chain_t *ch);
+ int (*ohf)(ngx_http_request_t *r);
+ int (*obf)(ngx_http_request_t *r, ngx_chain_t *ch);
- filter = ngx_http_write_filter;
+ ohf = NULL;
for (i = 0; modules[i]; i++) {
- if (modules[i]->init_output_body_filter)
- modules[i]->init_output_body_filter(&filter);
+ if (modules[i]->output_header_filter) {
+ modules[i]->next_output_header_filter = ohf;
+ ohf = modules[i]->output_header_filter;
+ }
+ }
+
+ ngx_http_top_header_filter = ohf;
+
+ obf = NULL;
+
+ for (i = 0; modules[i]; i++) {
+ if (modules[i]->output_body_filter) {
+ modules[i]->next_output_body_filter = obf;
+ obf = modules[i]->output_body_filter;
+ }
}
}
diff --git a/src/http/ngx_http_config.h b/src/http/ngx_http_config.h
index 8787fbe..43cd5ec 100644
--- a/src/http/ngx_http_config.h
+++ b/src/http/ngx_http_config.h
@@ -10,6 +10,8 @@
int ngx_http_config_modules(ngx_pool_t *pool, ngx_http_module_t **modules);
+extern int (*ngx_http_top_header_filter) (ngx_http_request_t *r);
+
extern void **ngx_srv_conf;
extern void **ngx_loc_conf;
diff --git a/src/http/ngx_http_core.c b/src/http/ngx_http_core.c
index 99b4b7d..a0555e3 100644
--- a/src/http/ngx_http_core.c
+++ b/src/http/ngx_http_core.c
@@ -18,7 +18,16 @@
static int ngx_http_core_translate_handler(ngx_http_request_t *r);
-static ngx_command_t ngx_http_core_commands[];
+static ngx_command_t ngx_http_core_commands[] = {
+
+ {"send_timeout", ngx_conf_set_time_slot,
+ offsetof(ngx_http_core_loc_conf_t, send_timeout),
+ NGX_HTTP_LOC_CONF, NGX_CONF_TAKE1,
+ "set timeout for sending response"},
+
+ {NULL}
+
+};
ngx_http_module_t ngx_http_core_module = {
@@ -35,18 +44,6 @@
};
-static ngx_command_t ngx_http_core_commands[] = {
-
- {"send_timeout", ngx_conf_set_time_slot,
- offsetof(ngx_http_core_loc_conf_t, send_timeout),
- NGX_HTTP_LOC_CONF, NGX_CONF_TAKE1,
- "set timeout for sending response"},
-
- {NULL}
-
-};
-
-
int ngx_http_handler(ngx_http_request_t *r)
{
int rc, i;
@@ -95,22 +92,54 @@
return NGX_OK;
}
- r->filename.len = r->server->doc_root_len + r->uri.len + 2;
+ r->file.name.len = r->server->doc_root_len + r->uri.len + 2;
- ngx_test_null(r->filename.data,
- ngx_palloc(r->pool, r->filename.len + 1),
+ ngx_test_null(r->file.name.data,
+ ngx_palloc(r->pool, r->file.name.len + 1),
NGX_HTTP_INTERNAL_SERVER_ERROR);
- loc = ngx_cpystrn(r->filename.data, r->server->doc_root,
+ loc = ngx_cpystrn(r->file.name.data, r->server->doc_root,
r->server->doc_root_len);
last = ngx_cpystrn(loc, r->uri.data, r->uri.len + 1);
- ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->filename.data);
+ ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _
+ r->file.name.data);
- if (ngx_file_type(r->filename.data, &r->fileinfo) == -1) {
+#if (WIN32)
+
+ /* There is no way to open file or directory in Win32 with
+ one syscall: CreateFile() returns ERROR_ACCESS_DENIED on directory,
+ so we need to check its type before opening */
+
+#if 0 /* OLD: ngx_file_type() is to be removed */
+ if (ngx_file_type(r->file.name.data, &r->file.info) == -1) {
+#endif
+
+ r->file.info.dwFileAttributes = GetFileAttributes(r->file.name.data);
+ if (r->file.info.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
err = ngx_errno;
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
- ngx_file_type_n " %s failed", r->filename.data);
+ "ngx_http_core_translate_handler: "
+ ngx_file_type_n " %s failed", r->file.name.data);
+
+ if (err == ERROR_FILE_NOT_FOUND)
+ return NGX_HTTP_NOT_FOUND;
+ else if (err == ERROR_PATH_NOT_FOUND)
+ return NGX_HTTP_NOT_FOUND;
+ else
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+#else
+
+ if (r->file.fd == NGX_INVALID_FILE)
+ r->file.fd = ngx_open_file(r->file.name.data, NGX_FILE_RDONLY);
+
+ if (r->file.fd == NGX_INVALID_FILE) {
+ err = ngx_errno;
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
+ "ngx_http_static_handler: "
+ ngx_open_file_n " %s failed", r->file.name.data);
if (err == NGX_ENOENT)
return NGX_HTTP_NOT_FOUND;
@@ -118,8 +147,33 @@
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- if (ngx_is_dir(r->fileinfo)) {
- ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->filename.data);
+ if (!r->file.info_valid) {
+ if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
+ "ngx_http_static_handler: "
+ ngx_stat_fd_n " %s failed", r->file.name.data);
+
+ if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR)
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
+ "ngx_http_static_handler: "
+ ngx_close_file_n " %s failed", r->file.name.data);
+
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ r->file.info_valid = 1;
+ }
+#endif
+
+ if (ngx_is_dir(r->file.info)) {
+ ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);
+
+#if !(WIN32)
+ if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR)
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
+ "ngx_http_static_handler: "
+ ngx_close_file_n " %s failed", r->file.name.data);
+#endif
/* BROKEN: need to include server name */
@@ -144,6 +198,11 @@
}
+int ngx_http_send_header(ngx_http_request_t *r)
+{
+ return (*ngx_http_top_header_filter)(r);
+}
+
int ngx_http_redirect(ngx_http_request_t *r, int redirect)
{
@@ -162,17 +221,27 @@
/* log request */
+ ngx_http_special_response(r, error);
return ngx_http_close_request(r);
}
int ngx_http_close_request(ngx_http_request_t *r)
{
- ngx_assert((r->fd != -1), /* void */; , r->connection->log,
- "file already closed");
+ ngx_log_debug(r->connection->log, "CLOSE#: %d" _ r->file.fd);
- if (r->fd != -1) {
- if (ngx_close_file(r->fd) == -1)
+ ngx_http_log_handler(r);
+
+ ngx_assert((r->file.fd != NGX_INVALID_FILE), /* void */ ; ,
+ r->connection->log, "file already closed");
+
+ if (r->file.fd != NGX_INVALID_FILE) {
+/* STUB WIN32 */
+#if (WIN32)
+ if (ngx_close_file(r->file.fd) == 0)
+#else
+ if (ngx_close_file(r->file.fd) == -1)
+#endif
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
ngx_close_file_n " failed");
}
diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c
index 905af47..cbea0c6 100644
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_event.c
@@ -13,6 +13,7 @@
#include <ngx_table.h>
#include <ngx_hunk.h>
#include <ngx_connection.h>
+#include <ngx_inet.h>
#include <ngx_http.h>
#include <ngx_http_config.h>
#include <ngx_http_core.h>
@@ -33,19 +34,14 @@
static int ngx_http_process_request_headers(ngx_http_request_t *r);
static int ngx_http_process_request_header_line(ngx_http_request_t *r);
-static int ngx_http_event_handler(ngx_http_request_t *r);
-static int ngx_http_block_read(ngx_event_t *ev);
-
-
-static int ngx_http_read_discarded_body(ngx_event_t *ev);
-
-int ngx_http_handler(ngx_http_request_t *r);
-static int ngx_http_set_default_handler(ngx_http_request_t *r);
+static int ngx_http_event_request_handler(ngx_http_request_t *r);
static int ngx_http_writer(ngx_event_t *ev);
-static int ngx_http_set_lingering_close(ngx_http_request_t *r);
+static int ngx_http_block_read(ngx_event_t *ev);
+static int ngx_http_read_discarded_body(ngx_event_t *ev);
static int ngx_http_keepalive_handler(ngx_event_t *ev);
-static int ngx_http_lingering_close(ngx_event_t *ev);
+static int ngx_http_set_lingering_close(ngx_http_request_t *r);
+static int ngx_http_lingering_close_handler(ngx_event_t *ev);
#if 0
int ngx_http_special_response(ngx_http_request_t *r, int error);
@@ -70,6 +66,8 @@
static ngx_http_header_t headers_in[] = {
{ 4, "Host", offsetof(ngx_http_headers_in_t, host) },
{ 10, "Connection", offsetof(ngx_http_headers_in_t, connection) },
+ { 17, "If-Modified-Since",
+ offsetof(ngx_http_headers_in_t,if_modified_since) },
{ 10, "User-Agent", offsetof(ngx_http_headers_in_t, user_agent) },
@@ -106,15 +104,11 @@
ngx_test_null(c->addr_text.data, ngx_palloc(c->pool, c->addr_text.len),
NGX_ERROR);
- /* STUB: should be ngx_inet_ntop() */
-#if (WIN32)
- c->addr_text.data = inet_ntoa((struct in_addr *)
- ((char *)c->sockaddr + c->addr));
-#else
- inet_ntop(c->family, (char *)c->sockaddr + c->addr,
- c->addr_text.data, c->addr_text.len);
-#endif
- /**/
+ ngx_test_null(c->addr_text.len,
+ ngx_inet_ntop(c->family,
+ (char *)c->sockaddr + c->addr,
+ c->addr_text.data, c->addr_text.len),
+ NGX_ERROR);
ngx_test_null(ctx, ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)),
NGX_ERROR);
@@ -166,6 +160,7 @@
c->data = r;
r->connection = c;
r->server = srv;
+ r->file.fd = NGX_INVALID_FILE;
/* STUB */
r->srv_conf = ngx_srv_conf;
@@ -189,6 +184,10 @@
ngx_test_null(r->ctx, ngx_pcalloc(r->pool, sizeof(void *) * ngx_max_module),
ngx_http_close_request(r));
+ r->headers_out.headers = ngx_create_table(r->pool, 10);
+ r->headers_out.content_length = -1;
+ r->headers_out.last_modified_time = -1;
+
ev->event_handler = ngx_http_process_request_header;
r->state_handler = ngx_http_process_request_line;
r->header_timeout = 1;
@@ -262,7 +261,7 @@
}
if (rc == NGX_OK)
- return ngx_http_event_handler(r);
+ return ngx_http_event_request_handler(r);
else
return rc;
}
@@ -280,7 +279,8 @@
c = r->connection;
if (rc == NGX_OK) {
- r->uri.len = r->uri_end - r->uri_start;
+ r->uri.len = (r->args_start ? r->args_start - 1 : r->uri_end)
+ - r->uri_start;
ngx_test_null(r->uri.data, ngx_palloc(r->pool, r->uri.len + 1),
ngx_http_close_request(r));
ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
@@ -309,7 +309,8 @@
/* */
if (r->uri_ext) {
- r->exten.len = r->uri_end - r->uri_ext;
+ r->exten.len = (r->args_start ? r->args_start - 1 : r->uri_end)
+ - r->uri_ext;
ngx_test_null(r->exten.data,
ngx_palloc(r->pool, r->exten.len + 1),
ngx_http_close_request(r));
@@ -326,8 +327,6 @@
/* TODO: check too long URI - no space for header, compact buffer */
r->headers_in.headers = ngx_create_table(r->pool, 10);
- /* THINK: when to create out.headers ? */
- r->headers_out.headers = ngx_create_table(r->pool, 10);
r->state_handler = ngx_http_process_request_headers;
ctx = r->connection->log->data;
@@ -372,7 +371,14 @@
} else if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
ngx_log_debug(r->connection->log, "HTTP header done");
- return NGX_OK;
+
+ if (r->http_version > NGX_HTTP_VERSION_10
+ && r->headers_in.host == NULL)
+ {
+ return ngx_http_error(r, NGX_HTTP_BAD_REQUEST);
+ } else {
+ return NGX_OK;
+ }
} else if (rc == NGX_AGAIN) {
return NGX_AGAIN;
@@ -422,7 +428,7 @@
}
-static int ngx_http_event_handler(ngx_http_request_t *r)
+static int ngx_http_event_request_handler(ngx_http_request_t *r)
{
int rc;
ngx_msec_t timeout;
@@ -494,181 +500,6 @@
}
-static int ngx_http_block_read(ngx_event_t *ev)
-{
- ngx_log_debug(ev->log, "http read blocked");
-
- ev->blocked = 1;
- return ngx_del_event(ev, NGX_READ_EVENT);
-}
-
-
-
-/* FIND PLACE ******************** */
-
-void ngx_http_discard_body(ngx_http_request_t *r)
-{
- ngx_log_debug(r->connection->log, "set discard body");
-
- ngx_del_timer(r->connection->read);
-
- if (r->client_content_length)
- r->connection->read->event_handler = ngx_http_read_discarded_body;
-}
-
-
-static int ngx_http_read_discarded_body(ngx_event_t *ev)
-{
- size_t size;
- ssize_t n;
- ngx_connection_t *c;
- ngx_http_request_t *r;
-
- c = (ngx_connection_t *) ev->data;
- r = (ngx_http_request_t *) c->data;
-
- ngx_log_debug(ev->log, "http read discarded body");
-
- if (ev->timedout)
- return NGX_ERROR;
-
- if (r->discarded_buffer == NULL)
- ngx_test_null(r->discarded_buffer,
- ngx_palloc(r->pool, r->server->discarded_buffer_size),
- NGX_ERROR);
-
- size = r->client_content_length;
- if (size > r->server->discarded_buffer_size)
- size = r->server->discarded_buffer_size;
-
- n = ngx_event_recv(c, r->discarded_buffer, size);
- if (n == NGX_ERROR)
- return NGX_ERROR;
-
- if (n == NGX_AGAIN)
- return NGX_OK;
-
- r->client_content_length -= n;
- /* XXX: what if r->client_content_length == 0 ? */
- return NGX_OK;
-}
-
-
-static int ngx_http_discarded_read(ngx_event_t *ev)
-{
- ssize_t n;
- ngx_connection_t *c;
- ngx_http_request_t *r;
-
- c = (ngx_connection_t *) ev->data;
- r = (ngx_http_request_t *) c->data;
-
- ngx_log_debug(ev->log, "http discarded read");
-
- if (ev->timedout)
- return NGX_ERROR;
-
- if (r->discarded_buffer == NULL)
- ngx_test_null(r->discarded_buffer,
- ngx_palloc(r->pool, r->server->discarded_buffer_size),
- NGX_ERROR);
-
- n = ngx_event_recv(c, r->discarded_buffer,
- r->server->discarded_buffer_size);
-
- return n;
-}
-
-/* ******************** */
-
-
-#if 0
-int ngx_http_handler(ngx_http_request_t *r)
-{
- int rc;
-
- r->connection->unexpected_eof = 0;
- r->lingering_close = 1;
-
- /* STUB: should find handler */
-#if 1
- r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
-#endif
- rc = ngx_http_set_default_handler(r);
-
- if (rc >= NGX_HTTP_SPECIAL_RESPONSE)
- return ngx_http_special_response(r, rc);
-
- rc = r->handler(r);
-
- return rc;
-}
-#endif
-
-
-#if 0
-static int ngx_http_set_default_handler(ngx_http_request_t *r)
-{
- ngx_err_t err;
- char *name, *loc, *file;
-
-#if 0
- /* STUB */
- r->handler = ngx_http_proxy_handler;
- return NGX_OK;
-#endif
-
-/* NO NEEDED
- ngx_test_null(r->headers_out,
- ngx_pcalloc(r->pool, sizeof(ngx_http_headers_out_t)),
- NGX_HTTP_INTERNAL_SERVER_ERROR);
-*/
-
- if (*(r->uri_end - 1) == '/') {
- r->handler = ngx_http_index_handler;
- return NGX_OK;
- }
-
- /* 20 bytes is spare space for some index name, i.e. index.html */
- r->filename_len = r->uri_end - r->uri_start + r->server->doc_root_len + 20;
-
- ngx_test_null(r->filename,
- ngx_palloc(r->pool, r->filename_len),
- NGX_HTTP_INTERNAL_SERVER_ERROR);
-
- r->location = ngx_cpystrn(r->filename, r->server->doc_root,
- r->server->doc_root_len);
- file = ngx_cpystrn(r->location, r->uri_start,
- r->uri_end - r->uri_start + 1);
-
- ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->filename);
-
- if (ngx_file_type(r->filename, &r->fileinfo) == -1) {
- err = ngx_errno;
- ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
- ngx_file_type_n " %s failed", r->filename);
-
- if (err == NGX_ENOENT)
- return NGX_HTTP_NOT_FOUND;
- else
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_is_dir(r->fileinfo)) {
- ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->filename);
- *file++ = '/';
- *file = '\0';
- r->headers_out.location = r->location;
- return NGX_HTTP_MOVED_PERMANENTLY;
- }
-
- r->handler = ngx_http_static_handler;
-
- return NGX_OK;
-}
-#endif
-
-
static int ngx_http_writer(ngx_event_t *ev)
{
int rc;
@@ -735,35 +566,93 @@
}
-static int ngx_http_set_lingering_close(ngx_http_request_t *r)
+static int ngx_http_block_read(ngx_event_t *ev)
{
- r->lingering_time = ngx_time() + r->server->lingering_time;
- r->connection->read->event_handler = ngx_http_lingering_close;
+ ngx_log_debug(ev->log, "http read blocked");
+
+ ev->blocked = 1;
+ return ngx_del_event(ev, NGX_READ_EVENT, 0);
+}
+
+
+int ngx_http_discard_body(ngx_http_request_t *r)
+{
+ ngx_log_debug(r->connection->log, "set discard body");
ngx_del_timer(r->connection->read);
- ngx_add_timer(r->connection->read, r->server->lingering_timeout);
-#if (HAVE_CLEAR_EVENT)
- if (ngx_add_event(r->connection->read, NGX_READ_EVENT,
- NGX_CLEAR_EVENT) == NGX_ERROR) {
-#else
- if (ngx_add_event(r->connection->read, NGX_READ_EVENT,
- NGX_ONESHOT_EVENT) == NGX_ERROR) {
-#endif
- return ngx_http_close_request(r);
- }
-
- if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) == NGX_ERROR)
- {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno,
- ngx_shutdown_socket_n " failed");
- return ngx_http_close_request(r);
- }
+ if (r->client_content_length)
+ r->connection->read->event_handler = ngx_http_read_discarded_body;
return NGX_OK;
}
+static int ngx_http_read_discarded_body(ngx_event_t *ev)
+{
+ size_t size;
+ ssize_t n;
+ ngx_connection_t *c;
+ ngx_http_request_t *r;
+
+ c = (ngx_connection_t *) ev->data;
+ r = (ngx_http_request_t *) c->data;
+
+ ngx_log_debug(ev->log, "http read discarded body");
+
+ if (ev->timedout)
+ return NGX_ERROR;
+
+ if (r->discarded_buffer == NULL)
+ ngx_test_null(r->discarded_buffer,
+ ngx_palloc(r->pool, r->server->discarded_buffer_size),
+ NGX_ERROR);
+
+ size = r->client_content_length;
+ if (size > r->server->discarded_buffer_size)
+ size = r->server->discarded_buffer_size;
+
+ n = ngx_event_recv(c, r->discarded_buffer, size);
+ if (n == NGX_ERROR)
+ return NGX_ERROR;
+
+ if (n == NGX_AGAIN)
+ return NGX_OK;
+
+ r->client_content_length -= n;
+ /* XXX: what if r->client_content_length == 0 ? */
+ return NGX_OK;
+}
+
+
+#if 0
+static int ngx_http_discarded_read(ngx_event_t *ev)
+{
+ ssize_t n;
+ ngx_connection_t *c;
+ ngx_http_request_t *r;
+
+ c = (ngx_connection_t *) ev->data;
+ r = (ngx_http_request_t *) c->data;
+
+ ngx_log_debug(ev->log, "http discarded read");
+
+ if (ev->timedout)
+ return NGX_ERROR;
+
+ if (r->discarded_buffer == NULL)
+ ngx_test_null(r->discarded_buffer,
+ ngx_palloc(r->pool, r->server->discarded_buffer_size),
+ NGX_ERROR);
+
+ n = ngx_event_recv(c, r->discarded_buffer,
+ r->server->discarded_buffer_size);
+
+ return n;
+}
+#endif
+
+
static int ngx_http_keepalive_handler(ngx_event_t *ev)
{
ssize_t n;
@@ -772,7 +661,7 @@
c = (ngx_connection_t *) ev->data;
- ngx_log_debug(ev->log, "http keepalive");
+ ngx_log_debug(ev->log, "http keepalive handler");
if (ev->timedout)
return NGX_DONE;
@@ -800,17 +689,46 @@
}
-static int ngx_http_lingering_close(ngx_event_t *ev)
+static int ngx_http_set_lingering_close(ngx_http_request_t *r)
{
- ssize_t n;
- ngx_msec_t timer;
+ r->lingering_time = ngx_time() + r->server->lingering_time;
+ r->connection->read->event_handler = ngx_http_lingering_close_handler;
+
+ ngx_del_timer(r->connection->read);
+ ngx_add_timer(r->connection->read, r->server->lingering_timeout);
+
+#if (HAVE_CLEAR_EVENT)
+ if (ngx_add_event(r->connection->read, NGX_READ_EVENT,
+ NGX_CLEAR_EVENT) == NGX_ERROR) {
+#else
+ if (ngx_add_event(r->connection->read, NGX_READ_EVENT,
+ NGX_ONESHOT_EVENT) == NGX_ERROR) {
+#endif
+ return ngx_http_close_request(r);
+ }
+
+ if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) == -1)
+ {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno,
+ ngx_shutdown_socket_n " failed");
+ return ngx_http_close_request(r);
+ }
+
+ return NGX_OK;
+}
+
+
+static int ngx_http_lingering_close_handler(ngx_event_t *ev)
+{
+ ssize_t n;
+ ngx_msec_t timer;
ngx_connection_t *c;
ngx_http_request_t *r;
c = (ngx_connection_t *) ev->data;
r = (ngx_http_request_t *) c->data;
- ngx_log_debug(ev->log, "http lingering close");
+ ngx_log_debug(ev->log, "http lingering close handler");
if (ev->timedout)
return NGX_DONE;
diff --git a/src/http/ngx_http_get_time.c b/src/http/ngx_http_get_time.c
index 33b14c3..d03e8b1 100644
--- a/src/http/ngx_http_get_time.c
+++ b/src/http/ngx_http_get_time.c
@@ -2,6 +2,7 @@
#include <nginx.h>
#include <ngx_config.h>
+#include <ngx_types.h>
ngx_http_get_time(char *buf, time_t t)
diff --git a/src/http/ngx_http_header.h b/src/http/ngx_http_header.h
deleted file mode 100644
index 48070b3..0000000
--- a/src/http/ngx_http_header.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-gx_chunk_t *gx_http_header(gx_http_request_t *r, gx_http_header_out_t *out);
diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c
index e8259a3..fb51235 100644
--- a/src/http/ngx_http_header_filter.c
+++ b/src/http/ngx_http_header_filter.c
@@ -9,7 +9,7 @@
#include <ngx_http.h>
-#if 0
+static int ngx_http_header_filter(ngx_http_request_t *r);
ngx_http_module_t ngx_http_header_filter_module = {
NGX_HTTP_MODULE,
@@ -21,33 +21,40 @@
NULL, /* init module */
NULL, /* translate handler */
- ngx_http_header_filter_init /* init output header filter */
- NULL /* init output body filter */
+ ngx_http_header_filter, /* output header filter */
+ NULL, /* next output header filter */
+ NULL, /* output body filter */
+ NULL /* next output body filter */
};
-#endif
-
static char server_string[] = "Server: " NGINX_VER CRLF;
static ngx_str_t http_codes[] = {
+
{ 6, "200 OK" },
{ 21, "301 Moved Permanently" },
+ { 21, "302 Moved Temporarily" },
+ { 0, NULL },
+ { 16, "304 Not Modified" },
{ 15, "400 Bad Request" },
{ 0, NULL },
{ 0, NULL },
{ 13, "403 Forbidden" },
- { 13, "404 Not Found" }
+ { 13, "404 Not Found" },
+
+ { 25, "500 Internal Server Error" }
};
-int ngx_http_header_filter(ngx_http_request_t *r)
+static int ngx_http_header_filter(ngx_http_request_t *r)
{
int len, status, i;
+ time_t ims;
ngx_hunk_t *h;
ngx_chain_t *ch;
ngx_table_elt_t *header;
@@ -55,10 +62,30 @@
if (r->http_version < NGX_HTTP_VERSION_10)
return NGX_OK;
- /* 9 is for "HTTP/1.1 ", 2 is for trailing "\r\n"
+ /* 9 is for "HTTP/1.x ", 2 is for trailing "\r\n"
and 2 is for end of header */
len = 9 + 2 + 2;
+ if (r->headers_in.if_modified_since && r->headers_out.status == NGX_HTTP_OK)
+ {
+ /* TODO: check LM header */
+ if (r->headers_out.last_modified_time) {
+ ims = ngx_http_parse_time(
+ r->headers_in.if_modified_since->value.data,
+ r->headers_in.if_modified_since->value.len);
+
+ ngx_log_debug(r->connection->log, "%d %d" _
+ ims _ r->headers_out.last_modified_time);
+
+ if (ims != NGX_ERROR && ims >= r->headers_out.last_modified_time) {
+ r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
+ r->headers_out.content_length = -1;
+ r->headers_out.content_type->key.len = 0;
+ r->header_only = 1;
+ }
+ }
+ }
+
/* status line */
if (r->headers_out.status_line.len) {
len += r->headers_out.status_line.len;
@@ -69,8 +96,12 @@
else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST)
status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 1;
+ else if (r->headers_out.status < NGX_HTTP_INTERNAL_SERVER_ERROR)
+ status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 1 + 4;
+
else
- status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 1 + 1;
+ status = r->headers_out.status
+ - NGX_HTTP_INTERNAL_SERVER_ERROR + 1 + 4 + 5;
len += http_codes[status].len;
}
@@ -99,6 +130,14 @@
len += r->headers_out.content_type.len + 16;
#endif
+ if (r->headers_out.last_modified && r->headers_out.last_modified->key.len) {
+ len += r->headers_out.last_modified->key.len
+ + r->headers_out.last_modified->value.len + 2;
+ } else if (r->headers_out.last_modified_time != -1) {
+ /* "Last-Modified: ... \r\n"; */
+ len += 46;
+ }
+
if (r->keepalive)
len += 24;
else
@@ -114,7 +153,7 @@
ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 64), NGX_ERROR);
- /* "HTTP/1.1 " */
+ /* "HTTP/1.x " */
ngx_memcpy(h->last.mem, "HTTP/1.1 ", 9);
h->last.mem += 9;
@@ -159,6 +198,17 @@
}
#endif
+ if (!(r->headers_out.last_modified
+ && r->headers_out.last_modified->key.len)
+ && r->headers_out.last_modified_time != -1)
+ {
+ ngx_memcpy(h->last.mem, "Last-Modified: ", 15);
+ h->last.mem += 15;
+ h->last.mem += ngx_http_get_time(h->last.mem,
+ r->headers_out.last_modified_time);
+ *(h->last.mem++) = CR; *(h->last.mem++) = LF;
+ }
+
if (r->keepalive) {
ngx_memcpy(h->last.mem, "Connection: keep-alive" CRLF, 24);
h->last.mem += 24;
@@ -181,9 +231,17 @@
*(h->last.mem++) = CR; *(h->last.mem++) = LF;
}
+ /* STUB */
+ *(h->last.mem) = '\0';
+ ngx_log_debug(r->connection->log, "%s\n" _ h->pos.mem);
+ /**/
+
/* end of HTTP header */
*(h->last.mem++) = CR; *(h->last.mem++) = LF;
+ if (r->header_only)
+ h->type |= NGX_HUNK_LAST;
+
ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), NGX_ERROR);
ch->hunk = h;
diff --git a/src/http/ngx_http_modules.c b/src/http/ngx_http_modules.c
index d8977ef..5b814ba 100644
--- a/src/http/ngx_http_modules.c
+++ b/src/http/ngx_http_modules.c
@@ -1,12 +1,18 @@
#include <ngx_http.h>
+extern ngx_http_module_t ngx_http_header_filter_module;
+
extern ngx_http_module_t ngx_http_write_filter_module;
extern ngx_http_module_t ngx_http_output_filter_module;
+
extern ngx_http_module_t ngx_http_core_module;
extern ngx_http_module_t ngx_http_index_module;
ngx_http_module_t *ngx_http_modules[] = {
+
+ &ngx_http_header_filter_module,
+
&ngx_http_write_filter_module,
&ngx_http_output_filter_module,
diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c
index 91c6275..e8388dc 100644
--- a/src/http/ngx_http_output_filter.c
+++ b/src/http/ngx_http_output_filter.c
@@ -9,29 +9,15 @@
#include <ngx_http_output_filter.h>
+int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk);
static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src);
+#if 0
static int ngx_http_output_filter_init(
int (**next_filter)(ngx_http_request_t *r, ngx_chain_t *ch));
+#endif
static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool);
-static ngx_command_t ngx_http_output_filter_commands[];
-
-
-ngx_http_module_t ngx_http_output_filter_module = {
- NGX_HTTP_MODULE,
-
- NULL, /* create server config */
- ngx_http_output_filter_create_conf, /* create location config */
- ngx_http_output_filter_commands, /* module directives */
-
- NULL, /* init module */
- NULL, /* translate handler */
-
- ngx_http_output_filter_init /* init output body filter */
-};
-
-
static ngx_command_t ngx_http_output_filter_commands[] = {
{"output_buffer", ngx_conf_set_size_slot,
@@ -44,8 +30,27 @@
};
+ngx_http_module_t ngx_http_output_filter_module = {
+ NGX_HTTP_MODULE,
+
+ NULL, /* create server config */
+ ngx_http_output_filter_create_conf, /* create location config */
+ ngx_http_output_filter_commands, /* module directives */
+
+ NULL, /* init module */
+ NULL, /* translate handler */
+
+ NULL, /* output header filter */
+ NULL, /* next output header filter */
+ ngx_http_output_filter, /* output body filter */
+ NULL /* next output body filter */
+};
+
+
+#if 0
static int (*ngx_http_output_next_filter)(ngx_http_request_t *r,
ngx_chain_t *ch);
+#endif
int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
@@ -66,7 +71,9 @@
ngx_http_output_filter_module,
sizeof(ngx_http_output_filter_ctx_t));
+#if 0
ctx->next_filter = ngx_http_output_next_filter;
+#endif
}
if (hunk && (hunk->type & NGX_HUNK_LAST))
@@ -87,7 +94,11 @@
/* our hunk is still busy */
if (ctx->hunk->pos.mem < ctx->hunk->last.mem) {
+ rc = ngx_http_output_filter_module.
+ next_output_body_filter(r, NULL);
+#if 0
rc = ctx->next_filter(r, NULL);
+#endif
/* our hunk is free */
} else {
@@ -110,7 +121,7 @@
if (ce->hunk->type & NGX_HUNK_FILE)
break;
- if ((ce->hunk->type & NGX_HUNK_MEMORY|NGX_HUNK_MMAP)
+ if ((ce->hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP))
&& (r->filter & NGX_HTTP_FILTER_NEED_TEMP))
break;
}
@@ -121,7 +132,11 @@
ctx->out.next = NULL;
}
+ rc = ngx_http_output_filter_module.
+ next_output_body_filter(r, &ctx->out);
+#if 0
rc = ctx->next_filter(r, &ctx->out);
+#endif;
}
/* delete completed hunks from input chain */
@@ -139,7 +154,11 @@
} else {
if (hunk == NULL) {
+ rc = ngx_http_output_filter_module.
+ next_output_body_filter(r, NULL);
+#if 0
rc = ctx->next_filter(r, NULL);
+#endif;
} else {
@@ -147,7 +166,7 @@
if (((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY)
&& (hunk->type & NGX_HUNK_FILE))
|| ((r->filter & NGX_HTTP_FILTER_NEED_TEMP)
- && (hunk->type & NGX_HUNK_MEMORY|NGX_HUNK_MMAP))
+ && (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP)))
) {
/* out hunk is still busy */
@@ -155,7 +174,11 @@
ngx_add_hunk_to_chain(ctx->in, hunk, r->pool,
NGX_ERROR);
+ rc = ngx_http_output_filter_module.
+ next_output_body_filter(r, NULL);
+#if 0
rc = ctx->next_filter(r, NULL);
+#endif
} else {
if (ctx->hunk == NULL) {
@@ -201,7 +224,11 @@
ctx->out.hunk = ctx->hunk;
ctx->out.next = NULL;
+ rc = ngx_http_output_filter_module.
+ next_output_body_filter(r, &ctx->out);
+#if 0
rc = ctx->next_filter(r, &ctx->out);
+#endif
}
}
@@ -209,7 +236,11 @@
ctx->out.hunk = hunk;
ctx->out.next = NULL;
+ rc = ngx_http_output_filter_module.
+ next_output_body_filter(r, &ctx->out);
+#if 0
rc = ctx->next_filter(r, &ctx->out);
+#endif
}
}
}
@@ -269,6 +300,11 @@
dst->last.mem += size;
}
+#if 1
+ if (src->type & NGX_HUNK_LAST)
+ dst->type |= NGX_HUNK_LAST;
+#endif
+
return NGX_OK;
}
@@ -286,6 +322,7 @@
return conf;
}
+#if 0
static int ngx_http_output_filter_init(
int (**next_filter)(ngx_http_request_t *r, ngx_chain_t *ch))
{
@@ -294,3 +331,4 @@
return NGX_OK;
}
+#endif
diff --git a/src/http/ngx_http_output_filter.h b/src/http/ngx_http_output_filter.h
index 1ea3c73..32af6fe 100644
--- a/src/http/ngx_http_output_filter.h
+++ b/src/http/ngx_http_output_filter.h
@@ -15,7 +15,9 @@
} ngx_http_output_filter_conf_t;
typedef struct {
+#if 0
int (*next_filter)(ngx_http_request_t *r, ngx_chain_t *ch);
+#endif
ngx_hunk_t *hunk;
ngx_chain_t *in;
ngx_chain_t out;
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index 2b4cc72..7d1cc23 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -110,7 +110,7 @@
}
break;
- /* check dot after slash */
+ /* check "/." or "//" */
case sw_after_slash_in_uri:
switch (ch) {
case CR:
@@ -132,8 +132,9 @@
state = sw_uri;
break;
case '/':
+#if (WIN32)
r->complex_uri = 1;
- state = sw_uri;
+#endif
break;
case '?':
r->args_start = p;
diff --git a/src/http/ngx_http_parse_time.c b/src/http/ngx_http_parse_time.c
index f4097ad..199a7f9 100644
--- a/src/http/ngx_http_parse_time.c
+++ b/src/http/ngx_http_parse_time.c
@@ -1,7 +1,8 @@
-#include <time.h>
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_types.h>
-#define NGX_ERROR -1
static int mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
@@ -16,6 +17,7 @@
isoc /* Tue Dec 10 23:50:13 2002 */
} fmt;
+ fmt = 0;
end = value + len;
for (p = value; p < end; p++) {
@@ -182,31 +184,38 @@
+ (*(p + 2) - '0') * 10 + *(p + 3) - '0';
}
+#if 0
printf("%d.%d.%d %d:%d:%d\n", day, month + 1, year, hour, min, sec);
+#endif
- if (hour > 23 || min > 60 || sec > 60)
+ if (hour > 23 || min > 59 || sec > 59)
return NGX_ERROR;
if (day == 29 && month == 1) {
if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0))
return NGX_ERROR;
- } else if (day > mday[month])
+ } else if (day > mday[month]) {
return NGX_ERROR;
}
if (sizeof(time_t) <= 4 && year >= 2038)
return NGX_ERROR;
+ /* shift new year to 1st March, needed for Gauss's formula */
if (--month <= 0) {
month += 12;
year -= 1;
}
-
- return year / 4 - year / 100 + year / 400
- + 367 * month / 12 + day + year * 365 - 719499;
+ /* Gauss's formula for days from 1 March 1 BC */
+ return (365 * year + year / 4 - year / 100 + year / 400
+ + 367 * month / 12 + day - 31
+ /* 719527 days are between 1 March 1 BC and 1 March 1970,
+ 31 and 28 days in Jan and Feb 1970 */
+ - 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec;
}
+#if 0
char zero[] = "Sun, 01 Jan 1970 08:49:30";
char one[] = "Sunday, 11-Dec-02 08:49:30";
char two[] = "Sun Mar 1 08:49:37 2000";
@@ -228,3 +237,5 @@
rc = ngx_http_parse_time(thr, sizeof(thr) - 1);
printf("rc: %d\n", rc);
}
+
+#endif
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 8ca49eb..92f938c 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -1,21 +1,91 @@
+#include <nginx.h>
#include <ngx_config.h>
-#if 0
#include <ngx_core.h>
-#endif
+#include <ngx_string.h>
#include <ngx_http.h>
+static char error_tail[] =
+"<hr><center>" NGINX_VER "</center>" CRLF
+"</body>" CRLF
+"</html>" CRLF
+;
+
+static char error_400_page[] =
+"<html>" CRLF
+"<head><title>400 Bad Request</title></head>" CRLF
+"<body bgcolor=\"white\">" CRLF
+"<center><h1>400 Bad Request</h1></center>" CRLF
+;
+
+static char error_404_page[] =
+"<html>" CRLF
+"<head><title>404 Not Found</title></head>" CRLF
+"<body bgcolor=\"white\">" CRLF
+"<center><h1>404 Not Found</h1></center>" CRLF
+;
+
+
+static ngx_str_t error_pages[] = {
+ { 0, NULL}, /* 301 */
+ { 0, NULL}, /* 302 */
+ { 0, NULL}, /* 303 */
+ { 0, NULL}, /* 304 */
+
+ { sizeof(error_400_page) - 1, error_400_page },
+ { 0, NULL}, /* 401 */
+ { 0, NULL}, /* 402 */
+ { 0, NULL}, /* 403 */
+ { sizeof(error_404_page) - 1, error_404_page },
+
+ { 0, NULL} /* 500 */
+};
int ngx_http_special_response(ngx_http_request_t *r, int error)
{
- switch (error) {
+ int rc, err, len;
+ ngx_hunk_t *message, *tail;
- default:
- r->headers_out.status = error;
- return ngx_http_header_filter(r);
+ len = 0;
- }
+ r->headers_out.status = error;
- return ngx_http_error(r, error);
+ if (error < NGX_HTTP_BAD_REQUEST)
+ err = error - NGX_HTTP_MOVED_PERMANENTLY;
+
+ else if (error < NGX_HTTP_INTERNAL_SERVER_ERROR)
+ err = error - NGX_HTTP_BAD_REQUEST + 4;
+
+ else
+ err = NGX_HTTP_INTERNAL_SERVER_ERROR + 4 + 5;
+
+ if (error_pages[err].len == 0)
+ r->headers_out.content_length = -1;
+ else
+ r->headers_out.content_length = error_pages[err].len
+ + len + sizeof(error_tail);
+
+ ngx_http_send_header(r);
+
+ if (error_pages[err].len == 0)
+ return NGX_OK;
+
+ ngx_test_null(message, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)),
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
+
+ message->type = NGX_HUNK_MEMORY;
+ message->pos.mem = error_pages[err].data;
+ message->last.mem = error_pages[err].data + error_pages[err].len;
+
+ rc = ngx_http_output_filter(r, message);
+
+ ngx_test_null(tail, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)),
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
+
+ tail->type = NGX_HUNK_MEMORY|NGX_HUNK_LAST;
+ tail->pos.mem = error_tail;
+ tail->last.mem = error_tail + sizeof(error_tail);
+
+ rc = ngx_http_output_filter(r, tail);
}
diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c
index 9914f0b..1dce403 100644
--- a/src/http/ngx_http_write_filter.c
+++ b/src/http/ngx_http_write_filter.c
@@ -9,23 +9,10 @@
#include <ngx_http_write_filter.h>
-static ngx_command_t ngx_http_write_filter_commands[];
+int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in);
static void *ngx_http_write_filter_create_conf(ngx_pool_t *pool);
-ngx_http_module_t ngx_http_write_filter_module = {
- NGX_HTTP_MODULE,
-
- NULL, /* create server config */
- ngx_http_write_filter_create_conf, /* create location config */
- ngx_http_write_filter_commands, /* module directives */
-
- NULL, /* init module */
- NULL, /* translate handler */
-
- NULL /* init output body filter */
-};
-
static ngx_command_t ngx_http_write_filter_commands[] = {
@@ -39,6 +26,23 @@
};
+ngx_http_module_t ngx_http_write_filter_module = {
+ NGX_HTTP_MODULE,
+
+ NULL, /* create server config */
+ ngx_http_write_filter_create_conf, /* create location config */
+ ngx_http_write_filter_commands, /* module directives */
+
+ NULL, /* init module */
+ NULL, /* translate handler */
+
+ NULL, /* output header filter */
+ NULL, /* next output header filter */
+ ngx_http_write_filter, /* output body filter */
+ NULL, /* next output body filter */
+};
+
+
int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
int last;
@@ -69,7 +73,7 @@
ch->hunk->type _ ch->hunk->pos.file _
ch->hunk->last.file - ch->hunk->pos.file);
- if (ch->hunk->type & NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)
+ if (ch->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED))
flush = size;
if (ch->hunk->type & NGX_HUNK_LAST)
@@ -90,7 +94,7 @@
ch->hunk->type _ ch->hunk->pos.file _
ch->hunk->last.file - ch->hunk->pos.file);
- if (ch->hunk->type & NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)
+ if (ch->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED))
flush = size;
if (ch->hunk->type & NGX_HUNK_LAST)
@@ -101,6 +105,8 @@
ngx_get_module_loc_conf(r->main ? r->main : r,
ngx_http_write_filter_module);
+ ngx_log_debug(r->connection->log, "l:%d f:%d" _ last _ flush);
+
if (!last && flush == 0 && size < conf->buffer_output)
return NGX_OK;
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index 90d6dd6..f0c324e 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -6,6 +6,9 @@
#include <sys/stat.h>
typedef int ngx_fd_t;
+#define NGX_INVALID_FILE -1
+#define NGX_FILE_ERROR -1
+
typedef struct stat ngx_file_info_t;
@@ -27,6 +30,7 @@
#define ngx_stat_fd_n "fstat()"
#define ngx_is_dir(sb) (S_ISDIR(sb.st_mode))
+#define ngx_is_file(sb) (S_ISREG(sb.st_mode))
#define ngx_file_size(sb) sb.st_size
#define ngx_file_mtime(sb) sb.st_mtime
diff --git a/src/os/unix/ngx_sendv.c b/src/os/unix/ngx_sendv.c
index 4094568..810caae 100644
--- a/src/os/unix/ngx_sendv.c
+++ b/src/os/unix/ngx_sendv.c
@@ -8,21 +8,21 @@
ssize_t ngx_sendv(ngx_connection_t *c, ngx_iovec_t *iovec, int n)
{
- ssize_t rc;
- ngx_err_t err;
+ ssize_t rc;
+ ngx_err_t err;
- rc = writev(c->fd, iovec, n);
+ rc = writev(c->fd, iovec, n);
- if (rc == -1) {
- err = ngx_socket_errno;
- if (err == NGX_EAGAIN) {
- ngx_log_error(NGX_LOG_INFO, c->log, err, "sendv() eagain");
- return NGX_AGAIN;
- }
+ if (rc == -1) {
+ err = ngx_socket_errno;
+ if (err == NGX_EAGAIN) {
+ ngx_log_error(NGX_LOG_INFO, c->log, err, "sendv() eagain");
+ return NGX_AGAIN;
+ }
- ngx_log_error(NGX_LOG_ERR, c->log, err, "sendv() failed");
- return NGX_ERROR;
- }
+ ngx_log_error(NGX_LOG_ERR, c->log, err, "sendv() failed");
+ return NGX_ERROR;
+ }
- return rc;
+ return rc;
}
diff --git a/src/os/win32/ngx_files.c b/src/os/win32/ngx_files.c
index 8a91901..ce0d3dd 100644
--- a/src/os/win32/ngx_files.c
+++ b/src/os/win32/ngx_files.c
@@ -14,5 +14,3 @@
return n;
}
-
-
diff --git a/src/os/win32/ngx_files.h b/src/os/win32/ngx_files.h
index bddfe0d..8cd58ef 100644
--- a/src/os/win32/ngx_files.h
+++ b/src/os/win32/ngx_files.h
@@ -11,6 +11,9 @@
#endif
typedef HANDLE ngx_fd_t;
+#define NGX_INVALID_FILE INVALID_HANDLE_VALUE
+#define NGX_FILE_ERROR 0
+
typedef unsigned __int64 off_t;
typedef BY_HANDLE_FILE_INFORMATION ngx_file_info_t;
@@ -25,33 +28,32 @@
#define NGX_FILE_RDONLY GENERIC_READ
+#define ngx_close_file CloseHandle
+#define ngx_close_file_n "CloseHandle()"
int ngx_file_type(char *filename, ngx_file_info_t *fi);
-#define ngx_file_type_n "GetFileAttributes"
+#define ngx_file_type_n "GetFileAttributes"
-#define ngx_stat_fd(fd, fi) GetFileInformationByHandle(fd, fi)
-#define ngx_stat_fd_n "GetFileInformationByHandle"
+#define ngx_stat_fd(fd, fi) GetFileInformationByHandle(fd, fi)
+#define ngx_stat_fd_n "GetFileInformationByHandle"
-#define ngx_is_dir(fi) (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+#define ngx_is_dir(fi) (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+#define ngx_is_file(fi) !(fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
#define ngx_file_size(fi) \
- fi.nFileSizeLow
-
-/*
-#define ngx_file_size(fi) \
- ((off_t) fi.nFileSizeHigh << 32 & fi.nFileSizeLow)
-*/
-
-#define ngx_file_mtime(fi) fi.ftLastWriteTime
-
-/*
-1970 - 1601:
- 116444736000000000
- 19DB1DED53E8000
-*/
+ (((off_t) fi.nFileSizeHigh << 32) | fi.nFileSizeLow)
-#define ngx_read_file_n "ReadFile()"
+/* There are 134774 days between 1 Jan 1970 and 1 Jan 1601,
+ 11644473600 seconds or 11644473600,000,000,0 100-nanosecond intervals */
+
+#define ngx_file_mtime(fi) \
+ (time_t) (((((unsigned __int64) fi.ftLastWriteTime.dwHighDateTime << 32) \
+ | fi.ftLastWriteTime.dwLowDateTime) \
+ - 116444736000000000) / 10000000)
+
+
+#define ngx_read_file_n "ReadFile()"
#endif /* _NGX_FILES_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_sendv.c b/src/os/win32/ngx_sendv.c
index 7bf590e..452df9f 100644
--- a/src/os/win32/ngx_sendv.c
+++ b/src/os/win32/ngx_sendv.c
@@ -6,29 +6,39 @@
#include <ngx_log.h>
#include <ngx_sendv.h>
+#include <ngx_string.h>
+
ssize_t ngx_sendv(ngx_connection_t *c, ngx_iovec_t *iovec, int n)
{
- int rc;
- size_t sent;
- ngx_err_t err;
+ int rc;
+ size_t sent;
+ ngx_err_t err;
- ngx_log_debug(c->log, "WSASend() start");
+#if 0
+ /* STUB: WSABUF must be 4-byte aligned. Undocumented WSAEINVAL error */
+ ngx_iovec_t iov[10];
+ ngx_memcpy(iov, iovec, n * sizeof(ngx_iovec_t));
+#endif
- rc = WSASend(c->fd, iovec, n, &sent, 0, NULL, NULL);
+ sent = 0;
- ngx_log_debug(c->log, "WSASend() done");
+ ngx_log_debug(c->log, "WSASend: %d, %d, %08x" _ c->fd _ n _ iovec);
- if (rc == -1) {
- err = ngx_socket_errno;
+ rc = WSASend(c->fd, iovec, n, &sent, 0, NULL, NULL);
- if (err == NGX_EAGAIN) {
- ngx_log_error(NGX_LOG_INFO, c->log, err, "WSASend() eagain");
- return NGX_AGAIN;
- }
+ ngx_log_debug(c->log, "WSASend() done");
- ngx_log_error(NGX_LOG_ERR, c->log, err, "WSASend() failed");
- return NGX_ERROR;
- }
+ if (rc == SOCKET_ERROR) {
+ err = ngx_socket_errno;
- return sent;
+ if (err == NGX_EAGAIN) {
+ ngx_log_error(NGX_LOG_INFO, c->log, err, "WSASend() eagain");
+ return NGX_AGAIN;
+ }
+
+ ngx_log_error(NGX_LOG_ERR, c->log, err, "WSASend() failed");
+ return NGX_ERROR;
+ }
+
+ return sent;
}
diff --git a/src/os/win32/ngx_time.h b/src/os/win32/ngx_time.h
index a810c70..57bd421 100644
--- a/src/os/win32/ngx_time.h
+++ b/src/os/win32/ngx_time.h
@@ -21,5 +21,8 @@
#define ngx_localtime GetLocalTime
#define ngx_msec GetTickCount
+/* STUB */
+#define ngx_time() time(NULL)
+
#endif /* _NGX_TIME_H_INCLUDED_ */