# HG changeset patch # User Igor Sysoev # Date 1158177600 -14400 # Node ID d8f5c91a5c0775ec278321ce2feae5148d31f9ff # Parent 8024b0d522638ffc8af99e5e2b8b79fab1571dc2 nginx 0.4.1 *) Bugfix: the DragonFlyBSD compatibility. Thanks to Pavel Nazarov. *) Workaround: of bug in 64-bit Linux sendfile(), when file is more than 2G. *) Feature: now on Linux nginx uses O_NOATIME flag for static requests. Thanks to Yusuf Goolamabbas. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,17 @@ +Changes with nginx 0.4.1 14 Sep 2006 + + *) Bugfix: the DragonFlyBSD compatibility. + Thanks to Pavel Nazarov. + + *) Workaround: of bug in 64-bit Linux sendfile(), when file is more + than 2G. + + *) Feature: now on Linux nginx uses O_NOATIME flag for static + requests. + Thanks to Yusuf Goolamabbas. + + Changes with nginx 0.4.0 30 Aug 2006 *) Change in internal API: the HTTP modules initialization was moved diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,17 @@ +Изменения в nginx 0.4.1 14.09.2006 + + *) Исправление: совместимость с DragonFlyBSD. + Спасибо Павлу Назарову. + + *) Изменение: обход ошибки в sendfile() в 64-битном Linux при передаче + файлов больше 2G. + + *) Добавление: теперь на Linux nginx для статических запросов + использует флаг O_NOATIME. + Спасибо Yusuf Goolamabbas. + + Изменения в nginx 0.4.0 30.08.2006 *) Изменение во внутреннем API: инициализация модулей HTTP перенесена diff --git a/auto/os/conf b/auto/os/conf --- a/auto/os/conf +++ b/auto/os/conf @@ -6,7 +6,7 @@ echo "checking for $NGX_SYSTEM specific case "$NGX_PLATFORM" in - FreeBSD:* | DragonFly:*) + FreeBSD:*) . auto/os/freebsd ;; @@ -22,6 +22,20 @@ case "$NGX_PLATFORM" in . auto/os/win32 ;; + DragonFly:*) + have=NGX_FREEBSD . auto/have_headers + CORE_INCS="$UNIX_INCS" + CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS" + CORE_SRCS="$UNIX_SRCS $FREEBSD_SRCS" + + echo " + sendfile() found" + have=NGX_HAVE_SENDFILE . auto/have + CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS" + + ngx_spacer=' +' + ;; + Darwin:*) have=NGX_DARWIN . auto/have_headers have=NGX_HAVE_INHERITED_NONBLOCK . auto/have diff --git a/auto/os/freebsd b/auto/os/freebsd --- a/auto/os/freebsd +++ b/auto/os/freebsd @@ -14,7 +14,7 @@ ngx_spacer=' # __FreeBSD_version and sysctl kern.osreldate are the best ways # to determine whether some capability exists and is safe to use. -# __FreeBSD_version is used for the testing of the build enviroment. +# __FreeBSD_version is used for the testing of the build environment. # sysctl kern.osreldate is used for the testing of the kernel capabilities. version=`grep "#define __FreeBSD_version" /usr/include/osreldate.h \ diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VER "nginx/0.4.0" +#define NGINX_VER "nginx/0.4.1" #define NGINX_VAR "NGINX" #define NGX_OLDPID_EXT ".oldbin" diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c --- a/src/http/modules/ngx_http_index_module.c +++ b/src/http/modules/ngx_http_index_module.c @@ -239,7 +239,8 @@ ngx_http_index_handler(ngx_http_request_ return NGX_HTTP_INTERNAL_SERVER_ERROR; } - fd = ngx_open_file(ctx->path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN); + fd = ngx_open_file(ctx->path.data, NGX_FILE_RDONLY|NGX_FILE_NOATIME, + NGX_FILE_OPEN); if (fd == (ngx_fd_t) NGX_AGAIN) { ctx->current = i; diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c --- a/src/http/modules/ngx_http_static_module.c +++ b/src/http/modules/ngx_http_static_module.c @@ -125,7 +125,8 @@ ngx_http_static_handler(ngx_http_request return NGX_HTTP_INTERNAL_SERVER_ERROR; } - fd = ngx_open_file(path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN); + fd = ngx_open_file(path.data, NGX_FILE_RDONLY|NGX_FILE_NOATIME, + NGX_FILE_OPEN); if (fd == NGX_INVALID_FILE) { err = ngx_errno; 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 @@ -17,7 +17,7 @@ time_t ngx_http_parse_time(u_char *value int day, month, year, hour, min, sec; enum { no = 0, - rfc822, /* Tue 10 Nov 2002 23:50:13 */ + rfc822, /* Tue, 10 Nov 2002 23:50:13 */ rfc850, /* Tuesday, 10-Dec-02 23:50:13 */ isoc /* Tue Dec 10 23:50:13 2002 */ } fmt; diff --git a/src/http/ngx_http_special_response.c-C b/src/http/ngx_http_special_response.c-C deleted file mode 100644 --- a/src/http/ngx_http_special_response.c-C +++ /dev/null @@ -1,548 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - */ - - -#include -#include -#include -#include - - -static u_char error_tail[] = -"
" NGINX_VER "
" CRLF -"" CRLF -"" CRLF -; - - -static u_char ngx_http_msie_stub[] = -"" CRLF -"" CRLF -"" CRLF -"" CRLF -"" CRLF -"" CRLF -; - - -static char error_301_page[] = -"" CRLF -"301 Moved Permanently" CRLF -"" CRLF -"

