nginx-0.1.36-RELEASE import

*) Change: if the request header has duplicate the "Host",
       "Connection", "Content-Length", or "Authorization" lines, then nginx
       now returns the 400 error.

    *) Change: the "post_accept_timeout" directive was canceled.

    *) Feature: the "default", "af=", "bl=", "deferred", and "bind"
       parameters of the "listen" directive.

    *) Feature: the FreeBSD accept filters support.

    *) Feature: the Linux TCP_DEFER_ACCEPT support.

    *) Bugfix: the ngx_http_autoindex_module did not support the file names
       in UTF-8.

    *) Bugfix: the new log file can be rotated by the -USR1 signal only if
       the reconfiguration by the -HUP signal was made twice.
This commit is contained in:
Igor Sysoev 2005-06-15 18:33:41 +00:00
parent eb9a494b1e
commit aa394d7b1c
23 changed files with 582 additions and 180 deletions

View file

@ -97,7 +97,7 @@ case "$NGX_ICC_VER" in
CFLAGS="$CFLAGS -wd1469" CFLAGS="$CFLAGS -wd1469"
# STUB # STUB
# non-POD class type passed through ellipsis # non-POD class type passed through ellipsis, Linux only ?
CFLAGS="$CFLAGS -wd1595" CFLAGS="$CFLAGS -wd1595"
;; ;;

View file

@ -23,11 +23,30 @@ if [ $PCRE != NONE ]; then
LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a" LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
echo $ngx_n "checking for PCRE library ...$ngx_c"
ngx_pcre_ver=`grep PCRE_MAJOR= $PCRE/configure.in \
| sed -e 's/^.*=\(.*\)$/\1/'`
echo " $ngx_pcre_ver major version found"
# to allow -ipo optimization we link with the *.o but not library # to allow -ipo optimization we link with the *.o but not library
CORE_LIBS="$CORE_LIBS $PCRE/maketables.o"
CORE_LIBS="$CORE_LIBS $PCRE/get.o" case "$ngx_pcre_ver" in
CORE_LIBS="$CORE_LIBS $PCRE/study.o" 6)
CORE_LIBS="$CORE_LIBS $PCRE/pcre.o" CORE_LIBS="$CORE_LIBS $PCRE/pcre_chartables.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_compile.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_exec.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_fullinfo.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_globals.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_tables.o"
CORE_LIBS="$CORE_LIBS $PCRE/pcre_try_flipped.o"
;;
*)
CORE_LIBS="$CORE_LIBS $PCRE/pcre.o"
;;
esac
;; ;;
*) *)

View file

@ -55,9 +55,7 @@ END
$PCRE/pcre.h: $NGX_MAKEFILE $PCRE/pcre.h: $NGX_MAKEFILE
cd $PCRE \\ cd $PCRE \\
&& if [ -f Makefile ]; then \$(MAKE) distclean; fi && if [ -f Makefile ]; then \$(MAKE) distclean; fi \\
cd $PCRE \\
&& CC="\$(CC)" CFLAGS="$PCRE_OPT" \\ && CC="\$(CC)" CFLAGS="$PCRE_OPT" \\
./configure --disable-shared ./configure --disable-shared

View file

@ -16,9 +16,9 @@ http {
default_type application/octet-stream; default_type application/octet-stream;
sendfile on; sendfile on;
# tcp_nodelay on; #tcp_nodelay on;
# keepalive_timeout 0; #keepalive_timeout 0;
#gzip on; #gzip on;

View file

@ -9,6 +9,79 @@
<title lang="en">nginx changelog</title> <title lang="en">nginx changelog</title>
<changes ver="0.1.36" date="15.06.2005">
<change type="change">
<para lang="ru">
ÅÓÌÉ × ÚÁÇÏÌÏ×ËÅ ÚÁÐÒÏÓÅ ÅÓÔØ ÄÕÂÌÉÒÕÀÝÉÅÓÑ ÓÔÒÏËÉ "Host", "Connection",
"Content-Length" É "Authorization", ÔÏ nginx ÔÅÐÅÒØ ×ÙÄÁ£Ô ÏÛÉÂËÕ 400.
</para>
<para lang="en">
if the request header has duplicate the "Host", "Connection", "Content-Length",
or "Authorization" lines, then nginx now returns the 400 error.
</para>
</change>
<change type="change">
<para lang="ru">
ÄÉÒÅËÔÉ×Á post_accept_timeout ÕÐÒÁÚÄÎÅÎÁ.
</para>
<para lang="en">
The "post_accept_timeout" directive was canceled.
</para>
</change>
<change type="feature">
<para lang="ru">
ÐÁÒÁÍÅÔÒÙ default, af=, bl=, deferred É bind × ÄÉÒÅËÔÉ×Å listen.
</para>
<para lang="en">
the "default", "af=", "bl=", "deferred", and "bind" parameters
of the "listen" directive.
</para>
</change>
<change type="feature">
<para lang="ru">
ÐÏÄÄÅÒÖËÁ accept ÆÉÌØÔÒÏ× ×Ï FreeBSD.
</para>
<para lang="en">
the FreeBSD accept filters support.
</para>
</change>
<change type="feature">
<para lang="ru">
ÐÏÄÄÅÒÖËÁ TCP_DEFER_ACCEPT × Linux.
</para>
<para lang="en">
the Linux TCP_DEFER_ACCEPT support.
</para>
</change>
<change type="bugfix">
<para lang="ru">
ÍÏÄÕÌØ ngx_http_autoindex_module ÎÅ ÐÏÄÄÅÒÖÉ×ÁÌ ÉÍÅÎÁ ÆÁÊÌÏ× × UTF-8.
</para>
<para lang="en">
the ngx_http_autoindex_module did not support the file names in UTF-8.
</para>
</change>
<change type="bugfix">
<para lang="ru">
ÐÏÓÌÅ ÄÏÂÁ×ÌÅÎÉÑ ÎÏ×ÙÊ ÌÏÇ-ÆÁÊÌ ÒÏÔÁÃÉÑ ÜÔÏÇÏ ÌÏÇÁ ÐÏ ÓÉÇÎÁÌÕ -USR1
×ÙÐÏÌÎÑÌÁÓØ, ÔÏÌØËÏ ÅÓÌÉ ÐÅÒÅËÏÎÆÉÇÕÒÉÒÏ×ÁÔØ nginx Ä×Á ÒÁÚÁ ÐÏ ÓÉÇÎÁÌÕ -HUP.
</para>
<para lang="en">
the new log file can be rotated by the -USR1 signal only if
the reconfiguration by the -HUP signal was made twice.
</para>
</change>
</changes>
<changes ver="0.1.35" date="07.06.2005"> <changes ver="0.1.35" date="07.06.2005">
<change type="feature"> <change type="feature">

View file

@ -301,6 +301,8 @@ ngx_add_inherited_sockets(ngx_cycle_t *cycle)
return NGX_ERROR; return NGX_ERROR;
} }
ngx_memzero(ls, sizeof(ngx_listening_t));
ls->fd = (ngx_socket_t) s; ls->fd = (ngx_socket_t) s;
} }
} }

