summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES26
-rw-r--r--CHANGES.ru18
-rw-r--r--auto/sources2
-rw-r--r--src/core/nginx.c4
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_config.h2
-rw-r--r--src/core/ngx_core.h1
-rw-r--r--src/core/ngx_crc.h6
-rw-r--r--src/core/ngx_crc32.c128
-rw-r--r--src/core/ngx_crc32.h55
-rw-r--r--src/core/ngx_file.c6
-rw-r--r--src/core/ngx_string.c11
-rw-r--r--src/http/modules/ngx_http_charset_filter_module.c8
-rw-r--r--src/http/modules/ngx_http_flv_module.c4
-rw-r--r--src/http/modules/ngx_http_map_module.c5
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c8
-rw-r--r--src/http/modules/ngx_http_userid_filter_module.c8
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_parse.c2
-rw-r--r--src/http/ngx_http_upstream.c2
-rw-r--r--src/http/ngx_http_variables.c3
-rw-r--r--src/imap/ngx_imap.h60
-rw-r--r--src/imap/ngx_imap_auth_http_module.c57
-rw-r--r--src/imap/ngx_imap_core_module.c45
-rw-r--r--src/imap/ngx_imap_handler.c82
-rw-r--r--src/imap/ngx_imap_parse.c24
-rw-r--r--src/os/unix/ngx_posix_init.c2
27 files changed, 513 insertions, 60 deletions
diff --git a/CHANGES b/CHANGES
index 52be26026..997aad537 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,22 @@
+Changes with nginx 0.4.10 23 Oct 2006
+
+ *) Feature: the IMAP/POP3 proxy supports the APOP command.
+
+ *) Bugfix: if the select, poll or /dev/poll methods were used, then
+ while waiting authentication server response the IMAP/POP3 proxy
+ hogged CPU.
+
+ *) Bugfix: a segmentation fault might occur if the $server_addr
+ variable was used in the "map" directive.
+
+ *) Bugfix: the ngx_http_flv_module did not support the byte ranges for
+ full responses; bug appeared in 0.4.7.
+
+ *) Bugfix: nginx could not be built on Debian amd64; bug appeared in
+ 0.4.9.
+
+
Changes with nginx 0.4.9 13 Oct 2006
*) Feature: the "set" parameter in the "include" SSI command.
@@ -1576,7 +1594,7 @@ Changes with nginx 0.1.29 12 May 2005
Changes with nginx 0.1.28 08 Apr 2005
- *) Bugfix: nginx hogs CPU while proxing the huge files.
+ *) Bugfix: nginx hogs CPU while proxying the huge files.
*) Bugfix: nginx could not be built by gcc 4.0 on Linux.
@@ -1687,7 +1705,7 @@ Changes with nginx 0.1.23 01 Mar 2005
Changes with nginx 0.1.22 22 Feb 2005
*) Bugfix: the ngx_http_stub_status_module showed incorrect handled
- connections statistics if the proxing or FastCGI server were used.
+ connections statistics if the proxying or FastCGI server were used.
*) Bugfix: the installation paths were incorrectly quoted on Linux and
Solaris; bug appeared in 0.1.21.
@@ -2051,7 +2069,7 @@ Changes with nginx 0.1.1 11 Oct 2004
*) Feature: the setproctitle() emulation for Linux and Solaris.
- *) Bugfix: the "Location" header rewrite bug fixed while the proxing.
+ *) Bugfix: the "Location" header rewrite bug fixed while the proxying.
*) Bugfix: the ngx_http_chunked_module module may get caught in an
endless loop.
@@ -2059,7 +2077,7 @@ Changes with nginx 0.1.1 11 Oct 2004
*) Bugfix: the /dev/poll module bugs fixed.
*) Bugfix: the responses were corrupted when the temporary files were
- used while the proxing.
+ used while the proxying.
*) Bugfix: the unescaped requests were passed to the backend.
diff --git a/CHANGES.ru b/CHANGES.ru
index a58f85315..598db7a78 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,22 @@
+Изменения в nginx 0.4.10 23.10.2006
+
+ *) Добавление: IMAP/POP3 прокси поддерживает APOP.
+
+ *) Исправление: при использовании методов select, poll и /dev/poll во
+ время ожидания ответа от сервера аутентификации IMAP/POP3 прокси
+ нагружал процессор.
+
+ *) Исправление: при использовании переменной $server_addr в директиве
+ map мог произойти segmentation fault.
+
+ *) Исправление: модуль ngx_http_flv_module не поддерживал byte ranges
+ для полных ответов; ошибка появилась в 0.4.7.
+
+ *) Исправление: nginx не собирался на Debian amd64; ошибка появилась в
+ 0.4.9.
+
+
Изменения в nginx 0.4.9 13.10.2006
*) Добавление: параметр set в команде SSI include.
diff --git a/auto/sources b/auto/sources
index 5af4dce38..c031ef8e1 100644
--- a/auto/sources
+++ b/auto/sources
@@ -20,6 +20,7 @@ CORE_DEPS="src/core/nginx.h \
src/core/ngx_inet.h \
src/core/ngx_file.h \
src/core/ngx_crc.h \
+ src/core/ngx_crc32.h \
src/core/ngx_rbtree.h \
src/core/ngx_radix_tree.h \
src/core/ngx_times.h \
@@ -42,6 +43,7 @@ CORE_SRCS="src/core/nginx.c \
src/core/ngx_parse.c \
src/core/ngx_inet.c \
src/core/ngx_file.c \
+ src/core/ngx_crc32.c \
src/core/ngx_rbtree.c \
src/core/ngx_radix_tree.c \
src/core/ngx_times.c \
diff --git a/src/core/nginx.c b/src/core/nginx.c
index 22a4d290b..a3f9ce3d8 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -283,6 +283,10 @@ main(int argc, char *const *argv)
ngx_os_status(cycle->log);
+ if (ngx_crc32_init(cycle->pool) != NGX_OK) {
+ return 1;
+ }
+
ngx_cycle = cycle;
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
diff --git a/src/core/nginx.h b/src/core/nginx.h
index f761a7925..e8d79cb87 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.4.9"
+#define NGINX_VERSION "0.4.10"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h
index 6078d89c7..ef31be538 100644
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -49,6 +49,8 @@
#define ngx_signal_helper(n) SIG##n
#define ngx_signal_value(n) ngx_signal_helper(n)
+#define ngx_random random
+
/* TODO: #ifndef */
#define NGX_SHUTDOWN_SIGNAL QUIT
#define NGX_TERMINATE_SIGNAL TERM
diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h
index cd066af35..0a82d8b2a 100644
--- a/src/core/ngx_core.h
+++ b/src/core/ngx_core.h
@@ -57,6 +57,7 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
#include <ngx_file.h>
#include <ngx_files.h>
#include <ngx_crc.h>
+#include <ngx_crc32.h>
#if (NGX_PCRE)
#include <ngx_regex.h>
#endif
diff --git a/src/core/ngx_crc.h b/src/core/ngx_crc.h
index b2aff8966..c77f037ab 100644
--- a/src/core/ngx_crc.h
+++ b/src/core/ngx_crc.h
@@ -8,10 +8,14 @@
#define _NGX_CRC_H_INCLUDED_
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
/* 32-bit crc16 */
static ngx_inline uint32_t
-ngx_crc(char *data, size_t len)
+ngx_crc(u_char *data, size_t len)
{
uint32_t sum;
diff --git a/src/core/ngx_crc32.c b/src/core/ngx_crc32.c
new file mode 100644
index 000000000..ac375b06f
--- /dev/null
+++ b/src/core/ngx_crc32.c
@@ -0,0 +1,128 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+/*
+ * The code and lookup tables are based on the algorithm
+ * described at http://www.w3.org/TR/PNG/
+ *
+ * The 256 element lookup table takes 1024 bytes, and it may be completely
+ * cached after processing about 30-60 bytes. So for short messages
+ * we use the 16 element lookup table that takes only 64 bytes and align it
+ * to CPU cache line size. Of course, the small table adds code inside
+ * CRC32 cycle, but cache misses overhead is bigger than overhead of
+ * the additional code. For example, ngx_crc32_short() of 16 byte message
+ * takes half as much CPU clocks than ngx_crc32_long().
+ */
+
+
+static uint32_t ngx_crc32_table16[] = {
+ 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
+ 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
+ 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
+ 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
+};
+
+
+uint32_t ngx_crc32_table256[] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+
+uint32_t *ngx_crc32_table_short = ngx_crc32_table16;
+
+
+ngx_int_t
+ngx_crc32_init(ngx_pool_t *pool)
+{
+ void *p;
+
+ if (((uintptr_t) ngx_crc32_table_short
+ & ~((uintptr_t) ngx_cacheline_size - 1))
+ == (uintptr_t) ngx_crc32_table_short)
+ {
+ return NGX_OK;
+ }
+
+ p = ngx_palloc(pool, 16 * sizeof(uint32_t) + ngx_cacheline_size);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ p = ngx_align_ptr(p, ngx_cacheline_size);
+
+ ngx_memcpy(p, ngx_crc32_table16, 16 * sizeof(uint32_t));
+
+ ngx_crc32_table_short = p;
+
+ return NGX_OK;
+}
diff --git a/src/core/ngx_crc32.h b/src/core/ngx_crc32.h
new file mode 100644
index 000000000..7c1827933
--- /dev/null
+++ b/src/core/ngx_crc32.h
@@ -0,0 +1,55 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#ifndef _NGX_CRC32_H_INCLUDED_
+#define _NGX_CRC32_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+extern uint32_t *ngx_crc32_table_short;
+extern uint32_t ngx_crc32_table256[];
+
+
+static ngx_inline uint32_t
+ngx_crc32_short(u_char *p, size_t len)
+{
+ u_char c;
+ uint32_t crc;
+
+ crc = 0xffffffff;
+
+ while (len--) {
+ c = *p++;
+ crc = ngx_crc32_table_short[(crc ^ (c & 0xf)) & 0xf] ^ (crc >> 4);
+ crc = ngx_crc32_table_short[(crc ^ (c >> 4)) & 0xf] ^ (crc >> 4);
+ }
+
+ return crc ^ 0xffffffff;
+}
+
+
+static ngx_inline uint32_t
+ngx_crc32_long(u_char *p, size_t len)
+{
+ uint32_t crc;
+
+ crc = 0xffffffff;
+
+ while (len--) {
+ crc = ngx_crc32_table256[(crc ^ *p++) & 0xff] ^ (crc >> 8);
+ }
+
+ return crc ^ 0xffffffff;
+}
+
+
+ngx_int_t ngx_crc32_init(ngx_pool_t *pool);
+
+
+#endif /* _NGX_CRC32_H_INCLUDED_ */
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
index f6bf04b03..e74c1aeab 100644
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -9,7 +9,7 @@
static ngx_atomic_uint_t ngx_temp_number;
-static ngx_atomic_uint_t ngx_random;
+static ngx_atomic_uint_t ngx_random_number;
ssize_t
@@ -216,7 +216,7 @@ void
ngx_init_temp_number(void)
{
ngx_temp_number = 0;
- ngx_random = 123456;
+ ngx_random_number = 123456;
}
@@ -224,7 +224,7 @@ ngx_atomic_uint_t
ngx_next_temp_number(ngx_uint_t collision)
{
if (collision) {
- ngx_temp_number += ngx_random;
+ ngx_temp_number += ngx_random_number;
}
return ngx_temp_number++;
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 3716df661..886fe00c6 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -593,7 +593,7 @@ ngx_atotm(u_char *line, size_t n)
ngx_int_t
ngx_hextoi(u_char *line, size_t n)
{
- u_char ch;
+ u_char c, ch;
ngx_int_t value;
if (n == 0) {
@@ -608,13 +608,10 @@ ngx_hextoi(u_char *line, size_t n)
continue;
}
- if (ch >= 'A' && ch <= 'F') {
- value = value * 16 + (ch - 'A' + 10);
- continue;
- }
+ c = (u_char) (ch | 0x20);
- if (ch >= 'a' && ch <= 'f') {
- value = value * 16 + (ch - 'a' + 10);
+ if (c >= 'a' && c <= 'f') {
+ value = value * 16 + (c - 'a' + 10);
continue;
}
diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c
index b9c9ade91..cae9bbe53 100644
--- a/src/http/modules/ngx_http_charset_filter_module.c
+++ b/src/http/modules/ngx_http_charset_filter_module.c
@@ -250,6 +250,10 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
vv = ngx_http_get_indexed_variable(r,
charset - NGX_HTTP_CHARSET_VAR);
+ if (vv == NULL || vv->not_found) {
+ return NGX_ERROR;
+ }
+
charset = ngx_http_charset_get_charset(charsets, n,
(ngx_str_t *) vv);
}
@@ -293,6 +297,10 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
vv = ngx_http_get_indexed_variable(r,
source_charset - NGX_HTTP_CHARSET_VAR);
+ if (vv == NULL || vv->not_found) {
+ return NGX_ERROR;
+ }
+
source_charset = ngx_http_charset_get_charset(charsets, n,
(ngx_str_t *) vv);
}
diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c
index 6030b7ba0..2b2b932c9 100644
--- a/src/http/modules/ngx_http_flv_module.c
+++ b/src/http/modules/ngx_http_flv_module.c
@@ -214,8 +214,12 @@ ngx_http_flv_handler(ngx_http_request_t *r)
out[0].buf = b;
out[0].next = &out[1];
+
+ } else {
+ r->allow_ranges = 1;
}
+
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
if (b == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
diff --git a/src/http/modules/ngx_http_map_module.c b/src/http/modules/ngx_http_map_module.c
index 0a533c0f5..fb8e8ee60 100644
--- a/src/http/modules/ngx_http_map_module.c
+++ b/src/http/modules/ngx_http_map_module.c
@@ -115,6 +115,11 @@ ngx_http_map_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
vv = ngx_http_get_flushed_variable(r, map->index);
+ if (vv == NULL || vv->not_found) {
+ *v = *map->default_value;
+ return NGX_OK;
+ }
+
len = vv->len;
if (len && map->hostnames && vv->data[len - 1] == '.') {
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index 945a4e5e5..dc0249867 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -1554,7 +1554,7 @@ ngx_http_ssi_get_variable(ngx_http_request_t *r, ngx_str_t *name,
if (part->next == NULL) {
break;
}
-
+
part = part->next;
var = part->elts;
i = 0;
@@ -1843,7 +1843,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
ngx_str_t *uri, *file, *wait, *set, *stub, args;
ngx_buf_t *b;
ngx_uint_t flags, i;
- ngx_chain_t *cl, *tl, **ll;
+ ngx_chain_t *cl, *tl, **ll, *out;
ngx_http_request_t *sr;
ngx_http_ssi_var_t *var;
ngx_http_ssi_ctx_t *mctx;
@@ -1947,7 +1947,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
if (bl[i].count++) {
- ll = (ngx_chain_t **) &psr->data;
+ ll = &out;
for (tl = bl[i].bufs; tl; tl = tl->next) {
@@ -1979,6 +1979,8 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
ll = &cl->next;
}
+ psr->data = out;
+
} else {
psr->data = bl[i].bufs;
}
diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c
index c341a0873..b316630eb 100644
--- a/src/http/modules/ngx_http_userid_filter_module.c
+++ b/src/http/modules/ngx_http_userid_filter_module.c
@@ -348,10 +348,12 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
if (r->in_addr == 0) {
slen = sizeof(struct sockaddr_in);
if (getsockname(r->connection->fd,
- (struct sockaddr *) &sin, &slen) == -1)
+ (struct sockaddr *) &sin, &slen)
+ == -1)
{
- ngx_log_error(NGX_LOG_CRIT, r->connection->log,
- ngx_socket_errno, "getsockname() failed");
+ ngx_connection_error(r->connection, ngx_socket_errno,
+ "getsockname() failed");
+ return NGX_ERROR;
}
r->in_addr = sin.sin_addr.s_addr;
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 2ab9820f4..b6189c6eb 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -17,7 +17,7 @@ our @EXPORT = qw(
HTTP_SERVER_ERROR
);
-our $VERSION = '0.4.9';
+our $VERSION = '0.4.10';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index 6017414f3..bbda9ecd8 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -537,6 +537,8 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
sw_header_almost_done
} state;
+ /* the last '\0' is not needed because string is zero terminated */
+
static u_char lowcase[] =
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0-\0\0" "0123456789\0\0\0\0\0\0"
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index dc70091de..b86f70128 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1167,7 +1167,7 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
if (hh && hh->redirect) {
if (hh->copy_handler(r, &h[i], hh->conf) != NGX_OK) {
- ngx_http_finalize_request(r,
+ ngx_http_finalize_request(r,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index ecf20c372..120145829 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -749,8 +749,7 @@ ngx_http_variable_server_addr(ngx_http_request_t *r,
if (r->in_addr == 0) {
len = sizeof(struct sockaddr_in);
if (getsockname(c->fd, (struct sockaddr *) &sin, &len) == -1) {
- ngx_log_error(NGX_LOG_CRIT, c->log,
- ngx_socket_errno, "getsockname() failed");
+ ngx_connection_error(c, ngx_socket_errno, "getsockname() failed");
return NGX_ERROR;
}
diff --git a/src/imap/ngx_imap.h b/src/imap/ngx_imap.h
index a55ad8cbc..2c24b5cf0 100644
--- a/src/imap/ngx_imap.h
+++ b/src/imap/ngx_imap.h
@@ -87,6 +87,10 @@ typedef struct {
ngx_str_t imap_starttls_capability;
ngx_str_t imap_starttls_only_capability;
+ ngx_str_t server_name;
+
+ ngx_uint_t auth_methods;
+
ngx_array_t pop3_capabilities;
ngx_array_t imap_capabilities;
@@ -149,10 +153,12 @@ typedef struct {
unsigned backslash:1;
unsigned no_sync_literal:1;
unsigned starttls:1;
+ unsigned auth_method:1;
ngx_str_t login;
ngx_str_t passwd;
+ ngx_str_t salt;
ngx_str_t tag;
ngx_str_t tagged_line;
@@ -179,29 +185,37 @@ typedef struct {
} ngx_imap_log_ctx_t;
-#define NGX_POP3_USER 1
-#define NGX_POP3_PASS 2
-#define NGX_POP3_CAPA 3
-#define NGX_POP3_QUIT 4
-#define NGX_POP3_NOOP 5
-#define NGX_POP3_STLS 6
-#define NGX_POP3_APOP 7
-#define NGX_POP3_STAT 8
-#define NGX_POP3_LIST 9
-#define NGX_POP3_RETR 10
-#define NGX_POP3_DELE 11
-#define NGX_POP3_RSET 12
-#define NGX_POP3_TOP 13
-#define NGX_POP3_UIDL 14
-
-
-#define NGX_IMAP_LOGIN 1
-#define NGX_IMAP_LOGOUT 2
-#define NGX_IMAP_CAPABILITY 3
-#define NGX_IMAP_NOOP 4
-#define NGX_IMAP_STARTTLS 5
-
-#define NGX_IMAP_NEXT 6
+#define NGX_POP3_USER 1
+#define NGX_POP3_PASS 2
+#define NGX_POP3_CAPA 3
+#define NGX_POP3_QUIT 4
+#define NGX_POP3_NOOP 5
+#define NGX_POP3_STLS 6
+#define NGX_POP3_APOP 7
+#define NGX_POP3_STAT 8
+#define NGX_POP3_LIST 9
+#define NGX_POP3_RETR 10
+#define NGX_POP3_DELE 11
+#define NGX_POP3_RSET 12
+#define NGX_POP3_TOP 13
+#define NGX_POP3_UIDL 14
+
+
+#define NGX_IMAP_LOGIN 1
+#define NGX_IMAP_LOGOUT 2
+#define NGX_IMAP_CAPABILITY 3
+#define NGX_IMAP_NOOP 4
+#define NGX_IMAP_STARTTLS 5
+
+#define NGX_IMAP_NEXT 6
+
+
+#define NGX_IMAP_AUTH_PLAIN 0
+#define NGX_IMAP_AUTH_APOP 1
+
+
+#define NGX_IMAP_AUTH_PLAIN_ENABLED 0x0002
+#define NGX_IMAP_AUTH_APOP_ENABLED 0x0004
#define NGX_IMAP_PARSE_INVALID_COMMAND 20
diff --git a/src/imap/ngx_imap_auth_http_module.c b/src/imap/ngx_imap_auth_http_module.c
index 8dbbb72b2..fd9bb5352 100644
--- a/src/imap/ngx_imap_auth_http_module.c
+++ b/src/imap/ngx_imap_auth_http_module.c
@@ -131,7 +131,10 @@ ngx_module_t ngx_imap_auth_http_module = {
};
-static char *ngx_imap_auth_http_protocol[] = { "pop3", "imap" };
+static char *ngx_imap_auth_http_protocol[] = { "pop3", "imap" };
+static ngx_str_t ngx_imap_auth_http_method[] = {
+ ngx_string("plain"), ngx_string("apop")
+};
void
@@ -250,6 +253,12 @@ ngx_imap_auth_http_write_handler(ngx_event_t *wev)
ngx_del_timer(wev);
}
+ if (ngx_handle_write_event(wev, 0) == NGX_ERROR) {
+ ngx_close_connection(ctx->peer.connection);
+ ngx_destroy_pool(ctx->pool);
+ ngx_imap_session_internal_server_error(s);
+ }
+
return;
}
}
@@ -552,6 +561,25 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
continue;
}
+ if (len == sizeof("Auth-Pass") - 1
+ && ngx_strncasecmp(ctx->header_name_start, "Auth-Pass",
+ sizeof("Auth-Pass") - 1) == 0)
+ {
+ s->passwd.len = ctx->header_end - ctx->header_start;
+
+ s->passwd.data = ngx_palloc(s->connection->pool, s->passwd.len);
+ if (s->passwd.data == NULL) {
+ ngx_close_connection(ctx->peer.connection);
+ ngx_destroy_pool(ctx->pool);
+ ngx_imap_session_internal_server_error(s);
+ return;
+ }
+
+ ngx_memcpy(s->passwd.data, ctx->header_start, s->passwd.len);
+
+ continue;
+ }
+
if (len == sizeof("Auth-Wait") - 1
&& ngx_strncasecmp(ctx->header_name_start, "Auth-Wait",
sizeof("Auth-Wait") - 1) == 0)
@@ -608,6 +636,15 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
return;
}
+ if (s->passwd.data == NULL) {
+ ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
+ "auth http server %V did not send password",
+ &ctx->peer.peers->peer[0].name);
+ ngx_destroy_pool(ctx->pool);
+ ngx_imap_session_internal_server_error(s);
+ return;
+ }
+
peers = ngx_pcalloc(s->connection->pool, sizeof(ngx_peers_t));
if (peers == NULL) {
ngx_destroy_pool(ctx->pool);
@@ -725,6 +762,8 @@ ngx_imap_auth_sleep_handler(ngx_event_t *rev)
s->connection->read->handler = ngx_imap_auth_state;
}
+ s->auth_method = NGX_IMAP_AUTH_PLAIN;
+
c->log->action = "in auth state";
ngx_imap_send(s->connection->write);
@@ -1001,6 +1040,7 @@ ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool,
+ sizeof("Auth-Method: plain" CRLF) - 1
+ sizeof("Auth-User: ") - 1 + login.len + sizeof(CRLF) - 1
+ sizeof("Auth-Pass: ") - 1 + passwd.len + sizeof(CRLF) - 1
+ + sizeof("Auth-Salt: ") - 1 + s->salt.len
+ sizeof("Auth-Protocol: imap" CRLF) - 1
+ sizeof("Auth-Login-Attempt: ") - 1 + NGX_INT_T_LEN
+ sizeof(CRLF) - 1
@@ -1023,8 +1063,12 @@ ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool,
ahcf->host_header.len);
*b->last++ = CR; *b->last++ = LF;
- b->last = ngx_cpymem(b->last, "Auth-Method: plain" CRLF,
- sizeof("Auth-Method: plain" CRLF) - 1);
+ b->last = ngx_cpymem(b->last, "Auth-Method: ",
+ sizeof("Auth-Method: ") - 1);
+ b->last = ngx_cpymem(b->last,
+ ngx_imap_auth_http_method[s->auth_method].data,
+ ngx_imap_auth_http_method[s->auth_method].len);
+ *b->last++ = CR; *b->last++ = LF;
b->last = ngx_cpymem(b->last, "Auth-User: ", sizeof("Auth-User: ") - 1);
b->last = ngx_copy(b->last, login.data, login.len);
@@ -1034,6 +1078,13 @@ ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool,
b->last = ngx_copy(b->last, passwd.data, passwd.len);
*b->last++ = CR; *b->last++ = LF;
+ if (s->salt.len) {
+ b->last = ngx_cpymem(b->last, "Auth-Salt: ", sizeof("Auth-Salt: ") - 1);
+ b->last = ngx_copy(b->last, s->salt.data, s->salt.len);
+
+ s->passwd.data = NULL;
+ }
+
b->last = ngx_cpymem(b->last, "Auth-Protocol: ",
sizeof("Auth-Protocol: ") - 1);
b->last = ngx_cpymem(b->last, ngx_imap_auth_http_protocol[s->protocol],
diff --git a/src/imap/ngx_imap_core_module.c b/src/imap/ngx_imap_core_module.c
index af50ad6cc..3ae370a5d 100644
--- a/src/imap/ngx_imap_core_module.c
+++ b/src/imap/ngx_imap_core_module.c
@@ -45,6 +45,13 @@ static ngx_str_t ngx_imap_default_capabilities[] = {
};
+static ngx_conf_bitmask_t ngx_imap_auth_methods[] = {
+ { ngx_string("plain"), NGX_IMAP_AUTH_PLAIN_ENABLED },
+ { ngx_string("apop"), NGX_IMAP_AUTH_APOP_ENABLED },
+ { ngx_null_string, 0 }
+};
+
+
static ngx_command_t ngx_imap_core_commands[] = {
{ ngx_string("server"),
@@ -103,6 +110,20 @@ static ngx_command_t ngx_imap_core_commands[] = {
offsetof(ngx_imap_core_srv_conf_t, imap_capabilities),
NULL },
+ { ngx_string("server_name"),
+ NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+ NGX_IMAP_SRV_CONF_OFFSET,
+ offsetof(ngx_imap_core_srv_conf_t, server_name),
+ NULL },
+
+ { ngx_string("auth"),
+ NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_1MORE,
+ ngx_conf_set_bitmask_slot,
+ NGX_IMAP_SRV_CONF_OFFSET,
+ offsetof(ngx_imap_core_srv_conf_t, auth_methods),
+ &ngx_imap_auth_methods },
+
ngx_null_command
};
@@ -210,6 +231,30 @@ ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0);
+ ngx_conf_merge_bitmask_value(conf->auth_methods, prev->auth_methods,
+ (NGX_CONF_BITMASK_SET|NGX_IMAP_AUTH_PLAIN_ENABLED));
+
+
+ ngx_conf_merge_str_value(conf->server_name, prev->server_name, "");
+
+ if (conf->server_name.len == 0) {
+ conf->server_name.data = ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN);
+ if (conf->server_name.data == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN)
+ == -1)
+ {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
+ "gethostname() failed");
+ return NGX_CONF_ERROR;
+ }
+
+ conf->server_name.len = ngx_strlen(conf->server_name.data);
+ }
+
+
if (conf->pop3_capabilities.nelts == 0) {
conf->pop3_capabilities = prev->pop3_capabilities;
}
diff --git a/src/imap/ngx_imap_handler.c b/src/imap/ngx_imap_handler.c
index 4a4c2c7cd..bb92b36df 100644
--- a/src/imap/ngx_imap_handler.c
+++ b/src/imap/ngx_imap_handler.c
@@ -233,6 +233,7 @@ ngx_imap_ssl_handshake_handler(ngx_connection_t *c)
static void
ngx_imap_init_session(ngx_connection_t *c)
{
+ u_char *p;
ngx_imap_session_t *s;
ngx_imap_core_srv_conf_t *cscf;
@@ -253,6 +254,35 @@ ngx_imap_init_session(ngx_connection_t *c)
s->out = greetings[s->protocol];
+ if ((cscf->auth_methods & NGX_IMAP_AUTH_APOP_ENABLED)
+ && s->protocol == NGX_IMAP_POP3_PROTOCOL)
+ {
+ s->salt.data = ngx_palloc(c->pool,
+ sizeof(" <18446744073709551616.@>" CRLF) - 1
+ + NGX_TIME_T_LEN
+ + cscf->server_name.len);
+ if (s->salt.data == NULL) {
+ ngx_imap_session_internal_server_error(s);
+ return;
+ }
+
+ s->salt.len = ngx_sprintf(s->salt.data, "<%ul.%T@%V>" CRLF,
+ ngx_random(), ngx_time(), &cscf->server_name)
+ - s->salt.data;
+
+ s->out.data = ngx_palloc(c->pool, greetings[0].len + 1 + s->salt.len);
+ if (s->out.data == NULL) {
+ ngx_imap_session_internal_server_error(s);
+ return;
+ }
+
+ p = ngx_cpymem(s->out.data, greetings[0].data, greetings[0].len - 2);
+ *p++ = ' ';
+ p = ngx_cpymem(p, s->salt.data, s->salt.len);
+
+ s->out.len = p - s->out.data;
+ }
+
ngx_add_timer(c->read, cscf->timeout);
if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
@@ -726,6 +756,56 @@ ngx_pop3_auth_state(ngx_event_t *rev)
text = cscf->pop3_capability.data;
break;
+ case NGX_POP3_APOP:
+ cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module);
+
+ if ((cscf->auth_methods & NGX_IMAP_AUTH_APOP_ENABLED)
+ && s->args.nelts == 2)
+ {
+ arg = s->args.elts;
+
+ s->login.len = arg[0].len;
+ s->login.data = ngx_palloc(c->pool, s->login.len);
+ if (s->login.data == NULL) {
+ ngx_imap_session_internal_server_error(s);
+ return;
+ }
+
+ ngx_memcpy(s->login.data, arg[0].data, s->login.len);
+
+ s->passwd.len = arg[1].len;
+ s->passwd.data = ngx_palloc(c->pool, s->passwd.len);
+ if (s->passwd.data == NULL) {
+ ngx_imap_session_internal_server_error(s);
+ return;
+ }
+
+ ngx_memcpy(s->passwd.data, arg[1].data, s->passwd.len);
+
+ ngx_log_debug2(NGX_LOG_DEBUG_IMAP, c->log, 0,
+ "pop3 apop: \"%V\" \"%V\"",
+ &s->login, &s->passwd);
+
+ s->auth_method = NGX_IMAP_AUTH_APOP;
+
+ s->args.nelts = 0;
+ s->buffer->pos = s->buffer->start;
+ s->buffer->last = s->buffer->start;
+
+ if (rev->timer_set) {
+ ngx_del_timer(rev);
+ }
+
+ ngx_imap_auth_http_init(s);
+
+ return;
+
+ } else {
+ rc = NGX_IMAP_PARSE_INVALID_COMMAND;
+ }
+
+ break;
+
case NGX_POP3_QUIT:
s->quit = 1;
break;
@@ -763,8 +843,6 @@ ngx_pop3_auth_state(ngx_event_t *rev)
case NGX_POP3_PASS:
if (s->args.nelts == 1) {
- /* STUB */ s->imap_state = ngx_pop3_start;
-
arg = s->args.elts;
s->passwd.len = arg[0].len;
s->passwd.data = ngx_palloc(c->pool, s->passwd.len);
diff --git a/src/imap/ngx_imap_parse.c b/src/imap/ngx_imap_parse.c
index eea4550a8..6256cc863 100644
--- a/src/imap/ngx_imap_parse.c
+++ b/src/imap/ngx_imap_parse.c
@@ -429,6 +429,10 @@ ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s)
{
s->command = NGX_POP3_PASS;
+ } else if (c0 == 'A' && c1 == 'P' && c2 == 'O' && c3 == 'P')
+ {
+ s->command = NGX_POP3_APOP;
+
} else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T')
{
s->command = NGX_POP3_QUIT;
@@ -496,12 +500,20 @@ ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s)
case sw_argument:
switch (ch) {
- /*
- * the space should be considered part of the at username
- * or password, but not of argument in other commands
- *
- * case ' ':
- */
+ case ' ':
+
+ /*
+ * the space should be considered as part of the at username
+ * or password, but not of argument in other commands
+ */
+
+ if (s->command == NGX_POP3_USER
+ || s->command == NGX_POP3_PASS)
+ {
+ break;
+ }
+
+ /* fall through */
case CR:
case LF:
diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c
index a44a89cb8..4844ae52f 100644
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -61,6 +61,8 @@ ngx_os_init(ngx_log_t *log)
ngx_inherited_nonblocking = 0;
#endif
+ srandom(ngx_time());
+
return NGX_OK;
}