nginx-0.0.1-2002-09-02-18:48:24 import
diff --git a/src/core/nginx.c b/src/core/nginx.c
index 748b443..b2f3f5f 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -36,8 +36,6 @@
int main(int argc, char *const *argv)
{
- int i;
-
/* STUB */
ngx_log.log_level = NGX_LOG_DEBUG;
@@ -68,6 +66,8 @@
/* STUB */
ngx_worker(&ngx_log);
+
+ return 0;
}
static void ngx_open_listening_sockets(ngx_log_t *log)
diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h
index 88f374a..f7223fa 100644
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -18,6 +18,7 @@
#include <winsock2.h>
#include <mswsock.h>
+#include <stddef.h> /* offsetof */
#include <stdio.h>
#include <stdarg.h>
@@ -88,6 +89,10 @@
#endif
+#ifndef HAVE_SELECT
+#define HAVE_SELECT 1
+#endif
+
#ifdef __FreeBSD__
diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h
index cdd72bb..f275f91 100644
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -21,6 +21,8 @@
ngx_event_t *write;
#endif
+ off_t sent;
+
ngx_log_t *log;
int (*handler)(ngx_connection_t *c);
ngx_server_t *server;
@@ -35,6 +37,8 @@
size_t addr_textlen;
unsigned int post_accept_timeout;
+
+ unsigned unexpected_eof:1;
};
diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h
new file mode 100644
index 0000000..0d68386
--- /dev/null
+++ b/src/core/ngx_file.h
@@ -0,0 +1,16 @@
+#ifndef _NGX_FILE_H_INCLUDED_
+#define _NGX_FILE_H_INCLUDED_
+
+
+#include <ngx_files.h>
+#include <ngx_log.h>
+
+typedef struct ngx_file_s ngx_file_t;
+
+struct ngx_file_s {
+ ngx_fd_t fd;
+ ngx_log_t *log;
+};
+
+
+#endif _NGX_FILE_H_INCLUDED_
diff --git a/src/core/ngx_hunk.c b/src/core/ngx_hunk.c
index f829b7e..79a8ad7 100644
--- a/src/core/ngx_hunk.c
+++ b/src/core/ngx_hunk.c
@@ -1,13 +1,13 @@
-#include <ngx_file.h>
#include <ngx_hunk.h>
-ngx_hunk_t *ngx_get_hunk(ngx_pool_t *pool, int size, int before, int after)
+ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,
+ int before, int after)
{
ngx_hunk_t *h = ngx_palloc(pool, sizeof(ngx_hunk_t));
-#ifndef OFF_EQUAL_PTR
+#if !(HAVE_OFFSET_EQUAL_PTR)
h->pos.file = h->last.file = 0;
#endif
@@ -18,16 +18,16 @@
h->type = NGX_HUNK_TEMP;
h->tag = 0;
- h->fd = (ngx_fd_t) -1;
+ h->file = NULL;
return h;
}
-ngx_hunk_t *ngx_get_hunk_before(ngx_pool_t *pool, ngx_hunk_t *hunk, int size)
+ngx_hunk_t *ngx_create_hunk_before(ngx_pool_t *pool, ngx_hunk_t *hunk, int size)
{
ngx_hunk_t *h = ngx_palloc(pool, sizeof(ngx_hunk_t));
-#ifndef OFF_EQUAL_PTR
+#if !(HAVE_OFFSET_EQUAL_PTR)
h->pos.file = h->last.file = 0;
#endif
@@ -39,7 +39,7 @@
h->type = NGX_HUNK_TEMP;
h->tag = 0;
- h->fd = (ngx_fd_t) -1;
+ h->file = NULL;
} else {
h->pre_start = h->start = h->pos.mem = h->last.mem
@@ -48,17 +48,17 @@
h->type = NGX_HUNK_TEMP;
h->tag = 0;
- h->fd = (ngx_fd_t) -1;
+ h->file = NULL;
}
return h;
}
-ngx_hunk_t *ngx_get_hunk_after(ngx_pool_t *pool, ngx_hunk_t *hunk, int size)
+ngx_hunk_t *ngx_create_hunk_after(ngx_pool_t *pool, ngx_hunk_t *hunk, int size)
{
ngx_hunk_t *h = ngx_palloc(pool, sizeof(ngx_hunk_t));
-#ifndef OFF_EQUAL_PTR
+#if !(HAVE_OFFSET_EQUAL_PTR)
h->pos.file = h->last.file = 0;
#endif
@@ -71,7 +71,7 @@
hunk->last.mem;
h->type = NGX_HUNK_TEMP;
h->tag = 0;
- h->fd = (ngx_fd_t) -1;
+ h->file = NULL;
} else {
h->pre_start = h->start = h->pos.mem = h->last.mem =
@@ -80,7 +80,7 @@
h->type = NGX_HUNK_TEMP;
h->tag = 0;
- h->fd = (ngx_fd_t) -1;
+ h->file = NULL;
}
return h;
diff --git a/src/core/ngx_hunk.h b/src/core/ngx_hunk.h
index 3703db4..75aaef1 100644
--- a/src/core/ngx_hunk.h
+++ b/src/core/ngx_hunk.h
@@ -27,6 +27,8 @@
/* can be used with NGX_HUNK_LAST only */
#define NGX_HUNK_SHUTDOWN 0x0400
+#define NGX_HUNK_RECYCLED 0x0800
+
#define NGX_HUNK_IN_MEMORY (NGX_HUNK_TEMP|NGX_HUNK_MEMORY|NGX_HUNK_MMAP)
@@ -48,7 +50,7 @@
char *pre_start; /* start of pre-allocated hunk */
char *post_end; /* end of post-allocated hunk */
int tag;
- ngx_fd_t fd;
+ ngx_file_t *file;
};
typedef struct ngx_chain_s ngx_chain_t;
@@ -57,8 +59,11 @@
ngx_chain_t *next;
};
-#define ngx_create_temp_hunk(pool, size, before, after) \
- ngx_get_hunk(pool, size, before, after)
+
+ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,
+ int before, int after);
+
+#define ngx_create_chain_entry(pool) ngx_palloc(pool, sizeof(ngx_chain_t))
#define ngx_add_hunk_to_chain(chain, h, pool, error) \
do { \
@@ -70,7 +75,6 @@
-ngx_hunk_t *ngx_get_hunk(ngx_pool_t *pool, int size, int before, int after);
#endif /* _NGX_CHUNK_H_INCLUDED_ */
diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c
index bed628a..6a68358 100644
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -45,7 +45,11 @@
" [%s] ", err_levels[level]);
len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1,
+#if (WIN32)
+ "%d#%d: ", 0, 0);
+#else
"%d#%d: ", getpid(), 0);
+#endif
#if (HAVE_VARIADIC_MACROS)
va_start(args, fmt);
diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h
index f1e49eb..d79237e 100644
--- a/src/core/ngx_log.h
+++ b/src/core/ngx_log.h
@@ -3,7 +3,7 @@
#include <ngx_errno.h>
-#include <ngx_file.h>
+#include <ngx_files.h>
typedef enum {
NGX_LOG_EMERG = 0,
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index 1ea3d22..efa573c 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -19,7 +19,6 @@
#error "kqueue is not supported on this platform"
#endif
-static void ngx_add_timer_core(ngx_event_t *ev, u_int timer);
static int kq;
@@ -50,6 +49,7 @@
#if !(USE_KQUEUE)
ngx_event_actions.add = ngx_kqueue_add_event;
ngx_event_actions.del = ngx_kqueue_del_event;
+ ngx_event_actions.timer = ngx_kqueue_add_timer;
ngx_event_actions.process = ngx_kqueue_process_events;
#endif
@@ -57,21 +57,11 @@
int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
{
- if (event == NGX_TIMER_EVENT) {
- ngx_add_timer_core(ev, flags);
- return 0;
- }
-
return ngx_kqueue_set_event(ev, event, EV_ADD | flags);
}
int ngx_kqueue_del_event(ngx_event_t *ev, int event)
{
- if (event == NGX_TIMER_EVENT) {
- ngx_del_timer(ev);
- return 0;
- }
-
return ngx_kqueue_set_event(ev, event, EV_DELETE);
}
@@ -156,14 +146,9 @@
delta -= ev->timer_delta;
nx = ev->timer_next;
ngx_del_timer(ev);
-#if 1
ev->timedout = 1;
if (ev->event_handler(ev) == NGX_ERROR)
ev->close_handler(ev);
-#else
- if (ev->timer_handler(ev) == -1)
- ev->close_handler(ev);
-#endif
ev = nx;
}
@@ -182,7 +167,8 @@
if (event_list[i].flags & EV_ERROR) {
ngx_log_error(NGX_LOG_ALERT, log, event_list[i].data,
- "ngx_kqueue_process_events: kevent error");
+ "ngx_kqueue_process_events: kevent error on %d",
+ event_list[i].ident);
continue;
}
@@ -215,10 +201,12 @@
return 0;
}
-static void ngx_add_timer_core(ngx_event_t *ev, u_int timer)
+void ngx_kqueue_add_timer(ngx_event_t *ev, ngx_msec_t timer)
{
ngx_event_t *e;
+ ngx_log_debug(ev->log, "set timer: %d" _ timer);
+
for (e = timer_queue.timer_next;
e != &timer_queue && timer > e->timer_delta;
e = e->timer_next)
@@ -232,19 +220,3 @@
e->timer_prev->timer_next = ev;
e->timer_prev = ev;
}
-
-#if 0
-static void ngx_inline ngx_del_timer(ngx_event_t *ev)
-{
- if (ev->timer_prev)
- ev->timer_prev->timer_next = ev->timer_next;
-
- if (ev->timer_next) {
- ev->timer_next->timer_prev = ev->timer_prev;
- ev->timer_next = NULL;
- }
-
- if (ev->timer_prev)
- ev->timer_prev = NULL;
-}
-#endif
diff --git a/src/event/modules/ngx_kqueue_module.h b/src/event/modules/ngx_kqueue_module.h
index 38509a0..389ff67 100644
--- a/src/event/modules/ngx_kqueue_module.h
+++ b/src/event/modules/ngx_kqueue_module.h
@@ -10,6 +10,7 @@
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_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 9639a1b..58b8bc8 100644
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -1,5 +1,6 @@
#include <ngx_config.h>
+#include <ngx_core.h>
#include <ngx_types.h>
#include <ngx_log.h>
#include <ngx_time.h>
@@ -7,10 +8,10 @@
#include <ngx_event.h>
#include <ngx_select_module.h>
-static fd_set master_read_fds;
-static fd_set master_write_fds;
-static fd_set work_read_fds;
-static fd_set work_write_fds;
+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;
@@ -23,8 +24,6 @@
static ngx_event_t timer_queue;
-static void ngx_add_timer_core(ngx_event_t *ev, u_int timer);
-
static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event,
ngx_log_t *log);
@@ -42,8 +41,8 @@
exit(1);
}
- FD_ZERO(&master_read_fds);
- FD_ZERO(&master_write_fds);
+ FD_ZERO(&master_read_fd_set);
+ FD_ZERO(&master_write_fd_set);
event_queue.prev = &event_queue;
event_queue.next = &event_queue;
@@ -53,6 +52,7 @@
ngx_event_actions.add = ngx_select_add_event;
ngx_event_actions.del = ngx_select_del_event;
+ ngx_event_actions.timer = ngx_select_add_timer;
ngx_event_actions.process = ngx_select_process_events;
#if (WIN32)
@@ -64,58 +64,76 @@
int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags)
{
- fd_set *fds;
- ngx_connection_t *cn = (ngx_connection_t *) ev->data;
+ ngx_connection_t *c;
- if (event == NGX_TIMER_EVENT) {
- ngx_add_timer_core(ev, flags);
- return 0;
+ c = (ngx_connection_t *) ev->data;
+
+ ngx_log_debug(ev->log, "select fd:%d event:%d" _ c->fd _ event);
+
+#if (WIN32)
+ if ((event == NGX_READ_EVENT) && (max_read >= FD_SETSIZE)
+ || (event == NGX_WRITE_EVENT) && (max_write >= FD_SETSIZE))
+ {
+ ngx_log_error(NGX_LOG_ERR, ev->log, 0,
+ "maximum number of descriptors "
+ "supported by select() is %d", FD_SETSIZE);
+ return NGX_ERROR;
}
- ngx_assert((flags != NGX_ONESHOT_EVENT), return -1, ev->log,
- "ngx_select_add_event: NGX_ONESHOT_EVENT is not supported");
+ if (event == NGX_READ_EVENT) {
+ FD_SET(c->fd, &master_read_fd_set);
+ max_read++;
- fds = ngx_select_get_fd_set(cn->fd, event, ev->log);
- if (fds == NULL)
- return -1;
+ } else if (event == NGX_WRITE_EVENT) {
+ FD_SET(c->fd, &master_write_fd_set);
+ max_write++;
+ }
+#else
+ if (event == NGX_READ_EVENT)
+ FD_SET(c->fd, &master_read_fd_set);
+
+ else if (event == NGX_WRITE_EVENT)
+ FD_SET(c->fd, &master_write_fd_set);
+
+ if (max_fd != -1 && max_fd < c->fd)
+ max_fd = c->fd;
+
+#endif
+
+ ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0;
ev->prev = &event_queue;
ev->next = event_queue.next;
event_queue.next->prev = ev;
event_queue.next = ev;
- FD_SET(cn->fd, fds);
-
-#if (WIN32)
- switch (event) {
- case NGX_READ_EVENT:
- max_read++;
- break;
- case NGX_WRITE_EVENT:
- max_write++;
- break;
- }
-#else
- if (max_fd != -1 && max_fd < cn->fd)
- max_fd = cn->fd;
-#endif
-
- return 0;
+ return NGX_OK;
}
int ngx_select_del_event(ngx_event_t *ev, int event)
{
- fd_set *fds;
- ngx_connection_t *cn = (ngx_connection_t *) ev->data;
+ ngx_connection_t *c;
+ c = (ngx_connection_t *) ev->data;
- if (event == NGX_TIMER_EVENT) {
- ngx_del_timer(ev);
- return 0;
+#if (WIN32)
+ if (event == NGX_READ_EVENT) {
+ FD_CLR(c->fd, &master_read_fd_set);
+ max_read--;
+
+ } else if (event == NGX_WRITE_EVENT) {
+ FD_CLR(c->fd, &master_write_fd_set);
+ max_write--;
}
+#else
+ if (event == NGX_READ_EVENT)
+ FD_CLR(c->fd, &master_read_fd_set);
- fds = ngx_select_get_fd_set(cn->fd, event, ev->log);
- if (fds == NULL)
- return -1;
+ else if (event == NGX_WRITE_EVENT)
+ FD_CLR(c->fd, &master_write_fd_set);
+
+ if (max_fd == c->fd)
+ max_fd = -1;
+#endif
if (ev->prev)
ev->prev->next = ev->next;
@@ -128,70 +146,7 @@
if (ev->prev)
ev->next = NULL;
- FD_CLR(cn->fd, fds);
-
-#if (WIN32)
- switch (event) {
- case NGX_READ_EVENT:
- max_read--;
- break;
- case NGX_WRITE_EVENT:
- max_write--;
- break;
- }
-#else
- if (max_fd == cn->fd)
- max_fd = -1;
-#endif
-
- return 0;
-}
-
-static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event, ngx_log_t *log)
-{
- ngx_log_debug(log, "ngx_select_get_fd_set: %d %d" _ fd _ event);
-
-#if !(WIN32)
- if (fd >= FD_SETSIZE) {
- ngx_log_error(NGX_LOG_ERR, log, 0,
- "ngx_select_get_event: maximum descriptor number"
- "supported by select() is %d",
- FD_SETSIZE - 1);
- return NULL;
- }
-#endif
-
- switch (event) {
- case NGX_READ_EVENT:
-#if (WIN32)
- if (max_read >= FD_SETSIZE) {
- ngx_log_error(NGX_LOG_ERR, log, 0,
- "ngx_select_get_event: maximum number of descriptors "
- "supported by select() is %d",
- FD_SETSIZE);
- return NULL;
- }
-#endif
- return &master_read_fds;
-
- case NGX_WRITE_EVENT:
-#if (WIN32)
- if (max_write >= FD_SETSIZE) {
- ngx_log_error(NGX_LOG_ERR, log, 0,
- "ngx_select_get_event: maximum number of descriptors "
- "supported by select() is %d",
- FD_SETSIZE);
- return NULL;
- }
-#endif
- return &master_write_fds;
-
- default:
- ngx_assert(0, return NULL, log,
- "ngx_select_get_fd_set: invalid event %d" _ event);
- }
-
- return NULL;
+ return NGX_OK;
}
int ngx_select_process_events(ngx_log_t *log)
@@ -199,11 +154,11 @@
int ready, found;
u_int timer, delta;
ngx_event_t *ev, *nx;
- ngx_connection_t *cn;
+ ngx_connection_t *c;
struct timeval tv, *tp;
- work_read_fds = master_read_fds;
- work_write_fds = master_write_fds;
+ work_read_fd_set = master_read_fd_set;
+ work_write_fd_set = master_write_fd_set;
if (timer_queue.timer_next != &timer_queue) {
timer = timer_queue.timer_next->timer_delta;
@@ -222,27 +177,27 @@
#if !(WIN32)
if (max_fd == -1) {
for (ev = event_queue.next; ev != &event_queue; ev = ev->next) {
- cn = (ngx_connection_t *) ev->data;
- if (max_fd < cn->fd)
- max_fd = cn->fd;
+ c = (ngx_connection_t *) ev->data;
+ if (max_fd < c->fd)
+ max_fd = c->fd;
}
- ngx_log_debug(log, "ngx_select_process_events: change max_fd: %d" _
- max_fd);
+ ngx_log_debug(log, "change max_fd: %d" _ max_fd);
}
#endif
ngx_log_debug(log, "ngx_select_process_events: timer: %d" _ timer);
#if (WIN32)
- if ((ready = select(0, &work_read_fds, &work_write_fds, NULL, tp))
+ if ((ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp))
#else
- if ((ready = select(max_fd + 1, &work_read_fds, &work_write_fds, NULL, tp))
+ if ((ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set,
+ NULL, tp))
#endif
== -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
"ngx_select_process_events: select failed");
- return -1;
+ return NGX_ERROR;
}
ngx_log_debug(log, "ngx_select_process_events: ready %d" _ ready);
@@ -251,7 +206,7 @@
delta = ngx_msec() - delta;
} else {
- ngx_assert((ready != 0), return -1, log,
+ ngx_assert((ready != 0), return NGX_ERROR, log,
"ngx_select_process_events: "
"select returns no events without timeout");
}
@@ -268,14 +223,9 @@
delta -= ev->timer_delta;
nx = ev->timer_next;
ngx_del_timer(ev);
-#if 1
ev->timedout = 1;
if (ev->event_handler(ev) == -1)
ev->close_handler(ev);
-#else
- if (ev->timer_handler(ev) == -1)
- ev->close_handler(ev);
-#endif
ev = nx;
}
@@ -285,26 +235,35 @@
}
for (ev = event_queue.next; ev != &event_queue; ev = ev->next) {
- cn = (ngx_connection_t *) ev->data;
+ c = (ngx_connection_t *) ev->data;
found = 0;
if (ev->write) {
- if (FD_ISSET(cn->fd, &work_write_fds)) {
+ if (FD_ISSET(c->fd, &work_write_fd_set)) {
ngx_log_debug(log, "ngx_select_process_events: write %d" _
- cn->fd);
+ c->fd);
found = 1;
}
} else {
- if (FD_ISSET(cn->fd, &work_read_fds)) {
+ if (FD_ISSET(c->fd, &work_read_fd_set)) {
ngx_log_debug(log, "ngx_select_process_events: read %d" _
- cn->fd);
+ c->fd);
found = 1;
}
}
if (found) {
ev->ready = 1;
+
+ if (ev->oneshot) {
+ ngx_del_timer(ev);
+ if (ev->write)
+ ngx_select_del_event(ev, NGX_WRITE_EVENT);
+ else
+ ngx_select_del_event(ev, NGX_READ_EVENT);
+ }
+
if (ev->event_handler(ev) == -1)
ev->close_handler(ev);
@@ -313,13 +272,13 @@
}
- ngx_assert((ready == 0), return 0, log,
+ ngx_assert((ready == 0), /* void */ ; , log,
"ngx_select_process_events: ready != events");
- return 0;
+ return NGX_OK;
}
-static void ngx_add_timer_core(ngx_event_t *ev, u_int timer)
+void ngx_select_add_timer(ngx_event_t *ev, ngx_msec_t timer)
{
ngx_event_t *e;
@@ -336,19 +295,3 @@
e->timer_prev->timer_next = ev;
e->timer_prev = ev;
}
-
-#if 0
-static void ngx_inline ngx_del_timer(ngx_event_t *ev)
-{
- if (ev->timer_prev)
- ev->timer_prev->timer_next = ev->timer_next;
-
- if (ev->timer_next) {
- ev->timer_next->timer_prev = ev->timer_prev;
- ev->timer_next = NULL;
- }
-
- if (ev->timer_prev)
- ev->timer_prev = NULL;
-}
-#endif
diff --git a/src/event/modules/ngx_select_module.h b/src/event/modules/ngx_select_module.h
index 6516981..ea08591 100644
--- a/src/event/modules/ngx_select_module.h
+++ b/src/event/modules/ngx_select_module.h
@@ -10,6 +10,7 @@
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_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 0d02dfe..5b4fc0b 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -1,6 +1,7 @@
#include <ngx_config.h>
#include <ngx_types.h>
+#include <ngx_string.h>
#include <ngx_log.h>
#include <ngx_alloc.h>
#include <ngx_listen.h>
@@ -19,7 +20,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;
@@ -78,7 +79,10 @@
ngx_connections[fd].handler = s[i].handler;
ngx_connections[fd].log = s[i].log;
- ngx_read_events[fd].log = ngx_connections[fd].log;
+ ngx_test_null(ngx_read_events[fd].log,
+ ngx_palloc(pool, sizeof(ngx_log_t)), /* void */ ; );
+ ngx_memcpy(ngx_read_events[fd].log, ngx_connections[fd].log,
+ sizeof(ngx_log_t));
ngx_read_events[fd].data = &ngx_connections[fd];
ngx_read_events[fd].event_handler = &ngx_event_accept;
ngx_read_events[fd].listening = 1;
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 9e4bc02..bf19f6c 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -4,6 +4,7 @@
#include <ngx_config.h>
#include <ngx_types.h>
+#include <ngx_time.h>
#include <ngx_socket.h>
#include <ngx_log.h>
#include <ngx_alloc.h>
@@ -40,11 +41,16 @@
/* accept: 1 if accept many, 0 otherwise */
/* flags - int are probably faster on write then bits ??? */
+#if !(USE_KQUEUE)
+ unsigned oneshot:1;
+#endif
unsigned listening:1;
unsigned write:1;
unsigned ready:1;
unsigned timedout:1;
+ unsigned blocked:1;
+
unsigned process:1;
unsigned read_discarded:1;
@@ -72,6 +78,7 @@
typedef struct {
int (*add)(ngx_event_t *ev, int event, u_int flags);
int (*del)(ngx_event_t *ev, int event);
+ 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);
/*
@@ -93,21 +100,22 @@
#define NGX_READ_EVENT EVFILT_READ
#define NGX_WRITE_EVENT EVFILT_WRITE
-#define NGX_TIMER_EVENT (-EVFILT_SYSCOUNT - 1)
#define NGX_LEVEL_EVENT 0
#define NGX_ONESHOT_EVENT EV_ONESHOT
+
+#ifndef HAVE_CLEAR_EVENT
+#define HAVE_CLEAR_EVENT 1
#define NGX_CLEAR_EVENT EV_CLEAR
+#endif
#else
#define NGX_READ_EVENT 0
#define NGX_WRITE_EVENT 1
-#define NGX_TIMER_EVENT 2
#define NGX_LEVEL_EVENT 0
#define NGX_ONESHOT_EVENT 1
-#define NGX_CLEAR_EVENT 2
#endif
@@ -116,8 +124,11 @@
#define ngx_init_events ngx_kqueue_init
#define ngx_process_events ngx_kqueue_process_events
-#define ngx_add_event ngx_kqueue_add_event
-#define ngx_del_event ngx_kqueue_del_event
+#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_timer ngx_kqueue_add_timer
#define ngx_event_recv ngx_event_recv_core
#else
@@ -126,13 +137,12 @@
#define ngx_process_events ngx_event_actions.process
#define ngx_add_event ngx_event_actions.add
#define ngx_del_event ngx_event_actions.del
+#define ngx_add_timer ngx_event_actions.timer
#define ngx_event_recv ngx_event_recv_core
#endif
-#define ngx_add_timer(ev, time) ngx_add_event(ev, NGX_TIMER_EVENT, time)
-
static void ngx_inline ngx_del_timer(ngx_event_t *ev)
{
if (ev->timer_prev)
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index 9db1bbd..fd36e35 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -63,7 +63,8 @@
ngx_connections[s].write = &ngx_write_events[s];
ngx_connections[s].fd = s;
- ngx_read_events[s].unexpected_eof = 1;
+ ngx_connections[s].unexpected_eof = 1;
+ ngx_write_events[s].write = 1;
ngx_write_events[s].ready = 1;
ngx_write_events[s].timer = ngx_read_events[s].timer = 10000;
diff --git a/src/event/ngx_event_write.c b/src/event/ngx_event_write.c
index b8411a4..97c0827 100644
--- a/src/event/ngx_event_write.c
+++ b/src/event/ngx_event_write.c
@@ -1,5 +1,6 @@
#include <ngx_config.h>
+#include <ngx_core.h>
#include <ngx_types.h>
#include <ngx_alloc.h>
#include <ngx_array.h>
@@ -10,7 +11,7 @@
#include <ngx_event_write.h>
-ngx_chain_t *ngx_event_write(ngx_connection_t *cn, ngx_chain_t *in,
+ngx_chain_t *ngx_event_write(ngx_connection_t *c, ngx_chain_t *in,
off_t flush)
{
int rc;
@@ -24,10 +25,10 @@
ch = in;
file = NULL;
- ngx_test_null(header, ngx_create_array(cn->pool, 10, sizeof(ngx_iovec_t)),
+ ngx_test_null(header, ngx_create_array(c->pool, 10, sizeof(ngx_iovec_t)),
(ngx_chain_t *) -1);
- ngx_test_null(trailer, ngx_create_array(cn->pool, 10, sizeof(ngx_iovec_t)),
+ ngx_test_null(trailer, ngx_create_array(c->pool, 10, sizeof(ngx_iovec_t)),
(ngx_chain_t *) -1);
do {
@@ -62,7 +63,7 @@
#if (HAVE_MAX_SENDFILE_IOVEC)
if (file && header->nelts > HAVE_MAX_SENDFILE_IOVEC) {
- rc = ngx_sendv(cn->fd, (ngx_iovec_t *) header->elts, header->nelts,
+ rc = ngx_sendv(c->fd, (ngx_iovec_t *) header->elts, header->nelts,
&sent);
} else {
#endif
@@ -90,44 +91,57 @@
}
if (file) {
- rc = ngx_sendfile(cn->fd,
+ rc = ngx_sendfile(c->fd,
(ngx_iovec_t *) header->elts, header->nelts,
- file->fd, file->pos.file,
+ file->file->fd, file->pos.file,
(size_t) (file->last.file - file->pos.file),
(ngx_iovec_t *) trailer->elts, trailer->nelts,
- &sent, cn->log);
+ &sent, c->log);
} else {
- rc = ngx_sendv(cn->fd, (ngx_iovec_t *) header->elts,
- header->nelts, (size_t *) &sent);
- ngx_log_debug(cn->log, "sendv: %d" _ sent);
+ size_t sendv_sent;
+
+ sendv_sent = 0;
+ rc = ngx_sendv(c->fd, (ngx_iovec_t *) header->elts,
+ header->nelts, &sendv_sent);
+ sent = sendv_sent;
+ ngx_log_debug(c->log, "sendv: " QD_FMT _ sent);
}
#if (HAVE_MAX_SENDFILE_IOVEC)
}
#endif
/* save sent for logging */
- if (rc == -1)
+ if (rc == NGX_ERROR)
return (ngx_chain_t *) -1;
+ c->sent = sent;
flush -= sent;
for (ch = in; ch; ch = ch->next) {
+
+ ngx_log_debug(c->log, "ch event write: %x %qx %qd" _
+ ch->hunk->type _
+ ch->hunk->pos.file _
+ ch->hunk->last.file - ch->hunk->pos.file);
+
if (sent >= ch->hunk->last.file - ch->hunk->pos.file) {
sent -= ch->hunk->last.file - ch->hunk->pos.file;
- ch->hunk->last.file = ch->hunk->pos.file;
+ ch->hunk->pos.file = ch->hunk->last.file;
- ngx_log_debug(cn->log, "event write: %qx 0" _
- ch->hunk->pos.file);
+ ngx_log_debug(c->log, "event write: " QX_FMT " 0 " QD_FMT _
+ ch->hunk->pos.file _ sent);
+/*
if (ch->hunk->type & NGX_HUNK_LAST)
break;
+*/
continue;
}
ch->hunk->pos.file += sent;
- ngx_log_debug(cn->log, "event write: %qx %qd" _
+ ngx_log_debug(c->log, "event write: %qx %qd" _
ch->hunk->pos.file _
ch->hunk->last.file - ch->hunk->pos.file);
@@ -135,7 +149,7 @@
}
/* flush hunks if threaded state */
- } while (cn->write->context && flush > 0);
+ } while (c->write->context && flush > 0);
ngx_destroy_array(trailer);
ngx_destroy_array(header);
diff --git a/src/http/modules/ngx_http_header_filter.c b/src/http/modules/ngx_http_header_filter.c
index efe0744..9cb1f4c 100644
--- a/src/http/modules/ngx_http_header_filter.c
+++ b/src/http/modules/ngx_http_header_filter.c
@@ -2,6 +2,7 @@
#include <nginx.h>
#include <ngx_config.h>
+#include <ngx_core.h>
#include <ngx_string.h>
#include <ngx_hunk.h>
#include <ngx_http.h>
@@ -25,12 +26,8 @@
ngx_hunk_t *h;
ngx_chain_t *ch;
- ngx_test_null(h, ngx_get_hunk(r->pool, 1024, 0, 64),
- /* STUB */
- -1);
-/*
- NGX_HTTP_FILTER_ERROR);
-*/
+ ngx_test_null(h, ngx_create_temp_hunk(r->pool, 1024, 0, 64),
+ NGX_ERROR);
status = r->headers_out->status - NGX_HTTP_OK;
diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c
index 20d0b9e..0900a42 100644
--- a/src/http/modules/ngx_http_static_handler.c
+++ b/src/http/modules/ngx_http_static_handler.c
@@ -26,7 +26,7 @@
{
int rc;
ngx_hunk_t *h;
- ngx_chain_t *ch;
+ ngx_http_log_ctx_t *ctx;
/*
ngx_http_event_static_handler_loc_conf_t *cf;
@@ -36,6 +36,10 @@
*/
+ ngx_http_discard_body(r);
+ ctx = r->connection->log->data;
+ ctx->action = "sending response";
+
r->fd = ngx_open_file(r->filename, NGX_FILE_RDONLY);
if (r->fd == -1) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
@@ -45,7 +49,7 @@
return -1;
}
- if (ngx_stat_fd(r->fd, &r->file_info) == -1) {
+ if (ngx_stat_fd(r->fd, &r->fileinfo) == -1) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
"ngx_http_static_handler: "
ngx_stat_fd_n " %s failed", r->filename);
@@ -54,9 +58,9 @@
}
r->headers_out->status = NGX_HTTP_OK;
- r->headers_out->content_length = ngx_file_size(r->file_info);
+ r->headers_out->content_length = ngx_file_size(r->fileinfo);
/*
- r->headers_out->last_modified = ngx_file_mtime(r->file_info);
+ r->headers_out->last_modified = ngx_file_mtime(r->fileinfo);
*/
/* STUB */
@@ -73,39 +77,22 @@
/* TODO: NGX_HTTP_INTERNAL_SERVER_ERROR is too late */
/* STUB */
- ngx_test_null(h, ngx_get_hunk(r->pool, 1024, 0, 64),
- /* STUB */
- -1);
-/*
- ngx_test_null(h, ngx_create_hunk(r->pool), NGX_HTTP_INTERNAL_SERVER_ERROR);
-*/
- h->type = NGX_HUNK_FILE|NGX_HUNK_LAST;
- h->fd = r->fd;
- h->pos.file = 0;
- h->last.file = ngx_file_size(r->file_info);
-
- /* STUB */
- ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)),
- /* STUB */
- -1);
-/*
- NGX_HTTP_FILTER_ERROR);
-*/
-
-/*
- ngx_test_null(ch, ngx_create_chain(r->pool),
+ ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)),
NGX_HTTP_INTERNAL_SERVER_ERROR);
-*/
- ch->hunk = h;
- ch->next = NULL;
+
+ h->type = NGX_HUNK_FILE|NGX_HUNK_LAST;
+ h->pos.file = 0;
+ h->last.file = ngx_file_size(r->fileinfo);
/* STUB */
- rc = ngx_http_write_filter(r, ch);
- ngx_log_debug(r->connection->log, "write_filter: %d" _ rc);
+ ngx_test_null(h->file, ngx_pcalloc(r->pool, sizeof(ngx_file_t)),
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
+ h->file->fd = r->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;
-/*
- return ngx_http_filter(r, ch);
-*/
}
#if 0
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index 5410d31..7e8cad5 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -1,6 +1,7 @@
#include <ngx_config.h>
#include <ngx_string.h>
+#include <ngx_socket.h>
#include <ngx_listen.h>
#include <ngx_http.h>
@@ -17,8 +18,11 @@
{
ngx_listen_t *ls;
+ ngx_http_server.request_pool_size = 16384;
ngx_http_server.header_timeout = 20000;
- ngx_http_server.buff_size = 1024;
+ ngx_http_server.header_buffer_size = 1024;
+ ngx_http_server.discarded_buffer_size = 1500;
+
#if (WIN32)
ngx_http_server.doc_root = "html";
#else
@@ -26,8 +30,11 @@
#endif
ngx_http_server.doc_root_len = strlen(ngx_http_server.doc_root) + 1;
+
+ ngx_http_output_filter_init();
ngx_http_write_filter_init();
+
ls = ngx_push_array(ngx_listening_sockets);
ngx_memzero(ls, sizeof(ngx_listen_t));
@@ -57,6 +64,7 @@
ls->server = &ngx_http_server;
ls->log = log;
+
return 1;
}
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index fe89874..3b943d6 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -5,7 +5,7 @@
#include <ngx_config.h>
#include <ngx_types.h>
#include <ngx_hunk.h>
-#include <ngx_file.h>
+#include <ngx_files.h>
#include <ngx_connection.h>
@@ -25,6 +25,7 @@
#define NGX_HTTP_OK 200
+#define NGX_HTTP_SPECIAL_RESPONSE 300
#define NGX_HTTP_MOVED_PERMANENTLY 302
#define NGX_HTTP_BAD_REQUEST 400
#define NGX_HTTP_NOT_FOUND 404
@@ -45,7 +46,11 @@
typedef struct {
char *doc_root;
size_t doc_root_len;
- size_t buff_size;
+
+ size_t request_pool_size;
+
+ size_t header_buffer_size;
+ size_t discarded_buffer_size;
unsigned int header_timeout;
} ngx_http_server_t;
@@ -88,7 +93,7 @@
int filename_len;
int (*handler)(ngx_http_request_t *r);
- ngx_file_info_t file_info;
+ ngx_file_info_t fileinfo;
int method;
@@ -104,7 +109,11 @@
int filter;
+ ssize_t client_content_length;
+ char *discarded_buffer;
+
unsigned header_timeout:1;
+ unsigned process_header:1;
unsigned header_only:1;
unsigned unusual_uri:1;
@@ -134,6 +143,9 @@
#define NGX_INDEX "index.html"
+/* STUB */
+int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log);
+
int ngx_http_init_connection(ngx_connection_t *c);
diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c
index 63fc29a..7783462 100644
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_event.c
@@ -2,7 +2,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_string.h>
-#include <ngx_file.h>
+#include <ngx_files.h>
#include <ngx_log.h>
#include <ngx_alloc.h>
#include <ngx_hunk.h>
@@ -10,6 +10,12 @@
#include <ngx_http.h>
+/* STUB */
+#include <ngx_http_output_filter.h>
+
+int ngx_http_static_handler(ngx_http_request_t *r);
+
+
int ngx_http_init_connection(ngx_connection_t *c);
static int ngx_http_init_request(ngx_event_t *ev);
@@ -17,8 +23,19 @@
static int ngx_http_process_request_line(ngx_http_request_t *r);
static int ngx_http_process_request_header(ngx_http_request_t *r);
+static int ngx_http_process_request_header_line(ngx_http_request_t *r);
-static int ngx_http_process_http_request(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_handler(ngx_http_request_t *r);
+static int ngx_http_set_default_handler(ngx_http_request_t *r);
+
+static int ngx_http_writer(ngx_event_t *ev);
+
+static int ngx_http_special_response(ngx_http_request_t *r, int error);
+static int ngx_http_redirect(ngx_http_request_t *r, int redirect);
+static int ngx_http_error(ngx_http_request_t *r, int error);
static int ngx_http_close_request(ngx_http_request_t *r);
static size_t ngx_http_log_error(void *data, char *buf, size_t len);
@@ -54,8 +71,15 @@
ngx_test_null(c->addr_text, ngx_palloc(c->pool, c->addr_textlen),
NGX_ERROR);
+#if (WIN32)
+/*
+ c->addr_text = inet_ntoa((struct in_addr) ((char *)c->sockaddr + c->addr));
+*/
+ c->addr_text = NULL;
+#else
inet_ntop(c->family, (char *)c->sockaddr + c->addr,
c->addr_text, c->addr_textlen);
+#endif
ngx_test_null(ctx, ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)),
NGX_ERROR);
@@ -107,22 +131,22 @@
r->connection = c;
r->server = srv;
- /* TODO: request's pool size */
- ngx_test_null(r->pool, ngx_create_pool(16384, ev->log),
+ ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log),
ngx_http_close_request(r));
ngx_test_null(r->header_in,
- ngx_create_temp_hunk(r->pool, srv->buff_size, 0, 0),
+ ngx_create_temp_hunk(r->pool, srv->header_buffer_size, 0, 0),
ngx_http_close_request(r));
ev->event_handler = ngx_http_process_request;
r->state_handler = ngx_http_process_request_line;
+ r->process_header = 1;
return ngx_http_process_request(ev);
}
-int ngx_http_process_request(ngx_event_t *ev)
+static int ngx_http_process_request(ngx_event_t *ev)
{
int n, rc;
ngx_connection_t *c ;
@@ -151,11 +175,9 @@
ngx_log_debug(ev->log, "http read %d" _ n);
if (n == 0) {
- /* STUB: c-> */
- if (ev->unexpected_eof)
+ if (c->unexpected_eof)
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client prematurely closed connection");
-
return ngx_http_close_request(r);
}
@@ -173,8 +195,9 @@
/* rc == NGX_OK || rc == NGX_AGAIN */
- } while (r->header_in->pos.mem < r->header_in->last.mem);
-
+ } while (r->process_header
+ && r->header_in->pos.mem < r->header_in->last.mem);
+
if (!r->header_timeout) {
r->header_timeout = 1;
ngx_del_timer(ev);
@@ -200,27 +223,23 @@
ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s" _
r->method _ r->http_version _ r->uri);
- if (r->http_version == 9) {
- /* set lock event */
- return ngx_http_process_http_request(r);
- }
+ if (r->http_version == 9)
+ return ngx_http_handler(r);
r->state_handler = ngx_http_process_request_header;
- r->connection->read->action = "reading client request headers";
+ ctx = r->connection->log->data;
+ ctx->action = "reading client request headers";
return NGX_OK;
}
- r->connection->log->handler = NULL;
ctx = r->connection->log->data;
-
+ r->connection->log->handler = NULL;
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
header_errors[rc - NGX_HTTP_INVALID_METHOD], ctx->client);
-
r->connection->log->handler = ngx_http_log_error;
- /* STUB return ngx_http_error(r, NGX_HTTP_BAD_REQUEST) */
- return ngx_http_close_request(r);
+ return ngx_http_error(r, NGX_HTTP_BAD_REQUEST);
}
static int ngx_http_process_request_header(ngx_http_request_t *r)
@@ -232,63 +251,192 @@
rc = ngx_read_http_header_line(r);
if (rc == NGX_OK) {
- *r->header_name_end = '\0';
- *r->header_end = '\0';
- ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'" _
- r->header_name_start _ r->header_start);
+ if (ngx_http_process_request_header_line(r) == NGX_ERROR)
+ return ngx_http_error(r, NGX_HTTP_BAD_REQUEST);
+
+ } else if (rc == NGX_HTTP_HEADER_DONE) {
+ ngx_log_debug(r->connection->log, "HTTP header done");
+ return ngx_http_handler(r);
} else if (rc == NGX_AGAIN) {
return NGX_AGAIN;
- } else if (rc == NGX_HTTP_HEADER_DONE) {
- break;
-
} else if (rc == NGX_HTTP_INVALID_HEADER) {
- r->connection->log->handler = NULL;
ctx = r->connection->log->data;
+ r->connection->log->handler = NULL;
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client %s sent invalid header", ctx->client);
r->connection->log->handler = ngx_http_log_error;
- /* STUB return ngx_http_error(r, NGX_HTTP_BAD_REQUEST) */
- return ngx_http_close_request(r);
+ return ngx_http_error(r, NGX_HTTP_BAD_REQUEST);
}
}
+}
- r->state_handler = NULL;
- r->connection->read->action = "reading client request body";
+static int ngx_http_process_request_header_line(ngx_http_request_t *r)
+{
+ /* STUB */
+ *r->header_name_end = '\0';
+ *r->header_end = '\0';
+ ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'" _
+ r->header_name_start _ r->header_start);
- r->connection->read->read_discarded = 1;
- r->connection->read->unexpected_eof = 0;
- ngx_log_debug(r->connection->log, "HTTP header done");
+ return NGX_OK;
+}
+
+static int ngx_http_block_read(ngx_event_t *ev)
+{
+ ngx_log_debug(ev->log, "http read blocked");
+
+ ngx_del_event(ev, NGX_READ_EVENT);
+ ev->blocked = 1;
+}
+
+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);
- return ngx_http_process_http_request(r);
+ if (r->client_content_length)
+ r->connection->read->event_handler = ngx_http_read_discarded_body;
}
-#if 0
-static int ngx_http_lock_read(ngx_event_t *ev)
+static int ngx_http_read_discarded_body(ngx_event_t *ev)
{
- ngx_del_event(ev, NGX_READ_EVENT);
- ev->read_blocked = 1;
-}
-#endif
+ size_t size;
+ ssize_t n;
+ ngx_connection_t *c;
+ ngx_http_request_t *r;
-static int ngx_http_process_http_request(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 > 0)
+ r->client_content_length -= n;
+
+ return n;
+}
+
+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;
+}
+
+static int ngx_http_handler(ngx_http_request_t *r)
+{
+ int rc;
+
+ ngx_del_timer(r->connection->read);
+ r->header_timeout = 1;
+
+ r->process_header = 0;
+ r->state_handler = NULL;
+ r->connection->unexpected_eof = 0;
+
+ r->connection->read->event_handler = ngx_http_block_read;
+
+ /* STUB: should find handler */
+ r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
+ rc = ngx_http_set_default_handler(r);
+
+ if (rc >= NGX_HTTP_SPECIAL_RESPONSE)
+ return ngx_http_special_response(r, rc);
+
+ rc = r->handler(r);
+
+ /* transfer not completed */
+ if (rc == NGX_AGAIN) {
+#if (HAVE_CLEAR_EVENT)
+ if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
+ NGX_CLEAR_EVENT) == NGX_ERROR) {
+#else
+ if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
+ NGX_ONESHOT_EVENT) == NGX_ERROR) {
+#endif
+ /* log http request */
+ return ngx_http_close_request(r);
+ }
+
+ ngx_add_timer(r->connection->write, 5000);
+
+ r->connection->write->event_handler = ngx_http_writer;
+ return rc;
+ }
+
+ if (rc == NGX_ERROR) {
+ /* log http request */
+ return ngx_http_close_request(r);
+ }
+
+ if (rc >= NGX_HTTP_SPECIAL_RESPONSE)
+ return ngx_http_special_response(r, rc);
+
+ /* rc == NGX_OK */
+
+ /* STUB */
+ return ngx_http_close_request(r);
+
+/*
+ if (!keepalive)
+ if (linger)
+ set linger timeout on read
+ shutdown socket
+ else
+ close socket
+*/
+}
+
+static int ngx_http_set_default_handler(ngx_http_request_t *r)
{
int err, rc;
char *name, *loc, *file;
- ngx_log_debug(r->connection->log, "HTTP request");
-
ngx_test_null(r->headers_out,
ngx_pcalloc(r->pool, sizeof(ngx_http_headers_out_t)),
- ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR));
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
if (*(r->uri_end - 1) == '/') {
- r->handler = NGX_HTTP_DIRECTORY_HANDLER;
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+#if 0
+ r->handler = ngx_http_index_handler;
return NGX_OK;
+#endif
}
/* 20 bytes is spare space for some index name, i.e. index.html */
@@ -296,7 +444,7 @@
ngx_test_null(r->filename,
ngx_palloc(r->pool, r->filename_len),
- ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR));
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
r->location = ngx_cpystrn(r->filename, r->server->doc_root,
r->server->doc_root_len);
@@ -305,99 +453,73 @@
ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->filename);
- if (ngx_file_type(r->filename, &r->file_info) == -1) {
+ if (ngx_file_type(r->filename, &r->fileinfo) == -1) {
err = ngx_errno;
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
- "ngx_process_http_request: "
ngx_file_type_n " %s failed", r->filename);
if (err == NGX_ENOENT)
- return ngx_http_error(r, NGX_HTTP_NOT_FOUND);
+ return NGX_HTTP_NOT_FOUND;
else
- return ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- if (ngx_is_dir(r->file_info)) {
+ 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_redirect(r, NGX_HTTP_MOVED_PERMANENTLY);
+ return NGX_HTTP_MOVED_PERMANENTLY;
}
- /* STUB */
- rc = ngx_http_static_handler(r);
- if (rc == 0) {
- r->connection->write->event_handler = ngx_http_writer;
- ngx_add_event(r->connection->write, NGX_WRITE_EVENT, NGX_CLEAR_EVENT);
- }
- return rc;
+ r->handler = ngx_http_static_handler;
- r->handler = NGX_HTTP_STATIC_HANDLER;
return NGX_OK;
}
-#if 0
-
-static int ngx_http_handler(ngx_http_request_t *r)
-{
- find_http_handler();
-
- if (r->discard_body && r->connection->read->ready)
- ngx_http_discarad_body();
-
- rc = http_handler();
-
- /* transfer not completed */
- if (rc == NGX_AGAIN)
- return rc;
-
- if (rc == NGX_ERROR) {
- log http request
- close http request
- return rc;
- }
-
- if (rc > 300) {
- send special response
- }
-
- /* rc == NGX_OK */
-
- if (!keepalive)
- if (linger)
- set linger timeout on read
- shutdown socket
- else
- close socket
-
- log http request
- close http request
- if (keepalive)
- return NGX_OK;
- else
- close connection
- return NGX_OK;
-}
static int ngx_http_writer(ngx_event_t *ev)
{
int rc;
+ unsigned int timeout;
+ ngx_connection_t *c;
+ ngx_http_request_t *r;
- ngx_connection_t *c = (ngx_connection_t *) ev->data;
- ngx_http_request_t *r = (ngx_http_request_t *) c->data;
+ c = (ngx_connection_t *) ev->data;
+ r = (ngx_http_request_t *) c->data;
- rc = ngx_http_filter(r, NULL);
+ rc = ngx_http_output_filter(r, NULL);
- if (rc == NGX_AGAIN)
+ ngx_log_debug(ev->log, "output_filter: %d" _ rc);
+
+ if (rc == NGX_AGAIN) {
+
+ if (c->sent > 0) {
+ ngx_log_debug(ev->log, "sent: " QD_FMT _ c->sent);
+ timeout = (ngx_msec_t) (c->sent * 10);
+ ngx_log_debug(ev->log, "timeout: %d" _ timeout);
+ ngx_del_timer(ev);
+ ngx_add_timer(ev, timeout);
+ }
+
+ if (ev->oneshot)
+ if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
+ NGX_ONESHOT_EVENT) == NGX_ERROR) {
+ /* log http request */
+ return ngx_http_close_request(r);
+ }
+
return rc;
+ }
if (rc == NGX_ERROR)
return rc;
/* rc == NGX_OK */
+ return ngx_http_close_request(r);
+/*
if (!keepalive)
if (linger)
shutdown socket
@@ -411,19 +533,10 @@
else
close connection
return NGX_OK;
+*/
}
-static int ngx_http_discarded_read(ngx_event_t *ev)
-{
- if (ev->timedout)
- return NGX_ERROR;
-
- while (full) {
- recv();
- }
-
- return NGX_OK;
-}
+#if 0
static int ngx_http_keepalive_handler(ngx_event_t *ev)
{
@@ -446,40 +559,28 @@
#endif
-static int ngx_http_writer(ngx_event_t *ev)
+static int ngx_http_special_response(ngx_http_request_t *r, int error)
{
- int rc;
- ngx_connection_t *c = (ngx_connection_t *) ev->data;
- ngx_http_request_t *r = (ngx_http_request_t *) c->data;
-
- rc = ngx_http_write_filter(r, NULL);
- ngx_log_debug(r->connection->log, "write_filter: %d" _ rc);
- return rc;
-}
-
-static int ngx_http_handler(ngx_http_request_t *r, int handler)
-{
- if (handler == NGX_HTTP_STATIC_HANDLER)
- return ngx_http_static_handler(r);
-
-#if 0
- elsif (handler == NGX_HTTP_DIRECTORY_HANDLER)
- return ngx_http_index_handler(r);
-#endif
-
- return ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return ngx_http_error(r, error);
}
static int ngx_http_redirect(ngx_http_request_t *r, int redirect)
{
/* STUB */
- return -1;
+
+ /* log request */
+
+ return ngx_http_close_request(r);
}
static int ngx_http_error(ngx_http_request_t *r, int error)
{
/* STUB */
- return -1;
+ ngx_log_debug(r->connection->log, "http error: %d" _ error);
+
+ /* log request */
+
+ return ngx_http_close_request(r);
}
#if 0
@@ -549,8 +650,8 @@
ngx_log_debug(r->connection->log, "http close");
- ngx_del_event(r->connection->read, NGX_TIMER_EVENT);
- ngx_del_event(r->connection->write, NGX_TIMER_EVENT);
+ ngx_del_timer(r->connection->read);
+ ngx_del_timer(r->connection->write);
return NGX_ERROR;
}
@@ -559,6 +660,7 @@
static size_t ngx_http_log_error(void *data, char *buf, size_t len)
{
ngx_http_log_ctx_t *ctx = (ngx_http_log_ctx_t *) data;
+
if (ctx->url)
return ngx_snprintf(buf, len, " while %s, client: %s, URL: %s",
ctx->action, ctx->client, ctx->url);
diff --git a/src/http/ngx_http_filter.c b/src/http/ngx_http_filter.c
deleted file mode 100644
index 6f39d9b..0000000
--- a/src/http/ngx_http_filter.c
+++ /dev/null
@@ -1,236 +0,0 @@
-
-
-#include <ngx_hunk.h>
-#include <ngx_http.h>
-#include <ngx_http_filter.h>
-
-
-ngx_http_module_t ngx_http_filter_module;
-
-
-/* STUB */
-static ngx_http_filter_ctx_t module_ctx;
-
-void ngx_http_filter_init()
-{
- module_ctx.hunk_size = 32 * 1024;
- module_ctx.out.hunk = NULL;
- module_ctx.out.next = NULL;
- module_ctx.next_filter = ngx_http_write_filter;
-
- ngx_http_filter_module.ctx = &module_ctx;
-}
-/* */
-
-
-/*
-int ngx_http_filter(ngx_http_request_t *r, ngx_chain_t *in)
-*/
-
-/*
- flags NGX_HUNK_RECYCLED, NGX_HUNK_FLUSH, NGX_HUNK_LAST
-*/
-
-int ngx_http_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
-{
- int rc;
- size_t size;
- ssize_t n;
- ngx_chain_t *ce;
- ngx_http_filter_ctx_t *ctx;
-
- ctx = (ngx_http_filter_ctx_t *)
- ngx_get_module_ctx(r->main ? r->main : r,
- &ngx_http_filter_module);
-
- if (hunk && (hunk->type & NGX_HUNK_LAST))
- ctx->last = 1;
-
- /* input chain is not empty */
- if (ctx->in) {
-
- while (ctx->in) {
-
- /* add hunk to input chain */
- if (hunk) {
- for (ce = ctx->in; ce->next; ce = ce->next)
- /* void */ ;
-
- ngx_add_hunk_to_chain(ce->next, hunk, r->pool,
- NGX_ERROR);
- }
-
- /* our hunk is still busy */
- if (ctx->hunk->pos.mem < ctx->hunk->last.mem) {
- rc = ctx->next_filter(r, NULL);
-
- /* our hunk is free */
- } else {
- ctx->out.hunk = ctx->hunk;
-
- rc = ngx_http_filter_copy_hunk(ctx->hunk, ctx->in->hunk);
-#if (NGX_FILE_AIO)
- if (rc == NGX_AGAIN)
- return rc;
-#endif
- if (rc == NGX_ERROR)
- return rc;
-
- /* whole hunk is copied so we send to next filter chain part
- up to next hunk that need to be copied */
- if (ctx->in->hunk->pos.mem == ctx->in->hunk->last.mem) {
- ctx->out.next = ctx->in->next;
-
- for (ce = ctx->in->next; ce; ce = ce->next) {
- if (ce->type & NGX_HUNK_FILE)
- break;
-
- if ((ce->type & NGX_HUNK_MEMORY|NGX_HUNK_MMAP)
- && (r->filter & NGX_HTTP_FILTER_NEED_TEMP))
- break;
- }
-
- ctx->out.next = ce;
-
- } else {
- ctx->out.next = NULL;
- }
-
- rc = ctx->next_filter(r, &ctx->out);
- }
-
- if (rc == NGX_OK)
- ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
- else
- return rc;
- }
-
- /* input chain is empty */
- } else {
-
- if (hunk == NULL) {
- rc = ctx->next_filter(r, NULL);
-
- } else {
-
- /* we need to copy hunk to our hunk */
- 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))
- ) {
-
- /* out hunk is still busy */
- if (ctx->hunk && ctx->hunk->pos.mem < ctx->hunk->last.mem) {
- ngx_add_hunk_to_chain(ctx->in, hunk, r->pool,
- NGX_ERROR);
-
- rc = ctx->next_filter(r, NULL);
-
- } else {
- if (ctx->hunk == NULL) {
-
- if (hunk->type & NGX_HUNK_LAST) {
- size = hunk->last.mem - hunk->pos.mem;
- if (size > ctx->hunk_size)
- size = ctx->hunk_size;
-
- } else {
- size = ctx->hunk_size;
- }
-
- ngx_test_null(ctx->hunk,
- ngx_create_temp_hunk(r->pool, size,
- 50, 50),
- NGX_ERROR);
-
- rc = ngx_http_filter_copy_hunk(ctx->hunk,
- ctx->in->hunk);
-#if (NGX_FILE_AIO)
- if (rc == NGX_AGAIN) {
- /* add hunk to input chain */
- ngx_add_hunk_to_chain(ctx->in, hunk, r->pool,
- NGX_ERROR);
-
- return rc;
- }
-#endif
- if (rc == NGX_ERROR)
- return rc;
-
- if (ctx->in->hunk->pos.mem < ctx->in->hunk->last.mem)
- ngx_add_hunk_to_chain(ctx->in, hunk, r->pool,
- NGX_ERROR);
-
- ctx->out.hunk = ctx->hunk;
- ctx->out.next = NULL;
-
- rc = ctx->next_filter(r, &ctx->out);
- }
- }
-
- } else {
- ctx->out.hunk = hunk;
- ctx->out.next = NULL;
-
- rc = ctx->next_filter(r, &ctx->out);
-
- }
- }
- }
-
- if (rc == NGX_OK && ctx->last) {
- /* STUB */
- return NGX_ERROR;
- }
-
- if (rc == NGX_OK) {
- ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
-#if level_event
- ngx_del_event(r->connection->write, NGX_WRITE_EVENT);
-#endif
- }
-
- return rc;
-}
-
-
-int ngx_http_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src, ngx_log_t *log)
-{
- size_t size;
-
- size = hunk->last.mem - hunk->pos.mem;
- if (size > dst->end - dst->pos.mem)
- size = dst->end - dst->pos.mem;
-
- if (src->type & NGX_HUNK_FILE) {
- n = ngx_read_file(src->handle, dst->pos.mem, size);
-
- if (n == NGX_ERROR) {
- ngx_log_error(NGX_LOG_ERR, log, ngx_errno,
- ngx_read_file_n " failed for client");
- return n;
-
-#if (NGX_FILE_AIO)
- } else if (n == NGX_AGAIN) {
- return n;
-#endif
-
- } else {
- ngx_assert((n == size), /* void */ ; , log,
- ngx_read_file_n " reads only %d of %d for client" _
- n _ size);
- }
-
- src->pos.mem += n;
- dst->last.mem += n;
-
- } else {
- ngx_memcpy(src->pos.mem, dst->pos.mem, size);
-
- src->pos.mem += size;
- dst->last.mem += size;
- }
-
- return NGX_OK;
-}
diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c
new file mode 100644
index 0000000..693b399
--- /dev/null
+++ b/src/http/ngx_http_output_filter.c
@@ -0,0 +1,253 @@
+
+
+#include <ngx_core.h>
+#include <ngx_files.h>
+#include <ngx_string.h>
+#include <ngx_hunk.h>
+#include <ngx_http.h>
+#include <ngx_http_output_filter.h>
+
+
+/* STUB */
+int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in);
+
+
+
+static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src);
+
+ngx_http_module_t ngx_http_output_filter_module;
+
+
+/* STUB */
+static ngx_http_output_filter_ctx_t module_ctx;
+
+void ngx_http_output_filter_init()
+{
+ module_ctx.hunk_size = 32 * 1024;
+ module_ctx.out.hunk = NULL;
+ module_ctx.out.next = NULL;
+ module_ctx.next_filter = ngx_http_write_filter;
+
+ ngx_http_output_filter_module.ctx = &module_ctx;
+}
+/* */
+
+
+/*
+ flags NGX_HUNK_RECYCLED, NGX_HUNK_FLUSH, NGX_HUNK_LAST
+*/
+
+int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
+{
+ int rc, first;
+ size_t size;
+ ssize_t n;
+ ngx_chain_t *ce;
+ ngx_http_output_filter_ctx_t *ctx;
+
+ ctx = (ngx_http_output_filter_ctx_t *)
+ ngx_get_module_ctx(r->main ? r->main : r,
+ &ngx_http_output_filter_module);
+
+ if (hunk && (hunk->type & NGX_HUNK_LAST))
+ ctx->last = 1;
+
+ first = 1;
+
+ while (first || ctx->in) {
+
+ /* input chain is not empty */
+ if (ctx->in) {
+
+ /* add hunk to input chain */
+ if (first && hunk) {
+ for (ce = ctx->in; ce->next; ce = ce->next)
+ /* void */ ;
+
+ ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR);
+ }
+
+ first = 0;
+
+ /* our hunk is still busy */
+ if (ctx->hunk->pos.mem < ctx->hunk->last.mem) {
+ rc = ctx->next_filter(r, NULL);
+
+ /* our hunk is free */
+ } else {
+ ctx->out.hunk = ctx->hunk;
+
+ rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk);
+#if (NGX_FILE_AIO)
+ if (rc == NGX_AGAIN)
+ return rc;
+#endif
+ if (rc == NGX_ERROR)
+ return rc;
+
+ /* whole hunk is copied so we send to next filter chain part
+ up to next hunk that need to be copied */
+ if (ctx->in->hunk->pos.mem == ctx->in->hunk->last.mem) {
+ ctx->out.next = ctx->in->next;
+
+ for (ce = ctx->in->next; ce; ce = ce->next) {
+ if (ce->hunk->type & NGX_HUNK_FILE)
+ break;
+
+ if ((ce->hunk->type & NGX_HUNK_MEMORY|NGX_HUNK_MMAP)
+ && (r->filter & NGX_HTTP_FILTER_NEED_TEMP))
+ break;
+ }
+
+ ctx->out.next = ce;
+
+ } else {
+ ctx->out.next = NULL;
+ }
+
+ rc = ctx->next_filter(r, &ctx->out);
+ }
+
+ /* delete completed hunks from input chain */
+ for (ce = ctx->in; ce; ce = ce->next) {
+ if (ce->hunk->pos.file == ce->hunk->last.file)
+ ctx->in = ce->next;
+ }
+
+ if (rc == NGX_OK)
+ ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
+ else
+ return rc;
+
+ /* input chain is empty */
+ } else {
+
+ first = 0;
+
+ if (hunk == NULL) {
+ rc = ctx->next_filter(r, NULL);
+
+ } else {
+
+ /* we need to copy hunk to our hunk */
+ 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))
+ ) {
+
+ /* out hunk is still busy */
+ if (ctx->hunk && ctx->hunk->pos.mem < ctx->hunk->last.mem) {
+ ngx_add_hunk_to_chain(ctx->in, hunk, r->pool,
+ NGX_ERROR);
+
+ rc = ctx->next_filter(r, NULL);
+
+ } else {
+ if (ctx->hunk == NULL) {
+
+ if (hunk->type & NGX_HUNK_LAST) {
+ size = hunk->last.mem - hunk->pos.mem;
+ if (size > ctx->hunk_size)
+ size = ctx->hunk_size;
+
+ } else {
+ size = ctx->hunk_size;
+ }
+
+ ngx_test_null(ctx->hunk,
+ ngx_create_temp_hunk(r->pool, size,
+ 50, 50),
+ NGX_ERROR);
+ ctx->hunk->type |= NGX_HUNK_RECYCLED;
+
+ rc = ngx_http_output_filter_copy_hunk(ctx->hunk,
+ hunk);
+#if (NGX_FILE_AIO)
+ if (rc == NGX_AGAIN) {
+ /* add hunk to input chain */
+ ngx_add_hunk_to_chain(ctx->in, hunk, r->pool,
+ NGX_ERROR);
+
+ return rc;
+ }
+#endif
+ if (rc == NGX_ERROR)
+ return rc;
+
+ if (hunk->pos.mem < hunk->last.mem)
+ ngx_add_hunk_to_chain(ctx->in, hunk, r->pool,
+ NGX_ERROR);
+
+ ctx->out.hunk = ctx->hunk;
+ ctx->out.next = NULL;
+
+ rc = ctx->next_filter(r, &ctx->out);
+ }
+ }
+
+ } else {
+ ctx->out.hunk = hunk;
+ ctx->out.next = NULL;
+
+ rc = ctx->next_filter(r, &ctx->out);
+ }
+ }
+ }
+
+ if (rc == NGX_OK && ctx->hunk)
+ ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
+ }
+
+ if (rc == NGX_OK && ctx->last)
+ return NGX_OK;
+
+ if (rc == NGX_OK) {
+ ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
+#if level_event
+ ngx_del_event(r->connection->write, NGX_WRITE_EVENT);
+#endif
+ }
+
+ return rc;
+}
+
+
+static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src)
+{
+ size_t size;
+ ssize_t n;
+
+ size = src->last.mem - src->pos.mem;
+ if (size > dst->end - dst->pos.mem)
+ size = dst->end - dst->pos.mem;
+
+ if (src->type & NGX_HUNK_FILE) {
+ n = ngx_read_file(src->file, dst->pos.mem, size, src->pos.file);
+
+ if (n == NGX_ERROR) {
+ return n;
+
+#if (NGX_FILE_AIO)
+ } else if (n == NGX_AGAIN) {
+ return n;
+#endif
+
+ } else {
+ ngx_assert((n == size), /* void */ ; , src->file->log,
+ ngx_read_file_n " reads only %d of %d" _
+ n _ size);
+ }
+
+ src->pos.mem += n;
+ dst->last.mem += n;
+
+ } else {
+ ngx_memcpy(src->pos.mem, dst->pos.mem, size);
+
+ src->pos.mem += size;
+ dst->last.mem += size;
+ }
+
+ return NGX_OK;
+}
diff --git a/src/http/ngx_http_filter.h b/src/http/ngx_http_output_filter.h
similarity index 65%
rename from src/http/ngx_http_filter.h
rename to src/http/ngx_http_output_filter.h
index 0f738cd..072e0bd 100644
--- a/src/http/ngx_http_filter.h
+++ b/src/http/ngx_http_output_filter.h
@@ -1,5 +1,5 @@
-#ifndef _NGX_HTTP_FILTER_H_INCLUDED_
-#define _NGX_HTTP_FILTER_H_INCLUDED_
+#ifndef _NGX_HTTP_OUTPUT_FILTER_H_INCLUDED_
+#define _NGX_HTTP_OUTPUT_FILTER_H_INCLUDED_
#include <ngx_core.h>
@@ -14,7 +14,7 @@
ngx_chain_t out;
size_t hunk_size;
unsigned last;
-} ngx_http_filter_ctx_t;
+} ngx_http_output_filter_ctx_t;
-#endif /* _NGX_HTTP_FILTER_H_INCLUDED_ */
+#endif /* _NGX_HTTP_OUTPUT_FILTER_H_INCLUDED_ */
diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c
index 2ccbe2e..dcb74c9 100644
--- a/src/http/ngx_http_write_filter.c
+++ b/src/http/ngx_http_write_filter.c
@@ -2,9 +2,9 @@
#include <ngx_config.h>
#include <ngx_hunk.h>
-#include <ngx_http.h>
-#include <ngx_http_filter.h>
#include <ngx_event_write.h>
+#include <ngx_http.h>
+#include <ngx_http_output_filter.h>
#include <ngx_http_write_filter.h>
@@ -48,7 +48,7 @@
ch->hunk->type _ ch->hunk->pos.file _
ch->hunk->last.file - ch->hunk->pos.file);
- if (ch->hunk->type & NGX_HUNK_FLUSH)
+ if (ch->hunk->type & NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)
flush = size;
if (ch->hunk->type & NGX_HUNK_LAST)
@@ -69,7 +69,7 @@
ch->hunk->type _ ch->hunk->pos.file _
ch->hunk->last.file - ch->hunk->pos.file);
- if (ch->hunk->type & NGX_HUNK_FLUSH)
+ if (ch->hunk->type & NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)
flush = size;
if (ch->hunk->type & NGX_HUNK_LAST)
@@ -85,5 +85,7 @@
ctx->out = chain;
+ ngx_log_debug(r->connection->log, "write filter %x" _ chain);
+
return (chain ? NGX_AGAIN : NGX_OK);
}
diff --git a/src/http/ngx_http_write_filter.h b/src/http/ngx_http_write_filter.h
index 6a2c6f2..0b3fa54 100644
--- a/src/http/ngx_http_write_filter.h
+++ b/src/http/ngx_http_write_filter.h
@@ -7,5 +7,7 @@
size_t buffer_output;
} ngx_http_write_filter_ctx_t;
+int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in);
+
#endif /* _NGX_HTTP_WRITE_FILTER_H_INCLUDED_ */
diff --git a/src/os/unix/freebsd/ngx_sendfile.c b/src/os/unix/freebsd/ngx_sendfile.c
index 1b60774..ff577db 100644
--- a/src/os/unix/freebsd/ngx_sendfile.c
+++ b/src/os/unix/freebsd/ngx_sendfile.c
@@ -1,5 +1,6 @@
#include <ngx_config.h>
+#include <ngx_core.h>
#include <ngx_types.h>
#include <ngx_file.h>
#include <ngx_socket.h>
@@ -14,12 +15,6 @@
check sent if errno == EINTR then should return right sent.
*/
-/*
- returns
- 0 done
- -1 error
-*/
-
#if (HAVE_FREEBSD_SENDFILE)
int ngx_sendfile(ngx_socket_t s,
@@ -50,7 +45,7 @@
if (err != NGX_EAGAIN && err != NGX_EINTR) {
ngx_log_error(NGX_LOG_ERR, log, err,
"ngx_sendfile: sendfile failed");
- return -1;
+ return NGX_ERROR;
} else {
ngx_log_error(NGX_LOG_INFO, log, err,
@@ -61,7 +56,7 @@
ngx_log_debug(log, "ngx_sendfile: %d, @%qd %qd:%d" _
rc _ offset _ *sent _ nbytes);
- return 0;
+ return NGX_OK;
}
#endif
diff --git a/src/os/unix/ngx_file.c b/src/os/unix/ngx_files.c
similarity index 80%
rename from src/os/unix/ngx_file.c
rename to src/os/unix/ngx_files.c
index 69b6975..a3dc36d 100644
--- a/src/os/unix/ngx_file.c
+++ b/src/os/unix/ngx_files.c
@@ -1,8 +1,19 @@
+#include <ngx_core.h>
+#include <ngx_file.h>
-ssize_t ngx_read_file(ngx_file_t file, char *buf, size_t size, off_t offset)
+ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
{
- return pread(file->fd, buf, size, offset);
+ ssize_t n;
+
+ ngx_log_debug(file->log, "read: %x, %d, %qd" _ buf _ size _ offset);
+
+ n = pread(file->fd, buf, size, offset);
+
+ if (n == NGX_ERROR)
+ ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "read() failed");
+
+ return n;
}
#if 0
diff --git a/src/os/unix/ngx_file.h b/src/os/unix/ngx_files.h
similarity index 82%
rename from src/os/unix/ngx_file.h
rename to src/os/unix/ngx_files.h
index 33ba6d8..9369db0 100644
--- a/src/os/unix/ngx_file.h
+++ b/src/os/unix/ngx_files.h
@@ -1,5 +1,5 @@
-#ifndef _NGX_FILE_H_INCLUDED_
-#define _NGX_FILE_H_INCLUDED_
+#ifndef _NGX_FILES_H_INCLUDED_
+#define _NGX_FILES_H_INCLUDED_
#include <sys/types.h>
@@ -12,7 +12,6 @@
#define ngx_open_file open
#define ngx_open_file_n "open()"
-#define ngx_read_file read
#define ngx_read_file_n "read()"
#define NGX_FILE_RDONLY O_RDONLY
@@ -29,4 +28,4 @@
#define ngx_file_mtime(sb) sb.st_mtime
-#endif /* _NGX_FILE_H_INCLUDED_ */
+#endif /* _NGX_FILES_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_sendfile.h b/src/os/unix/ngx_sendfile.h
index 768e23c..c9a5923 100644
--- a/src/os/unix/ngx_sendfile.h
+++ b/src/os/unix/ngx_sendfile.h
@@ -3,7 +3,7 @@
#include <ngx_types.h>
-#include <ngx_file.h>
+#include <ngx_files.h>
#include <ngx_socket.h>
#include <ngx_log.h>
#include <ngx_sendv.h>
diff --git a/src/os/unix/ngx_sendv.c b/src/os/unix/ngx_sendv.c
index 22838c2..dec16a1 100644
--- a/src/os/unix/ngx_sendv.c
+++ b/src/os/unix/ngx_sendv.c
@@ -1,15 +1,18 @@
+#include <ngx_core.h>
#include <ngx_types.h>
#include <ngx_socket.h>
#include <ngx_sendv.h>
ssize_t ngx_sendv(ngx_socket_t s, ngx_iovec_t *iovec, int n, size_t *sent)
{
- ssize_t rc = writev(s, iovec, n);
+ ssize_t rc;
+
+ rc = writev(s, iovec, n);
if (rc == -1)
- return -1;
+ return NGX_ERROR;
*sent = rc;
- return 0;
+ return NGX_OK;
}
diff --git a/src/os/unix/ngx_time.h b/src/os/unix/ngx_time.h
index f81ee4e..42bb716 100644
--- a/src/os/unix/ngx_time.h
+++ b/src/os/unix/ngx_time.h
@@ -4,6 +4,8 @@
#include <ngx_config.h>
+typedef u_int ngx_msec_t;
+
typedef struct tm ngx_tm_t;
#define ngx_tm_sec tm_sec
@@ -18,7 +20,7 @@
void ngx_localtime(ngx_tm_t *tm);
-u_int ngx_msec(void);
+ngx_msec_t ngx_msec(void);
#endif /* _NGX_TIME_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_errno.h b/src/os/win32/ngx_errno.h
index 5197fdd..bd20ddf 100644
--- a/src/os/win32/ngx_errno.h
+++ b/src/os/win32/ngx_errno.h
@@ -6,12 +6,14 @@
typedef DWORD ngx_err_t;
-#define ngx_errno GetLastError()
-#define ngx_socket_errno WSAGetLastError()
+#define ngx_errno GetLastError()
+#define ngx_socket_errno WSAGetLastError()
+#define ngx_set_socket_errno(err) WSASetLastError(err)
#define NGX_ENOENT ERROR_FILE_NOT_FOUND
#define NGX_EAGAIN WSAEWOULDBLOCK
#define NGX_EADDRINUSE WSAEADDRINUSE
+#define NGX_ETIMEDOUT WSAETIMEDOUT
int ngx_strerror_r(ngx_err_t err, char *errstr, size_t size);
diff --git a/src/os/win32/ngx_files.c b/src/os/win32/ngx_files.c
new file mode 100644
index 0000000..8a91901
--- /dev/null
+++ b/src/os/win32/ngx_files.c
@@ -0,0 +1,18 @@
+
+#include <ngx_core.h>
+#include <ngx_types.h>
+#include <ngx_file.h>
+
+ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset)
+{
+ size_t n;
+
+ if (ReadFile(file->fd, buf, size, &n, NULL) == 0) {
+ ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "ReadFile() failed");
+ return NGX_ERROR;
+ }
+
+ return n;
+}
+
+
diff --git a/src/os/win32/ngx_file.h b/src/os/win32/ngx_files.h
similarity index 83%
rename from src/os/win32/ngx_file.h
rename to src/os/win32/ngx_files.h
index aaae84b..bddfe0d 100644
--- a/src/os/win32/ngx_file.h
+++ b/src/os/win32/ngx_files.h
@@ -1,5 +1,5 @@
-#ifndef _NGX_FILE_H_INCLUDED_
-#define _NGX_FILE_H_INCLUDED_
+#ifndef _NGX_FILES_H_INCLUDED_
+#define _NGX_FILES_H_INCLUDED_
#include <ngx_config.h>
@@ -21,9 +21,9 @@
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, \
NULL, OPEN_EXISTING, 0, NULL)
-#define ngx_open_file_n "CreateFile"
+#define ngx_open_file_n "CreateFile()"
-#define NGX_FILE_RDONLY GENERIC_READ
+#define NGX_FILE_RDONLY GENERIC_READ
int ngx_file_type(char *filename, ngx_file_info_t *fi);
@@ -51,4 +51,7 @@
*/
-#endif /* _NGX_FILE_H_INCLUDED_ */
+#define ngx_read_file_n "ReadFile()"
+
+
+#endif /* _NGX_FILES_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_sendfile.c b/src/os/win32/ngx_sendfile.c
index c41b3b3..560f50f 100644
--- a/src/os/win32/ngx_sendfile.c
+++ b/src/os/win32/ngx_sendfile.c
@@ -1,6 +1,8 @@
#include <ngx_config.h>
+#include <ngx_core.h>
#include <ngx_types.h>
+#include <ngx_files.h>
#include <ngx_socket.h>
#include <ngx_errno.h>
#include <ngx_log.h>
@@ -13,17 +15,11 @@
TransmitPackets
*/
-/*
- returns
- 0 done
- -1 error
-*/
-
#if (HAVE_WIN32_TRANSMITFILE)
int ngx_sendfile(ngx_socket_t s,
ngx_iovec_t *headers, int hdr_cnt,
- ngx_file_t fd, off_t offset, size_t nbytes,
+ ngx_fd_t fd, off_t offset, size_t nbytes,
ngx_iovec_t *trailers, int trl_cnt,
off_t *sent,
ngx_log_t *log)
@@ -65,15 +61,13 @@
/* set sent */
#if 0
rc = WSAGetOverlappedResult(s, &olp, (unsigned long *) sent, 0, NULL);
+#else
+ *sent = olp.InternalHigh;
+ rc = 1;
#endif
-#if 0
ngx_log_debug(log, "ngx_sendfile: %d, @%I64d %I64d:%d" _
tfrc _ offset _ *sent _ nbytes);
-#else
- ngx_log_debug(log, "ngx_sendfile: %d, @%I64d %d:%d" _
- tfrc _ offset _ olp.InternalHigh _ nbytes);
-#endif
if (rc == 0) {
err = ngx_socket_errno;
@@ -85,7 +79,7 @@
if (tf_err != NGX_EAGAIN) {
ngx_log_error(NGX_LOG_ERR, log, tf_err,
"ngx_sendfile: TransmitFile failed");
- return -1;
+ return NGX_ERROR;
}
ngx_log_error(NGX_LOG_INFO, log, tf_err,
@@ -94,9 +88,9 @@
}
if (rc == 0)
- return -1;
+ return NGX_ERROR;
- return 0;
+ return NGX_OK;
}
#endif
diff --git a/src/os/win32/ngx_sendfile.h b/src/os/win32/ngx_sendfile.h
index 053db8e..a80750b 100644
--- a/src/os/win32/ngx_sendfile.h
+++ b/src/os/win32/ngx_sendfile.h
@@ -4,13 +4,14 @@
#include <ngx_config.h>
#include <ngx_types.h>
+#include <ngx_files.h>
#include <ngx_socket.h>
#include <ngx_log.h>
#include <ngx_sendv.h>
int ngx_sendfile(ngx_socket_t s,
ngx_iovec_t *headers, int hdr_cnt,
- ngx_file_t fd, off_t offset, size_t nbytes,
+ ngx_fd_t fd, off_t offset, size_t nbytes,
ngx_iovec_t *trailers, int trl_cnt,
off_t *sent,
ngx_log_t *log);
diff --git a/src/os/win32/ngx_socket.h b/src/os/win32/ngx_socket.h
index 2708b5f..95e427c 100644
--- a/src/os/win32/ngx_socket.h
+++ b/src/os/win32/ngx_socket.h
@@ -5,7 +5,10 @@
#include <ngx_config.h>
#include <ngx_log.h>
+#define INET_ADDRSTRLEN 16
+
typedef SOCKET ngx_socket_t;
+typedef int socklen_t;
void ngx_init_sockets(ngx_log_t *log);
@@ -13,11 +16,12 @@
WSASocket(af, type, proto, NULL, 0, flags)
#define ngx_socket_n "WSASocket()"
-int ngx_nonblocking_n(s);
+int ngx_nonblocking(ngx_socket_t s);
#define ngx_nonblocking_n "ioctlsocket(FIONBIO)"
#define ngx_close_socket closesocket
#define ngx_close_socket_n "closesocket()"
+
#endif /* _NGX_SOCKET_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_time.h b/src/os/win32/ngx_time.h
index be93244..a810c70 100644
--- a/src/os/win32/ngx_time.h
+++ b/src/os/win32/ngx_time.h
@@ -4,6 +4,8 @@
#include <windows.h>
+typedef unsigned int ngx_msec_t;
+
typedef SYSTEMTIME ngx_tm_t;
typedef FILETIME ngx_mtime_t;
diff --git a/src/os/win32/ngx_types.h b/src/os/win32/ngx_types.h
index fdf6ccd..7521633 100644
--- a/src/os/win32/ngx_types.h
+++ b/src/os/win32/ngx_types.h
@@ -5,6 +5,7 @@
#include <ngx_config.h>
+typedef int ssize_t;
typedef long time_t;