View file

@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_ #define _NGINX_H_INCLUDED_
#define NGINX_VER "nginx/0.1.35" #define NGINX_VER "nginx/0.1.36"
#define NGINX_VAR "NGINX" #define NGINX_VAR "NGINX"
#define NGX_NEWPID_EXT ".newbin" #define NGX_NEWPID_EXT ".newbin"

View file

@ -62,10 +62,18 @@ ngx_listening_inet_stream_socket(ngx_conf_t *cf, in_addr_t addr, in_port_t port)
ngx_int_t ngx_int_t
ngx_set_inherited_sockets(ngx_cycle_t *cycle) ngx_set_inherited_sockets(ngx_cycle_t *cycle)
{ {
size_t len; size_t len;
ngx_uint_t i; ngx_uint_t i;
ngx_listening_t *ls; ngx_listening_t *ls;
struct sockaddr_in *sin; struct sockaddr_in *sin;
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
socklen_t aflen;
struct accept_filter_arg af;
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
socklen_t tlen;
int timeout;
#endif
ls = cycle->listening.elts; ls = cycle->listening.elts;
for (i = 0; i < cycle->listening.nelts; i++) { for (i = 0; i < cycle->listening.nelts; i++) {
@ -98,7 +106,6 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
ls[i].addr_text_max_len = INET_ADDRSTRLEN; ls[i].addr_text_max_len = INET_ADDRSTRLEN;
ls[i].addr_text.data = ngx_palloc(cycle->pool, INET_ADDRSTRLEN - 1 ls[i].addr_text.data = ngx_palloc(cycle->pool, INET_ADDRSTRLEN - 1
+ sizeof(":65535") - 1); + sizeof(":65535") - 1);
if (ls[i].addr_text.data == NULL) { if (ls[i].addr_text.data == NULL) {
@ -115,6 +122,54 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
ls[i].addr_text.len = ngx_sprintf(ls[i].addr_text.data + len, ":%d", ls[i].addr_text.len = ngx_sprintf(ls[i].addr_text.data + len, ":%d",
ntohs(sin->sin_port)) ntohs(sin->sin_port))
- ls[i].addr_text.data; - ls[i].addr_text.data;
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
ngx_memzero(&af, sizeof(struct accept_filter_arg));
aflen = sizeof(struct accept_filter_arg);
if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &aflen)
== -1)
{
ngx_log_error(NGX_LOG_NOTICE, cycle->log, ngx_errno,
"getsockopt(SO_ACCEPTFILTER) for %V failed, ignored",
&ls[i].addr_text);
continue;
}
if (aflen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') {
continue;
}
ls[i].accept_filter = ngx_palloc(cycle->pool, 16);
if (ls[i].accept_filter == NULL) {
return NGX_ERROR;
}
(void) ngx_cpystrn((u_char *) ls[i].accept_filter,
(u_char *) af.af_name, 16);
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
timeout = 0;
tlen = sizeof(int);
if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &tlen)
== -1)
{
ngx_log_error(NGX_LOG_NOTICE, cycle->log, ngx_errno,
"getsockopt(TCP_DEFER_ACCEPT) for %V failed, ignored",
&ls[i].addr_text);
continue;
}
if (tlen < sizeof(int) || timeout == 0) {
continue;
}
ls[i].deferred_accept = 1;
#endif
} }
return NGX_OK; return NGX_OK;

View file

