diff options
Diffstat (limited to 'src/http')
| -rw-r--r-- | src/http/modules/ngx_http_index_handler.c | 32 | ||||
| -rw-r--r-- | src/http/ngx_http_cache.c | 63 | ||||
| -rw-r--r-- | src/http/ngx_http_core_module.c | 168 | ||||
| -rw-r--r-- | src/http/ngx_http_core_module.h | 3 |
4 files changed, 213 insertions, 53 deletions
diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c index 494621420..0286669f2 100644 --- a/src/http/modules/ngx_http_index_handler.c +++ b/src/http/modules/ngx_http_index_handler.c @@ -59,7 +59,7 @@ int ngx_http_index_handler(ngx_http_request_t *r) { int i, rc, test_dir; char *name, *file; - ngx_str_t loc, *index; + ngx_str_t redirect, *index; ngx_err_t err; ngx_fd_t fd; ngx_http_index_conf_t *icf; @@ -74,14 +74,14 @@ int ngx_http_index_handler(ngx_http_request_t *r) + icf->max_index_len), NGX_HTTP_INTERNAL_SERVER_ERROR); - loc.data = ngx_cpystrn(r->path.data, clcf->doc_root.data, - clcf->doc_root.len + 1); - file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1); + redirect.data = ngx_cpymem(r->path.data, clcf->doc_root.data, + clcf->doc_root.len); + file = ngx_cpystrn(redirect.data, r->uri.data, r->uri.len + 1); r->path.len = file - r->path.data; test_dir = 1; - index = (ngx_str_t *) icf->indices.elts; + index = icf->indices.elts; for (i = 0; i < icf->indices.nelts; i++) { if (index[i].data[0] != '/') { @@ -136,18 +136,15 @@ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err, if (index[i].data[0] == '/') { r->file.name.len = index[i].len; - loc.len = index[i].len; - loc.data = index[i].data; + redirect.len = index[i].len; + redirect.data = index[i].data; } else { - loc.len = r->uri.len + index[i].len; - r->file.name.len = clcf->doc_root.len + r->uri.len - + index[i].len; + redirect.len = r->uri.len + index[i].len; + r->file.name.len = clcf->doc_root.len + r->uri.len + index[i].len; } -/* STUB */ r->exten.len = 4; r->exten.data = "html"; - - return ngx_http_internal_redirect(r, loc); + return ngx_http_internal_redirect(r, &redirect, NULL); } return NGX_DECLINED; @@ -177,7 +174,6 @@ ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data); } ngx_log_error(NGX_LOG_CRIT, r->connection->log, r->path_err, - "ngx_http_index_test_dir: " ngx_file_type_n " %s failed", r->path.data); return NGX_HTTP_INTERNAL_SERVER_ERROR; @@ -263,7 +259,7 @@ static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) } -/* TODO: check duplicate indices */ +/* TODO: warn about duplicate indices */ static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) @@ -283,7 +279,9 @@ static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, for (i = 1; i < cf->args->nelts; i++) { if (value[i].len == 0) { - return "is invalid"; + ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1, + "index \"%s\" is invalid", value[1].data); + return ngx_conf_errstr; } ngx_test_null(index, ngx_push_array(&icf->indices), NGX_CONF_ERROR); @@ -295,5 +293,5 @@ static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, } } - return NULL; + return NGX_CONF_OK; } diff --git a/src/http/ngx_http_cache.c b/src/http/ngx_http_cache.c new file mode 100644 index 000000000..f9e36f597 --- /dev/null +++ b/src/http/ngx_http_cache.c @@ -0,0 +1,63 @@ + + + +#define NGX_HTTP_CACHE_ENTRY_DELETED 0x00000001 +#define NGX_HTTP_CACHE_ENTRY_MMAPED 0x00000002 + +/* "/" -> "/index.html" in ngx_http_index_handler */ +#define NGX_HTTP_CACHE_ENTRY_URI 0x00000004 + +#define NGX_HTTP_CACHE_FILTER_FLAGS 0xFFFF0000 + + +typedef struct { + ngx_fd_t fd; + off_t size; + void *data; + time_t accessed; + time_t last_modified; + time_t updated; /* no needed with kqueue */ + int refs; + int flags; +} ngx_http_cache_entry_t; + + +typedef struct { + u_int32_t crc; + ngx_str_t uri; + ngx_http_cache_t *cache; +} ngx_http_cache_hash_entry_t; + + +typedef struct { + ngx_http_cache_t *cache; + u_int32_t crc; + int n; +} ngx_http_cache_handle_t; + + +int ngx_http_cache_get(ngx_http_cache_hash_t *cache_hash, + ngx_str_t *uri, ngx_http_cache_handle_t *h) +{ + int hi; + ngx_http_cache_hash_entry_t *entry; + + h->crc = ngx_crc32(uri->data, uri->len); + + hi = h->crc % cache_hash->size; + entry = cache_hash[hi].elts; + + for (i = 0; i < cache_hash[hi].nelts; i++) { + if (entry[i].crc == crc + && entry[i].uri.len == uri->len + && ngx_strncmp(entry[i].uri.data, uri->data, uri->len) == 0 + { + h->cache = entry[i].cache; + h->cache->refs++; + h->n = hi; + return NGX_OK; + } + } + + return NGX_ERROR; +} diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index ba07718d3..b67866961 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -28,10 +28,13 @@ static char *ngx_http_core_merge_loc_conf(ngx_pool_t *pool, static int ngx_http_core_init(ngx_pool_t *pool); static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy); +static int ngx_cmp_locations(const void *first, const void *second); static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy); static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); static ngx_command_t ngx_http_core_commands[] = { @@ -41,7 +44,7 @@ static ngx_command_t ngx_http_core_commands[] = { ngx_server_block, 0, 0, - NULL,}, + NULL}, {ngx_string("connection_pool_size"), NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, @@ -99,6 +102,13 @@ static ngx_command_t ngx_http_core_commands[] = { 0, NULL}, + {ngx_string("server_name"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_ANY, + ngx_set_server_name, + NGX_HTTP_SRV_CONF_OFFSET, + 0, + NULL}, + {ngx_string("types"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF |NGX_CONF_BLOCK|NGX_CONF_NOARGS, @@ -215,8 +225,10 @@ ngx_log_debug(r->connection->log, "trans: %s" _ clcfp[i]->name.data); continue; } - rc = ngx_rstrncmp(r->uri.data, clcfp[i]->name.data, - clcfp[i]->name.len); + rc = ngx_strncmp(r->uri.data, clcfp[i]->name.data, + clcfp[i]->name.len); + +ngx_log_debug(r->connection->log, "rc: %d" _ rc); if (rc < 0) { break; @@ -235,9 +247,10 @@ ngx_log_debug(r->connection->log, "trans: %s" _ clcfp[i]->name.data); /* run translation phase */ - h = (ngx_http_handler_pt *) ngx_http_translate_handlers.elts; - for (i = ngx_http_translate_handlers.nelts; i > 0; /* void */) { - rc = h[--i](r); + h = ngx_http_translate_handlers.elts; + for (i = ngx_http_translate_handlers.nelts - 1; i >= 0; i--) { + + rc = h[i](r); if (rc == NGX_DECLINED) { continue; @@ -457,21 +470,46 @@ int ngx_http_error(ngx_http_request_t *r, int error) } -int ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t uri) +int ngx_http_internal_redirect(ngx_http_request_t *r, + ngx_str_t *uri, ngx_str_t *args) { - ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri.data); + int i; - r->uri.len = uri.len; - r->uri.data = uri.data; + ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri->data); - /* BROKEN, NEEDED ? */ - /* r->exten */ - r->uri_start = uri.data; - r->uri_end = uri.data + uri.len; - /**/ + r->uri.len = uri->len; + r->uri.data = uri->data; + + if (args) { + r->args.len = args->len; + r->args.data = args->data; + } + + r->exten.len = 0; + r->exten.data = NULL; + + for (i = uri->len - 1; i > 1; i--) { + if (uri->data[i] == '.' && uri->data[i - 1] != '/') { + r->exten.len = uri->len - i - 1; + + if (r->exten.len > 0) { + ngx_test_null(r->exten.data, + ngx_palloc(r->pool, r->exten.len + 1), + NGX_HTTP_INTERNAL_SERVER_ERROR); + + ngx_cpystrn(r->exten.data, &uri->data[i + 1], r->exten.len + 1); + } + + break; + + } else if (uri->data[i] == '/') { + break; + } + } ngx_http_handler(r); - return 0; + + return NGX_OK; } @@ -554,10 +592,26 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) rv = ngx_conf_parse(cf, NULL); *cf = pcf; + if (rv != NGX_CONF_OK) { + return rv; + } + + ngx_qsort(cscf->locations.elts, cscf->locations.nelts, + sizeof(void *), ngx_cmp_locations); + return rv; } +static int ngx_cmp_locations(const void *first, const void *second) +{ + ngx_http_core_loc_conf_t *one = *(ngx_http_core_loc_conf_t **) first; + ngx_http_core_loc_conf_t *two = *(ngx_http_core_loc_conf_t **) second; + + return ngx_strcmp(one->name.data, two->name.data); +} + + static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) { int m; @@ -724,6 +778,7 @@ static char *ngx_http_core_merge_srv_conf(ngx_pool_t *pool, ngx_http_core_srv_conf_t *prev = (ngx_http_core_srv_conf_t *) parent; ngx_http_core_srv_conf_t *conf = (ngx_http_core_srv_conf_t *) child; + ngx_err_t err; ngx_http_listen_t *l; ngx_http_server_name_t *n; @@ -740,10 +795,15 @@ static char *ngx_http_core_merge_srv_conf(ngx_pool_t *pool, ngx_test_null(n, ngx_push_array(&conf->server_names), NGX_CONF_ERROR); ngx_test_null(n->name.data, ngx_palloc(pool, NGX_MAXHOSTNAMELEN), NGX_CONF_ERROR); + if (gethostname(n->name.data, NGX_MAXHOSTNAMELEN) == -1) { - /* TODO: need ngx_errno here */ - return "gethostname() failed"; + err = ngx_errno; + ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1, + "gethostname() failed (%d: %s)", + err, ngx_strerror(err)); + return ngx_conf_errstr; } + n->name.len = ngx_strlen(n->name.data); n->core_srv_conf = conf; } @@ -868,7 +928,7 @@ static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_http_listen_t *ls; /* TODO: check duplicate 'listen' directives, - add resolved name to server names */ + add resolved name to server names ??? */ ngx_test_null(ls, ngx_push_array(&scf->listen), NGX_CONF_ERROR); @@ -879,37 +939,75 @@ static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ls->file_name = cf->conf_file->file.name; ls->line = cf->conf_file->line; - args = (ngx_str_t *) cf->args->elts; + args = cf->args->elts; addr = args[1].data; for (p = 0; p < args[1].len; p++) { if (addr[p] == ':') { addr[p++] = '\0'; - - ls->addr = inet_addr(addr); - if (ls->addr == INADDR_NONE) { - h = gethostbyname(addr); - - if (h == NULL || h->h_addr_list[0] == NULL) { - return "can not resolve host name"; - } - - ls->addr = *(u_int32_t *)(h->h_addr_list[0]); - } - break; } } if (p == args[1].len) { - ls->addr = INADDR_ANY; + /* no ":" in the "listen" */ p = 0; } ls->port = ngx_atoi(&addr[p], args[1].len - p); - if (ls->port < 1 || ls->port > 65536) { - return "port must be between 1 and 65535"; + if (ls->port == NGX_ERROR && p == 0) { + + /* "listen host" */ + ls->port = 80; + + } else if ((ls->port == NGX_ERROR && p != 0) /* "listen host:NONNUMBER" */ + || (ls->port < 1 || ls->port > 65536)) { /* "listen 99999" */ + + ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1, + "invalid port \"%s\", " + "it must be a number between 1 and 65535", + &addr[p]); + return ngx_conf_errstr; + + } else if (p == 0) { + ls->addr = INADDR_ANY; + return NGX_CONF_OK; } + ls->addr = inet_addr(addr); + if (ls->addr == INADDR_NONE) { + h = gethostbyname(addr); + + if (h == NULL || h->h_addr_list[0] == NULL) { + ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1, + "can not resolve host \"%s\"", addr); + return ngx_conf_errstr; + } + + ls->addr = *(u_int32_t *)(h->h_addr_list[0]); + } + + return NGX_CONF_OK; +} + + +static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf; + + ngx_str_t *args; + ngx_http_server_name_t *sn; + + /* TODO: several names */ + /* TODO: warn about duplicate 'server_name' directives */ + + ngx_test_null(sn, ngx_push_array(&scf->server_names), NGX_CONF_ERROR); + + args = cf->args->elts; + + sn->name.len = args[1].len; + sn->name.data = args[1].data; + sn->core_srv_conf = scf; + return NGX_CONF_OK; } diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index 6d4acff15..113c197a8 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -138,7 +138,8 @@ extern int ngx_http_max_module; int ngx_http_core_translate_handler(ngx_http_request_t *r); -int ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t uri); +int ngx_http_internal_redirect(ngx_http_request_t *r, + ngx_str_t *uri, ngx_str_t *args); int ngx_http_error(ngx_http_request_t *r, int error); |