301 Moved Permanently

" CRLF -; - - -static char error_302_page[] = -"" CRLF -"302 Found" CRLF -"" CRLF -"

302 Found

" CRLF -; - - -static char error_400_page[] = -"" CRLF -"400 Bad Request" CRLF -"" CRLF -"

400 Bad Request

" CRLF -; - - -static char error_401_page[] = -"" CRLF -"401 Authorization Required" CRLF -"" CRLF -"

401 Authorization Required

" CRLF -; - - -static char error_402_page[] = -"" CRLF -"402 Payment Required" CRLF -"" CRLF -"

402 Payment Required

" CRLF -; - - -static char error_403_page[] = -"" CRLF -"403 Forbidden" CRLF -"" CRLF -"

403 Forbidden

" CRLF -; - - -static char error_404_page[] = -"" CRLF -"404 Not Found" CRLF -"" CRLF -"

404 Not Found

" CRLF -; - - -static char error_405_page[] = -"" CRLF -"405 Not Allowed" CRLF -"" CRLF -"

405 Not Allowed

" CRLF -; - - -static char error_406_page[] = -"" CRLF -"406 Not Acceptable" CRLF -"" CRLF -"

406 Not Acceptable

" CRLF -; - - -static char error_408_page[] = -"" CRLF -"408 Request Time-out" CRLF -"" CRLF -"

408 Request Time-out

" CRLF -; - - -static char error_409_page[] = -"" CRLF -"409 Conflict" CRLF -"" CRLF -"

409 Conflict

" CRLF -; - - -static char error_410_page[] = -"" CRLF -"410 Gone" CRLF -"" CRLF -"

410 Gone

" CRLF -; - - -static char error_411_page[] = -"" CRLF -"411 Length Required" CRLF -"" CRLF -"

411 Length Required

" CRLF -; - - -static char error_413_page[] = -"" CRLF -"413 Request Entity Too Large" CRLF -"" CRLF -"

413 Request Entity Too Large

" CRLF -; - - -static char error_414_page[] = -"" CRLF -"414 Request-URI Too Large" CRLF -"" CRLF -"

414 Request-URI Too Large

" CRLF -; - - -static char error_415_page[] = -"" CRLF -"415 Unsupported Media Type" CRLF -"" CRLF -"

415 Unsupported Media Type

" CRLF -; - - -static char error_416_page[] = -"" CRLF -"416 Requested Range Not Satisfiable" CRLF -"" CRLF -"

416 Requested Range Not Satisfiable

" CRLF -; - - -static char error_495_page[] = -"" CRLF -"400 The SSL certificate error" -CRLF -"" CRLF -"

400 Bad Request

