# HG changeset patch # User Igor Sysoev # Date 1029854908 0 # Node ID 34a521b1a14870d446532cae21a17296f73b07b1 # Parent ffffe1499bce9debf5d4dabcc8280124e6d0dc32 nginx-0.0.1-2002-08-20-18:48:28 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include #include @@ -16,80 +18,134 @@ /* */ +static void ngx_open_listening_sockets(ngx_log_t *log); + +/* STUB */ int ngx_max_conn = 512; -ngx_pool_t ngx_pool; -ngx_log_t ngx_log; -ngx_server_t ngx_server; +ngx_server_t ngx_server; +/* */ + +ngx_log_t ngx_log; +ngx_pool_t *ngx_pool; -ngx_array_t ngx_listening_sockets; +ngx_array_t *ngx_listening_sockets; int main(int argc, char *const *argv) { int i; - ngx_socket_t s; - ngx_listen_t *ls; - int reuseaddr = 1; + /* STUB */ + ngx_log.log_level = NGX_LOG_DEBUG; - ngx_log.log_level = NGX_LOG_DEBUG; - ngx_pool.log = &ngx_log; + ngx_pool = ngx_create_pool(16 * 1024, &ngx_log); + /* */ ngx_init_sockets(&ngx_log); /* TODO: read config */ + ngx_test_null(ngx_listening_sockets, + ngx_create_array(ngx_pool, 10, sizeof(ngx_listen_t)), 1); + /* STUB */ /* TODO: init chain of global modules (like ngx_http.c), they would init its modules and ngx_listening_sockets */ - ngx_http_init(); - - /* for each listening socket */ - ls = (ngx_listen_t *) ngx_listening_sockets.elts; - for (i = 0; i < ngx_listening_sockets.nelts; i++) { - s = socket(ls->family, ls->type, ls->protocol); - if (s == -1) - ngx_log_error(NGX_LOG_EMERG, &(ngx_log), ngx_socket_errno, - "nginx: socket %s falied", ls->addr_text); - - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - (const void *) &reuseaddr, sizeof(int)) == -1) - ngx_log_error(NGX_LOG_EMERG, &(ngx_log), ngx_socket_errno, - "nginx: setsockopt (SO_REUSEADDR) %s failed", - ls->addr_text); - - /* TODO: close on exit */ + ngx_http_init(ngx_pool, &ngx_log); - if (ngx_nonblocking(s) == -1) - ngx_log_error(NGX_LOG_EMERG, &(ngx_log), ngx_socket_errno, - ngx_nonblocking_n " %s failed", ls->addr_text); - - if (bind(s, (struct sockaddr *) ls->addr, ls->addr_len) == -1) - ngx_log_error(NGX_LOG_EMERG, &(ngx_log), ngx_socket_errno, - "bind to %s failed", ls->addr_text); - - if (listen(s, ls->backlog) == -1) - ngx_log_error(NGX_LOG_EMERG, &(ngx_log), ngx_socket_errno, - "listen to %s failed", ls->addr_text); - - /* TODO: deferred accept */ - - ls->fd = s; - ls->server = &ngx_http_server; - ls->log = &ngx_log; - } + ngx_open_listening_sockets(&ngx_log); /* TODO: daemon */ /* TODO: fork */ - /* TODO: events: init ngx_connections and listen slots */ + ngx_pre_thread(ngx_listening_sockets, ngx_pool, &ngx_log); /* TODO: threads */ /* STUB */ - ngx_worker(&ls, 1, &ngx_pool, &ngx_log); + ngx_worker(&ngx_log); } + +static void ngx_open_listening_sockets(ngx_log_t *log) +{ + int times, failed, reuseaddr, i; + ngx_err_t err; + ngx_socket_t s; + ngx_listen_t *ls; + + reuseaddr = 1; + + for (times = 10; times; times--) { + failed = 0; + + /* for each listening socket */ + ls = (ngx_listen_t *) ngx_listening_sockets->elts; + for (i = 0; i < ngx_listening_sockets->nelts; i++) { + if (ls[i].done) + continue; + +#if (WIN32) + s = WSASocket(ls[i].family, ls[i].type, ls[i].protocol, NULL, 0, 0); +#else + s = socket(ls[i].family, ls[i].type, ls[i].protocol); +#endif + if (s == -1) + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + "nginx: socket %s falied", ls[i].addr_text); + + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, + (const void *) &reuseaddr, sizeof(int)) == -1) + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + "nginx: setsockopt (SO_REUSEADDR) %s failed", + ls[i].addr_text); + + /* TODO: close on exit */ + + if (ls[i].nonblocking) { + if (ngx_nonblocking(s) == -1) + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_nonblocking_n " %s failed", + ls[i].addr_text); + } + + if (bind(s, (struct sockaddr *) ls[i].addr, ls[i].addr_len) == -1) { + err = ngx_socket_errno; + ngx_log_error(NGX_LOG_ALERT, log, err, + "bind to %s failed", ls[i].addr_text); + + if (err != NGX_EADDRINUSE) + exit(1); + + if (ngx_close_socket(s) == -1) + ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, + ngx_close_socket_n " %s failed", + ls[i].addr_text); + + failed = 1; + continue; + } + + if (listen(s, ls[i].backlog) == -1) + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + "listen to %s failed", ls[i].addr_text); + + /* TODO: deferred accept */ + + ls[i].fd = s; + ls[i].done = 1; + } + + if (!failed) + break; + + ngx_log_error(NGX_LOG_NOTICE, log, 0, "try to bind again after 500ms"); + ngx_msleep(500); + } + + if (failed) + ngx_log_error(NGX_LOG_EMERG, log, 0, "can't bind"); +} 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 @@ -28,6 +28,10 @@ #define ngx_close_socket closesocket +#ifndef HAVE_INHERITED_NONBLOCK +#define HAVE_INHERITED_NONBLOCK 1 +#endif + #ifndef HAVE_WIN32_TRANSMITPACKETS #define HAVE_WIN32_TRANSMITPACKETS 1 #define HAVE_WIN32_TRANSMITFILE 0 @@ -88,6 +92,10 @@ #include +#ifndef HAVE_INHERITED_NONBLOCK +#define HAVE_INHERITED_NONBLOCK 1 +#endif + #if __FreeBSD_version >= 300007 #ifndef HAVE_FREEBSD_SENDFILE @@ -129,4 +137,13 @@ #endif /* __FreeBSD__ */ +#ifdef __SOME_OS_TEMPLATE__ + +#ifndef HAVE_INHERITED_NONBLOCK +#define HAVE_INHERITED_NONBLOCK 1 +#endif + +#endif + + #endif /* _NGX_CONFIG_H_INCLUDED_ */ 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 @@ -1,6 +1,7 @@ #ifndef _NGX_CONNECTION_H_INCLUDED_ #define _NGX_CONNECTION_H_INCLUDED_ +#include #include #include #include @@ -21,14 +22,14 @@ struct ngx_connection_s { #endif ngx_log_t *log; + int (*handler)(ngx_connection_t *c); ngx_server_t *server; ngx_server_t *servers; ngx_pool_t *pool; }; -/* - +#if 0 cached file int fd; -2 unused, -1 closed (but read or mmaped), >=0 open char *name; @@ -49,6 +50,6 @@ cached file EV_VNODE should notify by some signal if diretory tree is changed or stat if aged >= N seconds (big enough) -*/ +#endif #endif /* _NGX_CONNECTION_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,5 +1,5 @@ -#include +#include #include 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 @@ -4,6 +4,7 @@ #include #include +#include #include diff --git a/src/core/ngx_listen.h b/src/core/ngx_listen.h --- a/src/core/ngx_listen.h +++ b/src/core/ngx_listen.h @@ -2,8 +2,40 @@ #define _NGX_LISTEN_H_INCLUDED_ -ngx_socket_t ngx_listen(struct sockaddr *addr, int backlog, - ngx_log_t *log, char *addr_text); +#include +#include +#include +#include +#include + +typedef struct { + ngx_socket_t fd; + + void *addr; + size_t addr_len; + char *addr_text; + + int family; + int type; + int protocol; + + ngx_log_t *log; + void *server; + int (*handler)(ngx_connection_t *c); + + int backlog; + + unsigned done:1; + unsigned close:1; + unsigned nonblocking:1; +#if 0 + unsigned overlapped:1; +#endif + unsigned shared:1; /* shared between threads or processes */ +#if (HAVE_DEFERRED_ACCEPT) + unsigned deferred_accept:1; +#endif +} ngx_listen_t; #endif /* _NGX_LISTEN_H_INCLUDED_ */ 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 @@ -16,6 +16,21 @@ typedef enum { } ngx_log_e; /* + "[%time] [%level] %pid#%tid: %message:(%errno)%errstr, while %action" + " %peer and processing %context" + + message = "recv() failed"; + errno = 32; + action = "reading request headers from client"; + peer = "192.168.1.1"; + context = "URL /" + + "[2002/08/20 12:00:00] [error] 412#3: recv() failed:(32)Broken pipe," + " while reading request headers from client 192.168.1.1" + " and processing URL /" + + + OLD: "... while ", action = "reading client request headers" "... while reading client request headers" "... while ", action = "reading client request headers" diff --git a/src/core/ngx_server.h b/src/core/ngx_server.h --- a/src/core/ngx_server.h +++ b/src/core/ngx_server.h @@ -14,28 +14,4 @@ typedef struct { } ngx_server_t; -typedef struct { - ngx_socket_t fd; - - ngx_log_t *log; - void *server; - - int family; - int type; - int protocol; - - void *addr; - size_t addr_len; - char *addr_text; - - int backlog; - - unsigned non_blocking:1; - unsigned shared:1; /* shared between threads or processes */ -#if (HAVE_DEFERRED_ACCEPT) - unsigned deferred_accept:1; -#endif -} ngx_listen_t; - - #endif /* _NGX_SERVER_H_INCLUDED_ */ 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 @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -18,7 +19,7 @@ ngx_event_t *ngx_read_events, *n #if !(USE_KQUEUE) -#if 1 +#if 0 ngx_event_type_e ngx_event_type = NGX_SELECT_EVENT; #else ngx_event_type_e ngx_event_type = NGX_KQUEUE_EVENT; @@ -40,9 +41,10 @@ static void (*ngx_event_init[]) (int max #endif /* USE_KQUEUE */ -void ngx_worker(ngx_listen_t *sock, int n, ngx_pool_t *pool, ngx_log_t *log) +void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log) { int i, fd; + ngx_listen_t *s; /* per group */ int max_connections = 512; @@ -55,18 +57,21 @@ void ngx_worker(ngx_listen_t *sock, int * max_connections, log); /* for each listening socket */ - for (i = 0; i < n; i++) { - fd = sock[i].fd; + s = (ngx_listen_t *) ls->elts; + for (i = 0; i < ls->nelts; i++) { + + fd = s[i].fd; ngx_memzero(&ngx_read_events[fd], sizeof(ngx_event_t)); ngx_memzero(&ngx_write_events[fd], sizeof(ngx_event_t)); ngx_memzero(&ngx_connections[fd], sizeof(ngx_connection_t)); ngx_connections[fd].fd = fd; - ngx_connections[fd].server = sock[i].server; + ngx_connections[fd].server = s[i].server; ngx_connections[fd].read = (void *) &ngx_read_events[fd].data; + ngx_connections[fd].handler = s[i].handler; ngx_read_events[fd].data = &ngx_connections[fd]; - ngx_read_events[fd].log = ngx_connections[fd].log = sock[i].log; + ngx_read_events[fd].log = ngx_connections[fd].log = s[i].log; ngx_read_events[fd].data = &ngx_connections[fd]; ngx_read_events[fd].event_handler = &ngx_event_accept; ngx_read_events[fd].listening = 1; @@ -74,11 +79,14 @@ void ngx_worker(ngx_listen_t *sock, int ngx_read_events[fd].available = 0; #if (HAVE_DEFERRED_ACCEPT) - ngx_read_events[fd].accept_filter = sock->accept_filter; + ngx_read_events[fd].accept_filter = s[i].accept_filter; #endif ngx_add_event(&ngx_read_events[fd], NGX_READ_EVENT, 0); } +} +void ngx_worker(ngx_log_t *log) +{ while (1) { ngx_log_debug(log, "ngx_worker cycle"); 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,7 +4,10 @@ #include #include +#include #include +#include +#include typedef struct ngx_event_s ngx_event_t; @@ -76,13 +79,12 @@ typedef struct { */ } ngx_event_actions_t; + /* - NGX_LEVEL_EVENT (default) select, poll, kqueue requires to read whole data NGX_ONESHOT_EVENT kqueue NGX_CLEAR_EVENT kqueue - */ #if (HAVE_KQUEUE) @@ -135,7 +137,8 @@ extern ngx_event_type_e ngx_event_t #endif -void ngx_worker(ngx_listen_t *sock, int n, ngx_pool_t *pool, ngx_log_t *log); +void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log); +void ngx_worker(ngx_log_t *log); #endif /* _NGX_EVENT_H_INCLUDED_ */ 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 @@ -38,6 +38,12 @@ int ngx_event_accept(ngx_event_t *ev) ngx_log_debug(ev->log, "ngx_event_accept: accepted socket: %d" _ s); +#if !(HAVE_INHERITED_NONBLOCK) + if (ngx_nonblocking(s) == -1) + ngx_log_error(NGX_LOG_ERR, log, ngx_socket_errno, + ngx_nonblocking_n "failed"); +#endif + ngx_memzero(&ngx_read_events[s], sizeof(ngx_event_t)); ngx_memzero(&ngx_write_events[s], sizeof(ngx_event_t)); ngx_memzero(&ngx_connections[s], sizeof(ngx_connection_t)); @@ -69,7 +75,7 @@ int ngx_event_accept(ngx_event_t *ev) ngx_read_events[s].ready = 1; #endif - cn->server->handler(&ngx_connections[s]); + cn->handler(&ngx_connections[s]); #if (HAVE_KQUEUE) #if !(USE_KQUEUE) 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 @@ -99,6 +99,7 @@ ngx_chain_t *ngx_event_write(ngx_connect } else { rc = ngx_sendv(cn->fd, (ngx_iovec_t *) header->elts, header->nelts, (size_t *) &sent); + ngx_log_debug(cn->log, "sendv: %d" _ sent); } #if (HAVE_MAX_SENDFILE_IOVEC) } @@ -110,14 +111,26 @@ ngx_chain_t *ngx_event_write(ngx_connect flush -= sent; - for (ch = in; ch && !(ch->hunk->type & NGX_HUNK_LAST); ch = ch->next) { + for (ch = in; ch; ch = ch->next) { 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; - continue; + + ngx_log_debug(cn->log, "event write: %qx 0" _ + ch->hunk->pos.file); + + if (ch->hunk->type & NGX_HUNK_LAST) + break; + + continue; } ch->hunk->pos.file += sent; + + ngx_log_debug(cn->log, "event write: %qx %qd" _ + ch->hunk->pos.file _ + ch->hunk->last.file - ch->hunk->pos.file); + break; } 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 @@ -1,3 +1,10 @@ + +#include + +#include +#include +#include +#include typedef struct { @@ -18,44 +25,60 @@ 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), NGX_HTTP_FILTER_ERROR); + ngx_test_null(h, ngx_get_hunk(r->pool, 1024, 0, 64), + /* STUB */ + -1); +/* + NGX_HTTP_FILTER_ERROR); +*/ - status = r->headers_out->status - GX_HTTP_OK; + status = r->headers_out->status - NGX_HTTP_OK; - ngx_memcpy(h->pos.mem, "HTTP/1.0 ", 9); - h->pos.mem += 9; - ngx_memcpy(h->pos.mem, http_codes[status].line, http_codes[status].len); - h->pos.mem += http_codes[status].len; - *(h->pos.mem++) = CR; *(h->pos.mem++) = LF; + ngx_memcpy(h->last.mem, "HTTP/1.0 ", 9); + h->last.mem += 9; + ngx_memcpy(h->last.mem, http_codes[status].line, http_codes[status].len); + h->last.mem += http_codes[status].len; + *(h->last.mem++) = CR; *(h->last.mem++) = LF; - memcpy(h->pos.mem, "Date: ", 6); - h->pos.mem += 6; - h->pos.mem += ngx_http_get_time(h->pos.mem, time()); - *(h->pos.mem++) = CR; *(h->pos.mem++) = LF; +/* + memcpy(h->last.mem, "Date: ", 6); + h->last.mem += 6; + h->last.mem += ngx_http_get_time(h->last.mem, time(NULL)); + *(h->last.mem++) = CR; *(h->last.mem++) = LF; +*/ /* 2^64 is 20 characters */ if (r->headers_out->content_length) - h->pos.mem += ngx_snprintf(h->pos.mem, 49, "Content-Length: %d" CRLF, - r->headers_out->content_length); + h->last.mem += ngx_snprintf(h->last.mem, 49, "Content-Length: %d" CRLF, + r->headers_out->content_length); /* check */ - memcpy(h->pos.mem, "Server: ", 8); - h->pos.mem += 8; + memcpy(h->last.mem, "Server: ", 8); + h->last.mem += 8; if (r->headers_out->server) { - h->pos.mem = ngx_cpystrn(h->pos.mem, r->headers_out->server, - h->last.mem - h->pos.mem); - check space + h->last.mem = ngx_cpystrn(h->last.mem, r->headers_out->server, + h->end - h->last.mem); + + /* check space */ + } else { - ngx_memcpy(h->pos.mem, NGINX_VER, sizeof(NGINX_VER)); - h->pos.mem += sizeof(NGINX_VER); + ngx_memcpy(h->last.mem, NGINX_VER, sizeof(NGINX_VER)); + h->last.mem += sizeof(NGINX_VER); } - *(h->pos.mem++) = CR; *(h->pos.mem++) = LF; + *(h->last.mem++) = CR; *(h->last.mem++) = LF; + + /* end of HTTP header */ + *(h->last.mem++) = CR; *(h->last.mem++) = LF; ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), + /* STUB */ + -1); +/* NGX_HTTP_FILTER_ERROR); +*/ - ch->hunk = in->hunk; + ch->hunk = h; ch->next = NULL; return ngx_http_write_filter(r, ch); 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 @@ -1,55 +1,114 @@ #include +#include +#include +#include +#include -#include -#include -#include +ngx_http_module_t ngx_http_static_module; + + +#if 0 +/* STUB */ +static ngx_http_static_ctx_t module_ctx; -#include +void ngx_http_static_init() +{ + module_ctx.out = NULL; + + ngx_http_static_module.ctx = &module_ctx; +} +/* */ +#endif + int ngx_http_static_handler(ngx_http_request_t *r) { - int index_len, err, i; - char *name, *loc, *file - ngx_file_t fd; + int rc; + ngx_hunk_t *h; + ngx_chain_t *ch; - ngx_http_header_out_t out; +/* ngx_http_event_static_handler_loc_conf_t *cf; cf = (ngx_http_event_static_handler_loc_conf_t *) ngx_get_module_loc_conf(r, &ngx_http_event_static_handler_module); - ngx_assert(r->fd, return NGX_HTTP_INTERNAL_SERVER_ERROR, - r->connection->log, "ngx_http_static_handler: no file"); +*/ + + 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, + "ngx_http_static_handler: " + ngx_open_file_n " %s failed", r->filename); + /* STUB */ + return -1; + } - out.status = NGX_HTTP_OK; - out.content_length = r->stat.sb_size; - out.last_modified = r->stat.sb_mtime; + if (ngx_stat_fd(r->fd, &r->file_info) == -1) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, + "ngx_http_static_handler: " + ngx_stat_fd_n " %s failed", r->filename); + /* STUB */ + return -1; + } - /* */ - out.content_type = "text/html"; + r->headers_out->status = NGX_HTTP_OK; + r->headers_out->content_length = ngx_file_size(r->file_info); +/* + r->headers_out->last_modified = ngx_file_mtime(r->file_info); +*/ - rc = ngx_send_http_header(&out); + /* STUB */ + r->headers_out->content_type = "text/html"; + + /* STUB */ + rc = ngx_http_header_filter(r); +/* + rc = ngx_send_http_header(r->headers_out); +*/ if (r->header_only) return rc; - /* NGX_HTTP_INTERNAL_SERVER_ERROR is too late */ + /* 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->type = NGX_HUNK_FILE|NGX_HUNK_LAST; h->fd = r->fd; h->pos.file = 0; - h->end.file = r->stat.sb_size; + 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_HTTP_INTERNAL_SERVER_ERROR); +*/ ch->hunk = h; ch->next = NULL; - return ngx_http_filter(ch); + /* STUB */ + rc = ngx_http_write_filter(r, ch); + ngx_log_debug(r->connection->log, "write_filter: %d" _ rc); + return rc; +/* + return ngx_http_filter(r, ch); +*/ } -/* +#if 0 static void *ngx_create_index_config() { @@ -98,4 +157,4 @@ static void *ngx_set_index() *conf = cf; } -*/ +#endif 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,10 @@ +#include +#include +#include #include +extern ngx_array_t *ngx_listening_sockets; /* STUB */ @@ -9,22 +13,25 @@ static char addr_text[22]; static ngx_http_server_t ngx_http_server; -int ngx_http_init(ngx_pool_t *pool) +int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log) { ngx_listen_t *ls; - ngx_http_server.handler = ngx_http_init_connection; + ngx_http_server.buff_size = 1024; +#if (WIN32) + ngx_http_server.doc_root = "html"; +#else + ngx_http_server.doc_root = "/home/is/work/xml/site-1.0.0/html"; +#endif + ngx_http_server.doc_root_len = strlen(ngx_http_server.doc_root) + 1; - ngx_http_server.buff_size = 1024; - - ngx_http_server.doc_root = "/home/is/work/xml/site-1.0.0/html"; - ngx_http_server.doc_root_len = strlen(server.doc_root); + ngx_http_write_filter_init(); ls = ngx_push_array(ngx_listening_sockets); - ngx_memzero(ls, sizeof(nxg_listen_t)); + ngx_memzero(ls, sizeof(ngx_listen_t)); addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr(optarg) + addr.sin_addr.s_addr = inet_addr("0.0.0.0"); addr.sin_port = htons(8000); ngx_snprintf(ngx_cpystrn(addr_text, inet_ntoa(addr.sin_addr), 16), @@ -32,13 +39,17 @@ int ngx_http_init(ngx_pool_t *pool) ls->family = AF_INET; ls->type = SOCK_STREAM; - ls->protocol = 0; + ls->protocol = IPPROTO_IP; ls->addr = &addr; - ls->addr_len = sizeof(sockaddr_in); - ls->text = &addr_text; + ls->addr_len = sizeof(struct sockaddr_in); + ls->addr_text = addr_text; ls->backlog = -1; ls->nonblocking = 1; + ls->handler = ngx_http_init_connection; + 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 @@ -4,6 +4,7 @@ #include #include +#include #include @@ -22,6 +23,7 @@ #define NGX_OK 0 #define NGX_HTTP_OK 200 +#define NGX_HTTP_MOVED_PERMANENTLY 302 #define NGX_HTTP_NOT_FOUND 404 #define NGX_HTTP_INTERNAL_SERVER_ERROR 503 @@ -38,8 +40,9 @@ typedef struct { #define ngx_get_module_ctx(r, module) (module)->ctx typedef struct { - char *doc_root; - int doc_root_len; + char *doc_root; + size_t doc_root_len; + size_t buff_size; } ngx_http_server_t; typedef struct { @@ -52,23 +55,30 @@ typedef struct { typedef struct { int status; int connection; - size_t content_length; + off_t content_length; + char *location; char *content_type; char *charset; char *etag; + char *server; time_t date; time_t last_modified; -} ngx_http_header_out_t; +} ngx_http_headers_out_t; typedef struct ngx_http_request_s ngx_http_request_t; struct ngx_http_request_s { char *filename; char *location; + ngx_file_t fd; + + ngx_http_headers_out_t *headers_out; int filename_len; int (*handler)(ngx_http_request_t *r); + ngx_file_info_t file_info; + int method; int http_version; @@ -83,7 +93,7 @@ struct ngx_http_request_s { ngx_buff_t *buff; ngx_pool_t *pool; - /* internal */ + unsigned header_only:1; unsigned unusual_uri:1; unsigned complex_uri:1; 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 @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -26,6 +27,9 @@ static int ngx_process_http_request(ngx_ static int ngx_http_close_request(ngx_event_t *ev); +/* STUB */ +static int ngx_http_writer(ngx_event_t *ev); + /* returns -1 if error @@ -62,6 +66,7 @@ int ngx_http_init_connection(ngx_connect int ngx_http_init_request(ngx_event_t *ev) { ngx_connection_t *c = (ngx_connection_t *) ev->data; + ngx_http_server_t *srv = (ngx_http_server_t *) c->server; ngx_http_request_t *r; ngx_log_debug(ev->log, "ngx_http_init_request: entered"); @@ -71,14 +76,14 @@ int ngx_http_init_request(ngx_event_t *e c->data = r; r->connection = c; + r->server = srv; ngx_test_null(r->pool, ngx_create_pool(16384, ev->log), -1); ngx_test_null(r->buff, ngx_palloc(r->pool, sizeof(ngx_buff_t)), -1); - ngx_test_null(r->buff->buff, - ngx_pcalloc(r->pool, sizeof(c->server->buff_size)), -1); + ngx_test_null(r->buff->buff, ngx_palloc(r->pool, srv->buff_size), -1); r->buff->pos = r->buff->last = r->buff->buff; - r->buff->end = r->buff->buff + c->server->buff_size; + r->buff->end = r->buff->buff + srv->buff_size; r->state_handler = ngx_process_http_request_line; @@ -180,11 +185,15 @@ static int ngx_process_http_request_head static int ngx_process_http_request(ngx_http_request_t *r) { - int err; + 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)); + if (*(r->uri_end - 1) == '/') { r->handler = NGX_HTTP_DIRECTORY_HANDLER; return NGX_OK; @@ -204,14 +213,11 @@ static int ngx_process_http_request(ngx_ ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->filename); -} -#if 0 - - if (ngx_stat(r->filename, &r->stat) == -1) { + if (ngx_file_type(r->filename, &r->file_info) == -1) { err = ngx_errno; - ngx_log_error(GX_LOG_ERR, r->connection->log, err, + ngx_log_error(NGX_LOG_ERR, r->connection->log, err, "ngx_process_http_request: " - ngx_stat_n " %s failed", r->filename); + ngx_file_type_n " %s failed", r->filename); if (err == NGX_ENOENT) return ngx_http_error(r, NGX_HTTP_NOT_FOUND); @@ -219,29 +225,50 @@ static int ngx_process_http_request(ngx_ return ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR); } - if (ngx_is_dir(r->stat)) { + if (ngx_is_dir(r->file_info)) { + 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); } - r->stat_valid = 1; + /* 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; return NGX_OK; } + +static int ngx_http_writer(ngx_event_t *ev) +{ + 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); } -#endif static int ngx_http_redirect(ngx_http_request_t *r, int redirect) { diff --git a/src/http/ngx_http_filter.c b/src/http/ngx_http_filter.c new file mode 100644 --- /dev/null +++ b/src/http/ngx_http_filter.c @@ -0,0 +1,239 @@ + + + +ngx_http_module_t ngx_http_filter_module; + + +/* STUB */ +static ngx_http_filter_ctx_t module_ctx; + +void ngx_http_filter_init() +{ + module_ctx.buffer_output = 10240; + module_ctx.out = 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) +{ + enum { NO = 0, COPY, FILE } temp; + + ngx_http_write_ctx_t *ctx; + + ctx = (ngx_http_filter_ctx_t *) + ngx_get_module_ctx(r->main ? r->main : r, + &ngx_http_filter_module); + + + + if (hunk == NULL) + if (in == NULL) + next_filter(NULL); + else + + + + + + if (hunk != NULL) + if (in == NULL) + if (temp == NO) + fast_chain = hunk; + next_filter(fast_chain); + else + if (ctx->hunk busy) + add hunk to ctx->in + next_filter(NULL); + else + if (hunk > ctx->hunk) + copy hunk part to ctx->hunk + add hunk to ctx->in + else + copy hunk to ctx->hunk + fast_chain = ctx->hunk + next_filter(fast_chain); + + else /* in != NULL */ + add hunk to ctx->in + + + + + + + + + + if ((r->filter & NGX_FILT_NEED_IN_MEMORY) && (hunk->type & NGX_HUNK_FILE)) + temp = FILE; + + else if ((r->filter & NGX_FILT_NEED_TEMP) + && (hunk->type & NGX_HUNK_MEMORY|NGX_HUNK_MMAP)) + temp = COPY; + + if (temp) { + size = hunk->last.mem - hunk->pos.mem; + + if (hunk->type & NGX_HUNK_LAST) { + if (size > ctx->hunk_size) + size = ctx->hunk_size; + + hunk_size = size; + + } else { + hunk_size = ctx->hunk_size; + } + } + + if (!ctx->hunk) + ngx_test_null(ctx->hunk, ngx_create_temp_hunk(hunk_size), ...); + + if (temp == FILE) { + n = ngx_read_file(hunk->fd, ctx->hunk->pos.mem, size); + + if (n == -1) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, + ngx_read_file_n " failed for client"); + return -1; + + } else { + ngx_assert((n == size), /* void */ ; , + r->connection->log, 0, + ngx_read_file_n " reads only %d of %d for client", + n, size); + } + + hunk->pos.mem += n; + ctx->hunk->last.mem += n; + + } else if (temp == COPY) { + ngx_memcpy(ctx->hunk->pos.mem, hunk->pos.mem, size); + + hunk->pos.mem += size; + ctx->hunk->last.mem += size; + } + + + + + + + /* if no hunk is passed and there is no our hunk + or our hunk is still busy then call next filter */ + if (hunk == NULL + && (ctx->hunk == NULL + || ((ctx->hunk != NULL) + && (ctx->hunk->pos.mem < ctx->hunk->last.mem)) + ) + ) + ctx->next_filter(r, NULL); + } + + /* hunk != NULL || ctx->hunk->pos.mem == ctx->hunk->last.mem */ + + /* find last link of saved chain */ + prev = &ctx->out; + for (ch = ctx->out; ch; ch = ch->next) { + prev = &ch->next; + } + + if hunk + if need our hunk - alloc it and add to our queue + else add hunk to our queue + +/* + size += ch->hunk->last.file - ch->hunk->pos.file; + + ngx_log_debug(r->connection->log, "old chunk: %x %qx %qd" _ + ch->hunk->type _ ch->hunk->pos.file _ + ch->hunk->last.file - ch->hunk->pos.file); + + if (ch->hunk->type & NGX_HUNK_FLUSH) + flush = size; + + if (ch->hunk->type & NGX_HUNK_LAST) + last = 1; + } +*/ + + /* add new chain to existent one */ + for (/* void */; in; in = in->next) { + ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), + NGX_HTTP_FILTER_ERROR); + + ch->hunk = h; + ch->next = NULL; + *prev = ch; + prev = &ch->next; + size += ch->hunk->last.file - ch->hunk->pos.file; + + ngx_log_debug(r->connection->log, "new chunk: %x %qx %qd" _ + ch->hunk->type _ ch->hunk->pos.file _ + ch->hunk->last.file - ch->hunk->pos.file); + + if (ch->hunk->type & NGX_HUNK_FLUSH) + flush = size; + + if (ch->hunk->type & NGX_HUNK_LAST) + last = 1; + } + + + + + +/* + !(HAVE_SENDFILE) == NGX_FILT_NEED_IN_MEMORY +*/ + + if ((r->filter & NGX_FILT_NEED_IN_MEMORY) && (h->type & NGX_HUNK_FILE)) { + + size = h->last.mem - h->pos.mem; + if (size > ctx->hunk_size) + size = ctx->hunk_size; + + if (!ctx->hunk) + ngx_test_null(ctx->hunk, ngx_create_temp_hunk(size), ...); + + ngx_read_file(h->fd, ctx->hunk->pos.mem, size); + + h->hunk->pos.mem += size; + } + + if ((r->filter & NGX_FILT_NEED_TEMP) + && (h->type & NGX_HUNK_MEMORY|NGX_HUNK_MMAP)) + { + size = h->last.mem - h->pos.mem; + if (size > ctx->hunk_size) + size = ctx->hunk_size; + + if (!ctx->hunk) + ngx_test_null(ctx->hunk, ngx_create_temp_hunk(size), ...); + + ngx_memcpy(ctx->hunk->pos.mem, h->pos.mem, size); + + h->hunk->pos.mem += size; + } + + + + + + + rc = ctx->next_filter(r, ch); + + /* STUB */ + rc = ngx_http_write_filter(r, ch); +} 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 @@ -34,7 +34,7 @@ int ngx_http_write_filter(ngx_http_reque ctx = (ngx_http_write_filter_ctx_t *) ngx_get_module_ctx(r->main ? r->main : r, - &ngx_http_write_filter_module); + &ngx_http_write_filter_module); size = flush = 0; last = 0; prev = &ctx->out; @@ -44,6 +44,10 @@ int ngx_http_write_filter(ngx_http_reque prev = &ch->next; size += ch->hunk->last.file - ch->hunk->pos.file; + ngx_log_debug(r->connection->log, "old chunk: %x %qx %qd" _ + ch->hunk->type _ ch->hunk->pos.file _ + ch->hunk->last.file - ch->hunk->pos.file); + if (ch->hunk->type & NGX_HUNK_FLUSH) flush = size; @@ -62,6 +66,10 @@ int ngx_http_write_filter(ngx_http_reque prev = &ch->next; size += ch->hunk->last.file - ch->hunk->pos.file; + ngx_log_debug(r->connection->log, "new chunk: %x %qx %qd" _ + ch->hunk->type _ ch->hunk->pos.file _ + ch->hunk->last.file - ch->hunk->pos.file); + if (ch->hunk->type & NGX_HUNK_FLUSH) flush = size; @@ -69,7 +77,7 @@ int ngx_http_write_filter(ngx_http_reque last = 1; } - if (flush == 0 && size < ctx->buffer_output) + if (!last && flush == 0 && size < ctx->buffer_output) return NGX_HTTP_FILTER_DONE; chain = ngx_event_write(r->connection, ctx->out, flush); diff --git a/src/os/freebsd/ngx_os_thread.c b/src/os/freebsd/ngx_os_thread.c deleted file mode 100644 --- a/src/os/freebsd/ngx_os_thread.c +++ /dev/null @@ -1,64 +0,0 @@ - -#include - -char *ngx_stacks_start; -char *ngx_stacks_end; -size_t ngx_stack_size; - - -/* handle thread-safe errno */ -static int errno0; /* errno for main thread */ -static int *errnos; - -int *__error() -{ - ngx_tid_t tid = ngx_gettid(); - return tid ? &(errnos[ngx_gettid()]) : &errno0; -} - - -int ngx_create_os_thread(ngx_os_tid_t *tid, void *stack, - int (*func)(void *arg), void *arg, ngx_log_t log) -{ - int id, err; - - id = rfork_thread(RFPROC|RFMEM, stack, func, arg); - err = ngx_errno; - - if (id == -1) - ngx_log_error(NGX_LOG_ERR, log, err, - "ngx_create_os_thread: rfork failed"); - else - *tid = id; - - return err; -} - - -int ngx_create_os_thread_env(int n, size_t size, ngx_log_t log) -{ - char *addr; - - /* create thread stacks */ - addr = mmap(NULL, n * size, PROT_READ|PROT_WRITE, MAP_ANON, -1, NULL); - if (addr == MAP_FAILED) { - ngx_log_error(NGX_LOG_ERR, log, ngx_errno, - "ngx_create_os_thread_stacks: mmap failed"); - return -1; - } - - nxg_stacks_start = addr; - nxg_stacks_end = addr + n * size; - nxg_stack_size = size; - - /* create thread errno array */ - ngx_test_null(errnos, ngx_calloc(n * sizeof(int)), -1); - - /* create thread tid array */ - ngx_test_null(ngx_os_tids, ngx_calloc(n * sizeof(ngx_os_tid_t)), -1); - - /* allow spinlock in malloc() */ - __isthreaded = 1; - - return 0; -} diff --git a/src/os/freebsd/ngx_os_thread.h b/src/os/freebsd/ngx_os_thread.h deleted file mode 100644 --- a/src/os/freebsd/ngx_os_thread.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _NGX_OS_THREAD_H_INCLUDED_ -#define _NGX_OS_THREAD_H_INCLUDED_ - - -typedef int ngx_os_tid_t; -typedef int ngx_tid_t; - - -extern char *ngx_stacks_start; -extern char *ngx_stacks_end; -extern size_t ngx_stack_size; - - -static inline ngx_tid_t ngx_gettid() -{ - char *sp; - - __asm__ ("mov %%esp,%0" : "=r" (sp)); - return (sp > ngx_stacks_end) ? 0: - (sp - ngx_stacks_start) / ngx_stack_size + 1; -} - - -#endif /* _NGX_OS_THREAD_H_INCLUDED_ */ diff --git a/src/os/unix/freebsd/ngx_rfork_thread.c b/src/os/unix/freebsd/ngx_rfork_thread.c new file mode 100644 --- /dev/null +++ b/src/os/unix/freebsd/ngx_rfork_thread.c @@ -0,0 +1,64 @@ + +#include + +char *ngx_stacks_start; +char *ngx_stacks_end; +size_t ngx_stack_size; + + +/* handle thread-safe errno */ +static int errno0; /* errno for main thread */ +static int *errnos; + +int *__error() +{ + ngx_tid_t tid = ngx_gettid(); + return tid ? &(errnos[ngx_gettid()]) : &errno0; +} + + +int ngx_create_thread(ngx_os_tid_t *tid, void *stack, + int (*func)(void *arg), void *arg, ngx_log_t log) +{ + int id, err; + + id = rfork_thread(RFPROC|RFMEM, stack, func, arg); + err = ngx_errno; + + if (id == -1) + ngx_log_error(NGX_LOG_ERR, log, err, + "ngx_create_os_thread: rfork failed"); + else + *tid = id; + + return err; +} + + +int ngx_create_thread_env(int n, size_t size, ngx_log_t log) +{ + char *addr; + + /* create thread stacks */ + addr = mmap(NULL, n * size, PROT_READ|PROT_WRITE, MAP_ANON, -1, NULL); + if (addr == MAP_FAILED) { + ngx_log_error(NGX_LOG_ERR, log, ngx_errno, + "ngx_create_os_thread_stacks: mmap failed"); + return -1; + } + + nxg_stacks_start = addr; + nxg_stacks_end = addr + n * size; + nxg_stack_size = size; + + /* create thread errno array */ + ngx_test_null(errnos, ngx_calloc(n * sizeof(int)), -1); + + /* create thread tid array */ + ngx_test_null(ngx_os_tids, ngx_calloc(n * sizeof(ngx_os_tid_t)), -1); + + /* allow spinlock in malloc() */ + __isthreaded = 1; + + return 0; +} diff --git a/src/os/unix/freebsd/ngx_rfork_thread.h b/src/os/unix/freebsd/ngx_rfork_thread.h new file mode 100644 --- /dev/null +++ b/src/os/unix/freebsd/ngx_rfork_thread.h @@ -0,0 +1,24 @@ +#ifndef _NGX_OS_THREAD_H_INCLUDED_ +#define _NGX_OS_THREAD_H_INCLUDED_ + + +typedef int ngx_os_tid_t; +typedef int ngx_tid_t; + + +extern char *ngx_stacks_start; +extern char *ngx_stacks_end; +extern size_t ngx_stack_size; + + +static inline ngx_tid_t ngx_gettid() +{ + char *sp; + + __asm__ ("mov %%esp,%0" : "=r" (sp)); + return (sp > ngx_stacks_end) ? 0: + (sp - ngx_stacks_start) / ngx_stack_size + 1; +} + + +#endif /* _NGX_OS_THREAD_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_sendfile.c b/src/os/unix/freebsd/ngx_sendfile.c rename from src/os/unix/ngx_sendfile.c rename to src/os/unix/freebsd/ngx_sendfile.c --- a/src/os/unix/ngx_sendfile.c +++ b/src/os/unix/freebsd/ngx_sendfile.c @@ -1,6 +1,8 @@ #include #include +#include +#include #include #include #include @@ -56,8 +58,8 @@ int ngx_sendfile(ngx_socket_t s, } } - ngx_log_debug(log, "ngx_sendfile: %d, @%qd %d:%qd" _ - rc _ offset _ nbytes _ *sent); + ngx_log_debug(log, "ngx_sendfile: %d, @%qd %qd:%d" _ + rc _ offset _ *sent _ nbytes); return 0; } diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h --- a/src/os/unix/ngx_errno.h +++ b/src/os/unix/ngx_errno.h @@ -10,6 +10,7 @@ typedef int ngx_err_t; #define NGX_ENOENT ENOENT #define NGX_EINTR EINTR #define NGX_EAGAIN EWOULDBLOCK +#define NGX_EADDRINUSE EADDRINUSE #define ngx_errno errno #define ngx_socket_errno errno diff --git a/src/os/unix/ngx_file.h b/src/os/unix/ngx_file.h new file mode 100644 --- /dev/null +++ b/src/os/unix/ngx_file.h @@ -0,0 +1,29 @@ +#ifndef _NGX_FILE_H_INCLUDED_ +#define _NGX_FILE_H_INCLUDED_ + + +#include +#include + +typedef int ngx_file_t; +typedef struct stat ngx_file_info_t; + + +#define ngx_open_file open +#define ngx_open_file_n "open" + +#define NGX_FILE_RDONLY O_RDONLY + + +#define ngx_file_type(file, sb) stat(file, sb) +#define ngx_file_type_n "stat" + +#define ngx_stat_fd(fd, sb) fstat(fd, sb) +#define ngx_stat_fd_n "fstat" + +#define ngx_is_dir(sb) (S_ISDIR(sb.st_mode)) +#define ngx_file_size(sb) sb.st_size +#define ngx_file_mtime(sb) sb.st_mtime + + +#endif /* _NGX_FILE_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,6 +3,8 @@ #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,5 +1,6 @@ #include +#include #include ssize_t ngx_sendv(ngx_socket_t s, ngx_iovec_t *iovec, int n, size_t *sent) diff --git a/src/os/unix/ngx_sendv.h b/src/os/unix/ngx_sendv.h --- a/src/os/unix/ngx_sendv.h +++ b/src/os/unix/ngx_sendv.h @@ -3,6 +3,7 @@ #include +#include typedef struct iovec ngx_iovec_t; #define ngx_iov_base iov_base diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h --- a/src/os/unix/ngx_socket.h +++ b/src/os/unix/ngx_socket.h @@ -12,5 +12,8 @@ typedef int ngx_socket_t; #define ngx_nonblocking(s) fcntl(s, F_SETFL, O_NONBLOCK) #define ngx_nonblocking_n "fcntl (O_NONBLOCK)" +#define ngx_close_socket close +#define ngx_close_socket_n "close" + #endif /* _NGX_SOCKET_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_stat.h b/src/os/unix/ngx_stat.h deleted file mode 100644 --- a/src/os/unix/ngx_stat.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _NGX_STAT_H_INCLUDED_ -#define _NGX_STAT_H_INCLUDED_ - - -#include -#include - -typedef struct stat ngx_stat_t; - -#define ngx_is_dir(sb) (S_ISDIR(sb.st_mode)) - -#define ngx_stat(file, sb) stat(file, sb) -#define ngx_stat_n "stat" - -#define ngx_fstat(file, fd, sb) fstat(fd, sb) -#define ngx_fstat_n "stat" - - -#endif /* _NGX_STAT_H_INCLUDED_ */ 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 @@ -14,6 +14,8 @@ typedef struct tm ngx_tm_t; #define ngx_tm_year tm_year #define ngx_tm_wday tm_wday +#define ngx_msleep(ms) usleep(ms * 1000) + void ngx_localtime(ngx_tm_t *tm); u_int ngx_msec(void); diff --git a/src/os/unix/ngx_types.h b/src/os/unix/ngx_types.h --- a/src/os/unix/ngx_types.h +++ b/src/os/unix/ngx_types.h @@ -5,8 +5,6 @@ #include -typedef int ngx_file_t; -typedef int ngx_socket_t; #endif /* _NGX_TYPES_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 @@ -11,6 +11,7 @@ typedef DWORD ngx_err_t; #define NGX_ENOENT ERROR_FILE_NOT_FOUND #define NGX_EAGAIN WSAEWOULDBLOCK +#define NGX_EADDRINUSE WSAEADDRINUSE int ngx_strerror_r(ngx_err_t err, char *errstr, size_t size); diff --git a/src/os/win32/ngx_file.h b/src/os/win32/ngx_file.h new file mode 100644 --- /dev/null +++ b/src/os/win32/ngx_file.h @@ -0,0 +1,52 @@ +#ifndef _NGX_FILE_H_INCLUDED_ +#define _NGX_FILE_H_INCLUDED_ + + +#include + + +/* INVALID_FILE_ATTRIBUTES specified but never defined at least in VC6SP2 */ +#ifndef INVALID_FILE_ATTRIBUTES +#define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF +#endif + +typedef HANDLE ngx_file_t; +typedef BY_HANDLE_FILE_INFORMATION ngx_file_info_t; + + +#define ngx_open_file(name, flags) \ + CreateFile(name, flags, \ + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, \ + NULL, OPEN_EXISTING, 0, NULL) + +#define ngx_open_file_n "CreateFile" + +#define NGX_FILE_RDONLY GENERIC_READ + + +int ngx_file_type(char *filename, ngx_file_info_t *fi); +#define ngx_file_type_n "GetFileAttributes" + +#define ngx_stat_fd(fd, fi) GetFileInformationByHandle(fd, fi) +#define ngx_stat_fd_n "GetFileInformationByHandle" + +#define ngx_is_dir(fi) (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + +#define ngx_file_size(fi) \ + fi.nFileSizeLow + +/* +#define ngx_file_size(fi) \ + ((off_t) fi.nFileSizeHigh << 32 & fi.nFileSizeLow) +*/ + +#define ngx_file_mtime(fi) fi.ftLastWriteTime + +/* +1970 - 1601: + 116444736000000000 + 19DB1DED53E8000 +*/ + + +#endif /* _NGX_FILE_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,7 @@ #include #include +#include #include #include #include @@ -52,16 +53,22 @@ int ngx_sendfile(ngx_socket_t s, ptfb = NULL; } +#if 0 tfrc = TransmitFile(s, fd, nbytes, 0, &olp, ptfb, 0); +#else + tfrc = TransmitFile(s, fd, nbytes, 0, NULL, ptfb, 0); +#endif if (tfrc == 0) tf_err = ngx_socket_errno; /* set sent */ +#if 0 rc = WSAGetOverlappedResult(s, &olp, (unsigned long *) sent, 0, NULL); +#endif - ngx_log_debug(log, "ngx_sendfile: %d, @%qd %d:%qd" _ - tfrc _ offset _ nbytes _ *sent); + ngx_log_debug(log, "ngx_sendfile: %d, @%I64d %I64d:%d" _ + tfrc _ offset _ *sent _ nbytes); if (rc == 0) { err = ngx_socket_errno; @@ -77,7 +84,8 @@ int ngx_sendfile(ngx_socket_t s, } ngx_log_error(NGX_LOG_INFO, log, tf_err, - "ngx_sendfile: TransmitFile sent only %qd bytes", *sent); + "ngx_sendfile: TransmitFile sent only %I64d bytes", + *sent); } if (rc == 0) 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,6 +4,7 @@ #include #include +#include #include #include diff --git a/src/os/win32/ngx_socket.c b/src/os/win32/ngx_socket.c --- a/src/os/win32/ngx_socket.c +++ b/src/os/win32/ngx_socket.c @@ -1,8 +1,8 @@ -#include +#include -#include -#include -#include +#include +#include +#include void ngx_init_sockets(ngx_log_t *log) @@ -12,6 +12,8 @@ void ngx_init_sockets(ngx_log_t *log) if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, "ngx_init_sockets: WSAStartup failed"); + + /* get AcceptEx(), TransmitFile() functions */ } int ngx_nonblocking(ngx_socket_t s) @@ -20,3 +22,10 @@ int ngx_nonblocking(ngx_socket_t s) return ioctlsocket(s, FIONBIO, &nb); } + +int ngx_blocking(ngx_socket_t s) +{ + unsigned long nb = 0; + + return ioctlsocket(s, FIONBIO, &nb); +} 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 @@ -3,14 +3,17 @@ #include +#include -typedef SOCKET ngx_socket_t; +typedef SOCKET ngx_socket_t; void ngx_init_sockets(ngx_log_t *log); int ngx_nonblocking_n(s); -#define ngx_nonblocking_n "ioctlsocket (FIONBIO)" +#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_stat.c b/src/os/win32/ngx_stat.c --- a/src/os/win32/ngx_stat.c +++ b/src/os/win32/ngx_stat.c @@ -3,6 +3,18 @@ #include +int ngx_file_type(char *file, ngx_file_info_t *sb) +{ + sb->dwFileAttributes = GetFileAttributes(file); + + if (sb->dwFileAttributes == INVALID_FILE_ATTRIBUTES) { + return -1; + } + + return 0; +} + +/* int ngx_stat(char *file, ngx_stat_t *sb) { *sb = GetFileAttributes(file); @@ -13,3 +25,4 @@ int ngx_stat(char *file, ngx_stat_t *sb) return 0; } +*/ diff --git a/src/os/win32/ngx_stat.h b/src/os/win32/ngx_stat.h --- a/src/os/win32/ngx_stat.h +++ b/src/os/win32/ngx_stat.h @@ -4,15 +4,17 @@ #include -/* INVALID_FILE_ATTRIBUTES specified but never defined */ +/* INVALID_FILE_ATTRIBUTES specified but never defined at least in VC6SP2 */ #ifndef INVALID_FILE_ATTRIBUTES #define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF #endif -typedef DWORD ngx_stat_t; +typedef BY_HANDLE_FILE_INFORMATION ngx_file_info_t; -#define ngx_is_dir(sb) (*sb & FILE_ATTRIBUTE_DIRECTORY) +#define ngx_file_type_n "GetFileAttributes" + +#define ngx_is_dir(fi) (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) #define ngx_stat_n "GetFileAttributes" @@ -20,7 +22,9 @@ typedef DWORD ngx_stat_t; #define ngx_fstat_n "GetFileAttributes" +/* int ngx_stat(char *file, ngx_stat_t *sb); +*/ #endif /* _NGX_STAT_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 @@ -5,6 +5,7 @@ #include typedef SYSTEMTIME ngx_tm_t; +typedef FILETIME ngx_mtime_t; #define ngx_tm_sec wSecond #define ngx_tm_min wMinute @@ -14,6 +15,7 @@ typedef SYSTEMTIME ngx_tm_t; #define ngx_tm_year wYear #define ngx_tm_wday wDayOfWeek +#define ngx_msleep Sleep #define ngx_localtime GetLocalTime #define ngx_msec GetTickCount 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 @@ -6,7 +6,6 @@ typedef HANDLE ngx_file_t; -typedef SOCKET ngx_socket_t; typedef long time_t; typedef unsigned __int64 off_t;