# HG changeset patch # User Igor Sysoev # Date 1030978104 0 # Node ID 708f8bb772ec837e5b4e035aff40c96d374c37c0 # Parent b5481d6fbbd475ac2fe94250ff59eede4a477ba7 nginx-0.0.1-2002-09-02-18:48:24 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -36,8 +36,6 @@ ngx_array_t *ngx_listening_sockets; int main(int argc, char *const *argv) { - int i; - /* STUB */ ngx_log.log_level = NGX_LOG_DEBUG; @@ -68,6 +66,8 @@ int main(int argc, char *const *argv) /* 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 --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -18,6 +18,7 @@ #include #include +#include /* offsetof */ #include #include @@ -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 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -21,6 +21,8 @@ struct ngx_connection_s { 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 @@ struct ngx_connection_s { 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 --- /dev/null +++ b/src/core/ngx_file.h @@ -0,0 +1,16 @@ +#ifndef _NGX_FILE_H_INCLUDED_ +#define _NGX_FILE_H_INCLUDED_ + + +#include +#include + +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 --- a/src/core/ngx_hunk.c +++ b/src/core/ngx_hunk.c @@ -1,13 +1,13 @@ -#include #include -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 @@ ngx_hunk_t *ngx_get_hunk(ngx_pool_t *poo 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 @@ ngx_hunk_t *ngx_get_hunk_before(ngx_pool 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 @@ ngx_hunk_t *ngx_get_hunk_before(ngx_pool 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 @@ ngx_hunk_t *ngx_get_hunk_after(ngx_pool_ 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 @@ ngx_hunk_t *ngx_get_hunk_after(ngx_pool_ 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 --- 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 @@ struct ngx_hunk_s { 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 @@ struct ngx_chain_s { 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 @@ struct ngx_chain_s { -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 --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -45,7 +45,11 @@ void ngx_log_error_core(int level, ngx_l " [%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 --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -3,7 +3,7 @@ #include -#include +#include typedef enum { NGX_LOG_EMERG = 0, diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c --- 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 @@ void ngx_kqueue_init(int max_connections #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 @@ void ngx_kqueue_init(int max_connections 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 @@ int ngx_kqueue_process_events(ngx_log_t 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 @@ int ngx_kqueue_process_events(ngx_log_t 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 @@ int ngx_kqueue_process_events(ngx_log_t 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 @@ static void ngx_add_timer_core(ngx_event 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 --- a/src/event/modules/ngx_kqueue_module.h +++ b/src/event/modules/ngx_kqueue_module.h @@ -10,6 +10,7 @@ void ngx_kqueue_init(int max_connections 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 --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -7,10 +8,10 @@ #include #include -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 event_queue; 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 @@ void ngx_select_init(int max_connections 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 @@ void ngx_select_init(int max_connections 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 @@ void ngx_select_init(int max_connections 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; + + c = (ngx_connection_t *) ev->data; + + ngx_log_debug(ev->log, "select fd:%d event:%d" _ c->fd _ event); - if (event == NGX_TIMER_EVENT) { - ngx_add_timer_core(ev, flags); - return 0; +#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 (WIN32) + if (event == NGX_READ_EVENT) { + FD_CLR(c->fd, &master_read_fd_set); + max_read--; - if (event == NGX_TIMER_EVENT) { - ngx_del_timer(ev); - return 0; + } 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 @@ int ngx_select_del_event(ngx_event_t *ev 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 ngx_select_process_events(ngx_log_t 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 @@ int ngx_select_process_events(ngx_log_t #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 @@ int ngx_select_process_events(ngx_log_t 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 @@ int ngx_select_process_events(ngx_log_t 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 @@ int ngx_select_process_events(ngx_log_t } 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 @@ int ngx_select_process_events(ngx_log_t } - 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 @@ static void ngx_add_timer_core(ngx_event 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 --- a/src/event/modules/ngx_select_module.h +++ b/src/event/modules/ngx_select_module.h @@ -10,6 +10,7 @@ void ngx_select_init(int max_connections 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 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -19,7 +20,7 @@ ngx_event_t *ngx_read_events, *n #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 @@ void ngx_pre_thread(ngx_array_t *ls, ngx 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 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -40,11 +41,16 @@ struct ngx_event_s { /* 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 enum { 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 @@ NGX_AIO_EVENT overlapped, a #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 @@ NGX_AIO_EVENT overlapped, a #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 @@ NGX_AIO_EVENT overlapped, a #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 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -63,7 +63,8 @@ int ngx_event_accept(ngx_event_t *ev) 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 --- a/src/event/ngx_event_write.c +++ b/src/event/ngx_event_write.c @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -10,7 +11,7 @@ #include -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 @@ ngx_chain_t *ngx_event_write(ngx_connect 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 @@ ngx_chain_t *ngx_event_write(ngx_connect #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 @@ ngx_chain_t *ngx_event_write(ngx_connect } 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 @@ ngx_chain_t *ngx_event_write(ngx_connect } /* 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 --- a/src/http/modules/ngx_http_header_filter.c +++ b/src/http/modules/ngx_http_header_filter.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -25,12 +26,8 @@ int ngx_http_header_filter(ngx_http_requ 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 --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -26,7 +26,7 @@ int ngx_http_static_handler(ngx_http_req { 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 @@ int ngx_http_static_handler(ngx_http_req */ + 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 @@ int ngx_http_static_handler(ngx_http_req 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 @@ int ngx_http_static_handler(ngx_http_req } 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 @@ int ngx_http_static_handler(ngx_http_req /* 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); -*/ + 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->fd = r->fd; h->pos.file = 0; - h->last.file = ngx_file_size(r->file_info); + h->last.file = ngx_file_size(r->fileinfo); /* 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->file, ngx_pcalloc(r->pool, sizeof(ngx_file_t)), NGX_HTTP_INTERNAL_SERVER_ERROR); -*/ - ch->hunk = h; - ch->next = NULL; + h->file->fd = r->fd; + h->file->log = r->connection->log; - /* STUB */ - rc = ngx_http_write_filter(r, ch); - ngx_log_debug(r->connection->log, "write_filter: %d" _ rc); + 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 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -17,8 +18,11 @@ int ngx_http_init(ngx_pool_t *pool, ngx_ { 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 @@ int ngx_http_init(ngx_pool_t *pool, ngx_ #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 @@ int ngx_http_init(ngx_pool_t *pool, ngx_ ls->server = &ngx_http_server; ls->log = log; + return 1; } diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include @@ -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 { 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 @@ struct ngx_http_request_s { 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 @@ struct ngx_http_request_s { 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 @@ typedef struct { #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 --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include @@ -10,6 +10,12 @@ #include +/* STUB */ +#include + +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(ngx_ 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 @@ int ngx_http_init_connection(ngx_connect 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 @@ int ngx_http_init_request(ngx_event_t *e 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 @@ int ngx_http_process_request(ngx_event_t 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 @@ int ngx_http_process_request(ngx_event_t /* 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 @@ static int ngx_http_process_request_line 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; } + ctx = r->connection->log->data; r->connection->log->handler = NULL; - ctx = r->connection->log->data; - 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 @@ static int ngx_http_process_request_head 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) { + ctx = r->connection->log->data; r->connection->log->handler = NULL; - ctx = r->connection->log->data; 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; +} + +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 > 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; } -#if 0 -static int ngx_http_lock_read(ngx_event_t *ev) +static int ngx_http_handler(ngx_http_request_t *r) { - ngx_del_event(ev, NGX_READ_EVENT); - ev->read_blocked = 1; + 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 +*/ } -#endif -static int ngx_http_process_http_request(ngx_http_request_t *r) +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 @@ static int ngx_http_process_http_request 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 @@ static int ngx_http_process_http_request 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_output_filter(r, NULL); + + ngx_log_debug(ev->log, "output_filter: %d" _ rc); + + if (rc == NGX_AGAIN) { - rc = ngx_http_filter(r, NULL); + 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 (rc == NGX_AGAIN) + 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 @@ static int ngx_http_writer(ngx_event_t * 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 @@ static int ngx_http_keepalive_handler(ng #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 @@ static int ngx_http_close_request(ngx_ht 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 int ngx_http_close_request(ngx_ht 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_output_filter.c rename from src/http/ngx_http_filter.c rename to src/http/ngx_http_output_filter.c --- a/src/http/ngx_http_filter.c +++ b/src/http/ngx_http_output_filter.c @@ -1,65 +1,74 @@ +#include +#include +#include #include #include -#include - - -ngx_http_module_t ngx_http_filter_module; +#include /* STUB */ -static ngx_http_filter_ctx_t module_ctx; +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); -void ngx_http_filter_init() +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_filter_module.ctx = &module_ctx; + ngx_http_output_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 ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk) { - int rc; + int rc, first; size_t size; ssize_t n; ngx_chain_t *ce; - ngx_http_filter_ctx_t *ctx; + ngx_http_output_filter_ctx_t *ctx; - ctx = (ngx_http_filter_ctx_t *) + ctx = (ngx_http_output_filter_ctx_t *) ngx_get_module_ctx(r->main ? r->main : r, - &ngx_http_filter_module); + &ngx_http_output_filter_module); if (hunk && (hunk->type & NGX_HUNK_LAST)) ctx->last = 1; - /* input chain is not empty */ - if (ctx->in) { + first = 1; - while (ctx->in) { + while (first || ctx->in) { + + /* input chain is not empty */ + if (ctx->in) { /* add hunk to input chain */ - if (hunk) { + 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); + 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); @@ -68,7 +77,7 @@ int ngx_http_filter(ngx_http_request_t * } else { ctx->out.hunk = ctx->hunk; - rc = ngx_http_filter_copy_hunk(ctx->hunk, ctx->in->hunk); + rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk); #if (NGX_FILE_AIO) if (rc == NGX_AGAIN) return rc; @@ -82,10 +91,10 @@ int ngx_http_filter(ngx_http_request_t * ctx->out.next = ctx->in->next; for (ce = ctx->in->next; ce; ce = ce->next) { - if (ce->type & NGX_HUNK_FILE) + if (ce->hunk->type & NGX_HUNK_FILE) break; - if ((ce->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; } @@ -99,90 +108,99 @@ int ngx_http_filter(ngx_http_request_t * 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 { - - if (hunk == NULL) { - rc = ctx->next_filter(r, NULL); - + /* input chain is empty */ } 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)) - ) { + 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; - /* 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, + } 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 = ctx->next_filter(r, NULL); + 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 { - 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); + ctx->out.hunk = hunk; + ctx->out.next = NULL; - 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); - } + 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) { - /* STUB */ - return NGX_ERROR; - } + if (rc == NGX_OK && ctx->last) + return NGX_OK; if (rc == NGX_OK) { ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; @@ -195,20 +213,19 @@ int ngx_http_filter(ngx_http_request_t * } -int ngx_http_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src, ngx_log_t *log) +static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src) { - size_t size; + size_t size; + ssize_t n; - size = hunk->last.mem - hunk->pos.mem; + 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->handle, dst->pos.mem, size); + n = ngx_read_file(src->file, dst->pos.mem, size, src->pos.file); 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) @@ -217,8 +234,8 @@ int ngx_http_filter_copy_hunk(ngx_hunk_t #endif } else { - ngx_assert((n == size), /* void */ ; , log, - ngx_read_file_n " reads only %d of %d for client" _ + ngx_assert((n == size), /* void */ ; , src->file->log, + ngx_read_file_n " reads only %d of %d" _ n _ size); } diff --git a/src/http/ngx_http_filter.h b/src/http/ngx_http_output_filter.h rename from src/http/ngx_http_filter.h rename to src/http/ngx_http_output_filter.h --- 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 @@ -14,7 +14,7 @@ typedef struct { 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 --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -2,9 +2,9 @@ #include #include +#include #include -#include -#include +#include #include @@ -48,7 +48,7 @@ int ngx_http_write_filter(ngx_http_reque 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 @@ int ngx_http_write_filter(ngx_http_reque 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 @@ int ngx_http_write_filter(ngx_http_reque 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 --- a/src/http/ngx_http_write_filter.h +++ b/src/http/ngx_http_write_filter.h @@ -7,5 +7,7 @@ typedef struct { 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 --- a/src/os/unix/freebsd/ngx_sendfile.c +++ b/src/os/unix/freebsd/ngx_sendfile.c @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -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 @@ int ngx_sendfile(ngx_socket_t s, 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 @@ int ngx_sendfile(ngx_socket_t s, 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 rename from src/os/unix/ngx_file.c rename to src/os/unix/ngx_files.c --- a/src/os/unix/ngx_file.c +++ b/src/os/unix/ngx_files.c @@ -1,8 +1,19 @@ +#include +#include + +ssize_t ngx_read_file(ngx_file_t *file, char *buf, size_t size, off_t offset) +{ + ssize_t n; -ssize_t ngx_read_file(ngx_file_t file, char *buf, size_t size, off_t offset) -{ - return pread(file->fd, buf, size, offset); + 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 rename from src/os/unix/ngx_file.h rename to src/os/unix/ngx_files.h --- 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 @@ -12,7 +12,6 @@ typedef struct stat ngx_fil #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 @@ typedef struct stat ngx_fil #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 --- a/src/os/unix/ngx_sendfile.h +++ b/src/os/unix/ngx_sendfile.h @@ -3,7 +3,7 @@ #include -#include +#include #include #include #include diff --git a/src/os/unix/ngx_sendv.c b/src/os/unix/ngx_sendv.c --- a/src/os/unix/ngx_sendv.c +++ b/src/os/unix/ngx_sendv.c @@ -1,15 +1,18 @@ +#include #include #include #include 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 --- a/src/os/unix/ngx_time.h +++ b/src/os/unix/ngx_time.h @@ -4,6 +4,8 @@ #include +typedef u_int ngx_msec_t; + typedef struct tm ngx_tm_t; #define ngx_tm_sec tm_sec @@ -18,7 +20,7 @@ typedef struct tm ngx_tm_t; 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 --- 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 --- /dev/null +++ b/src/os/win32/ngx_files.c @@ -0,0 +1,18 @@ + +#include +#include +#include + +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 rename from src/os/win32/ngx_file.h rename to src/os/win32/ngx_files.h --- 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 @@ -21,9 +21,9 @@ typedef BY_HANDLE_FILE_INFORMATION ngx_ 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 @@ 1970 - 1601: */ -#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 --- a/src/os/win32/ngx_sendfile.c +++ b/src/os/win32/ngx_sendfile.c @@ -1,6 +1,8 @@ #include +#include #include +#include #include #include #include @@ -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 @@ int ngx_sendfile(ngx_socket_t s, /* 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 @@ int ngx_sendfile(ngx_socket_t s, 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 @@ int ngx_sendfile(ngx_socket_t s, } 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 --- a/src/os/win32/ngx_sendfile.h +++ b/src/os/win32/ngx_sendfile.h @@ -4,13 +4,14 @@ #include #include +#include #include #include #include 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 --- a/src/os/win32/ngx_socket.h +++ b/src/os/win32/ngx_socket.h @@ -5,7 +5,10 @@ #include #include +#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 @@ void ngx_init_sockets(ngx_log_t *log); 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 --- a/src/os/win32/ngx_time.h +++ b/src/os/win32/ngx_time.h @@ -4,6 +4,8 @@ #include +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 --- a/src/os/win32/ngx_types.h +++ b/src/os/win32/ngx_types.h @@ -5,6 +5,7 @@ #include +typedef int ssize_t; typedef long time_t;