@ -47,11 +47,17 @@ typedef struct {
unsigned nonblocking_accept:1; unsigned nonblocking_accept:1;
unsigned nonblocking:1; unsigned nonblocking:1;
unsigned shared:1; /* shared between threads or processes */ unsigned shared:1; /* shared between threads or processes */
unsigned addr_ntop:1;
#if (NGX_HAVE_DEFERRED_ACCEPT) #if (NGX_HAVE_DEFERRED_ACCEPT)
unsigned deferred_accept:1; unsigned deferred_accept:1;
unsigned delete_deferred:1;
unsigned add_deferred:1;
#ifdef SO_ACCEPTFILTER
char *accept_filter;
#endif
#endif #endif
unsigned addr_ntop:1;
} ngx_listening_t; } ngx_listening_t;

View file

@ -39,18 +39,24 @@ static ngx_str_t error_log = ngx_null_string;
ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle) ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle)
{ {
void *rv; void *rv;
ngx_uint_t i, n, failed; ngx_uint_t i, n, failed;
ngx_log_t *log; ngx_log_t *log;
ngx_conf_t conf; ngx_conf_t conf;
ngx_pool_t *pool; ngx_pool_t *pool;
ngx_cycle_t *cycle, **old; ngx_cycle_t *cycle, **old;
ngx_socket_t fd; ngx_socket_t fd;
ngx_list_part_t *part; ngx_list_part_t *part;
ngx_open_file_t *file; ngx_open_file_t *file;
ngx_listening_t *ls, *nls; ngx_listening_t *ls, *nls;
ngx_core_conf_t *ccf; ngx_core_conf_t *ccf;
ngx_core_module_t *module; ngx_core_module_t *module;
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
struct accept_filter_arg af;
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
int timeout;
#endif
log = old_cycle->log; log = old_cycle->log;
@ -307,7 +313,7 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle)
} }
if (ngx_cmp_sockaddr(nls[n].sockaddr, ls[i].sockaddr) if (ngx_cmp_sockaddr(nls[n].sockaddr, ls[i].sockaddr)
== NGX_OK) == NGX_OK)
{ {
fd = ls[i].fd; fd = ls[i].fd;
#if (NGX_WIN32) #if (NGX_WIN32)
@ -330,8 +336,44 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle)
} }
nls[n].fd = ls[i].fd; nls[n].fd = ls[i].fd;
nls[i].remain = 1; nls[n].remain = 1;
ls[i].remain = 1; ls[i].remain = 1;
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
/*
* FreeBSD, except the most recent versions,
* can not remove accept filter
*/
nls[n].deferred_accept = ls[i].deferred_accept;
if (ls[i].accept_filter && nls[n].accept_filter) {
if (ngx_strcmp(ls[i].accept_filter,
nls[n].accept_filter) != 0)
{
nls[n].delete_deferred = 1;
nls[n].add_deferred = 1;
}
} else if (ls[i].accept_filter) {
nls[n].delete_deferred = 1;
} else if (nls[n].accept_filter) {
nls[n].add_deferred = 1;
}
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
if (ls[n].deferred_accept && !nls[n].deferred_accept) {
nls[n].delete_deferred = 1;
} else if (ls[i].deferred_accept
!= nls[n].deferred_accept)
{
nls[n].add_deferred = 1;
}
#endif
break; break;
} }
} }
@ -345,6 +387,16 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle)
ls = cycle->listening.elts; ls = cycle->listening.elts;
for (i = 0; i < cycle->listening.nelts; i++) { for (i = 0; i < cycle->listening.nelts; i++) {
ls[i].open = 1; ls[i].open = 1;
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
if (ls[i].accept_filter) {
ls[i].add_deferred = 1;
}
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
if (ls[i].deferred_accept) {
ls[i].add_deferred = 1;
}
#endif
} }
} }
@ -352,6 +404,81 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle)
if (ngx_open_listening_sockets(cycle) == NGX_ERROR) { if (ngx_open_listening_sockets(cycle) == NGX_ERROR) {
failed = 1; failed = 1;
} }
#if (NGX_HAVE_DEFERRED_ACCEPT)
if (!failed) {
ls = cycle->listening.elts;
for (i = 0; i < cycle->listening.nelts; i++) {
#ifdef SO_ACCEPTFILTER
if (ls[i].delete_deferred) {
if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER,
NULL, 0) == -1)
{
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
"setsockopt(SO_ACCEPTFILTER, NULL) "
"for %V failed, ignored",
&ls[i].addr_text);
if (ls[i].accept_filter) {
ngx_log_error(NGX_LOG_ALERT, log, 0,
"could not change the accept filter "
"to \"%s\" for %V, ignored",
ls[i].accept_filter, &ls[i].addr_text);
}
continue;
}
ls[i].deferred_accept = 0;
}
if (ls[i].add_deferred) {
ngx_memzero(&af, sizeof(struct accept_filter_arg));
(void) ngx_cpystrn((u_char *) af.af_name,
(u_char *) ls[i].accept_filter, 16);
if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER,
&af, sizeof(struct accept_filter_arg)) == -1)
{
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
"setsockopt(SO_ACCEPTFILTER, \"%s\") "
"for %V failed, ignored",
ls[i].accept_filter, &ls[i].addr_text);
continue;
}
ls[i].deferred_accept = 1;
}
#endif
#ifdef TCP_DEFER_ACCEPT
if (ls[i].add_deferred || ls[i].delete_deferred) {
timeout = 0;
if (ls[i].add_deferred) {
timeout = (int) (ls[i].post_accept_timeout / 1000);
}
if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT,
&timeout, sizeof(int)) == -1)
{
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
"setsockopt(TCP_DEFER_ACCEPT, %d) "
"for %V failed, ignored",
timeout, &ls[i].addr_text);
continue;
}
}
if (ls[i].add_deferred) {
ls[i].deferred_accept = 1;
}
#endif
}
}
#endif
} }
} }
@ -682,6 +809,7 @@ void ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
break; break;
} }
part = part->next; part = part->next;
file = part->elts;
i = 0; i = 0;
} }

