summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2008-11-27 15:35:25 +0000
committerJonathan Kolb <jon@b0g.us>2008-11-27 15:35:25 +0000
commita69b72e794e280467a80f6f0edf29d9924d1472f (patch)
treeb6e266bff2de61718306ab651147b0512b965f36
parent95268be18c7024d8c4b005a7fa623bd17f8ad219 (diff)
downloadnginx-a69b72e794e280467a80f6f0edf29d9924d1472f.tar.gz
Changes with nginx 0.6.34 27 Nov 2008v0.6.34
*) Change: now the EAGAIN error returned by connect() is not considered as temporary error. *) Change: now the "gzip_vary" directive turned on issues a "Vary: Accept-Encoding" header line for uncompressed responses too. *) Feature: the "expires" directive supports daily time. *) Feature: the "Expect" request header line support. *) Feature: now the "rewrite" directive does a redirect automatically if the "https://" protocol is used. *) Bugfix: the "listen" directive parameters such as "backlog", "rcvbuf", etc. were not set, if a default server was not the first one. *) Bugfix: the "log_not_found" directive did not work for index files tests. *) Bugfix: now if FastCGI server sends a "Location" header line without status line, then nginx uses 302 status code. Thanks to Maxim Dounin. *) Bugfix: the ngx_http_flv_module did not support several values in a query string. *) Bugfix: when a request to a directory was redirected with the slash added, nginx dropped a query string from the original request.
-rw-r--r--CHANGES33
-rw-r--r--CHANGES.ru34
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_times.c39
-rw-r--r--src/core/ngx_times.h3
-rw-r--r--src/event/ngx_event_connect.c17
-rw-r--r--src/http/modules/ngx_http_charset_filter_module.c6
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c7
-rw-r--r--src/http/modules/ngx_http_flv_module.c10
-rw-r--r--src/http/modules/ngx_http_gzip_filter_module.c26
-rw-r--r--src/http/modules/ngx_http_gzip_static_module.c13
-rw-r--r--src/http/modules/ngx_http_headers_filter_module.c39
-rw-r--r--src/http/modules/ngx_http_index_module.c17
-rw-r--r--src/http/modules/ngx_http_proxy_module.c1
-rw-r--r--src/http/modules/ngx_http_rewrite_module.c6
-rw-r--r--src/http/modules/ngx_http_static_module.c25
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http.c1
-rw-r--r--src/http/ngx_http_core_module.c50
-rw-r--r--src/http/ngx_http_header_filter_module.c13
-rw-r--r--src/http/ngx_http_request.c4
-rw-r--r--src/http/ngx_http_request.h2
-rw-r--r--src/http/ngx_http_upstream.c3
23 files changed, 290 insertions, 63 deletions
diff --git a/CHANGES b/CHANGES
index c982b00fe..b25cb7530 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,37 @@
+Changes with nginx 0.6.34 27 Nov 2008
+
+ *) Change: now the EAGAIN error returned by connect() is not considered
+ as temporary error.
+
+ *) Change: now the "gzip_vary" directive turned on issues a
+ "Vary: Accept-Encoding" header line for uncompressed responses too.
+
+ *) Feature: the "expires" directive supports daily time.
+
+ *) Feature: the "Expect" request header line support.
+
+ *) Feature: now the "rewrite" directive does a redirect automatically
+ if the "https://" protocol is used.
+
+ *) Bugfix: the "listen" directive parameters such as "backlog",
+ "rcvbuf", etc. were not set, if a default server was not the first
+ one.
+
+ *) Bugfix: the "log_not_found" directive did not work for index files
+ tests.
+
+ *) Bugfix: now if FastCGI server sends a "Location" header line without
+ status line, then nginx uses 302 status code.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: the ngx_http_flv_module did not support several values in a
+ query string.
+
+ *) Bugfix: when a request to a directory was redirected with the slash
+ added, nginx dropped a query string from the original request.
+
+
Changes with nginx 0.6.33 20 Nov 2008
*) Feature: now nginx returns the 405 status code for POST method
diff --git a/CHANGES.ru b/CHANGES.ru
index 226912e2b..df61cbe99 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,38 @@
+Изменения в nginx 0.6.34 27.11.2008
+
+ *) Изменение: теперь ошибка EAGAIN при вызове connect() не считается
+ временной.
+
+ *) Изменение: теперь директива "gzip_vary on" выдаёт строку
+ "Vary: Accept-Encoding" в заголовке ответа и для несжатых ответов.
+
+ *) Добавление: директива expires поддерживает суточное время.
+
+ *) Добавление: поддержка строки "Expect" в заголовке запроса.
+
+ *) Добавление: теперь при использовании протокола "https://" в
+ директиве rewrite автоматически делается редирект.
+
+ *) Исправление: параметры директивы listen, такие как backlog, rcvbuf и
+ прочие, не устанавливались, если сервером по умолчанию был не первый
+ сервер.
+
+ *) Исправление: директива log_not_found не работала при поиске
+ индексных файлов.
+
+ *) Исправление: теперь, если FastCGI-сервер присылает строку "Location"
+ в заголовке ответа без строки статуса, то nginx использует код
+ статуса 302.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: модуль ngx_http_flv_module не поддерживал несколько
+ значений в аргументах запроса.
+
+ *) Исправление: при редиректе запроса к каталогу с добавлением слэша
+ nginx не добавлял аргументы из оригинального запроса.
+
+
Изменения в nginx 0.6.33 20.11.2008
*) Добавление: теперь nginx возвращает код 405 для метода POST при
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 65a2a34dc..ca71514af 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.6.33"
+#define NGINX_VERSION "0.6.34"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c
index c1798b5bc..99b25813b 100644
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -291,3 +291,42 @@ ngx_gmtime(time_t t, ngx_tm_t *tp)
tp->ngx_tm_year = (ngx_tm_year_t) year;
tp->ngx_tm_wday = (ngx_tm_wday_t) wday;
}
+
+
+time_t
+ngx_next_time(time_t when)
+{
+ time_t now, next;
+ struct tm tm;
+
+ now = ngx_time();
+
+ ngx_libc_localtime(now, &tm);
+
+ tm.tm_hour = (int) (when / 3600);
+ when %= 3600;
+ tm.tm_min = (int) (when / 60);
+ tm.tm_sec = (int) (when % 60);
+
+ next = mktime(&tm);
+
+ if (next == -1) {
+ return -1;
+ }
+
+ if (next - now > 0) {
+ return next;
+ }
+
+ tm.tm_mday++;
+
+ /* mktime() should normalize a date (Jan 32, etc) */
+
+ next = mktime(&tm);
+
+ if (next != -1) {
+ return next;
+ }
+
+ return -1;
+}
diff --git a/src/core/ngx_times.h b/src/core/ngx_times.h
index 6e7ab638c..8363ca136 100644
--- a/src/core/ngx_times.h
+++ b/src/core/ngx_times.h
@@ -25,6 +25,9 @@ u_char *ngx_http_time(u_char *buf, time_t t);
u_char *ngx_http_cookie_time(u_char *buf, time_t t);
void ngx_gmtime(time_t t, ngx_tm_t *tp);
+time_t ngx_next_time(time_t when);
+#define ngx_next_time_n "mktime()"
+
extern volatile ngx_time_t *ngx_cached_time;
diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c
index 5ae7b23bf..b5e1a870e 100644
--- a/src/event/ngx_event_connect.c
+++ b/src/event/ngx_event_connect.c
@@ -139,11 +139,22 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
if (rc == -1) {
err = ngx_socket_errno;
- /* Winsock returns WSAEWOULDBLOCK (NGX_EAGAIN) */
-
- if (err != NGX_EINPROGRESS && err != NGX_EAGAIN) {
+ if (err != NGX_EINPROGRESS
+#if (NGX_WIN32)
+ /* Winsock returns WSAEWOULDBLOCK (NGX_EAGAIN) */
+ && err != NGX_EAGAIN
+#endif
+ )
+ {
if (err == NGX_ECONNREFUSED
+#if (NGX_LINUX)
+ /*
+ * Linux returns EAGAIN instead of ECONNREFUSED
+ * for unix sockets if listen queue is full
+ */
+ || err == NGX_EAGAIN
+#endif
|| err == NGX_ENETDOWN
|| err == NGX_ENETUNREACH
|| err == NGX_EHOSTDOWN
diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c
index 850e64e75..a5db2d878 100644
--- a/src/http/modules/ngx_http_charset_filter_module.c
+++ b/src/http/modules/ngx_http_charset_filter_module.c
@@ -204,6 +204,12 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
if (r == r->main) {
+ if (r->headers_out.content_encoding
+ && r->headers_out.content_encoding->value.len)
+ {
+ return ngx_http_next_header_filter(r);
+ }
+
if (r->headers_out.content_type.len == 0) {
return ngx_http_next_header_filter(r);
}
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 17e8a3dbf..b2522ae34 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -1189,6 +1189,13 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
u->headers_in.status_n = status;
u->headers_in.status_line = *status_line;
+ } else if (u->headers_in.location) {
+ u->headers_in.status_n = 302;
+ u->headers_in.status_line.len =
+ sizeof("302 Moved Temporarily") - 1;
+ u->headers_in.status_line.data =
+ (u_char *) "302 Moved Temporarily";
+
} else {
u->headers_in.status_n = 200;
u->headers_in.status_line.len = sizeof("200 OK") - 1;
diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c
index 0e190910c..07bf5beb5 100644
--- a/src/http/modules/ngx_http_flv_module.c
+++ b/src/http/modules/ngx_http_flv_module.c
@@ -60,7 +60,7 @@ ngx_module_t ngx_http_flv_module = {
static ngx_int_t
ngx_http_flv_handler(ngx_http_request_t *r)
{
- u_char *p, *last;
+ u_char *p, *n, *last;
off_t start, len;
size_t root;
ngx_int_t rc;
@@ -168,7 +168,13 @@ ngx_http_flv_handler(ngx_http_request_t *r)
if (p) {
p += 6;
- start = ngx_atoof(p, r->args.len - (p - r->args.data));
+ for (n = p; n < r->args.data + r->args.len; n++) {
+ if (*n == '&') {
+ break;
+ }
+ }
+
+ start = ngx_atoof(p, n - p);
if (start == NGX_ERROR || start >= len) {
start = 0;
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
index 1587c009d..799f7c339 100644
--- a/src/http/modules/ngx_http_gzip_filter_module.c
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
@@ -204,12 +204,11 @@ static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
static ngx_int_t
ngx_http_gzip_header_filter(ngx_http_request_t *r)
{
- ngx_str_t *type;
- ngx_uint_t i;
- ngx_table_elt_t *h;
- ngx_http_gzip_ctx_t *ctx;
- ngx_http_gzip_conf_t *conf;
- ngx_http_core_loc_conf_t *clcf;
+ ngx_str_t *type;
+ ngx_uint_t i;
+ ngx_table_elt_t *h;
+ ngx_http_gzip_ctx_t *ctx;
+ ngx_http_gzip_conf_t *conf;
conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
@@ -264,21 +263,6 @@ found:
r->headers_out.content_encoding = h;
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->gzip_vary) {
- h = ngx_list_push(&r->headers_out.headers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- h->hash = 1;
- h->key.len = sizeof("Vary") - 1;
- h->key.data = (u_char *) "Vary";
- h->value.len = sizeof("Accept-Encoding") - 1;
- h->value.data = (u_char *) "Accept-Encoding";
- }
-
ctx->length = r->headers_out.content_length_n;
r->main_filter_need_in_memory = 1;
diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c
index c37364910..e6d44ec7b 100644
--- a/src/http/modules/ngx_http_gzip_static_module.c
+++ b/src/http/modules/ngx_http_gzip_static_module.c
@@ -203,19 +203,6 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
r->headers_out.content_encoding = h;
- if (clcf->gzip_vary) {
- h = ngx_list_push(&r->headers_out.headers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- h->hash = 1;
- h->key.len = sizeof("Vary") - 1;
- h->key.data = (u_char *) "Vary";
- h->value.len = sizeof("Accept-Encoding") - 1;
- h->value.data = (u_char *) "Accept-Encoding";
- }
-
/* we need to allocate all before the header would be sent */
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c
index ad9467ba9..9adc04dd1 100644
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -36,6 +36,7 @@ struct ngx_http_header_val_s {
#define NGX_HTTP_EXPIRES_MAX 2
#define NGX_HTTP_EXPIRES_ACCESS 3
#define NGX_HTTP_EXPIRES_MODIFIED 4
+#define NGX_HTTP_EXPIRES_DAILY 5
typedef struct {
@@ -187,7 +188,7 @@ static ngx_int_t
ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
{
size_t len;
- time_t since;
+ time_t now, expires_time, max_age;
ngx_uint_t i;
ngx_table_elt_t *expires, *cc, **ccp;
@@ -279,16 +280,24 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
return NGX_OK;
}
+ now = ngx_time();
+
if (conf->expires == NGX_HTTP_EXPIRES_ACCESS
|| r->headers_out.last_modified_time == -1)
{
- since = ngx_time();
+ expires_time = now + conf->expires_time;
+ max_age = conf->expires_time;
+
+ } else if (conf->expires == NGX_HTTP_EXPIRES_DAILY) {
+ expires_time = ngx_next_time(conf->expires_time);
+ max_age = expires_time - now;
} else {
- since = r->headers_out.last_modified_time;
+ expires_time = r->headers_out.last_modified_time + conf->expires_time;
+ max_age = expires_time - now;
}
- ngx_http_time(expires->value.data, since + conf->expires_time);
+ ngx_http_time(expires->value.data, expires_time);
if (conf->expires_time < 0) {
cc->value.len = sizeof("no-cache") - 1;
@@ -303,8 +312,7 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
return NGX_ERROR;
}
- cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T",
- since + conf->expires_time - ngx_time())
+ cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T", max_age)
- cc->value.data;
return NGX_OK;
@@ -514,7 +522,18 @@ ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
n = 2;
}
- if (value[n].data[0] == '+') {
+ if (value[n].data[0] == '@') {
+ value[n].data++;
+ value[n].len--;
+ minus = 0;
+
+ if (hcf->expires == NGX_HTTP_EXPIRES_MODIFIED) {
+ return "daily time can not be used with \"modified\" parameter";
+ }
+
+ hcf->expires = NGX_HTTP_EXPIRES_DAILY;
+
+ } else if (value[n].data[0] == '+') {
value[n].data++;
value[n].len--;
minus = 0;
@@ -534,6 +553,12 @@ ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return "invalid value";
}
+ if (hcf->expires == NGX_HTTP_EXPIRES_DAILY
+ && hcf->expires_time > 24 * 60 * 60)
+ {
+ return "daily time value must be less than 24 hours";
+ }
+
if (hcf->expires_time == NGX_PARSE_LARGE_TIME) {
return "value must be less than 68 years";
}
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index 01e6cd59a..678664c3b 100644
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -27,8 +27,8 @@ typedef struct {
static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
ngx_http_core_loc_conf_t *clcf, u_char *path, u_char *last);
-static ngx_int_t ngx_http_index_error(ngx_http_request_t *r, u_char *file,
- ngx_err_t err);
+static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
+ ngx_http_core_loc_conf_t *clcf, u_char *file, ngx_err_t err);
static ngx_int_t ngx_http_index_init(ngx_conf_t *cf);
static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf);
@@ -225,7 +225,7 @@ ngx_http_index_handler(ngx_http_request_t *r)
}
if (of.err == NGX_ENOTDIR || of.err == NGX_EACCES) {
- return ngx_http_index_error(r, path.data, of.err);
+ return ngx_http_index_error(r, clcf, path.data, of.err);
}
if (!dir_tested) {
@@ -303,7 +303,7 @@ ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf,
if (of.err == NGX_ENOENT) {
*last = c;
- return ngx_http_index_error(r, dir.data, NGX_ENOENT);
+ return ngx_http_index_error(r, clcf, dir.data, NGX_ENOENT);
}
if (of.err == NGX_EACCES) {
@@ -340,7 +340,8 @@ ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf,
static ngx_int_t
-ngx_http_index_error(ngx_http_request_t *r, u_char *file, ngx_err_t err)
+ngx_http_index_error(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf,
+ u_char *file, ngx_err_t err)
{
if (err == NGX_EACCES) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
@@ -349,8 +350,10 @@ ngx_http_index_error(ngx_http_request_t *r, u_char *file, ngx_err_t err)
return NGX_HTTP_FORBIDDEN;
}
- ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
- "\"%s\" is not found", file);
+ if (clcf->log_not_found) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
+ "\"%s\" is not found", file);
+ }
return NGX_HTTP_NOT_FOUND;
}
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 1d8264801..f5c6ceeaf 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -424,6 +424,7 @@ static ngx_keyval_t ngx_http_proxy_headers[] = {
{ ngx_string("Host"), ngx_string("$proxy_host") },
{ ngx_string("Connection"), ngx_string("close") },
{ ngx_string("Keep-Alive"), ngx_string("") },
+ { ngx_string("Expect"), ngx_string("") },
{ ngx_null_string, ngx_null_string }
};
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index 341e05424..249b3201d 100644
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -357,6 +357,12 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
last = 1;
}
+ if (ngx_strncmp(value[2].data, "https://", sizeof("https://") - 1) == 0) {
+ regex->status = NGX_HTTP_MOVED_TEMPORARILY;
+ regex->redirect = 1;
+ last = 1;
+ }
+
if (cf->args->nelts == 4) {
if (ngx_strcmp(value[3].data, "last") == 0) {
last = 1;
diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c
index b8ad57336..68574fe72 100644
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -48,7 +48,7 @@ static ngx_int_t
ngx_http_static_handler(ngx_http_request_t *r)
{
u_char *last, *location;
- size_t root;
+ size_t root, len;
ngx_str_t path;
ngx_int_t rc;
ngx_uint_t level;
@@ -144,26 +144,39 @@ ngx_http_static_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- if (!clcf->alias && clcf->root_lengths == NULL) {
+ len = r->uri.len + 1;
+
+ if (!clcf->alias && clcf->root_lengths == NULL && r->args.len == 0) {
location = path.data + clcf->root.len;
+ *last = '/';
+
} else {
- location = ngx_palloc(r->pool, r->uri.len + 1);
+ if (r->args.len) {
+ len += r->args.len + 1;
+ }
+
+ location = ngx_palloc(r->pool, len);
if (location == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
last = ngx_copy(location, r->uri.data, r->uri.len);
- }
- *last = '/';
+ *last = '/';
+
+ if (r->args.len) {
+ *++last = '?';
+ ngx_memcpy(++last, r->args.data, r->args.len);
+ }
+ }
/*
* we do not need to set the r->headers_out.location->hash and
* r->headers_out.location->key fields
*/
- r->headers_out.location->value.len = r->uri.len + 1;
+ r->headers_out.location->value.len = len;
r->headers_out.location->value.data = location;
return NGX_HTTP_MOVED_PERMANENTLY;
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 67751ca97..d82b07bfb 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.6.33';
+our $VERSION = '0.6.34';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index 3ef1dcbc8..deb3636a4 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -558,6 +558,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
in_addr[a].core_srv_conf = cscfp[s];
in_addr[a].default_server = 1;
+ in_addr[a].listen_conf = &lscf[l].conf;
}
goto found;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index f9b11b930..b58137d25 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -30,6 +30,7 @@ typedef struct {
static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r,
ngx_array_t *locations, ngx_uint_t regex_start, size_t len);
+static ngx_int_t ngx_http_core_send_continue(ngx_http_request_t *r);
static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
@@ -785,7 +786,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
{
u_char *p;
size_t len;
- ngx_int_t rc;
+ ngx_int_t rc, expect;
ngx_http_core_loc_conf_t *clcf;
ngx_http_core_srv_conf_t *cscf;
@@ -832,6 +833,14 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
return NGX_OK;
}
+ if (r->headers_in.expect) {
+ expect = ngx_http_core_send_continue(r);
+
+ if (expect != NGX_OK) {
+ ngx_http_finalize_request(r, expect);
+ return NGX_OK;
+ }
+ }
if (rc == NGX_HTTP_LOCATION_AUTO_REDIRECT) {
r->headers_out.location = ngx_list_push(&r->headers_out.headers);
@@ -1252,6 +1261,45 @@ ngx_http_core_find_location(ngx_http_request_t *r,
}
+static ngx_int_t
+ngx_http_core_send_continue(ngx_http_request_t *r)
+{
+ ngx_int_t n;
+ ngx_str_t *expect;
+
+ if (r->expect_tested) {
+ return NGX_OK;
+ }
+
+ r->expect_tested = 1;
+
+ expect = &r->headers_in.expect->value;
+
+ if (expect->len != sizeof("100-continue") - 1
+ || ngx_strncasecmp(expect->data, (u_char *) "100-continue",
+ sizeof("100-continue") - 1)
+ != 0)
+ {
+ return NGX_OK;
+ }
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "send 100 Continue");
+
+ n = r->connection->send(r->connection,
+ (u_char *) "HTTP/1.1 100 Continue" CRLF CRLF,
+ sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1);
+
+ if (n == sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1) {
+ return NGX_OK;
+ }
+
+ /* we assume that such small packet should be send successfully */
+
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+}
+
+
ngx_int_t
ngx_http_set_content_type(ngx_http_request_t *r)
{
diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c
index b7f26f654..7714873e0 100644
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -347,6 +347,12 @@ ngx_http_header_filter(ngx_http_request_t *r)
len += sizeof("Connection: closed" CRLF) - 1;
}
+#if (NGX_HTTP_GZIP)
+ if (r->gzip && clcf->gzip_vary) {
+ len += sizeof("Vary: Accept-Encoding" CRLF) - 1;
+ }
+#endif
+
part = &r->headers_out.headers.part;
header = part->elts;
@@ -516,6 +522,13 @@ ngx_http_header_filter(ngx_http_request_t *r)
sizeof("Connection: close" CRLF) - 1);
}
+#if (NGX_HTTP_GZIP)
+ if (r->gzip && clcf->gzip_vary) {
+ b->last = ngx_cpymem(b->last, "Vary: Accept-Encoding" CRLF,
+ sizeof("Vary: Accept-Encoding" CRLF) - 1);
+ }
+#endif
+
part = &r->headers_out.headers.part;
header = part->elts;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index aa61c5e62..738c1fde9 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -109,6 +109,10 @@ ngx_http_header_t ngx_http_headers_in[] = {
offsetof(ngx_http_headers_in_t, transfer_encoding),
ngx_http_process_header_line },
+ { ngx_string("Expect"),
+ offsetof(ngx_http_headers_in_t, expect),
+ ngx_http_process_unique_header_line },
+
#if (NGX_HTTP_GZIP)
{ ngx_string("Accept-Encoding"),
offsetof(ngx_http_headers_in_t, accept_encoding),
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 2e7ff54b6..1a4eae106 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -171,6 +171,7 @@ typedef struct {
ngx_table_elt_t *if_range;
ngx_table_elt_t *transfer_encoding;
+ ngx_table_elt_t *expect;
#if (NGX_HTTP_GZIP)
ngx_table_elt_t *accept_encoding;
@@ -467,6 +468,7 @@ struct ngx_http_request_s {
unsigned request_complete:1;
unsigned request_output:1;
unsigned header_sent:1;
+ unsigned expect_tested:1;
unsigned done:1;
unsigned utf8:1;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index b18bf477f..3f77c03c4 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -137,7 +137,8 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
ngx_http_upstream_copy_header_line, 0, 0 },
{ ngx_string("Location"),
- ngx_http_upstream_ignore_header_line, 0,
+ ngx_http_upstream_process_header_line,
+ offsetof(ngx_http_upstream_headers_in_t, location),
ngx_http_upstream_rewrite_location, 0, 0 },
{ ngx_string("Refresh"),