nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command. *) Feature: the ngx_http_ssi_module supports the condition command like 'if expr="$NAME"' and "else" and "endif" commands. Only one nested level is supported. *) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and DATE_GMT variables and "config timefmt" command. *) Feature: the "ssi_ignore_recycled_buffers" directive. *) Bugfix: the "echo" command did not show the default value for the empty QUERY_STRING variable. *) Change: the ngx_http_proxy_module was rewritten. *) Feature: the "proxy_redirect", "proxy_pass_request_headers", "proxy_pass_request_body", and "proxy_method" directives. *) Feature: the "proxy_set_header" directive. The "proxy_x_var" was canceled and must be replaced with the proxy_set_header directive. *) Change: the "proxy_preserve_host" is canceled and must be replaced with the "proxy_set_header Host $host" and the "proxy_redirect off" directives, the "proxy_set_header Host $host:$proxy_port" directive and the appropriate proxy_redirect directives. *) Change: the "proxy_set_x_real_ip" is canceled and must be replaced with the "proxy_set_header X-Real-IP $remote_addr" directive. *) Change: the "proxy_add_x_forwarded_for" is canceled and must be replaced with the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for" directive. *) Change: the "proxy_set_x_url" is canceled and must be replaced with the "proxy_set_header X-URL http://$host:$server_port$request_uri" directive. *) Feature: the "fastcgi_param" directive. *) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params" directive are canceled and must be replaced with the fastcgi_param directives. *) Feature: the "index" directive can use the variables. *) Feature: the "index" directive can be used at http and server levels. *) Change: the last index only in the "index" directive can be absolute. *) Feature: the "rewrite" directive can use the variables. *) Feature: the "internal" directive. *) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR, SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME, REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables. *) Change: nginx now passes the invalid lines in a client request headers or a backend response header. *) Bugfix: if the backend did not transfer response for a long time and the "send_timeout" was less than "proxy_read_timeout", then nginx returned the 408 response. *) Bugfix: the segmentation fault was occurred if the backend sent an invalid line in response header; the bug had appeared in 0.1.26. *) Bugfix: the segmentation fault may occurred in FastCGI fault tolerance configuration. *) Bugfix: the "expires" directive did not remove the previous "Expires" and "Cache-Control" headers. *) Bugfix: nginx did not take into account trailing dot in "Host" header line. *) Bugfix: the ngx_http_auth_module did not work under Linux. *) Bugfix: the rewrite directive worked incorrectly, if the arguments were in a request. *) Bugfix: nginx could not be built on MacOS X.
This commit is contained in:
parent
9ef32ce43c
commit
7fed746a3a
121 changed files with 7173 additions and 4618 deletions
|
@ -57,6 +57,11 @@ case $CPU in
|
|||
CPU_OPT="-march=pentium4"
|
||||
;;
|
||||
|
||||
opteron)
|
||||
# optimize for Opteron, gcc 3.x
|
||||
CPU_OPT="-march=opteron"
|
||||
;;
|
||||
|
||||
sparc64)
|
||||
# build 64-bit UltraSparc binary
|
||||
CPU_OPT="-m64"
|
||||
|
|
27
auto/cc/msvc
27
auto/cc/msvc
|
@ -6,18 +6,31 @@
|
|||
|
||||
# optimizations
|
||||
|
||||
# maximize speed
|
||||
# maximize speed, equivalent to -Og -Oi -Ot -Oy -Ob2 -Gs -GF -Gy
|
||||
CFLAGS="$CFLAGS -O2"
|
||||
|
||||
# enable global optimization
|
||||
CFLAGS="$CFLAGS -Og"
|
||||
#CFLAGS="$CFLAGS -Og"
|
||||
# enable intrinsic functions
|
||||
CFLAGS="$CFLAGS -Oi"
|
||||
# inline expansion
|
||||
CFLAGS="$CFLAGS -Ob1"
|
||||
#CFLAGS="$CFLAGS -Oi"
|
||||
|
||||
# disable inline expansion
|
||||
#CFLAGS="$CFLAGS -Ob0"
|
||||
# explicit inline expansion
|
||||
#CFLAGS="$CFLAGS -Ob1"
|
||||
# explicit and implicit inline expansion
|
||||
#CFLAGS="$CFLAGS -Ob2"
|
||||
|
||||
# enable frame pointer omission
|
||||
CFLAGS="$CFLAGS -Oy"
|
||||
#CFLAGS="$CFLAGS -Oy"
|
||||
# disable stack checking calls
|
||||
CFLAGS="$CFLAGS -Gs"
|
||||
#CFLAGS="$CFLAGS -Gs"
|
||||
|
||||
# pools strings as read/write
|
||||
#CFLAGS="$CFLAGS -Gf"
|
||||
# pools strings as read-only
|
||||
#CFLAGS="$CFLAGS -GF"
|
||||
|
||||
|
||||
case $CPU in
|
||||
pentium)
|
||||
|
|
11
auto/have_headers
Normal file
11
auto/have_headers
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
# Copyright (C) Igor Sysoev
|
||||
|
||||
|
||||
cat << END >> $NGX_AUTO_HEADERS_H
|
||||
|
||||
#ifndef $have
|
||||
#define $have 1
|
||||
#endif
|
||||
|
||||
END
|
|
@ -39,14 +39,7 @@ if [ -x $NGX_AUTOTEST ]; then
|
|||
| tr '[a-z]' '[A-Z]'`
|
||||
|
||||
|
||||
cat << END >> $NGX_AUTO_HEADERS_H
|
||||
|
||||
#ifndef NGX_HAVE_$ngx_name
|
||||
#define NGX_HAVE_$ngx_name 1
|
||||
#endif
|
||||
|
||||
END
|
||||
|
||||
have=NGX_HAVE_$ngx_name . auto/have_headers
|
||||
|
||||
eval "NGX_INCLUDE_$ngx_name='#include <$ngx_include>'"
|
||||
|
||||
|
|
10
auto/modules
10
auto/modules
|
@ -51,6 +51,10 @@ if [ $NGX_TEST_BUILD_SOLARIS_SENDFILEV = YES ]; then
|
|||
fi
|
||||
|
||||
|
||||
if [ $HTTP_SSI = YES ]; then
|
||||
HTTP_POSTPONE=YES
|
||||
fi
|
||||
|
||||
# the filter order is important
|
||||
# ngx_http_write_filter
|
||||
# ngx_http_header_filter
|
||||
|
@ -58,6 +62,7 @@ fi
|
|||
# ngx_http_range_header_filter
|
||||
# ngx_http_ssl_filter
|
||||
# ngx_http_gzip_filter
|
||||
# ngx_http_postpone_filter
|
||||
# ngx_http_charset_filter
|
||||
# ngx_http_ssi_filter
|
||||
# ngx_http_headers_filter
|
||||
|
@ -77,6 +82,11 @@ if [ $HTTP_GZIP = YES ]; then
|
|||
HTTP_SRCS="$HTTP_SRCS $HTTP_GZIP_SRCS"
|
||||
fi
|
||||
|
||||
if [ $HTTP_POSTPONE = YES ]; then
|
||||
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_POSTPONE_FILTER_MODULE"
|
||||
HTTP_SRCS="$HTTP_SRCS $HTPP_POSTPONE_FILTER_SRCS"
|
||||
fi
|
||||
|
||||
if [ $HTTP_CHARSET = YES ]; then
|
||||
have=NGX_HTTP_CHARSET . auto/have
|
||||
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_CHARSET_FILTER_MODULE"
|
||||
|
|
|
@ -49,6 +49,7 @@ HTTP_CHARSET=YES
|
|||
HTTP_GZIP=YES
|
||||
HTTP_SSL=NO
|
||||
HTTP_SSI=YES
|
||||
HTTP_POSTPONE=NO
|
||||
HTTP_ACCESS=YES
|
||||
HTTP_AUTH_BASIC=YES
|
||||
HTTP_USERID=YES
|
||||
|
|
17
auto/os/conf
17
auto/os/conf
|
@ -23,6 +23,15 @@ case "$NGX_PLATFORM" in
|
|||
. auto/os/freebsd
|
||||
;;
|
||||
|
||||
Darwin:*)
|
||||
have=NGX_DARWIN . auto/have_headers
|
||||
have=NGX_HAVE_INHERITED_NONBLOCK . auto/have
|
||||
CORE_INCS="$UNIX_INCS"
|
||||
CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
|
||||
CORE_SRCS="$UNIX_SRCS"
|
||||
CRYPT_LIB=
|
||||
;;
|
||||
|
||||
Linux:*)
|
||||
. auto/os/linux
|
||||
;;
|
||||
|
@ -47,16 +56,16 @@ esac
|
|||
|
||||
case "$NGX_MACHINE" in
|
||||
|
||||
i386|i686|i86pc|amd64)
|
||||
have=NGX_HAVE_NONALIGNED . auto/have
|
||||
;;
|
||||
i386|i686|i86pc|amd64)
|
||||
have=NGX_HAVE_NONALIGNED . auto/have
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
|
||||
if [ "$NGX_PLATFORM" != win32 ]; then
|
||||
|
||||
NGX_USER=${NGX_USER:-nobody}
|
||||
NGX_USER=${NGX_USER:-nobody}
|
||||
|
||||
if [ -z "$NGX_GROUP" -a $NGX_USER = nobody ] ; then
|
||||
if grep nobody /etc/group 2>&1 >/dev/null; then
|
||||
|
|
|
@ -2,14 +2,7 @@
|
|||
# Copyright (C) Igor Sysoev
|
||||
|
||||
|
||||
cat << END >> $NGX_AUTO_HEADERS_H
|
||||
|
||||
#ifndef NGX_FREEBSD
|
||||
#define NGX_FREEBSD 1
|
||||
#endif
|
||||
|
||||
END
|
||||
|
||||
have=NGX_FREEBSD . auto/have_headers
|
||||
|
||||
CORE_INCS="$UNIX_INCS"
|
||||
CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS"
|
||||
|
@ -39,6 +32,7 @@ then
|
|||
echo " + setproctitle() in libutil"
|
||||
|
||||
CORE_LIBS="$CORE_LIBS -lutil"
|
||||
NGX_SETPROCTITLE_LIB="-lutil"
|
||||
fi
|
||||
|
||||
# sendfile
|
||||
|
|
|
@ -2,13 +2,7 @@
|
|||
# Copyright (C) Igor Sysoev
|
||||
|
||||
|
||||
cat << END >> $NGX_AUTO_HEADERS_H
|
||||
|
||||
#ifndef NGX_LINUX
|
||||
#define NGX_LINUX 1
|
||||
#endif
|
||||
|
||||
END
|
||||
have=NGX_LINUX . auto/have_headers
|
||||
|
||||
CORE_INCS="$UNIX_INCS"
|
||||
CORE_DEPS="$UNIX_DEPS $LINUX_DEPS"
|
||||
|
|
|
@ -2,13 +2,7 @@
|
|||
# Copyright (C) Igor Sysoev
|
||||
|
||||
|
||||
cat << END >> $NGX_AUTO_HEADERS_H
|
||||
|
||||
#ifndef NGX_SOLARIS
|
||||
#define NGX_SOLARIS 1
|
||||
#endif
|
||||
|
||||
END
|
||||
have=NGX_SOLARIS . auto/have_headers
|
||||
|
||||
CORE_INCS="$UNIX_INCS"
|
||||
CORE_DEPS="$UNIX_DEPS $SOLARIS_DEPS"
|
||||
|
|
|
@ -2,14 +2,7 @@
|
|||
# Copyright (C) Igor Sysoev
|
||||
|
||||
|
||||
cat << END >> $NGX_AUTO_HEADERS_H
|
||||
|
||||
#ifndef NGX_WIN32
|
||||
#define NGX_WIN32 1
|
||||
#endif
|
||||
|
||||
END
|
||||
|
||||
have=NGX_WIN32 . auto/have_headers
|
||||
|
||||
CORE_INCS="$WIN32_INCS"
|
||||
CORE_DEPS="$WIN32_DEPS"
|
||||
|
|
19
auto/sources
19
auto/sources
|
@ -120,6 +120,7 @@ UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \
|
|||
src/os/unix/ngx_channel.h \
|
||||
src/os/unix/ngx_shared.h \
|
||||
src/os/unix/ngx_process.h \
|
||||
src/os/unix/ngx_setproctitle.h \
|
||||
src/os/unix/ngx_atomic.h \
|
||||
src/os/unix/ngx_thread.h \
|
||||
src/os/unix/ngx_socket.h \
|
||||
|
@ -224,9 +225,11 @@ HTTP_CACHE_MODULE=ngx_http_cache_module
|
|||
HTTP_WRITE_FILTER_MODULE="ngx_http_write_filter_module"
|
||||
HTTP_HEADER_FILTER_MODULE="ngx_http_header_filter_module"
|
||||
|
||||
HTTP_POSTPONE_FILTER_MODULE=ngx_http_postpone_filter_module
|
||||
HTTP_COPY_FILTER_MODULE=ngx_http_copy_filter_module
|
||||
|
||||
HTTP_CHUNKED_FILTER_MODULE=ngx_http_chunked_filter_module
|
||||
HTTP_HEADERS_FILTER_MODULE=ngx_http_headers_filter_module
|
||||
HTTP_COPY_FILTER_MODULE=ngx_http_copy_filter_module
|
||||
|
||||
HTTP_RANGE_HEADER_FILTER_MODULE=ngx_http_range_header_filter_module
|
||||
HTTP_RANGE_BODY_FILTER_MODULE=ngx_http_range_body_filter_module
|
||||
|
@ -273,6 +276,8 @@ HTTP_SRCS="src/http/ngx_http.c \
|
|||
# STUB
|
||||
HTTP_SRCS="$HTTP_SRCS src/http/ngx_http_busy_lock.c"
|
||||
|
||||
HTPP_POSTPONE_FILTER_SRCS=src/http/ngx_http_postpone_filter_module.c
|
||||
|
||||
HTPP_CACHE_SRCS=src/http/ngx_http_cache.c
|
||||
HTPP_FILE_CACHE_SRCS=src/http/ngx_http_file_cache.c
|
||||
|
||||
|
@ -323,17 +328,7 @@ HTTP_SSL_SRCS=src/http/modules/ngx_http_ssl_module.c
|
|||
|
||||
|
||||
HTTP_PROXY_MODULE=ngx_http_proxy_module
|
||||
#HTTP_PROXY_SRCS=src/http/modules/ngx_http_proxy_module.c
|
||||
|
||||
HTTP_PROXY_INCS="src/http/modules/proxy"
|
||||
HTTP_PROXY_DEPS=src/http/modules/proxy/ngx_http_proxy_handler.h
|
||||
HTTP_PROXY_SRCS="src/http/modules/proxy/ngx_http_proxy_handler.c \
|
||||
src/http/modules/proxy/ngx_http_proxy_upstream.c \
|
||||
src/http/modules/proxy/ngx_http_proxy_parse.c \
|
||||
src/http/modules/proxy/ngx_http_proxy_header.c"
|
||||
|
||||
# STUB
|
||||
# src/http/modules/proxy/ngx_http_proxy_cache.c \
|
||||
HTTP_PROXY_SRCS=src/http/modules/ngx_http_proxy_module.c
|
||||
|
||||
|
||||
HTTP_FASTCGI_MODULE=ngx_http_fastcgi_module
|
||||
|
|
|
@ -64,7 +64,7 @@ ngx_feature="setproctitle()"
|
|||
ngx_feature_name="NGX_HAVE_SETPROCTITLE"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_libs=$NGX_SETPROCTITLE_LIB
|
||||
ngx_feature_test="setproctitle(\"test\");"
|
||||
. auto/feature
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ types {
|
|||
application/x-javascript js;
|
||||
application/x-rar-compressed rar;
|
||||
application/x-xpinstall xpi;
|
||||
application/x-x509-ca-cert der pem crt;
|
||||
|
||||
audio/mpeg mp3;
|
||||
audio/x-realaudio ra;
|
||||
|
|
|
@ -9,6 +9,319 @@
|
|||
<title lang="en">nginx changelog</title>
|
||||
|
||||
|
||||
<changes ver="0.1.29" date="12.05.2005">
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÍÏÄÕÌØ ngx_http_ssi_module ÐÏÄÄÅÒÖÉ×ÁÅÔ ËÏÍÁÎÄÕ include virtual.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the ngx_http_ssi_module supports "include virtual" command.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÍÏÄÕÌØ ngx_http_ssi_module ÐÏÄÄÅÒÖÉ×ÁÅÔ ÕÓÌÏ×ÎÕÀ ËÏÍÁÎÄÕ ×ÉÄÁ
|
||||
'if expr="$NAME"' É ËÏÍÁÎÄÙ else É endif.
|
||||
äÏÐÕÓËÁÅÔÓÑ ÔÏÌØËÏ ÏÄÉÎ ÕÒÏ×ÅÎØ ×ÌÏÖÅÎÎÏÓÔÉ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the ngx_http_ssi_module supports the condition command like
|
||||
'if expr="$NAME"' and "else" and "endif" commands.
|
||||
Only one nested level is supported.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÍÏÄÕÌØ ngx_http_ssi_module ÐÏÄÄÅÒÖÉ×ÁÅÔ Ä×Å ÐÅÒÅÍÅÎÎÙÅ DATE_LOCAL É DATE_GMT
|
||||
É ËÏÍÁÎÄÕ config timefmt.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the ngx_http_ssi_module supports the DATE_LOCAL and DATE_GMT variables
|
||||
and "config timefmt" command.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á ssi_ignore_recycled_buffers.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "ssi_ignore_recycled_buffers" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÅÓÌÉ ÐÅÒÅÍÅÎÎÁÑ QUERY_STRING ÎÅ ÂÙÌÁ ÏÐÒÅÄÅÌÅÎÁ, ÔÏ × ËÏÍÁÎÄÅ echo
|
||||
ÎÅ ÓÔÁ×ÉÌÏÓØ ÚÎÁÞÅÎÉÅ ÐÏ ÕÍÏÌÞÁÎÉÀ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "echo" command did not show the default value for the empty QUERY_STRING
|
||||
variable.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
ÍÏÄÕÌØ ngx_http_proxy_module ÐÏÌÎÏÓÔØÀ ÐÅÒÅÐÉÓÁÎ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the ngx_http_proxy_module was rewritten.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Ù proxy_redirect, proxy_pass_request_headers,
|
||||
proxy_pass_request_body É proxy_method.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "proxy_redirect", "proxy_pass_request_headers",
|
||||
"proxy_pass_request_body", and "proxy_method" directives.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á proxy_set_header.
|
||||
äÉÒÅËÔÉ×Á proxy_x_var ÕÐÒÁÚÄÎÅÎÁ É ÄÏÌÖÎÁ ÂÙÔØ ÚÁÍÅÎÅÎÁ ÄÉÒÅËÔÉ×ÏÊ
|
||||
proxy_set_header.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "proxy_set_header" directive.
|
||||
The "proxy_x_var" is canceled and must be replaced with the proxy_set_header
|
||||
directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á proxy_preserve_host ÕÐÒÁÚÄÎÅÎÁ É ÄÏÌÖÎÁ ÂÙÔØ ÚÁÍÅÎÅÎÁ ÄÉÒÅËÔÉ×ÁÍÉ
|
||||
"proxy_set_header Host $host" É "proxy_redirect off"
|
||||
ÉÌÉ ÄÉÒÅËÔÉ×ÏÊ <nobr>"proxy_set_header Host $host:$proxy_port"</nobr>
|
||||
É ÓÏÏÔ×ÅÔÓÔ×ÕÀÝÉÍÉ ÅÊ ÄÉÒÅËÔÉ×ÁÍÉ proxy_redirect.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "proxy_preserve_host" is canceled and must be replaced with
|
||||
the "proxy_set_header Host $host" and the "proxy_redirect off" directives,
|
||||
the <nobr>"proxy_set_header Host $host:$proxy_port" directive</nobr>
|
||||
and the appropriate proxy_redirect directives.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á proxy_set_x_real_ip ÕÐÒÁÚÄÎÅÎÁ É ÄÏÌÖÎÁ ÂÙÔØ ÚÁÍÅÎÅÎÁ ÄÉÒÅËÔÉ×ÏÊ
|
||||
"proxy_set_header X-Real-IP $remote_addr".
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "proxy_set_x_real_ip" is canceled and must be replaced with
|
||||
the "proxy_set_header X-Real-IP $remote_addr" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á proxy_add_x_forwarded_for ÕÐÒÁÚÄÎÅÎÁ É ÄÏÌÖÎÁ ÂÙÔØ ÚÁÍÅÎÅÎÁ
|
||||
ÄÉÒÅËÔÉ×ÏÊ
|
||||
<nobr>"proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for".</nobr>
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "proxy_add_x_forwarded_for" is canceled and must be replaced with
|
||||
<nobr>the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"</nobr>
|
||||
directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á proxy_set_x_url ÕÐÒÁÚÄÎÅÎÁ É ÄÏÌÖÎÁ ÂÙÔØ ÚÁÍÅÎÅÎÁ ÄÉÒÅËÔÉ×ÏÊ
|
||||
<nobr>"proxy_set_header X-URL http://$host:$server_port$request_uri".</nobr>
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "proxy_set_x_url" is canceled and must be replaced with
|
||||
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
|
||||
directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á fastcgi_param.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "fastcgi_param" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Ù fastcgi_set_var É fastcgi_params ÕÐÒÁÚÄÎÅÎÙ É ÄÏÌÖÎÙ ÂÙÔØ
|
||||
ÚÁÍÅÎÙ ÄÉÒÅËÔÉ×ÁÍÉ fastcgi_param.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "fastcgi_set_var" and "fastcgi_params" directive are canceled and
|
||||
must be replaced with the fastcgi_param directives.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á index ÍÏÖÅÔ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÅÒÅÍÅÎÎÙÅ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "index" directive can use the variables.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á index ÍÏÖÅÔ ÂÙÔØ ÕËÁÚÁÎÁ ÎÁ ÕÒÏ×ÎÅ http É server.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "index" directive can be used at http and server levels.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
ÔÏÌØËÏ ÐÏÓÌÅÄÎÉÊ ÐÁÒÁÍÅÔÒ × ÄÉÒÅËÔÉ×Å index ÍÏÖÅÔ ÂÙÔØ ÁÂÓÏÌÀÔÎÙÍ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the last index only in the "index" directive can be absolute.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
× ÄÉÒÅËÔÉ×Å rewrite ÍÏÇÕÔ ÉÓÐÏÌØÚÏ×ÁÔØÓÑ ÐÅÒÅÍÅÎÎÙÅ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "rewrite" directive can use the variables.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á internal.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "internal" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÐÅÒÅÍÅÎÎÙÅ CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
|
||||
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
|
||||
REQUEST_METHOD, REQUEST_URI É REMOTE_USER.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
|
||||
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
|
||||
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
nginx ÔÅÐÅÒØ ÐÅÒÅÄÁ£Ô ÎÅ×ÅÒÎÙÅ ÓÔÒÏËÉ × ÚÁÇÏÌÏ×ËÁÈ ÚÁÐÒÏÓÁ ËÌÉÅÎÔÁ É
|
||||
ÏÔ×ÅÔÁ ÂÜËÅÎÄÁ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx now passes the invalid lines in a client request headers
|
||||
or a backend response header.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÅÓÌÉ ÂÜËÅÎÄ ÄÏÌÇÏ ÎÅ ÐÅÒÅÄÁ×ÁÌ ÏÔ×ÅÔ É send_timeout ÂÙÌ ÍÅÎØÛÅ, ÞÅÍ
|
||||
proxy_read_timeout, ÔÏ ËÌÉÅÎÔÕ ×ÏÚ×ÒÁÝÁÌÓÑ ÏÔ×ÅÔ 408.
|
||||
</para>
|
||||
<para lang="en">
|
||||
if the backend did not transfer response for a long time and
|
||||
the "send_timeout" was less than "proxy_read_timeout", then nginx
|
||||
returned the 408 response.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÅÓÌÉ ÂÜËÅÎÄ ÐÅÒÅÄÁ×ÁÌ ÎÅ×ÅÒÎÕÀ ÓÔÒÏËÕ × ÚÁÇÏÌÏ×ËÅ ÏÔ×ÅÔÁ, ÔÏ ÐÒÏÉÓÈÏÄÉÌ
|
||||
segmentation fault;
|
||||
ÏÛÉÂËÁ ÐÏÑ×ÉÌÁÓØ × 0.1.26.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the segmentation fault was occurred if the backend sent an invalid line
|
||||
in response header;
|
||||
bug appeared in 0.1.26.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ ÏÔËÁÚÏÕÓÔÏÊÞÉ×ÏÊ ËÏÎÆÉÇÕÒÁÃÉÉ × FastCGI ÍÏÇ
|
||||
ÐÒÏÉÓÈÏÄÉÔØ segmentation fault.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the segmentation fault may occurred in FastCGI fault tolerance configuration.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á expires ÎÅ ÕÄÁÌÑÌÁ ÕÖÅ ÕÓÔÁÎÏ×ÌÅÎÎÙÅ ÓÔÒÏËÉ ÚÁÇÏÌÏ×ËÁ
|
||||
"Expires" É "Cache-Control".
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "expires" directive did not remove the previous "Expires" and
|
||||
"Cache-Control" headers.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
nginx ÎÅ ÕÞÉÔÙ×ÁÌ ÚÁ×ÅÒÛÁÀÝÕÀ ÔÏÞËÕ × ÓÔÒÏËÅ ÚÁÇÏÌÏ×ËÁ ÚÁÐÒÏÓÁ "Host".
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx did not take into account trailing dot in "Host" header line.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÍÏÄÕÌØ ngx_http_auth_module ÎÅ ÒÁÂÏÔÁÌ ÎÁ Linux.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the ngx_http_auth_module did not work under Linux.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á rewrite ÎÅ×ÅÒÎÏ ÒÁÂÏÔÁÌÁ, ÅÓÌÉ × ÚÁÐÒÏÓÅ ÐÒÉÓÕÔÓÔ×Ï×ÁÌÉ ÁÒÇÕÍÅÎÔÙ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the rewrite directive worked incorrectly, if the arguments were in a request.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
nginx ÎÅ ÓÏÂÉÒÁÌÓÑ ÎÁ MacOS X.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx could not be built on MacOS X.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="0.1.28" date="08.04.2005">
|
||||
|
||||
<change type="bugfix">
|
||||
|
@ -586,7 +899,7 @@ the rewrite/location cycle and sets the current configuration to the request.
|
|||
|
||||
<changes ver="0.1.17" date="03.02.2005">
|
||||
|
||||
<change type="feature">
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
ÍÏÄÕÌØ ngx_http_rewrite_module ÐÏÌÎÏÓÔØÀ ÐÅÒÅÐÉÓÁÎ.
|
||||
ôÅÐÅÒØ ÍÏÖÎÏ ÄÅÌÁÔØ ÒÅÄÉÒÅËÔÙ, ×ÏÚ×ÒÁÝÁÔØ ËÏÄÙ ÏÛÉÂÏË
|
||||
|
|
|
@ -107,7 +107,7 @@ static ngx_core_module_t ngx_core_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_core_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_core_module_ctx, /* module context */
|
||||
ngx_core_commands, /* module directives */
|
||||
NGX_CORE_MODULE, /* module type */
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define NGINX_VER "nginx/0.1.28"
|
||||
#define NGINX_VER "nginx/0.1.29"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
#define NGX_NEWPID_EXT ".newbin"
|
||||
|
|
|
@ -30,16 +30,21 @@ void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);
|
|||
static ngx_inline ngx_int_t
|
||||
ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size)
|
||||
{
|
||||
array->elts = ngx_palloc(pool, n * size);
|
||||
if (array->elts == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
/*
|
||||
* set "array->nelts" before "array->elts", otherwise MSVC thinks
|
||||
* that "array->nelts" may be used without having been initialized
|
||||
*/
|
||||
|
||||
array->nelts = 0;
|
||||
array->size = size;
|
||||
array->nalloc = n;
|
||||
array->pool = pool;
|
||||
|
||||
array->elts = ngx_palloc(pool, n * size);
|
||||
if (array->elts == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ ngx_create_temp_buf(ngx_pool_t *pool, size_t size)
|
|||
* b->file = NULL;
|
||||
* b->shadow = NULL;
|
||||
* b->tag = 0;
|
||||
*
|
||||
* and flags
|
||||
*/
|
||||
|
||||
b->pos = b->start;
|
||||
|
@ -94,6 +94,7 @@ ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs)
|
|||
* b->file = NULL;
|
||||
* b->shadow = NULL;
|
||||
* b->tag = 0;
|
||||
* and flags
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
@ -44,7 +44,9 @@ struct ngx_buf_s {
|
|||
unsigned recycled:1;
|
||||
unsigned in_file:1;
|
||||
unsigned flush:1;
|
||||
unsigned sync:1;
|
||||
unsigned last_buf:1;
|
||||
unsigned last_in_chain:1;
|
||||
|
||||
unsigned last_shadow:1;
|
||||
unsigned temp_file:1;
|
||||
|
@ -104,7 +106,8 @@ typedef struct {
|
|||
#define ngx_buf_in_memory(b) (b->temporary || b->memory || b->mmap)
|
||||
#define ngx_buf_in_memory_only(b) (ngx_buf_in_memory(b) && !b->in_file)
|
||||
#define ngx_buf_special(b) \
|
||||
((b->flush || b->last_buf) && !ngx_buf_in_memory(b) && !b->in_file)
|
||||
((b->flush || b->last_buf || b->sync) \
|
||||
&& !ngx_buf_in_memory(b) && !b->in_file)
|
||||
|
||||
#define ngx_buf_size(b) \
|
||||
(ngx_buf_in_memory(b) ? (off_t) (b->last - b->pos): \
|
||||
|
|
|
@ -27,7 +27,7 @@ static ngx_command_t ngx_conf_commands[] = {
|
|||
|
||||
|
||||
ngx_module_t ngx_conf_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
NULL, /* module context */
|
||||
ngx_conf_commands, /* module directives */
|
||||
NGX_CONF_MODULE, /* module type */
|
||||
|
@ -336,7 +336,7 @@ ngx_conf_read_token(ngx_conf_t *cf)
|
|||
{
|
||||
u_char *start, ch, *src, *dst;
|
||||
int len;
|
||||
int found, need_space, last_space, sharp_comment;
|
||||
int found, need_space, last_space, sharp_comment, variable;
|
||||
int quoted, s_quoted, d_quoted;
|
||||
ssize_t n;
|
||||
ngx_str_t *word;
|
||||
|
@ -346,6 +346,7 @@ ngx_conf_read_token(ngx_conf_t *cf)
|
|||
need_space = 0;
|
||||
last_space = 1;
|
||||
sharp_comment = 0;
|
||||
variable = 0;
|
||||
quoted = s_quoted = d_quoted = 0;
|
||||
|
||||
cf->args->nelts = 0;
|
||||
|
@ -492,11 +493,22 @@ ngx_conf_read_token(ngx_conf_t *cf)
|
|||
}
|
||||
|
||||
} else {
|
||||
if (ch == '{' && variable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
variable = 0;
|
||||
|
||||
if (ch == '\\') {
|
||||
quoted = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '$') {
|
||||
variable = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (d_quoted) {
|
||||
if (ch == '"') {
|
||||
d_quoted = 0;
|
||||
|
@ -801,6 +813,45 @@ ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_conf_set_table_elt_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
char *p = conf;
|
||||
|
||||
ngx_str_t *value;
|
||||
ngx_array_t **a;
|
||||
ngx_table_elt_t *elt;
|
||||
ngx_conf_post_t *post;
|
||||
|
||||
a = (ngx_array_t **) (p + cmd->offset);
|
||||
|
||||
if (*a == NULL) {
|
||||
*a = ngx_array_create(cf->pool, 4, sizeof(ngx_table_elt_t));
|
||||
if (*a == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
elt = ngx_array_push(*a);
|
||||
if (elt == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
elt->hash = 0;
|
||||
elt->key = value[1];
|
||||
elt->value = value[2];
|
||||
|
||||
if (cmd->post) {
|
||||
post = cmd->post;
|
||||
return post->post_handler(cf, post, elt);
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
#define NGX_CONF_BLOCK_DONE 2
|
||||
#define NGX_CONF_FILE_DONE 3
|
||||
|
||||
#define NGX_MODULE 0, 0
|
||||
#define NGX_MODULE_V1 0, 0, 1, 0, 0
|
||||
|
||||
#define NGX_CORE_MODULE 0x45524F43 /* "CORE" */
|
||||
#define NGX_CONF_MODULE 0x464E4F43 /* "CONF" */
|
||||
|
@ -100,6 +100,10 @@ struct ngx_open_file_s {
|
|||
struct ngx_module_s {
|
||||
ngx_uint_t ctx_index;
|
||||
ngx_uint_t index;
|
||||
ngx_uint_t version;
|
||||
ngx_uint_t spare0;
|
||||
ngx_uint_t spare1;
|
||||
|
||||
void *ctx;
|
||||
ngx_command_t *commands;
|
||||
ngx_uint_t type;
|
||||
|
@ -280,6 +284,8 @@ void ngx_cdecl ngx_conf_log_error(ngx_uint_t level, ngx_conf_t *cf,
|
|||
|
||||
char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
char *ngx_conf_set_table_elt_slot(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
|
|
|
@ -517,7 +517,7 @@ ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle)
|
|||
ngx_old_cycles.nalloc = n;
|
||||
ngx_old_cycles.pool = ngx_temp_pool;
|
||||
|
||||
ngx_cleaner_event.event_handler = ngx_clean_old_cycles;
|
||||
ngx_cleaner_event.handler = ngx_clean_old_cycles;
|
||||
ngx_cleaner_event.log = cycle->log;
|
||||
ngx_cleaner_event.data = &dumb;
|
||||
dumb.fd = (ngx_socket_t) -1;
|
||||
|
|
|
@ -38,8 +38,10 @@ ngx_int_t
|
|||
ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool,
|
||||
int persistent)
|
||||
{
|
||||
ngx_err_t err;
|
||||
ngx_atomic_uint_t n;
|
||||
ngx_err_t err;
|
||||
ngx_atomic_uint_t n;
|
||||
ngx_pool_cleanup_file_t *cln;
|
||||
|
||||
|
||||
file->name.len = path->name.len + 1 + path->len + NGX_ATOMIC_T_LEN;
|
||||
|
||||
|
@ -74,6 +76,20 @@ ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool,
|
|||
"temp fd:%d", file->fd);
|
||||
|
||||
if (file->fd != NGX_INVALID_FILE) {
|
||||
cln = ngx_palloc(pool, sizeof(ngx_pool_cleanup_file_t));
|
||||
if (cln == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cln->fd = file->fd;
|
||||
cln->name = file->name.data;
|
||||
cln->log = pool->log;
|
||||
|
||||
if (ngx_pool_cleanup_add(pool, ngx_pool_cleanup_file, cln) == NULL)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,11 +9,20 @@
|
|||
|
||||
|
||||
ngx_int_t
|
||||
ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names)
|
||||
ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names, ngx_uint_t nelts)
|
||||
{
|
||||
u_char *p;
|
||||
ngx_str_t *n, *bucket;
|
||||
ngx_uint_t i, key, size, best, *test, buckets, min_buckets;
|
||||
ngx_str_t *name, *bucket;
|
||||
ngx_uint_t i, n, key, size, best, *test, buckets, min_buckets;
|
||||
|
||||
if (nelts == 0) {
|
||||
for (name = (ngx_str_t *) names;
|
||||
name->len;
|
||||
name = (ngx_str_t *) ((char *) name + hash->bucket_size))
|
||||
{
|
||||
nelts++;
|
||||
}
|
||||
}
|
||||
|
||||
test = ngx_alloc(hash->max_size * sizeof(ngx_uint_t), pool->log);
|
||||
if (test == NULL) {
|
||||
|
@ -34,14 +43,14 @@ ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names)
|
|||
test[i] = 0;
|
||||
}
|
||||
|
||||
for (n = (ngx_str_t *) names;
|
||||
n->len;
|
||||
n = (ngx_str_t *) ((char *) n + hash->bucket_size))
|
||||
for (n = 0, name = (ngx_str_t *) names;
|
||||
n < nelts;
|
||||
n++, name = (ngx_str_t *) ((char *) name + hash->bucket_size))
|
||||
{
|
||||
key = 0;
|
||||
|
||||
for (i = 0; i < n->len; i++) {
|
||||
key += ngx_tolower(n->data[i]);
|
||||
for (i = 0; i < name->len; i++) {
|
||||
key += ngx_tolower(name->data[i]);
|
||||
}
|
||||
|
||||
key %= size;
|
||||
|
@ -57,7 +66,7 @@ ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names)
|
|||
}
|
||||
}
|
||||
|
||||
if (n->len == 0) {
|
||||
if (n == nelts) {
|
||||
if (min_buckets > buckets) {
|
||||
min_buckets = buckets;
|
||||
best = size;
|
||||
|
@ -91,14 +100,14 @@ ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names)
|
|||
test[i] = 0;
|
||||
}
|
||||
|
||||
for (n = (ngx_str_t *) names;
|
||||
n->len;
|
||||
n = (ngx_str_t *) ((char *) n + hash->bucket_size))
|
||||
for (n = 0, name = (ngx_str_t *) names;
|
||||
n < nelts;
|
||||
n++, name = (ngx_str_t *) ((char *) name + hash->bucket_size))
|
||||
{
|
||||
key = 0;
|
||||
|
||||
for (i = 0; i < n->len; i++) {
|
||||
key += ngx_tolower(n->data[i]);
|
||||
for (i = 0; i < name->len; i++) {
|
||||
key += ngx_tolower(name->data[i]);
|
||||
}
|
||||
|
||||
key %= best;
|
||||
|
@ -122,21 +131,21 @@ ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names)
|
|||
}
|
||||
}
|
||||
|
||||
for (n = (ngx_str_t *) names;
|
||||
n->len;
|
||||
n = (ngx_str_t *) ((char *) n + hash->bucket_size))
|
||||
for (n = 0, name = (ngx_str_t *) names;
|
||||
n < nelts;
|
||||
n++, name = (ngx_str_t *) ((char *) name + hash->bucket_size))
|
||||
{
|
||||
key = 0;
|
||||
|
||||
for (i = 0; i < n->len; i++) {
|
||||
key += ngx_tolower(n->data[i]);
|
||||
for (i = 0; i < name->len; i++) {
|
||||
key += ngx_tolower(name->data[i]);
|
||||
}
|
||||
|
||||
key %= best;
|
||||
|
||||
if (hash->bucket_limit == 1) {
|
||||
p = (u_char *) hash->buckets + key * hash->bucket_size;
|
||||
ngx_memcpy(p, n, hash->bucket_size);
|
||||
ngx_memcpy(p, name, hash->bucket_size);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -147,7 +156,7 @@ ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names)
|
|||
bucket->len &= 0x7fffffff;
|
||||
}
|
||||
|
||||
ngx_memcpy(bucket, n, hash->bucket_size);
|
||||
ngx_memcpy(bucket, name, hash->bucket_size);
|
||||
bucket->len |= 0x80000000;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,8 @@ typedef struct {
|
|||
} ngx_table_elt_t;
|
||||
|
||||
|
||||
ngx_int_t ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names);
|
||||
ngx_int_t ngx_hash_init(ngx_hash_t *hash, ngx_pool_t *pool, void *names,
|
||||
ngx_uint_t nelts);
|
||||
|
||||
|
||||
#endif /* _NGX_HASH_H_INCLUDED_ */
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
*/
|
||||
|
||||
|
||||
static ngx_inline size_t ngx_sprint_uchar(u_char *text, u_char c, size_t len)
|
||||
static
|
||||
ngx_inline size_t ngx_sprint_uchar(u_char *text, u_char c, size_t len)
|
||||
{
|
||||
size_t n;
|
||||
ngx_uint_t c1, c2;
|
||||
|
@ -65,8 +66,8 @@ static ngx_inline size_t ngx_sprint_uchar(u_char *text, u_char c, size_t len)
|
|||
|
||||
/* AF_INET only */
|
||||
|
||||
size_t ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text,
|
||||
size_t len)
|
||||
size_t
|
||||
ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text, size_t len)
|
||||
{
|
||||
u_char *p;
|
||||
size_t n;
|
||||
|
@ -119,7 +120,8 @@ size_t ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text,
|
|||
return n;
|
||||
}
|
||||
|
||||
size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len)
|
||||
size_t
|
||||
ngx_inet_ntop(int family, void *addr, u_char *text, size_t len)
|
||||
{
|
||||
u_char *p;
|
||||
size_t n;
|
||||
|
@ -173,7 +175,8 @@ size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len)
|
|||
|
||||
/* AF_INET only */
|
||||
|
||||
ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr)
|
||||
ngx_int_t
|
||||
ngx_ptocidr(ngx_str_t *text, void *cidr)
|
||||
{
|
||||
ngx_int_t m;
|
||||
ngx_uint_t i;
|
||||
|
@ -217,7 +220,8 @@ ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr)
|
|||
}
|
||||
|
||||
|
||||
ngx_peers_t *ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u)
|
||||
ngx_peers_t *
|
||||
ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u)
|
||||
{
|
||||
char *err;
|
||||
u_char *host;
|
||||
|
@ -392,7 +396,8 @@ ngx_peers_t *ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u)
|
|||
}
|
||||
|
||||
|
||||
char *ngx_inet_parse_host_port(ngx_inet_upstream_t *u)
|
||||
char *
|
||||
ngx_inet_parse_host_port(ngx_inet_upstream_t *u)
|
||||
{
|
||||
size_t i;
|
||||
ngx_int_t port;
|
||||
|
|
|
@ -33,7 +33,7 @@ static ngx_core_module_t ngx_errlog_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_errlog_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_errlog_module_ctx, /* module context */
|
||||
ngx_errlog_commands, /* module directives */
|
||||
NGX_CORE_MODULE, /* module type */
|
||||
|
|
|
@ -49,7 +49,7 @@ ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
|
|||
#if (NGX_SENDFILE_LIMIT)
|
||||
&& !(in->buf->in_file && in->buf->file_last > NGX_SENDFILE_LIMIT)
|
||||
#endif
|
||||
&& (!ngx_output_chain_need_to_copy(ctx, in->buf)))
|
||||
&& !ngx_output_chain_need_to_copy(ctx, in->buf))
|
||||
{
|
||||
return ctx->output_filter(ctx->filter_ctx, in);
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
|
|||
|
||||
size = ctx->bufs.size;
|
||||
|
||||
if (ctx->in->buf->last_buf) {
|
||||
if (ctx->in->buf->last_in_chain) {
|
||||
|
||||
if (bsize < (off_t) ctx->bufs.size) {
|
||||
|
||||
|
@ -202,6 +202,11 @@ ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
|
|||
}
|
||||
|
||||
if (out == NULL && last != NGX_NONE) {
|
||||
|
||||
if (ctx->in) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ ngx_create_pool(size_t size, ngx_log_t *log)
|
|||
p->next = NULL;
|
||||
p->large = NULL;
|
||||
p->chain = NULL;
|
||||
p->cleanup = NULL;
|
||||
p->log = log;
|
||||
|
||||
return p;
|
||||
|
@ -32,8 +33,15 @@ ngx_create_pool(size_t size, ngx_log_t *log)
|
|||
void
|
||||
ngx_destroy_pool(ngx_pool_t *pool)
|
||||
{
|
||||
ngx_pool_t *p, *n;
|
||||
ngx_pool_large_t *l;
|
||||
ngx_pool_t *p, *n;
|
||||
ngx_pool_large_t *l;
|
||||
ngx_pool_cleanup_t *c;
|
||||
|
||||
for (c = pool->cleanup; c; c = c->next) {
|
||||
if (c->handler) {
|
||||
c->handler(c->data);
|
||||
}
|
||||
}
|
||||
|
||||
for (l = pool->large; l; l = l->next) {
|
||||
|
||||
|
@ -197,6 +205,39 @@ ngx_pcalloc(ngx_pool_t *pool, size_t size)
|
|||
return p;
|
||||
}
|
||||
|
||||
|
||||
ngx_pool_cleanup_t *
|
||||
ngx_pool_cleanup_add(ngx_pool_t *p, ngx_pool_cleanup_pt handler, void *data)
|
||||
{
|
||||
ngx_pool_cleanup_t *c;
|
||||
|
||||
c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));
|
||||
if (c == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
c->handler = handler;
|
||||
c->data = data;
|
||||
c->next = p->cleanup;
|
||||
|
||||
p->cleanup = c;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_pool_cleanup_file(void *data)
|
||||
{
|
||||
ngx_pool_cleanup_file_t *c = data;
|
||||
|
||||
if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
|
||||
ngx_close_file_n " \"%s\" failed", c->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
static void *
|
||||
|
|
|
@ -22,24 +22,44 @@
|
|||
#define NGX_DEFAULT_POOL_SIZE (16 * 1024)
|
||||
|
||||
|
||||
typedef void (*ngx_pool_cleanup_pt)(void *data);
|
||||
|
||||
typedef struct ngx_pool_cleanup_s ngx_pool_cleanup_t;
|
||||
|
||||
struct ngx_pool_cleanup_s {
|
||||
ngx_pool_cleanup_pt handler;
|
||||
void *data;
|
||||
ngx_pool_cleanup_t *next;
|
||||
};
|
||||
|
||||
|
||||
typedef struct ngx_pool_large_s ngx_pool_large_t;
|
||||
|
||||
struct ngx_pool_large_s {
|
||||
ngx_pool_large_t *next;
|
||||
void *alloc;
|
||||
ngx_pool_large_t *next;
|
||||
void *alloc;
|
||||
};
|
||||
|
||||
|
||||
struct ngx_pool_s {
|
||||
u_char *last;
|
||||
u_char *end;
|
||||
ngx_chain_t *chain;
|
||||
ngx_pool_t *next;
|
||||
ngx_pool_large_t *large;
|
||||
ngx_log_t *log;
|
||||
u_char *last;
|
||||
u_char *end;
|
||||
ngx_chain_t *chain;
|
||||
ngx_pool_t *next;
|
||||
ngx_pool_large_t *large;
|
||||
ngx_pool_cleanup_t *cleanup;
|
||||
ngx_log_t *log;
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_fd_t fd;
|
||||
u_char *name;
|
||||
ngx_log_t *log;
|
||||
} ngx_pool_cleanup_file_t;
|
||||
|
||||
|
||||
|
||||
void *ngx_alloc(size_t size, ngx_log_t *log);
|
||||
void *ngx_calloc(size_t size, ngx_log_t *log);
|
||||
|
||||
|
@ -51,4 +71,9 @@ void *ngx_pcalloc(ngx_pool_t *pool, size_t size);
|
|||
ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p);
|
||||
|
||||
|
||||
ngx_pool_cleanup_t *ngx_pool_cleanup_add(ngx_pool_t *p,
|
||||
ngx_pool_cleanup_pt handler, void *data);
|
||||
void ngx_pool_cleanup_file(void *data);
|
||||
|
||||
|
||||
#endif /* _NGX_PALLOC_H_INCLUDED_ */
|
||||
|
|
|
@ -12,8 +12,9 @@ ngx_epoch_msec_t ngx_elapsed_msec;
|
|||
ngx_epoch_msec_t ngx_old_elapsed_msec;
|
||||
ngx_epoch_msec_t ngx_start_msec;
|
||||
|
||||
ngx_int_t ngx_gmtoff;
|
||||
|
||||
static ngx_tm_t ngx_cached_gmtime;
|
||||
static ngx_int_t ngx_gmtoff;
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -53,6 +53,7 @@ extern ngx_epoch_msec_t ngx_elapsed_msec;
|
|||
*/
|
||||
extern ngx_epoch_msec_t ngx_old_elapsed_msec;
|
||||
|
||||
extern ngx_int_t ngx_gmtoff;
|
||||
|
||||
|
||||
#endif /* _NGX_TIMES_H_INCLUDED_ */
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
#undef sun
|
||||
|
||||
|
||||
ngx_peers_t *ngx_unix_upstream_parse(ngx_conf_t *cf,
|
||||
ngx_unix_domain_upstream_t *u)
|
||||
ngx_peers_t *
|
||||
ngx_unix_upstream_parse(ngx_conf_t *cf, ngx_unix_domain_upstream_t *u)
|
||||
{
|
||||
size_t len;
|
||||
ngx_uint_t i;
|
||||
|
|
|
@ -54,7 +54,7 @@ ngx_event_module_t ngx_aio_module_ctx = {
|
|||
};
|
||||
|
||||
ngx_module_t ngx_aio_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_aio_module_ctx, /* module context */
|
||||
NULL, /* module directives */
|
||||
NGX_EVENT_MODULE, /* module type */
|
||||
|
|
|
@ -91,7 +91,7 @@ ngx_event_module_t ngx_devpoll_module_ctx = {
|
|||
};
|
||||
|
||||
ngx_module_t ngx_devpoll_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_devpoll_module_ctx, /* module context */
|
||||
ngx_devpoll_commands, /* module directives */
|
||||
NGX_EVENT_MODULE, /* module type */
|
||||
|
@ -511,7 +511,7 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle)
|
|||
wev->ready = 1;
|
||||
|
||||
if (!ngx_threaded && !ngx_accept_mutex_held) {
|
||||
wev->event_handler(wev);
|
||||
wev->handler(wev);
|
||||
|
||||
} else {
|
||||
ngx_post_event(wev);
|
||||
|
@ -530,7 +530,7 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle)
|
|||
rev->ready = 1;
|
||||
|
||||
if (!ngx_threaded && !ngx_accept_mutex_held) {
|
||||
rev->event_handler(rev);
|
||||
rev->handler(rev);
|
||||
|
||||
} else if (!rev->accept) {
|
||||
ngx_post_event(rev);
|
||||
|
@ -538,7 +538,7 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle)
|
|||
} else if (ngx_accept_disabled <= 0) {
|
||||
ngx_mutex_unlock(ngx_posted_events_mutex);
|
||||
|
||||
c->read->event_handler(rev);
|
||||
c->read->handler(rev);
|
||||
|
||||
if (ngx_accept_disabled > 0) {
|
||||
ngx_accept_mutex_unlock();
|
||||
|
|
|
@ -121,7 +121,7 @@ ngx_event_module_t ngx_epoll_module_ctx = {
|
|||
};
|
||||
|
||||
ngx_module_t ngx_epoll_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_epoll_module_ctx, /* module context */
|
||||
ngx_epoll_commands, /* module directives */
|
||||
NGX_EVENT_MODULE, /* module type */
|
||||
|
@ -573,7 +573,7 @@ ngx_epoll_process_events(ngx_cycle_t *cycle)
|
|||
wev->ready = 1;
|
||||
|
||||
if (!ngx_accept_mutex_held) {
|
||||
wev->event_handler(wev);
|
||||
wev->handler(wev);
|
||||
|
||||
} else {
|
||||
ngx_post_event(wev);
|
||||
|
@ -600,7 +600,7 @@ ngx_epoll_process_events(ngx_cycle_t *cycle)
|
|||
rev->ready = 1;
|
||||
|
||||
if (!ngx_threaded && !ngx_accept_mutex_held) {
|
||||
rev->event_handler(rev);
|
||||
rev->handler(rev);
|
||||
|
||||
} else if (!rev->accept) {
|
||||
ngx_post_event(rev);
|
||||
|
@ -609,7 +609,7 @@ ngx_epoll_process_events(ngx_cycle_t *cycle)
|
|||
|
||||
ngx_mutex_unlock(ngx_posted_events_mutex);
|
||||
|
||||
rev->event_handler(rev);
|
||||
rev->handler(rev);
|
||||
|
||||
if (ngx_accept_disabled > 0) {
|
||||
ngx_accept_mutex_unlock();
|
||||
|
|
|
@ -69,7 +69,7 @@ ngx_event_module_t ngx_iocp_module_ctx = {
|
|||
};
|
||||
|
||||
ngx_module_t ngx_iocp_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_iocp_module_ctx, /* module context */
|
||||
ngx_iocp_commands, /* module directives */
|
||||
NGX_EVENT_MODULE, /* module type */
|
||||
|
@ -294,9 +294,9 @@ ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle)
|
|||
ev->available = bytes;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
||||
"iocp event handler: %p", ev->event_handler);
|
||||
"iocp event handler: %p", ev->handler);
|
||||
|
||||
ev->event_handler(ev);
|
||||
ev->handler(ev);
|
||||
|
||||
if (timer != INFINITE && delta) {
|
||||
ngx_event_expire_timers((ngx_msec_t) delta);
|
||||
|
|
|
@ -94,7 +94,7 @@ ngx_event_module_t ngx_kqueue_module_ctx = {
|
|||
};
|
||||
|
||||
ngx_module_t ngx_kqueue_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_kqueue_module_ctx, /* module context */
|
||||
ngx_kqueue_commands, /* module directives */
|
||||
NGX_EVENT_MODULE, /* module type */
|
||||
|
@ -192,11 +192,13 @@ ngx_kqueue_init(ngx_cycle_t *cycle)
|
|||
ngx_event_actions = ngx_kqueue_module_ctx.actions;
|
||||
|
||||
ngx_event_flags = NGX_USE_ONESHOT_EVENT
|
||||
#if 1
|
||||
#if (NGX_HAVE_CLEAR_EVENT)
|
||||
|NGX_USE_CLEAR_EVENT
|
||||
#else
|
||||
|NGX_USE_LEVEL_EVENT
|
||||
#endif
|
||||
#endif
|
||||
#if (NGX_HAVE_LOWAT_EVENT)
|
||||
|NGX_USE_LOWAT_EVENT
|
||||
#endif
|
||||
|
@ -615,6 +617,10 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle)
|
|||
ngx_kqueue_dump_event(ev->log, &event_list[i]);
|
||||
}
|
||||
|
||||
if (ev->oneshot) {
|
||||
ev->active = 0;
|
||||
}
|
||||
|
||||
#if (NGX_THREADS)
|
||||
|
||||
if (ngx_threaded && !ev->accept) {
|
||||
|
@ -663,7 +669,7 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle)
|
|||
}
|
||||
|
||||
if (!ngx_threaded && !ngx_accept_mutex_held) {
|
||||
ev->event_handler(ev);
|
||||
ev->handler(ev);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -678,7 +684,7 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle)
|
|||
|
||||
ngx_mutex_unlock(ngx_posted_events_mutex);
|
||||
|
||||
ev->event_handler(ev);
|
||||
ev->handler(ev);
|
||||
|
||||
if (ngx_accept_disabled > 0) {
|
||||
ngx_accept_mutex_unlock();
|
||||
|
|
|
@ -50,7 +50,7 @@ ngx_event_module_t ngx_poll_module_ctx = {
|
|||
};
|
||||
|
||||
ngx_module_t ngx_poll_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_poll_module_ctx, /* module context */
|
||||
NULL, /* module directives */
|
||||
NGX_EVENT_MODULE, /* module type */
|
||||
|
@ -536,7 +536,7 @@ ngx_poll_process_events(ngx_cycle_t *cycle)
|
|||
}
|
||||
}
|
||||
|
||||
ev->event_handler(ev);
|
||||
ev->handler(ev);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -553,7 +553,7 @@ ngx_poll_process_events(ngx_cycle_t *cycle)
|
|||
|
||||
ngx_mutex_unlock(ngx_posted_events_mutex);
|
||||
|
||||
ev->event_handler(ev);
|
||||
ev->handler(ev);
|
||||
|
||||
if (ngx_accept_disabled > 0) {
|
||||
lock = 0;
|
||||
|
|
|
@ -118,7 +118,7 @@ ngx_event_module_t ngx_rtsig_module_ctx = {
|
|||
};
|
||||
|
||||
ngx_module_t ngx_rtsig_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_rtsig_module_ctx, /* module context */
|
||||
ngx_rtsig_commands, /* module directives */
|
||||
NGX_EVENT_MODULE, /* module type */
|
||||
|
@ -461,11 +461,11 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle)
|
|||
rev->ready = 1;
|
||||
|
||||
if (!ngx_threaded && !ngx_accept_mutex_held) {
|
||||
rev->event_handler(rev);
|
||||
rev->handler(rev);
|
||||
|
||||
} else if (rev->accept) {
|
||||
if (ngx_accept_disabled <= 0) {
|
||||
rev->event_handler(rev);
|
||||
rev->handler(rev);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -495,7 +495,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle)
|
|||
wev->ready = 1;
|
||||
|
||||
if (!ngx_threaded && !ngx_accept_mutex_held) {
|
||||
wev->event_handler(wev);
|
||||
wev->handler(wev);
|
||||
|
||||
} else {
|
||||
ngx_post_event(wev);
|
||||
|
@ -598,11 +598,11 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle)
|
|||
|
||||
events = 0;
|
||||
|
||||
if (c->read->active && c->read->event_handler) {
|
||||
if (c->read->active && c->read->handler) {
|
||||
events |= POLLIN;
|
||||
}
|
||||
|
||||
if (c->write->active && c->write->event_handler) {
|
||||
if (c->write->active && c->write->handler) {
|
||||
events |= POLLOUT;
|
||||
}
|
||||
|
||||
|
@ -652,7 +652,7 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle)
|
|||
|
||||
if (rev->active
|
||||
&& !rev->closed
|
||||
&& rev->event_handler
|
||||
&& rev->handler
|
||||
&& (overflow_list[i].revents
|
||||
& (POLLIN|POLLERR|POLLHUP|POLLNVAL)))
|
||||
{
|
||||
|
@ -664,7 +664,7 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle)
|
|||
|
||||
} else {
|
||||
rev->ready = 1;
|
||||
rev->event_handler(rev);
|
||||
rev->handler(rev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -672,7 +672,7 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle)
|
|||
|
||||
if (wev->active
|
||||
&& !wev->closed
|
||||
&& wev->event_handler
|
||||
&& wev->handler
|
||||
&& (overflow_list[i].revents
|
||||
& (POLLOUT|POLLERR|POLLHUP|POLLNVAL)))
|
||||
{
|
||||
|
@ -684,7 +684,7 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle)
|
|||
|
||||
} else {
|
||||
wev->ready = 1;
|
||||
wev->event_handler(wev);
|
||||
wev->handler(wev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ ngx_event_module_t ngx_select_module_ctx = {
|
|||
};
|
||||
|
||||
ngx_module_t ngx_select_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_select_module_ctx, /* module context */
|
||||
NULL, /* module directives */
|
||||
NGX_EVENT_MODULE, /* module type */
|
||||
|
@ -540,7 +540,7 @@ ngx_select_process_events(ngx_cycle_t *cycle)
|
|||
}
|
||||
}
|
||||
|
||||
ev->event_handler(ev);
|
||||
ev->handler(ev);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -557,7 +557,7 @@ ngx_select_process_events(ngx_cycle_t *cycle)
|
|||
|
||||
ngx_mutex_unlock(ngx_posted_events_mutex);
|
||||
|
||||
ev->event_handler(ev);
|
||||
ev->handler(ev);
|
||||
|
||||
if (ngx_accept_disabled > 0) {
|
||||
lock = 0;
|
||||
|
|
|
@ -24,10 +24,10 @@ static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle);
|
|||
static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
|
||||
static char *ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
void *conf);
|
||||
static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
static char *ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
void *conf);
|
||||
|
||||
static void *ngx_event_create_conf(ngx_cycle_t *cycle);
|
||||
static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf);
|
||||
|
@ -91,7 +91,7 @@ static ngx_core_module_t ngx_events_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_events_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_events_module_ctx, /* module context */
|
||||
ngx_events_commands, /* module directives */
|
||||
NGX_CORE_MODULE, /* module type */
|
||||
|
@ -163,7 +163,7 @@ ngx_event_module_t ngx_event_core_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_event_core_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_event_core_module_ctx, /* module context */
|
||||
ngx_event_core_commands, /* module directives */
|
||||
NGX_EVENT_MODULE, /* module type */
|
||||
|
@ -172,7 +172,143 @@ ngx_module_t ngx_event_core_module = {
|
|||
};
|
||||
|
||||
|
||||
static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle)
|
||||
ngx_int_t
|
||||
ngx_handle_read_event(ngx_event_t *rev, u_int flags)
|
||||
{
|
||||
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
||||
|
||||
/* kqueue, epoll */
|
||||
|
||||
if (!rev->active && !rev->ready) {
|
||||
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
} else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
|
||||
|
||||
/* select, poll, /dev/poll */
|
||||
|
||||
if (!rev->active && !rev->ready) {
|
||||
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (rev->active && (rev->ready || (flags & NGX_CLOSE_EVENT))) {
|
||||
if (ngx_del_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT | flags)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
} else if (ngx_event_flags & NGX_USE_ONESHOT_EVENT) {
|
||||
|
||||
/* event ports */
|
||||
|
||||
if (!rev->active) {
|
||||
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_ONESHOT_EVENT)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
/* aio, iocp, rtsig */
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_handle_write_event(ngx_event_t *wev, size_t lowat)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
|
||||
if (lowat) {
|
||||
c = (ngx_connection_t *) wev->data;
|
||||
|
||||
if (ngx_send_lowat(c, lowat) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
||||
|
||||
/* kqueue, epoll */
|
||||
|
||||
if (!wev->active && !wev->ready) {
|
||||
if (ngx_add_event(wev, NGX_WRITE_EVENT,
|
||||
NGX_CLEAR_EVENT | (lowat ? NGX_LOWAT_EVENT : 0))
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
} else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
|
||||
|
||||
/* select, poll, /dev/poll */
|
||||
|
||||
if (!wev->active && !wev->ready) {
|
||||
if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (wev->active && wev->ready) {
|
||||
if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
} else if (ngx_event_flags & NGX_USE_ONESHOT_EVENT) {
|
||||
|
||||
/* event ports */
|
||||
|
||||
if (!wev->active) {
|
||||
if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
/* aio, iocp, rtsig */
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_event_module_init(ngx_cycle_t *cycle)
|
||||
{
|
||||
#if !(NGX_WIN32)
|
||||
|
||||
|
@ -248,7 +384,8 @@ static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle)
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle)
|
||||
static ngx_int_t
|
||||
ngx_event_process_init(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_uint_t m, i;
|
||||
ngx_socket_t fd;
|
||||
|
@ -417,7 +554,7 @@ static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle)
|
|||
#if (NGX_WIN32)
|
||||
|
||||
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
|
||||
rev->event_handler = ngx_event_acceptex;
|
||||
rev->handler = ngx_event_acceptex;
|
||||
|
||||
if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
|
@ -431,7 +568,7 @@ static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle)
|
|||
}
|
||||
|
||||
} else {
|
||||
rev->event_handler = ngx_event_accept;
|
||||
rev->handler = ngx_event_accept;
|
||||
|
||||
if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
|
@ -440,7 +577,7 @@ static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle)
|
|||
|
||||
#else
|
||||
|
||||
rev->event_handler = ngx_event_accept;
|
||||
rev->handler = ngx_event_accept;
|
||||
|
||||
if (ngx_accept_mutex) {
|
||||
continue;
|
||||
|
@ -464,7 +601,8 @@ static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle)
|
|||
}
|
||||
|
||||
|
||||
ngx_int_t ngx_send_lowat(ngx_connection_t *c, size_t lowat)
|
||||
ngx_int_t
|
||||
ngx_send_lowat(ngx_connection_t *c, size_t lowat)
|
||||
{
|
||||
int sndlowat;
|
||||
|
||||
|
@ -497,7 +635,8 @@ ngx_int_t ngx_send_lowat(ngx_connection_t *c, size_t lowat)
|
|||
}
|
||||
|
||||
|
||||
static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
static char *
|
||||
ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
char *rv;
|
||||
void ***ctx;
|
||||
|
@ -574,8 +713,8 @@ static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
static char *ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
static char *
|
||||
ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_event_conf_t *ecf = conf;
|
||||
|
||||
|
@ -600,7 +739,8 @@ static char *ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
}
|
||||
|
||||
|
||||
static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
static char *
|
||||
ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_event_conf_t *ecf = conf;
|
||||
|
||||
|
@ -662,8 +802,8 @@ static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
static char *ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
static char *
|
||||
ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
#if (NGX_DEBUG)
|
||||
ngx_event_conf_t *ecf = conf;
|
||||
|
@ -709,7 +849,8 @@ static char *ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
}
|
||||
|
||||
|
||||
static void *ngx_event_create_conf(ngx_cycle_t *cycle)
|
||||
static void *
|
||||
ngx_event_create_conf(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_event_conf_t *ecf;
|
||||
|
||||
|
@ -739,7 +880,8 @@ static void *ngx_event_create_conf(ngx_cycle_t *cycle)
|
|||
}
|
||||
|
||||
|
||||
static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
|
||||
static char *
|
||||
ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
|
||||
{
|
||||
ngx_event_conf_t *ecf = conf;
|
||||
|
||||
|
@ -874,7 +1016,8 @@ static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
|
|||
}
|
||||
|
||||
|
||||
static char *ngx_accept_mutex_check(ngx_conf_t *cf, void *post, void *data)
|
||||
static char *
|
||||
ngx_accept_mutex_check(ngx_conf_t *cf, void *post, void *data)
|
||||
{
|
||||
#if !(NGX_HAVE_ATOMIC_OPS)
|
||||
|
||||
|
|
|
@ -113,8 +113,7 @@ struct ngx_event_s {
|
|||
unsigned available:1;
|
||||
#endif
|
||||
|
||||
/* TODO rename to handler */
|
||||
ngx_event_handler_pt event_handler;
|
||||
ngx_event_handler_pt handler;
|
||||
|
||||
|
||||
#if (NGX_HAVE_AIO)
|
||||
|
@ -474,6 +473,10 @@ ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle);
|
|||
ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle);
|
||||
|
||||
|
||||
ngx_int_t ngx_handle_read_event(ngx_event_t *rev, u_int flags);
|
||||
ngx_int_t ngx_handle_write_event(ngx_event_t *wev, size_t lowat);
|
||||
|
||||
|
||||
#if (NGX_WIN32)
|
||||
void ngx_event_acceptex(ngx_event_t *ev);
|
||||
int ngx_event_post_acceptex(ngx_listening_t *ls, int n);
|
||||
|
@ -496,158 +499,4 @@ ngx_int_t ngx_send_lowat(ngx_connection_t *c, size_t lowat);
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
static ngx_inline ngx_int_t ngx_handle_read_event(ngx_event_t *rev, u_int flags)
|
||||
{
|
||||
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
||||
|
||||
/* kqueue, epoll */
|
||||
|
||||
if (!rev->active && !rev->ready) {
|
||||
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT)
|
||||
== NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
} else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
|
||||
|
||||
/* select, poll, /dev/poll */
|
||||
|
||||
if (!rev->active && !rev->ready) {
|
||||
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (rev->active && (rev->ready || (flags & NGX_CLOSE_EVENT))) {
|
||||
if (ngx_del_event(rev, NGX_READ_EVENT, flags) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* aio, iocp, rtsig */
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_inline ngx_int_t ngx_handle_level_read_event(ngx_event_t *rev)
|
||||
{
|
||||
if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
|
||||
if (!rev->active && !rev->ready) {
|
||||
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (rev->active && rev->ready) {
|
||||
if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_inline ngx_int_t ngx_handle_write_event(ngx_event_t *wev,
|
||||
size_t lowat)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
|
||||
if (lowat) {
|
||||
c = (ngx_connection_t *) wev->data;
|
||||
|
||||
if (ngx_send_lowat(c, lowat) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
||||
|
||||
/* kqueue, epoll */
|
||||
|
||||
if (!wev->active && !wev->ready) {
|
||||
if (ngx_add_event(wev, NGX_WRITE_EVENT,
|
||||
NGX_CLEAR_EVENT | (lowat ? NGX_LOWAT_EVENT : 0))
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
} else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
|
||||
|
||||
/* select, poll, /dev/poll */
|
||||
|
||||
if (!wev->active && !wev->ready) {
|
||||
if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (wev->active && wev->ready) {
|
||||
if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* aio, iocp, rtsig */
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_inline ngx_int_t ngx_handle_level_write_event(ngx_event_t *wev)
|
||||
{
|
||||
if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
|
||||
if (!wev->active && !wev->ready) {
|
||||
if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (wev->active && wev->ready) {
|
||||
if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif /* _NGX_EVENT_H_INCLUDED_ */
|
||||
|
|
|
@ -106,7 +106,9 @@ ngx_event_accept(ngx_event_t *ev)
|
|||
return;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ALERT, ev->log, err,
|
||||
ngx_log_error((err == NGX_ECONNABORTED) ? NGX_LOG_CRIT:
|
||||
NGX_LOG_ALERT,
|
||||
ev->log, err,
|
||||
"accept() on %V failed", &ls->listening->addr_text);
|
||||
|
||||
if (err == NGX_ECONNABORTED) {
|
||||
|
|
|
@ -132,7 +132,7 @@ int ngx_event_post_acceptex(ngx_listening_t *ls, int n)
|
|||
|
||||
rev->ovlp.event = rev;
|
||||
wev->ovlp.event = wev;
|
||||
rev->event_handler = ngx_event_acceptex;
|
||||
rev->handler = ngx_event_acceptex;
|
||||
|
||||
rev->data = c;
|
||||
wev->data = c;
|
||||
|
|
|
@ -43,7 +43,7 @@ ngx_int_t ngx_event_busy_lock(ngx_event_busy_lock_t *bl,
|
|||
} else if (ctx->timer && bl->waiting < bl->max_waiting) {
|
||||
bl->waiting++;
|
||||
ngx_add_timer(ctx->event, ctx->timer);
|
||||
ctx->event->event_handler = ngx_event_busy_lock_handler;
|
||||
ctx->event->handler = ngx_event_busy_lock_handler;
|
||||
|
||||
if (bl->events) {
|
||||
bl->last->next = ctx;
|
||||
|
@ -92,7 +92,7 @@ ngx_int_t ngx_event_busy_lock_cachable(ngx_event_busy_lock_t *bl,
|
|||
if (ctx->timer && bl->waiting < bl->max_waiting) {
|
||||
bl->waiting++;
|
||||
ngx_add_timer(ctx->event, ctx->timer);
|
||||
ctx->event->event_handler = ngx_event_busy_lock_handler;
|
||||
ctx->event->handler = ngx_event_busy_lock_handler;
|
||||
|
||||
if (bl->events == NULL) {
|
||||
bl->events = ctx;
|
||||
|
@ -296,7 +296,7 @@ static void ngx_event_busy_lock_handler(ngx_event_t *ev)
|
|||
|
||||
ngx_mutex_unlock(ngx_posted_events_mutex);
|
||||
|
||||
ev->event_handler = ngx_event_busy_lock_posted_handler;
|
||||
ev->handler = ngx_event_busy_lock_posted_handler;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -114,6 +114,9 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
|||
|
||||
s = ngx_socket(peer->sockaddr->sa_family, SOCK_STREAM, 0);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0,
|
||||
"socket %d", s);
|
||||
|
||||
if (s == -1) {
|
||||
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
|
||||
ngx_socket_n " failed");
|
||||
|
|
|
@ -170,7 +170,7 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n)
|
|||
|
||||
if (c->ssl->saved_write_handler) {
|
||||
|
||||
c->write->event_handler = c->ssl->saved_write_handler;
|
||||
c->write->handler = c->ssl->saved_write_handler;
|
||||
c->ssl->saved_write_handler = NULL;
|
||||
c->write->ready = 1;
|
||||
|
||||
|
@ -223,8 +223,8 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n)
|
|||
*/
|
||||
|
||||
if (c->ssl->saved_write_handler == NULL) {
|
||||
c->ssl->saved_write_handler = c->write->event_handler;
|
||||
c->write->event_handler = ngx_ssl_write_handler;
|
||||
c->ssl->saved_write_handler = c->write->handler;
|
||||
c->write->handler = ngx_ssl_write_handler;
|
||||
}
|
||||
|
||||
return NGX_AGAIN;
|
||||
|
@ -253,7 +253,7 @@ ngx_ssl_write_handler(ngx_event_t *wev)
|
|||
ngx_connection_t *c;
|
||||
|
||||
c = wev->data;
|
||||
c->read->event_handler(c->read);
|
||||
c->read->handler(c->read);
|
||||
}
|
||||
|
||||
|
||||
|
@ -405,7 +405,7 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
|
|||
if (n > 0) {
|
||||
if (c->ssl->saved_read_handler) {
|
||||
|
||||
c->read->event_handler = c->ssl->saved_read_handler;
|
||||
c->read->handler = c->ssl->saved_read_handler;
|
||||
c->ssl->saved_read_handler = NULL;
|
||||
c->read->ready = 1;
|
||||
|
||||
|
@ -460,8 +460,8 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
|
|||
*/
|
||||
|
||||
if (c->ssl->saved_read_handler == NULL) {
|
||||
c->ssl->saved_read_handler = c->read->event_handler;
|
||||
c->read->event_handler = ngx_ssl_read_handler;
|
||||
c->ssl->saved_read_handler = c->read->handler;
|
||||
c->read->handler = ngx_ssl_read_handler;
|
||||
}
|
||||
|
||||
return NGX_AGAIN;
|
||||
|
@ -482,7 +482,7 @@ ngx_ssl_read_handler(ngx_event_t *rev)
|
|||
ngx_connection_t *c;
|
||||
|
||||
c = rev->data;
|
||||
c->write->event_handler(c->write);
|
||||
c->write->handler(c->write);
|
||||
}
|
||||
|
||||
|
||||
|
@ -592,3 +592,12 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
|
|||
|
||||
ngx_log_error(level, log, err, "%s)", errstr);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_ssl_cleanup_ctx(void *data)
|
||||
{
|
||||
SSL_CTX *ctx = data;
|
||||
|
||||
SSL_CTX_free(ctx);
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in,
|
|||
ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c);
|
||||
void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
|
||||
char *fmt, ...);
|
||||
void ngx_ssl_cleanup_ctx(void *data);
|
||||
|
||||
|
||||
#endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */
|
||||
|
|
|
@ -64,13 +64,13 @@ ngx_int_t ngx_event_pipe(ngx_event_pipe_t *p, int do_write)
|
|||
}
|
||||
}
|
||||
|
||||
if (p->downstream->fd != -1) {
|
||||
if (p->downstream->fd != -1 && p->downstream->data == p->output_ctx) {
|
||||
wev = p->downstream->write;
|
||||
if (ngx_handle_write_event(wev, p->send_lowat) == NGX_ERROR) {
|
||||
return NGX_ABORT;
|
||||
}
|
||||
|
||||
if (wev->active) {
|
||||
if (wev->active && !wev->ready && !wev->delayed) {
|
||||
ngx_add_timer(wev, p->send_timeout);
|
||||
}
|
||||
}
|
||||
|
@ -180,8 +180,10 @@ static ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
|
|||
chain->buf = b;
|
||||
chain->next = NULL;
|
||||
|
||||
} else if (!p->cachable && p->downstream->write->ready) {
|
||||
|
||||
} else if (!p->cachable
|
||||
&& p->downstream->data == p->output_ctx
|
||||
&& p->downstream->write->ready)
|
||||
{
|
||||
/*
|
||||
* if the bufs are not needed to be saved in a cache and
|
||||
* a downstream is ready then write the bufs to a downstream
|
||||
|
@ -409,10 +411,18 @@ static ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
|
|||
|
||||
/* pass the p->out and p->in chains to the output filter */
|
||||
|
||||
for (cl = p->busy; cl; cl = cl->next) {
|
||||
cl->buf->recycled = 0;
|
||||
}
|
||||
|
||||
if (p->out) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
|
||||
"pipe write downstream flush out");
|
||||
|
||||
for (cl = p->out; cl; cl = cl->next) {
|
||||
cl->buf->recycled = 0;
|
||||
}
|
||||
|
||||
if (p->output_filter(p->output_ctx, p->out) == NGX_ERROR) {
|
||||
p->downstream_error = 1;
|
||||
return ngx_event_pipe_drain_chains(p);
|
||||
|
@ -425,6 +435,10 @@ static ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
|
|||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
|
||||
"pipe write downstream flush in");
|
||||
|
||||
for (cl = p->in; cl; cl = cl->next) {
|
||||
cl->buf->recycled = 0;
|
||||
}
|
||||
|
||||
if (p->output_filter(p->output_ctx, p->in) == NGX_ERROR) {
|
||||
p->downstream_error = 1;
|
||||
return ngx_event_pipe_drain_chains(p);
|
||||
|
@ -442,7 +456,9 @@ static ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
|
|||
break;
|
||||
}
|
||||
|
||||
if (!p->downstream->write->ready) {
|
||||
if (p->downstream->data != p->output_ctx
|
||||
|| !p->downstream->write->ready)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ void ngx_event_process_posted(ngx_cycle_t *cycle)
|
|||
|
||||
ngx_delete_posted_event(ev);
|
||||
|
||||
ev->event_handler(ev);
|
||||
ev->handler(ev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ ngx_int_t ngx_event_thread_process_posted(ngx_cycle_t *cycle)
|
|||
|
||||
ngx_mutex_unlock(ngx_posted_events_mutex);
|
||||
|
||||
ev->event_handler(ev);
|
||||
ev->handler(ev);
|
||||
|
||||
if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
|
|
|
@ -156,7 +156,7 @@ ngx_event_expire_timers(ngx_msec_t timer)
|
|||
|
||||
ev->timedout = 1;
|
||||
|
||||
ev->event_handler(ev);
|
||||
ev->handler(ev);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,8 @@ static ngx_command_t ngx_http_access_commands[] = {
|
|||
|
||||
|
||||
ngx_http_module_t ngx_http_access_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -68,7 +69,7 @@ ngx_http_module_t ngx_http_access_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_access_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_access_module_ctx, /* module context */
|
||||
ngx_http_access_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
|
|
@ -60,7 +60,8 @@ static ngx_command_t ngx_http_auth_basic_commands[] = {
|
|||
|
||||
|
||||
ngx_http_module_t ngx_http_auth_basic_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -74,7 +75,7 @@ ngx_http_module_t ngx_http_auth_basic_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_auth_basic_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_auth_basic_module_ctx, /* module context */
|
||||
ngx_http_auth_basic_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -327,6 +328,7 @@ ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
|
|||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.www_authenticate->hash = 1;
|
||||
r->headers_out.www_authenticate->key.len = sizeof("WWW-Authenticate") - 1;
|
||||
r->headers_out.www_authenticate->key.data = (u_char *) "WWW-Authenticate";
|
||||
r->headers_out.www_authenticate->value = *realm;
|
||||
|
|
|
@ -63,7 +63,8 @@ static ngx_command_t ngx_http_autoindex_commands[] = {
|
|||
|
||||
|
||||
ngx_http_module_t ngx_http_autoindex_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -77,7 +78,7 @@ ngx_http_module_t ngx_http_autoindex_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_autoindex_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_autoindex_module_ctx, /* module context */
|
||||
ngx_http_autoindex_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -419,16 +420,8 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
|
|||
|
||||
r->headers_out.status = NGX_HTTP_OK;
|
||||
r->headers_out.content_length_n = b->last - b->pos;
|
||||
|
||||
r->headers_out.content_type = ngx_list_push(&r->headers_out.headers);
|
||||
if (r->headers_out.content_type == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.content_type->key.len = 0;
|
||||
r->headers_out.content_type->key.data = NULL;
|
||||
r->headers_out.content_type->value.len = sizeof("text/html") - 1;
|
||||
r->headers_out.content_type->value.data = (u_char *) "text/html";
|
||||
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);
|
||||
|
||||
|
@ -436,10 +429,12 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
|
|||
return rc;
|
||||
}
|
||||
|
||||
if (!r->main) {
|
||||
if (r->main == NULL) {
|
||||
b->last_buf = 1;
|
||||
}
|
||||
|
||||
b->last_in_chain = 1;
|
||||
|
||||
out.buf = b;
|
||||
out.next = NULL;
|
||||
|
||||
|
|
|
@ -106,7 +106,8 @@ static ngx_command_t ngx_http_charset_filter_commands[] = {
|
|||
|
||||
|
||||
static ngx_http_module_t ngx_http_charset_filter_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
ngx_http_charset_create_main_conf, /* create main configuration */
|
||||
ngx_http_charset_init_main_conf, /* init main configuration */
|
||||
|
@ -120,7 +121,7 @@ static ngx_http_module_t ngx_http_charset_filter_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_charset_filter_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_charset_filter_module_ctx, /* module context */
|
||||
ngx_http_charset_filter_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -148,19 +149,18 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
|
|||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
if (r->headers_out.content_type == NULL) {
|
||||
if (r->headers_out.content_type.len == 0) {
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
if (ngx_strncasecmp(r->headers_out.content_type->value.data,
|
||||
"text/", 5) != 0
|
||||
&& ngx_strncasecmp(r->headers_out.content_type->value.data,
|
||||
"application/x-javascript", 24) != 0)
|
||||
if (ngx_strncasecmp(r->headers_out.content_type.data, "text/", 5) != 0
|
||||
&& ngx_strncasecmp(r->headers_out.content_type.data,
|
||||
"application/x-javascript", 24) != 0)
|
||||
{
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
if (ngx_strstr(r->headers_out.content_type->value.data, "charset") != NULL)
|
||||
if (ngx_strstr(r->headers_out.content_type.data, "charset") != NULL)
|
||||
{
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@ static ngx_int_t ngx_http_chunked_filter_init(ngx_cycle_t *cycle);
|
|||
|
||||
|
||||
static ngx_http_module_t ngx_http_chunked_filter_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -27,7 +28,7 @@ static ngx_http_module_t ngx_http_chunked_filter_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_chunked_filter_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_chunked_filter_module_ctx, /* module context */
|
||||
NULL, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -43,7 +44,7 @@ static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
|
|||
static ngx_int_t
|
||||
ngx_http_chunked_header_filter(ngx_http_request_t *r)
|
||||
{
|
||||
if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) {
|
||||
if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED || r->main) {
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -34,7 +34,8 @@ static ngx_command_t ngx_http_geo_commands[] = {
|
|||
|
||||
|
||||
static ngx_http_module_t ngx_http_geo_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -48,7 +49,7 @@ static ngx_http_module_t ngx_http_geo_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_geo_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_geo_module_ctx, /* module context */
|
||||
ngx_http_geo_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -110,7 +111,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
name.data++;
|
||||
}
|
||||
|
||||
var = ngx_http_add_variable(cf, &name, 1);
|
||||
var = ngx_http_add_variable(cf, &name, 0);
|
||||
if (var == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
|
|
@ -207,7 +207,8 @@ static ngx_command_t ngx_http_gzip_filter_commands[] = {
|
|||
|
||||
|
||||
static ngx_http_module_t ngx_http_gzip_filter_module_ctx = {
|
||||
ngx_http_gzip_add_log_formats, /* pre conf */
|
||||
ngx_http_gzip_add_log_formats, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -221,7 +222,7 @@ static ngx_http_module_t ngx_http_gzip_filter_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_gzip_filter_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_gzip_filter_module_ctx, /* module context */
|
||||
ngx_http_gzip_filter_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -257,6 +258,11 @@ struct gztrailer {
|
|||
#endif
|
||||
|
||||
|
||||
static ngx_str_t ngx_http_gzip_no_cache = ngx_string("no-cache");
|
||||
static ngx_str_t ngx_http_gzip_no_store = ngx_string("no-store");
|
||||
static ngx_str_t ngx_http_gzip_private = ngx_string("private");
|
||||
|
||||
|
||||
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
|
||||
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
|
||||
|
||||
|
@ -276,8 +282,9 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
|
|||
&& r->headers_out.status != NGX_HTTP_FORBIDDEN
|
||||
&& r->headers_out.status != NGX_HTTP_NOT_FOUND)
|
||||
|| r->header_only
|
||||
|| r->main
|
||||
|| r->http_version < conf->http_version
|
||||
|| r->headers_out.content_type == NULL
|
||||
|| r->headers_out.content_type.len == 0
|
||||
|| (r->headers_out.content_encoding
|
||||
&& r->headers_out.content_encoding->value.len)
|
||||
|| r->headers_in.accept_encoding == NULL
|
||||
|
@ -294,8 +301,8 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
|
|||
type = conf->types->elts;
|
||||
|
||||
for (i = 0; i < conf->types->nelts; i++) {
|
||||
if (r->headers_out.content_type->value.len >= type[i].name.len
|
||||
&& ngx_strncasecmp(r->headers_out.content_type->value.data,
|
||||
if (r->headers_out.content_type.len >= type[i].name.len
|
||||
&& ngx_strncasecmp(r->headers_out.content_type.data,
|
||||
type[i].name.data, type[i].name.len) == 0)
|
||||
{
|
||||
found = 1;
|
||||
|
@ -346,6 +353,7 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.content_encoding->hash = 1;
|
||||
r->headers_out.content_encoding->key.len = sizeof("Content-Encoding") - 1;
|
||||
r->headers_out.content_encoding->key.data = (u_char *) "Content-Encoding";
|
||||
r->headers_out.content_encoding->value.len = sizeof("gzip") - 1;
|
||||
|
@ -353,10 +361,12 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
|
|||
|
||||
ctx->length = r->headers_out.content_length_n;
|
||||
r->headers_out.content_length_n = -1;
|
||||
|
||||
if (r->headers_out.content_length) {
|
||||
r->headers_out.content_length->key.len = 0;
|
||||
r->headers_out.content_length->hash = 0;
|
||||
r->headers_out.content_length = NULL;
|
||||
}
|
||||
|
||||
r->filter_need_in_memory = 1;
|
||||
|
||||
return ngx_http_next_header_filter(r);
|
||||
|
@ -404,22 +414,25 @@ ngx_http_gzip_proxied(ngx_http_request_t *r, ngx_http_gzip_conf_t *conf)
|
|||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
if (r->headers_out.cache_control) {
|
||||
if (r->headers_out.cache_control.elts) {
|
||||
|
||||
if ((conf->proxied & NGX_HTTP_GZIP_PROXIED_NO_CACHE)
|
||||
&& ngx_strstr(r->headers_out.cache_control->value.data, "no-cache"))
|
||||
&& ngx_http_parse_multi_header_lines(&r->headers_out.cache_control,
|
||||
&ngx_http_gzip_no_cache, NULL) >= 0)
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if ((conf->proxied & NGX_HTTP_GZIP_PROXIED_NO_STORE)
|
||||
&& ngx_strstr(r->headers_out.cache_control->value.data, "no-store"))
|
||||
&& ngx_http_parse_multi_header_lines(&r->headers_out.cache_control,
|
||||
&ngx_http_gzip_no_store, NULL) >= 0)
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if ((conf->proxied & NGX_HTTP_GZIP_PROXIED_PRIVATE)
|
||||
&& ngx_strstr(r->headers_out.cache_control->value.data, "private"))
|
||||
&& ngx_http_parse_multi_header_lines(&r->headers_out.cache_control,
|
||||
&ngx_http_gzip_private, NULL) >= 0)
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -484,8 +497,8 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
* and do not wait while a whole response will be sent to a client.
|
||||
*
|
||||
* 8K is for zlib deflate_state, it takes
|
||||
* * 5816 bytes on x86 and sparc64 (32-bit mode)
|
||||
* * 5920 bytes on amd64 and sparc64
|
||||
* *) 5816 bytes on i386 and sparc64 (32-bit mode)
|
||||
* *) 5920 bytes on amd64 and sparc64
|
||||
*/
|
||||
|
||||
ctx->allocated = 8192 + (1 << (wbits + 2)) + (1 << (memlevel + 9));
|
||||
|
@ -696,7 +709,8 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
|
||||
if (ctx->flush == Z_SYNC_FLUSH) {
|
||||
|
||||
ctx->out_buf->flush = 0;
|
||||
ctx->zstream.avail_out = 0;
|
||||
ctx->out_buf->flush = 1;
|
||||
ctx->flush = Z_NO_FLUSH;
|
||||
|
||||
cl = ngx_alloc_chain_link(r->pool);
|
||||
|
|
|
@ -41,7 +41,8 @@ static ngx_command_t ngx_http_headers_filter_commands[] = {
|
|||
|
||||
|
||||
static ngx_http_module_t ngx_http_headers_filter_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -55,7 +56,7 @@ static ngx_http_module_t ngx_http_headers_filter_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_headers_filter_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_headers_filter_module_ctx, /* module context */
|
||||
ngx_http_headers_filter_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -71,10 +72,11 @@ static ngx_int_t
|
|||
ngx_http_headers_filter(ngx_http_request_t *r)
|
||||
{
|
||||
size_t len;
|
||||
ngx_uint_t i;
|
||||
ngx_table_elt_t *expires, *cc;
|
||||
ngx_http_headers_conf_t *conf;
|
||||
|
||||
if (r->headers_out.status != NGX_HTTP_OK) {
|
||||
if (r->headers_out.status != NGX_HTTP_OK || r->main) {
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
|
@ -82,28 +84,43 @@ ngx_http_headers_filter(ngx_http_request_t *r)
|
|||
|
||||
if (conf->expires != NGX_HTTP_EXPIRES_OFF) {
|
||||
|
||||
expires = ngx_list_push(&r->headers_out.headers);
|
||||
expires = r->headers_out.expires;
|
||||
|
||||
if (expires == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
||||
expires = ngx_list_push(&r->headers_out.headers);
|
||||
if (expires == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.expires = expires;
|
||||
|
||||
expires->hash = 1;
|
||||
expires->key.len = sizeof("Expires") - 1;
|
||||
expires->key.data = (u_char *) "Expires";
|
||||
}
|
||||
|
||||
r->headers_out.expires = expires;
|
||||
|
||||
cc = ngx_list_push(&r->headers_out.headers);
|
||||
if (cc == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.cache_control = cc;
|
||||
|
||||
len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT");
|
||||
|
||||
expires->key.len = sizeof("Expires") - 1;
|
||||
expires->key.data = (u_char *) "Expires";
|
||||
expires->value.len = len - 1;
|
||||
|
||||
cc->key.len = sizeof("Cache-Control") - 1;
|
||||
cc->key.data = (u_char *) "Cache-Control";
|
||||
cc = r->headers_out.cache_control.elts;
|
||||
|
||||
if (cc == NULL) {
|
||||
|
||||
cc = ngx_list_push(&r->headers_out.headers);
|
||||
if (cc == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cc->hash = 1;
|
||||
cc->key.len = sizeof("Cache-Control") - 1;
|
||||
cc->key.data = (u_char *) "Cache-Control";
|
||||
|
||||
} else {
|
||||
for (i = 1; i < r->headers_out.cache_control.nelts; i++) {
|
||||
cc[i].hash = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->expires == NGX_HTTP_EXPIRES_EPOCH) {
|
||||
expires->value.data = (u_char *) "Thu, 01 Jan 1970 00:00:01 GMT";
|
||||
|
|
|
@ -10,42 +10,52 @@
|
|||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t indices;
|
||||
ngx_str_t name;
|
||||
ngx_array_t *lengths;
|
||||
ngx_array_t *values;
|
||||
} ngx_http_index_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t *indices; /* array of ngx_http_index_t */
|
||||
size_t max_index_len;
|
||||
ngx_http_cache_hash_t *index_cache;
|
||||
} ngx_http_index_loc_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_uint_t index;
|
||||
u_char *last;
|
||||
ngx_str_t path;
|
||||
ngx_str_t redirect;
|
||||
ngx_http_cache_entry_t *cache;
|
||||
ngx_uint_t tested; /* unsigned tested:1 */
|
||||
ngx_uint_t current;
|
||||
size_t allocated;
|
||||
|
||||
u_char *path;
|
||||
ngx_str_t uri;
|
||||
ngx_str_t index;
|
||||
|
||||
ngx_uint_t tested; /* unsigned tested:1 */
|
||||
} ngx_http_index_ctx_t;
|
||||
|
||||
|
||||
#define NGX_HTTP_DEFAULT_INDEX "index.html"
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_index_alloc(ngx_http_request_t *r, size_t size,
|
||||
ngx_http_index_ctx_t *ctx, ngx_http_core_loc_conf_t *clcf);
|
||||
static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
|
||||
ngx_http_index_ctx_t *ctx);
|
||||
ngx_http_index_ctx_t *ctx);
|
||||
static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
|
||||
ngx_http_index_ctx_t *ctx, ngx_err_t err);
|
||||
ngx_http_index_ctx_t *ctx, ngx_err_t err);
|
||||
|
||||
static ngx_int_t ngx_http_index_init(ngx_cycle_t *cycle);
|
||||
static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_index_merge_loc_conf(ngx_conf_t *cf,
|
||||
void *parent, void *child);
|
||||
void *parent, void *child);
|
||||
static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
void *conf);
|
||||
|
||||
|
||||
static ngx_command_t ngx_http_index_commands[] = {
|
||||
|
||||
{ ngx_string("index"),
|
||||
NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
|
||||
ngx_http_index_set_index,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
|
@ -67,7 +77,8 @@ static ngx_command_t ngx_http_index_commands[] = {
|
|||
|
||||
|
||||
ngx_http_module_t ngx_http_index_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -81,7 +92,7 @@ ngx_http_module_t ngx_http_index_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_index_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_index_module_ctx, /* module context */
|
||||
ngx_http_index_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -100,21 +111,24 @@ ngx_module_t ngx_http_index_module = {
|
|||
* that path contains the usual file in place of the directory.
|
||||
*/
|
||||
|
||||
static ngx_int_t ngx_http_index_handler(ngx_http_request_t *r)
|
||||
static ngx_int_t
|
||||
ngx_http_index_handler(ngx_http_request_t *r)
|
||||
{
|
||||
u_char *name;
|
||||
ngx_fd_t fd;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *index;
|
||||
ngx_err_t err;
|
||||
ngx_log_t *log;
|
||||
ngx_http_index_ctx_t *ctx;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_index_loc_conf_t *ilcf;
|
||||
#if (NGX_HTTP_CACHE0)
|
||||
/* crc must be in ctx !! */
|
||||
uint32_t crc;
|
||||
#endif
|
||||
u_char *name;
|
||||
size_t len;
|
||||
ngx_fd_t fd;
|
||||
ngx_int_t rc;
|
||||
ngx_err_t err;
|
||||
ngx_log_t *log;
|
||||
ngx_uint_t i;
|
||||
ngx_http_index_t *index;
|
||||
ngx_http_index_ctx_t *ctx;
|
||||
ngx_pool_cleanup_file_t *cln;
|
||||
ngx_http_script_code_pt code;
|
||||
ngx_http_script_engine_t e;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_index_loc_conf_t *ilcf;
|
||||
ngx_http_script_len_code_pt lcode;
|
||||
|
||||
if (r->uri.data[r->uri.len - 1] != '/') {
|
||||
return NGX_DECLINED;
|
||||
|
@ -128,8 +142,8 @@ static ngx_int_t ngx_http_index_handler(ngx_http_request_t *r)
|
|||
log = r->connection->log;
|
||||
|
||||
/*
|
||||
* we use context because the handler supports an async file opening
|
||||
* and thus can be called several times
|
||||
* we use context because the handler supports an async file opening,
|
||||
* and may be called several times
|
||||
*/
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
@ -144,115 +158,71 @@ static ngx_int_t ngx_http_index_handler(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
ngx_http_set_ctx(r, ctx, ngx_http_index_module);
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
||||
if (ilcf->index_cache) {
|
||||
ctx->cache = ngx_http_cache_get(ilcf->index_cache, NULL,
|
||||
&r->uri, &crc);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
|
||||
"http index cache get: %p", ctx->cache);
|
||||
|
||||
if (ctx->cache && !ctx->cache->expired) {
|
||||
|
||||
ctx->cache->accessed = ngx_cached_time;
|
||||
|
||||
ctx->redirect.len = ctx->cache->data.value.len;
|
||||
ctx->redirect.data = ngx_palloc(r->pool, ctx->redirect.len + 1);
|
||||
if (ctx->redirect.data == NULL) {
|
||||
ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(ctx->redirect.data, ctx->cache->data.value.data,
|
||||
ctx->redirect.len + 1);
|
||||
ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
|
||||
|
||||
return ngx_http_internal_redirect(r, &ctx->redirect, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
ctx->path.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len
|
||||
+ ilcf->max_index_len
|
||||
- clcf->alias * clcf->name.len);
|
||||
if (ctx->path.data == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
ctx->redirect.data = ngx_cpymem(ctx->path.data, clcf->root.data,
|
||||
clcf->root.len);
|
||||
#endif
|
||||
|
||||
if (clcf->alias) {
|
||||
ctx->path.data = ngx_palloc(r->pool, clcf->root.len
|
||||
+ r->uri.len + 1 - clcf->name.len
|
||||
+ ilcf->max_index_len);
|
||||
if (ctx->path.data == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
ctx->redirect.data = ngx_palloc(r->pool, r->uri.len
|
||||
+ ilcf->max_index_len);
|
||||
if (ctx->redirect.data == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(ctx->path.data, clcf->root.data, clcf->root.len);
|
||||
|
||||
ctx->last = ngx_cpystrn(ctx->path.data + clcf->root.len,
|
||||
r->uri.data + clcf->name.len,
|
||||
r->uri.len + 1 - clcf->name.len);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* aliases usually have trailling "/",
|
||||
* set it in the start of the possible redirect
|
||||
*/
|
||||
|
||||
if (*ctx->redirect.data != '/') {
|
||||
ctx->redirect.data--;
|
||||
}
|
||||
#endif
|
||||
|
||||
} else {
|
||||
ctx->path.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len
|
||||
+ ilcf->max_index_len);
|
||||
if (ctx->path.data == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
ctx->redirect.data = ngx_cpymem(ctx->path.data, clcf->root.data,
|
||||
clcf->root.len);
|
||||
|
||||
ctx->last = ngx_cpystrn(ctx->redirect.data, r->uri.data,
|
||||
r->uri.len + 1);
|
||||
}
|
||||
}
|
||||
|
||||
ctx->path.len = ctx->last - ctx->path.data;
|
||||
index = ilcf->indices->elts;
|
||||
for (i = ctx->current; i < ilcf->indices->nelts; i++) {
|
||||
|
||||
index = ilcf->indices.elts;
|
||||
for (/* void */; ctx->index < ilcf->indices.nelts; ctx->index++) {
|
||||
if (index[i].lengths == NULL) {
|
||||
|
||||
if (index[ctx->index].data[0] == '/') {
|
||||
name = index[ctx->index].data;
|
||||
if (index[i].name.data[0] == '/') {
|
||||
return ngx_http_internal_redirect(r, &index[i].name, &r->args);
|
||||
}
|
||||
|
||||
len = ilcf->max_index_len;
|
||||
ctx->index.len = index[i].name.len;
|
||||
|
||||
} else {
|
||||
ngx_memcpy(ctx->last, index[ctx->index].data,
|
||||
index[ctx->index].len + 1);
|
||||
name = ctx->path.data;
|
||||
ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
|
||||
|
||||
e.ip = index[i].lengths->elts;
|
||||
e.request = r;
|
||||
|
||||
len = 1;
|
||||
|
||||
while (*(uintptr_t *) e.ip) {
|
||||
lcode = *(ngx_http_script_len_code_pt *) e.ip;
|
||||
len += lcode(&e);
|
||||
}
|
||||
|
||||
ctx->index.len = len;
|
||||
}
|
||||
|
||||
if (len > ctx->allocated) {
|
||||
if (ngx_http_index_alloc(r, len, ctx, clcf) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (index[i].values == NULL) {
|
||||
ngx_memcpy(ctx->index.data, index[i].name.data, ctx->index.len);
|
||||
|
||||
} else {
|
||||
e.ip = index[i].values->elts;
|
||||
e.pos = ctx->index.data;
|
||||
|
||||
while (*(uintptr_t *) e.ip) {
|
||||
code = *(ngx_http_script_code_pt *) e.ip;
|
||||
code((ngx_http_script_engine_t *) &e);
|
||||
}
|
||||
|
||||
if (*ctx->index.data == '/') {
|
||||
ctx->index.len--;
|
||||
return ngx_http_internal_redirect(r, &ctx->index, &r->args);
|
||||
}
|
||||
|
||||
*e.pos++ = '\0';
|
||||
}
|
||||
|
||||
name = ctx->path;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
|
||||
"open index \"%s\"", name);
|
||||
|
||||
fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN);
|
||||
|
||||
if (fd == (ngx_fd_t) NGX_AGAIN) {
|
||||
ctx->current = i;
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
|
@ -290,131 +260,268 @@ static ngx_int_t ngx_http_index_handler(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
|
||||
/* STUB: open file cache */
|
||||
|
||||
r->file.name.data = name;
|
||||
r->file.fd = fd;
|
||||
|
||||
if (index[ctx->index].data[0] == '/') {
|
||||
r->file.name.len = index[ctx->index].len;
|
||||
ctx->redirect.len = index[ctx->index].len;
|
||||
ctx->redirect.data = index[ctx->index].data;
|
||||
|
||||
} else {
|
||||
if (clcf->alias) {
|
||||
name = ngx_cpymem(ctx->redirect.data, r->uri.data, r->uri.len);
|
||||
ngx_memcpy(name, index[ctx->index].data,
|
||||
index[ctx->index].len + 1);
|
||||
}
|
||||
|
||||
ctx->redirect.len = r->uri.len + index[ctx->index].len;
|
||||
r->file.name.len = clcf->root.len + r->uri.len
|
||||
- clcf->alias * clcf->name.len
|
||||
+ index[ctx->index].len;
|
||||
cln = ngx_palloc(r->pool, sizeof(ngx_pool_cleanup_file_t));
|
||||
if (cln == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
/**/
|
||||
cln->fd = fd;
|
||||
cln->name = name;
|
||||
cln->log = r->pool->log;
|
||||
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
||||
if (ilcf->index_cache) {
|
||||
|
||||
if (ctx->cache) {
|
||||
if (ctx->redirect.len == ctx->cache->data.value.len
|
||||
&& ngx_memcmp(ctx->cache->data.value.data,
|
||||
ctx->redirect.data, ctx->redirect.len) == 0)
|
||||
{
|
||||
ctx->cache->accessed = ngx_cached_time;
|
||||
ctx->cache->updated = ngx_cached_time;
|
||||
ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
|
||||
|
||||
return ngx_http_internal_redirect(r, &ctx->redirect, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
ctx->redirect.len++;
|
||||
ctx->cache = ngx_http_cache_alloc(ilcf->index_cache, ctx->cache,
|
||||
NULL, &r->uri, crc,
|
||||
&ctx->redirect, log);
|
||||
ctx->redirect.len--;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
|
||||
"http index cache alloc: %p", ctx->cache);
|
||||
|
||||
if (ctx->cache) {
|
||||
ctx->cache->fd = NGX_INVALID_FILE;
|
||||
ctx->cache->accessed = ngx_cached_time;
|
||||
ctx->cache->last_modified = 0;
|
||||
ctx->cache->updated = ngx_cached_time;
|
||||
ctx->cache->memory = 1;
|
||||
ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
|
||||
}
|
||||
if (ngx_pool_cleanup_add(r->pool, ngx_pool_cleanup_file, cln) == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return ngx_http_internal_redirect(r, &ctx->redirect, NULL);
|
||||
if (clcf->alias) {
|
||||
name = ngx_cpymem(ctx->uri.data, r->uri.data, r->uri.len);
|
||||
ngx_memcpy(name, ctx->index.data, ctx->index.len - 1);
|
||||
}
|
||||
|
||||
ctx->uri.len = r->uri.len + ctx->index.len - 1;
|
||||
|
||||
return ngx_http_internal_redirect(r, &ctx->uri, &r->args);
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
|
||||
ngx_http_index_ctx_t *ctx)
|
||||
static ngx_int_t
|
||||
ngx_http_index_alloc(ngx_http_request_t *r, size_t size,
|
||||
ngx_http_index_ctx_t *ctx, ngx_http_core_loc_conf_t *clcf)
|
||||
{
|
||||
ngx_err_t err;
|
||||
ctx->allocated = size;
|
||||
|
||||
ctx->path.data[ctx->path.len - 1] = '\0';
|
||||
ctx->path.data[ctx->path.len] = '\0';
|
||||
if (!clcf->alias) {
|
||||
ctx->path = ngx_palloc(r->pool, clcf->root.len + r->uri.len + size);
|
||||
if (ctx->path == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ctx->uri.data = ngx_cpymem(ctx->path, clcf->root.data, clcf->root.len);
|
||||
|
||||
ctx->index.data = ngx_cpymem(ctx->uri.data, r->uri.data, r->uri.len);
|
||||
|
||||
} else {
|
||||
ctx->path = ngx_palloc(r->pool,
|
||||
clcf->root.len + r->uri.len - clcf->name.len + size);
|
||||
if (ctx->path == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ctx->uri.data = ngx_palloc(r->pool, r->uri.len + size);
|
||||
if (ctx->uri.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(ctx->path, clcf->root.data, clcf->root.len);
|
||||
|
||||
ctx->index.data = ngx_cpymem(ctx->path + clcf->root.len,
|
||||
r->uri.data + clcf->name.len,
|
||||
r->uri.len - clcf->name.len);
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx)
|
||||
{
|
||||
ngx_err_t err;
|
||||
ngx_file_info_t fi;
|
||||
|
||||
*(ctx->index.data - 1) = '\0';
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http check dir: \"%s\"", ctx->path.data);
|
||||
"http index check dir: \"%s\"", ctx->path);
|
||||
|
||||
if (ngx_file_info(ctx->path.data, &r->file.info) == -1) {
|
||||
if (ngx_file_info(ctx->path, &fi) == -1) {
|
||||
|
||||
err = ngx_errno;
|
||||
|
||||
if (err == NGX_ENOENT) {
|
||||
ctx->path.data[ctx->path.len - 1] = '/';
|
||||
*(ctx->index.data - 1) = '/';
|
||||
return ngx_http_index_error(r, ctx, err);
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
|
||||
ngx_file_info_n " \"%s\" failed", ctx->path.data);
|
||||
ngx_file_info_n " \"%s\" failed", ctx->path);
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
ctx->path.data[ctx->path.len - 1] = '/';
|
||||
*(ctx->index.data - 1) = '/';
|
||||
|
||||
if (ngx_is_dir(&r->file.info)) {
|
||||
if (ngx_is_dir(&fi)) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
/* THINK: not reached ??? */
|
||||
return ngx_http_index_error(r, ctx, 0);
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
"\"%s\" is not a directory", ctx->path);
|
||||
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
|
||||
ngx_http_index_ctx_t *ctx, ngx_err_t err)
|
||||
static ngx_int_t
|
||||
ngx_http_index_error(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx,
|
||||
ngx_err_t err)
|
||||
{
|
||||
if (err == NGX_EACCES) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
|
||||
"\"%s\" is forbidden", ctx->path.data);
|
||||
"\"%s\" is forbidden", ctx->path);
|
||||
|
||||
return NGX_HTTP_FORBIDDEN;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
|
||||
"\"%s\" is not found", ctx->path.data);
|
||||
"\"%s\" is not found", ctx->path);
|
||||
|
||||
return NGX_HTTP_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_index_init(ngx_cycle_t *cycle)
|
||||
static void *
|
||||
ngx_http_index_create_loc_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_index_loc_conf_t *conf;
|
||||
|
||||
conf = ngx_palloc(cf->pool, sizeof(ngx_http_index_loc_conf_t));
|
||||
if (conf == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
conf->indices = NULL;
|
||||
conf->max_index_len = 1;
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_index_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
{
|
||||
ngx_http_index_loc_conf_t *prev = parent;
|
||||
ngx_http_index_loc_conf_t *conf = child;
|
||||
|
||||
ngx_http_index_t *index;
|
||||
|
||||
if (conf->indices == NULL) {
|
||||
conf->indices = prev->indices;
|
||||
conf->max_index_len = prev->max_index_len;
|
||||
}
|
||||
|
||||
if (conf->indices == NULL) {
|
||||
conf->indices = ngx_array_create(cf->pool, 1, sizeof(ngx_http_index_t));
|
||||
if (conf->indices == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
index = ngx_array_push(conf->indices);
|
||||
if (index == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
index->name.len = sizeof(NGX_HTTP_DEFAULT_INDEX);
|
||||
index->name.data = (u_char *) NGX_HTTP_DEFAULT_INDEX;
|
||||
index->lengths = NULL;
|
||||
index->values = NULL;
|
||||
|
||||
conf->max_index_len = sizeof(NGX_HTTP_DEFAULT_INDEX);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: warn about duplicate indices */
|
||||
|
||||
static char *
|
||||
ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_index_loc_conf_t *ilcf = conf;
|
||||
|
||||
ngx_uint_t i, n;
|
||||
ngx_str_t *value;
|
||||
ngx_http_index_t *index;
|
||||
ngx_http_script_compile_t sc;
|
||||
|
||||
if (ilcf->indices == NULL) {
|
||||
ilcf->indices = ngx_array_create(cf->pool, 2, sizeof(ngx_http_index_t));
|
||||
if (ilcf->indices == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
for (i = 1; i < cf->args->nelts; i++) {
|
||||
if (value[i].data[0] == '/' && i != cf->args->nelts - 1) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"only the last index in \"index\" directive "
|
||||
"may be absolute");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (value[i].len == 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"index \"%V\" in \"index\" directive is invalid",
|
||||
&value[1]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
index = ngx_array_push(ilcf->indices);
|
||||
if (index == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
index->name.len = value[i].len;
|
||||
index->name.data = value[i].data;
|
||||
index->lengths = NULL;
|
||||
index->values = NULL;
|
||||
|
||||
n = ngx_http_script_variables_count(&value[i]);
|
||||
|
||||
if (n == 0) {
|
||||
index->name.len++;
|
||||
|
||||
if (ilcf->max_index_len != 0
|
||||
&& ilcf->max_index_len < index->name.len)
|
||||
{
|
||||
ilcf->max_index_len = index->name.len;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
|
||||
|
||||
sc.cf = cf;
|
||||
sc.source = &value[i];
|
||||
sc.lengths = &index->lengths;
|
||||
sc.values = &index->values;
|
||||
sc.variables = n;
|
||||
sc.complete_lengths = 1;
|
||||
sc.complete_values = 1;
|
||||
|
||||
if (ngx_http_script_compile(&sc) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ilcf->max_index_len = 0;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_index_init(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_http_handler_pt *h;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
@ -430,129 +537,3 @@ static ngx_int_t ngx_http_index_init(ngx_cycle_t *cycle)
|
|||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_index_loc_conf_t *conf;
|
||||
|
||||
conf = ngx_palloc(cf->pool, sizeof(ngx_http_index_loc_conf_t));
|
||||
if (conf == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_array_init(&conf->indices, cf->pool, 2, sizeof(ngx_str_t))
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
conf->max_index_len = 0;
|
||||
|
||||
conf->index_cache = NULL;
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: remove duplicate indices */
|
||||
|
||||
static char *ngx_http_index_merge_loc_conf(ngx_conf_t *cf,
|
||||
void *parent, void *child)
|
||||
{
|
||||
ngx_http_index_loc_conf_t *prev = parent;
|
||||
ngx_http_index_loc_conf_t *conf = child;
|
||||
|
||||
ngx_str_t *index;
|
||||
|
||||
if (conf->max_index_len == 0) {
|
||||
if (prev->max_index_len != 0) {
|
||||
ngx_memcpy(conf, prev, sizeof(ngx_http_index_loc_conf_t));
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
index = ngx_array_push(&conf->indices);
|
||||
if (index == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
index->len = sizeof(NGX_HTTP_DEFAULT_INDEX) - 1;
|
||||
index->data = (u_char *) NGX_HTTP_DEFAULT_INDEX;
|
||||
conf->max_index_len = sizeof(NGX_HTTP_DEFAULT_INDEX);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
if (prev->max_index_len != 0) {
|
||||
|
||||
prev_index = prev->indices.elts;
|
||||
for (i = 0; i < prev->indices.nelts; i++) {
|
||||
index = ngx_array_push(&conf->indices);
|
||||
if (index == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
index->len = prev_index[i].len;
|
||||
index->data = prev_index[i].data;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->max_index_len < prev->max_index_len) {
|
||||
conf->max_index_len = prev->max_index_len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (conf->index_cache == NULL) {
|
||||
conf->index_cache = prev->index_cache;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: warn about duplicate indices */
|
||||
|
||||
static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf)
|
||||
{
|
||||
ngx_http_index_loc_conf_t *ilcf = conf;
|
||||
|
||||
ngx_uint_t i;
|
||||
ngx_str_t *index, *value;
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (value[1].data[0] == '/' && ilcf->indices.nelts == 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"first index \"%V\" in \"%V\" directive "
|
||||
"must not be absolute",
|
||||
&value[1], &cmd->name);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
for (i = 1; i < cf->args->nelts; i++) {
|
||||
if (value[i].len == 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"index \"%V\" in \"%V\" directive is invalid",
|
||||
&value[1], &cmd->name);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
index = ngx_array_push(&ilcf->indices);
|
||||
if (index == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
index->len = value[i].len;
|
||||
index->data = value[i].data;
|
||||
|
||||
if (ilcf->max_index_len < index->len + 1) {
|
||||
ilcf->max_index_len = index->len + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,8 @@ static ngx_int_t ngx_http_not_modified_filter_init(ngx_cycle_t *cycle);
|
|||
|
||||
|
||||
static ngx_http_module_t ngx_http_not_modified_filter_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -28,7 +29,7 @@ static ngx_http_module_t ngx_http_not_modified_filter_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_not_modified_filter_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_not_modified_filter_module_ctx, /* module context */
|
||||
NULL, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -45,6 +46,7 @@ static ngx_int_t ngx_http_not_modified_header_filter(ngx_http_request_t *r)
|
|||
time_t ims;
|
||||
|
||||
if (r->headers_out.status != NGX_HTTP_OK
|
||||
|| r->main
|
||||
|| r->headers_in.if_modified_since == NULL
|
||||
|| r->headers_out.last_modified_time == -1)
|
||||
{
|
||||
|
@ -63,12 +65,11 @@ static ngx_int_t ngx_http_not_modified_header_filter(ngx_http_request_t *r)
|
|||
|
||||
if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) {
|
||||
r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
|
||||
r->headers_out.content_type->key.len = 0;
|
||||
r->headers_out.content_type = NULL;
|
||||
r->headers_out.content_type.len = 0;
|
||||
r->headers_out.content_length_n = -1;
|
||||
r->headers_out.content_length = NULL;
|
||||
#if 0
|
||||
r->headers_out.accept_ranges->key.len = 0;
|
||||
r->headers_out.accept_ranges->hash = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -54,7 +54,8 @@ static ngx_int_t ngx_http_range_body_filter_init(ngx_cycle_t *cycle);
|
|||
|
||||
|
||||
static ngx_http_module_t ngx_http_range_header_filter_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -68,7 +69,7 @@ static ngx_http_module_t ngx_http_range_header_filter_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_range_header_filter_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_range_header_filter_module_ctx, /* module context */
|
||||
NULL, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -78,7 +79,8 @@ ngx_module_t ngx_http_range_header_filter_module = {
|
|||
|
||||
|
||||
static ngx_http_module_t ngx_http_range_body_filter_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -92,7 +94,7 @@ static ngx_http_module_t ngx_http_range_body_filter_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_range_body_filter_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_range_body_filter_module_ctx, /* module context */
|
||||
NULL, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -120,6 +122,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||
|
||||
if (r->http_version < NGX_HTTP_VERSION_10
|
||||
|| r->headers_out.status != NGX_HTTP_OK
|
||||
|| r->main
|
||||
|| r->headers_out.content_length_n == -1
|
||||
|| !r->filter_allow_ranges)
|
||||
{
|
||||
|
@ -136,6 +139,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.accept_ranges->hash = 1;
|
||||
r->headers_out.accept_ranges->key.len = sizeof("Accept-Ranges") - 1;
|
||||
r->headers_out.accept_ranges->key.data = (u_char *) "Accept-Ranges";
|
||||
r->headers_out.accept_ranges->value.len = sizeof("bytes") - 1;
|
||||
|
@ -269,6 +273,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||
|
||||
r->headers_out.content_range = content_range;
|
||||
|
||||
content_range->hash = 1;
|
||||
content_range->key.len = sizeof("Content-Range") - 1;
|
||||
content_range->key.data = (u_char *) "Content-Range";
|
||||
|
||||
|
@ -303,6 +308,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||
|
||||
r->headers_out.content_range = content_range;
|
||||
|
||||
content_range->hash = 1;
|
||||
content_range->key.len = sizeof("Content-Range") - 1;
|
||||
content_range->key.data = (u_char *) "Content-Range";
|
||||
|
||||
|
@ -338,7 +344,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||
|
||||
len = sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN
|
||||
+ sizeof(CRLF "Content-Type: ") - 1
|
||||
+ r->headers_out.content_type->value.len
|
||||
+ r->headers_out.content_type.len
|
||||
+ sizeof(CRLF "Content-Range: bytes ") - 1;
|
||||
|
||||
if (r->headers_out.charset.len) {
|
||||
|
@ -366,7 +372,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||
"Content-Type: %V; charset=%V" CRLF
|
||||
"Content-Range: bytes ",
|
||||
boundary,
|
||||
&r->headers_out.content_type->value,
|
||||
&r->headers_out.content_type,
|
||||
&r->headers_out.charset)
|
||||
- ctx->boundary_header.data;
|
||||
|
||||
|
@ -378,26 +384,26 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
|
|||
"Content-Type: %V" CRLF
|
||||
"Content-Range: bytes ",
|
||||
boundary,
|
||||
&r->headers_out.content_type->value)
|
||||
&r->headers_out.content_type)
|
||||
- ctx->boundary_header.data;
|
||||
}
|
||||
|
||||
r->headers_out.content_type->value.data =
|
||||
ngx_palloc(r->pool,
|
||||
sizeof("Content-Type: multipart/byteranges; boundary=") - 1
|
||||
+ NGX_ATOMIC_T_LEN);
|
||||
r->headers_out.content_type.data =
|
||||
ngx_palloc(r->pool,
|
||||
sizeof("Content-Type: multipart/byteranges; boundary=") - 1
|
||||
+ NGX_ATOMIC_T_LEN);
|
||||
|
||||
if (r->headers_out.content_type->value.data == NULL) {
|
||||
if (r->headers_out.content_type.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/* "Content-Type: multipart/byteranges; boundary=0123456789" */
|
||||
|
||||
r->headers_out.content_type->value.len =
|
||||
ngx_sprintf(r->headers_out.content_type->value.data,
|
||||
r->headers_out.content_type.len =
|
||||
ngx_sprintf(r->headers_out.content_type.data,
|
||||
"multipart/byteranges; boundary=%0muA",
|
||||
boundary)
|
||||
- r->headers_out.content_type->value.data;
|
||||
- r->headers_out.content_type.data;
|
||||
|
||||
|
||||
/* the size of the last boundary CRLF "--0123456789--" CRLF */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,10 +16,13 @@
|
|||
|
||||
#define NGX_HTTP_SSI_ERROR 1
|
||||
|
||||
#define NGX_HTTP_SSI_DATE_LEN 2048
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_flag_t enable;
|
||||
ngx_flag_t silent_errors;
|
||||
ngx_flag_t ignore_recycled_buffers;
|
||||
|
||||
size_t min_file_chunk;
|
||||
size_t value_len;
|
||||
|
@ -50,6 +53,10 @@ typedef struct {
|
|||
size_t looked;
|
||||
|
||||
size_t value_len;
|
||||
|
||||
ngx_uint_t output; /* unsigned output:1; */
|
||||
|
||||
ngx_str_t timefmt;
|
||||
} ngx_http_ssi_ctx_t;
|
||||
|
||||
|
||||
|
@ -70,7 +77,8 @@ typedef struct {
|
|||
ngx_http_ssi_command_pt handler;
|
||||
ngx_http_ssi_param_t *params;
|
||||
|
||||
ngx_uint_t flush; /* unsigned flush:1; */
|
||||
unsigned conditional:1;
|
||||
unsigned flush:1;
|
||||
} ngx_http_ssi_command_t;
|
||||
|
||||
|
||||
|
@ -98,12 +106,28 @@ typedef enum {
|
|||
} ngx_http_ssi_state_e;
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_ssi_output(ngx_http_request_t *r,
|
||||
ngx_http_ssi_ctx_t *ctx);
|
||||
static ngx_int_t ngx_http_ssi_parse(ngx_http_request_t *r,
|
||||
ngx_http_ssi_ctx_t *ctx);
|
||||
|
||||
static ngx_int_t ngx_http_ssi_echo(ngx_http_request_t *r,
|
||||
ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
|
||||
static ngx_int_t ngx_http_ssi_config(ngx_http_request_t *r,
|
||||
ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
|
||||
static ngx_int_t ngx_http_ssi_include(ngx_http_request_t *r,
|
||||
ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
|
||||
static ngx_int_t ngx_http_ssi_if(ngx_http_request_t *r,
|
||||
ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
|
||||
static ngx_int_t ngx_http_ssi_else(ngx_http_request_t *r,
|
||||
ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
|
||||
static ngx_int_t ngx_http_ssi_endif(ngx_http_request_t *r,
|
||||
ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, uintptr_t gmt);
|
||||
|
||||
static ngx_int_t ngx_http_ssi_add_variables(ngx_conf_t *cf);
|
||||
static void *ngx_http_ssi_create_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_ssi_merge_conf(ngx_conf_t *cf,
|
||||
void *parent, void *child);
|
||||
|
@ -126,6 +150,13 @@ static ngx_command_t ngx_http_ssi_filter_commands[] = {
|
|||
offsetof(ngx_http_ssi_conf_t, silent_errors),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("ssi_ignore_recycled_buffers"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_ssi_conf_t, ignore_recycled_buffers),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("ssi_min_file_chunk"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_size_slot,
|
||||
|
@ -139,7 +170,8 @@ static ngx_command_t ngx_http_ssi_filter_commands[] = {
|
|||
|
||||
|
||||
static ngx_http_module_t ngx_http_ssi_filter_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
ngx_http_ssi_add_variables, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -153,7 +185,7 @@ static ngx_http_module_t ngx_http_ssi_filter_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_ssi_filter_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_ssi_filter_module_ctx, /* module context */
|
||||
ngx_http_ssi_filter_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -174,8 +206,16 @@ static u_char ngx_http_ssi_error_string[] =
|
|||
static ngx_str_t ngx_http_ssi_none = ngx_string("(none)");
|
||||
|
||||
|
||||
#define NGX_HTTP_SSI_ECHO_VAR 0
|
||||
#define NGX_HTTP_SSI_ECHO_DEFAULT 1
|
||||
#define NGX_HTTP_SSI_ECHO_VAR 0
|
||||
#define NGX_HTTP_SSI_ECHO_DEFAULT 1
|
||||
|
||||
#define NGX_HTTP_SSI_CONFIG_TIMEFMT 0
|
||||
|
||||
#define NGX_HTTP_SSI_INCLUDE_VIRTUAL 0
|
||||
#define NGX_HTTP_SSI_INCLUDE_FILE 1
|
||||
|
||||
#define NGX_HTTP_SSI_IF_EXPR 0
|
||||
|
||||
|
||||
static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = {
|
||||
{ ngx_string("var"), NGX_HTTP_SSI_ECHO_VAR, 1 },
|
||||
|
@ -183,13 +223,60 @@ static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = {
|
|||
{ ngx_null_string, 0, 0 }
|
||||
};
|
||||
|
||||
static ngx_http_ssi_param_t ngx_http_ssi_include_params[] = {
|
||||
{ ngx_string("virtual"), NGX_HTTP_SSI_INCLUDE_VIRTUAL, 0 },
|
||||
#if 0
|
||||
{ ngx_string("file"), NGX_HTTP_SSI_INCLUDE_FILE, 0 },
|
||||
#endif
|
||||
{ ngx_null_string, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_ssi_param_t ngx_http_ssi_config_params[] = {
|
||||
{ ngx_string("timefmt"), NGX_HTTP_SSI_CONFIG_TIMEFMT, 0 },
|
||||
{ ngx_null_string, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_ssi_param_t ngx_http_ssi_if_params[] = {
|
||||
{ ngx_string("expr"), NGX_HTTP_SSI_IF_EXPR, 0 },
|
||||
{ ngx_null_string, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_ssi_param_t ngx_http_ssi_no_params[] = {
|
||||
{ ngx_null_string, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_ssi_command_t ngx_http_ssi_commands[] = {
|
||||
{ ngx_string("echo"), ngx_http_ssi_echo, ngx_http_ssi_echo_params, 0 },
|
||||
{ ngx_null_string, NULL, NULL, 0 }
|
||||
{ ngx_string("echo"), ngx_http_ssi_echo, ngx_http_ssi_echo_params, 0, 0 },
|
||||
{ ngx_string("config"), ngx_http_ssi_config,
|
||||
ngx_http_ssi_config_params, 0, 0 },
|
||||
{ ngx_string("include"), ngx_http_ssi_include,
|
||||
ngx_http_ssi_include_params, 0, 1 },
|
||||
|
||||
{ ngx_string("if"), ngx_http_ssi_if, ngx_http_ssi_if_params, 0, 0 },
|
||||
{ ngx_string("else"), ngx_http_ssi_else, ngx_http_ssi_no_params, 1, 0 },
|
||||
{ ngx_string("endif"), ngx_http_ssi_endif, ngx_http_ssi_no_params, 1, 0 },
|
||||
|
||||
{ ngx_null_string, NULL, NULL, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_variable_t ngx_http_ssi_vars[] = {
|
||||
|
||||
{ ngx_string("date_local"), ngx_http_ssi_date_gmt_local_variable, 0,
|
||||
NGX_HTTP_VAR_NOCACHABLE },
|
||||
|
||||
{ ngx_string("date_gmt"), ngx_http_ssi_date_gmt_local_variable, 1,
|
||||
NGX_HTTP_VAR_NOCACHABLE },
|
||||
|
||||
{ ngx_null_string, NULL, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_ssi_header_filter(ngx_http_request_t *r)
|
||||
{
|
||||
|
@ -204,9 +291,9 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r)
|
|||
|
||||
/* TODO: "text/html" -> custom types */
|
||||
|
||||
if (r->headers_out.content_type
|
||||
&& ngx_strncasecmp(r->headers_out.content_type->value.data,
|
||||
"text/html", 5) != 0)
|
||||
if (r->headers_out.content_type.len == 0
|
||||
|| ngx_strncasecmp(r->headers_out.content_type.data, "text/html", 5)
|
||||
!= 0)
|
||||
{
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
@ -223,26 +310,33 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r)
|
|||
ctx->value_len = conf->value_len;
|
||||
ctx->last_out = &ctx->out;
|
||||
|
||||
ctx->output = 1;
|
||||
|
||||
ctx->params.elts = ctx->params_array;
|
||||
ctx->params.size = sizeof(ngx_table_elt_t);
|
||||
ctx->params.nalloc = NGX_HTTP_SSI_PARAMS_N;
|
||||
ctx->params.pool = r->pool;
|
||||
|
||||
r->headers_out.content_length_n = -1;
|
||||
if (r->headers_out.content_length) {
|
||||
r->headers_out.content_length->key.len = 0;
|
||||
r->headers_out.content_length = NULL;
|
||||
}
|
||||
|
||||
r->headers_out.last_modified_time = -1;
|
||||
if (r->headers_out.last_modified) {
|
||||
r->headers_out.last_modified->key.len = 0;
|
||||
r->headers_out.last_modified = NULL;
|
||||
}
|
||||
ctx->timefmt.len = sizeof("%A, %d-%b-%Y %H:%M:%S %Z") - 1;
|
||||
ctx->timefmt.data = (u_char *) "%A, %d-%b-%Y %H:%M:%S %Z";
|
||||
|
||||
r->filter_need_in_memory = 1;
|
||||
r->filter_ssi_need_in_memory = 1;
|
||||
|
||||
if (r->main == NULL) {
|
||||
r->headers_out.content_length_n = -1;
|
||||
if (r->headers_out.content_length) {
|
||||
r->headers_out.content_length->hash = 0;
|
||||
r->headers_out.content_length = NULL;
|
||||
}
|
||||
|
||||
r->headers_out.last_modified_time = -1;
|
||||
if (r->headers_out.last_modified) {
|
||||
r->headers_out.last_modified->hash = 0;
|
||||
r->headers_out.last_modified = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
|
@ -277,8 +371,8 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
|
||||
conf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http ssi filter");
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http ssi filter \"%V\"", &r->uri);
|
||||
|
||||
while (ctx->in || ctx->buf) {
|
||||
|
||||
|
@ -312,19 +406,50 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
|
||||
if (ctx->copy_start != ctx->copy_end) {
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"saved: %d", ctx->saved);
|
||||
if (ctx->output) {
|
||||
|
||||
if (ctx->saved) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"saved: %d", ctx->saved);
|
||||
|
||||
if (ctx->saved) {
|
||||
|
||||
if (ctx->free) {
|
||||
cl = ctx->free;
|
||||
ctx->free = ctx->free->next;
|
||||
b = cl->buf;
|
||||
ngx_memzero(b, sizeof(ngx_buf_t));
|
||||
|
||||
} else {
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cl = ngx_alloc_chain_link(r->pool);
|
||||
if (cl == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cl->buf = b;
|
||||
}
|
||||
|
||||
b->memory = 1;
|
||||
b->pos = ngx_http_ssi_string;
|
||||
b->last = ngx_http_ssi_string + ctx->saved;
|
||||
|
||||
*ctx->last_out = cl;
|
||||
ctx->last_out = &cl->next;
|
||||
|
||||
ctx->saved = 0;
|
||||
}
|
||||
|
||||
if (ctx->free) {
|
||||
cl = ctx->free;
|
||||
ctx->free = ctx->free->next;
|
||||
b = cl->buf;
|
||||
ngx_memzero(b, sizeof(ngx_buf_t));
|
||||
|
||||
} else {
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
b = ngx_alloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -337,56 +462,31 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
cl->buf = b;
|
||||
}
|
||||
|
||||
b->memory = 1;
|
||||
b->pos = ngx_http_ssi_string;
|
||||
b->last = ngx_http_ssi_string + ctx->saved;
|
||||
ngx_memcpy(b, ctx->buf, sizeof(ngx_buf_t));
|
||||
|
||||
b->last_buf = 0;
|
||||
b->recycled = 0;
|
||||
b->pos = ctx->copy_start;
|
||||
b->last = ctx->copy_end;
|
||||
|
||||
if (b->in_file) {
|
||||
if (conf->min_file_chunk < (size_t) (b->last - b->pos))
|
||||
{
|
||||
b->file_last = b->file_pos + (b->last - b->start);
|
||||
b->file_pos += b->pos - b->start;
|
||||
|
||||
} else {
|
||||
b->in_file = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cl->next = NULL;
|
||||
*ctx->last_out = cl;
|
||||
ctx->last_out = &cl->next;
|
||||
|
||||
} else {
|
||||
ctx->saved = 0;
|
||||
}
|
||||
|
||||
if (ctx->free) {
|
||||
cl = ctx->free;
|
||||
ctx->free = ctx->free->next;
|
||||
b = cl->buf;
|
||||
|
||||
} else {
|
||||
b = ngx_alloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cl = ngx_alloc_chain_link(r->pool);
|
||||
if (cl == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cl->buf = b;
|
||||
}
|
||||
|
||||
ngx_memcpy(b, ctx->buf, sizeof(ngx_buf_t));
|
||||
|
||||
b->last_buf = 0;
|
||||
b->recycled = 0;
|
||||
b->pos = ctx->copy_start;
|
||||
b->last = ctx->copy_end;
|
||||
|
||||
if (b->in_file) {
|
||||
|
||||
if (conf->min_file_chunk < (size_t) (b->last - b->pos)) {
|
||||
b->file_last = b->file_pos + (b->last - b->start);
|
||||
b->file_pos += b->pos - b->start;
|
||||
|
||||
} else {
|
||||
b->in_file = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cl->next = NULL;
|
||||
*ctx->last_out = cl;
|
||||
ctx->last_out = &cl->next;
|
||||
}
|
||||
|
||||
if (ctx->state == ssi_start_state) {
|
||||
|
@ -420,12 +520,16 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
break;
|
||||
}
|
||||
|
||||
if (cmd->name.len == 0) {
|
||||
if (cmd->name.len == 0 && ctx->output) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"invalid SSI command: \"%V\"", &ctx->command);
|
||||
goto ssi_error;
|
||||
}
|
||||
|
||||
if (!ctx->output && !cmd->conditional) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_memzero(params,
|
||||
NGX_HTTP_SSI_MAX_PARAMS * sizeof(ngx_str_t *));
|
||||
|
||||
|
@ -479,6 +583,14 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
}
|
||||
}
|
||||
|
||||
if (cmd->flush && ctx->out) {
|
||||
rc = ngx_http_ssi_output(r, ctx);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd->handler(r, ctx, params) == NGX_OK) {
|
||||
continue;
|
||||
}
|
||||
|
@ -525,9 +637,9 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (ctx->buf->recycled || ctx->buf->last_buf) {
|
||||
if (b == NULL) {
|
||||
if (ctx->buf->last_buf || ctx->buf->recycled) {
|
||||
|
||||
if (b == NULL) {
|
||||
if (ctx->free) {
|
||||
cl = ctx->free;
|
||||
ctx->free = ctx->free->next;
|
||||
|
@ -548,14 +660,19 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
cl->buf = b;
|
||||
}
|
||||
|
||||
b->sync = 1;
|
||||
|
||||
cl->next = NULL;
|
||||
*ctx->last_out = cl;
|
||||
ctx->last_out = &cl->next;
|
||||
}
|
||||
|
||||
b->last_buf = ctx->buf->last_buf;
|
||||
b->flush = ctx->buf->recycled;
|
||||
b->shadow = ctx->buf;
|
||||
|
||||
if (conf->ignore_recycled_buffers == 0) {
|
||||
b->recycled = ctx->buf->recycled;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->buf = NULL;
|
||||
|
@ -567,6 +684,17 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
return ngx_http_ssi_output(r, ctx);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_ssi_output(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_buf_t *b;
|
||||
ngx_chain_t *cl;
|
||||
|
||||
rc = ngx_http_next_body_filter(r, ctx->out);
|
||||
|
||||
if (ctx->busy == NULL) {
|
||||
|
@ -1154,7 +1282,7 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|||
var = params[NGX_HTTP_SSI_ECHO_VAR];
|
||||
|
||||
for (i = 0; i < var->len; i++) {
|
||||
var->data[i] = ngx_toupper(var->data[i]);
|
||||
var->data[i] = ngx_tolower(var->data[i]);
|
||||
}
|
||||
|
||||
vv = ngx_http_get_variable(r, var);
|
||||
|
@ -1163,7 +1291,7 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
if (vv == NGX_HTTP_VARIABLE_NOT_FOUND) {
|
||||
if (vv == NGX_HTTP_VAR_NOT_FOUND) {
|
||||
value = params[NGX_HTTP_SSI_ECHO_DEFAULT];
|
||||
|
||||
if (value == NULL) {
|
||||
|
@ -1204,6 +1332,325 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_ssi_config(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
ngx_str_t **params)
|
||||
{
|
||||
ngx_str_t *value;
|
||||
|
||||
value = params[NGX_HTTP_SSI_CONFIG_TIMEFMT];
|
||||
|
||||
if (value) {
|
||||
ctx->timefmt = *value;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
ngx_str_t **params)
|
||||
{
|
||||
u_char ch, *p, **value;
|
||||
size_t *size, len;
|
||||
ngx_uint_t i, j, n, bracket;
|
||||
ngx_str_t uri, args, name;
|
||||
ngx_array_t lengths, values;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
/* TODO: file, virtual vs file */
|
||||
|
||||
uri = *params[NGX_HTTP_SSI_INCLUDE_VIRTUAL];
|
||||
args.len = 0;
|
||||
args.data = NULL;
|
||||
|
||||
n = ngx_http_script_variables_count(&uri);
|
||||
|
||||
if (n > 0) {
|
||||
|
||||
if (ngx_array_init(&lengths, r->pool, 8, sizeof(size_t *)) != NGX_OK) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_array_init(&values, r->pool, 8, sizeof(u_char *)) != NGX_OK) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
|
||||
for (i = 0; i < uri.len; /* void */ ) {
|
||||
|
||||
name.len = 0;
|
||||
|
||||
if (uri.data[i] == '$') {
|
||||
|
||||
if (++i == uri.len) {
|
||||
goto invalid_variable;
|
||||
}
|
||||
|
||||
if (uri.data[i] == '{') {
|
||||
bracket = 1;
|
||||
|
||||
if (++i == uri.len) {
|
||||
goto invalid_variable;
|
||||
}
|
||||
|
||||
name.data = &uri.data[i];
|
||||
|
||||
} else {
|
||||
bracket = 0;
|
||||
name.data = &uri.data[i];
|
||||
}
|
||||
|
||||
for ( /* void */ ; i < uri.len; i++, name.len++) {
|
||||
ch = uri.data[i];
|
||||
|
||||
if (ch == '}' && bracket) {
|
||||
i++;
|
||||
bracket = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ch >= 'A' && ch <= 'Z')
|
||||
|| (ch >= 'a' && ch <= 'z')
|
||||
|| (ch >= '0' && ch <= '9')
|
||||
|| ch == '_')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (bracket) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"the closing bracket in \"%V\" "
|
||||
"variable is missing", &name);
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
if (name.len == 0) {
|
||||
goto invalid_variable;
|
||||
}
|
||||
|
||||
for (j = 0; j < name.len; j++) {
|
||||
name.data[j] = ngx_tolower(name.data[j]);
|
||||
}
|
||||
|
||||
vv = ngx_http_get_variable(r, &name);
|
||||
|
||||
if (vv == NULL) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
if (vv == NGX_HTTP_VAR_NOT_FOUND) {
|
||||
continue;
|
||||
}
|
||||
|
||||
name = vv->text;
|
||||
|
||||
} else {
|
||||
name.data = &uri.data[i];
|
||||
|
||||
while (i < uri.len && uri.data[i] != '$') {
|
||||
i++;
|
||||
name.len++;
|
||||
}
|
||||
}
|
||||
|
||||
len += name.len;
|
||||
|
||||
size = ngx_array_push(&lengths);
|
||||
if (size == NULL) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
*size = name.len;
|
||||
|
||||
value = ngx_array_push(&values);
|
||||
if (value == NULL) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
*value = name.data;
|
||||
}
|
||||
|
||||
p = ngx_palloc(r->pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
uri.len = len;
|
||||
uri.data = p;
|
||||
|
||||
size = lengths.elts;
|
||||
value = values.elts;
|
||||
|
||||
for (i = 0; i < values.nelts; i++) {
|
||||
p = ngx_cpymem(p, value[i], size[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < uri.len; i++) {
|
||||
if (uri.data[i] == '?') {
|
||||
args.len = uri.len - i - 1;
|
||||
args.data = &uri.data[i + 1];
|
||||
uri.len -= args.len + 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_http_subrequest(r, &uri, &args) != NGX_OK) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
invalid_variable:
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"invalid variable name in \"%V\"", &uri);
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_ssi_if(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
ngx_str_t **params)
|
||||
{
|
||||
ngx_str_t *expr, var;
|
||||
ngx_uint_t i;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
expr = params[NGX_HTTP_SSI_IF_EXPR];
|
||||
|
||||
if (expr->data[0] != '$') {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"invalid variable name in \"%V\"", expr);
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
var.len = expr->len - 1;
|
||||
var.data = expr->data + 1;
|
||||
|
||||
for (i = 0; i < var.len; i++) {
|
||||
var.data[i] = ngx_tolower(var.data[i]);
|
||||
}
|
||||
|
||||
vv = ngx_http_get_variable(r, &var);
|
||||
|
||||
if (vv == NULL) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
if (vv != NGX_HTTP_VAR_NOT_FOUND && vv->text.len != 0) {
|
||||
ctx->output = 1;
|
||||
|
||||
} else {
|
||||
ctx->output = 0;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_ssi_else(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
ngx_str_t **params)
|
||||
{
|
||||
ctx->output = !ctx->output;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_ssi_endif(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
ngx_str_t **params)
|
||||
{
|
||||
ctx->output = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, uintptr_t gmt)
|
||||
{
|
||||
ngx_http_ssi_ctx_t *ctx;
|
||||
ngx_http_variable_value_t *vv;
|
||||
struct tm tm;
|
||||
char buf[NGX_HTTP_SSI_DATE_LEN];
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
|
||||
|
||||
if (ctx->timefmt.len == sizeof("%s") - 1
|
||||
&& ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's')
|
||||
{
|
||||
vv->value = ngx_time() + (gmt ? 0 : ngx_gmtoff);
|
||||
|
||||
vv->text.data = ngx_palloc(r->pool, NGX_TIME_T_LEN);
|
||||
if (vv->text.data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->text.len = ngx_sprintf(vv->text.data, "%T", vv->value)
|
||||
- vv->text.data;
|
||||
return vv;
|
||||
}
|
||||
|
||||
if (gmt) {
|
||||
ngx_libc_gmtime(&tm);
|
||||
} else {
|
||||
ngx_libc_localtime(&tm);
|
||||
}
|
||||
|
||||
vv->value = ngx_time() + (gmt ? 0 : ngx_gmtoff);
|
||||
|
||||
vv->text.len = strftime(buf, NGX_HTTP_SSI_DATE_LEN,
|
||||
(char *) ctx->timefmt.data, &tm);
|
||||
if (vv->text.len == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->text.data = ngx_palloc(r->pool, vv->text.len);
|
||||
if (vv->text.data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ngx_memcpy(vv->text.data, buf, vv->text.len);
|
||||
|
||||
return vv;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_ssi_add_variables(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_variable_t *var, *v;
|
||||
|
||||
for (v = ngx_http_ssi_vars; v->name.len; v++) {
|
||||
var = ngx_http_add_variable(cf, &v->name, v->flags);
|
||||
if (var == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
var->handler = v->handler;
|
||||
var->data = v->data;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_ssi_create_conf(ngx_conf_t *cf)
|
||||
{
|
||||
|
@ -1216,6 +1663,7 @@ ngx_http_ssi_create_conf(ngx_conf_t *cf)
|
|||
|
||||
conf->enable = NGX_CONF_UNSET;
|
||||
conf->silent_errors = NGX_CONF_UNSET;
|
||||
conf->ignore_recycled_buffers = NGX_CONF_UNSET;
|
||||
|
||||
conf->min_file_chunk = NGX_CONF_UNSET_SIZE;
|
||||
conf->value_len = NGX_CONF_UNSET_SIZE;
|
||||
|
@ -1232,6 +1680,8 @@ ngx_http_ssi_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
|
||||
ngx_conf_merge_value(conf->enable, prev->enable, 0);
|
||||
ngx_conf_merge_value(conf->silent_errors, prev->silent_errors, 0);
|
||||
ngx_conf_merge_value(conf->ignore_recycled_buffers,
|
||||
prev->ignore_recycled_buffers, 0);
|
||||
|
||||
ngx_conf_merge_size_value(conf->min_file_chunk, prev->min_file_chunk, 1024);
|
||||
ngx_conf_merge_size_value(conf->value_len, prev->value_len, 256);
|
||||
|
|
|
@ -64,7 +64,8 @@ static ngx_command_t ngx_http_ssl_commands[] = {
|
|||
|
||||
|
||||
static ngx_http_module_t ngx_http_ssl_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
ngx_http_ssl_create_main_conf, /* create main configuration */
|
||||
ngx_http_ssl_init_main_conf, /* init main configuration */
|
||||
|
@ -78,7 +79,7 @@ static ngx_http_module_t ngx_http_ssl_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_ssl_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_ssl_module_ctx, /* module context */
|
||||
ngx_http_ssl_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -197,6 +198,13 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_pool_cleanup_add(cf->pool, ngx_ssl_cleanup_ctx, conf->ssl_ctx)
|
||||
== NULL)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
SSL_CTX_set_options(conf->ssl_ctx, SSL_OP_ALL);
|
||||
SSL_CTX_set_options(conf->ssl_ctx, SSL_OP_NO_SSLv3);
|
||||
|
|
|
@ -17,7 +17,7 @@ typedef struct {
|
|||
static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r);
|
||||
static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf,
|
||||
void *parent, void *child);
|
||||
void *parent, void *child);
|
||||
static ngx_int_t ngx_http_static_init(ngx_cycle_t *cycle);
|
||||
|
||||
|
||||
|
@ -38,9 +38,9 @@ static ngx_command_t ngx_http_static_commands[] = {
|
|||
};
|
||||
|
||||
|
||||
|
||||
ngx_http_module_t ngx_http_static_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -54,7 +54,7 @@ ngx_http_module_t ngx_http_static_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_static_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_static_module_ctx, /* module context */
|
||||
ngx_http_static_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -63,7 +63,8 @@ ngx_module_t ngx_http_static_module = {
|
|||
};
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
|
||||
static ngx_int_t
|
||||
ngx_http_static_handler(ngx_http_request_t *r)
|
||||
{
|
||||
u_char *last;
|
||||
ngx_fd_t fd;
|
||||
|
@ -75,16 +76,8 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
|
|||
ngx_buf_t *b;
|
||||
ngx_chain_t out;
|
||||
ngx_file_info_t fi;
|
||||
ngx_http_cleanup_t *file_cleanup;
|
||||
#if (NGX_HTTP_CACHE)
|
||||
ngx_http_cleanup_t *redirect_cleanup;
|
||||
#endif
|
||||
ngx_pool_cleanup_file_t *cln;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
#if (NGX_HTTP_CACHE)
|
||||
ngx_http_static_loc_conf_t *slcf;
|
||||
uint32_t file_crc, redirect_crc;
|
||||
ngx_http_cache_t *file, *redirect;
|
||||
#endif
|
||||
|
||||
if (r->uri.data[r->uri.len - 1] == '/') {
|
||||
return NGX_DECLINED;
|
||||
|
@ -105,19 +98,6 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
|
|||
return rc;
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
||||
/*
|
||||
* there is a valid cached open file, i.e by the index handler,
|
||||
* and it should be already registered in r->cleanup
|
||||
*/
|
||||
|
||||
if (r->cache && !r->cache->expired) {
|
||||
return ngx_http_send_cached(r);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
log = r->connection->log;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
@ -127,7 +107,19 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
|
|||
* in a possible redirect and for the last '\0'
|
||||
*/
|
||||
|
||||
if (clcf->alias) {
|
||||
if (!clcf->alias) {
|
||||
name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2);
|
||||
if (name.data == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
location.data = ngx_cpymem(name.data, clcf->root.data, clcf->root.len);
|
||||
last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1);
|
||||
|
||||
name.len = last - name.data;
|
||||
location.len = last - location.data + 1;
|
||||
|
||||
} else {
|
||||
name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2
|
||||
- clcf->name.len);
|
||||
if (name.data == NULL) {
|
||||
|
@ -147,119 +139,16 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
|
|||
|
||||
last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* aliases usually have trailling "/",
|
||||
* set it in the start of the possible redirect
|
||||
*/
|
||||
|
||||
if (*location.data != '/') {
|
||||
location.data--;
|
||||
}
|
||||
#endif
|
||||
|
||||
location.len = last - location.data + 1;
|
||||
|
||||
} else {
|
||||
name.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + 2);
|
||||
if (name.data == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
location.data = ngx_cpymem(name.data, clcf->root.data, clcf->root.len);
|
||||
last = ngx_cpystrn(location.data, r->uri.data, r->uri.len + 1);
|
||||
|
||||
name.len = last - name.data;
|
||||
location.len = last - location.data + 1;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
|
||||
"http filename: \"%s\"", name.data);
|
||||
|
||||
|
||||
/* allocate cleanups */
|
||||
|
||||
file_cleanup = ngx_array_push(&r->cleanup);
|
||||
if (file_cleanup == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
file_cleanup->valid = 0;
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
||||
slcf = ngx_http_get_module_loc_conf(r, ngx_http_static_module);
|
||||
if (slcf->redirect_cache) {
|
||||
redirect_cleanup = ngx_array_push(&r->cleanup);
|
||||
if (redirect_cleanup == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
redirect_cleanup->valid = 0;
|
||||
|
||||
} else {
|
||||
redirect_cleanup = NULL;
|
||||
}
|
||||
|
||||
/* look up an open files cache */
|
||||
|
||||
if (clcf->open_files) {
|
||||
file = ngx_http_cache_get(clcf->open_files, file_cleanup,
|
||||
&name, &file_crc);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
|
||||
"http open file cache get: %p", file);
|
||||
|
||||
if (file && !file->expired) {
|
||||
r->cache = file;
|
||||
return ngx_http_send_cached(r);
|
||||
}
|
||||
|
||||
} else {
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* look up an redirect cache */
|
||||
|
||||
if (slcf->redirect_cache) {
|
||||
redirect = ngx_http_cache_get(slcf->redirect_cache, redirect_cleanup,
|
||||
&name, &redirect_crc);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
|
||||
"http redirect cache get: %p", redirect);
|
||||
|
||||
if (redirect && !redirect->expired) {
|
||||
|
||||
/*
|
||||
* We do not copy a cached value so the cache entry is locked
|
||||
* until the end of the request. In a single threaded model
|
||||
* the redirected request should complete before other event
|
||||
* will be processed. In a multithreaded model this locking
|
||||
* should keep more popular redirects in cache.
|
||||
*/
|
||||
|
||||
r->headers_out.location = ngx_http_add_header(&r->headers_out,
|
||||
ngx_http_headers_out);
|
||||
if (r->headers_out.location == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.location->value = redirect->data.value;
|
||||
|
||||
return NGX_HTTP_MOVED_PERMANENTLY;
|
||||
}
|
||||
|
||||
} else {
|
||||
redirect = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* open file */
|
||||
|
||||
#if (NGX_WIN9X)
|
||||
|
||||
/* TODO: redirect cache */
|
||||
|
||||
if (ngx_win32_version < NGX_WIN_NT) {
|
||||
|
||||
/*
|
||||
|
@ -285,9 +174,6 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
if (ngx_is_dir(&fi)) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
|
||||
"HTTP DIR: \"%s\"", name.data);
|
||||
|
||||
r->headers_out.location = ngx_http_add_header(&r->headers_out,
|
||||
ngx_http_headers_out);
|
||||
if (r->headers_out.location == NULL) {
|
||||
|
@ -356,60 +242,18 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
|
|||
*last++ = '/';
|
||||
*last = '\0';
|
||||
|
||||
r->headers_out.location = ngx_list_push(&r->headers_out.headers);
|
||||
r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t));
|
||||
if (r->headers_out.location == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* we do not need to set the r->headers_out.location->hash and
|
||||
* r->headers_out.location->key fields
|
||||
*/
|
||||
|
||||
r->headers_out.location->value = location;
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
||||
if (slcf->redirect_cache) {
|
||||
if (redirect) {
|
||||
if (location.len == redirect->data.value.len
|
||||
&& ngx_memcmp(redirect->data.value.data, location.data,
|
||||
location.len) == 0)
|
||||
{
|
||||
redirect->accessed = ngx_cached_time;
|
||||
redirect->updated = ngx_cached_time;
|
||||
|
||||
/*
|
||||
* we can unlock the cache entry because
|
||||
* we have the local copy anyway
|
||||
*/
|
||||
|
||||
ngx_http_cache_unlock(slcf->redirect_cache, redirect, log);
|
||||
redirect_cleanup->valid = 0;
|
||||
|
||||
return NGX_HTTP_MOVED_PERMANENTLY;
|
||||
}
|
||||
}
|
||||
|
||||
location.len++;
|
||||
redirect = ngx_http_cache_alloc(slcf->redirect_cache, redirect,
|
||||
redirect_cleanup,
|
||||
&name, redirect_crc,
|
||||
&location, log);
|
||||
location.len--;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
|
||||
"http redirect cache alloc: %p", redirect);
|
||||
|
||||
if (redirect) {
|
||||
redirect->fd = NGX_INVALID_FILE;
|
||||
redirect->accessed = ngx_cached_time;
|
||||
redirect->last_modified = 0;
|
||||
redirect->updated = ngx_cached_time;
|
||||
redirect->memory = 1;
|
||||
ngx_http_cache_unlock(slcf->redirect_cache, redirect, log);
|
||||
redirect_cleanup->valid = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return NGX_HTTP_MOVED_PERMANENTLY;
|
||||
}
|
||||
|
||||
|
@ -427,70 +271,22 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
|
|||
return NGX_HTTP_NOT_FOUND;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
||||
if (clcf->open_files) {
|
||||
|
||||
#if (NGX_USE_HTTP_FILE_CACHE_UNIQ)
|
||||
|
||||
if (file && file->uniq == ngx_file_uniq(&fi)) {
|
||||
if (ngx_close_file(fd) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
|
||||
ngx_close_file_n " \"%s\" failed", name.data);
|
||||
}
|
||||
file->accessed = ngx_cached_time;
|
||||
file->updated = ngx_cached_time;
|
||||
file->expired = 0;
|
||||
r->cache = file;
|
||||
|
||||
return ngx_http_send_cached(r);
|
||||
|
||||
} else {
|
||||
if (file) {
|
||||
ngx_http_cache_unlock(clcf->open_files, file, log);
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
file = ngx_http_cache_alloc(clcf->open_files, file,
|
||||
file_cleanup,
|
||||
&name, file_crc, NULL, log);
|
||||
if (file) {
|
||||
file->uniq = ngx_file_uniq(&fi);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
file = ngx_http_cache_alloc(clcf->open_files, file,
|
||||
file_cleanup,
|
||||
&name, file_crc, NULL, log);
|
||||
#endif
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
|
||||
"http open file cache alloc: %p", file);
|
||||
|
||||
if (file) {
|
||||
file->fd = fd;
|
||||
file->data.size = ngx_file_size(&fi);
|
||||
file->accessed = ngx_cached_time;
|
||||
file->last_modified = ngx_file_mtime(&fi);
|
||||
file->updated = ngx_cached_time;
|
||||
r->cache = file;
|
||||
}
|
||||
|
||||
return ngx_http_send_cached(r);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
log->action = "sending response to client";
|
||||
|
||||
file_cleanup->data.file.fd = fd;
|
||||
file_cleanup->data.file.name = name.data;
|
||||
file_cleanup->valid = 1;
|
||||
file_cleanup->cache = 0;
|
||||
cln = ngx_palloc(r->pool, sizeof(ngx_pool_cleanup_file_t));
|
||||
if (cln == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
cln->fd = fd;
|
||||
cln->name = name.data;
|
||||
cln->log = r->pool->log;
|
||||
|
||||
if (ngx_pool_cleanup_add(r->pool, ngx_pool_cleanup_file, cln) == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.status = NGX_HTTP_OK;
|
||||
r->headers_out.content_length_n = ngx_file_size(&fi);
|
||||
|
@ -532,10 +328,12 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
|
|||
|
||||
b->in_file = 1;
|
||||
|
||||
if (!r->main) {
|
||||
if (r->main == NULL) {
|
||||
b->last_buf = 1;
|
||||
}
|
||||
|
||||
b->last_in_chain = 1;
|
||||
|
||||
b->file_pos = 0;
|
||||
b->file_last = ngx_file_size(&fi);
|
||||
|
||||
|
@ -550,7 +348,8 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
|
||||
static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf)
|
||||
static void *
|
||||
ngx_http_static_create_loc_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_static_loc_conf_t *conf;
|
||||
|
||||
|
@ -565,8 +364,8 @@ static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf)
|
|||
}
|
||||
|
||||
|
||||
static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf,
|
||||
void *parent, void *child)
|
||||
static char *
|
||||
ngx_http_static_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
{
|
||||
ngx_http_static_loc_conf_t *prev = parent;
|
||||
ngx_http_static_loc_conf_t *conf = child;
|
||||
|
@ -579,7 +378,8 @@ static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf,
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_static_init(ngx_cycle_t *cycle)
|
||||
static ngx_int_t
|
||||
ngx_http_static_init(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_http_handler_pt *h;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
|
|
@ -22,7 +22,8 @@ static ngx_command_t ngx_http_status_commands[] = {
|
|||
|
||||
|
||||
ngx_http_module_t ngx_http_stub_status_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -36,7 +37,7 @@ ngx_http_module_t ngx_http_stub_status_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_stub_status_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_stub_status_module_ctx, /* module context */
|
||||
ngx_http_status_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -63,15 +64,8 @@ static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
|
|||
return rc;
|
||||
}
|
||||
|
||||
r->headers_out.content_type = ngx_list_push(&r->headers_out.headers);
|
||||
if (r->headers_out.content_type == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.content_type->key.len = 0;
|
||||
r->headers_out.content_type->key.data = NULL;
|
||||
r->headers_out.content_type->value.len = sizeof("text/plain") - 1;
|
||||
r->headers_out.content_type->value.data = (u_char *) "text/plain";
|
||||
r->headers_out.content_type.len = sizeof("text/plain") - 1;
|
||||
r->headers_out.content_type.data = (u_char *) "text/plain";
|
||||
|
||||
if (r->method == NGX_HTTP_HEAD) {
|
||||
r->headers_out.status = NGX_HTTP_OK;
|
||||
|
@ -103,14 +97,14 @@ static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
|
|||
rd = *ngx_stat_reading;
|
||||
wr = *ngx_stat_writing;
|
||||
|
||||
b->last = ngx_sprintf(b->last, "Active connections: %A \n", ac);
|
||||
b->last = ngx_sprintf(b->last, "Active connections: %uA \n", ac);
|
||||
|
||||
b->last = ngx_cpymem(b->last, "server accepts handled requests\n",
|
||||
sizeof("server accepts handled requests\n") - 1);
|
||||
|
||||
b->last = ngx_sprintf(b->last, " %A %A %A \n", ap, hn, rq);
|
||||
b->last = ngx_sprintf(b->last, " %uA %uA %uA \n", ap, hn, rq);
|
||||
|
||||
b->last = ngx_sprintf(b->last, "Reading: %A Writing: %A Waiting: %A \n",
|
||||
b->last = ngx_sprintf(b->last, "Reading: %uA Writing: %uA Waiting: %uA \n",
|
||||
rd, wr, ac - (rd + wr));
|
||||
|
||||
r->headers_out.status = NGX_HTTP_OK;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
|
||||
typedef struct {
|
||||
ngx_flag_t enable;
|
||||
ngx_uint_t enable;
|
||||
|
||||
ngx_int_t service;
|
||||
|
||||
|
@ -83,7 +83,7 @@ static ngx_conf_enum_t ngx_http_userid_state[] = {
|
|||
|
||||
|
||||
static ngx_conf_post_handler_pt ngx_http_userid_domain_p =
|
||||
ngx_http_userid_domain;
|
||||
ngx_http_userid_domain;
|
||||
|
||||
static ngx_conf_post_handler_pt ngx_http_userid_path_p = ngx_http_userid_path;
|
||||
static ngx_conf_post_handler_pt ngx_http_userid_p3p_p = ngx_http_userid_p3p;
|
||||
|
@ -145,7 +145,8 @@ static ngx_command_t ngx_http_userid_commands[] = {
|
|||
|
||||
|
||||
ngx_http_module_t ngx_http_userid_filter_module_ctx = {
|
||||
ngx_http_userid_add_log_formats, /* pre conf */
|
||||
ngx_http_userid_add_log_formats, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -159,7 +160,7 @@ ngx_http_module_t ngx_http_userid_filter_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_userid_filter_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_userid_filter_module_ctx, /* module context */
|
||||
ngx_http_userid_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -186,6 +187,10 @@ ngx_http_userid_filter(ngx_http_request_t *r)
|
|||
ngx_http_userid_ctx_t *ctx;
|
||||
ngx_http_userid_conf_t *conf;
|
||||
|
||||
if (r->main) {
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module);
|
||||
|
||||
if (conf->enable == NGX_HTTP_USERID_OFF) {
|
||||
|
@ -225,82 +230,47 @@ static ngx_int_t
|
|||
ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
|
||||
ngx_http_userid_conf_t *conf)
|
||||
{
|
||||
u_char *start, *last, *end;
|
||||
ngx_uint_t i;
|
||||
ngx_int_t n;
|
||||
ngx_str_t src, dst;
|
||||
ngx_table_elt_t **cookies;
|
||||
|
||||
cookies = r->headers_in.cookies.elts;
|
||||
|
||||
for (i = 0; i < r->headers_in.cookies.nelts; i++) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"cookie: \"%V\"", &cookies[i]->value);
|
||||
|
||||
if (conf->name.len >= cookies[i]->value.len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
start = cookies[i]->value.data;
|
||||
end = cookies[i]->value.data + cookies[i]->value.len;
|
||||
|
||||
while (start < end) {
|
||||
|
||||
if (ngx_strncmp(start, conf->name.data, conf->name.len) != 0) {
|
||||
|
||||
while (start < end && *start++ != ';') { /* void */ }
|
||||
while (start < end && *start == ' ') { start++; }
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
start += conf->name.len;
|
||||
|
||||
while (start < end && *start == ' ') { start++; }
|
||||
|
||||
if (start == end || *start++ != '=') {
|
||||
/* the invalid "Cookie" header */
|
||||
break;
|
||||
}
|
||||
|
||||
while (start < end && *start == ' ') { start++; }
|
||||
|
||||
last = start;
|
||||
|
||||
while (last < end && *last++ != ';') { /* void */ }
|
||||
|
||||
if (last - start < 22) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"client sent too short userid cookie \"%V\"",
|
||||
&cookies[i]->value);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* we have to limit encoded string to 22 characters
|
||||
* because there are already the millions cookies with a garbage
|
||||
* instead of the correct base64 trail "=="
|
||||
*/
|
||||
|
||||
src.len = 22;
|
||||
src.data = start;
|
||||
dst.data = (u_char *) ctx->uid_got;
|
||||
|
||||
if (ngx_decode_base64(&dst, &src) == NGX_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"client sent invalid userid cookie \"%V\"",
|
||||
&cookies[i]->value);
|
||||
break;
|
||||
}
|
||||
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"uid: %08XD%08XD%08XD%08XD",
|
||||
ctx->uid_got[0], ctx->uid_got[1],
|
||||
ctx->uid_got[2], ctx->uid_got[3]);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
n = ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &conf->name,
|
||||
&src);
|
||||
if (n == NGX_DECLINED) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (src.len < 22) {
|
||||
cookies = r->headers_in.cookies.elts;
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"client sent too short userid cookie \"%V\"",
|
||||
&cookies[n]->value);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* we have to limit encoded string to 22 characters
|
||||
* because there are already the millions cookies with a garbage
|
||||
* instead of the correct base64 trail "=="
|
||||
*/
|
||||
|
||||
src.len = 22;
|
||||
|
||||
dst.data = (u_char *) ctx->uid_got;
|
||||
|
||||
if (ngx_decode_base64(&dst, &src) == NGX_ERROR) {
|
||||
cookies = r->headers_in.cookies.elts;
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"client sent invalid userid cookie \"%V\"",
|
||||
&cookies[n]->value);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"uid: %08XD%08XD%08XD%08XD",
|
||||
ctx->uid_got[0], ctx->uid_got[1],
|
||||
ctx->uid_got[2], ctx->uid_got[3]);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
@ -404,6 +374,7 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
set_cookie->hash = 1;
|
||||
set_cookie->key.len = sizeof("Set-Cookie") - 1;
|
||||
set_cookie->key.data = (u_char *) "Set-Cookie";
|
||||
set_cookie->value.len = p - cookie;
|
||||
|
@ -421,6 +392,7 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
p3p->hash = 1;
|
||||
p3p->key.len = sizeof("P3P") - 1;
|
||||
p3p->key.data = (u_char *) "P3P";
|
||||
p3p->value = conf->p3p;
|
||||
|
@ -570,7 +542,7 @@ ngx_http_userid_create_conf(ngx_conf_t *cf)
|
|||
* conf->p3p.date = NULL;
|
||||
*/
|
||||
|
||||
conf->enable = NGX_CONF_UNSET;
|
||||
conf->enable = NGX_CONF_UNSET_UINT;
|
||||
conf->service = NGX_CONF_UNSET;
|
||||
conf->expires = NGX_CONF_UNSET;
|
||||
|
||||
|
@ -584,7 +556,8 @@ ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_http_userid_conf_t *prev = parent;
|
||||
ngx_http_userid_conf_t *conf = child;
|
||||
|
||||
ngx_conf_merge_value(conf->enable, prev->enable, NGX_HTTP_USERID_OFF);
|
||||
ngx_conf_merge_unsigned_value(conf->enable, prev->enable,
|
||||
NGX_HTTP_USERID_OFF);
|
||||
|
||||
ngx_conf_merge_str_value(conf->name, prev->name, "uid");
|
||||
ngx_conf_merge_str_value(conf->domain, prev->domain, "");
|
||||
|
|
|
@ -311,7 +311,7 @@ static ngx_http_log_op_name_t ngx_http_proxy_log_fmt_ops[] = {
|
|||
|
||||
|
||||
|
||||
ngx_http_header_t ngx_http_proxy_headers_in[] = {
|
||||
ngx_http_header0_t ngx_http_proxy_headers_in[] = {
|
||||
{ ngx_string("Date"), offsetof(ngx_http_proxy_headers_in_t, date) },
|
||||
{ ngx_string("Server"), offsetof(ngx_http_proxy_headers_in_t, server) },
|
||||
|
||||
|
@ -490,13 +490,25 @@ static ngx_int_t ngx_http_proxy_cache_get(ngx_http_proxy_ctx_t *p)
|
|||
#endif
|
||||
|
||||
|
||||
void ngx_http_proxy_check_broken_connection(ngx_event_t *ev)
|
||||
void ngx_http_proxy_rd_check_broken_connection(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_http_proxy_check_broken_connection(r, r->connection->read);
|
||||
}
|
||||
|
||||
|
||||
void ngx_http_proxy_wr_check_broken_connection(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_http_proxy_check_broken_connection(r, r->connection->read);
|
||||
}
|
||||
|
||||
|
||||
void ngx_http_proxy_check_broken_connection(ngx_http_request_t *r,
|
||||
ngx_event_t *ev)
|
||||
{
|
||||
int n;
|
||||
char buf[1];
|
||||
ngx_err_t err;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_proxy_ctx_t *p;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, 0,
|
||||
|
@ -510,8 +522,7 @@ void ngx_http_proxy_check_broken_connection(ngx_event_t *ev)
|
|||
return;
|
||||
}
|
||||
|
||||
c = ev->data;
|
||||
r = c->data;
|
||||
c = r->connection;
|
||||
p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
|
||||
|
||||
ev->eof = 1;
|
||||
|
@ -542,8 +553,7 @@ void ngx_http_proxy_check_broken_connection(ngx_event_t *ev)
|
|||
|
||||
#endif
|
||||
|
||||
c = ev->data;
|
||||
r = c->data;
|
||||
c = r->connection;
|
||||
p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
|
||||
|
||||
n = recv(c->fd, buf, 1, MSG_PEEK);
|
||||
|
@ -712,13 +722,6 @@ void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc)
|
|||
p->cache->ctx.file.fd);
|
||||
}
|
||||
|
||||
if (p->upstream && p->upstream->event_pipe) {
|
||||
r->file.fd = p->upstream->event_pipe->temp_file->file.fd;
|
||||
|
||||
} else if (p->cache) {
|
||||
r->file.fd = p->cache->ctx.file.fd;
|
||||
}
|
||||
|
||||
if (rc == 0 && r->main == NULL) {
|
||||
rc = ngx_http_send_last(r);
|
||||
}
|
||||
|
|
|
@ -249,7 +249,10 @@ void ngx_http_proxy_cache_busy_lock(ngx_http_proxy_ctx_t *p);
|
|||
|
||||
#endif
|
||||
|
||||
void ngx_http_proxy_check_broken_connection(ngx_event_t *ev);
|
||||
void ngx_http_proxy_rd_check_broken_connection(ngx_http_request_t *r);
|
||||
void ngx_http_proxy_wr_check_broken_connection(ngx_http_request_t *r);
|
||||
void ngx_http_proxy_check_broken_connection(ngx_http_request_t *r,
|
||||
ngx_event_t *ev);
|
||||
|
||||
void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev);
|
||||
void ngx_http_proxy_upstream_busy_lock(ngx_http_proxy_ctx_t *p);
|
||||
|
@ -265,7 +268,7 @@ int ngx_http_proxy_copy_header(ngx_http_proxy_ctx_t *p,
|
|||
|
||||
|
||||
extern ngx_module_t ngx_http_proxy_module;
|
||||
extern ngx_http_header_t ngx_http_proxy_headers_in[];
|
||||
extern ngx_http_header0_t ngx_http_proxy_headers_in[];
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev);
|
|||
static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev);
|
||||
static ssize_t ngx_http_proxy_read_upstream_header(ngx_http_proxy_ctx_t *);
|
||||
static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p);
|
||||
static void ngx_http_proxy_process_downstream(ngx_http_request_t *r);
|
||||
static void ngx_http_proxy_process_body(ngx_event_t *ev);
|
||||
static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p,
|
||||
ngx_uint_t ft_type);
|
||||
|
@ -112,7 +113,7 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p)
|
|||
len = http_methods[p->upstream->method - 1].len + uc->uri.len;
|
||||
|
||||
} else {
|
||||
len = r->method_name.len + uc->uri.len;
|
||||
len = r->method_name.len + 1 + uc->uri.len;
|
||||
}
|
||||
|
||||
if (p->lcf->pass_unparsed_uri && r->valid_unparsed_uri) {
|
||||
|
@ -261,7 +262,8 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p)
|
|||
http_methods[p->upstream->method - 1].data,
|
||||
http_methods[p->upstream->method - 1].len);
|
||||
} else {
|
||||
b->last = ngx_cpymem(b->last, r->method_name.data, r->method_name.len);
|
||||
b->last = ngx_cpymem(b->last, r->method_name.data,
|
||||
r->method_name.len + 1);
|
||||
}
|
||||
|
||||
b->last = ngx_cpymem(b->last, uc->uri.data, uc->uri.len);
|
||||
|
@ -502,12 +504,11 @@ static void ngx_http_proxy_init_upstream(ngx_http_request_t *r)
|
|||
ngx_del_timer(r->connection->read);
|
||||
}
|
||||
|
||||
r->connection->read->event_handler = ngx_http_proxy_check_broken_connection;
|
||||
r->read_event_handler = ngx_http_proxy_rd_check_broken_connection;
|
||||
|
||||
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
||||
|
||||
r->connection->write->event_handler =
|
||||
ngx_http_proxy_check_broken_connection;
|
||||
r->write_event_handler = ngx_http_proxy_wr_check_broken_connection;
|
||||
|
||||
if (!r->connection->write->active) {
|
||||
if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
|
||||
|
@ -770,8 +771,8 @@ static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p)
|
|||
c = p->upstream->peer.connection;
|
||||
|
||||
c->data = p;
|
||||
c->write->event_handler = ngx_http_proxy_send_request_handler;
|
||||
c->read->event_handler = ngx_http_proxy_process_upstream_status_line;
|
||||
c->write->handler = ngx_http_proxy_send_request_handler;
|
||||
c->read->handler = ngx_http_proxy_process_upstream_status_line;
|
||||
|
||||
c->sendfile = r->connection->sendfile;
|
||||
|
||||
|
@ -925,9 +926,9 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p)
|
|||
}
|
||||
#endif
|
||||
|
||||
c->write->event_handler = ngx_http_proxy_dummy_handler;
|
||||
c->write->handler = ngx_http_proxy_dummy_handler;
|
||||
|
||||
if (ngx_handle_level_write_event(c->write) == NGX_ERROR) {
|
||||
if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
|
||||
ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
@ -1124,7 +1125,7 @@ static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev)
|
|||
}
|
||||
|
||||
|
||||
c->read->event_handler = ngx_http_proxy_process_upstream_headers;
|
||||
c->read->handler = ngx_http_proxy_process_upstream_headers;
|
||||
ngx_http_proxy_process_upstream_headers(rev);
|
||||
}
|
||||
|
||||
|
@ -1174,7 +1175,7 @@ static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev)
|
|||
|
||||
rc = ngx_http_parse_header_line(p->request, p->header_in);
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
if (rc == NGX_OK && !r->invalid_header) {
|
||||
|
||||
/* a header line has been parsed successfully */
|
||||
|
||||
|
@ -1241,6 +1242,10 @@ static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev)
|
|||
|
||||
} else if (rc != NGX_AGAIN) {
|
||||
|
||||
if (r->invalid_header) {
|
||||
rc = NGX_HTTP_PARSE_INVALID_HEADER;
|
||||
}
|
||||
|
||||
/* there was error while a header line parsing */
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
||||
|
@ -1465,9 +1470,8 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
|
|||
ep->send_timeout = clcf->send_timeout;
|
||||
ep->send_lowat = clcf->send_lowat;
|
||||
|
||||
p->upstream->peer.connection->read->event_handler =
|
||||
ngx_http_proxy_process_body;
|
||||
r->connection->write->event_handler = ngx_http_proxy_process_body;
|
||||
p->upstream->peer.connection->read->handler = ngx_http_proxy_process_body;
|
||||
r->write_event_handler = ngx_http_proxy_process_downstream;
|
||||
|
||||
ngx_http_proxy_process_body(p->upstream->peer.connection->read);
|
||||
|
||||
|
@ -1475,6 +1479,12 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
|
|||
}
|
||||
|
||||
|
||||
static void ngx_http_proxy_process_downstream(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_http_proxy_process_body(r->connection->write);
|
||||
}
|
||||
|
||||
|
||||
static void ngx_http_proxy_process_body(ngx_event_t *ev)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
|
|
|
@ -53,7 +53,7 @@ static ngx_core_module_t ngx_http_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_module_ctx, /* module context */
|
||||
ngx_http_commands, /* module directives */
|
||||
NGX_CORE_MODULE, /* module type */
|
||||
|
@ -85,11 +85,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
ngx_iocp_conf_t *iocpcf;
|
||||
#endif
|
||||
|
||||
#if (NGX_SUPPRESS_WARN)
|
||||
/* MSVC thinks "in_ports" may be used without having been initialized */
|
||||
ngx_memzero(&in_ports, sizeof(ngx_array_t));
|
||||
#endif
|
||||
|
||||
/* the main http context */
|
||||
|
||||
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
|
||||
|
@ -156,12 +151,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
module = ngx_modules[m]->ctx;
|
||||
mi = ngx_modules[m]->ctx_index;
|
||||
|
||||
if (module->pre_conf) {
|
||||
if (module->pre_conf(cf) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (module->create_main_conf) {
|
||||
ctx->main_conf[mi] = module->create_main_conf(cf);
|
||||
if (ctx->main_conf[mi] == NULL) {
|
||||
|
@ -184,11 +173,26 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
}
|
||||
|
||||
pcf = *cf;
|
||||
cf->ctx = ctx;
|
||||
|
||||
for (m = 0; ngx_modules[m]; m++) {
|
||||
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
module = ngx_modules[m]->ctx;
|
||||
mi = ngx_modules[m]->ctx_index;
|
||||
|
||||
if (module->preconfiguration) {
|
||||
if (module->preconfiguration(cf) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* parse inside the http{} block */
|
||||
|
||||
pcf = *cf;
|
||||
cf->ctx = ctx;
|
||||
cf->module_type = NGX_HTTP_MODULE;
|
||||
cf->cmd_type = NGX_HTTP_MAIN_CONF;
|
||||
rv = ngx_conf_parse(cf, NULL);
|
||||
|
@ -264,11 +268,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
/* we needed http{}'s cf->ctx while the merging configuration */
|
||||
|
||||
*cf = pcf;
|
||||
|
||||
|
||||
/* init lists of the handlers */
|
||||
|
||||
if (ngx_array_init(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers,
|
||||
|
@ -321,7 +320,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
cmcf->headers_in_hash.bucket_size = sizeof(ngx_http_header_t);
|
||||
cmcf->headers_in_hash.name = "http headers_in";
|
||||
|
||||
if (ngx_hash_init(&cmcf->headers_in_hash, cf->pool, ngx_http_headers_in)
|
||||
if (ngx_hash_init(&cmcf->headers_in_hash, cf->pool, ngx_http_headers_in, 0)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
|
@ -329,8 +328,32 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
||||
"http headers_in hash size: %ui, max buckets per entry: %ui",
|
||||
cmcf->headers_in_hash.hash_size,
|
||||
cmcf->headers_in_hash.min_buckets);
|
||||
cmcf->headers_in_hash.hash_size,
|
||||
cmcf->headers_in_hash.min_buckets);
|
||||
|
||||
for (m = 0; ngx_modules[m]; m++) {
|
||||
if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
module = ngx_modules[m]->ctx;
|
||||
mi = ngx_modules[m]->ctx_index;
|
||||
|
||||
if (module->postconfiguration) {
|
||||
if (module->postconfiguration(cf) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* http{}'s cf->ctx was needed while the configuration merging
|
||||
* and in postconfiguration process
|
||||
*/
|
||||
|
||||
*cf = pcf;
|
||||
|
||||
|
||||
/*
|
||||
* create the lists of ports, addresses and server names
|
||||
|
|
|
@ -12,11 +12,16 @@
|
|||
#include <ngx_core.h>
|
||||
#include <ngx_garbage_collector.h>
|
||||
|
||||
typedef struct ngx_http_request_s ngx_http_request_t;
|
||||
typedef struct ngx_http_log_ctx_s ngx_http_log_ctx_t;
|
||||
typedef struct ngx_http_cleanup_s ngx_http_cleanup_t;
|
||||
typedef struct ngx_http_in_addr_s ngx_http_in_addr_t;
|
||||
typedef struct ngx_http_variable_value_s ngx_http_variable_value_t;
|
||||
|
||||
typedef struct ngx_http_request_s ngx_http_request_t;
|
||||
typedef struct ngx_http_upstream_s ngx_http_upstream_t;
|
||||
typedef struct ngx_http_log_ctx_s ngx_http_log_ctx_t;
|
||||
typedef struct ngx_http_in_addr_s ngx_http_in_addr_t;
|
||||
|
||||
typedef ngx_int_t (*ngx_http_header_handler_pt)(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
typedef u_char *(*ngx_http_log_handler_pt)(ngx_http_request_t *r, u_char *buf,
|
||||
size_t len);
|
||||
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
@ -25,13 +30,13 @@ typedef struct ngx_http_variable_value_s ngx_http_variable_value_t;
|
|||
/* STUB */
|
||||
#include <ngx_http_cache.h>
|
||||
|
||||
#include <ngx_http_upstream.h>
|
||||
#include <ngx_http_variables.h>
|
||||
#include <ngx_http_request.h>
|
||||
#include <ngx_http_upstream.h>
|
||||
#include <ngx_http_config.h>
|
||||
#include <ngx_http_busy_lock.h>
|
||||
#include <ngx_http_log_module.h>
|
||||
#include <ngx_http_core_module.h>
|
||||
#include <ngx_http_variables.h>
|
||||
#include <ngx_http_script.h>
|
||||
|
||||
#if (NGX_HTTP_SSL)
|
||||
|
@ -58,16 +63,18 @@ void ngx_http_init_connection(ngx_connection_t *c);
|
|||
ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b);
|
||||
ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r);
|
||||
ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b);
|
||||
ngx_int_t ngx_http_parse_multi_header_lines(ngx_array_t *headers,
|
||||
ngx_str_t *name, ngx_str_t *value);
|
||||
|
||||
ngx_int_t ngx_http_find_server_conf(ngx_http_request_t *r);
|
||||
void ngx_http_handler(ngx_http_request_t *r);
|
||||
void ngx_http_finalize_request(ngx_http_request_t *r, int error);
|
||||
void ngx_http_writer(ngx_event_t *wev);
|
||||
void ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc);
|
||||
|
||||
void ngx_http_empty_handler(ngx_event_t *wev);
|
||||
void ngx_http_request_empty_handler(ngx_http_request_t *r);
|
||||
|
||||
ngx_int_t ngx_http_send_last(ngx_http_request_t *r);
|
||||
void ngx_http_close_request(ngx_http_request_t *r, int error);
|
||||
void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error);
|
||||
void ngx_http_close_connection(ngx_connection_t *c);
|
||||
u_char * ngx_http_log_error_info(ngx_http_request_t *r, u_char *buf,
|
||||
size_t len);
|
||||
|
|
|
@ -46,8 +46,10 @@ int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc)
|
|||
if (bl->waiting < bl->max_waiting) {
|
||||
bl->waiting++;
|
||||
|
||||
#if 0
|
||||
ngx_add_timer(bc->event, 1000);
|
||||
bc->event->event_handler = bc->event_handler;
|
||||
#endif
|
||||
|
||||
/* TODO: ngx_handle_level_read_event() */
|
||||
|
||||
|
@ -95,9 +97,11 @@ int ngx_http_busy_lock_cachable(ngx_http_busy_lock_t *bl,
|
|||
}
|
||||
|
||||
if (bl->waiting < bl->max_waiting) {
|
||||
#if 0
|
||||
bl->waiting++;
|
||||
ngx_add_timer(bc->event, 1000);
|
||||
bc->event->event_handler = bc->event_handler;
|
||||
#endif
|
||||
|
||||
/* TODO: ngx_handle_level_read_event() */
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ typedef struct {
|
|||
|
||||
|
||||
typedef struct {
|
||||
ngx_int_t (*pre_conf)(ngx_conf_t *cf);
|
||||
ngx_int_t (*preconfiguration)(ngx_conf_t *cf);
|
||||
ngx_int_t (*postconfiguration)(ngx_conf_t *cf);
|
||||
|
||||
void *(*create_main_conf)(ngx_conf_t *cf);
|
||||
char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
|
||||
|
|
|
@ -34,7 +34,8 @@ static ngx_command_t ngx_http_copy_filter_commands[] = {
|
|||
|
||||
|
||||
static ngx_http_module_t ngx_http_copy_filter_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -48,7 +49,7 @@ static ngx_http_module_t ngx_http_copy_filter_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_copy_filter_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_copy_filter_module_ctx, /* module context */
|
||||
ngx_http_copy_filter_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -63,6 +64,7 @@ static ngx_http_output_body_filter_pt ngx_http_next_filter;
|
|||
static ngx_int_t
|
||||
ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_output_chain_ctx_t *ctx;
|
||||
ngx_http_copy_filter_conf_t *conf;
|
||||
|
||||
|
@ -70,12 +72,13 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r->main ? r->main : r,
|
||||
ngx_http_copy_filter_module);
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"copy filter: \"%V\"", &r->uri);
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module);
|
||||
|
||||
if (ctx == NULL) {
|
||||
conf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
|
||||
ngx_http_copy_filter_module);
|
||||
conf = ngx_http_get_module_loc_conf(r, ngx_http_copy_filter_module);
|
||||
|
||||
ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t));
|
||||
if (ctx == NULL) {
|
||||
|
@ -97,7 +100,12 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
|
||||
}
|
||||
|
||||
return ngx_output_chain(ctx, in);
|
||||
rc = ngx_output_chain(ctx, in);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"copy filter: %i \"%V\"", rc, &r->uri);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,11 +17,12 @@
|
|||
#define NGX_HTTP_LOCATION_REGEX 4
|
||||
|
||||
|
||||
static void ngx_http_core_phase_event_handler(ngx_event_t *rev);
|
||||
static void ngx_http_core_run_phases(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r,
|
||||
ngx_array_t *locations, size_t len);
|
||||
|
||||
static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
|
||||
static ngx_int_t ngx_http_core_postconfiguration(ngx_conf_t *cf);
|
||||
static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
|
||||
static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf);
|
||||
|
@ -54,9 +55,10 @@ static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd,
|
|||
void *conf);
|
||||
static char *ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
||||
static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data);
|
||||
static ngx_int_t ngx_http_core_init(ngx_cycle_t *cycle);
|
||||
|
||||
static ngx_conf_post_t ngx_http_core_lowat_post =
|
||||
{ ngx_http_core_lowat_check };
|
||||
|
@ -183,7 +185,8 @@ static ngx_command_t ngx_http_core_commands[] = {
|
|||
NULL },
|
||||
|
||||
{ ngx_string("root"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_TAKE1,
|
||||
ngx_http_core_root,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
|
@ -281,6 +284,13 @@ static ngx_command_t ngx_http_core_commands[] = {
|
|||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("internal"),
|
||||
NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
|
||||
ngx_http_core_internal,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("lingering_time"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
|
@ -310,7 +320,8 @@ static ngx_command_t ngx_http_core_commands[] = {
|
|||
NULL },
|
||||
|
||||
{ ngx_string("error_page"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_2MORE,
|
||||
ngx_http_core_error_page,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
|
@ -339,7 +350,8 @@ static ngx_command_t ngx_http_core_commands[] = {
|
|||
|
||||
|
||||
ngx_http_module_t ngx_http_core_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
ngx_http_core_preconfiguration, /* preconfiguration */
|
||||
ngx_http_core_postconfiguration, /* postconfiguration */
|
||||
|
||||
ngx_http_core_create_main_conf, /* create main configuration */
|
||||
ngx_http_core_init_main_conf, /* init main configuration */
|
||||
|
@ -353,11 +365,11 @@ ngx_http_module_t ngx_http_core_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_core_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_core_module_ctx, /* module context */
|
||||
ngx_http_core_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
ngx_http_core_init, /* init module */
|
||||
NULL, /* init module */
|
||||
NULL /* init process */
|
||||
};
|
||||
|
||||
|
@ -413,11 +425,12 @@ ngx_http_handler(ngx_http_request_t *r)
|
|||
/* TEST STUB */ r->lingering_close = 1;
|
||||
#endif
|
||||
|
||||
r->connection->write->event_handler = ngx_http_core_phase_event_handler;
|
||||
r->write_event_handler = ngx_http_core_run_phases;
|
||||
|
||||
r->valid_unparsed_uri = 1;
|
||||
r->valid_location = 1;
|
||||
r->uri_changed = 1;
|
||||
r->uri_changes = 11;
|
||||
r->uri_changes = NGX_HTTP_MAX_REWRITE_CYCLES + 1;
|
||||
|
||||
r->phase = NGX_HTTP_REWRITE_PHASE;
|
||||
r->phase_handler = 0;
|
||||
|
@ -426,21 +439,6 @@ ngx_http_handler(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_core_phase_event_handler(ngx_event_t *ev)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
|
||||
c = ev->data;
|
||||
r = c->data;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, "phase event handler");
|
||||
|
||||
ngx_http_core_run_phases(r);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_core_run_phases(ngx_http_request_t *r)
|
||||
{
|
||||
|
@ -449,6 +447,9 @@ ngx_http_core_run_phases(ngx_http_request_t *r)
|
|||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http phase handler");
|
||||
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
||||
|
||||
for (/* void */; r->phase < NGX_HTTP_LAST_PHASE; r->phase++) {
|
||||
|
@ -478,7 +479,7 @@ ngx_http_core_run_phases(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
if (r->phase == NGX_HTTP_CONTENT_PHASE && r->content_handler) {
|
||||
r->connection->write->event_handler = ngx_http_empty_handler;
|
||||
r->write_event_handler = ngx_http_request_empty_handler;
|
||||
ngx_http_finalize_request(r, r->content_handler(r));
|
||||
return;
|
||||
}
|
||||
|
@ -564,6 +565,10 @@ ngx_http_find_location_config(ngx_http_request_t *r)
|
|||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (!r->internal && clcf->internal) {
|
||||
return NGX_HTTP_NOT_FOUND;
|
||||
}
|
||||
|
||||
r->connection->log->file = clcf->err_log->file;
|
||||
if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
|
||||
r->connection->log->log_level = clcf->err_log->log_level;
|
||||
|
@ -608,6 +613,11 @@ ngx_http_find_location_config(ngx_http_request_t *r)
|
|||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* we do not need to set the r->headers_out.location->hash and
|
||||
* r->headers_out.location->key fields
|
||||
*/
|
||||
|
||||
r->headers_out.location->value = clcf->name;
|
||||
|
||||
return NGX_HTTP_MOVED_PERMANENTLY;
|
||||
|
@ -765,16 +775,6 @@ ngx_http_set_content_type(ngx_http_request_t *r)
|
|||
ngx_http_type_t *type;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
r->headers_out.content_type = ngx_list_push(&r->headers_out.headers);
|
||||
if (r->headers_out.content_type == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.content_type->key.len = 0;
|
||||
r->headers_out.content_type->key.data = NULL;
|
||||
r->headers_out.content_type->value.len = 0;
|
||||
r->headers_out.content_type->value.data = NULL;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (r->exten.len) {
|
||||
|
@ -810,9 +810,6 @@ ngx_http_set_content_type(ngx_http_request_t *r)
|
|||
r->low_case_exten = 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
key = ngx_crc(r->exten.data, r->exten.key);
|
||||
#endif
|
||||
ngx_http_types_hash_key(key, r->exten);
|
||||
|
||||
type = clcf->types[key].elts;
|
||||
|
@ -824,14 +821,14 @@ ngx_http_set_content_type(ngx_http_request_t *r)
|
|||
if (ngx_memcmp(r->exten.data, type[i].exten.data, r->exten.len)
|
||||
== 0)
|
||||
{
|
||||
r->headers_out.content_type->value = type[i].type;
|
||||
r->headers_out.content_type = type[i].type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (r->headers_out.content_type->value.len == 0) {
|
||||
r->headers_out.content_type->value = clcf->default_type;
|
||||
if (r->headers_out.content_type.len == 0) {
|
||||
r->headers_out.content_type= clcf->default_type;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
@ -841,10 +838,6 @@ ngx_http_set_content_type(ngx_http_request_t *r)
|
|||
ngx_int_t
|
||||
ngx_http_send_header(ngx_http_request_t *r)
|
||||
{
|
||||
if (r->main) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (r->err_ctx) {
|
||||
r->headers_out.status = r->err_status;
|
||||
r->headers_out.status_line.len = 0;
|
||||
|
@ -863,12 +856,13 @@ ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http output filter \"%V\"", &r->uri);
|
||||
|
||||
rc = ngx_http_top_body_filter(r, in);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
|
||||
/* NGX_ERROR may be returned by any filter */
|
||||
|
||||
r->connection->write->error = 1;
|
||||
}
|
||||
|
||||
|
@ -923,6 +917,114 @@ ngx_http_set_exten(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_subrequest(ngx_http_request_t *r,
|
||||
ngx_str_t *uri, ngx_str_t *args)
|
||||
{
|
||||
ngx_http_request_t *sr;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
ngx_http_postponed_request_t *pr, *p;
|
||||
|
||||
sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
|
||||
if (sr == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
sr->signature = NGX_HTTP_MODULE;
|
||||
sr->connection = r->connection;
|
||||
|
||||
sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
|
||||
if (sr->ctx == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
|
||||
sizeof(ngx_table_elt_t)) == NGX_ERROR)
|
||||
{
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||
sr->main_conf = cscf->ctx->main_conf;
|
||||
sr->srv_conf = cscf->ctx->srv_conf;
|
||||
sr->loc_conf = cscf->ctx->loc_conf;
|
||||
|
||||
sr->pool = r->pool;
|
||||
|
||||
sr->headers_in = r->headers_in;
|
||||
|
||||
sr->start_time = ngx_time();
|
||||
sr->headers_out.content_length_n = -1;
|
||||
sr->headers_out.last_modified_time = -1;
|
||||
|
||||
sr->request_body = r->request_body;
|
||||
|
||||
sr->method = NGX_HTTP_GET;
|
||||
sr->http_version = r->http_version;
|
||||
sr->http_major = r->http_minor;
|
||||
|
||||
sr->request_line = r->request_line;
|
||||
sr->uri = *uri;
|
||||
if (args) {
|
||||
sr->args = *args;
|
||||
}
|
||||
sr->unparsed_uri = r->unparsed_uri;
|
||||
sr->method_name = r->method_name;
|
||||
sr->http_protocol = r->http_protocol;
|
||||
|
||||
if (ngx_http_set_exten(sr) != NGX_OK) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
sr->main = r->main ? r->main : r;
|
||||
sr->parent = r;
|
||||
sr->read_event_handler = ngx_http_request_empty_handler;
|
||||
sr->write_event_handler = ngx_http_request_empty_handler;
|
||||
|
||||
if (r->connection->data == r) {
|
||||
sr->connection->data = sr;
|
||||
}
|
||||
|
||||
sr->in_addr = r->in_addr;
|
||||
sr->port = r->port;
|
||||
sr->port_text = r->port_text;
|
||||
sr->server_name = r->server_name;
|
||||
|
||||
sr->variables = r->variables;
|
||||
|
||||
sr->log_handler = r->log_handler;
|
||||
|
||||
pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
|
||||
if (pr == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
pr->request = sr;
|
||||
pr->out = NULL;
|
||||
pr->next = NULL;
|
||||
|
||||
if (r->postponed) {
|
||||
for (p = r->postponed; p->next; p = p->next) { /* void */ }
|
||||
p->next = pr;
|
||||
|
||||
} else {
|
||||
r->postponed = pr;
|
||||
}
|
||||
|
||||
sr->internal = 1;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http subrequest \"%V\"", uri);
|
||||
|
||||
ngx_http_handler(sr);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http subrequest \"%V\" done", uri);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_internal_redirect(ngx_http_request_t *r,
|
||||
ngx_str_t *uri, ngx_str_t *args)
|
||||
|
@ -936,6 +1038,10 @@ ngx_http_internal_redirect(ngx_http_request_t *r,
|
|||
|
||||
if (args) {
|
||||
r->args = *args;
|
||||
|
||||
} else {
|
||||
r->args.len = 0;
|
||||
r->args.data = NULL;
|
||||
}
|
||||
|
||||
if (ngx_http_set_exten(r) != NGX_OK) {
|
||||
|
@ -961,6 +1067,8 @@ ngx_http_internal_redirect(ngx_http_request_t *r,
|
|||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||
r->loc_conf = cscf->ctx->loc_conf;
|
||||
|
||||
r->internal = 1;
|
||||
|
||||
ngx_http_handler(r);
|
||||
|
||||
return NGX_DONE;
|
||||
|
@ -1376,6 +1484,20 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_core_preconfiguration(ngx_conf_t *cf)
|
||||
{
|
||||
return ngx_http_variables_add_core_vars(cf);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_core_postconfiguration(ngx_conf_t *cf)
|
||||
{
|
||||
return ngx_http_variables_init_vars(cf);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_core_create_main_conf(ngx_conf_t *cf)
|
||||
{
|
||||
|
@ -1575,6 +1697,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
|
|||
lcf->client_max_body_size = NGX_CONF_UNSET_SIZE;
|
||||
lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
lcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
|
||||
lcf->internal = NGX_CONF_UNSET;
|
||||
lcf->sendfile = NGX_CONF_UNSET;
|
||||
lcf->tcp_nopush = NGX_CONF_UNSET;
|
||||
lcf->tcp_nodelay = NGX_CONF_UNSET;
|
||||
|
@ -1673,9 +1796,12 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
|
|||
(size_t) 2 * ngx_pagesize);
|
||||
ngx_conf_merge_msec_value(conf->client_body_timeout,
|
||||
prev->client_body_timeout, 60000);
|
||||
|
||||
ngx_conf_merge_value(conf->internal, prev->internal, 0);
|
||||
ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
|
||||
ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
|
||||
ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 0);
|
||||
|
||||
ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
|
||||
ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
|
||||
ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
|
||||
|
@ -1962,6 +2088,20 @@ ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_core_loc_conf_t *lcf = conf;
|
||||
|
||||
lcf->err_log = ngx_log_create_errlog(cf->cycle, cf->args);
|
||||
if (lcf->err_log == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
return ngx_set_error_log_levels(cf, lcf->err_log);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
|
@ -2004,16 +2144,17 @@ ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
|
||||
static char *
|
||||
ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_core_loc_conf_t *lcf = conf;
|
||||
|
||||
lcf->err_log = ngx_log_create_errlog(cf->cycle, cf->args);
|
||||
if (lcf->err_log == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
if (lcf->internal != NGX_CONF_UNSET) {
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
return ngx_set_error_log_levels(cf, lcf->err_log);
|
||||
lcf->internal = 1;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2044,10 +2185,3 @@ ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data)
|
|||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_core_init(ngx_cycle_t *cycle)
|
||||
{
|
||||
return ngx_http_variables_init(cycle);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ typedef struct {
|
|||
ngx_array_t index_handlers;
|
||||
|
||||
ngx_hash_t headers_in_hash;
|
||||
ngx_hash_t variables_hash;
|
||||
|
||||
ngx_uint_t server_names_hash;
|
||||
ngx_uint_t server_names_hash_threshold;
|
||||
|
@ -56,6 +57,7 @@ typedef struct {
|
|||
size_t max_server_name_len;
|
||||
|
||||
ngx_array_t variables; /* ngx_http_variable_t */
|
||||
ngx_array_t all_variables; /* ngx_http_variable_t */
|
||||
} ngx_http_core_main_conf_t;
|
||||
|
||||
|
||||
|
@ -197,6 +199,7 @@ struct ngx_http_core_loc_conf_s {
|
|||
|
||||
time_t keepalive_header; /* keepalive_timeout */
|
||||
|
||||
ngx_flag_t internal; /* internal */
|
||||
ngx_flag_t sendfile; /* sendfile */
|
||||
ngx_flag_t tcp_nopush; /* tcp_nopush */
|
||||
ngx_flag_t tcp_nodelay; /* tcp_nodelay */
|
||||
|
@ -230,6 +233,8 @@ ngx_int_t ngx_http_find_location_config(ngx_http_request_t *r);
|
|||
ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r);
|
||||
ngx_int_t ngx_http_set_exten(ngx_http_request_t *r);
|
||||
|
||||
ngx_int_t ngx_http_subrequest(ngx_http_request_t *r,
|
||||
ngx_str_t *uri, ngx_str_t *args);
|
||||
ngx_int_t ngx_http_internal_redirect(ngx_http_request_t *r,
|
||||
ngx_str_t *uri, ngx_str_t *args);
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@ static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r);
|
|||
|
||||
|
||||
static ngx_http_module_t ngx_http_header_filter_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -29,7 +30,7 @@ static ngx_http_module_t ngx_http_header_filter_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_header_filter_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_header_filter_module_ctx, /* module context */
|
||||
NULL, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -38,10 +39,10 @@ ngx_module_t ngx_http_header_filter_module = {
|
|||
};
|
||||
|
||||
|
||||
static char server_string[] = "Server: " NGINX_VER CRLF;
|
||||
static char ngx_http_server_string[] = "Server: " NGINX_VER CRLF;
|
||||
|
||||
|
||||
static ngx_str_t http_codes[] = {
|
||||
static ngx_str_t ngx_http_status_lines[] = {
|
||||
|
||||
ngx_string("200 OK"),
|
||||
ngx_null_string, /* "201 Created" */
|
||||
|
@ -115,11 +116,13 @@ static ngx_str_t http_codes[] = {
|
|||
};
|
||||
|
||||
|
||||
ngx_http_header_t ngx_http_headers_out[] = {
|
||||
ngx_http_header0_t ngx_http_headers_out[] = {
|
||||
{ ngx_string("Server"), offsetof(ngx_http_headers_out_t, server) },
|
||||
{ ngx_string("Date"), offsetof(ngx_http_headers_out_t, date) },
|
||||
#if 0
|
||||
{ ngx_string("Content-Type"),
|
||||
offsetof(ngx_http_headers_out_t, content_type) },
|
||||
#endif
|
||||
{ ngx_string("Content-Length"),
|
||||
offsetof(ngx_http_headers_out_t, content_length) },
|
||||
{ ngx_string("Content-Encoding"),
|
||||
|
@ -150,6 +153,10 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
ngx_table_elt_t *header;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
if (r->main) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (r->http_version < NGX_HTTP_VERSION_10) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -209,44 +216,44 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
+ NGX_HTTP_LEVEL_400;
|
||||
}
|
||||
|
||||
len += http_codes[status].len;
|
||||
len += ngx_http_status_lines[status].len;
|
||||
}
|
||||
|
||||
if (r->headers_out.server && r->headers_out.server->key.len) {
|
||||
len += r->headers_out.server->key.len
|
||||
+ r->headers_out.server->value.len + 2;
|
||||
} else {
|
||||
len += sizeof(server_string) - 1;
|
||||
if (r->headers_out.server == NULL) {
|
||||
len += sizeof(ngx_http_server_string) - 1;
|
||||
}
|
||||
|
||||
if (r->headers_out.date && r->headers_out.date->key.len) {
|
||||
len += r->headers_out.date->key.len
|
||||
+ r->headers_out.date->value.len + 2;
|
||||
} else {
|
||||
if (r->headers_out.date == NULL) {
|
||||
len += sizeof("Date: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1;
|
||||
}
|
||||
|
||||
if (r->headers_out.content_length == NULL) {
|
||||
if (r->headers_out.content_length_n >= 0) {
|
||||
len += sizeof("Content-Length: ") - 1 + NGX_OFF_T_LEN + 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (r->headers_out.content_type && r->headers_out.content_type->value.len) {
|
||||
r->headers_out.content_type->key.len = 0;
|
||||
if (r->headers_out.content_type.len) {
|
||||
len += sizeof("Content-Type: ") - 1
|
||||
+ r->headers_out.content_type->value.len + 2;
|
||||
+ r->headers_out.content_type.len + 2;
|
||||
|
||||
if (r->headers_out.charset.len) {
|
||||
len += sizeof("; charset=") - 1 + r->headers_out.charset.len;
|
||||
}
|
||||
}
|
||||
|
||||
if (r->headers_out.content_length == NULL
|
||||
&& r->headers_out.content_length_n >= 0)
|
||||
{
|
||||
len += sizeof("Content-Length: ") - 1 + NGX_OFF_T_LEN + 2;
|
||||
}
|
||||
|
||||
if (r->headers_out.last_modified == NULL
|
||||
&& r->headers_out.last_modified_time != -1)
|
||||
{
|
||||
len += sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1;
|
||||
}
|
||||
|
||||
if (r->headers_out.location
|
||||
&& r->headers_out.location->value.len
|
||||
&& r->headers_out.location->value.data[0] == '/')
|
||||
{
|
||||
r->headers_out.location->key.len = 0;
|
||||
r->headers_out.location->hash = 0;
|
||||
|
||||
len += sizeof("Location: http://") - 1
|
||||
+ r->server_name.len + r->headers_out.location->value.len + 2;
|
||||
|
||||
|
@ -255,14 +262,6 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
}
|
||||
}
|
||||
|
||||
if (r->headers_out.last_modified && r->headers_out.last_modified->key.len) {
|
||||
len += r->headers_out.last_modified->key.len
|
||||
+ r->headers_out.last_modified->value.len + 2;
|
||||
|
||||
} else if (r->headers_out.last_modified_time != -1) {
|
||||
len += sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1;
|
||||
}
|
||||
|
||||
if (r->chunked) {
|
||||
len += sizeof("Transfer-Encoding: chunked" CRLF) - 1;
|
||||
}
|
||||
|
@ -303,7 +302,7 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
i = 0;
|
||||
}
|
||||
|
||||
if (header[i].key.len == 0) {
|
||||
if (header[i].hash == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -325,16 +324,17 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
r->headers_out.status_line.len);
|
||||
|
||||
} else {
|
||||
b->last = ngx_cpymem(b->last, http_codes[status].data,
|
||||
http_codes[status].len);
|
||||
b->last = ngx_cpymem(b->last, ngx_http_status_lines[status].data,
|
||||
ngx_http_status_lines[status].len);
|
||||
}
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
if (!(r->headers_out.server && r->headers_out.server->key.len)) {
|
||||
b->last = ngx_cpymem(b->last, server_string, sizeof(server_string) - 1);
|
||||
if (r->headers_out.server == NULL) {
|
||||
b->last = ngx_cpymem(b->last, ngx_http_server_string,
|
||||
sizeof(ngx_http_server_string) - 1);
|
||||
}
|
||||
|
||||
if (!(r->headers_out.date && r->headers_out.date->key.len)) {
|
||||
if (r->headers_out.date == NULL) {
|
||||
b->last = ngx_cpymem(b->last, "Date: ", sizeof("Date: ") - 1);
|
||||
b->last = ngx_cpymem(b->last, ngx_cached_http_time.data,
|
||||
ngx_cached_http_time.len);
|
||||
|
@ -342,19 +342,12 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
*b->last++ = CR; *b->last++ = LF;
|
||||
}
|
||||
|
||||
if (r->headers_out.content_length == NULL) {
|
||||
if (r->headers_out.content_length_n >= 0) {
|
||||
b->last = ngx_sprintf(b->last, "Content-Length: %O" CRLF,
|
||||
r->headers_out.content_length_n);
|
||||
}
|
||||
}
|
||||
|
||||
if (r->headers_out.content_type && r->headers_out.content_type->value.len) {
|
||||
if (r->headers_out.content_type.len) {
|
||||
b->last = ngx_cpymem(b->last, "Content-Type: ",
|
||||
sizeof("Content-Type: ") - 1);
|
||||
p = b->last;
|
||||
b->last = ngx_cpymem(b->last, r->headers_out.content_type->value.data,
|
||||
r->headers_out.content_type->value.len);
|
||||
b->last = ngx_cpymem(b->last, r->headers_out.content_type.data,
|
||||
r->headers_out.content_type.len);
|
||||
|
||||
if (r->headers_out.charset.len) {
|
||||
b->last = ngx_cpymem(b->last, "; charset=",
|
||||
|
@ -362,13 +355,32 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
b->last = ngx_cpymem(b->last, r->headers_out.charset.data,
|
||||
r->headers_out.charset.len);
|
||||
|
||||
r->headers_out.content_type->value.len = b->last - p;
|
||||
r->headers_out.content_type->value.data = p;
|
||||
/* update r->headers_out.content_type for possible logging */
|
||||
|
||||
r->headers_out.content_type.len = b->last - p;
|
||||
r->headers_out.content_type.data = p;
|
||||
}
|
||||
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
}
|
||||
|
||||
if (r->headers_out.content_length == NULL
|
||||
&& r->headers_out.content_length_n >= 0)
|
||||
{
|
||||
b->last = ngx_sprintf(b->last, "Content-Length: %O" CRLF,
|
||||
r->headers_out.content_length_n);
|
||||
}
|
||||
|
||||
if (r->headers_out.last_modified == NULL
|
||||
&& r->headers_out.last_modified_time != -1)
|
||||
{
|
||||
b->last = ngx_cpymem(b->last, "Last-Modified: ",
|
||||
sizeof("Last-Modified: ") - 1);
|
||||
b->last = ngx_http_time(b->last, r->headers_out.last_modified_time);
|
||||
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
}
|
||||
|
||||
if (r->headers_out.location
|
||||
&& r->headers_out.location->value.len
|
||||
&& r->headers_out.location->value.data[0] == '/')
|
||||
|
@ -386,22 +398,14 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
b->last = ngx_cpymem(b->last, r->headers_out.location->value.data,
|
||||
r->headers_out.location->value.len);
|
||||
|
||||
/* update r->headers_out.location->value for possible logging */
|
||||
|
||||
r->headers_out.location->value.len = b->last - p;
|
||||
r->headers_out.location->value.data = p;
|
||||
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
}
|
||||
|
||||
if (!(r->headers_out.last_modified && r->headers_out.last_modified->key.len)
|
||||
&& r->headers_out.last_modified_time != -1)
|
||||
{
|
||||
b->last = ngx_cpymem(b->last, "Last-Modified: ",
|
||||
sizeof("Last-Modified: ") - 1);
|
||||
b->last = ngx_http_time(b->last, r->headers_out.last_modified_time);
|
||||
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
}
|
||||
|
||||
if (r->chunked) {
|
||||
b->last = ngx_cpymem(b->last, "Transfer-Encoding: chunked" CRLF,
|
||||
sizeof("Transfer-Encoding: chunked" CRLF) - 1);
|
||||
|
@ -436,7 +440,7 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
|||
i = 0;
|
||||
}
|
||||
|
||||
if (header[i].key.len == 0) {
|
||||
if (header[i].hash == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,8 @@ static ngx_command_t ngx_http_log_commands[] = {
|
|||
|
||||
|
||||
ngx_http_module_t ngx_http_log_module_ctx = {
|
||||
ngx_http_log_set_formats, /* pre conf */
|
||||
ngx_http_log_set_formats, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
ngx_http_log_create_main_conf, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -120,7 +121,7 @@ ngx_http_module_t ngx_http_log_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_log_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_log_module_ctx, /* module context */
|
||||
ngx_http_log_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -391,6 +392,11 @@ ngx_http_log_header_in_compile(ngx_conf_t *cf, ngx_http_log_op_t *op,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* STUB: "Cookie" speacial handling */
|
||||
if (ngx_http_headers_in[i].offset == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncasecmp(ngx_http_headers_in[i].name.data, value->data,
|
||||
value->len) == 0)
|
||||
{
|
||||
|
@ -733,22 +739,17 @@ static ngx_int_t
|
|||
ngx_http_log_variable_compile(ngx_conf_t *cf, ngx_http_log_op_t *op,
|
||||
ngx_str_t *value)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_http_variable_t *var;
|
||||
ngx_int_t index;
|
||||
|
||||
for (i = 0; i < value->len; i++) {
|
||||
value->data[i] = ngx_toupper(value->data[i]);
|
||||
}
|
||||
|
||||
var = ngx_http_add_variable(cf, value, 0);
|
||||
if (var == NULL) {
|
||||
index = ngx_http_get_variable_index(cf, value);
|
||||
if (index == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
op->len = 0;
|
||||
op->getlen = ngx_http_log_variable_getlen;
|
||||
op->run = ngx_http_log_variable;
|
||||
op->data = var->index;
|
||||
op->data = index;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -762,7 +763,7 @@ ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data)
|
|||
value = ngx_http_get_indexed_variable(r, data);
|
||||
|
||||
if (value == NULL
|
||||
|| value == NGX_HTTP_VARIABLE_NOT_FOUND
|
||||
|| value == NGX_HTTP_VAR_NOT_FOUND
|
||||
|| value->text.len == 0)
|
||||
{
|
||||
return 1;
|
||||
|
@ -780,7 +781,7 @@ ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
|
|||
value = ngx_http_get_indexed_variable(r, op->data);
|
||||
|
||||
if (value == NULL
|
||||
|| value == NGX_HTTP_VARIABLE_NOT_FOUND
|
||||
|| value == NGX_HTTP_VAR_NOT_FOUND
|
||||
|| value->text.len == 0)
|
||||
{
|
||||
*buf = '-';
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
#include <ngx_http.h>
|
||||
|
||||
|
||||
ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||
ngx_int_t
|
||||
ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||
{
|
||||
u_char c, ch, *p, *m;
|
||||
enum {
|
||||
|
@ -63,7 +64,7 @@ ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
|
||||
case sw_method:
|
||||
if (ch == ' ') {
|
||||
r->method_end = p;
|
||||
r->method_end = p - 1;
|
||||
m = r->request_start;
|
||||
|
||||
if (p - m == 3) {
|
||||
|
@ -502,7 +503,8 @@ done:
|
|||
}
|
||||
|
||||
|
||||
ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||
ngx_int_t
|
||||
ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||
{
|
||||
u_char c, ch, *p;
|
||||
ngx_uint_t hash;
|
||||
|
@ -513,7 +515,6 @@ ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
sw_value,
|
||||
sw_space_after_value,
|
||||
sw_ignore_line,
|
||||
sw_skip_line,
|
||||
sw_almost_done,
|
||||
sw_header_almost_done
|
||||
} state;
|
||||
|
@ -528,8 +529,6 @@ ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
|
||||
/* first char */
|
||||
case sw_start:
|
||||
r->invalid_header = 0;
|
||||
|
||||
switch (ch) {
|
||||
case CR:
|
||||
r->header_end = p;
|
||||
|
@ -548,18 +547,11 @@ ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
break;
|
||||
}
|
||||
|
||||
if (ch == '-') {
|
||||
hash = ch;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
hash = ch;
|
||||
break;
|
||||
}
|
||||
|
||||
r->invalid_header = 1;
|
||||
state = sw_skip_line;
|
||||
break;
|
||||
|
||||
}
|
||||
|
@ -589,18 +581,31 @@ ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
break;
|
||||
}
|
||||
|
||||
if (ch == CR) {
|
||||
r->header_name_end = p;
|
||||
r->header_start = p;
|
||||
r->header_end = p;
|
||||
state = sw_almost_done;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch == LF) {
|
||||
r->header_name_end = p;
|
||||
r->header_start = p;
|
||||
r->header_end = p;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* IIS may send the duplicate "HTTP/1.1 ..." lines */
|
||||
if (ch == '/'
|
||||
&& r->proxy
|
||||
&& p - r->header_start == 4
|
||||
&& ngx_strncmp(r->header_start, "HTTP", 4) == 0)
|
||||
&& r->upstream
|
||||
&& p - r->header_name_start == 4
|
||||
&& ngx_strncmp(r->header_name_start, "HTTP", 4) == 0)
|
||||
{
|
||||
state = sw_ignore_line;
|
||||
break;
|
||||
}
|
||||
|
||||
r->invalid_header = 1;
|
||||
state = sw_skip_line;
|
||||
break;
|
||||
|
||||
/* space* before header value */
|
||||
|
@ -609,11 +614,13 @@ ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
case ' ':
|
||||
break;
|
||||
case CR:
|
||||
r->header_start = r->header_end = p;
|
||||
r->header_start = p;
|
||||
r->header_end = p;
|
||||
state = sw_almost_done;
|
||||
break;
|
||||
case LF:
|
||||
r->header_start = r->header_end = p;
|
||||
r->header_start = p;
|
||||
r->header_end = p;
|
||||
goto done;
|
||||
default:
|
||||
r->header_start = p;
|
||||
|
@ -666,21 +673,6 @@ ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
|
|||
}
|
||||
break;
|
||||
|
||||
/* skip header line */
|
||||
case sw_skip_line:
|
||||
switch (ch) {
|
||||
case CR:
|
||||
r->header_end = p;
|
||||
state = sw_almost_done;
|
||||
break;
|
||||
case LF:
|
||||
r->header_end = p;
|
||||
goto done;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/* end of header line */
|
||||
case sw_almost_done:
|
||||
switch (ch) {
|
||||
|
@ -724,7 +716,8 @@ header_done:
|
|||
}
|
||||
|
||||
|
||||
ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
||||
ngx_int_t
|
||||
ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
||||
{
|
||||
u_char c, ch, decoded, *p, *u;
|
||||
enum {
|
||||
|
@ -1001,3 +994,75 @@ done:
|
|||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name,
|
||||
ngx_str_t *value)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
u_char *start, *last, *end, ch;
|
||||
ngx_table_elt_t **h;
|
||||
|
||||
h = headers->elts;
|
||||
|
||||
for (i = 0; i < headers->nelts; i++) {
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, headers->pool->log, 0,
|
||||
"parse header: \"%V: %V\"", &h[i]->key, &h[i]->value);
|
||||
|
||||
if (name->len > h[i]->value.len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
start = h[i]->value.data;
|
||||
end = h[i]->value.data + h[i]->value.len;
|
||||
|
||||
while (start < end) {
|
||||
|
||||
if (ngx_strncasecmp(start, name->data, name->len) != 0) {
|
||||
goto skip;
|
||||
}
|
||||
|
||||
for (start += name->len; start < end && *start == ' '; start++) {
|
||||
/* void */
|
||||
}
|
||||
|
||||
if (value == NULL) {
|
||||
if (start == end || *start == ',') {
|
||||
return i;
|
||||
}
|
||||
|
||||
goto skip;
|
||||
}
|
||||
|
||||
if (start == end || *start++ != '=') {
|
||||
/* the invalid header value */
|
||||
goto skip;
|
||||
}
|
||||
|
||||
while (start < end && *start == ' ') { start++; }
|
||||
|
||||
for (last = start; last < end && *last != ';'; last++) {
|
||||
/* void */
|
||||
}
|
||||
|
||||
value->len = last - start;
|
||||
value->data = start;
|
||||
|
||||
return i;
|
||||
|
||||
skip:
|
||||
while (start < end) {
|
||||
ch = *start++;
|
||||
if (ch == ';' || ch == ',') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (start < end && *start == ' ') { start++; }
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
|
126
src/http/ngx_http_postpone_filter_module.c
Normal file
126
src/http/ngx_http_postpone_filter_module.c
Normal file
|
@ -0,0 +1,126 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) Igor Sysoev
|
||||
*/
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_postpone_filter_init(ngx_cycle_t *cycle);
|
||||
|
||||
|
||||
static ngx_http_module_t ngx_http_postpone_filter_module_ctx = {
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
||||
NULL, /* create server configuration */
|
||||
NULL, /* merge server configuration */
|
||||
|
||||
NULL, /* create location configuration */
|
||||
NULL /* merge location configuration */
|
||||
};
|
||||
|
||||
|
||||
ngx_module_t ngx_http_postpone_filter_module = {
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_postpone_filter_module_ctx, /* module context */
|
||||
NULL, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
ngx_http_postpone_filter_init, /* init module */
|
||||
NULL /* init process */
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_output_body_filter_pt ngx_http_next_filter;
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_chain_t *out;
|
||||
ngx_http_postponed_request_t *pr, **ppr;
|
||||
|
||||
if (r->connection->write->error) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http postpone filter \"%V\" %p", &r->uri, in);
|
||||
|
||||
if (r != r->connection->data || (r->postponed && in)) {
|
||||
|
||||
if (r->postponed) {
|
||||
for (pr = r->postponed; pr->next; pr = pr->next) { /* void */ }
|
||||
|
||||
ppr = pr->request ? &pr->next : NULL;
|
||||
|
||||
} else {
|
||||
ppr = &r->postponed;
|
||||
#if (NGX_SUPPRESS_WARN)
|
||||
pr = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ppr) {
|
||||
pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
|
||||
if (pr == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ppr = pr;
|
||||
|
||||
pr->request = NULL;
|
||||
pr->out = NULL;
|
||||
pr->next = NULL;
|
||||
}
|
||||
|
||||
if (ngx_chain_add_copy(r->pool, &pr->out, in) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (r != r->connection->data || r->postponed->request) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
if (r->postponed) {
|
||||
out = r->postponed->out;
|
||||
r->postponed = r->postponed->next;
|
||||
|
||||
} else {
|
||||
out = in;
|
||||
}
|
||||
|
||||
if (out == NULL && r->out == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http postpone filter out \"%V\"", &r->uri);
|
||||
|
||||
rc = ngx_http_next_filter(r->main ? r->main : r, out);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
/* NGX_ERROR may be returned by any filter */
|
||||
r->connection->write->error = 1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_postpone_filter_init(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_http_next_filter = ngx_http_top_body_filter;
|
||||
ngx_http_top_body_filter = ngx_http_postpone_filter;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -8,6 +8,9 @@
|
|||
#define _NGX_HTTP_REQUEST_H_INCLUDED_
|
||||
|
||||
|
||||
#define NGX_HTTP_MAX_REWRITE_CYCLES 10
|
||||
|
||||
|
||||
#define NGX_HTTP_DISCARD_BUFFER_SIZE 4096
|
||||
#define NGX_HTTP_LINGERING_BUFFER_SIZE 4096
|
||||
|
||||
|
@ -114,9 +117,16 @@ typedef enum {
|
|||
typedef struct {
|
||||
ngx_str_t name;
|
||||
ngx_uint_t offset;
|
||||
ngx_http_header_handler_pt handler;
|
||||
} ngx_http_header_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
ngx_uint_t offset;
|
||||
} ngx_http_header0_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_list_t headers;
|
||||
|
||||
|
@ -183,7 +193,6 @@ typedef struct {
|
|||
|
||||
ngx_table_elt_t *server;
|
||||
ngx_table_elt_t *date;
|
||||
ngx_table_elt_t *content_type;
|
||||
ngx_table_elt_t *content_length;
|
||||
ngx_table_elt_t *content_encoding;
|
||||
ngx_table_elt_t *location;
|
||||
|
@ -192,12 +201,14 @@ typedef struct {
|
|||
ngx_table_elt_t *accept_ranges;
|
||||
ngx_table_elt_t *www_authenticate;
|
||||
ngx_table_elt_t *expires;
|
||||
ngx_table_elt_t *cache_control;
|
||||
ngx_table_elt_t *etag;
|
||||
|
||||
ngx_str_t content_type;
|
||||
ngx_str_t charset;
|
||||
ngx_array_t ranges;
|
||||
|
||||
ngx_array_t cache_control;
|
||||
|
||||
off_t content_length_n;
|
||||
time_t date_time;
|
||||
time_t last_modified_time;
|
||||
|
@ -215,24 +226,6 @@ typedef struct {
|
|||
} ngx_http_request_body_t;
|
||||
|
||||
|
||||
struct ngx_http_cleanup_s {
|
||||
union {
|
||||
struct {
|
||||
ngx_fd_t fd;
|
||||
u_char *name;
|
||||
} file;
|
||||
|
||||
struct {
|
||||
ngx_http_cache_hash_t *hash;
|
||||
ngx_http_cache_entry_t *cache;
|
||||
} cache;
|
||||
} data;
|
||||
|
||||
unsigned valid:1;
|
||||
unsigned cache:1;
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_request_t *request;
|
||||
|
||||
|
@ -246,7 +239,18 @@ typedef struct {
|
|||
} ngx_http_connection_t;
|
||||
|
||||
|
||||
typedef struct ngx_http_postponed_request_s ngx_http_postponed_request_t;
|
||||
|
||||
struct ngx_http_postponed_request_s {
|
||||
ngx_http_request_t *request;
|
||||
ngx_chain_t *out;
|
||||
ngx_http_postponed_request_t *next;
|
||||
};
|
||||
|
||||
|
||||
typedef ngx_int_t (*ngx_http_handler_pt)(ngx_http_request_t *r);
|
||||
typedef void (*ngx_http_event_handler_pt)(ngx_http_request_t *r);
|
||||
|
||||
|
||||
struct ngx_http_request_s {
|
||||
uint32_t signature; /* "HTTP" */
|
||||
|
@ -258,12 +262,13 @@ struct ngx_http_request_s {
|
|||
void **srv_conf;
|
||||
void **loc_conf;
|
||||
|
||||
ngx_http_event_handler_pt read_event_handler;
|
||||
ngx_http_event_handler_pt write_event_handler;
|
||||
|
||||
ngx_http_cache_t *cache;
|
||||
|
||||
ngx_http_upstream_t *upstream;
|
||||
|
||||
ngx_file_t file;
|
||||
|
||||
ngx_pool_t *pool;
|
||||
ngx_buf_t *header_in;
|
||||
|
||||
|
@ -289,7 +294,10 @@ struct ngx_http_request_s {
|
|||
ngx_str_t method_name;
|
||||
ngx_str_t http_protocol;
|
||||
|
||||
ngx_chain_t *out;
|
||||
ngx_http_request_t *main;
|
||||
ngx_http_request_t *parent;
|
||||
ngx_http_postponed_request_t *postponed;
|
||||
|
||||
uint32_t in_addr;
|
||||
ngx_uint_t port;
|
||||
|
@ -303,19 +311,18 @@ struct ngx_http_request_s {
|
|||
|
||||
ngx_http_variable_value_t **variables;
|
||||
|
||||
ngx_array_t cleanup;
|
||||
|
||||
/* used to learn the Apache compatible response length without a header */
|
||||
size_t header_size;
|
||||
|
||||
size_t request_length;
|
||||
|
||||
u_char *discarded_buffer;
|
||||
void **err_ctx;
|
||||
ngx_uint_t err_status;
|
||||
|
||||
ngx_http_connection_t *http_connection;
|
||||
|
||||
ngx_http_log_handler_pt log_handler;
|
||||
|
||||
unsigned http_state:4;
|
||||
|
||||
/* URI with "/." and on Win32 with "//" */
|
||||
|
@ -330,12 +337,11 @@ struct ngx_http_request_s {
|
|||
/* URI with "\0" or "%00" */
|
||||
unsigned zero_in_uri:1;
|
||||
|
||||
unsigned valid_location:1;
|
||||
unsigned valid_unparsed_uri:1;
|
||||
unsigned uri_changed:1;
|
||||
unsigned uri_changes:4;
|
||||
|
||||
unsigned invalid_header:1;
|
||||
|
||||
unsigned low_case_exten:1;
|
||||
unsigned header_timeout_set:1;
|
||||
|
||||
|
@ -346,14 +352,16 @@ struct ngx_http_request_s {
|
|||
#if 0
|
||||
unsigned cachable:1;
|
||||
#endif
|
||||
unsigned pipeline:1;
|
||||
|
||||
unsigned pipeline:1;
|
||||
unsigned plain_http:1;
|
||||
unsigned chunked:1;
|
||||
unsigned header_only:1;
|
||||
unsigned keepalive:1;
|
||||
unsigned lingering_close:1;
|
||||
unsigned internal:1;
|
||||
unsigned closed:1;
|
||||
unsigned done:1;
|
||||
|
||||
unsigned filter_need_in_memory:1;
|
||||
unsigned filter_ssi_need_in_memory:1;
|
||||
|
@ -365,8 +373,6 @@ struct ngx_http_request_s {
|
|||
unsigned stat_writing:1;
|
||||
#endif
|
||||
|
||||
ngx_uint_t headers_n;
|
||||
|
||||
/* used to parse HTTP headers */
|
||||
ngx_uint_t state;
|
||||
u_char *uri_start;
|
||||
|
@ -391,8 +397,7 @@ struct ngx_http_request_s {
|
|||
|
||||
|
||||
extern ngx_http_header_t ngx_http_headers_in[];
|
||||
extern ngx_http_header_t ngx_http_headers_out[];
|
||||
|
||||
extern ngx_http_header0_t ngx_http_headers_out[];
|
||||
|
||||
|
||||
#endif /* _NGX_HTTP_REQUEST_H_INCLUDED_ */
|
||||
|
|
|
@ -10,9 +10,8 @@
|
|||
#include <ngx_http.h>
|
||||
|
||||
|
||||
static void ngx_http_read_client_request_body_handler(ngx_event_t *rev);
|
||||
static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r,
|
||||
ngx_connection_t *c);
|
||||
static void ngx_http_read_client_request_body_handler(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r);
|
||||
|
||||
/*
|
||||
* on completion ngx_http_read_client_request_body() adds to
|
||||
|
@ -29,10 +28,14 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
|
|||
ssize_t size;
|
||||
ngx_buf_t *b;
|
||||
ngx_chain_t *cl;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_body_t *rb;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
if (r->request_body) {
|
||||
post_handler(r);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
|
||||
if (rb == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
|
@ -40,16 +43,6 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
|
|||
|
||||
r->request_body = rb;
|
||||
|
||||
/* STUB */
|
||||
if (r->file.fd != NGX_INVALID_FILE) {
|
||||
if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
|
||||
ngx_close_file_n " \"%V\" failed", &r->file.name);
|
||||
}
|
||||
r->file.fd = NGX_INVALID_FILE;
|
||||
}
|
||||
/**/
|
||||
|
||||
if (r->headers_in.content_length_n <= 0) {
|
||||
post_handler(r);
|
||||
return NGX_OK;
|
||||
|
@ -138,30 +131,23 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
|
|||
rb->bufs = cl;
|
||||
}
|
||||
|
||||
c = r->connection;
|
||||
r->read_event_handler = ngx_http_read_client_request_body_handler;
|
||||
|
||||
c->read->event_handler = ngx_http_read_client_request_body_handler;
|
||||
|
||||
return ngx_http_do_read_client_request_body(r, c);
|
||||
return ngx_http_do_read_client_request_body(r);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_read_client_request_body_handler(ngx_event_t *rev)
|
||||
ngx_http_read_client_request_body_handler(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ngx_int_t rc;
|
||||
|
||||
c = rev->data;
|
||||
r = c->data;
|
||||
|
||||
if (rev->timedout) {
|
||||
if (r->connection->read->timedout) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = ngx_http_do_read_client_request_body(r, c);
|
||||
rc = ngx_http_do_read_client_request_body(r);
|
||||
|
||||
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
|
||||
ngx_http_finalize_request(r, rc);
|
||||
|
@ -170,16 +156,17 @@ ngx_http_read_client_request_body_handler(ngx_event_t *rev)
|
|||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_do_read_client_request_body(ngx_http_request_t *r,
|
||||
ngx_connection_t *c)
|
||||
ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
||||
{
|
||||
size_t size;
|
||||
ssize_t n;
|
||||
ngx_buf_t *b;
|
||||
ngx_temp_file_t *tf;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_body_t *rb;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
c = r->connection;
|
||||
rb = r->request_body;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
|
@ -218,8 +205,6 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
rb->temp_file->offset += n;
|
||||
|
||||
rb->buf->pos = rb->buf->start;
|
||||
rb->buf->last = rb->buf->start;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,107 +9,274 @@
|
|||
#include <ngx_http.h>
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_script_compile_lite(ngx_conf_t *cf, ngx_array_t *sources,
|
||||
ngx_array_t **lengths, ngx_array_t **values,
|
||||
ngx_http_script_compile_lite_start_pt start,
|
||||
ngx_http_script_compile_lite_end_pt end)
|
||||
#define ngx_http_script_exit (u_char *) &ngx_http_script_exit_code
|
||||
|
||||
static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL;
|
||||
|
||||
|
||||
ngx_uint_t
|
||||
ngx_http_script_variables_count(ngx_str_t *value)
|
||||
{
|
||||
uintptr_t *code;
|
||||
ngx_uint_t i;
|
||||
ngx_table_elt_t *src;
|
||||
ngx_http_variable_t *var;
|
||||
ngx_http_script_var_code_t *var_code;
|
||||
ngx_uint_t i, n;
|
||||
|
||||
if (sources->nelts == 0) {
|
||||
return NGX_OK;
|
||||
for (n = 0, i = 0; i < value->len; i++) {
|
||||
if (value->data[i] == '$') {
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
if (*lengths == NULL) {
|
||||
*lengths = ngx_array_create(cf->pool, 64, 1);
|
||||
if (*lengths == NULL) {
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_script_compile(ngx_http_script_compile_t *sc)
|
||||
{
|
||||
u_char ch;
|
||||
size_t size;
|
||||
ngx_int_t index;
|
||||
ngx_str_t name;
|
||||
uintptr_t *code;
|
||||
ngx_uint_t i, n, bracket;
|
||||
ngx_http_script_var_code_t *var_code;
|
||||
ngx_http_script_copy_code_t *copy;
|
||||
ngx_http_script_copy_capture_code_t *copy_capture;
|
||||
|
||||
if (*sc->lengths == NULL) {
|
||||
n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
|
||||
+ sizeof(ngx_http_script_var_code_t))
|
||||
+ sizeof(uintptr_t);
|
||||
|
||||
*sc->lengths = ngx_array_create(sc->cf->pool, n, 1);
|
||||
if (*sc->lengths == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (*values == NULL) {
|
||||
*values = ngx_array_create(cf->pool, 256, 1);
|
||||
if (*values == NULL) {
|
||||
|
||||
if (*sc->values == NULL) {
|
||||
n = (sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
|
||||
+ sizeof(ngx_http_script_var_code_t))
|
||||
+ sizeof(uintptr_t)
|
||||
+ sc->source->len
|
||||
+ sizeof(uintptr_t) - 1)
|
||||
& ~(sizeof(uintptr_t) - 1);
|
||||
|
||||
*sc->values = ngx_array_create(sc->cf->pool, n, 1);
|
||||
if (*sc->values == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
src = sources->elts;
|
||||
for (i = 0; i < sources->nelts; i++) {
|
||||
sc->variables = 0;
|
||||
|
||||
if (src[i].value.data[0] == '$') {
|
||||
if (start(&src[i], *lengths, *values, 0) != NGX_OK) {
|
||||
for (i = 0; i < sc->source->len; /* void */ ) {
|
||||
|
||||
name.len = 0;
|
||||
|
||||
if (sc->source->data[i] == '$') {
|
||||
|
||||
if (++i == sc->source->len) {
|
||||
goto invalid_variable;
|
||||
}
|
||||
|
||||
if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {
|
||||
|
||||
copy_capture = ngx_http_script_add_code(*sc->lengths,
|
||||
sizeof(ngx_http_script_copy_capture_code_t),
|
||||
NULL);
|
||||
if (copy_capture == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
copy_capture->code = (ngx_http_script_code_pt)
|
||||
ngx_http_script_copy_capture_len_code;
|
||||
copy_capture->n = 2 * (sc->source->data[i] - '0');
|
||||
|
||||
copy_capture = ngx_http_script_add_code(*sc->values,
|
||||
sizeof(ngx_http_script_copy_capture_code_t),
|
||||
&sc->main);
|
||||
if (copy_capture == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
copy_capture->code = ngx_http_script_copy_capture_code;
|
||||
copy_capture->n = sc->source->data[i] - '0';
|
||||
|
||||
if (sc->ncaptures < copy_capture->n) {
|
||||
sc->ncaptures = copy_capture->n;
|
||||
}
|
||||
|
||||
copy_capture->n *= 2;
|
||||
|
||||
i++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sc->source->data[i] == '{') {
|
||||
bracket = 1;
|
||||
|
||||
if (++i == sc->source->len) {
|
||||
goto invalid_variable;
|
||||
}
|
||||
|
||||
name.data = &sc->source->data[i];
|
||||
|
||||
} else {
|
||||
bracket = 0;
|
||||
name.data = &sc->source->data[i];
|
||||
}
|
||||
|
||||
for ( /* void */ ; i < sc->source->len; i++, name.len++) {
|
||||
ch = sc->source->data[i];
|
||||
|
||||
if (ch == '}' && bracket) {
|
||||
i++;
|
||||
bracket = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ch >= 'A' && ch <= 'Z')
|
||||
|| (ch >= 'a' && ch <= 'z')
|
||||
|| (ch >= '0' && ch <= '9')
|
||||
|| ch == '_')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (bracket) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,
|
||||
"the closing bracket in \"%V\" "
|
||||
"variable is missing", &name);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
src[i].value.len--;
|
||||
src[i].value.data++;
|
||||
if (name.len == 0) {
|
||||
goto invalid_variable;
|
||||
}
|
||||
|
||||
var = ngx_http_add_variable(cf, &src[i].value, 0);
|
||||
sc->variables++;
|
||||
|
||||
if (var == NULL) {
|
||||
index = ngx_http_get_variable_index(sc->cf, &name);
|
||||
|
||||
if (index == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
var_code = ngx_array_push_n(*lengths,
|
||||
sizeof(ngx_http_script_var_code_t));
|
||||
var_code = ngx_http_script_add_code(*sc->lengths,
|
||||
sizeof(ngx_http_script_var_code_t),
|
||||
NULL);
|
||||
if (var_code == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
var_code->code = (ngx_http_script_code_pt)
|
||||
ngx_http_script_copy_var_len;
|
||||
var_code->index = var->index;
|
||||
ngx_http_script_copy_var_len_code;
|
||||
var_code->index = (uintptr_t) index;
|
||||
|
||||
|
||||
var_code = ngx_array_push_n(*values,
|
||||
sizeof(ngx_http_script_var_code_t));
|
||||
var_code = ngx_http_script_add_code(*sc->values,
|
||||
sizeof(ngx_http_script_var_code_t),
|
||||
&sc->main);
|
||||
if (var_code == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
var_code->code = ngx_http_script_copy_var;
|
||||
var_code->index = var->index;
|
||||
|
||||
|
||||
if (end(*lengths, *values) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
var_code->code = ngx_http_script_copy_var_code;
|
||||
var_code->index = (uintptr_t) index;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (start(&src[i], *lengths, *values, 1) != NGX_OK) {
|
||||
if (sc->source->data[i] == '?' && sc->compile_args) {
|
||||
sc->args = 1;
|
||||
sc->compile_args = 0;
|
||||
|
||||
code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t),
|
||||
&sc->main);
|
||||
if (code == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*code = (uintptr_t) ngx_http_script_start_args_code;
|
||||
|
||||
i++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
name.data = &sc->source->data[i];
|
||||
|
||||
while (i < sc->source->len
|
||||
&& sc->source->data[i] != '$'
|
||||
&& !(sc->source->data[i] == '?' && sc->compile_args))
|
||||
{
|
||||
i++;
|
||||
name.len++;
|
||||
}
|
||||
|
||||
sc->size += name.len;
|
||||
|
||||
copy = ngx_http_script_add_code(*sc->lengths,
|
||||
sizeof(ngx_http_script_copy_code_t),
|
||||
NULL);
|
||||
if (copy == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
|
||||
copy->len = name.len;
|
||||
|
||||
size = (sizeof(ngx_http_script_copy_code_t) + name.len
|
||||
+ sizeof(uintptr_t) - 1)
|
||||
& ~(sizeof(uintptr_t) - 1);
|
||||
|
||||
copy = ngx_http_script_add_code(*sc->values, size, &sc->main);
|
||||
if (copy == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
copy->code = ngx_http_script_copy_code;
|
||||
copy->len = name.len;
|
||||
|
||||
ngx_memcpy((u_char *) copy + sizeof(ngx_http_script_copy_code_t),
|
||||
name.data, name.len);
|
||||
}
|
||||
|
||||
code = ngx_array_push_n(*lengths, sizeof(uintptr_t));
|
||||
if (code == NULL) {
|
||||
return NGX_ERROR;
|
||||
if (sc->complete_lengths) {
|
||||
code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
|
||||
if (code == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*code = (uintptr_t) NULL;
|
||||
}
|
||||
|
||||
*code = (uintptr_t) NULL;
|
||||
if (sc->complete_values) {
|
||||
code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t),
|
||||
&sc->main);
|
||||
if (code == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
code = ngx_array_push_n(*values, sizeof(uintptr_t));
|
||||
if (code == NULL) {
|
||||
return NGX_ERROR;
|
||||
*code = (uintptr_t) NULL;
|
||||
}
|
||||
|
||||
*code = (uintptr_t) NULL;
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
invalid_variable:
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name");
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
static void *
|
||||
void *
|
||||
ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size)
|
||||
{
|
||||
if (*codes == NULL) {
|
||||
|
@ -122,51 +289,79 @@ ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size)
|
|||
return ngx_array_push_n(*codes, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void *
|
||||
ngx_http_script_add_code(ngx_array_t *codes, size_t size, void *code)
|
||||
{
|
||||
u_char *elts, **p;
|
||||
void *new;
|
||||
|
||||
elts = codes->elts;
|
||||
|
||||
new = ngx_array_push_n(codes, size);
|
||||
if (new == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (code) {
|
||||
if (elts != codes->elts) {
|
||||
p = code;
|
||||
*p += (u_char *) codes->elts - elts;
|
||||
}
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
ngx_http_script_copy_len(ngx_http_script_engine_t *e)
|
||||
ngx_http_script_copy_len_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_script_copy_code_t *code;
|
||||
|
||||
code = (ngx_http_script_copy_code_t *) e->lite.ip;
|
||||
code = (ngx_http_script_copy_code_t *) e->ip;
|
||||
|
||||
e->lite.ip += sizeof(ngx_http_script_copy_code_t);
|
||||
e->ip += sizeof(ngx_http_script_copy_code_t);
|
||||
|
||||
return code->len;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_script_copy(ngx_http_script_engine_t *e)
|
||||
ngx_http_script_copy_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_script_copy_code_t *code;
|
||||
|
||||
code = (ngx_http_script_copy_code_t *) e->lite.ip;
|
||||
code = (ngx_http_script_copy_code_t *) e->ip;
|
||||
|
||||
e->lite.pos = ngx_cpymem(e->lite.pos,
|
||||
e->lite.ip + sizeof(ngx_http_script_copy_code_t),
|
||||
code->len);
|
||||
if (!e->skip) {
|
||||
e->pos = ngx_cpymem(e->pos, e->ip + sizeof(ngx_http_script_copy_code_t),
|
||||
code->len);
|
||||
}
|
||||
|
||||
e->lite.ip += sizeof(ngx_http_script_copy_code_t)
|
||||
+ ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1));
|
||||
e->ip += sizeof(ngx_http_script_copy_code_t)
|
||||
+ ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1));
|
||||
|
||||
if (e->log) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script copy: \"%V\"", &e->buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
ngx_http_script_copy_var_len(ngx_http_script_engine_t *e)
|
||||
ngx_http_script_copy_var_len_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_variable_value_t *value;
|
||||
ngx_http_script_var_code_t *code;
|
||||
|
||||
code = (ngx_http_script_var_code_t *) e->lite.ip;
|
||||
code = (ngx_http_script_var_code_t *) e->ip;
|
||||
|
||||
e->lite.ip += sizeof(ngx_http_script_var_code_t);
|
||||
e->ip += sizeof(ngx_http_script_var_code_t);
|
||||
|
||||
value = ngx_http_get_indexed_variable(e->lite.request, code->index);
|
||||
value = ngx_http_get_indexed_variable(e->request, code->index);
|
||||
|
||||
if (value == NULL || value == NGX_HTTP_VARIABLE_NOT_FOUND) {
|
||||
if (value == NULL || value == NGX_HTTP_VAR_NOT_FOUND) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -175,20 +370,456 @@ ngx_http_script_copy_var_len(ngx_http_script_engine_t *e)
|
|||
|
||||
|
||||
void
|
||||
ngx_http_script_copy_var(ngx_http_script_engine_t *e)
|
||||
ngx_http_script_copy_var_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_variable_value_t *value;
|
||||
ngx_http_script_var_code_t *code;
|
||||
|
||||
code = (ngx_http_script_var_code_t *) e->lite.ip;
|
||||
code = (ngx_http_script_var_code_t *) e->ip;
|
||||
|
||||
e->lite.ip += sizeof(ngx_http_script_var_code_t);
|
||||
e->ip += sizeof(ngx_http_script_var_code_t);
|
||||
|
||||
value = ngx_http_get_indexed_variable(e->lite.request, code->index);
|
||||
if (!e->skip) {
|
||||
value = ngx_http_get_indexed_variable(e->request, code->index);
|
||||
|
||||
if (value == NULL || value == NGX_HTTP_VARIABLE_NOT_FOUND) {
|
||||
if (value == NULL || value == NGX_HTTP_VAR_NOT_FOUND) {
|
||||
return;
|
||||
}
|
||||
|
||||
e->pos = ngx_cpymem(e->pos, value->text.data, value->text.len);
|
||||
|
||||
if (e->log) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script var: \"%V\"", &e->buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_script_copy_capture_code_t *code;
|
||||
|
||||
code = (ngx_http_script_copy_capture_code_t *) e->ip;
|
||||
|
||||
e->ip += sizeof(ngx_http_script_copy_capture_code_t);
|
||||
|
||||
if ((e->args || e->quote)
|
||||
&& (e->request->quoted_uri || e->request->plus_in_uri))
|
||||
{
|
||||
return e->captures[code->n + 1] - e->captures[code->n]
|
||||
+ ngx_escape_uri(NULL,
|
||||
&e->line->data[e->captures[code->n]],
|
||||
e->captures[code->n + 1] - e->captures[code->n],
|
||||
NGX_ESCAPE_ARGS);
|
||||
} else {
|
||||
return e->captures[code->n + 1] - e->captures[code->n];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_script_copy_capture_code_t *code;
|
||||
|
||||
code = (ngx_http_script_copy_capture_code_t *) e->ip;
|
||||
|
||||
e->ip += sizeof(ngx_http_script_copy_capture_code_t);
|
||||
|
||||
if ((e->args || e->quote)
|
||||
&& (e->request->quoted_uri || e->request->plus_in_uri))
|
||||
{
|
||||
e->pos = (u_char *) ngx_escape_uri(e->pos,
|
||||
&e->line->data[e->captures[code->n]],
|
||||
e->captures[code->n + 1] - e->captures[code->n],
|
||||
NGX_ESCAPE_ARGS);
|
||||
} else {
|
||||
e->pos = ngx_cpymem(e->pos,
|
||||
&e->line->data[e->captures[code->n]],
|
||||
e->captures[code->n + 1] - e->captures[code->n]);
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script capture: \"%V\"", &e->buf);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_script_start_args_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script args");
|
||||
|
||||
e->args = e->pos;
|
||||
e->ip += sizeof(uintptr_t);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
size_t len;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t n;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_script_engine_t le;
|
||||
ngx_http_script_len_code_pt lcode;
|
||||
ngx_http_script_regex_code_t *code;
|
||||
|
||||
code = (ngx_http_script_regex_code_t *) e->ip;
|
||||
|
||||
r = e->request;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http script regex: \"%V\"", &code->name);
|
||||
|
||||
if (code->uri) {
|
||||
e->line = &r->uri;
|
||||
} else {
|
||||
e->sp--;
|
||||
e->line = &e->sp->text;
|
||||
}
|
||||
|
||||
rc = ngx_regex_exec(code->regex, e->line, e->captures, code->ncaptures);
|
||||
|
||||
if (rc == NGX_REGEX_NO_MATCHED) {
|
||||
if (e->log) {
|
||||
ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
|
||||
"\"%V\" does not match \"%V\"", &code->name, e->line);
|
||||
}
|
||||
|
||||
if (code->test) {
|
||||
e->sp->value = 0;
|
||||
e->sp->text.len = 0;
|
||||
e->sp->text.data = (u_char *) "";
|
||||
e->sp++;
|
||||
|
||||
e->ip += sizeof(ngx_http_script_regex_code_t);
|
||||
return;
|
||||
}
|
||||
|
||||
e->ip += code->next;
|
||||
return;
|
||||
}
|
||||
|
||||
e->lite.pos = ngx_cpymem(e->lite.pos, value->text.data, value->text.len);
|
||||
if (rc < 0) {
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"",
|
||||
rc, e->line, &code->name);
|
||||
|
||||
e->ip = ngx_http_script_exit;
|
||||
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->log) {
|
||||
ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
|
||||
"\"%V\" matches \"%V\"", &code->name, e->line);
|
||||
}
|
||||
|
||||
if (code->test) {
|
||||
e->sp->value = 1;
|
||||
e->sp->text.len = 1;
|
||||
e->sp->text.data = (u_char *) "1";
|
||||
e->sp++;
|
||||
|
||||
e->ip += sizeof(ngx_http_script_regex_code_t);
|
||||
return;
|
||||
}
|
||||
|
||||
if (code->status) {
|
||||
e->status = code->status;
|
||||
|
||||
if (!code->redirect) {
|
||||
e->ip = ngx_http_script_exit;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (code->uri) {
|
||||
r->internal = 1;
|
||||
r->valid_unparsed_uri = 0;
|
||||
|
||||
if (code->break_cycle) {
|
||||
r->valid_location = 0;
|
||||
|
||||
} else {
|
||||
r->uri_changed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (code->lengths == NULL) {
|
||||
e->buf.len = code->size;
|
||||
|
||||
if (code->uri) {
|
||||
if (rc && (r->quoted_uri || r->plus_in_uri)) {
|
||||
e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len,
|
||||
NGX_ESCAPE_ARGS);
|
||||
}
|
||||
}
|
||||
|
||||
for (n = 1; n < (ngx_uint_t) rc; n++) {
|
||||
e->buf.len += e->captures[2 * n + 1] - e->captures[2 * n];
|
||||
}
|
||||
|
||||
} else {
|
||||
ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
|
||||
|
||||
le.ip = code->lengths->elts;
|
||||
le.request = r;
|
||||
le.captures = e->captures;
|
||||
|
||||
len = 1; /* reserve 1 byte for possible "?" */
|
||||
|
||||
while (*(uintptr_t *) le.ip) {
|
||||
lcode = *(ngx_http_script_len_code_pt *) le.ip;
|
||||
len += lcode(&le);
|
||||
}
|
||||
|
||||
e->buf.len = len;
|
||||
}
|
||||
|
||||
if (code->args && code->add_args && r->args.len) {
|
||||
e->buf.len += r->args.len + 1;
|
||||
}
|
||||
|
||||
e->buf.data = ngx_palloc(r->pool, e->buf.len);
|
||||
if (e->buf.data == NULL) {
|
||||
e->ip = ngx_http_script_exit;
|
||||
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
e->quote = code->redirect;
|
||||
|
||||
e->pos = e->buf.data;
|
||||
|
||||
e->ip += sizeof(ngx_http_script_regex_code_t);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_script_regex_end_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_script_regex_end_code_t *code;
|
||||
|
||||
code = (ngx_http_script_regex_end_code_t *) e->ip;
|
||||
|
||||
r = e->request;
|
||||
|
||||
e->quote = 0;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http script regex end");
|
||||
|
||||
if (code->redirect) {
|
||||
|
||||
if (code->add_args && r->args.len) {
|
||||
*e->pos++ = (u_char) (code->args ? '&' : '?');
|
||||
e->pos = ngx_cpymem(e->pos, r->args.data, r->args.len);
|
||||
}
|
||||
|
||||
e->buf.len = e->pos - e->buf.data;
|
||||
|
||||
if (e->log) {
|
||||
ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
|
||||
"rewritten redirect: \"%V\"", &e->buf);
|
||||
}
|
||||
|
||||
r->headers_out.location = ngx_list_push(&r->headers_out.headers);
|
||||
if (r->headers_out.location == NULL) {
|
||||
e->ip = ngx_http_script_exit;
|
||||
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
r->headers_out.location->hash = 1;
|
||||
r->headers_out.location->key.len = sizeof("Location") - 1;
|
||||
r->headers_out.location->key.data = (u_char *) "Location";
|
||||
r->headers_out.location->value = e->buf;
|
||||
|
||||
e->ip += sizeof(ngx_http_script_regex_end_code_t);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->args) {
|
||||
e->buf.len = e->args - e->buf.data;
|
||||
|
||||
if (code->add_args && r->args.len) {
|
||||
*e->pos++ = '&';
|
||||
e->pos = ngx_cpymem(e->pos, r->args.data, r->args.len);
|
||||
}
|
||||
|
||||
r->args.len = e->pos - e->args;
|
||||
r->args.data = e->args;
|
||||
|
||||
e->args = NULL;
|
||||
|
||||
} else {
|
||||
e->buf.len = e->pos - e->buf.data;
|
||||
}
|
||||
|
||||
if (e->log) {
|
||||
ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
|
||||
"rewritten data: \"%V\", args: \"%V\"",
|
||||
&e->buf, &r->args);
|
||||
}
|
||||
|
||||
if (code->uri) {
|
||||
r->uri = e->buf;
|
||||
|
||||
if (ngx_http_set_exten(r) != NGX_OK) {
|
||||
e->ip = ngx_http_script_exit;
|
||||
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
e->ip += sizeof(ngx_http_script_regex_end_code_t);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_script_return_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_script_return_code_t *code;
|
||||
|
||||
code = (ngx_http_script_return_code_t *) e->ip;
|
||||
|
||||
e->status = code->status;
|
||||
|
||||
e->ip += sizeof(ngx_http_script_return_code_t) - sizeof(uintptr_t);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_script_if_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_script_if_code_t *code;
|
||||
|
||||
code = (ngx_http_script_if_code_t *) e->ip;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script if");
|
||||
|
||||
e->sp--;
|
||||
|
||||
if (e->sp->value) {
|
||||
if (code->loc_conf) {
|
||||
e->request->loc_conf = code->loc_conf;
|
||||
}
|
||||
|
||||
e->ip += sizeof(ngx_http_script_if_code_t);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script if false");
|
||||
|
||||
e->ip += code->next;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_script_value_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_script_value_code_t *code;
|
||||
|
||||
code = (ngx_http_script_value_code_t *) e->ip;
|
||||
|
||||
e->ip += sizeof(ngx_http_script_value_code_t);
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script value");
|
||||
|
||||
e->sp->value = (ngx_uint_t) code->value;
|
||||
e->sp->text.len = (size_t) code->text_len;
|
||||
e->sp->text.data = (u_char *) code->text_data;
|
||||
e->sp++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_script_set_var_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_variable_value_t *value;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
ngx_http_script_var_code_t *code;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script set var");
|
||||
|
||||
code = (ngx_http_script_var_code_t *) e->ip;
|
||||
|
||||
e->ip += sizeof(ngx_http_script_var_code_t);
|
||||
|
||||
r = e->request;
|
||||
|
||||
if (r->variables == NULL) {
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
||||
|
||||
r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
|
||||
* sizeof(ngx_http_variable_value_t *));
|
||||
if (r->variables == NULL) {
|
||||
e->ip = ngx_http_script_exit;
|
||||
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
value = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (value == NULL) {
|
||||
e->ip = ngx_http_script_exit;
|
||||
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
e->sp--;
|
||||
|
||||
*value = *e->sp;
|
||||
|
||||
r->variables[code->index] = value;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_script_var_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
ngx_http_variable_value_t *value;
|
||||
ngx_http_script_var_code_t *code;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script var");
|
||||
|
||||
code = (ngx_http_script_var_code_t *) e->ip;
|
||||
|
||||
e->ip += sizeof(ngx_http_script_var_code_t);
|
||||
|
||||
value = ngx_http_get_indexed_variable(e->request, code->index);
|
||||
|
||||
if (value == NULL || value == NGX_HTTP_VAR_NOT_FOUND) {
|
||||
e->sp->value = 0;
|
||||
e->sp->text.len = 0;
|
||||
e->sp->text.data = (u_char *) "";
|
||||
e->sp++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script var: %ui, \"%V\"", value->value, &value->text);
|
||||
|
||||
*e->sp = *value;
|
||||
e->sp++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_script_nop_code(ngx_http_script_engine_t *e)
|
||||
{
|
||||
e->ip += sizeof(uintptr_t);
|
||||
}
|
||||
|
|
|
@ -16,23 +16,48 @@
|
|||
typedef struct {
|
||||
u_char *ip;
|
||||
u_char *pos;
|
||||
ngx_http_variable_value_t *sp;
|
||||
|
||||
ngx_str_t buf;
|
||||
ngx_str_t *line;
|
||||
|
||||
/* the start of the rewritten arguments */
|
||||
u_char *args;
|
||||
|
||||
unsigned skip:1;
|
||||
unsigned quote:1;
|
||||
unsigned log:1;
|
||||
|
||||
int *captures;
|
||||
|
||||
ngx_int_t status;
|
||||
ngx_http_request_t *request;
|
||||
} ngx_http_script_lite_engine_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_lite_engine_t lite;
|
||||
} ngx_http_script_engine_t;
|
||||
|
||||
|
||||
typedef void (*ngx_http_script_code_pt) (ngx_http_script_engine_t *e);
|
||||
typedef size_t (*ngx_http_script_len_code_pt)
|
||||
(ngx_http_script_lite_engine_t *e);
|
||||
typedef struct {
|
||||
ngx_conf_t *cf;
|
||||
ngx_str_t *source;
|
||||
ngx_array_t **lengths;
|
||||
ngx_array_t **values;
|
||||
|
||||
typedef ngx_int_t (*ngx_http_script_compile_lite_start_pt) (ngx_table_elt_t *h,
|
||||
ngx_array_t *lengths, ngx_array_t *values, ngx_uint_t value);
|
||||
typedef ngx_int_t (*ngx_http_script_compile_lite_end_pt) (ngx_array_t *lengths,
|
||||
ngx_array_t *values);
|
||||
ngx_uint_t variables;
|
||||
ngx_uint_t ncaptures;
|
||||
ngx_uint_t size;
|
||||
|
||||
void *main;
|
||||
|
||||
unsigned compile_args:1;
|
||||
unsigned compile_null:1;
|
||||
unsigned complete_lengths:1;
|
||||
unsigned complete_values:1;
|
||||
|
||||
unsigned args:1;
|
||||
} ngx_http_script_compile_t;
|
||||
|
||||
|
||||
typedef void (*ngx_http_script_code_pt) (ngx_http_script_engine_t *e);
|
||||
typedef size_t (*ngx_http_script_len_code_pt) (ngx_http_script_engine_t *e);
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@ -47,20 +72,93 @@ typedef struct {
|
|||
} ngx_http_script_var_code_t;
|
||||
|
||||
|
||||
ngx_int_t ngx_http_script_compile_lite(ngx_conf_t *cf, ngx_array_t *sources,
|
||||
ngx_array_t **lengths, ngx_array_t **values,
|
||||
ngx_http_script_compile_lite_start_pt start,
|
||||
ngx_http_script_compile_lite_end_pt end);
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t n;
|
||||
} ngx_http_script_copy_capture_code_t;
|
||||
|
||||
|
||||
static void *ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes,
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
ngx_regex_t *regex;
|
||||
ngx_array_t *lengths;
|
||||
uintptr_t size;
|
||||
uintptr_t ncaptures;
|
||||
uintptr_t status;
|
||||
uintptr_t next;
|
||||
|
||||
uintptr_t test:1;
|
||||
uintptr_t uri:1;
|
||||
uintptr_t args:1;
|
||||
|
||||
/* add the r->args to the new arguments */
|
||||
uintptr_t add_args:1;
|
||||
|
||||
uintptr_t redirect:1;
|
||||
uintptr_t break_cycle:1;
|
||||
|
||||
ngx_str_t name;
|
||||
} ngx_http_script_regex_code_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
|
||||
uintptr_t uri:1;
|
||||
uintptr_t args:1;
|
||||
|
||||
/* add the r->args to the new arguments */
|
||||
uintptr_t add_args:1;
|
||||
|
||||
uintptr_t redirect:1;
|
||||
} ngx_http_script_regex_end_code_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t status;
|
||||
uintptr_t null;
|
||||
} ngx_http_script_return_code_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t next;
|
||||
void **loc_conf;
|
||||
} ngx_http_script_if_code_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_http_script_code_pt code;
|
||||
uintptr_t value;
|
||||
uintptr_t text_len;
|
||||
uintptr_t text_data;
|
||||
} ngx_http_script_value_code_t;
|
||||
|
||||
|
||||
ngx_uint_t ngx_http_script_variables_count(ngx_str_t *value);
|
||||
ngx_int_t ngx_http_script_compile(ngx_http_script_compile_t *sc);
|
||||
|
||||
void *ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes,
|
||||
size_t size);
|
||||
void *ngx_http_script_add_code(ngx_array_t *codes, size_t size, void *code);
|
||||
|
||||
size_t ngx_http_script_copy_len(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_copy(ngx_http_script_engine_t *e);
|
||||
size_t ngx_http_script_copy_var_len(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_copy_var(ngx_http_script_engine_t *e);
|
||||
|
||||
size_t ngx_http_script_copy_len_code(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_copy_code(ngx_http_script_engine_t *e);
|
||||
size_t ngx_http_script_copy_var_len_code(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_copy_var_code(ngx_http_script_engine_t *e);
|
||||
size_t ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_regex_start_code(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_regex_end_code(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_start_args_code(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_return_code(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_if_code(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_value_code(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_set_var_code(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_var_code(ngx_http_script_engine_t *e);
|
||||
void ngx_http_script_nop_code(ngx_http_script_engine_t *e);
|
||||
|
||||
|
||||
#endif /* _NGX_HTTP_SCRIPT_H_INCLUDED_ */
|
||||
|
|
|
@ -331,22 +331,15 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
|
|||
msie_padding = 1;
|
||||
}
|
||||
|
||||
r->headers_out.content_type = ngx_list_push(&r->headers_out.headers);
|
||||
if (r->headers_out.content_type == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.content_type->key.len = sizeof("Content-Type") - 1;
|
||||
r->headers_out.content_type->key.data = (u_char *) "Content-Type";
|
||||
r->headers_out.content_type->value.len = sizeof("text/html") - 1;
|
||||
r->headers_out.content_type->value.data = (u_char *) "text/html";
|
||||
r->headers_out.content_type.len = sizeof("text/html") - 1;
|
||||
r->headers_out.content_type.data = (u_char *) "text/html";
|
||||
|
||||
} else {
|
||||
r->headers_out.content_length_n = -1;
|
||||
}
|
||||
|
||||
if (r->headers_out.content_length) {
|
||||
r->headers_out.content_length->key.len = 0;
|
||||
r->headers_out.content_length->hash = 0;
|
||||
r->headers_out.content_length = NULL;
|
||||
}
|
||||
|
||||
|
@ -415,7 +408,11 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
|
|||
cl->buf = b;
|
||||
}
|
||||
|
||||
b->last_buf = 1;
|
||||
if (r->main == NULL) {
|
||||
b->last_buf = 1;
|
||||
}
|
||||
|
||||
b->last_in_chain = 1;
|
||||
|
||||
cl->next = NULL;
|
||||
|
||||
|
|
|
@ -6,14 +6,17 @@
|
|||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_http.h>
|
||||
#include <ngx_event_connect.h>
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
static void ngx_http_upstream_check_broken_connection(ngx_event_t *ev);
|
||||
static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r);
|
||||
static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r);
|
||||
static void ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
|
||||
ngx_event_t *ev);
|
||||
static void ngx_http_upstream_connect(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u);
|
||||
static void ngx_http_upstream_reinit(ngx_http_request_t *r,
|
||||
static ngx_int_t ngx_http_upstream_reinit(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u);
|
||||
static void ngx_http_upstream_send_request(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u);
|
||||
|
@ -21,6 +24,7 @@ static void ngx_http_upstream_send_request_handler(ngx_event_t *wev);
|
|||
static void ngx_http_upstream_process_header(ngx_event_t *rev);
|
||||
static void ngx_http_upstream_send_response(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u);
|
||||
static void ngx_http_upstream_process_downstream(ngx_http_request_t *r);
|
||||
static void ngx_http_upstream_process_body(ngx_event_t *ev);
|
||||
static void ngx_http_upstream_dummy_handler(ngx_event_t *wev);
|
||||
static void ngx_http_upstream_next(ngx_http_request_t *r,
|
||||
|
@ -28,19 +32,125 @@ static void ngx_http_upstream_next(ngx_http_request_t *r,
|
|||
static void ngx_http_upstream_finalize_request(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u, ngx_int_t rc);
|
||||
|
||||
static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_conditional_copy_header_line(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_upstream_copy_content_type(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_upstream_copy_content_length(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_upstream_rewrite_location(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
#if (NGX_HTTP_GZIP)
|
||||
static ngx_int_t ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
#endif
|
||||
|
||||
static size_t ngx_http_upstream_log_status_getlen(ngx_http_request_t *r,
|
||||
uintptr_t data);
|
||||
static u_char *ngx_http_upstream_log_status(ngx_http_request_t *r,
|
||||
u_char *buf, ngx_http_log_op_t *op);
|
||||
|
||||
static u_char *ngx_http_upstream_log_error(ngx_http_request_t *r, u_char *buf,
|
||||
size_t len);
|
||||
static ngx_int_t ngx_http_upstream_add_log_formats(ngx_conf_t *cf);
|
||||
static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
|
||||
|
||||
|
||||
ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
|
||||
|
||||
{ ngx_string("Status"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
offsetof(ngx_http_upstream_headers_in_t, status),
|
||||
/* STUB */ ngx_http_upstream_ignore_header_line, 0 },
|
||||
|
||||
{ ngx_string("Content-Type"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
offsetof(ngx_http_upstream_headers_in_t, content_type),
|
||||
ngx_http_upstream_copy_content_type, 0 },
|
||||
|
||||
{ ngx_string("Content-Length"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
offsetof(ngx_http_upstream_headers_in_t, content_length),
|
||||
ngx_http_upstream_copy_content_length, 0 },
|
||||
|
||||
{ ngx_string("Date"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
offsetof(ngx_http_upstream_headers_in_t, date),
|
||||
ngx_http_upstream_conditional_copy_header_line,
|
||||
offsetof(ngx_http_upstream_conf_t, pass_date) },
|
||||
|
||||
{ ngx_string("Server"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
offsetof(ngx_http_upstream_headers_in_t, server),
|
||||
ngx_http_upstream_conditional_copy_header_line,
|
||||
offsetof(ngx_http_upstream_conf_t, pass_server) },
|
||||
|
||||
{ ngx_string("Location"),
|
||||
ngx_http_upstream_ignore_header_line, 0,
|
||||
ngx_http_upstream_rewrite_location, 0 },
|
||||
|
||||
{ ngx_string("Refresh"),
|
||||
ngx_http_upstream_ignore_header_line, 0,
|
||||
ngx_http_upstream_rewrite_refresh, 0 },
|
||||
|
||||
{ ngx_string("Cache-Control"),
|
||||
ngx_http_upstream_process_multi_header_lines,
|
||||
offsetof(ngx_http_upstream_headers_in_t, cache_control),
|
||||
ngx_http_upstream_copy_multi_header_lines,
|
||||
offsetof(ngx_http_headers_out_t, cache_control) },
|
||||
|
||||
{ ngx_string("Connection"),
|
||||
ngx_http_upstream_ignore_header_line, 0,
|
||||
ngx_http_upstream_ignore_header_line, 0 },
|
||||
|
||||
{ ngx_string("X-Pad"),
|
||||
ngx_http_upstream_ignore_header_line, 0,
|
||||
ngx_http_upstream_ignore_header_line, 0 },
|
||||
|
||||
{ ngx_string("X-Powered-By"),
|
||||
ngx_http_upstream_ignore_header_line, 0,
|
||||
ngx_http_upstream_conditional_copy_header_line,
|
||||
offsetof(ngx_http_upstream_conf_t, pass_x_powered_by) },
|
||||
|
||||
{ ngx_string("X-Accel-Expires"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
offsetof(ngx_http_upstream_headers_in_t, x_accel_expires),
|
||||
ngx_http_upstream_conditional_copy_header_line,
|
||||
offsetof(ngx_http_upstream_conf_t, pass_x_accel_expires) },
|
||||
|
||||
#if (NGX_HTTP_GZIP)
|
||||
{ ngx_string("Content-Encoding"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
offsetof(ngx_http_upstream_headers_in_t, content_encoding),
|
||||
ngx_http_upstream_copy_content_encoding, 0 },
|
||||
#endif
|
||||
|
||||
{ ngx_null_string, NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
|
||||
ngx_http_module_t ngx_http_upstream_module_ctx = {
|
||||
ngx_http_upstream_add_log_formats, /* pre conf */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
ngx_http_upstream_add_log_formats, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
ngx_http_upstream_create_main_conf, /* create main configuration */
|
||||
ngx_http_core_init_main_conf, /* init main configuration */
|
||||
|
||||
NULL, /* create server configuration */
|
||||
NULL, /* merge server configuration */
|
||||
|
@ -51,7 +161,7 @@ ngx_http_module_t ngx_http_upstream_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_upstream_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_upstream_module_ctx, /* module context */
|
||||
NULL, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -77,8 +187,9 @@ char *ngx_http_upstream_header_errors[] = {
|
|||
void
|
||||
ngx_http_upstream_init(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
ngx_http_upstream_t *u;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_upstream_t *u;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
c = r->connection;
|
||||
|
||||
|
@ -89,11 +200,11 @@ ngx_http_upstream_init(ngx_http_request_t *r)
|
|||
ngx_del_timer(c->read);
|
||||
}
|
||||
|
||||
c->read->event_handler = ngx_http_upstream_check_broken_connection;
|
||||
r->read_event_handler = ngx_http_upstream_rd_check_broken_connection;
|
||||
|
||||
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
|
||||
|
||||
c->write->event_handler = ngx_http_upstream_check_broken_connection;
|
||||
r->write_event_handler = ngx_http_upstream_wr_check_broken_connection;
|
||||
|
||||
if (!c->write->active) {
|
||||
if (ngx_add_event(c->write, NGX_WRITE_EVENT,
|
||||
|
@ -107,7 +218,14 @@ ngx_http_upstream_init(ngx_http_request_t *r)
|
|||
|
||||
u = r->upstream;
|
||||
|
||||
u->method = r->method;
|
||||
u->request_bufs = r->request_body->bufs;
|
||||
|
||||
if (u->conf->method == NGX_CONF_UNSET_UINT) {
|
||||
u->method = r->method;
|
||||
|
||||
} else {
|
||||
u->method = u->conf->method;
|
||||
}
|
||||
|
||||
if (u->create_request(r) == NGX_ERROR) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
|
@ -115,14 +233,15 @@ ngx_http_upstream_init(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
u->peer.log = r->connection->log;
|
||||
u->saved_log_ctx = r->connection->log->data;
|
||||
u->saved_log_handler = r->connection->log->handler;
|
||||
r->connection->log->data = u->log_ctx;
|
||||
r->connection->log->handler = u->log_handler;
|
||||
u->saved_log_handler = r->log_handler;
|
||||
r->log_handler = ngx_http_upstream_log_error;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
u->output.sendfile = r->connection->sendfile;
|
||||
u->output.pool = r->pool;
|
||||
u->output.bufs.num = 1;
|
||||
u->output.bufs.size = clcf->client_body_buffer_size;
|
||||
u->output.output_filter = ngx_chain_writer;
|
||||
u->output.filter_ctx = &u->writer;
|
||||
|
||||
|
@ -148,20 +267,33 @@ ngx_http_upstream_init(ngx_http_request_t *r)
|
|||
|
||||
|
||||
static void
|
||||
ngx_http_upstream_check_broken_connection(ngx_event_t *ev)
|
||||
ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_http_upstream_check_broken_connection(r, r->connection->read);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_http_upstream_check_broken_connection(r, r->connection->write);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
|
||||
ngx_event_t *ev)
|
||||
{
|
||||
int n;
|
||||
char buf[1];
|
||||
ngx_err_t err;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, 0,
|
||||
"http upstream check client, write event:%d", ev->write);
|
||||
|
||||
c = ev->data;
|
||||
r = c->data;
|
||||
c = r->connection;
|
||||
u = r->upstream;
|
||||
|
||||
if (u->peer.connection == NULL) {
|
||||
|
@ -296,8 +428,8 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
c = u->peer.connection;
|
||||
|
||||
c->data = r;
|
||||
c->write->event_handler = ngx_http_upstream_send_request_handler;
|
||||
c->read->event_handler = ngx_http_upstream_process_header;
|
||||
c->write->handler = ngx_http_upstream_send_request_handler;
|
||||
c->read->handler = ngx_http_upstream_process_header;
|
||||
|
||||
c->sendfile = r->connection->sendfile;
|
||||
|
||||
|
@ -312,11 +444,20 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
u->writer.limit = 0;
|
||||
|
||||
if (u->request_sent) {
|
||||
ngx_http_upstream_reinit(r, u);
|
||||
if (ngx_http_upstream_reinit(r, u) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (r->request_body->buf) {
|
||||
if (r->request_body->temp_file) {
|
||||
if (r->request_body) {
|
||||
if (r->request_body->temp_file && r->main == NULL) {
|
||||
|
||||
/*
|
||||
* the r->request_body->buf can be reused for one request only,
|
||||
* the subrequests should allocate their own temporay bufs
|
||||
*/
|
||||
|
||||
u->output.free = ngx_alloc_chain_link(r->pool);
|
||||
if (u->output.free == NULL) {
|
||||
|
@ -332,9 +473,6 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
r->request_body->buf->pos = r->request_body->buf->start;
|
||||
r->request_body->buf->last = r->request_body->buf->start;
|
||||
r->request_body->buf->tag = u->output.tag;
|
||||
|
||||
} else {
|
||||
r->request_body->buf->pos = r->request_body->buf->start;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -351,29 +489,51 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
{
|
||||
ngx_chain_t *cl;
|
||||
|
||||
if (u->reinit_request(r) == NGX_ERROR) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
if (u->reinit_request(r) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memzero(&r->upstream->headers_in,
|
||||
sizeof(ngx_http_upstream_headers_in_t));
|
||||
|
||||
if (ngx_list_init(&r->upstream->headers_in.headers, r->pool, 8,
|
||||
sizeof(ngx_table_elt_t)) != NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/* reinit the request chain */
|
||||
|
||||
for (cl = r->request_body->bufs; cl; cl = cl->next) {
|
||||
for (cl = u->request_bufs; cl; cl = cl->next) {
|
||||
cl->buf->pos = cl->buf->start;
|
||||
cl->buf->file_pos = 0;
|
||||
}
|
||||
|
||||
/* reinit the ngx_output_chain() context */
|
||||
/* reinit the subrequest's ngx_output_chain() context */
|
||||
|
||||
if (r->request_body) {
|
||||
if (r->request_body->temp_file && r->main && u->output.buf) {
|
||||
|
||||
u->output.free = ngx_alloc_chain_link(r->pool);
|
||||
if (u->output.free == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
u->output.free->buf = u->output.buf;
|
||||
u->output.free->next = NULL;
|
||||
|
||||
u->output.buf->pos = u->output.buf->start;
|
||||
u->output.buf->last = u->output.buf->start;
|
||||
}
|
||||
}
|
||||
|
||||
u->output.buf = NULL;
|
||||
u->output.in = NULL;
|
||||
u->output.free = NULL;
|
||||
u->output.busy = NULL;
|
||||
|
||||
/* reinit u->header_in buffer */
|
||||
|
@ -388,20 +548,22 @@ ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
u->header_in.last = u->header_in.start;
|
||||
}
|
||||
#else
|
||||
|
||||
u->header_in.pos = u->header_in.start;
|
||||
u->header_in.last = u->header_in.start;
|
||||
|
||||
#endif
|
||||
|
||||
/* add one more state */
|
||||
|
||||
u->state = ngx_array_push(&u->states);
|
||||
if (u->state == NULL) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t));
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -433,8 +595,7 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
|
||||
c->log->action = "sending request to upstream";
|
||||
|
||||
rc = ngx_output_chain(&u->output,
|
||||
u->request_sent ? NULL : r->request_body->bufs);
|
||||
rc = ngx_output_chain(&u->output, u->request_sent ? NULL : u->request_bufs);
|
||||
|
||||
u->request_sent = 1;
|
||||
|
||||
|
@ -494,9 +655,9 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
}
|
||||
#endif
|
||||
|
||||
c->write->event_handler = ngx_http_upstream_dummy_handler;
|
||||
c->write->handler = ngx_http_upstream_dummy_handler;
|
||||
|
||||
if (ngx_handle_level_write_event(c->write) == NGX_ERROR) {
|
||||
if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
|
@ -575,6 +736,14 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
|
|||
|
||||
u->header_in.tag = u->output.tag;
|
||||
|
||||
if (ngx_list_init(&r->upstream->headers_in.headers, r->pool, 8,
|
||||
sizeof(ngx_table_elt_t)) == NGX_ERROR)
|
||||
{
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (u->cache) {
|
||||
u->header_in.pos += u->cache->ctx.header_size;
|
||||
|
@ -631,7 +800,7 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
|
|||
ngx_add_timer(rev, u->read_timeout);
|
||||
#endif
|
||||
|
||||
if (u->header_in.last == u->header_in.end) {
|
||||
if (u->header_in.pos == u->header_in.end) {
|
||||
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
||||
"upstream sent too big header");
|
||||
|
||||
|
@ -661,6 +830,38 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
|
|||
|
||||
/* rc == NGX_OK */
|
||||
|
||||
if (r->headers_out.status == NGX_HTTP_INTERNAL_SERVER_ERROR) {
|
||||
|
||||
if (u->peer.tries > 1
|
||||
&& (u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_HTTP_500))
|
||||
{
|
||||
ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_HTTP_500);
|
||||
return;
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
||||
if (u->peer.tries == 0
|
||||
&& u->stale
|
||||
&& (u->conf->use_stale & NGX_HTTP_UPSTREAM_FT_HTTP_500))
|
||||
{
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
ngx_http_send_cached_response(r));
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
if (r->headers_out.status == NGX_HTTP_NOT_FOUND
|
||||
&& u->peer.tries > 1
|
||||
&& u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_HTTP_404)
|
||||
{
|
||||
ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_HTTP_404);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (r->headers_out.status >= NGX_HTTP_BAD_REQUEST
|
||||
&& u->conf->redirect_errors
|
||||
&& r->err_ctx == NULL)
|
||||
|
@ -687,11 +888,55 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
|
|||
static void
|
||||
ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_event_pipe_t *p;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t i, key;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *h;
|
||||
ngx_event_pipe_t *p;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_upstream_header_t *hh;
|
||||
ngx_http_upstream_main_conf_t *umcf;
|
||||
|
||||
rc = u->send_header(r);
|
||||
umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
|
||||
hh = (ngx_http_upstream_header_t *) umcf->headers_in_hash.buckets;
|
||||
|
||||
part = &r->upstream->headers_in.headers.part;
|
||||
h = part->elts;
|
||||
|
||||
for (i = 0; /* void */; i++) {
|
||||
|
||||
if (i >= part->nelts) {
|
||||
if (part->next == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
part = part->next;
|
||||
h = part->elts;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
key = h[i].hash % umcf->headers_in_hash.hash_size;
|
||||
|
||||
if (hh[key].name.len == h[i].key.len
|
||||
&& ngx_strcasecmp(hh[key].name.data, h[i].key.data) == 0)
|
||||
{
|
||||
if (hh[key].copy_handler(r, &h[i], hh[key].conf) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_http_upstream_copy_header_line(r, &h[i], 0) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ngx_http_send_header(r);
|
||||
|
||||
if (rc == NGX_ERROR || rc > NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u, rc);
|
||||
|
@ -820,20 +1065,27 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
p->send_timeout = clcf->send_timeout;
|
||||
p->send_lowat = clcf->send_lowat;
|
||||
|
||||
u->peer.connection->read->event_handler = ngx_http_upstream_process_body;
|
||||
r->connection->write->event_handler = ngx_http_upstream_process_body;
|
||||
u->peer.connection->read->handler = ngx_http_upstream_process_body;
|
||||
r->write_event_handler = ngx_http_upstream_process_downstream;
|
||||
|
||||
ngx_http_upstream_process_body(u->peer.connection->read);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_upstream_process_downstream(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_http_upstream_process_body(r->connection->write);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_upstream_process_body(ngx_event_t *ev)
|
||||
{
|
||||
ngx_event_pipe_t *p;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_upstream_t *u;
|
||||
ngx_event_pipe_t *p;
|
||||
|
||||
c = ev->data;
|
||||
r = c->data;
|
||||
|
@ -1046,11 +1298,6 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
|
|||
rc = 0;
|
||||
}
|
||||
|
||||
if (u->saved_log_ctx) {
|
||||
r->connection->log->data = u->saved_log_ctx;
|
||||
r->connection->log->handler = u->saved_log_handler;
|
||||
}
|
||||
|
||||
if (u->pipe.temp_file) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http upstream temp fd: %d",
|
||||
|
@ -1065,15 +1312,7 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
|
|||
}
|
||||
#endif
|
||||
|
||||
if (u->pipe.temp_file) {
|
||||
r->file.fd = u->pipe.temp_file->file.fd;
|
||||
|
||||
#if 0
|
||||
} else if (u->cache) {
|
||||
r->file.fd = u->cache->ctx.file.fd;
|
||||
#endif
|
||||
}
|
||||
|
||||
r->log_handler = u->saved_log_handler;
|
||||
r->connection->log->action = "sending to client";
|
||||
|
||||
if (rc == 0 && r->main == NULL) {
|
||||
|
@ -1084,6 +1323,260 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_process_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->upstream->headers_in + offset);
|
||||
|
||||
if (*ph == NULL) {
|
||||
*ph = h;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset)
|
||||
{
|
||||
ngx_array_t *pa;
|
||||
ngx_table_elt_t **ph;
|
||||
|
||||
pa = (ngx_array_t *) ((char *) &r->upstream->headers_in + offset);
|
||||
|
||||
if (pa->elts == NULL) {
|
||||
if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ph = ngx_array_push(pa);
|
||||
if (ph == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ph = h;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
ngx_table_elt_t *ho;
|
||||
|
||||
ho = ngx_list_push(&r->headers_out.headers);
|
||||
if (ho == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_conditional_copy_header_line(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset)
|
||||
{
|
||||
ngx_flag_t *f;
|
||||
ngx_table_elt_t *ho;
|
||||
|
||||
f = (ngx_flag_t *) ((char *) r->upstream->conf + offset);
|
||||
|
||||
if (*f == 0) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ho = ngx_list_push(&r->headers_out.headers);
|
||||
if (ho == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset)
|
||||
{
|
||||
ngx_array_t *pa;
|
||||
ngx_table_elt_t *ho, **ph;
|
||||
|
||||
pa = (ngx_array_t *) ((char *) &r->headers_out + offset);
|
||||
|
||||
if (pa->elts == NULL) {
|
||||
if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ph = ngx_array_push(pa);
|
||||
if (ph == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ho = ngx_list_push(&r->headers_out.headers);
|
||||
if (ho == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
*ph = ho;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_copy_content_type(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
r->headers_out.content_type = h->value;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_copy_content_length(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
ngx_table_elt_t *ho;
|
||||
|
||||
ho = ngx_list_push(&r->headers_out.headers);
|
||||
if (ho == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
|
||||
r->headers_out.content_length = ho;
|
||||
r->headers_out.content_length_n = ngx_atoof(h->value.data, h->value.len);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_rewrite_location(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_table_elt_t *ho;
|
||||
|
||||
ho = ngx_list_push(&r->headers_out.headers);
|
||||
if (ho == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
|
||||
if (r->upstream->rewrite_redirect) {
|
||||
rc = r->upstream->rewrite_redirect(r, ho, 0);
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
r->headers_out.location = ho;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"rewritten location: \"%V\"", &ho->value);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* we do not set r->headers_out.location here to avoid the handling
|
||||
* the local redirects without a host name by ngx_http_header_filter()
|
||||
*/
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
u_char *p;
|
||||
ngx_int_t rc;
|
||||
ngx_table_elt_t *ho;
|
||||
|
||||
ho = ngx_list_push(&r->headers_out.headers);
|
||||
if (ho == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
|
||||
if (r->upstream->rewrite_redirect) {
|
||||
|
||||
p = (u_char *) ngx_strstr(ho->value.data, "url=");
|
||||
|
||||
if (p) {
|
||||
rc = r->upstream->rewrite_redirect(r, ho, p + 4 - ho->value.data);
|
||||
|
||||
} else {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
if (rc == NGX_OK) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"rewritten refresh: \"%V\"", &ho->value);
|
||||
}
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
#if (NGX_HTTP_GZIP)
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset)
|
||||
{
|
||||
ngx_table_elt_t *ho;
|
||||
|
||||
ho = ngx_list_push(&r->headers_out.headers);
|
||||
if (ho == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
|
||||
r->headers_out.content_encoding = ho;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static size_t
|
||||
ngx_http_upstream_log_status_getlen(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
|
@ -1131,51 +1624,45 @@ ngx_http_upstream_log_status(ngx_http_request_t *r, u_char *buf,
|
|||
}
|
||||
|
||||
|
||||
u_char *
|
||||
ngx_http_upstream_log_error(ngx_log_t *log, u_char *buf, size_t len)
|
||||
static u_char *
|
||||
ngx_http_upstream_log_error(ngx_http_request_t *r, u_char *buf, size_t len)
|
||||
{
|
||||
u_char *p;
|
||||
uintptr_t escape;
|
||||
ngx_http_log_ctx_t *ctx;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_upstream_t *u;
|
||||
ngx_peer_connection_t *peer;
|
||||
|
||||
ctx = log->data;
|
||||
r = ctx->request;
|
||||
u = r->upstream;
|
||||
peer = &u->peer;
|
||||
|
||||
p = ngx_snprintf(buf, len,
|
||||
" while %s, client: %V, server: %V, URL: \"%V\","
|
||||
", server: %V, URL: \"%V\","
|
||||
" upstream: %V%V%s%V",
|
||||
log->action,
|
||||
&r->connection->addr_text,
|
||||
&r->server_name,
|
||||
&r->unparsed_uri,
|
||||
&u->schema0,
|
||||
&u->conf->schema,
|
||||
&peer->peers->peer[peer->cur_peer].name,
|
||||
peer->peers->peer[peer->cur_peer].uri_separator,
|
||||
&u->uri0);
|
||||
&u->conf->uri);
|
||||
len -= p - buf;
|
||||
buf = p;
|
||||
|
||||
if (r->quoted_uri) {
|
||||
escape = 2 * ngx_escape_uri(NULL, r->uri.data + u->location0->len,
|
||||
r->uri.len - u->location0->len,
|
||||
escape = 2 * ngx_escape_uri(NULL, r->uri.data + u->conf->location->len,
|
||||
r->uri.len - u->conf->location->len,
|
||||
NGX_ESCAPE_URI);
|
||||
} else {
|
||||
escape = 0;
|
||||
}
|
||||
|
||||
if (escape) {
|
||||
if (len >= r->uri.len - u->location0->len + escape) {
|
||||
if (len >= r->uri.len - u->conf->location->len + escape) {
|
||||
|
||||
ngx_escape_uri(buf, r->uri.data + u->location0->len,
|
||||
r->uri.len - u->location0->len, NGX_ESCAPE_URI);
|
||||
ngx_escape_uri(buf, r->uri.data + u->conf->location->len,
|
||||
r->uri.len - u->conf->location->len, NGX_ESCAPE_URI);
|
||||
|
||||
buf += r->uri.len - u->location0->len + escape;
|
||||
len -= r->uri.len - u->location0->len + escape;
|
||||
buf += r->uri.len - u->conf->location->len + escape;
|
||||
len -= r->uri.len - u->conf->location->len + escape;
|
||||
|
||||
if (r->args.len) {
|
||||
p = ngx_snprintf(buf, len, "?%V", &r->args);
|
||||
|
@ -1186,19 +1673,19 @@ ngx_http_upstream_log_error(ngx_log_t *log, u_char *buf, size_t len)
|
|||
return ngx_http_log_error_info(r, buf, len);
|
||||
}
|
||||
|
||||
p = ngx_palloc(r->pool, r->uri.len - u->location0->len + escape);
|
||||
p = ngx_palloc(r->pool, r->uri.len - u->conf->location->len + escape);
|
||||
if (p == NULL) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
ngx_escape_uri(p, r->uri.data + u->location0->len,
|
||||
r->uri.len - u->location0->len, NGX_ESCAPE_URI);
|
||||
ngx_escape_uri(p, r->uri.data + u->conf->location->len,
|
||||
r->uri.len - u->conf->location->len, NGX_ESCAPE_URI);
|
||||
|
||||
p = ngx_cpymem(buf, p, r->uri.len - u->location0->len + escape);
|
||||
p = ngx_cpymem(buf, p, r->uri.len - u->conf->location->len + escape);
|
||||
|
||||
} else {
|
||||
p = ngx_cpymem(buf, r->uri.data + u->location0->len,
|
||||
r->uri.len - u->location0->len);
|
||||
p = ngx_cpymem(buf, r->uri.data + u->conf->location->len,
|
||||
r->uri.len - u->conf->location->len);
|
||||
}
|
||||
|
||||
len -= p - buf;
|
||||
|
@ -1232,3 +1719,43 @@ ngx_http_upstream_add_log_formats(ngx_conf_t *cf)
|
|||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_upstream_create_main_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_upstream_main_conf_t *umcf;
|
||||
|
||||
umcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_main_conf_t));
|
||||
if (umcf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return umcf;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
|
||||
{
|
||||
ngx_http_upstream_main_conf_t *umcf = conf;
|
||||
|
||||
umcf->headers_in_hash.max_size = 100;
|
||||
umcf->headers_in_hash.bucket_limit = 1;
|
||||
umcf->headers_in_hash.bucket_size = sizeof(ngx_http_upstream_header_t);
|
||||
umcf->headers_in_hash.name = "upstream_headers_in";
|
||||
|
||||
if (ngx_hash_init(&umcf->headers_in_hash, cf->pool,
|
||||
ngx_http_upstream_headers_in, 0) != NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
||||
"http upstream headers_in hash size: %ui, "
|
||||
"max buckets per entry: %ui",
|
||||
umcf->headers_in_hash.hash_size,
|
||||
umcf->headers_in_hash.min_buckets);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
|
|
@ -29,88 +29,141 @@
|
|||
|
||||
|
||||
typedef struct {
|
||||
time_t bl_time;
|
||||
ngx_uint_t bl_state;
|
||||
time_t bl_time;
|
||||
ngx_uint_t bl_state;
|
||||
|
||||
ngx_uint_t status;
|
||||
time_t time;
|
||||
ngx_uint_t status;
|
||||
time_t time;
|
||||
|
||||
ngx_str_t *peer;
|
||||
ngx_str_t *peer;
|
||||
} ngx_http_upstream_state_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_msec_t connect_timeout;
|
||||
ngx_msec_t send_timeout;
|
||||
ngx_msec_t read_timeout;
|
||||
ngx_hash_t headers_in_hash;
|
||||
} ngx_http_upstream_main_conf_t;
|
||||
|
||||
size_t send_lowat;
|
||||
size_t header_buffer_size;
|
||||
size_t busy_buffers_size;
|
||||
size_t max_temp_file_size;
|
||||
size_t temp_file_write_size;
|
||||
|
||||
ngx_uint_t next_upstream;
|
||||
typedef struct {
|
||||
ngx_msec_t connect_timeout;
|
||||
ngx_msec_t send_timeout;
|
||||
ngx_msec_t read_timeout;
|
||||
|
||||
ngx_bufs_t bufs;
|
||||
size_t send_lowat;
|
||||
size_t header_buffer_size;
|
||||
size_t busy_buffers_size;
|
||||
size_t max_temp_file_size;
|
||||
size_t temp_file_write_size;
|
||||
|
||||
ngx_flag_t redirect_errors;
|
||||
ngx_flag_t pass_unparsed_uri;
|
||||
ngx_flag_t x_powered_by;
|
||||
ngx_flag_t cyclic_temp_file;
|
||||
ngx_uint_t next_upstream;
|
||||
ngx_uint_t method;
|
||||
|
||||
ngx_path_t *temp_path;
|
||||
ngx_bufs_t bufs;
|
||||
|
||||
ngx_flag_t pass_request_headers;
|
||||
ngx_flag_t pass_request_body;
|
||||
|
||||
ngx_flag_t redirect_errors;
|
||||
ngx_flag_t pass_unparsed_uri;
|
||||
ngx_flag_t cyclic_temp_file;
|
||||
|
||||
ngx_flag_t pass_x_powered_by;
|
||||
ngx_flag_t pass_server;
|
||||
ngx_flag_t pass_date;
|
||||
ngx_flag_t pass_x_accel_expires;
|
||||
|
||||
ngx_path_t *temp_path;
|
||||
|
||||
ngx_str_t schema;
|
||||
ngx_str_t uri;
|
||||
ngx_str_t *location;
|
||||
ngx_str_t url; /* used in proxy_rewrite_location */
|
||||
} ngx_http_upstream_conf_t;
|
||||
|
||||
|
||||
typedef struct ngx_http_upstream_s ngx_http_upstream_t;
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
ngx_http_header_handler_pt handler;
|
||||
ngx_uint_t offset;
|
||||
ngx_http_header_handler_pt copy_handler;
|
||||
ngx_uint_t conf;
|
||||
} ngx_http_upstream_header_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_list_t headers;
|
||||
|
||||
ngx_table_elt_t *status;
|
||||
ngx_table_elt_t *date;
|
||||
ngx_table_elt_t *server;
|
||||
ngx_table_elt_t *connection;
|
||||
|
||||
ngx_table_elt_t *expires;
|
||||
ngx_table_elt_t *etag;
|
||||
ngx_table_elt_t *x_accel_expires;
|
||||
|
||||
ngx_table_elt_t *content_type;
|
||||
ngx_table_elt_t *content_length;
|
||||
|
||||
ngx_table_elt_t *last_modified;
|
||||
ngx_table_elt_t *location;
|
||||
ngx_table_elt_t *accept_ranges;
|
||||
|
||||
#if (NGX_HTTP_GZIP)
|
||||
ngx_table_elt_t *content_encoding;
|
||||
#endif
|
||||
|
||||
ngx_array_t cache_control;
|
||||
} ngx_http_upstream_headers_in_t;
|
||||
|
||||
|
||||
struct ngx_http_upstream_s {
|
||||
ngx_http_request_t *request;
|
||||
ngx_http_request_t *request;
|
||||
|
||||
ngx_peer_connection_t peer;
|
||||
ngx_peer_connection_t peer;
|
||||
|
||||
ngx_event_pipe_t pipe;
|
||||
ngx_event_pipe_t pipe;
|
||||
|
||||
ngx_output_chain_ctx_t output;
|
||||
ngx_chain_writer_ctx_t writer;
|
||||
ngx_chain_t *request_bufs;
|
||||
|
||||
ngx_http_upstream_conf_t *conf;
|
||||
ngx_output_chain_ctx_t output;
|
||||
ngx_chain_writer_ctx_t writer;
|
||||
|
||||
ngx_buf_t header_in;
|
||||
ngx_http_upstream_conf_t *conf;
|
||||
|
||||
ngx_int_t (*create_request)(ngx_http_request_t *r);
|
||||
ngx_int_t (*reinit_request)(ngx_http_request_t *r);
|
||||
ngx_int_t (*process_header)(ngx_http_request_t *r);
|
||||
ngx_int_t (*send_header)(ngx_http_request_t *r);
|
||||
void (*abort_request)(ngx_http_request_t *r);
|
||||
void (*finalize_request)(ngx_http_request_t *r,
|
||||
ngx_int_t rc);
|
||||
ngx_uint_t method;
|
||||
ngx_http_upstream_headers_in_t headers_in;
|
||||
|
||||
ngx_str_t schema0;
|
||||
ngx_str_t uri0;
|
||||
ngx_str_t *location0;
|
||||
ngx_buf_t header_in;
|
||||
|
||||
ngx_http_log_ctx_t *log_ctx;
|
||||
ngx_log_handler_pt log_handler;
|
||||
ngx_http_log_ctx_t *saved_log_ctx;
|
||||
ngx_log_handler_pt saved_log_handler;
|
||||
ngx_int_t (*create_request)(ngx_http_request_t *r);
|
||||
ngx_int_t (*reinit_request)(ngx_http_request_t *r);
|
||||
ngx_int_t (*process_header)(ngx_http_request_t *r);
|
||||
void (*abort_request)(ngx_http_request_t *r);
|
||||
void (*finalize_request)(ngx_http_request_t *r,
|
||||
ngx_int_t rc);
|
||||
ngx_int_t (*rewrite_redirect)(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, size_t prefix);
|
||||
|
||||
ngx_http_upstream_state_t *state;
|
||||
ngx_array_t states; /* of ngx_http_upstream_state_t */
|
||||
ngx_uint_t method;
|
||||
|
||||
unsigned cachable:1;
|
||||
ngx_http_log_handler_pt saved_log_handler;
|
||||
|
||||
unsigned request_sent:1;
|
||||
unsigned header_sent:1;
|
||||
ngx_http_upstream_state_t *state;
|
||||
ngx_array_t states; /* of ngx_http_upstream_state_t */
|
||||
|
||||
unsigned cachable:1;
|
||||
unsigned accel:1;
|
||||
|
||||
unsigned request_sent:1;
|
||||
unsigned header_sent:1;
|
||||
};
|
||||
|
||||
|
||||
void ngx_http_upstream_init(ngx_http_request_t *r);
|
||||
u_char *ngx_http_upstream_log_error(ngx_log_t *log, u_char *buf, size_t len);
|
||||
|
||||
|
||||
extern ngx_module_t ngx_http_upstream_module;
|
||||
|
||||
extern char *ngx_http_upstream_header_errors[];
|
||||
|
||||
|
||||
|
|
|
@ -10,66 +10,157 @@
|
|||
#include <ngx_http.h>
|
||||
|
||||
|
||||
#define NGX_HTTP_VARS_HASH_PRIME 29
|
||||
|
||||
#define ngx_http_vars_hash_key(key, vn) \
|
||||
{ \
|
||||
ngx_uint_t n; \
|
||||
for (key = 0, n = 0; n < (vn)->len; n++) { \
|
||||
key += (vn)->data[n]; \
|
||||
} \
|
||||
key %= NGX_HTTP_VARS_HASH_PRIME; \
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_request(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_header(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_unknown_header(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_host(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_remote_addr(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_uri(ngx_http_request_t *r, uintptr_t data);
|
||||
ngx_http_variable_remote_port(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_query_string(ngx_http_request_t *r, uintptr_t data);
|
||||
ngx_http_variable_server_addr(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_server_port(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_document_root(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_request_filename(ngx_http_request_t *r, uintptr_t data);
|
||||
|
||||
|
||||
static ngx_array_t *ngx_http_core_variables_hash;
|
||||
/*
|
||||
* TODO:
|
||||
* Apache CGI: AUTH_TYPE, PATH_INFO (null), PATH_TRANSLATED
|
||||
* REMOTE_HOST (null), REMOTE_IDENT (null),
|
||||
* SERVER_SOFTWARE
|
||||
*
|
||||
* Apache SSI: DATE_GMT, DOCUMENT_NAME, LAST_MODIFIED,
|
||||
* USER_NAME (file owner)
|
||||
*/
|
||||
|
||||
static ngx_http_variable_t ngx_http_core_variables[] = {
|
||||
|
||||
static ngx_http_core_variable_t ngx_http_core_variables[] = {
|
||||
{ ngx_string("http_host"), ngx_http_variable_header,
|
||||
offsetof(ngx_http_request_t, headers_in.host), 0 },
|
||||
|
||||
{ ngx_string("HTTP_HOST"), ngx_http_variable_header,
|
||||
offsetof(ngx_http_headers_in_t, host) },
|
||||
{ ngx_string("http_user_agent"), ngx_http_variable_header,
|
||||
offsetof(ngx_http_request_t, headers_in.user_agent), 0 },
|
||||
|
||||
{ ngx_string("HTTP_USER_AGENT"), ngx_http_variable_header,
|
||||
offsetof(ngx_http_headers_in_t, user_agent) },
|
||||
|
||||
{ ngx_string("HTTP_REFERER"), ngx_http_variable_header,
|
||||
offsetof(ngx_http_headers_in_t, referer) },
|
||||
{ ngx_string("http_referer"), ngx_http_variable_header,
|
||||
offsetof(ngx_http_request_t, headers_in.referer), 0 },
|
||||
|
||||
#if (NGX_HTTP_GZIP)
|
||||
{ ngx_string("HTTP_VIA"), ngx_http_variable_header,
|
||||
offsetof(ngx_http_headers_in_t, via) },
|
||||
{ ngx_string("http_via"), ngx_http_variable_header,
|
||||
offsetof(ngx_http_request_t, headers_in.via), 0 },
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_PROXY)
|
||||
{ ngx_string("HTTP_X_FORWARDED_FOR"), ngx_http_variable_header,
|
||||
offsetof(ngx_http_headers_in_t, x_forwarded_for) },
|
||||
{ ngx_string("http_x_forwarded_for"), ngx_http_variable_header,
|
||||
offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0 },
|
||||
#endif
|
||||
|
||||
{ ngx_string("REMOTE_ADDR"), ngx_http_variable_remote_addr, 0 },
|
||||
{ ngx_string("content_length"), ngx_http_variable_header,
|
||||
offsetof(ngx_http_request_t, headers_in.content_length), 0 },
|
||||
|
||||
{ ngx_string("DOCUMENT_URI"), ngx_http_variable_uri, 0 },
|
||||
{ ngx_string("content_type"), ngx_http_variable_header,
|
||||
offsetof(ngx_http_request_t, headers_in.content_type), 0 },
|
||||
|
||||
{ ngx_string("QUERY_STRING"), ngx_http_variable_query_string, 0 },
|
||||
{ ngx_string("host"), ngx_http_variable_host, 0, 0 },
|
||||
|
||||
{ ngx_null_string, NULL, 0 }
|
||||
{ ngx_string("remote_addr"), ngx_http_variable_remote_addr, 0, 0 },
|
||||
|
||||
{ ngx_string("remote_port"), ngx_http_variable_remote_port, 0, 0 },
|
||||
|
||||
{ ngx_string("server_addr"), ngx_http_variable_server_addr, 0, 0 },
|
||||
|
||||
{ ngx_string("server_port"), ngx_http_variable_server_port, 0, 0 },
|
||||
|
||||
{ ngx_string("server_protocol"), ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, http_protocol), 0 },
|
||||
|
||||
{ ngx_string("request_uri"), ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, unparsed_uri), 0 },
|
||||
|
||||
{ ngx_string("document_uri"), ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, uri), 0 },
|
||||
|
||||
{ ngx_string("document_root"), ngx_http_variable_document_root, 0, 0 },
|
||||
|
||||
{ ngx_string("query_string"), ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, args),
|
||||
NGX_HTTP_VAR_NOCACHABLE },
|
||||
|
||||
{ ngx_string("request_filename"), ngx_http_variable_request_filename, 0,
|
||||
NGX_HTTP_VAR_NOCACHABLE },
|
||||
|
||||
{ ngx_string("server_name"), ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, server_name), 0 },
|
||||
|
||||
{ ngx_string("request_method"), ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, method_name), 0 },
|
||||
|
||||
{ ngx_string("remote_user"), ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, headers_in.user), 0 },
|
||||
|
||||
{ ngx_null_string, NULL, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
ngx_http_variable_t *
|
||||
ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t set)
|
||||
ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_http_variable_t *v;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
|
||||
v = cmcf->all_variables.elts;
|
||||
for (i = 0; i < cmcf->all_variables.nelts; i++) {
|
||||
if (name->len != v[i].name.len
|
||||
|| ngx_strncasecmp(name->data, v[i].name.data, name->len) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(v[i].flags & NGX_HTTP_VAR_CHANGABLE)) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the duplicate \"%V\" variable", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &v[i];
|
||||
}
|
||||
|
||||
v = ngx_array_push(&cmcf->all_variables);
|
||||
if (v == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
v->name.len = name->len;
|
||||
v->name.data = ngx_palloc(cf->pool, name->len);
|
||||
if (v->name.data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < name->len; i++) {
|
||||
v->name.data[i] = ngx_tolower(name->data[i]);
|
||||
}
|
||||
|
||||
v->handler = NULL;
|
||||
v->data = 0;
|
||||
v->flags = flags;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_http_variable_t *v;
|
||||
|
@ -83,7 +174,7 @@ ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t set)
|
|||
if (ngx_array_init(&cmcf->variables, cf->pool, 4,
|
||||
sizeof(ngx_http_variable_t)) == NGX_ERROR)
|
||||
{
|
||||
return NULL;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -94,36 +185,30 @@ ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t set)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (set && v[i].handler) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the duplicate \"%V\" variable", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &v[i];
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
v = ngx_array_push(&cmcf->variables);
|
||||
if (v == NULL) {
|
||||
return NULL;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
v->name.len = name->len;
|
||||
v->name.data = ngx_palloc(cf->pool, name->len);
|
||||
if (v->name.data == NULL) {
|
||||
return NULL;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
for (i = 0; i < name->len; i++) {
|
||||
v->name.data[i] = ngx_toupper(name->data[i]);
|
||||
v->name.data[i] = ngx_tolower(name->data[i]);
|
||||
}
|
||||
|
||||
v->index = cmcf->variables.nelts - 1;
|
||||
v->handler = NULL;
|
||||
v->data = 0;
|
||||
v->flags = 0;
|
||||
|
||||
return v;
|
||||
return cmcf->variables.nelts - 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -158,7 +243,9 @@ ngx_http_get_indexed_variable(ngx_http_request_t *r, ngx_uint_t index)
|
|||
}
|
||||
}
|
||||
|
||||
r->variables[index] = vv;
|
||||
if (!(v[index].flags & NGX_HTTP_VAR_NOCACHABLE)) {
|
||||
r->variables[index] = vv;
|
||||
}
|
||||
|
||||
return vv;
|
||||
}
|
||||
|
@ -169,43 +256,56 @@ ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name)
|
|||
{
|
||||
ngx_uint_t i, key;
|
||||
ngx_http_variable_t *v;
|
||||
ngx_http_core_variable_t *cv;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
||||
|
||||
v = cmcf->variables.elts;
|
||||
for (i = 0; i < cmcf->variables.nelts; i++) {
|
||||
if (v[i].name.len != name->len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(v[i].name.data, name->data, name->len) == 0) {
|
||||
return ngx_http_get_indexed_variable(r, v[i].index);
|
||||
}
|
||||
key = 0;
|
||||
for (i = 0; i < name->len; i++) {
|
||||
key += name->data[i];
|
||||
}
|
||||
|
||||
ngx_http_vars_hash_key(key, name);
|
||||
key %= cmcf->variables_hash.hash_size;
|
||||
v = (ngx_http_variable_t *) cmcf->variables_hash.buckets;
|
||||
|
||||
cv = ngx_http_core_variables_hash[key].elts;
|
||||
for (i = 0; i < ngx_http_core_variables_hash[key].nelts; i++) {
|
||||
if (cv[i].name.len != name->len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(cv[i].name.data, name->data, name->len) == 0) {
|
||||
return cv[i].handler(r, cv[i].data);
|
||||
}
|
||||
if (v[key].name.len == name->len
|
||||
&& ngx_strncmp(v[key].name.data, name->data, name->len) == 0)
|
||||
{
|
||||
return v[key].handler(r, v[key].data);
|
||||
}
|
||||
|
||||
if (ngx_strncmp(name->data, "HTTP_", 5) == 0) {
|
||||
if (ngx_strncmp(name->data, "http_", 5) == 0) {
|
||||
return ngx_http_variable_unknown_header(r, (uintptr_t) name);
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"unknown \"%V\" variable", name);
|
||||
|
||||
return NGX_HTTP_VARIABLE_NOT_FOUND;
|
||||
return NGX_HTTP_VAR_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_request(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
ngx_str_t *s;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
s = (ngx_str_t *) ((char *) r + data);
|
||||
|
||||
if (s->data == NULL) {
|
||||
return NGX_HTTP_VAR_NOT_FOUND;
|
||||
}
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = 0;
|
||||
vv->text = *s;
|
||||
|
||||
return vv;
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,10 +315,10 @@ ngx_http_variable_header(ngx_http_request_t *r, uintptr_t data)
|
|||
ngx_table_elt_t *h;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
h = *(ngx_table_elt_t **) ((char *) &r->headers_in + data);
|
||||
h = *(ngx_table_elt_t **) ((char *) r + data);
|
||||
|
||||
if (h == NULL) {
|
||||
return NGX_HTTP_VARIABLE_NOT_FOUND;
|
||||
return NGX_HTTP_VAR_NOT_FOUND;
|
||||
}
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
|
@ -259,12 +359,11 @@ ngx_http_variable_unknown_header(ngx_http_request_t *r, uintptr_t data)
|
|||
i = 0;
|
||||
}
|
||||
|
||||
for (n = 0; n + 5 < var->len && n < header[i].key.len; n++)
|
||||
{
|
||||
for (n = 0; n + 5 < var->len && n < header[i].key.len; n++) {
|
||||
ch = header[i].key.data[n];
|
||||
|
||||
if (ch >= 'a' && ch <= 'z') {
|
||||
ch &= ~0x20;
|
||||
if (ch >= 'A' && ch <= 'Z') {
|
||||
ch |= 0x20;
|
||||
|
||||
} else if (ch == '-') {
|
||||
ch = '_';
|
||||
|
@ -287,7 +386,31 @@ ngx_http_variable_unknown_header(ngx_http_request_t *r, uintptr_t data)
|
|||
}
|
||||
}
|
||||
|
||||
return NGX_HTTP_VARIABLE_NOT_FOUND;
|
||||
return NGX_HTTP_VAR_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_host(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = 0;
|
||||
|
||||
if (r->headers_in.host) {
|
||||
vv->text.len = r->headers_in.host_name_len;
|
||||
vv->text.data = r->headers_in.host->value.data;
|
||||
|
||||
} else {
|
||||
vv->text = r->server_name;
|
||||
}
|
||||
|
||||
return vv;
|
||||
}
|
||||
|
||||
|
||||
|
@ -309,8 +432,10 @@ ngx_http_variable_remote_addr(ngx_http_request_t *r, uintptr_t data)
|
|||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_uri(ngx_http_request_t *r, uintptr_t data)
|
||||
ngx_http_variable_remote_port(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
ngx_uint_t port;
|
||||
struct sockaddr_in *sin;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
|
@ -319,15 +444,37 @@ ngx_http_variable_uri(ngx_http_request_t *r, uintptr_t data)
|
|||
}
|
||||
|
||||
vv->value = 0;
|
||||
vv->text = r->uri;
|
||||
vv->text.len = 0;
|
||||
|
||||
vv->text.data = ngx_palloc(r->pool, sizeof("65535") - 1);
|
||||
if (vv->text.data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* AF_INET only */
|
||||
|
||||
if (r->connection->sockaddr->sa_family == AF_INET) {
|
||||
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
||||
|
||||
port = ntohs(sin->sin_port);
|
||||
|
||||
if (port > 0 && port < 65536) {
|
||||
vv->value = port;
|
||||
vv->text.len = ngx_sprintf(vv->text.data, "%ui", port)
|
||||
- vv->text.data;
|
||||
}
|
||||
}
|
||||
|
||||
return vv;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_query_string(ngx_http_request_t *r, uintptr_t data)
|
||||
ngx_http_variable_server_addr(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
socklen_t len;
|
||||
ngx_connection_t *c;
|
||||
struct sockaddr_in sin;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
|
@ -336,84 +483,207 @@ ngx_http_variable_query_string(ngx_http_request_t *r, uintptr_t data)
|
|||
}
|
||||
|
||||
vv->value = 0;
|
||||
vv->text = r->args;
|
||||
|
||||
vv->text.data = ngx_palloc(r->pool, INET_ADDRSTRLEN);
|
||||
if (vv->text.data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
c = r->connection;
|
||||
|
||||
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");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r->in_addr = sin.sin_addr.s_addr;
|
||||
}
|
||||
|
||||
vv->text.len = ngx_inet_ntop(c->listening->family, &r->in_addr,
|
||||
vv->text.data, INET_ADDRSTRLEN);
|
||||
|
||||
return vv;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_server_port(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = r->port;
|
||||
vv->text.len = r->port_text->len - 1;
|
||||
vv->text.data = r->port_text->data + 1;
|
||||
|
||||
return vv;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_document_root(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
vv->value = 0;
|
||||
vv->text = clcf->root;
|
||||
|
||||
return vv;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_request_filename(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
u_char *p;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = 0;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (!clcf->alias) {
|
||||
vv->text.len = clcf->root.len + r->uri.len;
|
||||
vv->text.data = ngx_palloc(r->pool, vv->text.len);
|
||||
if (vv->text.data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = ngx_cpymem(vv->text.data, clcf->root.data, clcf->root.len);
|
||||
ngx_memcpy(p, r->uri.data, r->uri.len + 1);
|
||||
|
||||
} else {
|
||||
vv->text.len = clcf->root.len + r->uri.len + 2 - clcf->name.len;
|
||||
vv->text.data = ngx_palloc(r->pool, vv->text.len);
|
||||
if (vv->text.data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = ngx_cpymem(vv->text.data, clcf->root.data, clcf->root.len);
|
||||
ngx_memcpy(p, r->uri.data + clcf->name.len,
|
||||
r->uri.len + 1 - clcf->name.len);
|
||||
}
|
||||
|
||||
return vv;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_variables_init(ngx_cycle_t *cycle)
|
||||
ngx_http_variables_add_core_vars(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_uint_t i, j, key;
|
||||
ngx_http_variable_t *v;
|
||||
ngx_http_core_variable_t *cv, *vp;
|
||||
ngx_http_variable_t *v, *cv;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
ngx_http_core_variables_hash = ngx_palloc(cycle->pool,
|
||||
NGX_HTTP_VARS_HASH_PRIME
|
||||
* sizeof(ngx_array_t));
|
||||
if (ngx_http_core_variables_hash == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
|
||||
for (i = 0; i < NGX_HTTP_VARS_HASH_PRIME; i++) {
|
||||
if (ngx_array_init(&ngx_http_core_variables_hash[i], cycle->pool, 4,
|
||||
sizeof(ngx_http_core_variable_t)) == NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
if (ngx_array_init(&cmcf->all_variables, cf->pool, 32,
|
||||
sizeof(ngx_http_variable_t)) == NGX_ERROR)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
for (cv = ngx_http_core_variables; cv->name.len; cv++) {
|
||||
ngx_http_vars_hash_key(key, &cv->name);
|
||||
|
||||
vp = ngx_array_push(&ngx_http_core_variables_hash[key]);
|
||||
if (vp == NULL) {
|
||||
v = ngx_array_push(&cmcf->all_variables);
|
||||
if (v == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*vp = *cv;
|
||||
}
|
||||
|
||||
|
||||
cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module);
|
||||
|
||||
v = cmcf->variables.elts;
|
||||
for (i = 0; i < cmcf->variables.nelts; i++) {
|
||||
|
||||
if (v[i].handler) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_http_vars_hash_key(key, &v[i].name);
|
||||
|
||||
cv = ngx_http_core_variables_hash[key].elts;
|
||||
for (j = 0; j < ngx_http_core_variables_hash[key].nelts; j++) {
|
||||
if (cv[j].name.len != v[i].name.len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(cv[j].name.data, v[i].name.data, v[i].name.len)
|
||||
== 0)
|
||||
{
|
||||
v[i].handler = cv[j].handler;
|
||||
v[i].data = cv[j].data;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_strncmp(v[i].name.data, "HTTP_", 5) == 0) {
|
||||
v[i].handler = ngx_http_variable_unknown_header;
|
||||
v[i].data = (uintptr_t) &v[i].name;
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, cycle->log, 0,
|
||||
"unknown \"%V\" variable", &v[i].name);
|
||||
|
||||
return NGX_ERROR;
|
||||
*v = *cv;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_variables_init_vars(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_uint_t i, n;
|
||||
ngx_http_variable_t *v, *av;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
/* set the handlers for the indexed http variables */
|
||||
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
|
||||
v = cmcf->variables.elts;
|
||||
av = cmcf->all_variables.elts;
|
||||
|
||||
for (i = 0; i < cmcf->variables.nelts; i++) {
|
||||
|
||||
for (n = 0; n < cmcf->all_variables.nelts; n++) {
|
||||
|
||||
if (v[i].name.len == av[n].name.len
|
||||
&& ngx_strncmp(v[i].name.data, av[n].name.data, v[i].name.len)
|
||||
== 0)
|
||||
{
|
||||
v[i].handler = av[n].handler;
|
||||
v[i].data = av[n].data;
|
||||
v[i].flags = av[n].flags;
|
||||
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_strncmp(v[i].name.data, "http_", 5) == 0) {
|
||||
v[i].handler = ngx_http_variable_unknown_header;
|
||||
v[i].data = (uintptr_t) &v[i].name;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"unknown \"%V\" variable", &v[i].name);
|
||||
|
||||
return NGX_ERROR;
|
||||
|
||||
next:
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
||||
"http variables: %ui", cmcf->variables.nelts);
|
||||
|
||||
|
||||
/* init the all http variables hash */
|
||||
|
||||
cmcf->variables_hash.max_size = 500;
|
||||
cmcf->variables_hash.bucket_limit = 1;
|
||||
cmcf->variables_hash.bucket_size = sizeof(ngx_http_variable_t);
|
||||
cmcf->variables_hash.name = "http variables";
|
||||
|
||||
if (ngx_hash_init(&cmcf->variables_hash, cf->pool,
|
||||
cmcf->all_variables.elts, cmcf->all_variables.nelts) != NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
||||
"http variables hash size: %ui for %ui values, "
|
||||
"max buckets per entry: %ui",
|
||||
cmcf->variables_hash.hash_size, cmcf->all_variables.nelts,
|
||||
cmcf->variables_hash.min_buckets);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
#include <ngx_http.h>
|
||||
|
||||
|
||||
#define NGX_HTTP_VARIABLE_NOT_FOUND (ngx_http_variable_value_t *) -1
|
||||
#define NGX_HTTP_VAR_NOT_FOUND (ngx_http_variable_value_t *) -1
|
||||
|
||||
|
||||
struct ngx_http_variable_value_s {
|
||||
typedef struct {
|
||||
ngx_uint_t value;
|
||||
ngx_str_t text;
|
||||
};
|
||||
} ngx_http_variable_value_t;
|
||||
|
||||
typedef struct ngx_http_variable_s ngx_http_variable_t;
|
||||
|
||||
|
@ -28,30 +28,28 @@ typedef ngx_http_variable_value_t *
|
|||
(*ngx_http_get_variable_pt) (ngx_http_request_t *r, uintptr_t data);
|
||||
|
||||
|
||||
#define NGX_HTTP_VAR_CHANGABLE 1
|
||||
#define NGX_HTTP_VAR_NOCACHABLE 2
|
||||
|
||||
|
||||
struct ngx_http_variable_s {
|
||||
ngx_str_t name;
|
||||
ngx_uint_t index;
|
||||
ngx_str_t name; /* must be first to build the hash */
|
||||
ngx_http_get_variable_pt handler;
|
||||
uintptr_t data;
|
||||
ngx_uint_t flags;
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
ngx_http_get_variable_pt handler;
|
||||
uintptr_t data;
|
||||
} ngx_http_core_variable_t;
|
||||
|
||||
|
||||
ngx_http_variable_t *ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name,
|
||||
ngx_uint_t set);
|
||||
ngx_int_t ngx_http_get_variable_index(ngx_http_core_main_conf_t *cmcf,
|
||||
ngx_str_t *name);
|
||||
ngx_uint_t flags);
|
||||
ngx_int_t ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name);
|
||||
ngx_http_variable_value_t *ngx_http_get_indexed_variable(ngx_http_request_t *r,
|
||||
ngx_uint_t index);
|
||||
ngx_http_variable_value_t *ngx_http_get_variable(ngx_http_request_t *r,
|
||||
ngx_str_t *name);
|
||||
ngx_int_t ngx_http_variables_init(ngx_cycle_t *cycle);
|
||||
|
||||
ngx_int_t ngx_http_variables_add_core_vars(ngx_conf_t *cf);
|
||||
ngx_int_t ngx_http_variables_init_vars(ngx_conf_t *cf);
|
||||
|
||||
|
||||
#endif /* _NGX_HTTP_VARIABLES_H_INCLUDED_ */
|
||||
|
|
|
@ -10,16 +10,12 @@
|
|||
#include <ngx_http.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_chain_t *out;
|
||||
} ngx_http_write_filter_ctx_t;
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_write_filter_init(ngx_cycle_t *cycle);
|
||||
|
||||
|
||||
ngx_http_module_t ngx_http_write_filter_module_ctx = {
|
||||
NULL, /* pre conf */
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
@ -33,7 +29,7 @@ ngx_http_module_t ngx_http_write_filter_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_http_write_filter_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_write_filter_module_ctx, /* module context */
|
||||
NULL, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
|
@ -45,34 +41,20 @@ ngx_module_t ngx_http_write_filter_module = {
|
|||
ngx_int_t
|
||||
ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
{
|
||||
off_t size, sent;
|
||||
ngx_uint_t last, flush;
|
||||
ngx_chain_t *cl, *ln, **ll, *chain;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_write_filter_ctx_t *ctx;
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r->main ? r->main : r,
|
||||
ngx_http_write_filter_module);
|
||||
|
||||
if (ctx == NULL) {
|
||||
|
||||
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_write_filter_ctx_t));
|
||||
if (ctx == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_http_set_ctx(r, ctx, ngx_http_write_filter_module);
|
||||
}
|
||||
off_t size, sent;
|
||||
ngx_uint_t last, flush;
|
||||
ngx_chain_t *cl, *ln, **ll, *chain;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
size = 0;
|
||||
flush = 0;
|
||||
last = 0;
|
||||
ll = &ctx->out;
|
||||
ll = &r->out;
|
||||
|
||||
/* find the size, the flush point and the last link of the saved chain */
|
||||
|
||||
for (cl = ctx->out; cl; cl = cl->next) {
|
||||
for (cl = r->out; cl; cl = cl->next) {
|
||||
ll = &cl->next;
|
||||
|
||||
ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
|
||||
|
@ -174,11 +156,10 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http write filter: l:%d f:%d s:%O", last, flush, size);
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
|
||||
ngx_http_core_module);
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
/*
|
||||
* avoid the output if there is no last buf, no flush point,
|
||||
* avoid the output if there are no last buf, no flush point,
|
||||
* there are the incoming bufs and the size of all bufs
|
||||
* is smaller than "postpone_output" directive
|
||||
*/
|
||||
|
@ -187,20 +168,30 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* avoid the output if there are no incoming bufs but there are
|
||||
* the postponed requests or data
|
||||
*/
|
||||
|
||||
if (in == NULL && r->postponed) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (c->write->delayed) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
if (size == 0 && !c->buffered) {
|
||||
if (last) {
|
||||
r->out = NULL;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (flush) {
|
||||
do {
|
||||
ctx->out = ctx->out->next;
|
||||
r->out = r->out->next;
|
||||
}
|
||||
while (ctx->out);
|
||||
while (r->out);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -215,7 +206,7 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
|
||||
sent = c->sent;
|
||||
|
||||
chain = c->send_chain(c, ctx->out, clcf->limit_rate);
|
||||
chain = c->send_chain(c, r->out, clcf->limit_rate);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http write filter %p", chain);
|
||||
|
@ -231,13 +222,13 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
for (cl = ctx->out; cl && cl != chain; /* void */) {
|
||||
for (cl = r->out; cl && cl != chain; /* void */) {
|
||||
ln = cl;
|
||||
cl = cl->next;
|
||||
ngx_free_chain(r->pool, ln);
|
||||
}
|
||||
|
||||
ctx->out = chain;
|
||||
r->out = chain;
|
||||
|
||||
if (chain || (last && c->buffered)) {
|
||||
return NGX_AGAIN;
|
||||
|
|
|
@ -34,7 +34,7 @@ static ngx_core_module_t ngx_imap_module_ctx = {
|
|||
|
||||
|
||||
ngx_module_t ngx_imap_module = {
|
||||
NGX_MODULE,
|
||||
NGX_MODULE_V1,
|
||||
&ngx_imap_module_ctx, /* module context */
|
||||
ngx_imap_commands, /* module directives */
|
||||
NGX_CORE_MODULE, /* module type */
|
||||
|
|
|
@ -47,7 +47,7 @@ void ngx_imap_init_connection(ngx_connection_t *c)
|
|||
return;
|
||||
}
|
||||
|
||||
c->read->event_handler = ngx_imap_init_session;
|
||||
c->read->handler = ngx_imap_init_session;
|
||||
|
||||
ngx_add_timer(c->read, /* STUB */ 60000);
|
||||
|
||||
|
@ -93,7 +93,7 @@ static void ngx_imap_init_session(ngx_event_t *rev)
|
|||
return;
|
||||
}
|
||||
|
||||
c->read->event_handler = ngx_pop3_auth_state;
|
||||
c->read->handler = ngx_pop3_auth_state;
|
||||
|
||||
ngx_pop3_auth_state(rev);
|
||||
}
|
||||
|
|
|
@ -82,9 +82,9 @@ void ngx_imap_proxy_init(ngx_imap_session_t *s)
|
|||
p->upstream.connection->data = s;
|
||||
p->upstream.connection->pool = s->connection->pool;
|
||||
|
||||
s->connection->read->event_handler = ngx_imap_proxy_block_read;
|
||||
p->upstream.connection->read->event_handler = ngx_imap_proxy_auth_handler;
|
||||
p->upstream.connection->write->event_handler = ngx_imap_proxy_dummy_handler;
|
||||
s->connection->read->handler = ngx_imap_proxy_block_read;
|
||||
p->upstream.connection->read->handler = ngx_imap_proxy_auth_handler;
|
||||
p->upstream.connection->write->handler = ngx_imap_proxy_dummy_handler;
|
||||
}
|
||||
|
||||
|
||||
|
@ -200,10 +200,10 @@ static void ngx_imap_proxy_auth_handler(ngx_event_t *rev)
|
|||
s->proxy->buffer->pos = s->proxy->buffer->start;
|
||||
s->proxy->buffer->last = s->proxy->buffer->start;
|
||||
|
||||
s->connection->read->event_handler = ngx_imap_proxy_handler;
|
||||
s->connection->write->event_handler = ngx_imap_proxy_handler;
|
||||
rev->event_handler = ngx_imap_proxy_handler;
|
||||
c->write->event_handler = ngx_imap_proxy_handler;
|
||||
s->connection->read->handler = ngx_imap_proxy_handler;
|
||||
s->connection->write->handler = ngx_imap_proxy_handler;
|
||||
rev->handler = ngx_imap_proxy_handler;
|
||||
c->write->handler = ngx_imap_proxy_handler;
|
||||
}
|
||||
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue