# HG changeset patch # User Igor Sysoev # Date 1042090560 0 # Node ID 0e81ac0bb3e214ea6cc48888c82810f62978c946 # Parent 53cd0589226152235201309b5aacbcbdfc194157 nginx-0.0.1-2003-01-09-08:36:00 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -36,7 +36,7 @@ ngx_pool_t *ngx_pool; int ngx_connection_counter; -ngx_array_t *ngx_listening_sockets; +ngx_array_t ngx_listening_sockets; int main(int argc, char *const *argv) @@ -56,9 +56,9 @@ int main(int argc, char *const *argv) ngx_init_sockets(&ngx_log); - /* TODO: read config */ + ngx_init_array(ngx_listening_sockets, ngx_pool, 10, sizeof(ngx_listen_t), + 1); -#if 1 ngx_memzero(&conf, sizeof(ngx_conf_t)); ngx_test_null(conf.args, ngx_create_array(ngx_pool, 10, sizeof(ngx_str_t)), 1); @@ -69,16 +69,16 @@ int main(int argc, char *const *argv) conf_file.len = sizeof("nginx.conf") - 1; conf_file.data = "nginx.conf"; - ngx_conf_parse(&conf, &conf_file); -#endif + if (ngx_conf_parse(&conf, &conf_file) != NGX_CONF_OK) { + exit(1); + } - ngx_test_null(ngx_listening_sockets, - ngx_create_array(ngx_pool, 10, sizeof(ngx_listen_t)), 1); - +#if 0 /* STUB */ /* TODO: init chain of global modules (like ngx_http.c), they would init its modules and ngx_listening_sockets */ ngx_http_init(ngx_pool, &ngx_log); +#endif ngx_open_listening_sockets(&ngx_log); @@ -86,7 +86,7 @@ int main(int argc, char *const *argv) /* TODO: fork */ - ngx_pre_thread(ngx_listening_sockets, ngx_pool, &ngx_log); + ngx_pre_thread(&ngx_listening_sockets, ngx_pool, &ngx_log); /* TODO: threads */ @@ -125,10 +125,10 @@ static void ngx_open_listening_sockets(n failed = 0; /* for each listening socket */ - ls = (ngx_listen_t *) ngx_listening_sockets->elts; - for (i = 0; i < ngx_listening_sockets->nelts; i++) { + ls = (ngx_listen_t *) ngx_listening_sockets.elts; + for (i = 0; i < ngx_listening_sockets.nelts; i++) { - if (ls[i].done) + if (ls[i].bound) continue; if (ls[i].inherited) { @@ -137,7 +137,7 @@ static void ngx_open_listening_sockets(n /* TODO: nonblocking */ /* TODO: deferred accept */ - ls[i].done = 1; + ls[i].bound = 1; continue; } @@ -194,7 +194,7 @@ static void ngx_open_listening_sockets(n /* TODO: deferred accept */ ls[i].fd = s; - ls[i].done = 1; + ls[i].bound = 1; } if (!failed) diff --git a/src/core/ngx_alloc.h b/src/core/ngx_alloc.h --- a/src/core/ngx_alloc.h +++ b/src/core/ngx_alloc.h @@ -10,7 +10,7 @@ #define NGX_MAX_ALLOC_FROM_POOL (8192 - sizeof(ngx_pool_t)) #define NGX_DEFAULT_POOL_SIZE (16 * 1024) -#define ngx_test_null(p, alloc, rc) if ((p = alloc) == NULL) return rc +#define ngx_test_null(p, alloc, rc) if ((p = alloc) == NULL) { return rc; } typedef struct ngx_pool_large_s ngx_pool_large_t; diff --git a/src/core/ngx_array.c b/src/core/ngx_array.c --- a/src/core/ngx_array.c +++ b/src/core/ngx_array.c @@ -2,19 +2,17 @@ #include #include +#include #include + ngx_array_t *ngx_create_array(ngx_pool_t *p, int n, size_t size) { ngx_array_t *a; - a = ngx_palloc(p, sizeof(ngx_array_t)); - if (a == NULL) - return NULL; + ngx_test_null(a, ngx_palloc(p, sizeof(ngx_array_t)), NULL); - a->elts = ngx_palloc(p, n * size); - if (a->elts == NULL) - return NULL; + ngx_test_null(a->elts, ngx_palloc(p, n * size), NULL); a->pool = p; a->nelts = 0; @@ -24,24 +22,31 @@ ngx_array_t *ngx_create_array(ngx_pool_t return a; } + void ngx_destroy_array(ngx_array_t *a) { - ngx_pool_t *p = a->pool; + ngx_pool_t *p; - if (a->elts + a->size * a->nalloc == p->last) + p = a->pool; + + if (a->elts + a->size * a->nalloc == p->last) { p->last -= a->size * a->nalloc; + } - if ((char *) a + sizeof(ngx_array_t) == p->last) + if ((char *) a + sizeof(ngx_array_t) == p->last) { p->last = (char *) a; + } } + void *ngx_push_array(ngx_array_t *a) { - void *elt; + void *elt, *new; + ngx_pool_t *p; /* array is full */ if (a->nelts == a->nalloc) { - ngx_pool_t *p = a->pool; + p = a->pool; /* array allocation is the last in the pool */ if (a->elts + a->size * a->nelts == p->last @@ -52,11 +57,9 @@ void *ngx_push_array(ngx_array_t *a) /* allocate new array */ } else { - void *new = ngx_palloc(p, 2 * a->nalloc * a->size); - if (new == NULL) - return NULL; + ngx_test_null(new, ngx_palloc(p, 2 * a->nalloc * a->size), NULL); - memcpy(new, a->elts, a->nalloc * a->size); + ngx_memcpy(new, a->elts, a->nalloc * a->size); a->elts = new; a->nalloc *= 2; } diff --git a/src/core/ngx_array.h b/src/core/ngx_array.h --- a/src/core/ngx_array.h +++ b/src/core/ngx_array.h @@ -20,4 +20,9 @@ void ngx_destroy_array(ngx_array_t *a); void *ngx_push_array(ngx_array_t *a); +#define ngx_init_array(a, p, n, s, rc) \ + ngx_test_null(a.elts, ngx_palloc(p, n * s), rc); \ + a.nelts = 0; a.size = s; a.nalloc = n; a.pool = p; + + #endif /* _NGX_ARRAY_H_INCLUDED_ */ diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -13,10 +13,11 @@ static int argument_number[] = { static int ngx_conf_read_token(ngx_conf_t *cf); -int ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename) +char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename) { - int rc, i; - char *error; + int i, rc, found; + char *rv; + void *conf, **pconf; ngx_str_t *name; ngx_fd_t fd; ngx_conf_file_t *prev; @@ -29,13 +30,13 @@ int ngx_conf_parse(ngx_conf_t *cf, ngx_s ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno, "ngx_conf_file: " ngx_open_file_n " %s failed", filename->data); - return NGX_ERROR; + return NGX_CONF_ERROR; } prev = cf->conf_file; ngx_test_null(cf->conf_file, ngx_palloc(cf->pool, sizeof(ngx_conf_file_t)), - NGX_ERROR); + NGX_CONF_ERROR); if (ngx_stat_fd(fd, &cf->conf_file->file.info) == -1) { ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno, @@ -45,7 +46,7 @@ int ngx_conf_parse(ngx_conf_t *cf, ngx_s ngx_test_null(cf->conf_file->hunk, ngx_create_temp_hunk(cf->pool, 1024, 0, 0), - NGX_ERROR); + NGX_CONF_ERROR); cf->conf_file->file.fd = fd; cf->conf_file->file.name.len = filename->len; @@ -59,22 +60,29 @@ int ngx_conf_parse(ngx_conf_t *cf, ngx_s /* NGX_OK, NGX_ERROR, NGX_CONF_FILE_DONE, NGX_CONF_BLOCK_DONE */ - if (rc == NGX_ERROR || rc == NGX_CONF_FILE_DONE) { - return rc; +ngx_log_debug(cf->log, "token %d" _ rc); + + if (rc == NGX_ERROR) { + return NGX_CONF_ERROR; + } + + if (rc != NGX_OK) { + return NGX_CONF_OK; } if (cf->handler) { - if ((*cf->handler)(cf) == NGX_ERROR) { - return NGX_ERROR; + if ((*cf->handler)(cf) == NGX_CONF_ERROR) { + return NGX_CONF_ERROR; } continue; } name = (ngx_str_t *) cf->args->elts; + found = 0; - for (i = 0; ngx_modules[i]; i++) { + for (i = 0; !found && ngx_modules[i]; i++) { if (ngx_modules[i]->type != NULL && ngx_modules[i]->type != cf->type) { @@ -93,86 +101,56 @@ int ngx_conf_parse(ngx_conf_t *cf, ngx_s ngx_log_debug(cf->log, "command '%s'" _ cmd->name.data); - cmd->set(cf, cmd, NULL); + if (!(cmd->type & argument_number[cf->args->nelts - 1])) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "invalid number arguments in " + "directive \"%s\" in %s:%d", + name->data, + cf->conf_file->file.name.data, + cf->conf_file->line); + return NGX_CONF_ERROR; + } + + conf = NULL; + if (cf->ctx) { + pconf = *(void **) ((char *) cf->ctx + cmd->conf); + + if (pconf) { + conf = pconf[ngx_modules[i]->index]; + } + } + + rv = cmd->set(cf, cmd, conf); + +ngx_log_debug(cf->log, "rv: %d" _ rv); + + if (rv == NGX_CONF_OK) { + found = 1; + break; + + } else if (rv == NGX_CONF_ERROR) { + return NGX_CONF_ERROR; + + } else { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "%s", rv); + return NGX_CONF_ERROR; + } } cmd++; } - } - -#if 0 - cmd = ngx_conf_find_token(cf); - if (cmd == NULL) { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "unknown directive \"%s\" in %s:%d", - cf->name, cf->file->name, cf->file->line); - return NGX_ERROR; } - if (cmd->type & argument_number[cf->args->nelts - 1]) { - error = cmd->set(cf, cmd->offset, cf->args); - - if (error) { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "%s in directive \"%s\" in %s:%d", - error, cf->name, cf->file->name, cf->file->line); - return NGX_ERROR; - } - } -#endif - -#if 0 - if (cmd->type == NGX_CONF_CONTAINER) { - ngx_conf_parse(cf, cmd->container, NULL); - - } else if (cmd->type == NGX_CONF_FLAG) { - - if (cf->args->nelts != 1) { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "invalid number of arguments " - "in directive \"%s\" in %s:%d", - cf->name, cf->file->name, cf->file->line); - return NGX_ERROR; - } - - if (ngx_strcasecmp(cf->args->elts[0], "on") == 0) { - flag = 1; - - } else if (ngx_strcasecmp(cf->args->elts[0], "off") == 0) { - flag = 0; + if (!found) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "unknown directive \"%s\" in %s:%d", + name->data, + cf->conf_file->file.name.data, + cf->conf_file->line); - } else { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "invalid flag in directive \"%s\" in %s:%d", - cf->name, cf->file->name, cf->file->line); - return NGX_ERROR; - } - - rv = cmd->set(cf, cmd->offset, flag); - if (rv) { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "%s in directive \"%s\" in %s:%d", - rv, cf->name, cf->file->name, cf->file->line); - return NGX_ERROR; - } - - } else if (cmd->type & argument_number[args->nelts]) { - rv = cmd->set(cf, cmd->offset, cf->args); - if (rv) { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "%s in directive \"%s\" in %s:%d", - rv, cf->name, cf->file->name, cf->file->line); - return NGX_ERROR; - } - - } else { - ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "invalid number of arguments " - "in directive \"%s\" in %s:%d", - cf->name, cf->file->name, cf->file->line); - return NGX_ERROR; + return NGX_CONF_ERROR; } -#endif } if (filename) { @@ -182,11 +160,11 @@ ngx_log_debug(cf->log, "command '%s'" _ ngx_log_error(NGX_LOG_ERR, cf->log, ngx_errno, ngx_close_file_n " %s failed", cf->conf_file->file.name.data); - return NGX_ERROR; + return NGX_CONF_ERROR; } } - return NGX_OK; + return NGX_CONF_OK; } @@ -391,6 +369,20 @@ ngx_log_debug(cf->log, "FOUND %d:'%s'" _ } +char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +{ + ngx_str_t *field, *value; + + field = (ngx_str_t *) conf + cmd->offset; + value = (ngx_str_t *) cf->args->elts; + + field->len = value->len; + field->data = value->data; + + return NGX_CONF_OK; +} + + char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) { int size; @@ -405,7 +397,7 @@ char *ngx_conf_set_size_slot(ngx_conf_t *(int *) (conf + cmd->offset) = size; - return NULL; + return NGX_CONF_OK; } @@ -423,5 +415,5 @@ char *ngx_conf_set_time_slot(ngx_conf_t *(int *) (conf + cmd->offset) = size; - return NULL; + return NGX_CONF_OK; } diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -15,15 +15,16 @@ #define NGX_CONF_NOARGS 1 #define NGX_CONF_TAKE1 2 #define NGX_CONF_TAKE2 4 -#define NGX_CONF_ARGS_NUMBER 0x0ffff -#define NGX_CONF_ANY 0x10000 -#define NGX_CONF_BLOCK 0x20000 +#define NGX_CONF_ARGS_NUMBER 0x00ffff +#define NGX_CONF_ANY 0x010000 +#define NGX_CONF_BLOCK 0x020000 #define NGX_CONF_UNSET -1 -#define NGX_CONF_ERROR (char *) -1 +#define NGX_CONF_OK NULL +#define NGX_CONF_ERROR (void *) -1 #define NGX_CONF_BLOCK_DONE 1 #define NGX_CONF_FILE_DONE 2 @@ -46,6 +47,7 @@ struct ngx_command_s { typedef struct { + int index; void *ctx; ngx_command_t *commands; int type; @@ -70,13 +72,21 @@ struct ngx_conf_s { void *ctx; int type; - int (*handler)(ngx_conf_t *cf); + char *(*handler)(ngx_conf_t *cf); }; -int ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename); +#define ngx_conf_merge(conf, prev, default) \ + if (conf == NGX_CONF_UNSET) { \ + conf = (prev == NGX_CONF_UNSET) ? default : prev; \ + } + +char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename); + + +char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); char *ngx_conf_set_time_slot(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); 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 @@ -30,16 +30,18 @@ struct ngx_connection_s { off_t sent; + int (*handler)(ngx_connection_t *c); + void *ctx; + ngx_server_t *servers; + + ngx_pool_t *pool; ngx_log_t *log; - int (*handler)(ngx_connection_t *c); - ngx_server_t *server; - ngx_server_t *servers; - ngx_pool_t *pool; int family; struct sockaddr *sockaddr; socklen_t socklen; - size_t addr; + int addr; + int addr_text_max_len; ngx_str_t addr_text; ngx_hunk_t *buffer; 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 @@ -9,36 +9,44 @@ #include typedef struct { - ngx_socket_t fd; + ngx_socket_t fd; struct sockaddr *sockaddr; - socklen_t socklen; - size_t addr; + socklen_t socklen; /* size of sockaddr */ + int addr; /* offset to address in sockaddr */ + int addr_text_max_len; ngx_str_t addr_text; - int family; - int type; - int protocol; - int flags; + int family; + int type; + int protocol; + int flags; /* Winsock2 flags */ - ngx_log_t *log; - void *server; - int (*handler)(ngx_connection_t *c); + int (*handler)(ngx_connection_t *c); /* handler of accepted + connection */ + void *ctx; /* ngx_http_conf_ctx_t, for example */ + void *servers; /* array of ngx_http_in_addr_t, for example */ + + ngx_log_t *log; - int backlog; - time_t post_accept_timeout; + int backlog; + time_t post_accept_timeout; /* should be here because + of the deferred accept */ - unsigned done:1; - unsigned inherited:1; - unsigned nonblocking:1; + unsigned bound:1; /* already bound */ + unsigned inherited:1; /* inherited from previous process */ + unsigned nonblocking:1; #if 0 - unsigned overlapped:1; + unsigned overlapped:1; /* Winsock2 overlapped */ #endif - unsigned shared:1; /* shared between threads or processes */ + unsigned shared:1; /* shared between threads or processes */ #if (HAVE_DEFERRED_ACCEPT) - unsigned deferred_accept:1; + unsigned deferred_accept:1; #endif } ngx_listen_t; +extern ngx_array_t ngx_listening_sockets; + + #endif /* _NGX_LISTEN_H_INCLUDED_ */ diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -18,7 +18,8 @@ typedef struct { #define ngx_memzero ZeroMemory -#define strcasecmp stricmp +#define ngx_strcasecmp stricmp +#define ngx_strncmp strncmp #define ngx_strcmp strcmp #define ngx_snprintf _snprintf @@ -28,6 +29,7 @@ typedef struct { #define ngx_memzero bzero +#define ngx_strncmp strncmp #define ngx_strcmp strcmp #define ngx_snprintf snprintf 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 @@ -84,8 +84,9 @@ void ngx_pre_thread(ngx_array_t *ls, ngx /* STUB */ int max_connections = 512; - if (ngx_init_events(max_connections, log) == NGX_ERROR) + if (ngx_init_events(max_connections, log) == NGX_ERROR) { exit(1); + } ngx_connections = ngx_alloc(sizeof(ngx_connection_t) * max_connections, log); @@ -101,43 +102,44 @@ void ngx_pre_thread(ngx_array_t *ls, ngx c = &ngx_connections[fd]; ev = &ngx_read_events[fd]; - ngx_memzero(&ngx_connections[fd], sizeof(ngx_connection_t)); - ngx_memzero(&ngx_read_events[fd], sizeof(ngx_event_t)); + ngx_memzero(c, sizeof(ngx_connection_t)); + ngx_memzero(ev, sizeof(ngx_event_t)); - ngx_connections[fd].fd = fd; - ngx_connections[fd].family = s[i].family; - ngx_connections[fd].socklen = s[i].socklen; - ngx_connections[fd].sockaddr = ngx_palloc(pool, s[i].socklen); - ngx_connections[fd].addr = s[i].addr; - ngx_connections[fd].addr_text = s[i].addr_text; - ngx_connections[fd].post_accept_timeout = s[i].post_accept_timeout; + c->fd = fd; + c->family = s[i].family; + c->socklen = s[i].socklen; + c->sockaddr = ngx_palloc(pool, s[i].socklen); + c->addr = s[i].addr; + c->addr_text = s[i].addr_text; + c->addr_text_max_len = s[i].addr_text_max_len; + c->post_accept_timeout = s[i].post_accept_timeout; - ngx_connections[fd].server = s[i].server; - ngx_connections[fd].handler = s[i].handler; - ngx_connections[fd].log = s[i].log; + c->handler = s[i].handler; + c->ctx = s[i].ctx; + c->servers = s[i].servers; + c->log = s[i].log; - ngx_test_null(ngx_read_events[fd].log, + ngx_test_null(ev->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_memcpy(ev->log, c->log, sizeof(ngx_log_t)); c->read = ev; - ngx_read_events[fd].data = &ngx_connections[fd]; - ngx_read_events[fd].event_handler = &ngx_event_accept; - ngx_read_events[fd].listening = 1; + ev->data = c; + ev->event_handler = &ngx_event_accept; + ev->listening = 1; ev->index = NGX_INVALID_INDEX; - ngx_read_events[fd].available = 0; + ev->available = 0; #if (HAVE_DEFERRED_ACCEPT) - ngx_read_events[fd].deferred_accept = s[i].deferred_accept; + ev->deferred_accept = s[i].deferred_accept; #endif - ngx_add_event(&ngx_read_events[fd], NGX_READ_EVENT, 0); + ngx_add_event(ev, NGX_READ_EVENT, 0); } } void ngx_worker(ngx_log_t *log) { - while (1) { + for ( ;; ) { ngx_log_debug(log, "ngx_worker cycle"); ngx_process_events(log); 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 @@ -98,12 +98,14 @@ typedef struct { /* NGX_LEVEL_EVENT (default) select, poll, /dev/poll, kqueue requires to read whole data -NGX_ONESHOT_EVENT select, poll, kqueue -NGX_CLEAR_EVENT kqueue +NGX_ONESHOT_EVENT select, poll, /dev/poll(*), kqueue, epoll(*) + (*) - additional syscall +NGX_CLEAR_EVENT kqueue, epoll NGX_AIO_EVENT overlapped, aio_read, aioread no need to add or delete events NGX_CLOSE_EVENT kqueue: kqueue deletes events for file that closed + /dev/poll: need to flush events before closing */ #define NGX_CLOSE_EVENT 1 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 @@ -59,7 +59,7 @@ int ngx_event_accept(ngx_event_t *ev) c->family = ac->family; c->socklen = ac->socklen; c->addr = ac->addr; - c->addr_text.len = ac->addr_text.len; + c->addr_text_max_len = ac->addr_text_max_len; c->post_accept_timeout = ac->post_accept_timeout; rev->index = wev->index = NGX_INVALID_INDEX; @@ -77,7 +77,7 @@ int ngx_event_accept(ngx_event_t *ev) wev->timer_handler = rev->timer_handler = ngx_event_close_connection; wev->close_handler = rev->close_handler = ngx_event_close_connection; - c->server = ac->server; + c->ctx = ac->ctx; c->servers = ac->servers; c->log = rev->log = wev->log = ev->log; 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 @@ -102,7 +102,9 @@ ngx_chain_t *ngx_event_write(ngx_connect sent = rc > 0 ? rc: 0; +#if (NGX_DEBUG_EVENT_WRITE) ngx_log_debug(c->log, "sendv: " QD_FMT _ sent); +#endif } #if (HAVE_MAX_SENDFILE_IOVEC) } @@ -115,17 +117,21 @@ ngx_chain_t *ngx_event_write(ngx_connect for (ch = in; ch; ch = ch->next) { - ngx_log_debug(c->log, "ch event write: %x %qx %qd" _ +#if (NGX_DEBUG_EVENT_WRITE) + ngx_log_debug(c->log, "event write: %x " QX_FMT " " QD_FMT _ ch->hunk->type _ ch->hunk->pos.file _ ch->hunk->last.file - ch->hunk->pos.file); +#endif if (sent >= ch->hunk->last.file - ch->hunk->pos.file) { sent -= ch->hunk->last.file - ch->hunk->pos.file; ch->hunk->pos.file = ch->hunk->last.file; +#if (NGX_DEBUG_EVENT_WRITE) ngx_log_debug(c->log, "event write: " QX_FMT " 0 " QD_FMT _ ch->hunk->pos.file _ sent); +#endif /* if (ch->hunk->type & NGX_HUNK_LAST) @@ -137,9 +143,11 @@ ngx_chain_t *ngx_event_write(ngx_connect ch->hunk->pos.file += sent; - ngx_log_debug(c->log, "event write: %qx %qd" _ +#if (NGX_DEBUG_EVENT_WRITE) + ngx_log_debug(c->log, "event write: " QX_FMT " " QD_FMT _ ch->hunk->pos.file _ ch->hunk->last.file - ch->hunk->pos.file); +#endif break; } diff --git a/src/http/modules/ngx_http_event_proxy_handler.c b/src/http/modules/ngx_http_event_proxy_handler.c --- a/src/http/modules/ngx_http_event_proxy_handler.c +++ b/src/http/modules/ngx_http_event_proxy_handler.c @@ -39,13 +39,15 @@ int ngx_http_proxy_handler(ngx_http_requ p = (ngx_http_proxy_ctx_t *) ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); - if (p == NULL) + if (p == NULL) { ngx_http_create_ctx(r, p, ngx_http_proxy_module_ctx, sizeof(ngx_http_proxy_ctx_t)); + } chain = ngx_http_proxy_create_request(r); - if (chain == NULL) + if (chain == NULL) { return NGX_ERROR; + } p->out = chain; @@ -75,11 +77,13 @@ static ngx_chain_t *ngx_http_proxy_creat header = (ngx_table_elt_t *) r->headers_in.headers->elts; for (i = 0; i < r->headers_in.headers->nelts; i++) { - if (&header[i] == r->headers_in.host) + if (&header[i] == r->headers_in.host) { continue; + } - if (&header[i] == r->headers_in.connection) + if (&header[i] == r->headers_in.connection) { continue; + } /* 2 is for ": " and 2 is for "\r\n" */ len += header[i].key.len + 2 + header[i].value.len + 2; @@ -98,11 +102,13 @@ static ngx_chain_t *ngx_http_proxy_creat hunk->last.mem += sizeof(conn_close) - 1; for (i = 0; i < r->headers_in.headers->nelts; i++) { - if (&header[i] == r->headers_in.host) + if (&header[i] == r->headers_in.host) { continue; + } - if (&header[i] == r->headers_in.connection) + if (&header[i] == r->headers_in.connection) { continue; + } ngx_memcpy(hunk->last.mem, header[i].key.data, header[i].key.len); hunk->last.mem += header[i].key.len; @@ -115,7 +121,7 @@ static ngx_chain_t *ngx_http_proxy_creat *(hunk->last.mem++) = CR; *(hunk->last.mem++) = LF; ngx_log_debug(r->connection->log, "proxy: '%s: %s'" _ - header[i].key.data _ header[i].value.data); + header[i].key.data _ header[i].value.data); } /* add "\r\n" at the header end */ @@ -157,9 +163,10 @@ static int ngx_http_proxy_connect(ngx_ht ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, "setsockopt(SO_RCVBUF) failed"); - if (ngx_close_socket(s) == -1) + if (ngx_close_socket(s) == -1) { ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, ngx_close_socket_n " failed"); + } return NGX_ERROR; } @@ -170,9 +177,10 @@ static int ngx_http_proxy_connect(ngx_ht ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, ngx_nonblocking_n " failed"); - if (ngx_close_socket(s) == -1) + if (ngx_close_socket(s) == -1) { ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, ngx_close_socket_n " failed"); + } return NGX_ERROR; } @@ -184,9 +192,10 @@ static int ngx_http_proxy_connect(ngx_ht if (err != NGX_EINPROGRESS) { ngx_log_error(NGX_LOG_ERR, c->log, err, "connect() failed"); - if (ngx_close_socket(s) == -1) + if (ngx_close_socket(s) == -1) { ngx_log_error(NGX_LOG_ERR, c->log, ngx_socket_errno, ngx_close_socket_n " failed"); + } return NGX_ERROR; } @@ -207,7 +216,6 @@ static int ngx_http_proxy_connect(ngx_ht pc->data = r; pc->fd = s; - pc->server = c->server; pc->servers = c->servers; pc->log = rev->log = wev->log = c->log; @@ -220,14 +228,16 @@ static int ngx_http_proxy_connect(ngx_ht rev->event_handler = ngx_http_proxy_read_response_header; #if (HAVE_CLEAR_EVENT) - if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) != NGX_OK) + if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) != NGX_OK) { #else - if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) != NGX_OK) + if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) != NGX_OK) { #endif return NGX_ERROR; + } - if (rc == -1) + if (rc == -1) { return ngx_add_event(wev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT); + } wev->write = 1; wev->ready = 1; @@ -249,8 +259,9 @@ static int ngx_http_proxy_send_request(n ngx_http_get_module_ctx(r, ngx_http_proxy_module_ctx); chain = ngx_event_write(c, p->out, 0); - if (chain == (ngx_chain_t *) -1) + if (chain == (ngx_chain_t *) -1) { return NGX_ERROR; + } p->out = chain; @@ -266,8 +277,9 @@ static int ngx_http_proxy_read_response_ ngx_http_request_t *r; ngx_http_proxy_ctx_t *p; - if (ev->timedout) + if (ev->timedout) { return NGX_ERROR; + } c = (ngx_connection_t *) ev->data; r = (ngx_http_request_t *) c->data; @@ -330,8 +342,9 @@ static int ngx_http_proxy_read_response_ do { rc = (p->state_handler)(r, p); - if (rc == NGX_ERROR) + if (rc == NGX_ERROR) { return rc; + } /* rc == NGX_OK || rc == NGX_AGAIN */ @@ -339,8 +352,9 @@ static int ngx_http_proxy_read_response_ #endif ev->event_handler = ngx_http_proxy_read_response_body; - if (p->header_in->end - p->header_in->last.mem == 0) + if (p->header_in->end - p->header_in->last.mem == 0) { return ngx_http_proxy_read_response_body(ev); + } return NGX_WAITING; } @@ -406,11 +420,15 @@ static int ngx_http_proxy_read_response_ #if (HAVE_KQUEUE) #if !(USE_KQUEUE) - if (ngx_event_type == NGX_KQUEUE_EVENT) + if (ngx_event_type == NGX_KQUEUE_EVENT) { #endif /* do not allocate new block if there is EOF */ - if (ev->eof && ev->available == 0) + if (ev->eof && ev->available == 0) { left = 1; + } +#if !(USE_KQUEUE) + } +#endif #endif if (left == 0) { ngx_test_null(ph, ngx_push_array(p->hunks), NGX_ERROR); @@ -427,11 +445,13 @@ static int ngx_http_proxy_read_response_ ngx_log_debug(c->log, "READ:%d" _ n); - if (n == NGX_AGAIN) + if (n == NGX_AGAIN) { return NGX_WAITING; + } - if (n == NGX_ERROR) + if (n == NGX_ERROR) { return NGX_ERROR; + } h->last.mem += n; left = h->end - h->last.mem; @@ -475,11 +495,13 @@ static int ngx_http_proxy_write_to_clien h = ((ngx_hunk_t **) p->hunks->elts)[p->hunk_n]; rc = ngx_http_output_filter(r, h); - if (rc != NGX_OK) + if (rc != NGX_OK) { return rc; + } - if (p->hunk_n >= p->hunks->nelts) + if (p->hunk_n >= p->hunks->nelts) { break; + } p->hunk_n++; @@ -519,12 +541,15 @@ fprintf(stderr, "state: %d, pos: %x, end /* "HTTP/" */ case sw_start: - if (p + 3 >= ctx->header_in->last.mem) + if (p + 3 >= ctx->header_in->last.mem) { return NGX_AGAIN; + } if (ch != 'H' || *p != 'T' || *(p + 1) != 'T' || *(p + 2) != 'P' || *(p + 3) != '/') + { return NGX_HTTP_PROXY_PARSE_NO_HEADER; + } p += 4; state = sw_first_major_digit; @@ -532,8 +557,9 @@ fprintf(stderr, "state: %d, pos: %x, end /* first digit of major HTTP version */ case sw_first_major_digit: - if (ch < '1' || ch > '9') + if (ch < '1' || ch > '9') { return NGX_HTTP_PROXY_PARSE_NO_HEADER; + } state = sw_major_digit; break; @@ -545,15 +571,17 @@ fprintf(stderr, "state: %d, pos: %x, end break; } - if (ch < '0' || ch > '9') + if (ch < '0' || ch > '9') { return NGX_HTTP_PROXY_PARSE_NO_HEADER; + } break; /* first digit of minor HTTP version */ case sw_first_minor_digit: - if (ch < '0' || ch > '9') + if (ch < '0' || ch > '9') { return NGX_HTTP_PROXY_PARSE_NO_HEADER; + } state = sw_minor_digit; break; @@ -565,15 +593,17 @@ fprintf(stderr, "state: %d, pos: %x, end break; } - if (ch < '0' || ch > '9') + if (ch < '0' || ch > '9') { return NGX_HTTP_PROXY_PARSE_NO_HEADER; + } break; /* HTTP status code */ case sw_status: - if (ch < '0' || ch > '9') + if (ch < '0' || ch > '9') { return NGX_HTTP_PROXY_PARSE_NO_HEADER; + } ctx->status = ctx->status * 10 + ch - '0'; @@ -630,10 +660,13 @@ fprintf(stderr, "state: %d, pos: %x, end ctx->header_in->pos.mem = p; if (state == sw_done) { - if (ctx->request_end == NULL) + if (ctx->request_end == NULL) { ctx->request_end = p - 1; + } + ctx->state = sw_start; return NGX_OK; + } else { ctx->state = state; return NGX_AGAIN; diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c --- a/src/http/modules/ngx_http_index_handler.c +++ b/src/http/modules/ngx_http_index_handler.c @@ -9,11 +9,12 @@ #include #include +#include #include static void *ngx_http_index_create_conf(ngx_pool_t *pool); -static void *ngx_http_index_merge_conf(ngx_pool_t *p, +static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child); static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); @@ -50,6 +51,7 @@ ngx_http_module_t ngx_http_index_module ngx_module_t ngx_http_index_module = { + 0, /* module index */ &ngx_http_index_module_ctx, /* module context */ ngx_http_index_commands, /* module directives */ NGX_HTTP_MODULE_TYPE, /* module type */ @@ -65,18 +67,23 @@ int ngx_http_index_handler(ngx_http_requ ngx_err_t err; ngx_fd_t fd; - ngx_http_index_conf_t *cf; + ngx_http_index_conf_t *cf; + ngx_http_core_loc_conf_t *core_cf; cf = (ngx_http_index_conf_t *) ngx_http_get_module_loc_conf(r, ngx_http_index_module_ctx); + core_cf = (ngx_http_core_loc_conf_t *) + ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + ngx_test_null(name, ngx_palloc(r->pool, - r->server->doc_root_len + r->uri.len + core_cf->doc_root.len + r->uri.len + cf->max_index_len), NGX_HTTP_INTERNAL_SERVER_ERROR); - loc.data = ngx_cpystrn(name, r->server->doc_root, r->server->doc_root_len); + loc.data = ngx_cpystrn(name, core_cf->doc_root.data, + core_cf->doc_root.len + 1); file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1); index = (ngx_str_t *) cf->indices->elts; @@ -101,7 +108,7 @@ int ngx_http_index_handler(ngx_http_requ return NGX_HTTP_INTERNAL_SERVER_ERROR; } - r->file.name.len = r->server->doc_root_len + r->uri.len + index[i].len; + r->file.name.len = core_cf->doc_root.len + r->uri.len + index[i].len; r->file.name.data = name; r->file.fd = fd; @@ -117,17 +124,34 @@ static void *ngx_http_index_create_conf( { ngx_http_index_conf_t *conf; - ngx_test_null(conf, ngx_pcalloc(pool, sizeof(ngx_http_index_conf_t)), NULL); + ngx_test_null(conf, ngx_pcalloc(pool, sizeof(ngx_http_index_conf_t)), + NGX_CONF_ERROR); ngx_test_null(conf->indices, ngx_create_array(pool, sizeof(ngx_str_t), 3), - NULL); + NGX_CONF_ERROR); return conf; } -static void *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) +static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) +{ + ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent; + ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child; + ngx_str_t *index; + + ngx_test_null(index, ngx_push_array(conf->indices), NGX_CONF_ERROR); + index->len = sizeof(NGX_HTTP_INDEX) - 1; + index->data = NGX_HTTP_INDEX; + conf->max_index_len = sizeof(NGX_HTTP_INDEX); + + return NULL; +} + + +#if 0 +static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) { ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent; ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child; @@ -146,7 +170,7 @@ static void *ngx_http_index_merge_conf(n return conf; } - +#endif static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) 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 @@ -117,6 +117,9 @@ int ngx_http_static_handler(ngx_http_req } else if (strcasecmp(r->exten.data, "jpg") == 0) { r->headers_out.content_type->value.len = 10; r->headers_out.content_type->value.data = "image/jpeg"; + } else if (strcasecmp(r->exten.data, "pdf") == 0) { + r->headers_out.content_type->value.len = 15; + r->headers_out.content_type->value.data = "application/pdf"; } } else { 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 @@ -5,15 +5,343 @@ #include #include #include +#include -extern ngx_array_t *ngx_listening_sockets; + +static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); + + +int ngx_http_max_module; + +ngx_array_t ngx_http_servers; /* array of ngx_http_core_srv_conf_t */ + +int ngx_http_post_accept_timeout = 10000; +int ngx_http_connection_pool_size = 16384; +int ngx_http_request_pool_size = 16384; +int ngx_http_client_header_timeout = 20000; +int ngx_http_client_header_buffer_size = 1024; + +/* STUB: per location */ +int ngx_http_lingering_timeout = 5000; +int ngx_http_lingering_time = 30; +/**/ + +int (*ngx_http_top_header_filter) (ngx_http_request_t *r); + + +static ngx_str_t http_name = ngx_string("http"); + + +static ngx_command_t ngx_http_commands[] = { + + {ngx_string("http"), + NGX_CONF_BLOCK|NGX_CONF_NOARGS, + ngx_http_block, + 0, + 0}, + + {ngx_string(""), 0, NULL, 0, 0} +}; + + +ngx_module_t ngx_http_module = { + 0, /* module index */ + &http_name, /* module context */ + ngx_http_commands, /* module directives */ + NGX_CORE_MODULE_TYPE, /* module type */ + NULL /* init module */ +}; + + +static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) +{ + int i, s, l, p, a, n, start; + int port_found, addr_found, virtual_names; + char *rv; + struct sockaddr_in *addr_in; + ngx_array_t in_ports; + ngx_listen_t *ls; + ngx_http_module_t *module; + ngx_http_conf_ctx_t *ctx, *prev; + ngx_http_in_port_t *in_port; + ngx_http_in_addr_t *in_addr, *inaddr; + ngx_http_core_srv_conf_t **cscf; + ngx_http_listen_t *lscf; + ngx_http_server_name_t *s_name, *name;; + + ngx_init_array(ngx_http_servers, cf->pool, 10, + sizeof(ngx_http_core_srv_conf_t *), NGX_CONF_ERROR); + + ngx_test_null(ctx, + ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), + NGX_CONF_ERROR); + + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { + continue; + } + + /* STUB */ + module = (ngx_http_module_t *) ngx_modules[i]->ctx; + module->index = ngx_http_max_module; + + ngx_modules[i]->index = ngx_http_max_module++; + } + + /* null loc_conf */ + ngx_test_null(ctx->loc_conf, + ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), + NGX_CONF_ERROR); + + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { + continue; + } + + module = (ngx_http_module_t *) ngx_modules[i]->ctx; + + if (module->create_loc_conf) { + ngx_test_null(ctx->loc_conf[module->index], + module->create_loc_conf(cf->pool), + NGX_CONF_ERROR); + } + } + + prev = cf->ctx; + cf->ctx = ctx; + cf->type = NGX_HTTP_MODULE_TYPE; + + rv = ngx_conf_parse(cf, NULL); + cf->ctx = prev; + + if (rv != NGX_CONF_OK) + return rv; + + ngx_http_init_filters(cf->pool, ngx_modules); + +#if 1 + ngx_init_array(in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t), + NGX_CONF_ERROR); + + cscf = (ngx_http_core_srv_conf_t **) ngx_http_servers.elts; + for (s = 0; s < ngx_http_servers.nelts; s++) { + + lscf = (ngx_http_listen_t *) cscf[s]->listen.elts; + for (l = 0; l < cscf[s]->listen.nelts; l++) { + + port_found = 0; + + /* AF_INET only */ + + in_port = (ngx_http_in_port_t *) in_ports.elts; + for (p = 0; p < in_ports.nelts; p++) { + + if (lscf[l].port == in_port[p].port) { + + port_found = 1; + addr_found = 0; + + in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; + for (a = 0; a < in_port[p].addr.nelts; a++) { + + if (lscf[l].addr == in_addr[a].addr) { + s_name = (ngx_http_server_name_t *) + cscf[s]->server_names.elts; + for (n = 0; n < cscf[s]->server_names.nelts; n++) { + ngx_test_null(name, + ngx_push_array(&in_addr[a].names), + NGX_CONF_ERROR); + + name->name = s_name[n].name; + name->core_srv_conf = s_name[n].core_srv_conf; + } + + if (lscf[l].flags & NGX_HTTP_DEFAULT_SERVER) { + if (in_addr[a].flags + & NGX_HTTP_DEFAULT_SERVER) { + + ngx_log_error(NGX_LOG_ERR, cf->log, 0, + "duplicate default server in %s:%d", + lscf[l].conf_file->file.name.data, + lscf[l].line); + + return NGX_CONF_ERROR; + } + + in_addr[a].flags |= NGX_HTTP_DEFAULT_SERVER; + in_addr[a].core_srv_conf = cscf[s]; + } + addr_found = 1; + + break; + + /* "*:XX" is the last resort */ + } else if (in_addr[p].addr == INADDR_ANY) { + ngx_test_null(inaddr, + ngx_push_array(&in_port[p].addr), + NGX_CONF_ERROR); + + ngx_memcpy(inaddr, &in_addr[a], + sizeof(ngx_http_in_addr_t)); + + inaddr->addr = lscf[l].addr; + inaddr->flags = lscf[l].flags; + inaddr->core_srv_conf = cscf[s]; + + ngx_init_array(inaddr->names, cf->pool, 10, + sizeof(ngx_http_server_name_t), + NGX_CONF_ERROR); + + addr_found = 1; + + break; + } + } + + if (!addr_found) { + ngx_test_null(inaddr, + ngx_push_array(&in_port[p].addr), + NGX_CONF_ERROR); + + inaddr->addr = lscf[l].addr; + inaddr->flags = lscf[l].flags; + inaddr->core_srv_conf = cscf[s]; + + ngx_init_array(inaddr->names, cf->pool, 10, + sizeof(ngx_http_server_name_t), + NGX_CONF_ERROR); + } + } + } + + if (!port_found) { + ngx_test_null(in_port, + ngx_push_array(&in_ports), + NGX_CONF_ERROR); + + in_port->port = lscf[l].port; + + ngx_init_array(in_port->addr, cf->pool, 10, + sizeof(ngx_http_in_addr_t), + NGX_CONF_ERROR); + + ngx_test_null(inaddr, ngx_push_array(&in_port[p].addr), + NGX_CONF_ERROR); + + inaddr->addr = lscf[l].addr; + inaddr->flags = lscf[l].flags; + inaddr->core_srv_conf = cscf[s]; + + ngx_init_array(inaddr->names, cf->pool, 10, + sizeof(ngx_http_server_name_t), + NGX_CONF_ERROR); + } + } + } + + /* AF_INET only */ + + in_port = (ngx_http_in_port_t *) in_ports.elts; + for (p = 0; p < in_ports.nelts; p++) { + + in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; + for (a = 0; a < in_port[p].addr.nelts; a++) { + + virtual_names = 0; + + name = (ngx_http_server_name_t *) in_addr[a].names.elts; + for (n = 0; n < in_addr[a].names.nelts; n++) { + if (in_addr[a].core_srv_conf != name[n].core_srv_conf) { + virtual_names = 1; + break; + } + } + + /* if all server names point to the same server + then we do not need to check them at run time */ + if (!virtual_names) { + in_addr[a].names.nelts = 0; + } + } + + /* if there is binding to "*:XX" then we need to bind to "*:XX" only + and ignore other binding */ + if (in_addr[a - 1].addr == INADDR_ANY) { + start = a - 1; + + } else { + start = 0; + } + + in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; + for (a = start; a < in_port[p].addr.nelts; a++) { + + ngx_test_null(ls, ngx_push_array(&ngx_listening_sockets), + NGX_CONF_ERROR); + ngx_memzero(ls, sizeof(ngx_listen_t)); + + ngx_test_null(addr_in, + ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)), + NGX_CONF_ERROR); + + addr_in->sin_family = AF_INET; + addr_in->sin_addr.s_addr = in_addr[a].addr; + addr_in->sin_port = htons(in_port[p].port); + + ngx_test_null(ls->addr_text.data, + ngx_palloc(cf->pool, INET_ADDRSTRLEN + 6), + NGX_CONF_ERROR); + + ls->addr_text.len = + ngx_snprintf(ls->addr_text.data + + ngx_inet_ntop(AF_INET, + &in_addr[a].addr, + ls->addr_text.data, + INET_ADDRSTRLEN), + 6, ":%d", in_port[p].port); + + ls->family = AF_INET; + ls->type = SOCK_STREAM; + ls->protocol = IPPROTO_IP; +#if (NGX_OVERLAPPED) + ls->flags = WSA_FLAG_OVERLAPPED; +#endif + ls->sockaddr = (struct sockaddr *) addr_in; + ls->socklen = sizeof(struct sockaddr_in); + ls->addr = offsetof(struct sockaddr_in, sin_addr); + ls->addr_text_max_len = INET_ADDRSTRLEN; + ls->backlog = -1; + ls->post_accept_timeout = ngx_http_post_accept_timeout; + ls->nonblocking = 1; + + ls->handler = ngx_http_init_connection; + ls->log = cf->log; + ls->ctx = ctx; + ls->servers = &in_port[p].addr; + + if (in_port[p].addr.nelts == 1) { + in_addr = (ngx_http_in_addr_t *) in_port[p].addr.elts; + + if (in_addr[a].names.nelts == 0) { + ls->ctx = in_addr->core_srv_conf->ctx; + ls->servers = NULL; + } + } + } + } +#endif + + return NGX_CONF_OK; +} + + +#if 0 /* 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_log_t *log) { @@ -40,8 +368,8 @@ int ngx_http_init(ngx_pool_t *pool, ngx_ ngx_http_config_modules(pool, ngx_modules); + #if 0 - /* STUB */ ngx_http_output_filter_set_stub(pool, ngx_http_modules); ngx_http_write_filter_set_stub(pool, ngx_http_modules); @@ -49,9 +377,10 @@ int ngx_http_init(ngx_pool_t *pool, ngx_ ngx_http_init_modules(pool, ngx_http_modules); #endif + ngx_http_init_filters(pool, ngx_modules); - ls = ngx_push_array(ngx_listening_sockets); + ls = ngx_push_array(&ngx_listening_sockets); ngx_memzero(ls, sizeof(ngx_listen_t)); addr.sin_family = AF_INET; @@ -84,4 +413,5 @@ int ngx_http_init(ngx_pool_t *pool, ngx_ return 1; } -/* */ +/**/ +#endif 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 @@ -114,8 +114,8 @@ struct ngx_http_request_s { #endif void **ctx; + void **srv_conf; void **loc_conf; - void **srv_conf; ngx_pool_t *pool; ngx_hunk_t *header_in; @@ -139,7 +139,6 @@ struct ngx_http_request_s { ngx_http_request_t *main; ngx_connection_t *connection; - ngx_http_server_t *server; int filter; @@ -192,9 +191,9 @@ typedef struct { int index; void *(*create_srv_conf)(ngx_pool_t *p); - void *(*init_srv_conf)(ngx_pool_t *p, void *conf); + char *(*init_srv_conf)(ngx_pool_t *p, void *conf); void *(*create_loc_conf)(ngx_pool_t *p); - void *(*merge_loc_conf)(ngx_pool_t *p, void *prev, void *conf); + char *(*merge_loc_conf)(ngx_pool_t *p, void *prev, void *conf); int (*translate_handler)(ngx_http_request_t *r); @@ -217,8 +216,8 @@ typedef struct { #define ngx_http_create_ctx(r, cx, module, size) \ do { \ - ngx_test_null(cx, ngx_pcalloc(r->pool, size), NGX_ERROR); \ - r->ctx[module.index] = cx; \ + ngx_test_null(cx, ngx_pcalloc(r->pool, size), NGX_ERROR); \ + r->ctx[module.index] = cx; \ } while (0) @@ -237,9 +236,22 @@ int ngx_http_init_connection(ngx_connect int ngx_http_discard_body(ngx_http_request_t *r); -extern int ngx_max_module; +extern int ngx_max_module; +extern ngx_array_t ngx_http_servers; + -extern ngx_http_module_t *ngx_http_modules[]; +extern int ngx_http_post_accept_timeout; +extern int ngx_http_connection_pool_size; +extern int ngx_http_request_pool_size; +extern int ngx_http_client_header_timeout; +extern int ngx_http_client_header_buffer_size; +extern int ngx_http_discarded_buffer_size; + +extern int ngx_http_lingering_timeout; +extern int ngx_http_lingering_time; + + +extern ngx_http_module_t *ngx_http_modules[]; diff --git a/src/http/ngx_http_config.c b/src/http/ngx_http_config.c deleted file mode 100644 --- a/src/http/ngx_http_config.c +++ /dev/null @@ -1,316 +0,0 @@ - -/* TODO: - ngx_http_conf_ctx_t ctx; on stack or in pool ? */ - - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - - -/* STUB */ -void **ngx_srv_conf; -void **ngx_loc_conf; -/**/ - - -static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); -static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); - - -void **null_loc_conf; - - -static ngx_command_t ngx_http_commands[] = { - - {ngx_string("http"), - NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_http_block, - 0, - 0}, - - {ngx_string(""), 0, NULL, 0, 0} -}; - - -ngx_module_t ngx_http_module = { - NULL, /* module context */ - ngx_http_commands, /* module directives */ - NGX_CORE_MODULE_TYPE, /* module type */ - NULL /* init module */ -}; - - -static ngx_command_t ngx_http_core_commands[] = { - - {ngx_string("server"), - NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_server_block, - NGX_HTTP_MODULE_TYPE, - 0}, - - {ngx_string(""), 0, NULL, 0, 0} -}; - - -static ngx_http_module_t ngx_http_core_module_ctx = { - NGX_HTTP_MODULE, - - NULL, /* create server config */ - NULL, /* init server config */ - NULL, /* create location config */ - NULL, /* merge location config */ - - NULL, /* translate handler */ - - NULL, /* output header filter */ - NULL, /* next output header filter */ - NULL, /* output body filter */ - NULL /* next output body filter */ -}; - - -ngx_module_t ngx_http_core_module = { - &ngx_http_core_module_ctx, /* module context */ - ngx_http_core_commands, /* module directives */ - NGX_HTTP_MODULE_TYPE, /* module type */ - NULL /* init module */ -}; - - -static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) -{ - int i; - ngx_http_module_t *module; - ngx_http_conf_ctx_t ctx; - - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { - continue; - } - - module = (ngx_http_module_t *) ngx_modules[i]->ctx; - module->index = ngx_http_max_module++; - } - - ngx_test_null(null_loc_conf, - ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), - NGX_CONF_ERROR); - - ctx.srv_conf = NULL; - ctx.loc_conf = null_loc_conf; - ctx.locations = NULL; - - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { - continue; - } - - module = (ngx_http_module_t *) ngx_modules[i]->ctx; - - if (module->create_loc_conf) { - ngx_test_null(null_loc_conf[module->index], - module->create_loc_conf(cf->pool), - NGX_CONF_ERROR); - } - } - - cf->ctx = &ctx; - cf->type = NGX_HTTP_MODULE_TYPE; - return ngx_conf_parse(cf, NULL); -} - - -static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) -{ - int i, j; - char *rv; - void ***loc_conf; /* YES! 3 stars */ - ngx_http_module_t *module; - ngx_http_conf_ctx_t *ctx, *prev; - - ngx_test_null(ctx, - ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), - NGX_CONF_ERROR); - - /* server config */ - ngx_test_null(ctx->srv_conf, - ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), - NGX_CONF_ERROR); - - /* server location config */ - ngx_test_null(ctx->loc_conf, - ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), - NGX_CONF_ERROR); - - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { - continue; - } - - module = (ngx_http_module_t *) ngx_modules[i]->ctx; - - if (module->create_srv_conf) { - ngx_test_null(ctx->srv_conf[module->index], - module->create_srv_conf(cf->pool), - NGX_CONF_ERROR); - } - - if (module->create_loc_conf) { - ngx_test_null(ctx->loc_conf[module->index], - module->create_loc_conf(cf->pool), - NGX_CONF_ERROR); - } - } - - prev = cf->ctx; - cf->ctx = ctx; - rv = ngx_conf_parse(cf, NULL); - cf->ctx = prev; - - if (rv != NULL) - return rv; - - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { - continue; - } - - module = (ngx_http_module_t *) ngx_modules[i]->ctx; - - if (module->init_srv_conf) { - if (module->init_srv_conf(cf->pool, - ctx->srv_conf[module->index]) - == NGX_CONF_ERROR) { - return NGX_CONF_ERROR; - } - } - - if (module->merge_loc_conf) { - if (module->merge_loc_conf(cf->pool, - prev->loc_conf[module->index], - ctx->loc_conf[module->index]) - == NGX_CONF_ERROR) { - return NGX_CONF_ERROR; - } - - loc_conf = (void ***)ctx->locations->elts; - for (j = 0; j < ctx->locations->nelts; j++) { - if (module->merge_loc_conf(cf->pool, - ctx->loc_conf[module->index], - loc_conf[j][module->index]) - == NGX_CONF_ERROR) { - return NGX_CONF_ERROR; - } - } - } - } - - return NULL; -} - - -#if 0 -int ngx_location_block(ngx_conf_t *cf) -{ - ngx_http_conf_ctx_t *ctx, *prev; - - ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), - NGX_ERROR); - - ctx->srv_conf = cf->ctx->srv_conf; - - ngx_test_null(ctx->loc_conf, - ngx_pcalloc(cf->pool, sizeof(void *) * ngx_max_module), - NGX_ERROR); - - for (i = 0; modules[i]; i++) { - if (modules[i]->create_loc_conf) - ngx_test_null(ctx->loc_conf[i], - modules[i]->create_loc_conf(cf->pool), - NGX_ERROR); - - if (ngx_http_core_module.index == i) - ctx->loc_conf[i].location = cf->args[0]; - } - - push - - return ngx_conf_parse(cf); -} - -#endif - - -int ngx_http_config_modules(ngx_pool_t *pool, ngx_module_t **modules) -{ - int i; - ngx_http_module_t *module; - - for (i = 0; modules[i]; i++) { - if (modules[i]->type != NGX_HTTP_MODULE_TYPE) { - continue; - } - - module = (ngx_http_module_t *) modules[i]->ctx; - module->index = i; - } - - ngx_http_max_module = i; - -#if 0 - ngx_test_null(ngx_srv_conf, - ngx_pcalloc(pool, sizeof(void *) * ngx_http_max_module), - NGX_ERROR); - ngx_test_null(ngx_loc_conf, - ngx_pcalloc(pool, sizeof(void *) * ngx_http_max_module), - NGX_ERROR); - - for (i = 0; modules[i]; i++) { - if (modules[i]->create_srv_conf) - ngx_srv_conf[i] = modules[i]->create_srv_conf(pool); - - if (modules[i]->create_loc_conf) - ngx_loc_conf[i] = modules[i]->create_loc_conf(pool); - } -#endif -} - - -void ngx_http_init_filters(ngx_pool_t *pool, ngx_module_t **modules) -{ - int i; - ngx_http_module_t *module; - int (*ohf)(ngx_http_request_t *r); - int (*obf)(ngx_http_request_t *r, ngx_chain_t *ch); - - ohf = NULL; - obf = NULL; - - for (i = 0; modules[i]; i++) { - if (modules[i]->type != NGX_HTTP_MODULE_TYPE) { - continue; - } - - module = (ngx_http_module_t *) modules[i]->ctx; - if (module->output_header_filter) { - module->next_output_header_filter = ohf; - ohf = module->output_header_filter; - } - - if (module->output_body_filter) { - module->next_output_body_filter = obf; - obf = module->output_body_filter; - } - } - - ngx_http_top_header_filter = ohf; -} diff --git a/src/http/ngx_http_config.h b/src/http/ngx_http_config.h --- a/src/http/ngx_http_config.h +++ b/src/http/ngx_http_config.h @@ -9,12 +9,15 @@ typedef struct { void **srv_conf; void **loc_conf; - ngx_array_t *locations; } ngx_http_conf_ctx_t; -#define NGX_HTTP_SRV_CONF offsetof(ngx_http_conf_ctx_t, srv_conf) -#define NGX_HTTP_LOC_CONF offsetof(ngx_http_conf_ctx_t, loc_conf) +#define NGX_HTTP_MAIN_CONF 0x1000000 +#define NGX_HTTP_SRV_CONF 0x2000000 +#define NGX_HTTP_LOC_CONF 0x6000000 + +#define NGX_HTTP_SRV_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, srv_conf) +#define NGX_HTTP_LOC_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, loc_conf) int ngx_http_config_modules(ngx_pool_t *pool, ngx_module_t **modules); diff --git a/src/http/ngx_http_core.c b/src/http/ngx_http_core_module.c rename from src/http/ngx_http_core.c rename to src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core.c +++ b/src/http/ngx_http_core_module.c @@ -5,42 +5,66 @@ #include #include -#include #include +#include + +#if 0 +#include +#include +#include +#endif /* STUB */ +#include int ngx_http_static_handler(ngx_http_request_t *r); int ngx_http_index_handler(ngx_http_request_t *r); int ngx_http_proxy_handler(ngx_http_request_t *r); /**/ + +static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); +static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, + char *dummy); static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool); +static char *ngx_http_core_init_srv_conf(ngx_pool_t *pool, void *conf); static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool); -static int ngx_http_core_translate_handler(ngx_http_request_t *r); -int (*ngx_http_top_header_filter) (ngx_http_request_t *r); +static ngx_command_t ngx_http_core_commands[] = { + + {ngx_string("server"), + NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, + ngx_server_block, + 0, + 0}, -int ngx_http_max_module; + {ngx_string("location"), + NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, + ngx_location_block, + 0, + 0}, -#if 0 -static ngx_command_t ngx_http_core_commands[] = { + {ngx_string("root"), + NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_core_loc_conf_t, doc_root)}, {ngx_string("send_timeout"), - NGX_CONF_TAKE1, + NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, ngx_conf_set_time_slot, - NGX_HTTP_LOC_CONF, + NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_core_loc_conf_t, send_timeout)}, {ngx_string(""), 0, NULL, 0, 0} }; -#endif + ngx_http_module_t ngx_http_core_module_ctx = { NGX_HTTP_MODULE, ngx_http_core_create_srv_conf, /* create server config */ - NULL, /* init server config */ + ngx_http_core_init_srv_conf, /* init server config */ ngx_http_core_create_loc_conf, /* create location config */ NULL, /* merge location config */ @@ -49,28 +73,39 @@ ngx_http_module_t ngx_http_core_module_ NULL, /* output header filter */ NULL, /* next output header filter */ NULL, /* output body filter */ - NULL, /* next output body filter */ + NULL /* next output body filter */ }; -#if 0 + ngx_module_t ngx_http_core_module = { + 0, /* module index */ &ngx_http_core_module_ctx, /* module context */ ngx_http_core_commands, /* module directives */ NGX_HTTP_MODULE_TYPE, /* module type */ NULL /* init module */ }; -#endif + int ngx_http_handler(ngx_http_request_t *r) { int rc, i; - ngx_http_module_t *module; + ngx_http_module_t *module; + ngx_http_conf_ctx_t *ctx; r->connection->unexpected_eof = 0; r->lingering_close = 1; r->keepalive = 0; -#if 0 + ctx = (ngx_http_conf_ctx_t *) r->connection->ctx; + r->srv_conf = ctx->srv_conf; + r->loc_conf = ctx->loc_conf; + +ngx_log_debug(r->connection->log, "srv_conf: %0x" _ r->srv_conf); +ngx_log_debug(r->connection->log, "loc_conf: %0x" _ r->loc_conf); +ngx_log_debug(r->connection->log, "servers: %0x" _ r->connection->servers); + + +#if 1 r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; #endif @@ -81,6 +116,7 @@ int ngx_http_handler(ngx_http_request_t } module = (ngx_http_module_t *) ngx_modules[i]->ctx; + if (module->translate_handler == NULL) { continue; } @@ -105,13 +141,36 @@ int ngx_http_handler(ngx_http_request_t } -static int ngx_http_core_translate_handler(ngx_http_request_t *r) +int ngx_http_core_translate_handler(ngx_http_request_t *r) { - char *loc, *last; - ngx_err_t err; - ngx_table_elt_t *h; + int i, rc; + char *location, *last; + ngx_err_t err; + ngx_table_elt_t *h; + ngx_http_core_srv_conf_t *scf; + ngx_http_core_loc_conf_t **lcf, *loc_conf; + + scf = (ngx_http_core_srv_conf_t *) + ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); - /* TODO: find location conf */ + /* find location config */ + lcf = (ngx_http_core_loc_conf_t **) scf->locations.elts; + for (i = 0; i < scf->locations.nelts; i++) { +ngx_log_debug(r->connection->log, "trans: %s" _ lcf[i]->name.data); + if (r->uri.len < lcf[i]->name.len) { + continue; + } + + rc = ngx_strncmp(r->uri.data, lcf[i]->name.data, lcf[i]->name.len); + + if (rc < 0) { + break; + } + + if (rc == 0) { + r->loc_conf = lcf[i]->loc_conf; + } + } if (r->uri.data[r->uri.len - 1] == '/') { /* TODO: find index handler */ @@ -120,15 +179,18 @@ static int ngx_http_core_translate_handl return NGX_OK; } - r->file.name.len = r->server->doc_root_len + r->uri.len + 2; + loc_conf = (ngx_http_core_loc_conf_t *) + ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + + r->file.name.len = loc_conf->doc_root.len + r->uri.len; ngx_test_null(r->file.name.data, ngx_palloc(r->pool, r->file.name.len + 1), NGX_HTTP_INTERNAL_SERVER_ERROR); - loc = ngx_cpystrn(r->file.name.data, r->server->doc_root, - r->server->doc_root_len); - last = ngx_cpystrn(loc, r->uri.data, r->uri.len + 1); + location = ngx_cpystrn(r->file.name.data, loc_conf->doc_root.data, + loc_conf->doc_root.len + 1); + last = ngx_cpystrn(location, r->uri.data, r->uri.len + 1); ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data); @@ -139,10 +201,6 @@ static int ngx_http_core_translate_handl one syscall: Win9X has not FILE_FLAG_BACKUP_SEMANTICS flag. so we need to check its type before opening */ -#if 0 /* OLD: ngx_file_type() is to be removed */ - if (ngx_file_type(r->file.name.data, &r->file.info) == -1) { -#endif - r->file.info.dwFileAttributes = GetFileAttributes(r->file.name.data); if (r->file.info.dwFileAttributes == INVALID_FILE_ATTRIBUTES) { err = ngx_errno; @@ -173,6 +231,10 @@ static int ngx_http_core_translate_handl if (err == NGX_ENOENT) { return NGX_HTTP_NOT_FOUND; +#if (WIN32) + } else if (err == ERROR_PATH_NOT_FOUND) { + return NGX_HTTP_NOT_FOUND; +#endif } else { return NGX_HTTP_INTERNAL_SERVER_ERROR; } @@ -217,8 +279,8 @@ static int ngx_http_core_translate_handl *last = '\0'; h->key.len = 8; h->key.data = "Location" ; - h->value.len = last - loc; - h->value.data = loc; + h->value.len = last - location; + h->value.data = location; r->headers_out.location = h; return NGX_HTTP_MOVED_PERMANENTLY; @@ -307,29 +369,342 @@ int ngx_http_internal_redirect(ngx_http_ } +#if 0 +void *ngx_http_find_server_conf(ngx_http_request_t *r) +{ + int i; + ngx_http_listen_t *fs, *ls; + ngx_http_server_name_t *n; + + fs = NULL; + ls = (ngx_http_listen_t *) http->ports.elts; + + for (i = 0; i < http->ports.nelts; i++) { + if (s->family != ls[i].family || s->port != ls[i].port) { + continue; + } + + if (s->family == AF_INET) { + + if (ls[i].addr == INADDR_ANY || ls[i].addr == s->addr) { + fs = &ls[i]; + break; + } + + } else { + /* STUB: AF_INET only */ + } + } + + if (fs == NULL) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "unknown local socket %s:%d", + s->addr_text.data, s->port); + return NULL; + } + + if (r->headers_in.host && fs->server_names.nelts) { + + n = (ngx_http_server_name_t *) fs->server_names.elts; + for (i = 0; i < fs->server_names.nelts; i++) { + if (r->headers_in.host->value.len != n[i].name.len) { + continue; + } + + if (ngx_strcmp(r->headers_in.host->value.data, n[i].name.data) == 0) { + return n[i].srv_conf; + } + } + } + + return fs->srv_conf; +} +#endif + + +static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) +{ + int i, j; + char *rv; + ngx_http_module_t *module; + ngx_http_conf_ctx_t *ctx, *prev; + ngx_http_core_srv_conf_t *scf; + ngx_http_core_loc_conf_t **lcf; + + ngx_test_null(ctx, + ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), + NGX_CONF_ERROR); + + /* server config */ + ngx_test_null(ctx->srv_conf, + ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), + NGX_CONF_ERROR); + + /* server location config */ + ngx_test_null(ctx->loc_conf, + ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), + NGX_CONF_ERROR); + + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { + continue; + } + + module = (ngx_http_module_t *) ngx_modules[i]->ctx; + + if (module->create_srv_conf) { + ngx_test_null(ctx->srv_conf[module->index], + module->create_srv_conf(cf->pool), + NGX_CONF_ERROR); +ngx_log_debug(cf->log, "srv_conf: %d:%0x" _ + module->index _ ctx->loc_conf[module->index]); + } + + if (module->create_loc_conf) { + ngx_test_null(ctx->loc_conf[module->index], + module->create_loc_conf(cf->pool), + NGX_CONF_ERROR); +ngx_log_debug(cf->log, "srv loc_conf: %d:%0x" _ + module->index _ ctx->loc_conf[module->index]); + } + } + + prev = cf->ctx; + cf->ctx = ctx; + rv = ngx_conf_parse(cf, NULL); + cf->ctx = prev; + + if (rv != NGX_CONF_OK) + return rv; + + + scf = ctx->srv_conf[ngx_http_core_module_ctx.index]; + scf->ctx = ctx; + + lcf = (ngx_http_core_loc_conf_t **)scf->locations.elts; + + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { + continue; + } + + module = (ngx_http_module_t *) ngx_modules[i]->ctx; + + if (module->init_srv_conf) { + if (module->init_srv_conf(cf->pool, + ctx->srv_conf[module->index]) + == NGX_CONF_ERROR) { + return NGX_CONF_ERROR; + } + } + + if (module->merge_loc_conf) { + if (module->merge_loc_conf(cf->pool, + prev->loc_conf[module->index], + ctx->loc_conf[module->index]) + == NGX_CONF_ERROR) { + return NGX_CONF_ERROR; + } + + for (j = 0; j < scf->locations.nelts; j++) { +ngx_log_debug(cf->log, "%d:%0x" _ j _ lcf[j]); +ngx_log_debug(cf->log, "%d:'%s'" _ lcf[j]->name.len _ lcf[j]->name.data); + if (module->merge_loc_conf(cf->pool, + ctx->loc_conf[module->index], + lcf[j]->loc_conf[module->index]) + == NGX_CONF_ERROR) { + return NGX_CONF_ERROR; + } + } + } + } + + return NGX_CONF_OK; +} + + +static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) +{ + int i; + char *rv; + void **loc; + ngx_str_t *location; + ngx_http_module_t *module; + ngx_http_conf_ctx_t *ctx, *prev; + ngx_http_core_srv_conf_t *scf; + ngx_http_core_loc_conf_t *lcf; + + ngx_test_null(ctx, + ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), + NGX_CONF_ERROR); + + prev = (ngx_http_conf_ctx_t *) cf->ctx; + ctx->srv_conf = prev->srv_conf; + + ngx_test_null(ctx->loc_conf, + ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), + NGX_CONF_ERROR); + + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { + continue; + } + + module = (ngx_http_module_t *) ngx_modules[i]->ctx; + + if (module->create_loc_conf) { + ngx_test_null(ctx->loc_conf[module->index], + module->create_loc_conf(cf->pool), + NGX_CONF_ERROR); +ngx_log_debug(cf->log, "loc_conf: %d:%0x" _ + module->index _ ctx->loc_conf[module->index]); + } + } + + lcf = (ngx_http_core_loc_conf_t *) + ctx->loc_conf[ngx_http_core_module_ctx.index]; + location = (ngx_str_t *) cf->args->elts; + lcf->name.len = location[1].len; + lcf->name.data = location[1].data; + lcf->loc_conf = ctx->loc_conf; + + scf = (ngx_http_core_srv_conf_t *) + ctx->srv_conf[ngx_http_core_module_ctx.index]; + ngx_test_null(loc, ngx_push_array(&scf->locations), NGX_CONF_ERROR); + *loc = lcf; + +ngx_log_debug(cf->log, "%0x:%s" _ lcf _ lcf->name.data); + + cf->ctx = ctx; + rv = ngx_conf_parse(cf, NULL); + cf->ctx = prev; + + return rv; +} + + +int ngx_http_config_modules(ngx_pool_t *pool, ngx_module_t **modules) +{ + int i; + ngx_http_module_t *module; + + for (i = 0; modules[i]; i++) { + if (modules[i]->type != NGX_HTTP_MODULE_TYPE) { + continue; + } + + module = (ngx_http_module_t *) modules[i]->ctx; + module->index = i; + } + + ngx_http_max_module = i; + +#if 0 + ngx_test_null(ngx_srv_conf, + ngx_pcalloc(pool, sizeof(void *) * ngx_http_max_module), + NGX_ERROR); + ngx_test_null(ngx_loc_conf, + ngx_pcalloc(pool, sizeof(void *) * ngx_http_max_module), + NGX_ERROR); + + for (i = 0; modules[i]; i++) { + if (modules[i]->create_srv_conf) + ngx_srv_conf[i] = modules[i]->create_srv_conf(pool); + + if (modules[i]->create_loc_conf) + ngx_loc_conf[i] = modules[i]->create_loc_conf(pool); + } +#endif +} + + +void ngx_http_init_filters(ngx_pool_t *pool, ngx_module_t **modules) +{ + int i; + ngx_http_module_t *module; + int (*ohf)(ngx_http_request_t *r); + int (*obf)(ngx_http_request_t *r, ngx_chain_t *ch); + + ohf = NULL; + obf = NULL; + + for (i = 0; modules[i]; i++) { + if (modules[i]->type != NGX_HTTP_MODULE_TYPE) { + continue; + } + + module = (ngx_http_module_t *) modules[i]->ctx; + + if (module->output_header_filter) { + module->next_output_header_filter = ohf; + ohf = module->output_header_filter; + } + + if (module->output_body_filter) { + module->next_output_body_filter = obf; + obf = module->output_body_filter; + } + } + + ngx_http_top_header_filter = ohf; +} + + static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool) { - ngx_http_core_srv_conf_t *conf; + ngx_http_core_srv_conf_t *scf, **cf; + + ngx_test_null(scf, + ngx_pcalloc(pool, sizeof(ngx_http_core_srv_conf_t)), + NGX_CONF_ERROR); + + ngx_init_array(scf->locations, pool, 5, sizeof(void *), NGX_CONF_ERROR); + ngx_init_array(scf->listen, pool, 5, sizeof(ngx_http_listen_t), + NGX_CONF_ERROR); + + ngx_test_null(cf, ngx_push_array(&ngx_http_servers), NGX_CONF_ERROR); + *cf = scf; + + return scf; +} + - ngx_test_null(conf, - ngx_pcalloc(pool, sizeof(ngx_http_core_srv_conf_t)), - NULL); +static char *ngx_http_core_init_srv_conf(ngx_pool_t *pool, void *conf) +{ + ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf; + + ngx_http_listen_t *l; - return conf; + if (scf->listen.nelts == 0) { + ngx_test_null(l, ngx_push_array(&scf->listen), NGX_CONF_ERROR); + l->addr = INADDR_ANY; + l->port = 8000; + l->family = AF_INET; + } + + return NGX_CONF_OK; } + static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool) { - ngx_http_core_loc_conf_t *conf; + ngx_http_core_loc_conf_t *lcf; + + ngx_test_null(lcf, + ngx_pcalloc(pool, sizeof(ngx_http_core_loc_conf_t)), + NGX_CONF_ERROR); - ngx_test_null(conf, - ngx_pcalloc(pool, sizeof(ngx_http_core_loc_conf_t)), - NULL); + lcf->doc_root.len = 4; + lcf->doc_root.data = "html"; - conf->send_timeout = 10; + lcf->send_timeout = 10; + lcf->discarded_buffer_size = 1500; + lcf->lingering_time = 30; + lcf->lingering_timeout = 5000; + /* - conf->send_timeout = NGX_CONF_UNSET; + lcf->send_timeout = NGX_CONF_UNSET; */ - return conf; + return lcf; } diff --git a/src/http/ngx_http_core.h b/src/http/ngx_http_core_module.h rename from src/http/ngx_http_core.h rename to src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core.h +++ b/src/http/ngx_http_core_module.h @@ -2,24 +2,75 @@ #define _NGX_HTTP_CORE_H_INCLUDED_ +#include +#include #include typedef struct { - int dummy; -} ngx_http_core_conf_t; + int addr; + int port; + int family; + int flags; /* 'default' */ + ngx_conf_file_t *conf_file; + int line; +} ngx_http_listen_t; typedef struct { - int dummy; + ngx_array_t locations; /* array of ngx_http_core_loc_conf_t */ + + ngx_array_t listen; /* 'listen', array of ngx_http_listen_t */ + ngx_array_t server_names; /* 'server_name', + array of ngx_http_server_name_t */ + ngx_http_conf_ctx_t *ctx; } ngx_http_core_srv_conf_t; typedef struct { - time_t send_timeout; + ngx_str_t name; + ngx_http_core_srv_conf_t *core_srv_conf; +} ngx_http_server_name_t; + + +typedef struct { + int port; + ngx_array_t addr; +} ngx_http_in_port_t; + +typedef struct { + u_int32_t addr; + ngx_array_t names; + int flags; + ngx_http_core_srv_conf_t *core_srv_conf; +} ngx_http_in_addr_t; + +#define NGX_HTTP_DEFAULT_SERVER 1 + + + +typedef struct { + ngx_str_t name; /* location name */ + void **loc_conf; /* used in translation handler */ + + ngx_str_t doc_root; /* 'root' */ + + time_t send_timeout; /* 'send_timeout' */ + size_t discarded_buffer_size; /* 'discarded_buffer_size */ + time_t lingering_time; /* 'lingering_time */ + ngx_msec_t lingering_timeout; /* 'lingering_timeout */ } ngx_http_core_loc_conf_t; + + +#if 0 +typedef struct { + int dummy; +} ngx_http_core_conf_t; +#endif + + extern ngx_http_module_t ngx_http_core_module_ctx; extern ngx_module_t ngx_http_core_module; @@ -27,4 +78,9 @@ extern int (*ngx_http_top_header_filter) extern int ngx_http_max_module; + +int ngx_http_core_translate_handler(ngx_http_request_t *r); + + + #endif /* _NGX_HTTP_CORE_H_INCLUDED_ */ 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 @@ -12,7 +12,7 @@ #include #include #include -#include +#include /* STUB */ #include @@ -75,16 +75,13 @@ int ngx_http_init_connection(ngx_connect { ngx_event_t *ev; struct sockaddr *addr; - ngx_http_server_t *srv; ngx_http_log_ctx_t *ctx; ev = c->read; ev->event_handler = ngx_http_init_request; - srv = (ngx_http_server_t *) c->server; - ngx_test_null(c->pool, - ngx_create_pool(srv->connection_pool_size, ev->log), + ngx_create_pool(ngx_http_connection_pool_size, ev->log), NGX_ERROR); ngx_test_null(c->requests, ngx_create_array(c->pool, 10, sizeof(char *)), @@ -97,12 +94,12 @@ int ngx_http_init_connection(ngx_connect ngx_memcpy(addr, c->sockaddr, c->socklen); c->sockaddr = addr; - ngx_test_null(c->addr_text.data, ngx_palloc(c->pool, c->addr_text.len), + ngx_test_null(c->addr_text.data, ngx_palloc(c->pool, c->addr_text_max_len), NGX_ERROR); c->addr_text.len = ngx_inet_ntop(c->family, (char *)c->sockaddr + c->addr, - c->addr_text.data, c->addr_text.len); + c->addr_text.data, c->addr_text_max_len); if (c->addr_text.len == 0) return NGX_ERROR; @@ -118,7 +115,6 @@ int ngx_http_init_connection(ngx_connect return ngx_http_init_request(ev); } else { #endif - /* STUB: post_accept_timeout should be in http_conf */ ngx_add_timer(ev, c->post_accept_timeout); #if (USE_KQUEUE) return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT); @@ -143,29 +139,22 @@ int ngx_http_init_connection(ngx_connect static int ngx_http_init_request(ngx_event_t *ev) { - ngx_connection_t *c; - ngx_http_server_t *srv; - ngx_http_request_t *r; + ngx_connection_t *c; + ngx_http_request_t *r; c = (ngx_connection_t *) ev->data; - srv = (ngx_http_server_t *) c->server; ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)), NGX_ERROR); c->data = r; r->connection = c; - r->server = srv; r->file.fd = NGX_INVALID_FILE; - /* STUB */ - r->srv_conf = ngx_srv_conf; - r->loc_conf = ngx_loc_conf; - /**/ - if (c->buffer == NULL) { ngx_test_null(c->buffer, - ngx_create_temp_hunk(c->pool, srv->header_buffer_size, + ngx_create_temp_hunk(c->pool, + ngx_http_client_header_buffer_size, 0, 0), NGX_ERROR); } else { @@ -174,7 +163,7 @@ static int ngx_http_init_request(ngx_eve r->header_in = c->buffer; - ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log), + ngx_test_null(r->pool, ngx_create_pool(ngx_http_request_pool_size, ev->log), ngx_http_close_request(r)); ngx_test_null(r->ctx, @@ -218,9 +207,7 @@ static int ngx_http_process_request_head if (r->header_timeout) { r->header_timeout = 0; ngx_del_timer(ev); - /* STUB: r->server->header_timeout - OR r->srv_conf->header_timeout ? */ - ngx_add_timer(ev, r->server->header_timeout); + ngx_add_timer(ev, ngx_http_client_header_timeout); } return NGX_AGAIN; } @@ -254,7 +241,7 @@ static int ngx_http_process_request_head if (r->header_timeout) { r->header_timeout = 0; ngx_del_timer(ev); - ngx_add_timer(ev, r->server->header_timeout); + ngx_add_timer(ev, ngx_http_client_header_timeout); } if (rc == NGX_OK) @@ -591,25 +578,29 @@ static int ngx_http_read_discarded_body( { 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_connection_t *c; + ngx_http_request_t *r; + ngx_http_core_loc_conf_t *lcf; ngx_log_debug(ev->log, "http read discarded body"); if (ev->timedout) return NGX_ERROR; + c = (ngx_connection_t *) ev->data; + r = (ngx_http_request_t *) c->data; + + lcf = (ngx_http_core_loc_conf_t *) + ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + if (r->discarded_buffer == NULL) ngx_test_null(r->discarded_buffer, - ngx_palloc(r->pool, r->server->discarded_buffer_size), + ngx_palloc(r->pool, lcf->discarded_buffer_size), NGX_ERROR); size = r->client_content_length; - if (size > r->server->discarded_buffer_size) - size = r->server->discarded_buffer_size; + if (size > lcf->discarded_buffer_size) + size = lcf->discarded_buffer_size; n = ngx_event_recv(c, r->discarded_buffer, size); if (n == NGX_ERROR) @@ -624,34 +615,6 @@ static int ngx_http_read_discarded_body( } -#if 0 -static int ngx_http_discarded_read(ngx_event_t *ev) -{ - ssize_t n; - ngx_connection_t *c; - ngx_http_request_t *r; - - c = (ngx_connection_t *) ev->data; - r = (ngx_http_request_t *) c->data; - - ngx_log_debug(ev->log, "http discarded read"); - - if (ev->timedout) - return NGX_ERROR; - - if (r->discarded_buffer == NULL) - ngx_test_null(r->discarded_buffer, - ngx_palloc(r->pool, r->server->discarded_buffer_size), - NGX_ERROR); - - n = ngx_event_recv(c, r->discarded_buffer, - r->server->discarded_buffer_size); - - return n; -} -#endif - - static int ngx_http_keepalive_handler(ngx_event_t *ev) { ssize_t n; @@ -690,11 +653,16 @@ static int ngx_http_keepalive_handler(ng static int ngx_http_set_lingering_close(ngx_http_request_t *r) { - r->lingering_time = ngx_time() + r->server->lingering_time; + ngx_http_core_loc_conf_t *lcf; + + lcf = (ngx_http_core_loc_conf_t *) + ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + + r->lingering_time = ngx_time() + lcf->lingering_time; r->connection->read->event_handler = ngx_http_lingering_close_handler; ngx_del_timer(r->connection->read); - ngx_add_timer(r->connection->read, r->server->lingering_timeout); + ngx_add_timer(r->connection->read, lcf->lingering_timeout); if (r->connection->read->blocked) { if (ngx_add_event(r->connection->read, NGX_READ_EVENT, @@ -725,9 +693,7 @@ static int ngx_http_lingering_close_hand ngx_msec_t timer; ngx_connection_t *c; ngx_http_request_t *r; - - c = (ngx_connection_t *) ev->data; - r = (ngx_http_request_t *) c->data; + ngx_http_core_loc_conf_t *lcf; ngx_log_debug(ev->log, "http lingering close handler"); @@ -735,25 +701,30 @@ static int ngx_http_lingering_close_hand return ngx_http_close_request(r); } + c = (ngx_connection_t *) ev->data; + r = (ngx_http_request_t *) c->data; + timer = r->lingering_time - ngx_time(); if (timer <= 0) { return ngx_http_close_request(r); } + lcf = (ngx_http_core_loc_conf_t *) + ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + if (r->discarded_buffer == NULL) { if (r->header_in->end - r->header_in->last.mem - >= r->server->discarded_buffer_size) { + >= lcf->discarded_buffer_size) { r->discarded_buffer = r->header_in->last.mem; } else { ngx_test_null(r->discarded_buffer, - ngx_palloc(c->pool, r->server->discarded_buffer_size), + ngx_palloc(c->pool, lcf->discarded_buffer_size), ngx_http_close_request(r)); } } - n = ngx_event_recv(c, r->discarded_buffer, - r->server->discarded_buffer_size); + n = ngx_event_recv(c, r->discarded_buffer, lcf->discarded_buffer_size); ngx_log_debug(ev->log, "lingering read: %d" _ n); @@ -762,8 +733,8 @@ static int ngx_http_lingering_close_hand } timer *= 1000; - if (timer > r->server->lingering_timeout) { - timer = r->server->lingering_timeout; + if (timer > lcf->lingering_timeout) { + timer = lcf->lingering_timeout; } ngx_del_timer(ev); diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -34,6 +34,7 @@ ngx_http_module_t ngx_http_header_filte ngx_module_t ngx_http_header_filter_module = { + 0, /* module index */ &ngx_http_header_filter_module_ctx, /* module context */ NULL, /* module directives */ NGX_HTTP_MODULE_TYPE, /* module type */ diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c --- a/src/http/ngx_http_output_filter.c +++ b/src/http/ngx_http_output_filter.c @@ -14,14 +14,16 @@ static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src); static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool); +static char *ngx_http_output_filter_merge_conf(ngx_pool_t *pool, + void *parent, void *child); static ngx_command_t ngx_http_output_filter_commands[] = { {ngx_string("output_buffer"), - NGX_CONF_TAKE1, + NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, ngx_conf_set_size_slot, - NGX_HTTP_LOC_CONF, + NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_output_filter_conf_t, hunk_size)}, {ngx_string(""), 0, NULL, 0, 0} @@ -34,7 +36,7 @@ static ngx_http_module_t ngx_http_outpu NULL, /* create server config */ NULL, /* init server config */ ngx_http_output_filter_create_conf, /* create location config */ - NULL, /* merge location config */ + ngx_http_output_filter_merge_conf, /* merge location config */ NULL, /* translate handler */ @@ -47,6 +49,7 @@ static ngx_http_module_t ngx_http_outpu ngx_module_t ngx_http_output_filter_module = { + 0, /* module index */ &ngx_http_output_filter_module_ctx, /* module context */ ngx_http_output_filter_commands, /* module directives */ NGX_HTTP_MODULE_TYPE, /* module type */ @@ -249,7 +252,7 @@ int ngx_http_output_filter(ngx_http_requ if (ctx->hunk) { ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; } -#if (!NGX_ONESHOT_EVENT) +#if (NGX_LEVEL_EVENT) ngx_del_event(r->connection->write, NGX_WRITE_EVENT); #endif } @@ -315,3 +318,17 @@ static void *ngx_http_output_filter_crea return conf; } + + +static char *ngx_http_output_filter_merge_conf(ngx_pool_t *pool, + void *parent, void *child) +{ + ngx_http_output_filter_conf_t *prev = + (ngx_http_output_filter_conf_t *) parent; + ngx_http_output_filter_conf_t *conf = + (ngx_http_output_filter_conf_t *) child; + + ngx_conf_merge(conf->hunk_size, prev->hunk_size, 32768); + + return NULL; +} diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -43,33 +43,39 @@ printf("\nstate: %d, pos: %x, end: %x, c case sw_start: switch (ch) { case 'G': - if (p + 1 >= r->header_in->last.mem) + if (p + 1 >= r->header_in->last.mem) { return NGX_AGAIN; + } - if (*p != 'E' || *(p + 1) != 'T') + if (*p != 'E' || *(p + 1) != 'T') { return NGX_HTTP_PARSE_INVALID_METHOD; + } r->method = NGX_HTTP_GET; p += 2; break; case 'H': - if (p + 2 >= r->header_in->last.mem) + if (p + 2 >= r->header_in->last.mem) { return NGX_AGAIN; + } - if (*p != 'E' || *(p + 1) != 'A' || *(p + 2) != 'D') + if (*p != 'E' || *(p + 1) != 'A' || *(p + 2) != 'D') { return NGX_HTTP_PARSE_INVALID_METHOD; + } r->method = NGX_HTTP_HEAD; p += 3; break; case 'P': - if (p + 2 >= r->header_in->last.mem) + if (p + 2 >= r->header_in->last.mem) { return NGX_AGAIN; + } - if (*p != 'O' || *(p + 1) != 'S' || *(p + 2) != 'T') + if (*p != 'O' || *(p + 1) != 'S' || *(p + 2) != 'T') { return NGX_HTTP_PARSE_INVALID_METHOD; + } r->method = NGX_HTTP_POST; p += 3; @@ -226,8 +232,9 @@ printf("\nstate: %d, pos: %x, end: %x, c return NGX_AGAIN; } - if (ch != 'T' || *p != 'T' || *(p + 1) != 'P' || *(p + 2) != '/') + if (ch != 'T' || *p != 'T' || *(p + 1) != 'P' || *(p + 2) != '/') { return NGX_HTTP_PARSE_INVALID_REQUEST; + } p += 3; state = sw_first_major_digit; @@ -235,8 +242,9 @@ printf("\nstate: %d, pos: %x, end: %x, c /* first digit of major HTTP version */ case sw_first_major_digit: - if (ch < '1' || ch > '9') + if (ch < '1' || ch > '9') { return NGX_HTTP_PARSE_INVALID_REQUEST; + } r->http_major = ch - '0'; state = sw_major_digit; @@ -249,16 +257,18 @@ printf("\nstate: %d, pos: %x, end: %x, c break; } - if (ch < '0' || ch > '9') + if (ch < '0' || ch > '9') { return NGX_HTTP_PARSE_INVALID_REQUEST; + } r->http_major = r->http_major * 10 + ch - '0'; break; /* first digit of minor HTTP version */ case sw_first_minor_digit: - if (ch < '0' || ch > '9') + if (ch < '0' || ch > '9') { return NGX_HTTP_PARSE_INVALID_REQUEST; + } r->http_minor = ch - '0'; state = sw_minor_digit; @@ -276,8 +286,9 @@ printf("\nstate: %d, pos: %x, end: %x, c break; } - if (ch < '0' || ch > '9') + if (ch < '0' || ch > '9') { return NGX_HTTP_PARSE_INVALID_REQUEST; + } r->http_minor = r->http_minor * 10 + ch - '0'; break; @@ -299,14 +310,19 @@ printf("\nstate: %d, pos: %x, end: %x, c r->header_in->pos.mem = p; if (state == sw_done) { - if (r->request_end == NULL) + if (r->request_end == NULL) { r->request_end = p - 1; + } + r->http_version = r->http_major * 1000 + r->http_minor; r->state = sw_start; - if (r->http_version == 9 && r->method == NGX_HTTP_HEAD) + + if (r->http_version == 9 && r->method == NGX_HTTP_HEAD) { return NGX_HTTP_PARSE_INVALID_HEAD; - else + } else { return NGX_OK; + } + } else { r->state = state; return NGX_AGAIN; @@ -358,14 +374,17 @@ printf("\nstate: %d, pos: %x, end: %x, c r->header_name_start = p - 1; c = ch | 0x20; - if (c >= 'a' && c <= 'z') + if (c >= 'a' && c <= 'z') { break; + } - if (ch == '-') + if (ch == '-') { break; + } - if (ch >= '0' && ch <= '9') + if (ch >= '0' && ch <= '9') { break; + } return NGX_HTTP_PARSE_INVALID_HEADER; @@ -375,8 +394,9 @@ printf("\nstate: %d, pos: %x, end: %x, c /* header name */ case sw_name: c = ch | 0x20; - if (c >= 'a' && c <= 'z') + if (c >= 'a' && c <= 'z') { break; + } if (ch == ':') { r->header_name_end = p - 1; @@ -384,11 +404,13 @@ printf("\nstate: %d, pos: %x, end: %x, c break; } - if (ch == '-') + if (ch == '-') { break; + } - if (ch >= '0' && ch <= '9') + if (ch >= '0' && ch <= '9') { break; + } return NGX_HTTP_PARSE_INVALID_HEADER; @@ -476,9 +498,11 @@ printf("\nstate: %d, pos: %x, end: %x, c if (state == sw_done) { r->state = sw_start; return NGX_OK; + } else if (state == sw_header_done) { r->state = sw_start; return NGX_HTTP_PARSE_HEADER_DONE; + } else { r->state = state; return NGX_AGAIN; diff --git a/src/http/ngx_http_parse_time.c b/src/http/ngx_http_parse_time.c --- a/src/http/ngx_http_parse_time.c +++ b/src/http/ngx_http_parse_time.c @@ -21,8 +21,9 @@ time_t ngx_http_parse_time(char *value, end = value + len; for (p = value; p < end; p++) { - if (*p == ',') + if (*p == ',') { break; + } if (*p == ' ') { fmt = isoc; @@ -31,22 +32,26 @@ time_t ngx_http_parse_time(char *value, } for (p++; p < end; p++) - if (*p != ' ') + if (*p != ' ') { break; + } - if (end - p < 18) + if (end - p < 18) { return NGX_ERROR; + } if (fmt != isoc) { - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { return NGX_ERROR; + } day = (*p - '0') * 10 + *(p + 1) - '0'; p += 2; if (*p == ' ') { - if (end - p < 18) + if (end - p < 18) { return NGX_ERROR; + } fmt = rfc822; } else if (*p == '-') { @@ -99,8 +104,9 @@ time_t ngx_http_parse_time(char *value, p += 3; - if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) + if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) { return NGX_ERROR; + } p++; @@ -108,15 +114,18 @@ time_t ngx_http_parse_time(char *value, if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9' || *(p + 2) < '0' || *(p + 2) > '9' || *(p + 3) < '0' || *(p + 3) > '9') + { return NGX_ERROR; + } year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100 + (*(p + 2) - '0') * 10 + *(p + 3) - '0'; p += 4; } else if (fmt == rfc850) { - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { return NGX_ERROR; + } year = (*p - '0') * 10 + *(p + 1) - '0'; year += (year < 70) ? 2000 : 1900; @@ -124,61 +133,74 @@ time_t ngx_http_parse_time(char *value, } if (fmt == isoc) { - if (*p == ' ') + if (*p == ' ') { p++; + } - if (*p < '0' || *p > '9') + if (*p < '0' || *p > '9') { return NGX_ERROR; + } day = *p++ - '0'; if (*p != ' ') { - if (*p < '0' || *p > '9') + if (*p < '0' || *p > '9') { return NGX_ERROR; + } day = day * 10 + *p++ - '0'; } - if (end - p < 14) + if (end - p < 14) { return NGX_ERROR; + } } - if (*p++ != ' ') + if (*p++ != ' ') { return NGX_ERROR; + } - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { return NGX_ERROR; + } hour = (*p - '0') * 10 + *(p + 1) - '0'; p += 2; - if (*p++ != ':') + if (*p++ != ':') { return NGX_ERROR; + } - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { return NGX_ERROR; + } min = (*p - '0') * 10 + *(p + 1) - '0'; p += 2; - if (*p++ != ':') + if (*p++ != ':') { return NGX_ERROR; + } - if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') + if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') { return NGX_ERROR; + } sec = (*p - '0') * 10 + *(p + 1) - '0'; if (fmt == isoc) { p += 2; - if (*p++ != ' ') + if (*p++ != ' ') { return NGX_ERROR; + } if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9' || *(p + 2) < '0' || *(p + 2) > '9' || *(p + 3) < '0' || *(p + 3) > '9') + { return NGX_ERROR; + } year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100 + (*(p + 2) - '0') * 10 + *(p + 3) - '0'; @@ -188,19 +210,22 @@ time_t ngx_http_parse_time(char *value, printf("%d.%d.%d %d:%d:%d\n", day, month + 1, year, hour, min, sec); #endif - if (hour > 23 || min > 59 || sec > 59) + if (hour > 23 || min > 59 || sec > 59) { return NGX_ERROR; + } if (day == 29 && month == 1) { - if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) + if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) { return NGX_ERROR; + } } else if (day > mday[month]) { return NGX_ERROR; } - if (sizeof(time_t) <= 4 && year >= 2038) + if (sizeof(time_t) <= 4 && year >= 2038) { return NGX_ERROR; + } /* shift new year to 1st March, needed for Gauss's formula */ if (--month <= 0) { 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 @@ -13,14 +13,16 @@ static void *ngx_http_write_filter_create_conf(ngx_pool_t *pool); +static char *ngx_http_write_filter_merge_conf(ngx_pool_t *pool, + void *parent, void *child); static ngx_command_t ngx_http_write_filter_commands[] = { {ngx_string("write_buffer"), - NGX_CONF_TAKE1, + NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1, ngx_conf_set_size_slot, - NGX_HTTP_LOC_CONF, + NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_write_filter_conf_t, buffer_output)}, {ngx_string(""), 0, NULL, 0, 0} @@ -33,7 +35,7 @@ ngx_http_module_t ngx_http_write_filter NULL, /* create server config */ NULL, /* init server config */ ngx_http_write_filter_create_conf, /* create location config */ - NULL, /* merge location config */ + ngx_http_write_filter_merge_conf, /* merge location config */ NULL, /* translate handler */ @@ -45,6 +47,7 @@ ngx_http_module_t ngx_http_write_filter ngx_module_t ngx_http_write_filter_module = { + 0, /* module index */ &ngx_http_write_filter_module_ctx, /* module context */ ngx_http_write_filter_commands, /* module directives */ NGX_HTTP_MODULE_TYPE, /* module type */ @@ -79,9 +82,12 @@ 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_FMT " " QD_FMT _ +#if (NGX_DEBUG_WRITE_FILTER) + ngx_log_debug(r->connection->log, "write filter: old chunk: %x " + QX_FMT " " QD_FMT _ ch->hunk->type _ ch->hunk->pos.file _ ch->hunk->last.file - ch->hunk->pos.file); +#endif if (ch->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) { flush = size; @@ -102,9 +108,12 @@ 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_FMT " " QD_FMT _ +#if (NGX_DEBUG_WRITE_FILTER) + ngx_log_debug(r->connection->log, "write filter: new chunk: %x " + QX_FMT " " QD_FMT _ ch->hunk->type _ ch->hunk->pos.file _ ch->hunk->last.file - ch->hunk->pos.file); +#endif if (ch->hunk->type & (NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)) { flush = size; @@ -119,7 +128,10 @@ int ngx_http_write_filter(ngx_http_reque ngx_http_get_module_loc_conf(r->main ? r->main : r, ngx_http_write_filter_module_ctx); - ngx_log_debug(r->connection->log, "l:%d f:%d" _ last _ flush); +#if (NGX_DEBUG_WRITE_FILTER) + ngx_log_debug(r->connection->log, "write filter: last:%d flush:%d" _ + last _ flush); +#endif if (!last && flush == 0 && size < conf->buffer_output) { return NGX_OK; @@ -150,3 +162,18 @@ static void *ngx_http_write_filter_creat return conf; } + + +static char *ngx_http_write_filter_merge_conf(ngx_pool_t *pool, + void *parent, void *child) +{ + ngx_http_write_filter_conf_t *prev = + (ngx_http_write_filter_conf_t *) parent; + ngx_http_write_filter_conf_t *conf = + (ngx_http_write_filter_conf_t *) child; + + ngx_conf_merge(conf->buffer_output, prev->buffer_output, 1460); + + return NULL; +} + diff --git a/src/os/unix/ngx_pthread.c b/src/os/unix/ngx_pthread.c new file mode 100644 --- /dev/null +++ b/src/os/unix/ngx_pthread.c @@ -0,0 +1,26 @@ + + +#include + +#include +#include + + +int ngx_create_os_thread(ngx_os_tid_t *tid, void *stack, + ngx_thread_start_routine_t func, void *arg, + ngx_log_t log) +{ + int err; + pthread_attr_t *attr; + + attr = NULL; + + err = pthread_create(tid, attr, func, arg); + + if (err != 0) { + ngx_log_error(NGX_LOG_ERR, log, err, "pthread_create() failed"); + return NGX_ERROR; + } + + return NGX_OK; +} diff --git a/src/os/unix/ngx_pthread.h b/src/os/unix/ngx_pthread.h new file mode 100644 --- /dev/null +++ b/src/os/unix/ngx_pthread.h @@ -0,0 +1,14 @@ +#ifndef _NGX_OS_THREAD_H_INCLUDED_ +#define _NGX_OS_THREAD_H_INCLUDED_ + + +#include + + +typedef pthread_t ngx_os_tid_t; +typedef int ngx_tid_t; + +typedef void *(*)(void *) ngx_thread_start_routine_t + + +#endif /* _NGX_OS_THREAD_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_os_thread.c b/src/os/win32/ngx_os_thread.c new file mode 100644 --- /dev/null +++ b/src/os/win32/ngx_os_thread.c @@ -0,0 +1,26 @@ + + +#include + +#include +#include + + +int ngx_create_os_thread(ngx_os_tid_t *tid, void *stack, + ngx_thread_start_routine_t func, void *arg, + ngx_log_t log) +{ + ngx_os_tid_t id; + int dummy; /* needed in Win9X only, in NT can be NULL */ + + id = CreateThread(NULL, stack_size, func, arg, 0, &dummy); + + if (id == NULL) { + ngx_log_error(NGX_LOG_ERR, log, err, "CreateThread() failed"); + return NGX_ERROR; + } + + *tid = id; + + return NGX_OK; +} diff --git a/src/os/win32/ngx_os_thread.h b/src/os/win32/ngx_os_thread.h new file mode 100644 --- /dev/null +++ b/src/os/win32/ngx_os_thread.h @@ -0,0 +1,14 @@ +#ifndef _NGX_OS_THREAD_H_INCLUDED_ +#define _NGX_OS_THREAD_H_INCLUDED_ + + +#include + + +typedef HANDLE ngx_os_tid_t; +typedef int ngx_tid_t; + +typedef LPTHREAD_START_ROUTINE ngx_thread_start_routine_t + + +#endif /* _NGX_OS_THREAD_H_INCLUDED_ */