View file

@ -728,6 +728,35 @@ ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src)
} }
size_t
ngx_utf_length(ngx_str_t *utf)
{
u_char c;
size_t len;
ngx_uint_t i;
for (len = 0, i = 0; i < utf->len; len++, i++) {
c = utf->data[i];
if (c < 0x80) {
continue;
}
if (c < 0xC0) {
/* invalid utf */
return utf->len;
}
for (c <<= 1; c & 0x80; c <<= 1) {
i++;
}
}
return len;
}
uintptr_t uintptr_t
ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type) ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
{ {
@ -792,30 +821,8 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ }; 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ };
/* " ", """, "%", "'", %00-%1F, %7F-%FF */
static uint32_t utf[] =
{ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
0x800000ad, /* 0000 0000 0000 0000 0000 0000 1010 1101 */
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
0x00000000 /* 0000 0000 0000 0000 0000 0000 0000 0000 */ };
switch (type) { switch (type) {
case NGX_ESCAPE_UTF:
escape = utf;
break;
case NGX_ESCAPE_HTML: case NGX_ESCAPE_HTML:
escape = html; escape = html;
break; break;

View file

@ -96,11 +96,11 @@ void ngx_md5_text(u_char *text, u_char *md5);
void ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src); void ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src);
ngx_int_t ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src); ngx_int_t ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src);
size_t ngx_utf_length(ngx_str_t *utf);
#define NGX_ESCAPE_URI 0 #define NGX_ESCAPE_URI 0
#define NGX_ESCAPE_ARGS 1 #define NGX_ESCAPE_ARGS 1
#define NGX_ESCAPE_HTML 2 #define NGX_ESCAPE_HTML 2
#define NGX_ESCAPE_UTF 3
uintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size, uintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size,
ngx_uint_t type); ngx_uint_t type);

View file

@ -247,6 +247,9 @@ ngx_event_accept(ngx_event_t *ev)
if (ev->deferred_accept) { if (ev->deferred_accept) {
rev->ready = 1; rev->ready = 1;
#if (NGX_HAVE_KQUEUE)
rev->available = 1;
#endif
} }
c->ctx = ls->ctx; c->ctx = ls->ctx;

View file

