From ad22e01112003ec8600f3e1f6ef184fc18a69bc8 Mon Sep 17 00:00:00 2001 From: Igor Sysoev Date: Wed, 15 Jan 2003 07:02:27 +0000 Subject: [PATCH] nginx-0.0.1-2003-01-15-10:02:27 import --- src/core/ngx_core.h | 6 ++ src/core/ngx_hunk.h | 4 +- src/core/ngx_string.h | 4 + src/event/modules/ngx_devpoll_module.c | 11 ++- src/http/modules/ngx_http_index_handler.c | 63 +++++++--------- src/http/modules/ngx_http_index_handler.h | 1 - src/http/ngx_http.h | 1 + src/http/ngx_http_core_module.c | 92 ++++++++++++++++++----- src/http/ngx_http_core_module.h | 2 +- src/http/ngx_http_event.c | 3 +- src/http/ngx_http_header_filter.c | 2 +- src/http/ngx_http_output_filter.c | 2 +- src/http/ngx_http_output_filter.h | 5 +- src/http/ngx_http_special_response.c | 11 ++- src/os/unix/ngx_errno.h | 2 +- src/os/win32/ngx_errno.h | 2 +- 16 files changed, 142 insertions(+), 69 deletions(-) diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index f5b25c43a..adab5018c 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -10,4 +10,10 @@ #define NGX_DECLINED -4 +#define NGX_MAXHOSTNAMELEN 32 +/* +#define NGX_MAXHOSTNAMELEN MAXHOSTNAMELEN +*/ + + #endif /* _NGX_CORE_H_INCLUDED_ */ diff --git a/src/core/ngx_hunk.h b/src/core/ngx_hunk.h index 75aaef132..42030eb26 100644 --- a/src/core/ngx_hunk.h +++ b/src/core/ngx_hunk.h @@ -24,8 +24,10 @@ #define NGX_HUNK_FLUSH 0x0100 /* last hunk */ #define NGX_HUNK_LAST 0x0200 +#if 0 /* can be used with NGX_HUNK_LAST only */ -#define NGX_HUNK_SHUTDOWN 0x0400 +#define NGX_HUNK_SHUTDOWN 0x0400 / +#endif #define NGX_HUNK_RECYCLED 0x0800 diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h index 193308452..ea255ba2f 100644 --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -22,6 +22,8 @@ typedef struct { #define ngx_strncmp strncmp #define ngx_strcmp strcmp +#define ngx_strlen strlen + #define ngx_snprintf _snprintf #define ngx_vsnprintf _vsnprintf @@ -33,6 +35,8 @@ typedef struct { #define ngx_strncmp strncmp #define ngx_strcmp strcmp +#define ngx_strlen strlen + #define ngx_snprintf snprintf #define ngx_vsnprintf vsnprintf diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c index 4f470d307..29cd298b1 100644 --- a/src/event/modules/ngx_devpoll_module.c +++ b/src/event/modules/ngx_devpoll_module.c @@ -206,10 +206,13 @@ int ngx_devpoll_process_events(ngx_log_t *log) ngx_log_debug(log, "devpoll timer: %d" _ timer); #endif - n = nchanges * sizeof(struct pollfd); - if (write(dp, change_list, n) != n) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "write(/dev/poll) failed"); - return NGX_ERROR; + if (nchanges) { + n = nchanges * sizeof(struct pollfd); + if (write(dp, change_list, n) != n) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + "write(/dev/poll) failed"); + return NGX_ERROR; + } } dvp.dp_fds = event_list; diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c index 2f893d218..19de209cb 100644 --- a/src/http/modules/ngx_http_index_handler.c +++ b/src/http/modules/ngx_http_index_handler.c @@ -62,10 +62,9 @@ ngx_module_t ngx_http_index_module = { /* - If the first index file is local (i.e. 'index.html', not '/index.html') then - try to open it before the test of the directory existence because - the valid requests should be many more then invalid ones. If open() - is failed then stat() should be more quickly because some data + Try to open first index file before the test of the directory existence + because the valid requests should be many more then invalid ones. + If open() is failed then stat() should be more quickly because some data is already cached in the kernel. Besides Win32 has ERROR_PATH_NOT_FOUND and Unix has ENOTDIR error (although it less helpfull). */ @@ -98,17 +97,7 @@ int ngx_http_index_handler(ngx_http_request_t *r) file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1); r->path.len = file - r->path.data; - if (cf->test_dir) { - rc = ngx_http_index_test_dir(r); - if (rc != NGX_OK) { - return rc; - } - - test_dir = 0; - - } else { - test_dir = 1; - } + test_dir = 1; index = (ngx_str_t *) cf->indices->elts; for (i = 0; i < cf->indices->nelts; i++) { @@ -125,8 +114,8 @@ int ngx_http_index_handler(ngx_http_request_t *r) if (fd == NGX_INVALID_FILE) { err = ngx_errno; - ngx_log_error(NGX_LOG_ERR, r->connection->log, err, - ngx_open_file_n " %s failed", name); +ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err, + "DEBUG: " ngx_open_file_n " %s failed", name); #if (WIN32) if (err == ERROR_PATH_NOT_FOUND) { @@ -134,10 +123,15 @@ int ngx_http_index_handler(ngx_http_request_t *r) if (err == NGX_ENOTDIR) { #endif r->path_not_found = 1; + + } else if (err == NGX_EACCES) { + r->path_err = err; + return NGX_HTTP_FORBIDDEN; } if (test_dir) { if (r->path_not_found) { + r->path_err = err; return NGX_HTTP_NOT_FOUND; } @@ -147,10 +141,6 @@ int ngx_http_index_handler(ngx_http_request_t *r) } test_dir = 0; - - if (r->path_not_found) { - continue; - } } if (err == NGX_ENOENT) { @@ -186,31 +176,36 @@ int ngx_http_index_handler(ngx_http_request_t *r) static int ngx_http_index_test_dir(ngx_http_request_t *r) { - ngx_err_t err; - r->path.data[r->path.len - 1] = '\0'; + r->path.data[r->path.len] = '\0'; ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data); +#if 0 + if (r->path_err == NGX_EACCES) { + return NGX_HTTP_FORBIDDEN; + } +#endif + if (ngx_file_type(r->path.data, &r->file.info) == -1) { - err = ngx_errno; - if (err == NGX_ENOENT) { + + r->path_err = ngx_errno; + + if (r->path_err == NGX_ENOENT) { + r->path.data[r->path.len - 1] = '/'; return NGX_HTTP_NOT_FOUND; } - if (err == NGX_EACCESS) { - return NGX_HTTP_FORBIDDEN; - } - - ngx_log_error(NGX_LOG_ERR, r->connection->log, err, - "ngx_http_index_is_dir: " - "stat() %s failed", 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; } + r->path.data[r->path.len - 1] = '/'; + if (ngx_is_dir(r->file.info)) { - r->path.data[r->path.len - 1] = '/'; return NGX_OK; } else { @@ -260,7 +255,7 @@ static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) conf->max_index_len = sizeof(NGX_HTTP_INDEX); } - /* TODO: set conf->test_dir if first index is started with '/' */ + /* FAIL: if first index is started with '/' */ return NULL; } diff --git a/src/http/modules/ngx_http_index_handler.h b/src/http/modules/ngx_http_index_handler.h index d077feb4c..3dd6bd82c 100644 --- a/src/http/modules/ngx_http_index_handler.h +++ b/src/http/modules/ngx_http_index_handler.h @@ -13,7 +13,6 @@ typedef struct { ngx_array_t *indices; size_t max_index_len; - int test_dir; } ngx_http_index_conf_t; diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h index 44b9497e7..c818b5a88 100644 --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -140,6 +140,7 @@ struct ngx_http_request_s { char *discarded_buffer; ngx_str_t path; + int path_err; unsigned keepalive:1; unsigned lingering_close:1; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 575312a76..972b461e7 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -94,7 +94,7 @@ int ngx_http_handler(ngx_http_request_t *r) r->connection->unexpected_eof = 0; r->lingering_close = 1; - r->keepalive = 0; + r->keepalive = 1; ctx = (ngx_http_conf_ctx_t *) r->connection->ctx; r->srv_conf = ctx->srv_conf; @@ -143,10 +143,11 @@ ngx_log_debug(r->connection->log, "servers: %0x" _ r->connection->servers); int ngx_http_core_translate_handler(ngx_http_request_t *r) { - int i, rc; - char *location, *last; + int i, rc, len, f_offset, l_offset; + char *buf, *location, *last; ngx_err_t err; ngx_table_elt_t *h; + ngx_http_server_name_t *s_name; ngx_http_core_srv_conf_t *scf; ngx_http_core_loc_conf_t **lcf, *loc_conf; @@ -180,18 +181,36 @@ ngx_log_debug(r->connection->log, "trans: %s" _ lcf[i]->name.data); 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; + s_name = (ngx_http_server_name_t *) scf->server_names.elts; - ngx_test_null(r->file.name.data, - ngx_palloc(r->pool, r->file.name.len + 1), + /* "+ 7" is "http://" */ + if (loc_conf->doc_root.len > s_name[0].name.len + 7) { + len = loc_conf->doc_root.len; + f_offset = 0; + l_offset = len - (s_name[0].name.len + 7); + + } else { + len = s_name[0].name.len + 7; + f_offset = len - loc_conf->doc_root.len; + l_offset = 0; + } + + /* "+ 2" is for trailing '/' in redirect and '\0' */ + len += r->uri.len + 2; + + ngx_test_null(buf, ngx_palloc(r->pool, len), NGX_HTTP_INTERNAL_SERVER_ERROR); - 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); + r->file.name.data = buf + f_offset; + location = buf + l_offset; - ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ - r->file.name.data); + last = ngx_cpystrn(ngx_cpystrn(r->file.name.data, loc_conf->doc_root.data, + loc_conf->doc_root.len + 1), + r->uri.data, r->uri.len + 1); + + r->file.name.len = last - r->file.name.data; + +ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data); #if (WIN9X) @@ -212,7 +231,7 @@ ngx_log_debug(r->connection->log, "trans: %s" _ lcf[i]->name.data); } else if (err == ERROR_PATH_NOT_FOUND) { return NGX_HTTP_NOT_FOUND; - } else if (err == NGX_EACCESS) { + } else if (err == NGX_EACCES) { return NGX_HTTP_FORBIDDEN; } else { @@ -241,7 +260,7 @@ ngx_log_debug(r->connection->log, "trans: %s" _ lcf[i]->name.data); } else if (err == NGX_ENOTDIR) { return NGX_HTTP_NOT_FOUND; #endif - } else if (err == NGX_EACCESS) { + } else if (err == NGX_EACCES) { return NGX_HTTP_FORBIDDEN; } else { @@ -251,12 +270,12 @@ ngx_log_debug(r->connection->log, "trans: %s" _ lcf[i]->name.data); if (!r->file.info_valid) { if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, + ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, "ngx_http_core_handler: " ngx_stat_fd_n " %s failed", r->file.name.data); if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, + ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, "ngx_http_core_handler: " ngx_close_file_n " %s failed", r->file.name.data); } @@ -269,11 +288,11 @@ ngx_log_debug(r->connection->log, "trans: %s" _ lcf[i]->name.data); #endif if (ngx_is_dir(r->file.info)) { - ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data); +ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data); #if !(WIN9X) if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, + ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, "ngx_http_core_handler: " ngx_close_file_n " %s failed", r->file.name.data); } @@ -284,6 +303,9 @@ ngx_log_debug(r->connection->log, "trans: %s" _ lcf[i]->name.data); ngx_test_null(h, ngx_push_table(r->headers_out.headers), NGX_HTTP_INTERNAL_SERVER_ERROR); + ngx_memcpy(location, "http://", 7); + ngx_memcpy(location + 7, s_name[0].name.data, s_name[0].name.len); + *last++ = '/'; *last = '\0'; h->key.len = 8; @@ -312,10 +334,25 @@ static int ngx_http_core_index_handler(ngx_http_request_t *r) rc = h[i](r); if (rc != NGX_DECLINED) { + + if (rc == NGX_HTTP_NOT_FOUND) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, r->path_err, + "%s is not found", r->path.data); + } + + if (rc == NGX_HTTP_FORBIDDEN) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, r->path_err, + "%s is forbidden", r->path.data); + } + return rc; } } + r->path.data[r->path.len] = '\0'; + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "directory index of %s is forbidden", r->path.data); + return NGX_HTTP_FORBIDDEN; } @@ -359,7 +396,7 @@ int ngx_http_close_request(ngx_http_request_t *r) if (r->file.fd != NGX_INVALID_FILE) { if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, + ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, ngx_close_file_n " failed"); } } @@ -688,6 +725,8 @@ static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool) 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_init_array(scf->server_names, pool, 5, sizeof(ngx_http_server_name_t), + NGX_CONF_ERROR); ngx_test_null(cf, ngx_push_array(&ngx_http_servers), NGX_CONF_ERROR); *cf = scf; @@ -701,6 +740,7 @@ 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; + ngx_http_server_name_t *n; if (scf->listen.nelts == 0) { ngx_test_null(l, ngx_push_array(&scf->listen), NGX_CONF_ERROR); @@ -709,6 +749,22 @@ static char *ngx_http_core_init_srv_conf(ngx_pool_t *pool, void *conf) l->family = AF_INET; } + if (scf->server_names.nelts == 0) { + ngx_test_null(n, ngx_push_array(&scf->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) { +/* STUB: no log here */ +#if 0 + ngx_log_error(NGX_LOG_EMERG, scf->log, ngx_errno, + "gethostname() failed"); +#endif + return NGX_CONF_ERROR; + } + n->name.len = ngx_strlen(n->name.data); + n->core_srv_conf = conf; + } + return NGX_CONF_OK; } diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index ed0173bd5..48b1ced73 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -28,7 +28,7 @@ typedef struct { typedef struct { - ngx_str_t name; + ngx_str_t name; ngx_http_core_srv_conf_t *core_srv_conf; } ngx_http_server_name_t; diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c index 1a8338b8c..948b3f726 100644 --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -143,6 +143,7 @@ static int ngx_http_init_request(ngx_event_t *ev) ngx_http_request_t *r; c = (ngx_connection_t *) ev->data; + c->sent = 0; ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)), NGX_ERROR); @@ -497,8 +498,6 @@ static int ngx_http_writer(ngx_event_t *ev) c = (ngx_connection_t *) ev->data; r = (ngx_http_request_t *) c->data; - c->sent = 0; - rc = ngx_http_output_filter(r, NULL); ngx_log_debug(ev->log, "output filter in writer: %d" _ rc); diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c index 04a383733..08369b7f3 100644 --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -99,7 +99,6 @@ static int ngx_http_header_filter(ngx_http_request_t *r) r->headers_out.status = NGX_HTTP_NOT_MODIFIED; r->headers_out.content_length = -1; r->headers_out.content_type->key.len = 0; - r->header_only = 1; } } } @@ -114,6 +113,7 @@ static int ngx_http_header_filter(ngx_http_request_t *r) } else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) { status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 1; + r->header_only = 1; } else if (r->headers_out.status < NGX_HTTP_INTERNAL_SERVER_ERROR) { status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 1 + 4; diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c index 815c3fe38..b2eec279d 100644 --- a/src/http/ngx_http_output_filter.c +++ b/src/http/ngx_http_output_filter.c @@ -297,7 +297,7 @@ static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src) dst->last.mem += size; } - if (src->type & NGX_HUNK_LAST) { + if (src->type & NGX_HUNK_LAST && src->pos.mem == src->last.mem) { dst->type |= NGX_HUNK_LAST; } diff --git a/src/http/ngx_http_output_filter.h b/src/http/ngx_http_output_filter.h index d8df958bf..175550eaa 100644 --- a/src/http/ngx_http_output_filter.h +++ b/src/http/ngx_http_output_filter.h @@ -7,8 +7,9 @@ #include -#define NGX_HTTP_FILTER_NEED_IN_MEMORY 1 -#define NGX_HTTP_FILTER_NEED_TEMP 2 +#define NGX_HTTP_FILTER_NEED_IN_MEMORY 1 +#define NGX_HTTP_FILTER_SSI_NEED_IN_MEMORY 2 +#define NGX_HTTP_FILTER_NEED_TEMP 4 typedef struct { diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c index b458f5973..4e5e3b251 100644 --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -33,6 +33,13 @@ static char error_404_page[] = "