" CRLF -"
The SSL certificate error
" CRLF -; - - -static char error_496_page[] = -"" CRLF -"400 No required SSL certificate was sent" -CRLF -"" CRLF -"

400 Bad Request

" CRLF -"
No required SSL certificate was sent
" CRLF -; - - -static char error_497_page[] = -"" CRLF -"400 The plain HTTP request was sent to HTTPS port" -CRLF -"" CRLF -"

400 Bad Request

" CRLF -"
The plain HTTP request was sent to HTTPS port
" CRLF -; - - -static char error_500_page[] = -"" CRLF -"500 Internal Server Error" CRLF -"" CRLF -"

500 Internal Server Error

" CRLF -; - - -static char error_501_page[] = -"" CRLF -"501 Method Not Implemented" CRLF -"" CRLF -"

501 Method Not Implemented

" CRLF -; - - -static char error_502_page[] = -"" CRLF -"502 Bad Gateway" CRLF -"" CRLF -"

502 Bad Gateway

" CRLF -; - - -static char error_503_page[] = -"" CRLF -"503 Service Temporarily Unavailable" CRLF -"" CRLF -"

503 Service Temporarily Unavailable

" CRLF -; - - -static char error_504_page[] = -"" CRLF -"504 Gateway Time-out" CRLF -"" CRLF -"

504 Gateway Time-out

" CRLF -; - - -static char error_507_page[] = -"" CRLF -"507 Insufficient Storage" CRLF -"" CRLF -"

507 Insufficient Storage