@ -217,6 +217,16 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
return ngx_http_autoindex_error(r, &dir, dname.data); return ngx_http_autoindex_error(r, &dir, dname.data);
} }
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_type.len = sizeof("text/html") - 1;
r->headers_out.content_type.data = (u_char *) "text/html";
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}
fname.len = 0; fname.len = 0;
#if (NGX_SUPPRESS_WARN) #if (NGX_SUPPRESS_WARN)
fname.data = NULL; fname.data = NULL;
@ -334,6 +344,10 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
+ sizeof(" 28-Sep-1970 12:00 ") - 1 + sizeof(" 28-Sep-1970 12:00 ") - 1
+ 19 + 19
+ 2; + 2;
if (r->utf8) {
len += entry[i].name.len - ngx_utf_length(&entry[i].name);
}
} }
b = ngx_create_temp_buf(r->pool, len); b = ngx_create_temp_buf(r->pool, len);
@ -380,7 +394,11 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
b->last = ngx_cpystrn(b->last, entry[i].name.data, b->last = ngx_cpystrn(b->last, entry[i].name.data,
NGX_HTTP_AUTOINDEX_NAME_LEN + 1); NGX_HTTP_AUTOINDEX_NAME_LEN + 1);
len = entry[i].name.len; if (r->utf8) {
len = ngx_utf_length(&entry[i].name);
} else {
len = entry[i].name.len;
}
if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) { if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
b->last = ngx_cpymem(b->last - 3, "..&gt;</a>", b->last = ngx_cpymem(b->last - 3, "..&gt;</a>",
@ -426,17 +444,6 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
b->last = ngx_cpymem(b->last, tail, sizeof(tail) - 1); b->last = ngx_cpymem(b->last, tail, sizeof(tail) - 1);
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = b->last - b->pos;
r->headers_out.content_type.len = sizeof("text/html") - 1;
r->headers_out.content_type.data = (u_char *) "text/html";
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}
if (r->main == NULL) { if (r->main == NULL) {
b->last_buf = 1; b->last_buf = 1;
} }

View file

@ -12,15 +12,17 @@
typedef struct { typedef struct {
char **tables; char **tables;
ngx_str_t name; ngx_str_t name;
ngx_uint_t server; /* unsigned server:1; */
unsigned server:1;
unsigned utf8:1;
} ngx_http_charset_t; } ngx_http_charset_t;
typedef struct { typedef struct {
ngx_int_t src; ngx_int_t src;
ngx_int_t dst; ngx_int_t dst;
char *src2dst; char *src2dst;
char *dst2src; char *dst2src;
} ngx_http_charset_tables_t; } ngx_http_charset_tables_t;
@ -31,17 +33,17 @@ typedef struct {
typedef struct { typedef struct {
ngx_flag_t enable; ngx_flag_t enable;
ngx_flag_t autodetect; ngx_flag_t autodetect;
ngx_int_t default_charset; ngx_int_t default_charset;
ngx_int_t source_charset; ngx_int_t source_charset;
} ngx_http_charset_loc_conf_t; } ngx_http_charset_loc_conf_t;
typedef struct { typedef struct {
ngx_int_t server; ngx_int_t server;
ngx_int_t client; ngx_int_t client;
} ngx_http_charset_ctx_t; } ngx_http_charset_ctx_t;
@ -183,6 +185,7 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
charsets = mcf->charsets.elts; charsets = mcf->charsets.elts;
r->headers_out.charset = charsets[lcf->default_charset].name; r->headers_out.charset = charsets[lcf->default_charset].name;
r->utf8 = charsets[lcf->default_charset].utf8;
if (lcf->default_charset == lcf->source_charset) { if (lcf->default_charset == lcf->source_charset) {
return ngx_http_next_header_filter(r); return ngx_http_next_header_filter(r);
@ -448,6 +451,10 @@ ngx_http_add_charset(ngx_array_t *charsets, ngx_str_t *name)
c->name = *name; c->name = *name;
c->server = 0; c->server = 0;
if (ngx_strcasecmp(name->data, "utf-8") == 0) {
c->utf8 = 1;
}
return i; return i;
} }

View file

@ -66,8 +66,9 @@ static char *
ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{ {
char *rv; char *rv;
ngx_uint_t mi, m, s, l, p, a, n; ngx_uint_t mi, m, s, l, p, a, n, key;
ngx_uint_t port_found, addr_found, virtual_names, key; ngx_uint_t port_found, addr_found;
ngx_uint_t virtual_names, separate_binding;
ngx_conf_t pcf; ngx_conf_t pcf;
ngx_array_t in_ports; ngx_array_t in_ports;
ngx_listening_t *ls; ngx_listening_t *ls;
@ -408,9 +409,9 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
* for this address:port * for this address:port
*/ */
if (lscf[l].default_server) { if (lscf[l].conf.default_server) {
if (in_addr[a].default_server) { if (in_addr[a].conf.default_server) {
ngx_log_error(NGX_LOG_ERR, cf->log, 0, ngx_log_error(NGX_LOG_ERR, cf->log, 0,
"the duplicate default server in %V:%d", "the duplicate default server in %V:%d",
&lscf[l].file_name, lscf[l].line); &lscf[l].file_name, lscf[l].line);
@ -419,7 +420,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].core_srv_conf = cscfp[s];
in_addr[a].default_server = 1; in_addr[a].conf.default_server = 1;
} }
addr_found = 1; addr_found = 1;
@ -449,8 +450,8 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
in_addr[a].names.elts = NULL; in_addr[a].names.elts = NULL;
in_addr[a].hash = NULL; in_addr[a].hash = NULL;
in_addr[a].wildcards.elts = NULL; in_addr[a].wildcards.elts = NULL;
in_addr[a].default_server = lscf[l].default_server;
in_addr[a].core_srv_conf = cscfp[s]; in_addr[a].core_srv_conf = cscfp[s];
in_addr[a].conf = lscf[l].conf;
if (ngx_http_add_names(cf, &in_addr[a], cscfp[s]) if (ngx_http_add_names(cf, &in_addr[a], cscfp[s])
!= NGX_OK) != NGX_OK)
@ -518,6 +519,8 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
in_port = in_ports.elts; in_port = in_ports.elts;
for (p = 0; p < in_ports.nelts; p++) { for (p = 0; p < in_ports.nelts; p++) {
separate_binding = 0;
/* /*
* check whether all name-based servers have the same configuraiton * check whether all name-based servers have the same configuraiton
* as the default server, or some servers restrict the host names * as the default server, or some servers restrict the host names
@ -526,6 +529,10 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
in_addr = in_port[p].addrs.elts; in_addr = in_port[p].addrs.elts;
for (a = 0; a < in_port[p].addrs.nelts; a++) { for (a = 0; a < in_port[p].addrs.nelts; a++) {
if (in_addr[a].conf.bind) {
separate_binding = 1;
}
virtual_names = 0; virtual_names = 0;
name = in_addr[a].names.elts; name = in_addr[a].names.elts;
@ -608,7 +615,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
* to the "*:port" only and ignore the other bindings * to the "*:port" only and ignore the other bindings
*/ */
if (in_addr[a - 1].addr == INADDR_ANY) { if (in_addr[a - 1].addr == INADDR_ANY && !separate_binding) {
a--; a--;
} else { } else {
@ -624,15 +631,13 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR; return NGX_CONF_ERROR;
} }
ls->backlog = -1;
ls->addr_ntop = 1; ls->addr_ntop = 1;
ls->handler = ngx_http_init_connection; ls->handler = ngx_http_init_connection;
cscf = in_addr[a].core_srv_conf; cscf = in_addr[a].core_srv_conf;
ls->pool_size = cscf->connection_pool_size; ls->pool_size = cscf->connection_pool_size;
ls->post_accept_timeout = cscf->post_accept_timeout; ls->post_accept_timeout = cscf->client_header_timeout;
clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index]; clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
ls->log = clcf->err_log; ls->log = clcf->err_log;
@ -644,6 +649,16 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
} }
#endif #endif
ls->backlog = in_addr[a].conf.backlog;
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
ls->accept_filter = in_addr[a].conf.accept_filter;
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
ls->deferred_accept = in_addr[a].conf.deferred_accept;
#endif
ls->ctx = ctx; ls->ctx = ctx;
if (in_port[p].addrs.nelts > 1) { if (in_port[p].addrs.nelts > 1) {
@ -766,8 +781,8 @@ ngx_http_add_address(ngx_conf_t *cf, ngx_http_in_port_t *in_port,
in_addr->names.elts = NULL; in_addr->names.elts = NULL;
in_addr->hash = NULL; in_addr->hash = NULL;
in_addr->wildcards.elts = NULL; in_addr->wildcards.elts = NULL;
in_addr->default_server = lscf->default_server;
in_addr->core_srv_conf = cscf; in_addr->core_srv_conf = cscf;
in_addr->conf = lscf->conf;
#if (NGX_DEBUG) #if (NGX_DEBUG)
{ {

View file

@ -102,13 +102,6 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_srv_conf_t, connection_pool_size), offsetof(ngx_http_core_srv_conf_t, connection_pool_size),
NULL }, NULL },
{ ngx_string("post_accept_timeout"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_core_srv_conf_t, post_accept_timeout),
NULL },
{ ngx_string("request_pool_size"), { ngx_string("request_pool_size"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_size_slot, ngx_conf_set_size_slot,
@ -160,9 +153,9 @@ static ngx_command_t ngx_http_core_commands[] = {
{ ngx_string("listen"), { ngx_string("listen"),
#if 0 #if 0
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
#else #else
NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12, NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
#endif #endif
ngx_http_core_listen, ngx_http_core_listen,
NGX_HTTP_SRV_CONF_OFFSET, NGX_HTTP_SRV_CONF_OFFSET,
@ -1592,7 +1585,6 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
} }
cscf->connection_pool_size = NGX_CONF_UNSET_SIZE; cscf->connection_pool_size = NGX_CONF_UNSET_SIZE;
cscf->post_accept_timeout = NGX_CONF_UNSET_MSEC;
cscf->request_pool_size = NGX_CONF_UNSET_SIZE; cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
cscf->client_header_timeout = NGX_CONF_UNSET_MSEC; cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE; cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
@ -1621,6 +1613,8 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR; return NGX_CONF_ERROR;
} }
ngx_memzero(ls, sizeof(ngx_http_listen_t));
ls->addr = INADDR_ANY; ls->addr = INADDR_ANY;
#if (NGX_WIN32) #if (NGX_WIN32)
ls->port = 80; ls->port = 80;
@ -1629,7 +1623,6 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ls->port = (getuid() == 0) ? 80 : 8000; ls->port = (getuid() == 0) ? 80 : 8000;
#endif #endif
ls->family = AF_INET; ls->family = AF_INET;
ls->default_server = 0;
} }
if (conf->server_names.nelts == 0) { if (conf->server_names.nelts == 0) {
@ -1662,8 +1655,6 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_size_value(conf->connection_pool_size, ngx_conf_merge_size_value(conf->connection_pool_size,
prev->connection_pool_size, 256); prev->connection_pool_size, 256);
ngx_conf_merge_msec_value(conf->post_accept_timeout,
prev->post_accept_timeout, 60000);
ngx_conf_merge_size_value(conf->request_pool_size, ngx_conf_merge_size_value(conf->request_pool_size,
prev->request_pool_size, 4096); prev->request_pool_size, 4096);
ngx_conf_merge_msec_value(conf->client_header_timeout, ngx_conf_merge_msec_value(conf->client_header_timeout,
@ -1859,89 +1850,145 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
} }
/* AF_INET only */
static char * static char *
ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{ {
ngx_http_core_srv_conf_t *scf = conf; ngx_http_core_srv_conf_t *scf = conf;
u_char *addr; char *err;
ngx_int_t port; ngx_str_t *value;
ngx_uint_t p; ngx_uint_t n;
ngx_str_t *args; struct hostent *h;
struct hostent *h; ngx_http_listen_t *ls;
ngx_http_listen_t *ls; ngx_inet_upstream_t inet_upstream;
/* /*
* TODO: check duplicate 'listen' directives, * TODO: check duplicate 'listen' directives,
* add resolved name to server names ??? * add resolved name to server names ???
*/ */
value = cf->args->elts;
ngx_memzero(&inet_upstream, sizeof(ngx_inet_upstream_t));
inet_upstream.url = value[1];
inet_upstream.port_only = 1;
err = ngx_inet_parse_host_port(&inet_upstream);
if (err) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"%s in \"%V\" of the \"listen\" directive",
err, &inet_upstream.url);
return NGX_CONF_ERROR;
}
ls = ngx_array_push(&scf->listen); ls = ngx_array_push(&scf->listen);
if (ls == NULL) { if (ls == NULL) {
return NGX_CONF_ERROR; return NGX_CONF_ERROR;
} }
/* AF_INET only */ ngx_memzero(ls, sizeof(ngx_http_listen_t));
ls->family = AF_INET; ls->family = AF_INET;
ls->port = (in_port_t) (inet_upstream.default_port ?
80 : inet_upstream.port);
ls->file_name = cf->conf_file->file.name; ls->file_name = cf->conf_file->file.name;
ls->line = cf->conf_file->line; ls->line = cf->conf_file->line;
ls->default_server = 0; ls->conf.backlog = -1;
args = cf->args->elts; if (inet_upstream.host.len) {
addr = args[1].data; inet_upstream.host.data[inet_upstream.host.len] = '\0';
for (p = 0; p < args[1].len; p++) { ls->addr = inet_addr((const char *) inet_upstream.host.data);
if (addr[p] == ':') {
addr[p++] = '\0'; if (ls->addr == INADDR_NONE) {
break; h = gethostbyname((const char *) inet_upstream.host.data);
if (h == NULL || h->h_addr_list[0] == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"can not resolve host \"%s\" "
"in the \"listen\" directive",
inet_upstream.host.data);
return NGX_CONF_ERROR;
}
ls->addr = *(in_addr_t *)(h->h_addr_list[0]);
} }
}
if (p == args[1].len) {
/* no ":" in the "listen" */
p = 0;
}
port = ngx_atoi(&addr[p], args[1].len - p);
if (port == NGX_ERROR && p == 0) {
/* "listen host" */
ls->port = 80;
} else if ((port == NGX_ERROR && p != 0) /* "listen host:NONNUMBER" */
|| (port < 1 || port > 65536)) { /* "listen 99999" */
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid port \"%s\" in \"%V\" directive, "
"it must be a number between 1 and 65535",
&addr[p], &cmd->name);
return NGX_CONF_ERROR;
} else if (p == 0) {
ls->addr = INADDR_ANY;
ls->port = (in_port_t) port;
return NGX_CONF_OK;
} else { } else {
ls->port = (in_port_t) port; ls->addr = INADDR_ANY;
} }
ls->addr = inet_addr((const char *) addr); if (cf->args->nelts == 2) {
return NGX_CONF_OK;
}
if (ls->addr == INADDR_NONE) { if (ngx_strcmp(value[2].data, "default") == 0) {
h = gethostbyname((const char *) addr); ls->conf.default_server = 1;
n = 3;
} else {
n = 2;
}
if (h == NULL || h->h_addr_list[0] == NULL) { for ( /* void */ ; n < cf->args->nelts; n++) {
if (ls->conf.default_server == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"can not resolve host \"%s\" " "\"%V\" parameter can be specified for "
"in \"%V\" directive", addr, &cmd->name); "the default \"listen\" directive only",
&value[n]);
return NGX_CONF_ERROR; return NGX_CONF_ERROR;
} }
ls->addr = *(in_addr_t *)(h->h_addr_list[0]); if (ngx_strcmp(value[n].data, "bind") == 0) {
ls->conf.bind = 1;
continue;
}
if (ngx_strncmp(value[n].data, "bl=", 3) == 0) {
ls->conf.backlog = ngx_atoi(value[n].data + 3, value[n].len - 3);
ls->conf.bind = 1;
if (ls->conf.backlog == NGX_ERROR || ls->conf.backlog == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid backlog \"%V\"", &value[n]);
return NGX_CONF_ERROR;
}
continue;
}
if (ngx_strncmp(value[n].data, "af=", 3) == 0) {
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
ls->conf.accept_filter = (char *) &value[n].data[3];
ls->conf.bind = 1;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"accept filters \"%V\" are not supported "
"on this platform, ignored",
&value[n]);
#endif
continue;
}
if (ngx_strcmp(value[n].data, "deferred") == 0) {
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
ls->conf.deferred_accept = 1;
ls->conf.bind = 1;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"the deferred accept is not supported "
"on this platform, ignored");
#endif
continue;
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"the invalid \"%V\" parameter", &value[n]);
return NGX_CONF_ERROR;
} }
return NGX_CONF_OK; return NGX_CONF_OK;

View file

@ -13,14 +13,31 @@
#include <ngx_http.h> #include <ngx_http.h>
typedef struct {
unsigned default_server:1;
unsigned bind:1;
int backlog;
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
char *accept_filter;
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
ngx_uint_t deferred_accept;
#endif
} ngx_http_listen_conf_t;
typedef struct { typedef struct {
in_addr_t addr; in_addr_t addr;
in_port_t port; in_port_t port;
int family; int family;
ngx_str_t file_name; ngx_str_t file_name;
ngx_int_t line; ngx_int_t line;
ngx_uint_t default_server; /* unsigned default_server:1; */ ngx_http_listen_conf_t conf;
} ngx_http_listen_t; } ngx_http_listen_t;
@ -83,7 +100,6 @@ typedef struct {
ngx_bufs_t large_client_header_buffers; ngx_bufs_t large_client_header_buffers;
ngx_msec_t post_accept_timeout;
ngx_msec_t client_header_timeout; ngx_msec_t client_header_timeout;
ngx_uint_t restrict_host_names; ngx_uint_t restrict_host_names;
@ -111,7 +127,7 @@ struct ngx_http_in_addr_s {
/* the default server configuration for this address:port */ /* the default server configuration for this address:port */
ngx_http_core_srv_conf_t *core_srv_conf; ngx_http_core_srv_conf_t *core_srv_conf;
ngx_uint_t default_server; /* unsigned default_server:1; */ ngx_http_listen_conf_t conf;
}; };

View file

@ -22,6 +22,8 @@ static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r, static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset); ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r, static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset); ngx_table_elt_t *h, ngx_uint_t offset);
@ -62,10 +64,10 @@ static char *ngx_http_client_errors[] = {
ngx_http_header_t ngx_http_headers_in[] = { ngx_http_header_t ngx_http_headers_in[] = {
{ ngx_string("Host"), offsetof(ngx_http_headers_in_t, host), { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host),
ngx_http_process_header_line }, ngx_http_process_unique_header_line },
{ ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection), { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection),
ngx_http_process_header_line }, ngx_http_process_unique_header_line },
{ ngx_string("If-Modified-Since"), { ngx_string("If-Modified-Since"),
offsetof(ngx_http_headers_in_t, if_modified_since), offsetof(ngx_http_headers_in_t, if_modified_since),
@ -79,7 +81,7 @@ ngx_http_header_t ngx_http_headers_in[] = {
{ ngx_string("Content-Length"), { ngx_string("Content-Length"),
offsetof(ngx_http_headers_in_t, content_length), offsetof(ngx_http_headers_in_t, content_length),
ngx_http_process_header_line }, ngx_http_process_unique_header_line },
{ ngx_string("Content-Type"), { ngx_string("Content-Type"),
offsetof(ngx_http_headers_in_t, content_type), offsetof(ngx_http_headers_in_t, content_type),
@ -104,7 +106,7 @@ ngx_http_header_t ngx_http_headers_in[] = {
{ ngx_string("Authorization"), { ngx_string("Authorization"),
offsetof(ngx_http_headers_in_t, authorization), offsetof(ngx_http_headers_in_t, authorization),
ngx_http_process_header_line }, ngx_http_process_unique_header_line },
{ ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive), { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive),
ngx_http_process_header_line }, ngx_http_process_header_line },
@ -113,12 +115,6 @@ ngx_http_header_t ngx_http_headers_in[] = {
{ ngx_string("X-Forwarded-For"), { ngx_string("X-Forwarded-For"),
offsetof(ngx_http_headers_in_t, x_forwarded_for), offsetof(ngx_http_headers_in_t, x_forwarded_for),
ngx_http_process_header_line }, ngx_http_process_header_line },
{ ngx_string("X-Real-IP"), offsetof(ngx_http_headers_in_t, x_real_ip),
ngx_http_process_header_line },
{ ngx_string("X-URL"), offsetof(ngx_http_headers_in_t, x_url),
ngx_http_process_header_line },
#endif #endif
#if (NGX_HTTP_HEADERS) #if (NGX_HTTP_HEADERS)
@ -906,13 +902,13 @@ ngx_http_read_request_header(ngx_http_request_t *r)
return n; return n;
} }
if (!rev->ready) { if (rev->ready) {
return NGX_AGAIN; n = r->connection->recv(r->connection, r->header_in->last,
r->header_in->end - r->header_in->last);
} else {
n = NGX_AGAIN;
} }
n = r->connection->recv(r->connection, r->header_in->last,
r->header_in->end - r->header_in->last);
if (n == NGX_AGAIN) { if (n == NGX_AGAIN) {
if (!r->header_timeout_set) { if (!r->header_timeout_set) {
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
@ -1106,6 +1102,29 @@ ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
} }
static ngx_int_t
ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{
ngx_table_elt_t **ph;
ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
if (*ph == NULL) {
*ph = h;
return NGX_OK;
}
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent duplicate header line: \"%V: %V\"",
&h->key, &h->value);
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
return NGX_ERROR;
}
static ngx_int_t static ngx_int_t
ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset) ngx_uint_t offset)
@ -1113,15 +1132,15 @@ ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_table_elt_t **cookie; ngx_table_elt_t **cookie;
cookie = ngx_array_push(&r->headers_in.cookies); cookie = ngx_array_push(&r->headers_in.cookies);
if (cookie == NULL) { if (cookie) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); *cookie = h;
ngx_http_close_connection(r->connection); return NGX_OK;
return NGX_ERROR;
} }
*cookie = h; ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
ngx_http_close_connection(r->connection);
return NGX_OK; return NGX_ERROR;
} }