404 Not Found

" CRLF ; +static char error_500_page[] = +"" CRLF +"500 Internal Server Error" CRLF +"" CRLF +"

500 Internal Server Error

" CRLF +; + static ngx_str_t error_pages[] = { { 0, NULL}, /* 301 */ @@ -46,7 +53,7 @@ static ngx_str_t error_pages[] = { { sizeof(error_403_page) - 1, error_403_page }, { sizeof(error_404_page) - 1, error_404_page }, - { 0, NULL} /* 500 */ + { sizeof(error_500_page) - 1, error_500_page } }; int ngx_http_special_response(ngx_http_request_t *r, int error) @@ -65,7 +72,7 @@ int ngx_http_special_response(ngx_http_request_t *r, int error) err = error - NGX_HTTP_BAD_REQUEST + 4; else - err = NGX_HTTP_INTERNAL_SERVER_ERROR + 4 + 5; + err = error - NGX_HTTP_INTERNAL_SERVER_ERROR + 4 + 5; if (error_pages[err].len == 0) r->headers_out.content_length = -1; diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h index 82a3a598f..62e1b0703 100644 --- a/src/os/unix/ngx_errno.h +++ b/src/os/unix/ngx_errno.h @@ -9,7 +9,7 @@ typedef int ngx_err_t; #define NGX_ENOENT ENOENT #define NGX_EINTR EINTR -#define NGX_EACCESS EACCESS +#define NGX_EACCES EACCES #define NGX_ENOTDIR ENOTDIR #define NGX_EAGAIN EWOULDBLOCK #define NGX_EINPROGRESS EINPROGRESS diff --git a/src/os/win32/ngx_errno.h b/src/os/win32/ngx_errno.h index 52ab29e97..92e5f21b0 100644 --- a/src/os/win32/ngx_errno.h +++ b/src/os/win32/ngx_errno.h @@ -11,7 +11,7 @@ typedef DWORD ngx_err_t; #define ngx_set_socket_errno(err) WSASetLastError(err) #define NGX_ENOENT ERROR_FILE_NOT_FOUND -#define NGX_EACCESS ERROR_ACCESS_DENIED +#define NGX_EACCES ERROR_ACCESS_DENIED #define NGX_EAGAIN WSAEWOULDBLOCK #define NGX_EINPROGRESS WSAEINPROGRESS #define NGX_EADDRINUSE WSAEADDRINUSE