# HG changeset patch # User Igor Sysoev # Date 1029511623 0 # Node ID ffffe1499bce9debf5d4dabcc8280124e6d0dc32 # Parent d220029ac7f3531d6d84c32c82026fc299e3a361 nginx-0.0.1-2002-08-16-19:27:03 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -5,145 +5,91 @@ #include #include #include +#include +#include #include #include #include -/* +/* STUB */ #include -*/ - +/* */ -#if !(WIN32) -static int ngx_options(int argc, char *const *argv); -#endif - -char *ngx_root = "/home/is/work/xml/xml/html"; - -int ngx_http_init_connection(void *data); int ngx_max_conn = 512; -struct sockaddr_in ngx_addr = {0, AF_INET, 0, 0, 0}; -int ngx_backlog = 0; ngx_pool_t ngx_pool; ngx_log_t ngx_log; ngx_server_t ngx_server; +ngx_array_t ngx_listening_sockets; + + int main(int argc, char *const *argv) { - char addr_text[22]; - ngx_socket_t s; - ngx_listen_t ls; - int reuseaddr = 1; -#if (WIN32) - WSADATA wsd; - unsigned long nb = 1; -#endif + int i; + ngx_socket_t s; + ngx_listen_t *ls; + int reuseaddr = 1; ngx_log.log_level = NGX_LOG_DEBUG; ngx_pool.log = &ngx_log; - ngx_addr.sin_port = htons(8000); - ngx_addr.sin_family = AF_INET; -#if !(WIN32) - if (ngx_options(argc, argv) == -1) - ngx_log_error(NGX_LOG_EMERG, (&ngx_log), 0, "invalid argument"); -#endif + ngx_init_sockets(&ngx_log); + + /* TODO: read config */ - ngx_log_debug((&ngx_log), "%d, %s:%d" _ ngx_max_conn _ - inet_ntoa(ngx_addr.sin_addr) _ ntohs(ngx_addr.sin_port)); - -#if (WIN32) - if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) - ngx_log_error(NGX_LOG_EMERG, (&ngx_log), ngx_socket_errno, - "WSAStartup failed"); -#endif + /* 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 */ - s = socket(AF_INET, SOCK_STREAM, 0); - if (s == -1) - ngx_log_error(NGX_LOG_EMERG, &(ngx_log), ngx_socket_errno, - "socket failed"); - - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - (const void *) &reuseaddr, sizeof(int)) == -1) - ngx_log_error(NGX_LOG_EMERG, &(ngx_log), ngx_socket_errno, - "setsockopt (SO_REUSEADDR) failed"); + 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 (WIN32) - if (ioctlsocket(s, FIONBIO, &nb) == -1) - ngx_log_error(NGX_LOG_EMERG, &(ngx_log), ngx_socket_errno, - "ioctlsocket (FIONBIO) failed"); -#else - if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) - ngx_log_error(NGX_LOG_EMERG, &(ngx_log), ngx_socket_errno, - "fcntl (O_NONBLOCK) failed"); -#endif + 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 */ + + if (ngx_nonblocking(s) == -1) + ngx_log_error(NGX_LOG_EMERG, &(ngx_log), ngx_socket_errno, + ngx_nonblocking_n " %s failed", ls->addr_text); - ngx_snprintf(ngx_cpystrn(addr_text, inet_ntoa(ngx_addr.sin_addr), 16), - 7, ":%d", ntohs(ngx_addr.sin_port)); + 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 (bind(s, (struct sockaddr *) &ngx_addr, - sizeof(struct sockaddr_in)) == -1) - ngx_log_error(NGX_LOG_EMERG, &(ngx_log), ngx_socket_errno, - "bind to %s failed", 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); - if (listen(s, ngx_backlog) == -1) - ngx_log_error(NGX_LOG_EMERG, &(ngx_log), ngx_socket_errno, - "listen to %s failed", addr_text); + /* TODO: deferred accept */ - ngx_server.buff_size = 1024; - ngx_server.handler = ngx_http_init_connection; + ls->fd = s; + ls->server = &ngx_http_server; + ls->log = &ngx_log; + } - /* daemon */ + /* TODO: daemon */ - ls.fd = s; - ls.server = &ngx_server; - ls.log = &ngx_log; + /* TODO: fork */ + + /* TODO: events: init ngx_connections and listen slots */ - /* fork */ + /* TODO: threads */ + /* STUB */ ngx_worker(&ls, 1, &ngx_pool, &ngx_log); } - -#if !(WIN32) -extern char *optarg; - -static int ngx_options(int argc, char *const *argv) -{ - char ch, *pos; - int port; - - while ((ch = getopt(argc, argv, "l:c:")) != -1) { - switch (ch) { - case 'l': - if (pos = strchr(optarg, ':')) { - *(pos) = '\0'; - if ((port = atoi(pos + 1)) <= 0) - return -1; - ngx_addr.sin_port = htons(port); - } - - if ((ngx_addr.sin_addr.s_addr = inet_addr(optarg)) == INADDR_NONE) - return -1; - break; - - case 'c': - if ((ngx_max_conn = atoi(optarg)) <= 0) - return -1; - break; - - case '?': - default: - return -1; - } - - } - - return 0; -} -#endif diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -2,7 +2,7 @@ #define _NGINX_H_INCLUDED_ -extern char *gx_root; +#define NGINX_VER "nginx/0.0.1" #endif /* _NGINX_H_INCLUDED_ */ 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 @@ -18,11 +18,22 @@ typedef struct { ngx_socket_t fd; ngx_log_t *log; - ngx_server_t *server; + void *server; + + int family; + int type; + int protocol; - unsigned shared:1; + 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 accept_filter:1; + unsigned deferred_accept:1; #endif } ngx_listen_t; 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 @@ -12,11 +12,11 @@ static line http_codes[] = { - int ngx_http_header_filter(ngx_http_request_t *r) { int status; - ngx_hunk_t *h; + ngx_hunk_t *h; + ngx_chain_t *ch; ngx_test_null(h, ngx_get_hunk(r->pool, 1024, 0, 64), NGX_HTTP_FILTER_ERROR); @@ -51,5 +51,12 @@ int ngx_http_header_filter(ngx_http_requ h->pos.mem += sizeof(NGINX_VER); } *(h->pos.mem++) = CR; *(h->pos.mem++) = LF; - + + ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), + NGX_HTTP_FILTER_ERROR); + + ch->hunk = in->hunk; + ch->next = NULL; + + return ngx_http_write_filter(r, ch); } diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c new file mode 100644 --- /dev/null +++ b/src/http/ngx_http.c @@ -0,0 +1,45 @@ + +#include + + +/* STUB */ + +static struct sockaddr_in addr; +static char addr_text[22]; + +static ngx_http_server_t ngx_http_server; + +int ngx_http_init(ngx_pool_t *pool) +{ + ngx_listen_t *ls; + + ngx_http_server.handler = ngx_http_init_connection; + + 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); + + ls = ngx_push_array(ngx_listening_sockets); + ngx_memzero(ls, sizeof(nxg_listen_t)); + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(optarg) + addr.sin_port = htons(8000); + + ngx_snprintf(ngx_cpystrn(addr_text, inet_ntoa(addr.sin_addr), 16), + 7, ":%d", ntohs(addr.sin_port)); + + ls->family = AF_INET; + ls->type = SOCK_STREAM; + ls->protocol = 0; + ls->addr = &addr; + ls->addr_len = sizeof(sockaddr_in); + ls->text = &addr_text; + ls->backlog = -1; + ls->nonblocking = 1; + + 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 @@ -19,7 +19,15 @@ #define NGX_HTTP_CONN_CLOSE 0 #define NGX_HTTP_CONN_KEEP_ALIVE 1 -#define NGX_HTTP_OK 200 +#define NGX_OK 0 + +#define NGX_HTTP_OK 200 +#define NGX_HTTP_NOT_FOUND 404 +#define NGX_HTTP_INTERNAL_SERVER_ERROR 503 + + +#define NGX_HTTP_STATIC_HANDLER 0 +#define NGX_HTTP_DIRECTORY_HANDLER 1 typedef struct { @@ -30,6 +38,11 @@ typedef struct { #define ngx_get_module_ctx(r, module) (module)->ctx typedef struct { + char *doc_root; + int doc_root_len; +} ngx_http_server_t; + +typedef struct { char *buff; char *pos; char *last; @@ -50,6 +63,12 @@ typedef struct { typedef struct ngx_http_request_s ngx_http_request_t; struct ngx_http_request_s { + char *filename; + char *location; + + int filename_len; + int (*handler)(ngx_http_request_t *r); + int method; int http_version; @@ -59,7 +78,8 @@ struct ngx_http_request_s { char *uri; ngx_http_request_t *main; - ngx_connection_t *connection; + ngx_connection_t *connection; + ngx_http_server_t *server; ngx_buff_t *buff; ngx_pool_t *pool; 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 @@ -180,6 +180,78 @@ static int ngx_process_http_request_head static int ngx_process_http_request(ngx_http_request_t *r) { + int err; + char *name, *loc, *file; + + ngx_log_debug(r->connection->log, "HTTP request"); + + if (*(r->uri_end - 1) == '/') { + r->handler = NGX_HTTP_DIRECTORY_HANDLER; + return NGX_OK; + } + + /* 20 bytes is spare space for some index name, i.e. index.html */ + r->filename_len = r->uri_end - r->uri_start + r->server->doc_root_len + 20; + + ngx_test_null(r->filename, + ngx_palloc(r->pool, r->filename_len), + ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR)); + + r->location = ngx_cpystrn(r->filename, r->server->doc_root, + r->server->doc_root_len); + file = ngx_cpystrn(r->location, r->uri_start, + r->uri_end - r->uri_start + 1); + + ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->filename); + +} +#if 0 + + if (ngx_stat(r->filename, &r->stat) == -1) { + err = ngx_errno; + ngx_log_error(GX_LOG_ERR, r->connection->log, err, + "ngx_process_http_request: " + ngx_stat_n " %s failed", r->filename); + + if (err == NGX_ENOENT) + return ngx_http_error(r, NGX_HTTP_NOT_FOUND); + else + return ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + } + + if (ngx_is_dir(r->stat)) { + *file++ = '/'; + *file = '\0'; + r->headers_out->location = r->location; + return ngx_http_redirect(r, NGX_HTTP_MOVED_PERMANENTLY); + } + + r->stat_valid = 1; + r->handler = NGX_HTTP_STATIC_HANDLER; + return NGX_OK; +} + +static int ngx_http_handler(ngx_http_request_t *r, int handler) +{ + if (handler == NGX_HTTP_STATIC_HANDLER) + return ngx_http_static_handler(r); + + elsif (handler == NGX_HTTP_DIRECTORY_HANDLER) + return ngx_http_index_handler(r); + + return ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR); +} +#endif + +static int ngx_http_redirect(ngx_http_request_t *r, int redirect) +{ + /* STUB */ + return -1; +} + +static int ngx_http_error(ngx_http_request_t *r, int error) +{ + /* STUB */ return -1; } diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h new file mode 100644 --- /dev/null +++ b/src/os/unix/ngx_socket.h @@ -0,0 +1,16 @@ +#ifndef _NGX_SOCKET_H_INCLUDED_ +#define _NGX_SOCKET_H_INCLUDED_ + + +#include + + +typedef int ngx_socket_t; + +#define ngx_init_sockets + +#define ngx_nonblocking(s) fcntl(s, F_SETFL, O_NONBLOCK) +#define ngx_nonblocking_n "fcntl (O_NONBLOCK)" + + +#endif /* _NGX_SOCKET_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_socket.c b/src/os/win32/ngx_socket.c new file mode 100644 --- /dev/null +++ b/src/os/win32/ngx_socket.c @@ -0,0 +1,22 @@ +#include + +#include +#include +#include + + +void ngx_init_sockets(ngx_log_t *log) +{ + WSADATA wsd; + + if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + "ngx_init_sockets: WSAStartup failed"); +} + +int ngx_nonblocking(ngx_socket_t s) +{ + unsigned long nb = 1; + + return ioctlsocket(s, FIONBIO, &nb); +} diff --git a/src/os/win32/ngx_socket.h b/src/os/win32/ngx_socket.h new file mode 100644 --- /dev/null +++ b/src/os/win32/ngx_socket.h @@ -0,0 +1,16 @@ +#ifndef _NGX_SOCKET_H_INCLUDED_ +#define _NGX_SOCKET_H_INCLUDED_ + + +#include + +typedef SOCKET ngx_socket_t; + +void ngx_init_sockets(ngx_log_t *log); + +int ngx_nonblocking_n(s); +#define ngx_nonblocking_n "ioctlsocket (FIONBIO)" + + + +#endif /* _NGX_SOCKET_H_INCLUDED_ */