" CRLF -; - - -static ngx_str_t error_pages[] = { - - ngx_null_string, /* 201, 204 */ - -#define NGX_HTTP_LEVEL_200 1 - - /* ngx_null_string, */ /* 300 */ - ngx_string(error_301_page), - ngx_string(error_302_page), - ngx_null_string, /* 303 */ - -#define NGX_HTTP_LEVEL_300 3 - - ngx_string(error_400_page), - ngx_string(error_401_page), - ngx_string(error_402_page), - ngx_string(error_403_page), - ngx_string(error_404_page), - ngx_string(error_405_page), - ngx_string(error_406_page), - ngx_null_string, /* 407 */ - ngx_string(error_408_page), - ngx_string(error_409_page), - ngx_string(error_410_page), - ngx_string(error_411_page), - ngx_null_string, /* 412 */ - ngx_string(error_413_page), - ngx_string(error_414_page), - ngx_string(error_415_page), - ngx_string(error_416_page), - -#define NGX_HTTP_LEVEL_400 17 - - ngx_string(error_495_page), /* 495, https certificate error */ - ngx_string(error_496_page), /* 496, https no certificate */ - ngx_string(error_497_page), /* 497, http to https */ - ngx_string(error_404_page), /* 498, invalid host name */ - ngx_null_string, /* 499, client had closed connection */ - - ngx_string(error_500_page), - ngx_string(error_501_page), - ngx_string(error_502_page), - ngx_string(error_503_page), - ngx_string(error_504_page), - ngx_null_string, /* 505 */ - ngx_null_string, /* 506 */ - ngx_string(error_507_page) -}; - - -ngx_int_t -ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error) -{ - ngx_int_t rc; - ngx_buf_t *b; - ngx_str_t *uri; - ngx_uint_t i, n, err, msie_padding; - ngx_chain_t *out, *cl; - ngx_http_err_page_t *err_page; - ngx_http_core_loc_conf_t *clcf; - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http special response: %d, \"%V\"", error, &r->uri); - - rc = ngx_http_discard_body(r); - - if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { - error = NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - r->headers_out.status = error; - r->err_status = error; - - if (r->keepalive != 0) { - switch (error) { - case NGX_HTTP_BAD_REQUEST: - case NGX_HTTP_REQUEST_ENTITY_TOO_LARGE: - case NGX_HTTP_REQUEST_URI_TOO_LARGE: - case NGX_HTTP_TO_HTTPS: - case NGX_HTTPS_CERT_ERROR: - case NGX_HTTPS_NO_CERT: - case NGX_HTTP_INTERNAL_SERVER_ERROR: - r->keepalive = 0; - } - } - - if (r->lingering_close == 1) { - switch (error) { - case NGX_HTTP_BAD_REQUEST: - case NGX_HTTP_TO_HTTPS: - case NGX_HTTPS_CERT_ERROR: - case NGX_HTTPS_NO_CERT: - r->lingering_close = 0; - } - } - - r->headers_out.content_type.len = 0; - - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - - if (!r->error_page && clcf->error_pages) { - - if (clcf->recursive_error_pages == 0) { - r->error_page = 1; - } - - err_page = clcf->error_pages->elts; - - for (i = 0; i < clcf->error_pages->nelts; i++) { - - if (err_page[i].status == error) { - r->err_status = err_page[i].overwrite; - - r->method = NGX_HTTP_GET; - - uri = &err_page[i].uri; - - if (err_page[i].uri_lengths) { - if (ngx_http_script_run(r, uri, - err_page[i].uri_lengths->elts, 0, - err_page[i].uri_values->elts) - == NULL) - { - return NGX_ERROR; - } - - if (r->zero_in_uri) { - for (n = 0; n < uri->len; n++) { - if (uri->data[n] == '\0') { - goto zero; - } - } - - r->zero_in_uri = 0; - } - - } else { - r->zero_in_uri = 0; - } - - zero: - - if (uri->data[0] == '/') { - return ngx_http_internal_redirect(r, uri, NULL); - } - - r->headers_out.location = - ngx_list_push(&r->headers_out.headers); - - if (r->headers_out.location) { - error = NGX_HTTP_MOVED_TEMPORARILY; - - r->err_status = NGX_HTTP_MOVED_TEMPORARILY; - - r->headers_out.location->hash = 1; - r->headers_out.location->key.len = sizeof("Location") - 1; - r->headers_out.location->key.data = (u_char *) "Location"; - r->headers_out.location->value = *uri; - - } else { - return NGX_ERROR; - } - } - } - } - - if (error == NGX_HTTP_CREATED) { - /* 201 */ - err = 0; - r->header_only = 1; - - } else if (error == NGX_HTTP_NO_CONTENT) { - /* 204 */ - err = 0; - - } else if (error < NGX_HTTP_BAD_REQUEST) { - /* 3XX */ - err = error - NGX_HTTP_MOVED_PERMANENTLY + NGX_HTTP_LEVEL_200; - - } else if (error < NGX_HTTP_OWN_CODES) { - /* 4XX */ - err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_LEVEL_200 - + NGX_HTTP_LEVEL_300; - - } else { - /* 49X, 5XX */ - err = error - NGX_HTTP_OWN_CODES + NGX_HTTP_LEVEL_200 - + NGX_HTTP_LEVEL_300 - + NGX_HTTP_LEVEL_400; - switch (error) { - case NGX_HTTP_TO_HTTPS: - case NGX_HTTPS_CERT_ERROR: - case NGX_HTTPS_NO_CERT: - r->headers_out.status = NGX_HTTP_BAD_REQUEST; - error = NGX_HTTP_BAD_REQUEST; - break; - } - } - - msie_padding = 0; - - if (error_pages[err].len) { - r->headers_out.content_length_n = error_pages[err].len - + sizeof(error_tail) - 1; - - if (clcf->msie_padding - && r->headers_in.msie - && r->http_version >= NGX_HTTP_VERSION_10 - && error >= NGX_HTTP_BAD_REQUEST - && error != NGX_HTTP_REQUEST_URI_TOO_LARGE) - { - r->headers_out.content_length_n += sizeof(ngx_http_msie_stub) - 1; - msie_padding = 1; - } - - r->headers_out.content_type.len = sizeof("text/html") - 1; - r->headers_out.content_type.data = (u_char *) "text/html"; - - } else { - r->headers_out.content_length_n = -1; - } - - if (r->headers_out.content_length) { - r->headers_out.content_length->hash = 0; - r->headers_out.content_length = NULL; - } - - ngx_http_clear_accept_ranges(r); - ngx_http_clear_last_modified(r); - - rc = ngx_http_send_header(r); - - if (rc == NGX_ERROR || r->header_only) { - return rc; - } - - if (error_pages[err].len == 0) { - return NGX_OK; - } - - - b = ngx_calloc_buf(r->pool); - if (b == NULL) { - return NGX_ERROR; - } - - b->memory = 1; - b->pos = error_pages[err].data; - b->last = error_pages[err].data + error_pages[err].len; - - cl = ngx_alloc_chain_link(r->pool); - if (cl == NULL) { - return NGX_ERROR; - } - - cl->buf = b; - out = cl; - - - b = ngx_calloc_buf(r->pool); - if (b == NULL) { - return NGX_ERROR; - } - - b->memory = 1; - b->pos = error_tail; - b->last = error_tail + sizeof(error_tail) - 1; - - cl->next = ngx_alloc_chain_link(r->pool); - if (cl->next == NULL) { - return NGX_ERROR; - } - - cl = cl->next; - cl->buf = b; - - if (msie_padding) { - b = ngx_calloc_buf(r->pool); - if (b == NULL) { - return NGX_ERROR; - } - - b->memory = 1; - b->pos = ngx_http_msie_stub; - b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1; - - cl->next = ngx_alloc_chain_link(r->pool); - if (cl->next == NULL) { - return NGX_ERROR; - } - - cl = cl->next; - cl->buf = b; - } - - if (r == r->main) { - b->last_buf = 1; - } - - b->last_in_chain = 1; - - cl->next = NULL; - - return ngx_http_output_filter(r, out); -} diff --git a/src/http/ngx_http_special_response.c.rej b/src/http/ngx_http_special_response.c.rej deleted file mode 100644 --- a/src/http/ngx_http_special_response.c.rej +++ /dev/null @@ -1,23 +0,0 @@ -*************** -*** 294,302 **** - ngx_int_t - ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error) - { - ngx_int_t rc; - ngx_buf_t *b; -- ngx_str_t *uri; - ngx_uint_t i, err, msie_padding; - ngx_chain_t *out, *cl; - ngx_http_err_page_t *err_page; ---- 302,312 ---- - ngx_int_t - ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error) - { -+ u_char *p; -+ size_t msie_refresh; - ngx_int_t rc; - ngx_buf_t *b; -+ ngx_str_t *uri, *location; - ngx_uint_t i, err, msie_padding; - ngx_chain_t *out, *cl; - ngx_http_err_page_t *err_page; diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -28,6 +28,11 @@ #define NGX_FILE_TRUNCATE O_TRUNC #define NGX_FILE_APPEND O_APPEND +#ifdef O_NOATIME +#define NGX_FILE_NOATIME O_NOATIME +#else +#define NGX_FILE_NOATIME 0 +#endif #define ngx_close_file close #define ngx_close_file_n "close()" diff --git a/src/os/unix/ngx_linux_sendfile_chain.c b/src/os/unix/ngx_linux_sendfile_chain.c --- a/src/os/unix/ngx_linux_sendfile_chain.c +++ b/src/os/unix/ngx_linux_sendfile_chain.c @@ -16,9 +16,15 @@ * parameter is int32_t, and use sendfile() for the file parts below 2G only, * see src/os/unix/ngx_linux_config.h * - * Linux 2.4.21 has a new sendfile64() syscall #239. + * Linux 2.4.21 has the new sendfile64() syscall #239. + * + * On Linux up to 2.6.16 sendfile() does not allow to pass the count parameter + * more than 2G-1 bytes even on 64-bit platforms: it returns EINVAL, + * so we limit it to 2G-1 bytes. */ +#define NGX_SENDFILE_LIMIT 2147483647L + #if (IOV_MAX > 64) #define NGX_HEADERS 64 @@ -54,10 +60,10 @@ ngx_linux_sendfile_chain(ngx_connection_ } - /* the maximum limit size is the maximum size_t value - the page size */ + /* the maximum limit size is 2G-1 - the page size */ - if (limit == 0 || limit > NGX_MAX_SIZE_T_VALUE - ngx_pagesize) { - limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize; + if (limit == 0 || limit > NGX_SENDFILE_LIMIT - ngx_pagesize) { + limit = NGX_SENDFILE_LIMIT - ngx_pagesize; }