View file

@ -152,8 +152,6 @@ typedef struct {
#if (NGX_HTTP_PROXY) #if (NGX_HTTP_PROXY)
ngx_table_elt_t *x_forwarded_for; ngx_table_elt_t *x_forwarded_for;
ngx_table_elt_t *x_real_ip;
ngx_table_elt_t *x_url;
#endif #endif
#if (NGX_HTTP_HEADERS) #if (NGX_HTTP_HEADERS)
@ -365,6 +363,7 @@ struct ngx_http_request_s {
unsigned internal:1; unsigned internal:1;
unsigned closed:1; unsigned closed:1;
unsigned done:1; unsigned done:1;
unsigned utf8:1;
unsigned main_filter_need_in_memory:1; unsigned main_filter_need_in_memory:1;
unsigned filter_need_in_memory:1; unsigned filter_need_in_memory:1;

View file

@ -249,7 +249,8 @@ ngx_imap_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (err) { if (err) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"%s in \"%V\" of the \"listen\" directive", err); "%s in \"%V\" of the \"listen\" directive",
err, &inet_upstream.url);
return NGX_CONF_ERROR; return NGX_CONF_ERROR;
} }

View file

@ -76,7 +76,7 @@
#endif #endif
#if defined SO_ACCEPTFILTER && !defined NGX_HAVE_DEFERRED_ACCEPT #if (defined SO_ACCEPTFILTER && !defined NGX_HAVE_DEFERRED_ACCEPT)
#define NGX_HAVE_DEFERRED_ACCEPT 1 #define NGX_HAVE_DEFERRED_ACCEPT 1
#endif #endif

View file

@ -839,7 +839,7 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority)
#endif #endif
if (ccf->working_directory.len) { if (ccf->working_directory.len) {
if (chdir(ccf->working_directory.data) == -1) { if (chdir((char *) ccf->working_directory.data) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"chdir(\"%s\") failed", ccf->working_directory.data); "chdir(\"%s\") failed", ccf->working_directory.data);
/* fatal */ /* fatal */