mirror of
https://github.com/nginx/nginx.git
synced 2025-02-25 18:55:26 -06:00
nginx-0.3.8-RELEASE import
*) Security: nginx now checks URI got from a backend in "X-Accel-Redirect" header line or in SSI file for the "/../" paths and zeroes. *) Change: nginx now does not treat the empty user name in the "Authorization" header line as valid one. *) Feature: the "ssl_session_timeout" directives of the ngx_http_ssl_module and ngx_imap_ssl_module. *) Feature: the "auth_http_header" directive of the ngx_imap_auth_http_module. *) Feature: the "add_header" directive. *) Feature: the ngx_http_realip_module. *) Feature: the new variables to use in the "log_format" directive: $bytes_sent, $apache_bytes_sent, $status, $time_gmt, $uri, $request_time, $request_length, $upstream_status, $upstream_response_time, $gzip_ratio, $uid_got, $uid_set, $connection, $pipe, and $msec. The parameters in the "%name" form will be canceled soon. *) Change: now the false variable values in the "if" directive are the empty string "" and string starting with "0". *) Bugfix: while using proxied or FastCGI-server nginx may leave connections and temporary files with client requests in open state. *) Bugfix: the worker processes did not flush the buffered logs on graceful exit. *) Bugfix: if the request URI was changes by the "rewrite" directive and the request was proxied in location given by regular expression, then the incorrect request was transferred to backend; the bug had appeared in 0.2.6. *) Bugfix: the "expires" directive did not remove the previous "Expires" header. *) Bugfix: nginx may stop to accept requests if the "rtsig" method and several worker processes were used. *) Bugfix: the "\"" and "\'" escape symbols were incorrectly handled in SSI commands. *) Bugfix: if the response was ended just after the SSI command and gzipping was used, then the response did not transferred complete or did not transferred at all.
This commit is contained in:
parent
51425a465a
commit
09c684b2d5
@ -63,5 +63,9 @@ ngx_binout="-e"
|
||||
ngx_objext="obj"
|
||||
ngx_binext=".exe"
|
||||
|
||||
ngx_long_start='@&&|
|
||||
'
|
||||
ngx_long_end='|'
|
||||
|
||||
ngx_regex_dirsep='\\'
|
||||
ngx_dirsep="\\"
|
||||
|
@ -11,6 +11,9 @@ ngx_binout="-o "
|
||||
ngx_objext="o"
|
||||
ngx_binext=
|
||||
|
||||
ngx_long_start=
|
||||
ngx_long_end=
|
||||
|
||||
ngx_regex_dirsep="\/"
|
||||
ngx_dirsep='/'
|
||||
|
||||
@ -22,6 +25,9 @@ ngx_tab=' \
|
||||
'
|
||||
ngx_spacer=
|
||||
|
||||
ngx_long_regex_cont=$ngx_regex_cont
|
||||
ngx_long_cont=$ngx_cont
|
||||
|
||||
. auto/cc/name
|
||||
|
||||
if test -n "$CFLAGS"; then
|
||||
|
12
auto/cc/icc
12
auto/cc/icc
@ -38,6 +38,7 @@ CFLAGS="$CFLAGS $IPO"
|
||||
CORE_LINK="$CORE_LINK $IPO"
|
||||
CORE_LINK="$CORE_LINK -opt_report_file=$NGX_OBJS/opt_report_file"
|
||||
|
||||
|
||||
case $CPU in
|
||||
pentium)
|
||||
# optimize for Pentium and Athlon
|
||||
@ -104,7 +105,7 @@ CFLAGS="$CFLAGS -wd1418"
|
||||
CFLAGS="$CFLAGS -wd1419"
|
||||
|
||||
case "$NGX_ICC_VER" in
|
||||
8.* | 9.*)
|
||||
9.*)
|
||||
# "cc" clobber ignored, warnings for Liunx's htons()
|
||||
CFLAGS="$CFLAGS -wd1469"
|
||||
# explicit conversion of a 64-bit integral type to a smaller
|
||||
@ -119,6 +120,15 @@ case "$NGX_ICC_VER" in
|
||||
CFLAGS="$CFLAGS -wd1595"
|
||||
;;
|
||||
|
||||
8.*)
|
||||
# "cc" clobber ignored, warnings for Liunx's htons()
|
||||
CFLAGS="$CFLAGS -wd1469"
|
||||
|
||||
# STUB
|
||||
# non-POD class type passed through ellipsis, Linux only ?
|
||||
CFLAGS="$CFLAGS -wd1595"
|
||||
;;
|
||||
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
@ -114,5 +114,13 @@ ngx_binout="-Fe"
|
||||
ngx_objext="obj"
|
||||
ngx_binext=".exe"
|
||||
|
||||
ngx_long_start='@<<
|
||||
'
|
||||
ngx_long_end='<<'
|
||||
ngx_long_regex_cont=' \
|
||||
'
|
||||
ngx_long_cont='
|
||||
'
|
||||
|
||||
#ngx_regex_dirsep='\\'
|
||||
#ngx_dirsep="\\"
|
||||
|
12
auto/make
12
auto/make
@ -26,7 +26,9 @@ if [ "$CC" = wcl386 ]; then
|
||||
echo MAKE = wmake >> $NGX_MAKEFILE
|
||||
|
||||
ngx_regex_cont=' '
|
||||
ngx_long_regex_cont=' '
|
||||
ngx_cont=' '
|
||||
ngx_long_cont=' '
|
||||
ngx_tab=' '
|
||||
|
||||
fi
|
||||
@ -170,22 +172,22 @@ ngx_deps=`echo $ngx_all_objs $ngx_modules_obj $ngx_res $LINK_DEPS \
|
||||
-e "s/\//$ngx_regex_dirsep/g"`
|
||||
|
||||
ngx_objs=`echo $ngx_all_objs $ngx_modules_obj \
|
||||
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
|
||||
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \
|
||||
-e "s/\//$ngx_regex_dirsep/g"`
|
||||
|
||||
ngx_libs=${CORE_LIBS:+`echo $NGX_LD_OPT $CORE_LIBS \
|
||||
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_regex_cont/"`}
|
||||
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`}
|
||||
|
||||
ngx_link=${CORE_LINK:+`echo $CORE_LINK \
|
||||
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_regex_cont/"`}
|
||||
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`}
|
||||
|
||||
|
||||
cat << END >> $NGX_MAKEFILE
|
||||
|
||||
$NGX_OBJS${ngx_dirsep}nginx${ngx_binext}: $ngx_deps$ngx_spacer
|
||||
\$(LINK) ${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_cont$ngx_objs$ngx_libs$ngx_link
|
||||
\$(LINK) ${ngx_long_start}${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link
|
||||
$ngx_rcc
|
||||
|
||||
${ngx_long_end}
|
||||
END
|
||||
|
||||
|
||||
|
@ -139,6 +139,12 @@ if [ $HTTP_ACCESS = YES ]; then
|
||||
HTTP_SRCS="$HTTP_SRCS $HTTP_ACCESS_SRCS"
|
||||
fi
|
||||
|
||||
if [ $HTTP_REALIP = YES ]; then
|
||||
have=NGX_HTTP_REALIP . auto/have
|
||||
HTTP_MODULES="$HTTP_MODULES $HTTP_REALIP_MODULE"
|
||||
HTTP_SRCS="$HTTP_SRCS $HTTP_REALIP_SRCS"
|
||||
fi
|
||||
|
||||
if [ $HTTP_STATUS = YES ]; then
|
||||
have=NGX_HTTP_STATUS . auto/have
|
||||
HTTP_MODULES="$HTTP_MODULES $HTTP_STATUS_MODULE"
|
||||
|
@ -50,6 +50,7 @@ HTTP_GZIP=YES
|
||||
HTTP_SSL=NO
|
||||
HTTP_SSI=YES
|
||||
HTTP_POSTPONE=NO
|
||||
HTTP_REALIP=NO
|
||||
HTTP_ACCESS=YES
|
||||
HTTP_AUTH_BASIC=YES
|
||||
HTTP_USERID=YES
|
||||
@ -125,6 +126,7 @@ do
|
||||
--http-fastcgi-temp-path=*) NGX_HTTP_FASTCGI_TEMP_PATH="$value" ;;
|
||||
|
||||
--with-http_ssl_module) HTTP_SSL=YES ;;
|
||||
--with-http_realip_module) HTTP_REALIP=YES ;;
|
||||
--without-http_charset_module) HTTP_CHARSET=NO ;;
|
||||
--without-http_gzip_module) HTTP_GZIP=NO ;;
|
||||
--without-http_ssi_module) HTTP_SSI=NO ;;
|
||||
|
@ -310,6 +310,10 @@ HTTP_USERID_FILTER_MODULE=ngx_http_userid_filter_module
|
||||
HTTP_USERID_SRCS=src/http/modules/ngx_http_userid_filter_module.c
|
||||
|
||||
|
||||
HTTP_REALIP_MODULE=ngx_http_realip_module
|
||||
HTTP_REALIP_SRCS=src/http/modules/ngx_http_realip_module.c
|
||||
|
||||
|
||||
HTTP_ACCESS_MODULE=ngx_http_access_module
|
||||
HTTP_ACCESS_SRCS=src/http/modules/ngx_http_access_module.c
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
|
||||
#user nobody;
|
||||
worker_processes 3;
|
||||
worker_processes 1;
|
||||
|
||||
#error_log logs/error.log;
|
||||
#pid logs/nginx.pid;
|
||||
|
||||
|
||||
events {
|
||||
connections 1024;
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ http {
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
charset koi8-r;
|
||||
#charset koi8-r;
|
||||
|
||||
#access_log logs/access.log;
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
<bugfix>éÓÐÒÁ×ÌÅÎÉÅ</bugfix>
|
||||
<feature>äÏÂÁ×ÌÅÎÉÅ</feature>
|
||||
<change>éÚÍÅÎÅÎÉÅ</change>
|
||||
<security>âÅÚÏÐÁÓÎÏÓÔØ</security>
|
||||
<workaround>éÚÍÅÎÅÎÉÅ</workaround>
|
||||
</changes>
|
||||
|
||||
@ -25,6 +26,7 @@
|
||||
<bugfix>Bugfix</bugfix>
|
||||
<feature>Feature</feature>
|
||||
<change>Change</change>
|
||||
<security>Security</security>
|
||||
<workaround>Workaround</workaround>
|
||||
|
||||
<month> Jan </month>
|
||||
|
@ -9,6 +9,181 @@
|
||||
<title lang="en">nginx changelog</title>
|
||||
|
||||
|
||||
<changes ver="0.3.8" date="09.11.2005">
|
||||
|
||||
<change type="security">
|
||||
<para lang="ru">
|
||||
nginx ÔÅÐÅÒØ ÐÒÏ×ÅÒÑÔ URI, ÐÏÌÕÞÅÎÎÙÅ ÏÔ ÂÜËÅÎÄÁ × ÓÔÒÏËÅ "X-Accel-Redirect"
|
||||
× ÚÁÇÏÌÏ×ËÅ ÏÔ×ÅÔÁ, ÉÌÉ × SSI ÆÁÊÌÅ ÎÁ ÎÁÌÉÞÉÅ ÐÕÔÅÊ "/../" É ÎÕÌÅÊ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx now checks URI got from a backend in "X-Accel-Redirect" header line
|
||||
or in SSI file for the "/../" paths and zeroes.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
nginx ÔÅÐÅÒØ ÎÅ ×ÏÓÐÒÉÎÉÍÁÅÔ ÐÕÓÔÏÅ ÉÍÑ ËÁË ÐÒÁ×ÉÌØÎÏÅ
|
||||
× ÓÔÒÏËÅ "Authorization" × ÚÁÇÏÌÏ×ËÅ ÚÁÐÒÏÓÁ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx now does not treat the empty user name in the "Authorization" header
|
||||
line as valid one.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á ssl_session_timeout ÍÏÄÕÌÅÊ
|
||||
ngx_http_ssl_module É ngx_imap_ssl_module.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "ssl_session_timeout" directives
|
||||
of the ngx_http_ssl_module and ngx_imap_ssl_module.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á auth_http_header ÍÏÄÕÌÑ ngx_imap_auth_http_module.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "auth_http_header" directive of the ngx_imap_auth_http_module.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á add_header.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "add_header" directive.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÍÏÄÕÌØ ngx_http_realip_module.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the ngx_http_realip_module.
|
||||
directives.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="feature">
|
||||
<para lang="ru">
|
||||
ÎÏ×ÙÅ ÐÅÒÅÍÅÎÎÙÅ ÄÌÑ ÉÓÐÏÌØÚÏ×ÁÎÉÑ × ÄÉÒÅËÔÉ×Å log_format:
|
||||
$bytes_sent, $apache_bytes_sent, $status, $time_gmt,
|
||||
$uri, $request_time, $request_length,
|
||||
$upstream_status, $upstream_response_time,
|
||||
$gzip_ratio,
|
||||
$uid_got, $uid_set,
|
||||
$connection, $pipe É $msec.
|
||||
ðÁÒÁÍÅÔÒÙ × ×ÉÄÅ "%name" ÓËÏÒÏ ÂÕÄÕÔ ÕÐÒÁÚÄÎÅÎÙ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the new variables to use in the "log_format" directive:
|
||||
$bytes_sent, $apache_bytes_sent, $status, $time_gmt,
|
||||
$uri, $request_time, $request_length,
|
||||
$upstream_status, $upstream_response_time,
|
||||
$gzip_ratio,
|
||||
$uid_got, $uid_set,
|
||||
$connection, $pipe, and $msec.
|
||||
The parameters in the "%name" form will be canceled soon.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
× ÄÉÒÅËÔÉ×Å "if" ÌÏÖÎÙÍÉ ÚÎÁÞÅÎÉÑÍÉ ÐÅÒÅÍÅÎÎÙÈ ÔÅÐÅÒØ Ñ×ÌÑÀÔÓÑ
|
||||
ÐÕÓÔÁÑ ÓÔÒÏËÁ "" É ÓÔÒÏËÉ, ÎÁÞÉÎÁÀÝÉÅÓÑ ÎÁ "0".
|
||||
</para>
|
||||
<para lang="en">
|
||||
now the false variable values in the "if" directive are the empty string ""
|
||||
and string starting with "0".
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÐÒÉ ÒÁÂÏÔÁÅÔ Ó ÐÒÏËÓÉÒÏ×ÁÎÎÙÍÉ ÉÌÉ FastCGI-ÓÅÒ×ÅÒÁÍÉ nginx ÍÏÇ ÏÓÔÁ×ÌÑÔØ
|
||||
ÏÔËÒÙÔÙÍÉ ÓÏÅÄÉÎÅÎÉÑ É ×ÒÅÍÅÎÎÙÅ ÆÁÊÌÙ Ó ÚÁÐÒÏÓÁÍÉ ËÌÉÅÎÔÏ×.
|
||||
</para>
|
||||
<para lang="en">
|
||||
while using proxied or FastCGI-server nginx may leave connections
|
||||
and temporary files with client requests in open state.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÒÁÂÏÞÉÅ ÐÒÏÃÅÓÓÙ ÎÅ ÓÂÒÁÓÙ×ÁÌ ÂÕÆÅÒÉÚÉÒÏ×ÁÎÎÙÅ ÌÏÇÉ ÐÒÉ ÐÌÁ×ÎÏÍ ×ÙÈÏÄÅ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the worker processes did not flush the buffered logs on graceful exit.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÅÓÌÉ URI ÚÁÐÒÏÓÁ ÉÚÍÅÎÑÌÏÓØ Ó ÐÏÍÏÝØÀ rewrite, Á ÚÁÔÅÍ ÚÁÐÒÏÓ ÐÒÏËÓÉÒÏ×ÁÌÓÑ
|
||||
× location, ÚÁÄÁÎÎÏÍ ÒÅÇÕÌÑÒÎÙÍ ×ÙÒÁÖÅÎÉÅÍ, ÔÏ ÂÜËÅÎÄÕ ÐÅÒÅÄÁ×ÁÌÓÑ
|
||||
ÎÅ×ÅÒÎÙÊ ÚÁÐÒÏÓ;
|
||||
ÏÛÉÂËÁ ÐÏÑ×ÉÌÁÓØ × 0.2.6.
|
||||
</para>
|
||||
<para lang="en">
|
||||
if the request URI was changes by the "rewrite" directive and the request
|
||||
was proxied in location given by regular expression, then the incorrect
|
||||
request was transferred to backend;
|
||||
bug appeared in 0.2.6.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÄÉÒÅËÔÉ×Á expires ÎÅ ÕÄÁÌÑÌÁ ÕÖÅ ÕÓÔÁÎÏ×ÌÅÎÎÕÀ ÓÔÒÏËÕ ÚÁÇÏÌÏ×ËÁ "Expires".
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "expires" directive did not remove the previous "Expires" header.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ ÍÅÔÏÄÁ rtsig É ÎÅÓËÏÌØËÉÈ ÒÁÂÏÞÉÈ ÐÒÏÃÅÓÓÁÈ nginx
|
||||
ÍÏÇ ÐÅÒÅÓÔÁÔØ ÐÒÉÎÉÍÁÔØ ÚÁÐÒÏÓÙ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx may stop to accept requests if the "rtsig" method and several worker
|
||||
processes were used.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
× SSI ËÏÍÁÎÄÁÈ ÎÅ×ÅÒÎÏ ÏÂÒÁÂÁÔÙ×ÁÌÉÓØ ÓÔÒÏËÉ "\"" É "\'".
|
||||
</para>
|
||||
<para lang="en">
|
||||
the "\"" and "\'" escape symbols were incorrectly handled in SSI commands.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
ÅÓÌÉ ÏÔ×ÅÔ ÚÁËÁÎÞÉ×ÁÌÓÑ ÓÒÁÚÕ ÖÅ ÐÏÓÌÅ SSI ËÏÍÁÎÄÙ, ÔÏ ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ
|
||||
ÓÖÁÔÉÑ ÏÔ×ÅÔ ÐÅÒÅÄÁ×ÁÌÓÑ ÎÅ ÄÏ ËÏÎÃÁ ÉÌÉ ÎÅ ÐÅÒÅÄÁ×ÁÌÓÑ ×ÏÏÂÝÅ.
|
||||
</para>
|
||||
<para lang="en">
|
||||
if the response was ended just after the SSI command and gzipping was used,
|
||||
then the response did not transferred complete or did not transferred at all.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="0.3.7" date="27.10.2005">
|
||||
|
||||
<change type="feature">
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define NGINX_VER "nginx/0.3.7"
|
||||
#define NGINX_VER "nginx/0.3.8"
|
||||
|
||||
#define NGINX_VAR "NGINX"
|
||||
#define NGX_OLDPID_EXT ".oldbin"
|
||||
|
@ -82,7 +82,7 @@ struct ngx_command_s {
|
||||
void *post;
|
||||
};
|
||||
|
||||
#define ngx_null_command { ngx_null_string, 0, NULL, 0, 0, NULL }
|
||||
#define ngx_null_command { ngx_null_string, 0, NULL, 0, 0, NULL }
|
||||
|
||||
|
||||
struct ngx_open_file_s {
|
||||
|
@ -190,7 +190,9 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
|
||||
case 'V':
|
||||
s = va_arg(args, ngx_str_t *);
|
||||
|
||||
len = (buf + s->len < last) ? s->len : (size_t) (last - buf);
|
||||
len = s->len & 0xffff;
|
||||
len = (buf + len < last) ? len : (size_t) (last - buf);
|
||||
|
||||
buf = ngx_cpymem(buf, s->data, len);
|
||||
fmt++;
|
||||
|
||||
|
@ -46,7 +46,7 @@ typedef struct {
|
||||
#define ngx_strncmp(s1, s2, n) strncmp((const char *) s1, (const char *) s2, n)
|
||||
|
||||
|
||||
/* msvc and icc compile strcmp() to inline loop */
|
||||
/* msvc and icc7 compile strcmp() to inline loop */
|
||||
#define ngx_strcmp(s1, s2) strcmp((const char *) s1, (const char *) s2)
|
||||
|
||||
|
||||
@ -55,20 +55,55 @@ typedef struct {
|
||||
|
||||
|
||||
/*
|
||||
* msvc and icc compile memset() to the inline "rep stos"
|
||||
* msvc and icc7 compile memset() to the inline "rep stos"
|
||||
* while ZeroMemory() and bzero() are the calls.
|
||||
* icc may also inline several mov's of a zeroed register for small blocks.
|
||||
* icc7 may also inline several mov's of a zeroed register for small blocks.
|
||||
*/
|
||||
#define ngx_memzero(buf, n) (void) memset(buf, 0, n)
|
||||
#define ngx_memset(buf, c, n) (void) memset(buf, c, n)
|
||||
|
||||
|
||||
/* msvc and icc compile memcpy() to the inline "rep movs" */
|
||||
/*
|
||||
* gcc3, msvc, and icc7 compile memcpy() to the inline "rep movs".
|
||||
* gcc3 compiles memcpy(d, s, 4) to the inline "mov"es.
|
||||
* icc8 compile memcpy(d, s, 4) to the inline "mov"es or XMM moves.
|
||||
*/
|
||||
#define ngx_memcpy(dst, src, n) (void) memcpy(dst, src, n)
|
||||
#define ngx_cpymem(dst, src, n) ((u_char *) memcpy(dst, src, n)) + (n)
|
||||
|
||||
|
||||
/* msvc and icc compile memcmp() to the inline loop */
|
||||
#if ( __INTEL_COMPILER >= 800 )
|
||||
|
||||
/*
|
||||
* the simple inline cycle copies the variable length strings up to 16
|
||||
* bytes faster than icc8 autodetecting _intel_fast_memcpy()
|
||||
*/
|
||||
|
||||
static ngx_inline u_char *
|
||||
ngx_copy(u_char *dst, u_char *src, size_t len)
|
||||
{
|
||||
if (len < 17) {
|
||||
|
||||
while (len) {
|
||||
*dst++ = *src++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return dst;
|
||||
|
||||
} else {
|
||||
return ngx_cpymem(dst, src, len);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define ngx_copy ngx_cpymem
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* msvc and icc7 compile memcmp() to the inline loop */
|
||||
#define ngx_memcmp memcmp
|
||||
|
||||
|
||||
|
@ -288,7 +288,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
||||
ngx_int_t instance;
|
||||
ngx_err_t err;
|
||||
siginfo_t si;
|
||||
ngx_event_t *rev, *wev;
|
||||
ngx_event_t *rev, *wev, **queue;
|
||||
struct timespec ts, *tp;
|
||||
struct sigaction sa;
|
||||
ngx_connection_t *c;
|
||||
@ -381,15 +381,32 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
||||
}
|
||||
|
||||
if ((si.si_band & (POLLIN|POLLHUP|POLLERR)) && rev->active) {
|
||||
|
||||
rev->ready = 1;
|
||||
rev->handler(rev);
|
||||
|
||||
if (flags & NGX_POST_EVENTS) {
|
||||
queue = (ngx_event_t **) (rev->accept ?
|
||||
&ngx_posted_accept_events : &ngx_posted_events);
|
||||
|
||||
ngx_locked_post_event(rev, queue);
|
||||
|
||||
} else {
|
||||
rev->handler(rev);
|
||||
}
|
||||
}
|
||||
|
||||
wev = c->write;
|
||||
|
||||
if ((si.si_band & (POLLOUT|POLLHUP|POLLERR)) && wev->active) {
|
||||
|
||||
wev->ready = 1;
|
||||
wev->handler(wev);
|
||||
|
||||
if (flags & NGX_POST_EVENTS) {
|
||||
ngx_locked_post_event(wev, &ngx_posted_events);
|
||||
|
||||
} else {
|
||||
wev->handler(wev);
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
@ -48,6 +48,7 @@ ngx_atomic_t *ngx_connection_counter = &connection_counter;
|
||||
|
||||
|
||||
ngx_atomic_t *ngx_accept_mutex_ptr;
|
||||
ngx_atomic_t *ngx_accept_mutex_last_owner;
|
||||
ngx_atomic_t *ngx_accept_mutex;
|
||||
ngx_uint_t ngx_accept_mutex_held;
|
||||
ngx_msec_t ngx_accept_mutex_delay;
|
||||
@ -249,10 +250,6 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle)
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
||||
"timer delta: %M", delta);
|
||||
|
||||
if (delta) {
|
||||
ngx_event_expire_timers();
|
||||
}
|
||||
|
||||
if (ngx_posted_accept_events) {
|
||||
ngx_event_process_posted(cycle, &ngx_posted_accept_events);
|
||||
}
|
||||
@ -261,6 +258,10 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle)
|
||||
*ngx_accept_mutex = 0;
|
||||
}
|
||||
|
||||
if (delta) {
|
||||
ngx_event_expire_timers();
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
||||
"posted events %p", ngx_posted_events);
|
||||
|
||||
@ -470,6 +471,7 @@ ngx_event_module_init(ngx_cycle_t *cycle)
|
||||
/* TODO: adjust cache line size, 128 is P4 cache line size */
|
||||
|
||||
size = 128 /* ngx_accept_mutex */
|
||||
+ 128 /* ngx_accept_mutex_last_owner */
|
||||
+ 128; /* ngx_connection_counter */
|
||||
|
||||
#if (NGX_STAT_STUB)
|
||||
@ -489,16 +491,17 @@ ngx_event_module_init(ngx_cycle_t *cycle)
|
||||
}
|
||||
|
||||
ngx_accept_mutex_ptr = (ngx_atomic_t *) shared;
|
||||
ngx_connection_counter = (ngx_atomic_t *) (shared + 128);
|
||||
ngx_accept_mutex_last_owner = (ngx_atomic_t *) (shared + 1 * 128);
|
||||
ngx_connection_counter = (ngx_atomic_t *) (shared + 2 * 128);
|
||||
|
||||
#if (NGX_STAT_STUB)
|
||||
|
||||
ngx_stat_accepted = (ngx_atomic_t *) (shared + 2 * 128);
|
||||
ngx_stat_handled = (ngx_atomic_t *) (shared + 3 * 128);
|
||||
ngx_stat_requests = (ngx_atomic_t *) (shared + 4 * 128);
|
||||
ngx_stat_active = (ngx_atomic_t *) (shared + 5 * 128);
|
||||
ngx_stat_reading = (ngx_atomic_t *) (shared + 6 * 128);
|
||||
ngx_stat_writing = (ngx_atomic_t *) (shared + 7 * 128);
|
||||
ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * 128);
|
||||
ngx_stat_handled = (ngx_atomic_t *) (shared + 4 * 128);
|
||||
ngx_stat_requests = (ngx_atomic_t *) (shared + 5 * 128);
|
||||
ngx_stat_active = (ngx_atomic_t *) (shared + 6 * 128);
|
||||
ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * 128);
|
||||
ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * 128);
|
||||
|
||||
#endif
|
||||
|
||||
@ -1082,10 +1085,10 @@ ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
|
||||
#endif
|
||||
#if (NGX_HAVE_RTSIG)
|
||||
ngx_uint_t rtsig;
|
||||
ngx_core_conf_t *ccf;
|
||||
#endif
|
||||
ngx_int_t i, connections;
|
||||
ngx_module_t *module;
|
||||
ngx_core_conf_t *ccf;
|
||||
ngx_event_module_t *event_module;
|
||||
|
||||
connections = NGX_CONF_UNSET_UINT;
|
||||
@ -1189,8 +1192,6 @@ ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (ecf->accept_mutex) {
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
@ -1205,6 +1206,12 @@ ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
|
||||
"the \"rtsig\" method requires \"accept_mutex\" to be on");
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
|
||||
#else
|
||||
|
||||
return NGX_CONF_OK;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -438,6 +438,7 @@ typedef struct {
|
||||
extern ngx_atomic_t *ngx_connection_counter;
|
||||
|
||||
extern ngx_atomic_t *ngx_accept_mutex_ptr;
|
||||
extern ngx_atomic_t *ngx_accept_mutex_last_owner;
|
||||
extern ngx_atomic_t *ngx_accept_mutex;
|
||||
extern ngx_uint_t ngx_accept_mutex_held;
|
||||
extern ngx_msec_t ngx_accept_mutex_delay;
|
||||
@ -474,8 +475,6 @@ extern ngx_module_t ngx_event_core_module;
|
||||
|
||||
void ngx_event_accept(ngx_event_t *ev);
|
||||
ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle);
|
||||
ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle);
|
||||
ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle);
|
||||
u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len);
|
||||
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
#define NGX_SOCKLEN 512
|
||||
|
||||
|
||||
static ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle);
|
||||
static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle);
|
||||
static void ngx_close_accepted_connection(ngx_connection_t *c);
|
||||
|
||||
|
||||
@ -262,15 +264,20 @@ ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
|
||||
"accept mutex locked");
|
||||
|
||||
if (!ngx_accept_mutex_held) {
|
||||
if (ngx_enable_accept_events(cycle) == NGX_ERROR) {
|
||||
*ngx_accept_mutex = 0;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_accept_mutex_held = 1;
|
||||
if (ngx_accept_mutex_held
|
||||
&& (!(ngx_event_flags & NGX_USE_RTSIG_EVENT)
|
||||
|| *ngx_accept_mutex_last_owner == (ngx_atomic_t) ngx_pid))
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_enable_accept_events(cycle) == NGX_ERROR) {
|
||||
*ngx_accept_mutex = 0;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_accept_mutex_held = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -286,7 +293,7 @@ ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
static ngx_int_t
|
||||
ngx_enable_accept_events(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
@ -299,10 +306,17 @@ ngx_enable_accept_events(ngx_cycle_t *cycle)
|
||||
c = ls[i].connection;
|
||||
|
||||
if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
|
||||
|
||||
if (ngx_accept_mutex_held) {
|
||||
c->read->disabled = 1;
|
||||
}
|
||||
|
||||
if (ngx_add_conn(c) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ngx_accept_mutex_last_owner = ngx_pid;
|
||||
|
||||
} else {
|
||||
if (ngx_add_event(c->read, NGX_READ_EVENT, 0) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
@ -314,7 +328,7 @@ ngx_enable_accept_events(ngx_cycle_t *cycle)
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
static ngx_int_t
|
||||
ngx_disable_accept_events(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
|
@ -14,7 +14,7 @@
|
||||
typedef struct {
|
||||
in_addr_t mask;
|
||||
in_addr_t addr;
|
||||
unsigned deny;
|
||||
ngx_uint_t deny; /* unsigned deny:1; */
|
||||
} ngx_http_access_rule_t;
|
||||
|
||||
|
||||
@ -106,7 +106,7 @@ ngx_http_access_handler(ngx_http_request_t *r)
|
||||
for (i = 0; i < alcf->rules->nelts; i++) {
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"%08XD %08XD %08XD",
|
||||
"access: %08XD %08XD %08XD",
|
||||
sin->sin_addr.s_addr, rule[i].mask, rule[i].addr);
|
||||
|
||||
if ((sin->sin_addr.s_addr & rule[i].mask) == rule[i].addr) {
|
||||
|
@ -17,6 +17,7 @@ typedef struct {
|
||||
|
||||
ngx_str_t index;
|
||||
|
||||
ngx_array_t *flushes;
|
||||
ngx_array_t *params_len;
|
||||
ngx_array_t *params;
|
||||
ngx_array_t *params_source;
|
||||
@ -111,9 +112,8 @@ static ngx_int_t ngx_http_fastcgi_add_variables(ngx_conf_t *cf);
|
||||
static void *ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf,
|
||||
void *parent, void *child);
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
|
||||
uintptr_t data);
|
||||
static ngx_int_t ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
||||
static char *ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
@ -410,6 +410,9 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
|
||||
if (flcf->params_len) {
|
||||
ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
|
||||
|
||||
ngx_http_script_flush_no_cachable_variables(r, flcf->flushes);
|
||||
le.flushed = 1;
|
||||
|
||||
le.ip = flcf->params_len->elts;
|
||||
le.request = r;
|
||||
|
||||
@ -507,6 +510,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
|
||||
e.ip = flcf->params->elts;
|
||||
e.pos = b->last;
|
||||
e.request = r;
|
||||
e.flushed = 1;
|
||||
|
||||
le.ip = flcf->params_len->elts;
|
||||
|
||||
@ -597,8 +601,8 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
|
||||
*b->last++ = ch;
|
||||
}
|
||||
|
||||
b->last = ngx_cpymem(b->last, header[i].value.data,
|
||||
header[i].value.len);
|
||||
b->last = ngx_copy(b->last, header[i].value.data,
|
||||
header[i].value.len);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1634,9 +1638,10 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
}
|
||||
|
||||
if (conf->params_source == NULL) {
|
||||
conf->params_source = prev->params_source;
|
||||
conf->flushes = prev->flushes;
|
||||
conf->params_len = prev->params_len;
|
||||
conf->params = prev->params;
|
||||
conf->params_source = prev->params_source;
|
||||
|
||||
if (conf->params_source == NULL) {
|
||||
return NGX_CONF_OK;
|
||||
@ -1647,7 +1652,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
if (conf->params_len == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
|
||||
conf->params = ngx_array_create(cf->pool, 512, 1);
|
||||
if (conf->params == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
@ -1729,6 +1734,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
sc.cf = cf;
|
||||
sc.source = &src[i].value;
|
||||
sc.flushes = &conf->flushes;
|
||||
sc.lengths = &conf->params_len;
|
||||
sc.values = &conf->params;
|
||||
|
||||
@ -1764,38 +1770,36 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
u_char *p;
|
||||
ngx_http_variable_value_t *vv;
|
||||
ngx_http_fastcgi_loc_conf_t *flcf;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = 0;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
|
||||
|
||||
if (r->uri.data[r->uri.len - 1] != '/') {
|
||||
vv->text = r->uri;
|
||||
return vv;
|
||||
v->len = r->uri.len;
|
||||
v->data = r->uri.data;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
vv->text.len = r->uri.len + flcf->index.len;
|
||||
v->len = r->uri.len + flcf->index.len;
|
||||
|
||||
vv->text.data = ngx_palloc(r->pool, vv->text.len);
|
||||
if (vv->text.data == NULL) {
|
||||
return NULL;
|
||||
v->data = ngx_palloc(r->pool, v->len);
|
||||
if (v->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
p = ngx_cpymem(vv->text.data, r->uri.data, r->uri.len);
|
||||
p = ngx_copy(v->data, r->uri.data, r->uri.len);
|
||||
ngx_memcpy(p, flcf->index.data, flcf->index.len);
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -1860,7 +1864,7 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
clcf->handler = ngx_http_fastcgi_handler;
|
||||
|
||||
lcf->upstream.location = &clcf->name;
|
||||
lcf->upstream.location = clcf->name;
|
||||
|
||||
if (clcf->name.data[clcf->name.len - 1] == '/') {
|
||||
clcf->auto_redirect = 1;
|
||||
|
@ -65,31 +65,34 @@ ngx_module_t ngx_http_geo_module = {
|
||||
|
||||
|
||||
static ngx_http_variable_value_t ngx_http_geo_null_value =
|
||||
{ 0, ngx_string("0") };
|
||||
ngx_http_variable("");
|
||||
|
||||
|
||||
/* AF_INET only */
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_geo_variable(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_geo_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
uintptr_t data)
|
||||
{
|
||||
ngx_radix_tree_t *tree = (ngx_radix_tree_t *) data;
|
||||
|
||||
struct sockaddr_in *sin;
|
||||
ngx_http_variable_value_t *var;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http geo started");
|
||||
|
||||
var = (ngx_http_variable_value_t *)
|
||||
vv = (ngx_http_variable_value_t *)
|
||||
ngx_radix32tree_find(tree, ntohl(sin->sin_addr.s_addr));
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http geo: %V %V", &r->connection->addr_text, &var->text);
|
||||
*v = *vv;
|
||||
|
||||
return var;
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http geo: %V %V", &r->connection->addr_text, v);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -182,7 +185,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
static char *
|
||||
ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
||||
{
|
||||
ngx_int_t rc, n;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value, file;
|
||||
ngx_uint_t i;
|
||||
ngx_inet_cidr_t cidrin;
|
||||
@ -226,30 +229,18 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
||||
cidrin.mask = ntohl(cidrin.mask);
|
||||
}
|
||||
|
||||
n = ngx_atoi(value[1].data, value[1].len);
|
||||
|
||||
var = NULL;
|
||||
v = geo->values.elts;
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
for (i = 0; i < geo->values.nelts; i++) {
|
||||
if (v[i]->text.len != value[1].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(value[1].data, v[i]->text.data, value[1].len) == 0)
|
||||
{
|
||||
var = v[i];
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < geo->values.nelts; i++) {
|
||||
if ((size_t) v[i]->len != value[1].len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
} else {
|
||||
for (i = 0; i < geo->values.nelts; i++) {
|
||||
if (v[i]->value == (ngx_uint_t) n) {
|
||||
var = v[i];
|
||||
break;
|
||||
}
|
||||
if (ngx_strncmp(value[1].data, v[i]->data, value[1].len) == 0)
|
||||
{
|
||||
var = v[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,13 +250,15 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
var->text.len = value[1].len;
|
||||
var->text.data = ngx_pstrdup(geo->pool, &value[1]);
|
||||
if (var->text.data == NULL) {
|
||||
var->len = value[1].len;
|
||||
var->data = ngx_pstrdup(geo->pool, &value[1]);
|
||||
if (var->data == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
var->value = (n == NGX_ERROR) ? 0 : n;
|
||||
var->valid = 1;
|
||||
var->no_cachable = 0;
|
||||
var->not_found = 0;
|
||||
|
||||
v = ngx_array_push(&geo->values);
|
||||
if (v == NULL) {
|
||||
@ -294,7 +287,7 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"duplicate parameter \"%V\", value: \"%V\", "
|
||||
"old value: \"%V\"",
|
||||
&value[0], &var->text, &old->text);
|
||||
&value[0], var, old);
|
||||
|
||||
rc = ngx_radix32tree_delete(geo->tree, cidrin.addr, cidrin.mask);
|
||||
|
||||
|
@ -79,7 +79,9 @@ static void ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx);
|
||||
static u_char *ngx_http_gzip_log_ratio(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
|
||||
static ngx_int_t ngx_http_gzip_add_log_formats(ngx_conf_t *cf);
|
||||
static ngx_int_t ngx_http_gzip_add_variables(ngx_conf_t *cf);
|
||||
static ngx_int_t ngx_http_gzip_ratio_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
||||
static ngx_int_t ngx_http_gzip_filter_init(ngx_cycle_t *cycle);
|
||||
static void *ngx_http_gzip_create_conf(ngx_conf_t *cf);
|
||||
@ -199,7 +201,7 @@ 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, /* preconfiguration */
|
||||
ngx_http_gzip_add_variables, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
@ -256,6 +258,7 @@ struct gztrailer {
|
||||
#endif
|
||||
|
||||
|
||||
static ngx_str_t ngx_http_gzip_ratio = ngx_string("gzip_ratio");
|
||||
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");
|
||||
@ -956,10 +959,18 @@ ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx)
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_gzip_add_log_formats(ngx_conf_t *cf)
|
||||
ngx_http_gzip_add_variables(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_variable_t *var;
|
||||
ngx_http_log_op_name_t *op;
|
||||
|
||||
var = ngx_http_add_variable(cf, &ngx_http_gzip_ratio, 0);
|
||||
if (var == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
var->handler = ngx_http_gzip_ratio_variable;
|
||||
|
||||
for (op = ngx_http_gzip_log_fmt_ops; op->name.len; op++) { /* void */ }
|
||||
op->run = NULL;
|
||||
|
||||
@ -975,6 +986,50 @@ ngx_http_gzip_add_log_formats(ngx_conf_t *cf)
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_gzip_ratio_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_uint_t zint, zfrac;
|
||||
ngx_http_gzip_ctx_t *ctx;
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module);
|
||||
|
||||
if (ctx == NULL || ctx->zout == 0) {
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
v->data = ngx_palloc(r->pool, NGX_INT32_LEN + 3);
|
||||
if (v->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
zint = (ngx_uint_t) (ctx->zin / ctx->zout);
|
||||
zfrac = (ngx_uint_t) ((ctx->zin * 100 / ctx->zout) % 100);
|
||||
|
||||
if ((ctx->zin * 1000 / ctx->zout) % 10 > 4) {
|
||||
|
||||
/* the rounding, e.g., 2.125 to 2.13 */
|
||||
|
||||
zfrac++;
|
||||
|
||||
if (zfrac > 99) {
|
||||
zint++;
|
||||
zfrac = 0;
|
||||
}
|
||||
}
|
||||
|
||||
v->len = ngx_sprintf(v->data, "%ui.%02ui", zint, zfrac) - v->data;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_gzip_filter_init(ngx_cycle_t *cycle)
|
||||
{
|
||||
|
@ -10,7 +10,9 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
time_t expires;
|
||||
time_t expires;
|
||||
ngx_str_t cache_control;
|
||||
ngx_array_t *headers;
|
||||
} ngx_http_headers_conf_t;
|
||||
|
||||
|
||||
@ -22,20 +24,31 @@ typedef struct {
|
||||
static ngx_int_t ngx_http_headers_filter_init(ngx_cycle_t *cycle);
|
||||
static void *ngx_http_headers_create_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_headers_merge_conf(ngx_conf_t *cf,
|
||||
void *parent, void *child);
|
||||
void *parent, void *child);
|
||||
static char *ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
||||
|
||||
static ngx_command_t ngx_http_headers_filter_commands[] = {
|
||||
|
||||
{ ngx_string("expires"),
|
||||
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_headers_expires,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
NULL},
|
||||
|
||||
{ ngx_string("add_header"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|
||||
|NGX_CONF_TAKE2,
|
||||
ngx_http_headers_add,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
NULL},
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
@ -79,7 +92,7 @@ ngx_http_headers_filter(ngx_http_request_t *r)
|
||||
{
|
||||
size_t len;
|
||||
ngx_uint_t i;
|
||||
ngx_table_elt_t *expires, *cc, **ccp;
|
||||
ngx_table_elt_t *expires, *cc, **ccp, *h, *out;
|
||||
ngx_http_headers_conf_t *conf;
|
||||
|
||||
if ((r->headers_out.status != NGX_HTTP_OK
|
||||
@ -117,7 +130,8 @@ ngx_http_headers_filter(ngx_http_request_t *r)
|
||||
if (ccp == NULL) {
|
||||
|
||||
if (ngx_array_init(&r->headers_out.cache_control, r->pool,
|
||||
1, sizeof(ngx_table_elt_t *)) != NGX_OK)
|
||||
1, sizeof(ngx_table_elt_t *))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@ -188,6 +202,50 @@ ngx_http_headers_filter(ngx_http_request_t *r)
|
||||
}
|
||||
}
|
||||
|
||||
if (conf->cache_control.len) {
|
||||
|
||||
ccp = r->headers_out.cache_control.elts;
|
||||
|
||||
if (ccp == NULL) {
|
||||
|
||||
if (ngx_array_init(&r->headers_out.cache_control, r->pool,
|
||||
1, sizeof(ngx_table_elt_t *))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ccp = ngx_array_push(&r->headers_out.cache_control);
|
||||
if (ccp == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
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";
|
||||
cc->value = conf->cache_control;
|
||||
|
||||
*ccp = cc;
|
||||
}
|
||||
|
||||
if (conf->headers) {
|
||||
h = conf->headers->elts;
|
||||
for (i = 0; i < conf->headers->nelts; i++) {
|
||||
out = ngx_list_push(&r->headers_out.headers);
|
||||
if (out == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*out = h[i];
|
||||
}
|
||||
}
|
||||
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
@ -207,11 +265,19 @@ ngx_http_headers_create_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_headers_conf_t *conf;
|
||||
|
||||
conf = ngx_palloc(cf->pool, sizeof(ngx_http_headers_conf_t));
|
||||
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_headers_conf_t));
|
||||
if (conf == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* conf->cache_control.len = 0;
|
||||
* conf->cache_control.data = NULL;
|
||||
* conf->headers = NULL;
|
||||
*/
|
||||
|
||||
conf->expires = NGX_HTTP_EXPIRES_UNSET;
|
||||
|
||||
return conf;
|
||||
@ -229,6 +295,14 @@ ngx_http_headers_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
NGX_HTTP_EXPIRES_OFF : prev->expires;
|
||||
}
|
||||
|
||||
if (conf->cache_control.data == NULL) {
|
||||
conf->cache_control = prev->cache_control;
|
||||
}
|
||||
|
||||
if (conf->headers == NULL) {
|
||||
conf->headers = prev->headers;
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
@ -287,3 +361,38 @@ ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_headers_conf_t *hcf = conf;
|
||||
|
||||
ngx_str_t *value;
|
||||
ngx_table_elt_t *h;
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
if (ngx_strcasecmp(value[1].data, "cache-control") == 0) {
|
||||
hcf->cache_control = value[2];
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (hcf->headers == NULL) {
|
||||
hcf->headers = ngx_array_create(cf->pool, 1, sizeof(ngx_table_elt_t));
|
||||
if (hcf->headers == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
h = ngx_array_push(hcf->headers);
|
||||
if (h == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
h->hash = 1;
|
||||
h->key = value[1];
|
||||
h->value = value[2];
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
@ -180,6 +180,7 @@ ngx_http_index_handler(ngx_http_request_t *r)
|
||||
|
||||
e.ip = index[i].lengths->elts;
|
||||
e.request = r;
|
||||
e.flushed = 1;
|
||||
|
||||
/* 1 byte for terminating '\0' */
|
||||
|
||||
@ -298,7 +299,7 @@ ngx_http_index_handler(ngx_http_request_t *r)
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
last = ngx_cpymem(uri.data, r->uri.data, r->uri.len);
|
||||
last = ngx_copy(uri.data, r->uri.data, r->uri.len);
|
||||
ngx_memcpy(last, ctx->index.data, ctx->index.len - 1);
|
||||
}
|
||||
|
||||
@ -476,7 +477,7 @@ ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
ilcf->max_index_len = index->name.len;
|
||||
}
|
||||
|
||||
/* include the terminating '\0' to the length to use ngx_memcpy() */
|
||||
/* include the terminating '\0' to the length to use ngx_copy() */
|
||||
index->name.len++;
|
||||
|
||||
continue;
|
||||
|
@ -10,6 +10,35 @@
|
||||
#include <nginx.h>
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
ngx_array_t *ops; /* array of ngx_http_log_op_t */
|
||||
} ngx_http_log_fmt_t;
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t formats; /* array of ngx_http_log_fmt_t */
|
||||
ngx_uint_t combined_used; /* unsigned combined_used:1 */
|
||||
} ngx_http_log_main_conf_t;
|
||||
|
||||
typedef struct {
|
||||
ngx_open_file_t *file;
|
||||
ngx_array_t *ops; /* array of ngx_http_log_op_t */
|
||||
} ngx_http_log_t;
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t *logs; /* array of ngx_http_log_t */
|
||||
ngx_uint_t off; /* unsigned off:1 */
|
||||
} ngx_http_log_loc_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
size_t len;
|
||||
ngx_http_log_op_run_pt run;
|
||||
} ngx_http_log_var_t;
|
||||
|
||||
|
||||
static u_char *ngx_http_log_addr(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf,
|
||||
@ -24,10 +53,10 @@ static u_char *ngx_http_log_request_time(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
static u_char *ngx_http_log_status(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
static u_char *ngx_http_log_length(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
static u_char *ngx_http_log_apache_length(ngx_http_request_t *r, u_char *buf,
|
||||
static u_char *ngx_http_log_bytes_sent(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
static u_char *ngx_http_log_apache_bytes_sent(ngx_http_request_t *r,
|
||||
u_char *buf, ngx_http_log_op_t *op);
|
||||
static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
|
||||
@ -83,7 +112,9 @@ static char *ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static char *ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static ngx_int_t ngx_http_log_init(ngx_cycle_t *cycle);
|
||||
static char *ngx_http_log_compile_format(ngx_conf_t *cf,
|
||||
ngx_array_t *ops, ngx_array_t *args, ngx_uint_t s);
|
||||
static ngx_int_t ngx_http_log_init(ngx_conf_t *cf);
|
||||
|
||||
|
||||
static ngx_command_t ngx_http_log_commands[] = {
|
||||
@ -108,7 +139,7 @@ static ngx_command_t ngx_http_log_commands[] = {
|
||||
|
||||
ngx_http_module_t ngx_http_log_module_ctx = {
|
||||
ngx_http_log_set_formats, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
ngx_http_log_init, /* postconfiguration */
|
||||
|
||||
ngx_http_log_create_main_conf, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
@ -127,7 +158,7 @@ ngx_module_t ngx_http_log_module = {
|
||||
ngx_http_log_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
ngx_http_log_init, /* init module */
|
||||
NULL, /* init module */
|
||||
NULL, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
@ -137,21 +168,34 @@ ngx_module_t ngx_http_log_module = {
|
||||
};
|
||||
|
||||
|
||||
static ngx_str_t http_access_log = ngx_string(NGX_HTTP_LOG_PATH);
|
||||
static ngx_str_t http_access_log = ngx_string(NGX_HTTP_LOG_PATH);
|
||||
|
||||
|
||||
static ngx_str_t ngx_http_combined_fmt =
|
||||
#if 0
|
||||
ngx_string("$remote_addr - $remote_user [%time] "
|
||||
"\"$request\" %status %apache_length "
|
||||
static ngx_str_t ngx_http_combined_fmt =
|
||||
ngx_string("$remote_addr - $remote_user [$time_gmt] "
|
||||
"\"$request\" $status $apache_bytes_sent "
|
||||
"\"$http_referer\" \"$http_user_agent\"");
|
||||
#endif
|
||||
ngx_string("%addr - - [%time] "
|
||||
"\"%request\" %status %apache_length "
|
||||
"\"%{referer}i\" \"%{user-agent}i\"");
|
||||
|
||||
|
||||
ngx_http_log_op_name_t ngx_http_log_fmt_ops[] = {
|
||||
static ngx_http_log_var_t ngx_http_log_vars[] = {
|
||||
{ ngx_string("connection"), NGX_ATOMIC_T_LEN, ngx_http_log_connection },
|
||||
{ ngx_string("pipe"), 1, ngx_http_log_pipe },
|
||||
{ ngx_string("time_gmt"), sizeof("28/Sep/1970:12:00:00 +0600") - 1,
|
||||
ngx_http_log_time },
|
||||
{ ngx_string("msec"), NGX_TIME_T_LEN + 4, ngx_http_log_msec },
|
||||
{ ngx_string("request_time"), NGX_TIME_T_LEN, ngx_http_log_request_time },
|
||||
{ ngx_string("status"), 3, ngx_http_log_status },
|
||||
{ ngx_string("bytes_sent"), NGX_OFF_T_LEN, ngx_http_log_bytes_sent },
|
||||
{ ngx_string("apache_bytes_sent"), NGX_OFF_T_LEN,
|
||||
ngx_http_log_apache_bytes_sent },
|
||||
{ ngx_string("request_length"), NGX_SIZE_T_LEN,
|
||||
ngx_http_log_request_length },
|
||||
|
||||
{ ngx_null_string, 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
ngx_http_log_op_name_t ngx_http_log_fmt_ops[] = {
|
||||
{ ngx_string("addr"), INET_ADDRSTRLEN - 1, NULL, NULL, ngx_http_log_addr },
|
||||
{ ngx_string("conn"), NGX_ATOMIC_T_LEN, NULL, NULL,
|
||||
ngx_http_log_connection },
|
||||
@ -162,9 +206,10 @@ ngx_http_log_op_name_t ngx_http_log_fmt_ops[] = {
|
||||
{ ngx_string("request_time"), NGX_TIME_T_LEN, NULL, NULL,
|
||||
ngx_http_log_request_time },
|
||||
{ ngx_string("status"), 3, NULL, NULL, ngx_http_log_status },
|
||||
{ ngx_string("length"), NGX_OFF_T_LEN, NULL, NULL, ngx_http_log_length },
|
||||
{ ngx_string("length"), NGX_OFF_T_LEN,
|
||||
NULL, NULL, ngx_http_log_bytes_sent },
|
||||
{ ngx_string("apache_length"), NGX_OFF_T_LEN,
|
||||
NULL, NULL, ngx_http_log_apache_length },
|
||||
NULL, NULL, ngx_http_log_apache_bytes_sent },
|
||||
{ ngx_string("request_length"), NGX_SIZE_T_LEN,
|
||||
NULL, NULL, ngx_http_log_request_length },
|
||||
|
||||
@ -376,14 +421,15 @@ ngx_http_log_status(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
|
||||
|
||||
|
||||
static u_char *
|
||||
ngx_http_log_length(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
|
||||
ngx_http_log_bytes_sent(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op)
|
||||
{
|
||||
return ngx_sprintf(buf, "%O", r->connection->sent);
|
||||
}
|
||||
|
||||
|
||||
static u_char *
|
||||
ngx_http_log_apache_length(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_apache_bytes_sent(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op)
|
||||
{
|
||||
off_t length;
|
||||
@ -792,14 +838,11 @@ 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_VAR_NOT_FOUND
|
||||
|| value->text.len == 0)
|
||||
{
|
||||
if (value == NULL || value->not_found) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return value->text.len;
|
||||
return value->len;
|
||||
}
|
||||
|
||||
|
||||
@ -810,15 +853,12 @@ 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_VAR_NOT_FOUND
|
||||
|| value->text.len == 0)
|
||||
{
|
||||
if (value == NULL || value->not_found) {
|
||||
*buf = '-';
|
||||
return buf + 1;
|
||||
}
|
||||
|
||||
return ngx_cpymem(buf, value->text.data, value->text.len);
|
||||
return ngx_cpymem(buf, value->data, value->len);
|
||||
}
|
||||
|
||||
|
||||
@ -839,8 +879,7 @@ ngx_http_log_create_main_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_log_main_conf_t *conf;
|
||||
|
||||
char *rc;
|
||||
ngx_str_t *value;
|
||||
ngx_http_log_fmt_t *fmt;
|
||||
|
||||
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_main_conf_t));
|
||||
if (conf == NULL) {
|
||||
@ -848,38 +887,21 @@ ngx_http_log_create_main_conf(ngx_conf_t *cf)
|
||||
}
|
||||
|
||||
if (ngx_array_init(&conf->formats, cf->pool, 4, sizeof(ngx_http_log_fmt_t))
|
||||
== NGX_ERROR)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
cf->args->nelts = 0;
|
||||
|
||||
value = ngx_array_push(cf->args);
|
||||
if (value == NULL) {
|
||||
fmt = ngx_array_push(&conf->formats);
|
||||
if (fmt == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
value->len = 0;
|
||||
value->data = NULL;
|
||||
fmt->name.len = sizeof("combined") - 1;
|
||||
fmt->name.data = (u_char *) "combined";
|
||||
|
||||
value = ngx_array_push(cf->args);
|
||||
if (value == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
value->len = sizeof("combined") - 1;
|
||||
value->data = (u_char *) "combined";
|
||||
|
||||
value = ngx_array_push(cf->args);
|
||||
if (value == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
*value = ngx_http_combined_fmt;
|
||||
|
||||
rc = ngx_http_log_set_format(cf, NULL, conf);
|
||||
if (rc != NGX_CONF_OK) {
|
||||
fmt->ops = ngx_array_create(cf->pool, 16, sizeof(ngx_http_log_op_t));
|
||||
if (fmt->ops == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
@ -947,6 +969,7 @@ ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
/* the default "combined" format */
|
||||
log->ops = fmt[0].ops;
|
||||
lmcf->combined_used = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -997,6 +1020,7 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
} else {
|
||||
name.len = sizeof("combined") - 1;
|
||||
name.data = (u_char *) "combined";
|
||||
lmcf->combined_used = 1;
|
||||
}
|
||||
|
||||
fmt = lmcf->formats.elts;
|
||||
@ -1058,20 +1082,16 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_log_main_conf_t *lmcf = conf;
|
||||
|
||||
u_char *data, *p, *fname, ch;
|
||||
size_t i, len, fname_len;
|
||||
ngx_str_t *value, var, arg, *a;
|
||||
ngx_uint_t s, f, bracket;
|
||||
ngx_http_log_op_t *op;
|
||||
ngx_http_log_fmt_t *fmt;
|
||||
ngx_http_log_op_name_t *name;
|
||||
ngx_str_t *value;
|
||||
ngx_uint_t i;
|
||||
ngx_http_log_fmt_t *fmt;
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
fmt = lmcf->formats.elts;
|
||||
for (f = 0; f < lmcf->formats.nelts; f++) {
|
||||
if (fmt[f].name.len == value[1].len
|
||||
&& ngx_strcmp(fmt->name.data, value[1].data) == 0)
|
||||
for (i = 0; i < lmcf->formats.nelts; i++) {
|
||||
if (fmt[i].name.len == value[1].len
|
||||
&& ngx_strcmp(fmt[i].name.data, value[1].data) == 0)
|
||||
{
|
||||
return "duplicate \"log_format\" name";
|
||||
}
|
||||
@ -1084,20 +1104,38 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
fmt->name = value[1];
|
||||
|
||||
fmt->ops = ngx_array_create(cf->pool, 20, sizeof(ngx_http_log_op_t));
|
||||
fmt->ops = ngx_array_create(cf->pool, 16, sizeof(ngx_http_log_op_t));
|
||||
if (fmt->ops == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
arg.data = NULL;
|
||||
return ngx_http_log_compile_format(cf, fmt->ops, cf->args, 2);
|
||||
}
|
||||
|
||||
for (s = 2; s < cf->args->nelts; s++) {
|
||||
|
||||
static char *
|
||||
ngx_http_log_compile_format(ngx_conf_t *cf, ngx_array_t *ops,
|
||||
ngx_array_t *args, ngx_uint_t s)
|
||||
{
|
||||
u_char *data, *p, *fname, *arg_data, ch;
|
||||
size_t i, len, fname_len, arg_len;
|
||||
ngx_str_t *value, var, *a;
|
||||
ngx_uint_t bracket;
|
||||
ngx_http_log_op_t *op;
|
||||
ngx_http_log_var_t *v;
|
||||
ngx_http_log_op_name_t *name;
|
||||
static ngx_uint_t warn;
|
||||
|
||||
value = args->elts;
|
||||
arg_data = NULL;
|
||||
|
||||
for ( /* void */ ; s < args->nelts; s++) {
|
||||
|
||||
i = 0;
|
||||
|
||||
while (i < value[s].len) {
|
||||
|
||||
op = ngx_array_push(fmt->ops);
|
||||
op = ngx_array_push(ops);
|
||||
if (op == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
@ -1114,22 +1152,29 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
if (value[s].data[i] == '{') {
|
||||
i++;
|
||||
|
||||
arg.data = &value[s].data[i];
|
||||
arg_data = &value[s].data[i];
|
||||
|
||||
while (i < value[s].len && value[s].data[i] != '}') {
|
||||
i++;
|
||||
}
|
||||
|
||||
arg.len = &value[s].data[i] - arg.data;
|
||||
arg_len = &value[s].data[i] - arg_data;
|
||||
|
||||
if (i == value[s].len || arg.len == 0) {
|
||||
if (i == value[s].len || arg_len == 0) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
} else {
|
||||
arg.len = 0;
|
||||
arg_len = 0;
|
||||
}
|
||||
|
||||
if (warn == 0) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"the parameters in the \"%%name\" form are deprecated, "
|
||||
"use the \"$variable\" instead");
|
||||
warn = 1;
|
||||
}
|
||||
|
||||
fname = &value[s].data[i];
|
||||
@ -1156,7 +1201,7 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
&& ngx_strncmp(name->name.data, fname, fname_len) == 0)
|
||||
{
|
||||
if (name->compile == NULL) {
|
||||
if (arg.len) {
|
||||
if (arg_len) {
|
||||
fname[fname_len] = '\0';
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"%s\" must not have argument",
|
||||
@ -1172,7 +1217,7 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
break;
|
||||
}
|
||||
|
||||
if (arg.len == 0) {
|
||||
if (arg_len == 0) {
|
||||
fname[fname_len] = '\0';
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"%s\" requires argument",
|
||||
@ -1185,7 +1230,9 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
*a = arg;
|
||||
a->len = arg_len;
|
||||
a->data = arg_data;
|
||||
|
||||
if (name->compile(cf, op, a) == NGX_ERROR) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
@ -1198,6 +1245,8 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
} else if (value[s].data[i] == '$') {
|
||||
|
||||
if (++i == value[s].len) {
|
||||
@ -1249,47 +1298,64 @@ ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
for (v = ngx_http_log_vars; v->name.len; v++) {
|
||||
|
||||
if (v->name.len == var.len
|
||||
&& ngx_strncmp(v->name.data, var.data, var.len) == 0)
|
||||
{
|
||||
op->len = v->len;
|
||||
op->getlen = NULL;
|
||||
op->run = v->run;
|
||||
op->data = 0;
|
||||
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_http_log_variable_compile(cf, op, &var) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
} else {
|
||||
found:
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
while (i < value[s].len
|
||||
&& value[s].data[i] != '$'
|
||||
&& value[s].data[i] != '%')
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
while (i < value[s].len
|
||||
&& value[s].data[i] != '$'
|
||||
&& value[s].data[i] != '%')
|
||||
{
|
||||
i++;
|
||||
}
|
||||
len = &value[s].data[i] - data;
|
||||
|
||||
len = &value[s].data[i] - data;
|
||||
if (len) {
|
||||
|
||||
if (len) {
|
||||
op->len = len;
|
||||
op->getlen = NULL;
|
||||
|
||||
op->len = len;
|
||||
op->getlen = NULL;
|
||||
if (len <= sizeof(uintptr_t)) {
|
||||
op->run = ngx_http_log_copy_short;
|
||||
op->data = 0;
|
||||
|
||||
if (len <= sizeof(uintptr_t)) {
|
||||
op->run = ngx_http_log_copy_short;
|
||||
op->data = 0;
|
||||
|
||||
while (len--) {
|
||||
op->data <<= 8;
|
||||
op->data |= data[len];
|
||||
}
|
||||
|
||||
} else {
|
||||
op->run = ngx_http_log_copy_long;
|
||||
|
||||
p = ngx_palloc(cf->pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(p, data, len);
|
||||
op->data = (uintptr_t) p;
|
||||
while (len--) {
|
||||
op->data <<= 8;
|
||||
op->data |= data[len];
|
||||
}
|
||||
|
||||
} else {
|
||||
op->run = ngx_http_log_copy_long;
|
||||
|
||||
p = ngx_palloc(cf->pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(p, data, len);
|
||||
op->data = (uintptr_t) p;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1306,11 +1372,37 @@ invalid:
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_log_init(ngx_cycle_t *cycle)
|
||||
ngx_http_log_init(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_str_t *value;
|
||||
ngx_array_t a;
|
||||
ngx_http_log_fmt_t *fmt;
|
||||
ngx_http_log_main_conf_t *lmcf;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module);
|
||||
lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module);
|
||||
|
||||
if (lmcf->combined_used) {
|
||||
if (ngx_array_init(&a, cf->pool, 1, sizeof(ngx_str_t)) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
value = ngx_array_push(&a);
|
||||
if (value == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*value = ngx_http_combined_fmt;
|
||||
fmt = lmcf->formats.elts;
|
||||
|
||||
if (ngx_http_log_compile_format(cf, fmt->ops, &a, 0)
|
||||
!= NGX_CONF_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
|
||||
cmcf->log_handler = ngx_http_log_handler;
|
||||
|
||||
|
@ -33,12 +33,6 @@ struct ngx_http_log_op_s {
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
ngx_array_t *ops; /* array of ngx_http_log_op_t */
|
||||
} ngx_http_log_fmt_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_str_t name;
|
||||
size_t len;
|
||||
@ -48,23 +42,6 @@ typedef struct {
|
||||
} ngx_http_log_op_name_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t formats; /* array of ngx_http_log_fmt_t */
|
||||
} ngx_http_log_main_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_open_file_t *file;
|
||||
ngx_array_t *ops; /* array of ngx_http_log_op_t */
|
||||
} ngx_http_log_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t *logs; /* array of ngx_http_log_t */
|
||||
ngx_uint_t off; /* unsigned off:1 */
|
||||
} ngx_http_log_loc_conf_t;
|
||||
|
||||
|
||||
extern ngx_http_log_op_name_t ngx_http_log_fmt_ops[];
|
||||
|
||||
|
||||
|
@ -37,6 +37,7 @@ typedef struct {
|
||||
|
||||
ngx_peers_t *peers;
|
||||
|
||||
ngx_array_t *flushes;
|
||||
ngx_array_t *headers_set_len;
|
||||
ngx_array_t *headers_set;
|
||||
ngx_hash_t *headers_set_hash;
|
||||
@ -75,13 +76,13 @@ static void ngx_http_proxy_abort_request(ngx_http_request_t *r);
|
||||
static void ngx_http_proxy_finalize_request(ngx_http_request_t *r,
|
||||
ngx_int_t rc);
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_proxy_host_variable(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_proxy_port_variable(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
static ngx_int_t ngx_http_proxy_host_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_proxy_port_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t
|
||||
ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
|
||||
uintptr_t data);
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, size_t prefix);
|
||||
|
||||
@ -431,7 +432,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
|
||||
|
||||
escape = 0;
|
||||
|
||||
loc_len = r->valid_location ? u->conf->location->len : 0;
|
||||
loc_len = r->valid_location ? u->conf->location.len : 0;
|
||||
|
||||
if (u->conf->uri.len == 0 && r->valid_unparsed_uri) {
|
||||
len += r->unparsed_uri.len;
|
||||
@ -447,8 +448,11 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
|
||||
|
||||
ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
|
||||
|
||||
ngx_http_script_flush_no_cachable_variables(r, plcf->flushes);
|
||||
|
||||
le.ip = plcf->headers_set_len->elts;
|
||||
le.request = r;
|
||||
le.flushed = 1;
|
||||
|
||||
while (*(uintptr_t *) le.ip) {
|
||||
while (*(uintptr_t *) le.ip) {
|
||||
@ -506,16 +510,16 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
|
||||
|
||||
/* the request line */
|
||||
|
||||
b->last = ngx_cpymem(b->last, method.data, method.len);
|
||||
b->last = ngx_copy(b->last, method.data, method.len);
|
||||
|
||||
u->uri.data = b->last;
|
||||
|
||||
if (u->conf->uri.len == 0 && r->valid_unparsed_uri) {
|
||||
b->last = ngx_cpymem(b->last, r->unparsed_uri.data,
|
||||
r->unparsed_uri.len);
|
||||
b->last = ngx_copy(b->last, r->unparsed_uri.data, r->unparsed_uri.len);
|
||||
|
||||
} else {
|
||||
if (r->valid_location) {
|
||||
b->last = ngx_cpymem(b->last, u->conf->uri.data, u->conf->uri.len);
|
||||
b->last = ngx_copy(b->last, u->conf->uri.data, u->conf->uri.len);
|
||||
}
|
||||
|
||||
if (escape) {
|
||||
@ -524,13 +528,13 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
|
||||
b->last += r->uri.len - loc_len + escape;
|
||||
|
||||
} else {
|
||||
b->last = ngx_cpymem(b->last, r->uri.data + loc_len,
|
||||
r->uri.len - loc_len);
|
||||
b->last = ngx_copy(b->last, r->uri.data + loc_len,
|
||||
r->uri.len - loc_len);
|
||||
}
|
||||
|
||||
if (r->args.len > 0) {
|
||||
*b->last++ = '?';
|
||||
b->last = ngx_cpymem(b->last, r->args.data, r->args.len);
|
||||
b->last = ngx_copy(b->last, r->args.data, r->args.len);
|
||||
}
|
||||
}
|
||||
|
||||
@ -543,6 +547,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
|
||||
e.ip = plcf->headers_set->elts;
|
||||
e.pos = b->last;
|
||||
e.request = r;
|
||||
e.flushed = 1;
|
||||
|
||||
le.ip = plcf->headers_set_len->elts;
|
||||
|
||||
@ -600,13 +605,12 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
|
||||
continue;
|
||||
}
|
||||
|
||||
b->last = ngx_cpymem(b->last, header[i].key.data,
|
||||
header[i].key.len);
|
||||
b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len);
|
||||
|
||||
*b->last++ = ':'; *b->last++ = ' ';
|
||||
|
||||
b->last = ngx_cpymem(b->last, header[i].value.data,
|
||||
header[i].value.len);
|
||||
b->last = ngx_copy(b->last, header[i].value.data,
|
||||
header[i].value.len);
|
||||
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
@ -735,6 +739,7 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
|
||||
if (u->headers_in.status_line.data == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(u->headers_in.status_line.data, p->status_start,
|
||||
u->headers_in.status_line.len);
|
||||
|
||||
@ -1054,83 +1059,77 @@ ngx_http_proxy_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_proxy_host_variable(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_proxy_host_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_http_variable_value_t *vv;
|
||||
ngx_http_proxy_loc_conf_t *plcf;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
|
||||
|
||||
vv->value = 0;
|
||||
vv->text = plcf->host_header;
|
||||
v->len = plcf->host_header.len;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = plcf->host_header.data;
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_proxy_port_variable(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_proxy_port_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_http_variable_value_t *vv;
|
||||
ngx_http_proxy_loc_conf_t *plcf;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
|
||||
|
||||
vv->value = 0;
|
||||
vv->text = plcf->port_text;
|
||||
v->len = plcf->port_text.len;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = plcf->port_text.data;
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
static ngx_int_t
|
||||
ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
|
||||
uintptr_t data)
|
||||
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
u_char *p;
|
||||
ngx_http_variable_value_t *vv;
|
||||
u_char *p;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = 0;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
if (r->headers_in.x_forwarded_for == NULL) {
|
||||
vv->text = r->connection->addr_text;
|
||||
return vv;
|
||||
v->len = r->connection->addr_text.len;
|
||||
v->data = r->connection->addr_text.data;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
vv->text.len = r->headers_in.x_forwarded_for->value.len
|
||||
+ sizeof(", ") - 1 + r->connection->addr_text.len;
|
||||
v->len = r->headers_in.x_forwarded_for->value.len
|
||||
+ sizeof(", ") - 1 + r->connection->addr_text.len;
|
||||
|
||||
p = ngx_palloc(r->pool, vv->text.len);
|
||||
p = ngx_palloc(r->pool, v->len);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
vv->text.data = p;
|
||||
v->data = p;
|
||||
|
||||
p = ngx_cpymem(p, r->headers_in.x_forwarded_for->value.data,
|
||||
r->headers_in.x_forwarded_for->value.len);
|
||||
p = ngx_copy(p, r->headers_in.x_forwarded_for->value.data,
|
||||
r->headers_in.x_forwarded_for->value.len);
|
||||
|
||||
*p++ = ','; *p++ = ' ';
|
||||
|
||||
ngx_memcpy(p, r->connection->addr_text.data, r->connection->addr_text.len);
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -1186,11 +1185,9 @@ ngx_http_proxy_rewrite_redirect_text(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
|
||||
p = data;
|
||||
|
||||
if (prefix) {
|
||||
p = ngx_cpymem(p, h->value.data, prefix);
|
||||
}
|
||||
p = ngx_copy(p, h->value.data, prefix);
|
||||
|
||||
p = ngx_cpymem(p, pr->replacement.text.data, pr->replacement.text.len);
|
||||
p = ngx_copy(p, pr->replacement.text.data, pr->replacement.text.len);
|
||||
|
||||
ngx_memcpy(p, h->value.data + prefix + pr->redirect.len,
|
||||
h->value.len - pr->redirect.len - prefix);
|
||||
@ -1235,9 +1232,7 @@ ngx_http_proxy_rewrite_redirect_vars(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
|
||||
p = data;
|
||||
|
||||
if (prefix) {
|
||||
p = ngx_cpymem(p, h->value.data, prefix);
|
||||
}
|
||||
p = ngx_copy(p, h->value.data, prefix);
|
||||
|
||||
e.ip = pr->replacement.vars.values;
|
||||
e.pos = p;
|
||||
@ -1530,7 +1525,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
pr->handler = ngx_http_proxy_rewrite_redirect_text;
|
||||
pr->redirect = conf->upstream.url;
|
||||
pr->replacement.text = *conf->upstream.location;
|
||||
pr->replacement.text = conf->upstream.location;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1540,10 +1535,11 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
}
|
||||
|
||||
if (conf->headers_source == NULL) {
|
||||
conf->headers_source = prev->headers_source;
|
||||
conf->flushes = prev->flushes;
|
||||
conf->headers_set_len = prev->headers_set_len;
|
||||
conf->headers_set = prev->headers_set;
|
||||
conf->headers_set_hash = prev->headers_set_hash;
|
||||
conf->headers_source = prev->headers_source;
|
||||
}
|
||||
|
||||
if (conf->headers_set_hash) {
|
||||
@ -1680,6 +1676,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
sc.cf = cf;
|
||||
sc.source = &src[i].value;
|
||||
sc.flushes = &conf->flushes;
|
||||
sc.lengths = &conf->headers_set_len;
|
||||
sc.values = &conf->headers_set;
|
||||
|
||||
@ -1843,15 +1840,19 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
clcf->handler = ngx_http_proxy_handler;
|
||||
|
||||
plcf->upstream.location = &clcf->name;
|
||||
plcf->upstream.location = clcf->name;
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
||||
if (clcf->regex && plcf->upstream.uri.len) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"proxy_pass\" may not have URI part in "
|
||||
"location given by regular expression");
|
||||
return NGX_CONF_ERROR;
|
||||
if (clcf->regex) {
|
||||
if (plcf->upstream.uri.len) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"proxy_pass\" may not have URI part in "
|
||||
"location given by regular expression");
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
plcf->upstream.location.len = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1911,7 +1912,7 @@ ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
pr->handler = ngx_http_proxy_rewrite_redirect_text;
|
||||
pr->redirect = plcf->upstream.url;
|
||||
pr->replacement.text = *plcf->upstream.location;
|
||||
pr->replacement.text = plcf->upstream.location;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
275
src/http/modules/ngx_http_realip_module.c
Normal file
275
src/http/modules/ngx_http_realip_module.c
Normal file
@ -0,0 +1,275 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) Igor Sysoev
|
||||
*/
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
/* AF_INET only */
|
||||
|
||||
typedef struct {
|
||||
in_addr_t mask;
|
||||
in_addr_t addr;
|
||||
} ngx_http_realip_from_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_array_t *from; /* array of ngx_http_realip_from_t */
|
||||
|
||||
ngx_uint_t xfwd;
|
||||
} ngx_http_realip_loc_conf_t;
|
||||
|
||||
|
||||
static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r);
|
||||
static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_realip_merge_loc_conf(ngx_conf_t *cf,
|
||||
void *parent, void *child);
|
||||
static ngx_int_t ngx_http_realip_init(ngx_cycle_t *cycle);
|
||||
|
||||
|
||||
static ngx_conf_enum_t ngx_http_realip_header[] = {
|
||||
{ ngx_string("X-Forwarded-For"), 1 },
|
||||
{ ngx_string("X-Real-IP"), 0 },
|
||||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
|
||||
static ngx_command_t ngx_http_realip_commands[] = {
|
||||
|
||||
{ ngx_string("set_real_ip_from"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_realip_from,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
{ ngx_string("real_ip_header"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_enum_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_realip_loc_conf_t, xfwd),
|
||||
&ngx_http_realip_header },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
|
||||
|
||||
ngx_http_module_t ngx_http_realip_module_ctx = {
|
||||
NULL, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
NULL, /* init main configuration */
|
||||
|
||||
NULL, /* create server configuration */
|
||||
NULL, /* merge server configuration */
|
||||
|
||||
ngx_http_realip_create_loc_conf, /* create location configuration */
|
||||
ngx_http_realip_merge_loc_conf /* merge location configuration */
|
||||
};
|
||||
|
||||
|
||||
ngx_module_t ngx_http_realip_module = {
|
||||
NGX_MODULE_V1,
|
||||
&ngx_http_realip_module_ctx, /* module context */
|
||||
ngx_http_realip_commands, /* module directives */
|
||||
NGX_HTTP_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
ngx_http_realip_init, /* init module */
|
||||
NULL, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
NULL, /* exit master */
|
||||
NGX_MODULE_V1_PADDING
|
||||
};
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_realip_handler(ngx_http_request_t *r)
|
||||
{
|
||||
u_char *ip, *p;
|
||||
size_t len;
|
||||
ngx_uint_t i;
|
||||
struct sockaddr_in *sin;
|
||||
ngx_http_realip_from_t *from;
|
||||
ngx_http_realip_loc_conf_t *rlcf;
|
||||
|
||||
if (r->realip_set) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module);
|
||||
|
||||
if (rlcf->from == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (rlcf->xfwd == 0) {
|
||||
if (r->headers_in.x_real_ip == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
len = r->headers_in.x_real_ip->value.len;
|
||||
ip = r->headers_in.x_real_ip->value.data;
|
||||
|
||||
} else {
|
||||
if (r->headers_in.x_forwarded_for == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
len = r->headers_in.x_forwarded_for->value.len;
|
||||
ip = r->headers_in.x_forwarded_for->value.data;
|
||||
|
||||
for (p = ip + len; p > ip; p--) {
|
||||
if (*p == ' ' || *p == ',') {
|
||||
p++;
|
||||
len -= p - ip;
|
||||
ip = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* AF_INET only */
|
||||
|
||||
sin = (struct sockaddr_in *) r->connection->sockaddr;
|
||||
|
||||
from = rlcf->from->elts;
|
||||
for (i = 0; i < rlcf->from->nelts; i++) {
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"realip: %08XD %08XD %08XD",
|
||||
sin->sin_addr.s_addr, from[i].mask, from[i].addr);
|
||||
|
||||
if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) {
|
||||
|
||||
r->connection->addr_text.len = len;
|
||||
r->connection->addr_text.data = ip;
|
||||
|
||||
sin->sin_addr.s_addr = inet_addr((char *) ip);
|
||||
|
||||
r->realip_set = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_realip_loc_conf_t *rlcf = conf;
|
||||
|
||||
ngx_str_t *value;
|
||||
ngx_inet_cidr_t in_cidr;
|
||||
ngx_http_realip_from_t *from;
|
||||
|
||||
if (rlcf->from == NULL) {
|
||||
rlcf->from = ngx_array_create(cf->pool, 2,
|
||||
sizeof(ngx_http_realip_from_t));
|
||||
if (rlcf->from == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
from = ngx_array_push(rlcf->from);
|
||||
if (from == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
from->addr = inet_addr((char *) value[1].data);
|
||||
|
||||
if (from->addr != INADDR_NONE) {
|
||||
from->mask = 0xffffffff;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
if (ngx_ptocidr(&value[1], &in_cidr) == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
|
||||
&value[1]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
from->mask = in_cidr.mask;
|
||||
from->addr = in_cidr.addr;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_realip_create_loc_conf(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_realip_loc_conf_t *conf;
|
||||
|
||||
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_realip_loc_conf_t));
|
||||
if (conf == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* conf->from = NULL;
|
||||
*/
|
||||
|
||||
conf->xfwd = NGX_CONF_UNSET_UINT;
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
{
|
||||
ngx_http_realip_loc_conf_t *prev = parent;
|
||||
ngx_http_realip_loc_conf_t *conf = child;
|
||||
|
||||
if (conf->from == NULL) {
|
||||
conf->from = prev->from;
|
||||
}
|
||||
|
||||
ngx_conf_merge_unsigned_value(conf->xfwd, prev->xfwd, 0);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_realip_init(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_http_handler_pt *h;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module);
|
||||
|
||||
h = ngx_array_push(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers);
|
||||
if (h == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*h = ngx_http_realip_handler;
|
||||
|
||||
h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
|
||||
if (h == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*h = ngx_http_realip_handler;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
@ -142,7 +142,7 @@ ngx_module_t ngx_http_rewrite_module = {
|
||||
|
||||
|
||||
static ngx_http_variable_value_t ngx_http_rewrite_null_value =
|
||||
{ 0, ngx_string("") };
|
||||
ngx_http_variable("");
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
@ -214,9 +214,8 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e)
|
||||
e->ip += sizeof(uintptr_t);
|
||||
|
||||
if (cf->referers == NULL) {
|
||||
e->sp->value = 0;
|
||||
e->sp->text.len = 0;
|
||||
e->sp->text.data = (u_char *) "";
|
||||
e->sp->data = (u_char *) "";
|
||||
e->sp->len = 0;
|
||||
e->sp++;
|
||||
|
||||
return;
|
||||
@ -224,17 +223,15 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e)
|
||||
|
||||
if (r->headers_in.referer == NULL) {
|
||||
if (cf->no_referer) {
|
||||
e->sp->value = 0;
|
||||
e->sp->text.len = 0;
|
||||
e->sp->text.data = (u_char *) "";
|
||||
e->sp->data = (u_char *) "";
|
||||
e->sp->len = 0;
|
||||
e->sp++;
|
||||
|
||||
return;
|
||||
|
||||
} else {
|
||||
e->sp->value = 1;
|
||||
e->sp->text.len = 1;
|
||||
e->sp->text.data = (u_char *) "1";
|
||||
e->sp->data = (u_char *) "1";
|
||||
e->sp->len = 1;
|
||||
e->sp++;
|
||||
|
||||
return;
|
||||
@ -248,17 +245,15 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e)
|
||||
|| (ngx_strncasecmp(ref, "http://", 7) != 0))
|
||||
{
|
||||
if (cf->blocked_referer) {
|
||||
e->sp->value = 0;
|
||||
e->sp->text.len = 0;
|
||||
e->sp->text.data = (u_char *) "0";
|
||||
e->sp->data = (u_char *) "";
|
||||
e->sp->len = 0;
|
||||
e->sp++;
|
||||
|
||||
return;
|
||||
|
||||
} else {
|
||||
e->sp->value = 1;
|
||||
e->sp->text.len = 1;
|
||||
e->sp->text.data = (u_char *) "1";
|
||||
e->sp->data = (u_char *) "1";
|
||||
e->sp->len = 1;
|
||||
e->sp++;
|
||||
|
||||
return;
|
||||
@ -288,9 +283,8 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e)
|
||||
if (ngx_strncmp(&ref[n], refs[i].name.data,
|
||||
refs[i].name.len) == 0)
|
||||
{
|
||||
e->sp->value = 0;
|
||||
e->sp->text.len = 0;
|
||||
e->sp->text.data = (u_char *) "";
|
||||
e->sp->data = (u_char *) "";
|
||||
e->sp->len = 0;
|
||||
e->sp++;
|
||||
|
||||
return;
|
||||
@ -300,9 +294,8 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e)
|
||||
} else {
|
||||
if (ngx_strncasecmp(refs[i].name.data, ref, refs[i].name.len) == 0)
|
||||
{
|
||||
e->sp->value = 0;
|
||||
e->sp->text.len = 0;
|
||||
e->sp->text.data = (u_char *) "";
|
||||
e->sp->data = (u_char *) "";
|
||||
e->sp->len = 0;
|
||||
e->sp++;
|
||||
|
||||
return;
|
||||
@ -310,15 +303,15 @@ ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e)
|
||||
}
|
||||
}
|
||||
|
||||
e->sp->value = 1;
|
||||
e->sp->text.len = 1;
|
||||
e->sp->text.data = (u_char *) "1";
|
||||
e->sp->data = (u_char *) "1";
|
||||
e->sp->len = 1;
|
||||
e->sp++;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_rewrite_var(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_rewrite_var(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
uintptr_t data)
|
||||
{
|
||||
ngx_http_variable_t *var;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
@ -336,7 +329,9 @@ ngx_http_rewrite_var(ngx_http_request_t *r, uintptr_t data)
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
"using uninitialized \"%V\" variable", &var[data].name);
|
||||
|
||||
return &ngx_http_rewrite_null_value;
|
||||
*v = ngx_http_rewrite_null_value;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -411,6 +406,13 @@ ngx_http_rewrite_init(ngx_cycle_t *cycle)
|
||||
|
||||
cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module);
|
||||
|
||||
h = ngx_array_push(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers);
|
||||
if (h == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*h = ngx_http_rewrite_handler;
|
||||
|
||||
h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
|
||||
if (h == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
@ -144,8 +144,8 @@ static ngx_int_t ngx_http_ssi_else(ngx_http_request_t *r,
|
||||
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_date_gmt_local_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t gmt);
|
||||
|
||||
static char *ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
|
||||
@ -562,6 +562,8 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
}
|
||||
|
||||
|
||||
b = NULL;
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
|
||||
for (cmd = ngx_http_ssi_commands; cmd->handler; cmd++) {
|
||||
@ -1200,10 +1202,12 @@ ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
|
||||
}
|
||||
|
||||
if (ch == '"' && state == ssi_double_quoted_value_state) {
|
||||
ctx->param->value.data[ctx->param->value.len - 1] = ch;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ch == '\'' && state == ssi_quoted_value_state) {
|
||||
ctx->param->value.data[ctx->param->value.len - 1] = ch;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1378,9 +1382,9 @@ static ngx_int_t
|
||||
ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
ngx_str_t *text, ngx_uint_t flags)
|
||||
{
|
||||
u_char ch, *p, **value, *data;
|
||||
size_t *size, len, prefix;
|
||||
ngx_str_t var, part, *val;
|
||||
u_char ch, *p, **value, *data, *part_data;
|
||||
size_t *size, len, prefix, part_len;
|
||||
ngx_str_t var, *val;
|
||||
ngx_uint_t i, j, n, bracket;
|
||||
ngx_array_t lengths, values;
|
||||
ngx_http_variable_value_t *vv;
|
||||
@ -1408,7 +1412,7 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
p = ngx_cpymem(data, r->uri.data, prefix);
|
||||
p = ngx_copy(data, r->uri.data, prefix);
|
||||
ngx_memcpy(p, text->data, text->len);
|
||||
|
||||
text->len = len;
|
||||
@ -1498,20 +1502,22 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (vv == NGX_HTTP_VAR_NOT_FOUND) {
|
||||
if (vv->not_found) {
|
||||
continue;
|
||||
}
|
||||
|
||||
part = vv->text;
|
||||
part_data = vv->data;
|
||||
part_len = vv->len;
|
||||
|
||||
} else {
|
||||
part = *val;
|
||||
part_data = val->data;
|
||||
part_len = val->len;
|
||||
}
|
||||
|
||||
} else {
|
||||
part.data = &text->data[i];
|
||||
part_data = &text->data[i];
|
||||
|
||||
for (p = part.data; i < text->len; i++) {
|
||||
for (p = part_data; i < text->len; i++) {
|
||||
ch = text->data[i];
|
||||
|
||||
if (ch == '$') {
|
||||
@ -1527,24 +1533,24 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
*p++ = ch;
|
||||
}
|
||||
|
||||
part.len = p - part.data;
|
||||
part_len = p - part_data;
|
||||
}
|
||||
|
||||
len += part.len;
|
||||
len += part_len;
|
||||
|
||||
size = ngx_array_push(&lengths);
|
||||
if (size == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*size = part.len;
|
||||
*size = part_len;
|
||||
|
||||
value = ngx_array_push(&values);
|
||||
if (value == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*value = part.data;
|
||||
*value = part_data;
|
||||
}
|
||||
|
||||
prefix = 0;
|
||||
@ -1577,12 +1583,10 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
text->len = len;
|
||||
text->data = p;
|
||||
|
||||
if (prefix) {
|
||||
p = ngx_cpymem(p, r->uri.data, prefix);
|
||||
}
|
||||
p = ngx_copy(p, r->uri.data, prefix);
|
||||
|
||||
for (i = 0; i < values.nelts; i++) {
|
||||
p = ngx_cpymem(p, value[i], size[i]);
|
||||
p = ngx_copy(p, value[i], size[i]);
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
@ -1601,7 +1605,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
ngx_str_t **params)
|
||||
{
|
||||
ngx_str_t *uri, *file, args;
|
||||
ngx_uint_t i;
|
||||
ngx_uint_t flags;
|
||||
|
||||
uri = params[NGX_HTTP_SSI_INCLUDE_VIRTUAL];
|
||||
file = params[NGX_HTTP_SSI_INCLUDE_FILE];
|
||||
@ -1631,20 +1635,16 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
|
||||
args.len = 0;
|
||||
args.data = NULL;
|
||||
flags = 0;
|
||||
|
||||
if (params[NGX_HTTP_SSI_INCLUDE_VIRTUAL]) {
|
||||
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;
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"ssi include: \"%V\"", uri);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_http_subrequest(r, uri, &args) != NGX_OK) {
|
||||
if (ngx_http_subrequest(r, uri, &args, flags) != NGX_OK) {
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
@ -1658,7 +1658,7 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_buf_t *b;
|
||||
ngx_str_t *var, *value;
|
||||
ngx_str_t *var, *value, text;
|
||||
ngx_chain_t *cl;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
@ -1677,8 +1677,10 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
return NGX_HTTP_SSI_ERROR;
|
||||
}
|
||||
|
||||
if (vv != NGX_HTTP_VAR_NOT_FOUND) {
|
||||
value = &vv->text;
|
||||
if (!vv->not_found) {
|
||||
text.data = vv->data;
|
||||
text.len = vv->len;
|
||||
value = &text;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1817,7 +1819,8 @@ ngx_http_ssi_if(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
|
||||
if ((*p >= 'a' && *p <= 'z')
|
||||
|| (*p >= '0' && *p <= '9')
|
||||
|| *p == '$' || *p == '{' || *p == '}' || *p == '_')
|
||||
|| *p == '$' || *p == '{' || *p == '}' || *p == '_'
|
||||
|| *p == '"' || *p == '\'')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -1971,19 +1974,18 @@ ngx_http_ssi_endif(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
||||
}
|
||||
|
||||
|
||||
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_date_gmt_local_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t gmt)
|
||||
{
|
||||
ngx_http_ssi_ctx_t *ctx;
|
||||
ngx_http_variable_value_t *vv;
|
||||
ngx_time_t *tp;
|
||||
struct tm tm;
|
||||
char buf[NGX_HTTP_SSI_DATE_LEN];
|
||||
ngx_http_ssi_ctx_t *ctx;
|
||||
ngx_time_t *tp;
|
||||
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;
|
||||
}
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
tp = ngx_timeofday();
|
||||
|
||||
@ -1992,16 +1994,14 @@ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, uintptr_t gmt)
|
||||
if (ctx->timefmt.len == sizeof("%s") - 1
|
||||
&& ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's')
|
||||
{
|
||||
vv->value = tp->sec + (gmt ? 0 : tp->gmtoff);
|
||||
|
||||
vv->text.data = ngx_palloc(r->pool, NGX_TIME_T_LEN);
|
||||
if (vv->text.data == NULL) {
|
||||
return NULL;
|
||||
v->data = ngx_palloc(r->pool, NGX_TIME_T_LEN);
|
||||
if (v->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
vv->text.len = ngx_sprintf(vv->text.data, "%T", vv->value)
|
||||
- vv->text.data;
|
||||
return vv;
|
||||
v->len = ngx_sprintf(v->data, "%T", tp->sec + (gmt ? 0 : tp->gmtoff))
|
||||
- v->data;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (gmt) {
|
||||
@ -2010,22 +2010,20 @@ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, uintptr_t gmt)
|
||||
ngx_libc_localtime(tp->sec, &tm);
|
||||
}
|
||||
|
||||
vv->value = tp->sec + (gmt ? 0 : tp->gmtoff);
|
||||
|
||||
vv->text.len = strftime(buf, NGX_HTTP_SSI_DATE_LEN,
|
||||
(char *) ctx->timefmt.data, &tm);
|
||||
if (vv->text.len == 0) {
|
||||
return NULL;
|
||||
v->len = strftime(buf, NGX_HTTP_SSI_DATE_LEN,
|
||||
(char *) ctx->timefmt.data, &tm);
|
||||
if (v->len == 0) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
vv->text.data = ngx_palloc(r->pool, vv->text.len);
|
||||
if (vv->text.data == NULL) {
|
||||
return NULL;
|
||||
v->data = ngx_palloc(r->pool, v->len);
|
||||
if (v->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_memcpy(vv->text.data, buf, vv->text.len);
|
||||
ngx_memcpy(v->data, buf, v->len);
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
#define NGX_DEFLAUT_CERTIFICATE "cert.pem"
|
||||
#define NGX_DEFLAUT_CERTIFICATE_KEY "cert.pem"
|
||||
#define NGX_DEFLAUT_CIPHERS "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
|
||||
@ -84,6 +85,13 @@ static ngx_command_t ngx_http_ssl_commands[] = {
|
||||
ngx_http_ssl_nosupported, 0, 0, ngx_http_ssl_openssl097 },
|
||||
#endif
|
||||
|
||||
{ ngx_string("ssl_session_timeout"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_sec_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_ssl_srv_conf_t, session_timeout),
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
@ -146,6 +154,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
|
||||
*/
|
||||
|
||||
scf->enable = NGX_CONF_UNSET;
|
||||
scf->session_timeout = NGX_CONF_UNSET;
|
||||
scf->prefer_server_ciphers = NGX_CONF_UNSET;
|
||||
|
||||
return scf;
|
||||
@ -166,6 +175,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
ngx_conf_merge_value(conf->session_timeout,
|
||||
prev->session_timeout, 300);
|
||||
|
||||
ngx_conf_merge_value(conf->prefer_server_ciphers,
|
||||
prev->prefer_server_ciphers, 0);
|
||||
|
||||
@ -229,6 +241,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
SSL_CTX_set_session_id_context(conf->ssl.ctx, ngx_http_session_id_ctx,
|
||||
sizeof(ngx_http_session_id_ctx) - 1);
|
||||
|
||||
SSL_CTX_set_timeout(conf->ssl.ctx, conf->session_timeout);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ typedef struct {
|
||||
|
||||
ngx_uint_t protocols;
|
||||
|
||||
time_t session_timeout;
|
||||
|
||||
ngx_str_t certificate;
|
||||
ngx_str_t certificate_key;
|
||||
|
||||
@ -29,14 +31,6 @@ typedef struct {
|
||||
} ngx_http_ssl_srv_conf_t;
|
||||
|
||||
|
||||
ngx_int_t ngx_http_ssl_read(ngx_http_request_t *r, u_char *buf, size_t size);
|
||||
ngx_int_t ngx_http_ssl_shutdown(ngx_http_request_t *r);
|
||||
ngx_chain_t *ngx_http_ssl_write(ngx_connection_t *c, ngx_chain_t *in,
|
||||
off_t limit);
|
||||
|
||||
void ngx_http_ssl_close_connection(SSL *ssl, ngx_log_t *log);
|
||||
|
||||
|
||||
extern ngx_module_t ngx_http_ssl_module;
|
||||
|
||||
|
||||
|
@ -195,7 +195,7 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
last = ngx_cpymem(location, r->uri.data, r->uri.len);
|
||||
last = ngx_copy(location, r->uri.data, r->uri.len);
|
||||
}
|
||||
|
||||
*last = '/';
|
||||
|
@ -55,7 +55,10 @@ static size_t ngx_http_userid_log_uid_set_getlen(ngx_http_request_t *r,
|
||||
static u_char *ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
|
||||
static ngx_int_t ngx_http_userid_add_log_formats(ngx_conf_t *cf);
|
||||
static ngx_int_t ngx_http_userid_add_variables(ngx_conf_t *cf);
|
||||
static ngx_int_t ngx_http_userid_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
||||
static ngx_int_t ngx_http_userid_init(ngx_cycle_t *cycle);
|
||||
static void *ngx_http_userid_create_conf(ngx_conf_t *cf);
|
||||
static char *ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent,
|
||||
@ -158,7 +161,7 @@ static ngx_command_t ngx_http_userid_commands[] = {
|
||||
|
||||
|
||||
ngx_http_module_t ngx_http_userid_filter_module_ctx = {
|
||||
ngx_http_userid_add_log_formats, /* preconfiguration */
|
||||
ngx_http_userid_add_variables, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
NULL, /* create main configuration */
|
||||
@ -199,6 +202,10 @@ static ngx_http_log_op_name_t ngx_http_userid_log_fmt_ops[] = {
|
||||
};
|
||||
|
||||
|
||||
static ngx_str_t ngx_http_userid_got = ngx_string("uid_got");
|
||||
static ngx_str_t ngx_http_userid_set = ngx_string("uid_set");
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_userid_filter(ngx_http_request_t *r)
|
||||
{
|
||||
@ -387,7 +394,7 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
p = ngx_cpymem(cookie, conf->name.data, conf->name.len);
|
||||
p = ngx_copy(cookie, conf->name.data, conf->name.len);
|
||||
*p++ = '=';
|
||||
|
||||
if (ctx->uid_got[3] == 0) {
|
||||
@ -417,11 +424,9 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
|
||||
p = ngx_http_cookie_time(p, ngx_time() + conf->expires);
|
||||
}
|
||||
|
||||
if (conf->domain.len) {
|
||||
p = ngx_cpymem(p, conf->domain.data, conf->domain.len);
|
||||
}
|
||||
p = ngx_copy(p, conf->domain.data, conf->domain.len);
|
||||
|
||||
p = ngx_cpymem(p, conf->path.data, conf->path.len);
|
||||
p = ngx_copy(p, conf->path.data, conf->path.len);
|
||||
|
||||
set_cookie = ngx_list_push(&r->headers_out.headers);
|
||||
if (set_cookie == NULL) {
|
||||
@ -489,7 +494,7 @@ ngx_http_userid_log_uid_got(ngx_http_request_t *r, u_char *buf,
|
||||
|
||||
conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module);
|
||||
|
||||
buf = ngx_cpymem(buf, conf->name.data, conf->name.len);
|
||||
buf = ngx_copy(buf, conf->name.data, conf->name.len);
|
||||
|
||||
*buf++ = '=';
|
||||
|
||||
@ -533,7 +538,7 @@ ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf,
|
||||
|
||||
conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module);
|
||||
|
||||
buf = ngx_cpymem(buf, conf->name.data, conf->name.len);
|
||||
buf = ngx_copy(buf, conf->name.data, conf->name.len);
|
||||
|
||||
*buf++ = '=';
|
||||
|
||||
@ -544,10 +549,28 @@ ngx_http_userid_log_uid_set(ngx_http_request_t *r, u_char *buf,
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_userid_add_log_formats(ngx_conf_t *cf)
|
||||
ngx_http_userid_add_variables(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_variable_t *var;
|
||||
ngx_http_log_op_name_t *op;
|
||||
|
||||
var = ngx_http_add_variable(cf, &ngx_http_userid_got, 0);
|
||||
if (var == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
var->handler = ngx_http_userid_variable;
|
||||
var->data = offsetof(ngx_http_userid_ctx_t, uid_got);
|
||||
|
||||
var = ngx_http_add_variable(cf, &ngx_http_userid_set, 0);
|
||||
if (var == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
var->handler = ngx_http_userid_variable;
|
||||
var->data = offsetof(ngx_http_userid_ctx_t, uid_set);
|
||||
|
||||
|
||||
for (op = ngx_http_userid_log_fmt_ops; op->name.len; op++) { /* void */ }
|
||||
op->run = NULL;
|
||||
|
||||
@ -563,6 +586,42 @@ ngx_http_userid_add_log_formats(ngx_conf_t *cf)
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_userid_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
uintptr_t data)
|
||||
{
|
||||
uint32_t *uid;
|
||||
ngx_http_userid_ctx_t *ctx;
|
||||
ngx_http_userid_conf_t *conf;
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module);
|
||||
|
||||
uid = (uint32_t *) ((char *) ctx + data);
|
||||
|
||||
if (ctx == NULL || uid[3] == 0) {
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module);
|
||||
|
||||
v->len = conf->name.len + sizeof("=00001111222233334444555566667777") - 1;
|
||||
v->data = ngx_palloc(r->pool, v->len);
|
||||
if (v->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_sprintf(v->data, "%V=%08XD%08XD%08XD%08XD",
|
||||
&conf->name, uid[0], uid[1], uid[2], uid[3]);
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_userid_init(ngx_cycle_t *cycle)
|
||||
{
|
||||
|
@ -277,19 +277,31 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
/* init lists of the handlers */
|
||||
|
||||
if (ngx_array_init(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers,
|
||||
cf->pool, 1, sizeof(ngx_http_handler_pt)) != NGX_OK)
|
||||
if (ngx_array_init(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers,
|
||||
cf->pool, 1, sizeof(ngx_http_handler_pt))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
cmcf->phases[NGX_HTTP_REWRITE_PHASE].type = NGX_OK;
|
||||
cmcf->phases[NGX_HTTP_POST_READ_PHASE].type = NGX_OK;
|
||||
|
||||
|
||||
if (ngx_array_init(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers,
|
||||
cf->pool, 1, sizeof(ngx_http_handler_pt))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].type = NGX_OK;
|
||||
|
||||
|
||||
/* the special find config phase for a single handler */
|
||||
|
||||
if (ngx_array_init(&cmcf->phases[NGX_HTTP_FIND_CONFIG_PHASE].handlers,
|
||||
cf->pool, 1, sizeof(ngx_http_handler_pt)) != NGX_OK)
|
||||
cf->pool, 1, sizeof(ngx_http_handler_pt))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
@ -304,8 +316,19 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
*h = ngx_http_find_location_config;
|
||||
|
||||
|
||||
if (ngx_array_init(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers,
|
||||
cf->pool, 1, sizeof(ngx_http_handler_pt))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
cmcf->phases[NGX_HTTP_REWRITE_PHASE].type = NGX_OK;
|
||||
|
||||
|
||||
if (ngx_array_init(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers,
|
||||
cf->pool, 1, sizeof(ngx_http_handler_pt)) != NGX_OK)
|
||||
cf->pool, 4, sizeof(ngx_http_handler_pt))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
@ -314,7 +337,8 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
|
||||
if (ngx_array_init(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers,
|
||||
cf->pool, 4, sizeof(ngx_http_handler_pt)) != NGX_OK)
|
||||
cf->pool, 4, sizeof(ngx_http_handler_pt))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
@ -353,6 +377,9 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_http_variables_init_vars(cf) != NGX_OK) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* http{}'s cf->ctx was needed while the configuration merging
|
||||
|
@ -62,6 +62,8 @@ 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_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
|
||||
ngx_str_t *args, ngx_uint_t *flags);
|
||||
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);
|
||||
|
@ -22,7 +22,6 @@ 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);
|
||||
@ -368,7 +367,7 @@ static ngx_command_t ngx_http_core_commands[] = {
|
||||
|
||||
ngx_http_module_t ngx_http_core_module_ctx = {
|
||||
ngx_http_core_preconfiguration, /* preconfiguration */
|
||||
ngx_http_core_postconfiguration, /* postconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
ngx_http_core_create_main_conf, /* create main configuration */
|
||||
ngx_http_core_init_main_conf, /* init main configuration */
|
||||
@ -448,7 +447,8 @@ ngx_http_handler(ngx_http_request_t *r)
|
||||
r->uri_changed = 1;
|
||||
r->uri_changes = NGX_HTTP_MAX_REWRITE_CYCLES + 1;
|
||||
|
||||
r->phase = NGX_HTTP_REWRITE_PHASE;
|
||||
r->phase = (r->main == r) ? NGX_HTTP_POST_READ_PHASE:
|
||||
NGX_HTTP_SERVER_REWRITE_PHASE;
|
||||
r->phase_handler = 0;
|
||||
|
||||
ngx_http_core_run_phases(r);
|
||||
@ -991,7 +991,7 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
last = ngx_cpymem(path->data, clcf->root.data, clcf->root.len);
|
||||
last = ngx_copy(path->data, clcf->root.data, clcf->root.len);
|
||||
last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1);
|
||||
|
||||
return last;
|
||||
@ -1054,7 +1054,7 @@ ngx_http_auth_basic_user(ngx_http_request_t *r)
|
||||
}
|
||||
}
|
||||
|
||||
if (len == auth.len) {
|
||||
if (len == 0 || len == auth.len) {
|
||||
r->headers_in.user.data = (u_char *) "";
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
@ -1070,7 +1070,7 @@ ngx_http_auth_basic_user(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_str_t *uri, ngx_str_t *args, ngx_uint_t flags)
|
||||
{
|
||||
ngx_http_request_t *sr;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
@ -1116,9 +1116,21 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
||||
|
||||
sr->request_line = r->request_line;
|
||||
sr->uri = *uri;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http subrequest \"%V\"", uri);
|
||||
|
||||
if (args) {
|
||||
sr->args = *args;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http subrequest args \"%V\"", args);
|
||||
}
|
||||
|
||||
if (flags & NGX_HTTP_ZERO_IN_URI) {
|
||||
sr->zero_in_uri = 1;
|
||||
}
|
||||
|
||||
sr->unparsed_uri = r->unparsed_uri;
|
||||
sr->method_name = r->method_name;
|
||||
sr->http_protocol = r->http_protocol;
|
||||
@ -1167,9 +1179,6 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
||||
sr->discard_body = r->discard_body;
|
||||
sr->main_filter_need_in_memory = r->main_filter_need_in_memory;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http subrequest \"%V\"", uri);
|
||||
|
||||
ngx_http_handler(sr);
|
||||
|
||||
/* the request pool may be already destroyed */
|
||||
@ -1192,6 +1201,9 @@ ngx_http_internal_redirect(ngx_http_request_t *r,
|
||||
if (args) {
|
||||
r->args = *args;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"internal redirect args: \"%V\"", args);
|
||||
|
||||
} else {
|
||||
r->args.len = 0;
|
||||
r->args.data = NULL;
|
||||
@ -1657,13 +1669,6 @@ ngx_http_core_preconfiguration(ngx_conf_t *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)
|
||||
{
|
||||
|
@ -44,8 +44,10 @@ typedef struct {
|
||||
|
||||
|
||||
typedef enum {
|
||||
NGX_HTTP_FIND_CONFIG_PHASE = 0,
|
||||
NGX_HTTP_POST_READ_PHASE = 0,
|
||||
|
||||
NGX_HTTP_SERVER_REWRITE_PHASE,
|
||||
NGX_HTTP_FIND_CONFIG_PHASE,
|
||||
NGX_HTTP_REWRITE_PHASE,
|
||||
|
||||
NGX_HTTP_ACCESS_PHASE,
|
||||
@ -260,7 +262,7 @@ u_char *ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *name,
|
||||
ngx_int_t ngx_http_auth_basic_user(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_str_t *uri, ngx_str_t *args, ngx_uint_t flags);
|
||||
ngx_int_t ngx_http_internal_redirect(ngx_http_request_t *r,
|
||||
ngx_str_t *uri, ngx_str_t *args);
|
||||
|
||||
|
@ -351,12 +351,12 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
||||
|
||||
/* status line */
|
||||
if (r->headers_out.status_line.len) {
|
||||
b->last = ngx_cpymem(b->last, r->headers_out.status_line.data,
|
||||
r->headers_out.status_line.len);
|
||||
b->last = ngx_copy(b->last, r->headers_out.status_line.data,
|
||||
r->headers_out.status_line.len);
|
||||
|
||||
} else {
|
||||
b->last = ngx_cpymem(b->last, ngx_http_status_lines[status].data,
|
||||
ngx_http_status_lines[status].len);
|
||||
b->last = ngx_copy(b->last, ngx_http_status_lines[status].data,
|
||||
ngx_http_status_lines[status].len);
|
||||
}
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
@ -377,14 +377,14 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
||||
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.data,
|
||||
r->headers_out.content_type.len);
|
||||
b->last = ngx_copy(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=",
|
||||
sizeof("; charset=") - 1);
|
||||
b->last = ngx_cpymem(b->last, r->headers_out.charset.data,
|
||||
r->headers_out.charset.len);
|
||||
b->last = ngx_copy(b->last, r->headers_out.charset.data,
|
||||
r->headers_out.charset.len);
|
||||
|
||||
/* update r->headers_out.content_type for possible logging */
|
||||
|
||||
@ -428,28 +428,27 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
||||
#endif
|
||||
|
||||
*b->last++ = ':'; *b->last++ = '/'; *b->last++ = '/';
|
||||
b->last = ngx_cpymem(b->last, r->server_name.data,
|
||||
r->server_name.len);
|
||||
b->last = ngx_copy(b->last, r->server_name.data, r->server_name.len);
|
||||
|
||||
if (clcf->port_in_redirect) {
|
||||
#if (NGX_HTTP_SSL)
|
||||
if (r->connection->ssl) {
|
||||
if (r->port != 443) {
|
||||
b->last = ngx_cpymem(b->last, r->port_text->data,
|
||||
r->port_text->len);
|
||||
b->last = ngx_copy(b->last, r->port_text->data,
|
||||
r->port_text->len);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (r->port != 80) {
|
||||
b->last = ngx_cpymem(b->last, r->port_text->data,
|
||||
r->port_text->len);
|
||||
b->last = ngx_copy(b->last, r->port_text->data,
|
||||
r->port_text->len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b->last = ngx_cpymem(b->last, r->headers_out.location->value.data,
|
||||
r->headers_out.location->value.len);
|
||||
b->last = ngx_copy(b->last, r->headers_out.location->value.data,
|
||||
r->headers_out.location->value.len);
|
||||
|
||||
/* update r->headers_out.location->value for possible logging */
|
||||
|
||||
@ -497,11 +496,10 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
||||
continue;
|
||||
}
|
||||
|
||||
b->last = ngx_cpymem(b->last, header[i].key.data, header[i].key.len);
|
||||
b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len);
|
||||
*b->last++ = ':' ; *b->last++ = ' ' ;
|
||||
|
||||
b->last = ngx_cpymem(b->last, header[i].value.data,
|
||||
header[i].value.len);
|
||||
b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len);
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
}
|
||||
|
||||
|
@ -763,6 +763,7 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
||||
"s:%d in:'%Xd:%c', out:'%c'", state, ch, ch, *u);
|
||||
|
||||
switch (state) {
|
||||
|
||||
case sw_usual:
|
||||
switch(ch) {
|
||||
#if (NGX_WIN32)
|
||||
@ -810,7 +811,6 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
||||
switch(ch) {
|
||||
#if (NGX_WIN32)
|
||||
case '\\':
|
||||
break;
|
||||
#endif
|
||||
case '/':
|
||||
break;
|
||||
@ -837,7 +837,6 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
||||
switch(ch) {
|
||||
#if (NGX_WIN32)
|
||||
case '\\':
|
||||
/* fall through */
|
||||
#endif
|
||||
case '/':
|
||||
state = sw_slash;
|
||||
@ -866,7 +865,6 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
||||
switch(ch) {
|
||||
#if (NGX_WIN32)
|
||||
case '\\':
|
||||
/* fall through */
|
||||
#endif
|
||||
case '/':
|
||||
state = sw_slash;
|
||||
@ -923,6 +921,9 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
|
||||
quoted_state = state;
|
||||
state = sw_quoted;
|
||||
break;
|
||||
case '?':
|
||||
r->args_start = p;
|
||||
goto done;
|
||||
default:
|
||||
state = sw_usual;
|
||||
*u++ = ch;
|
||||
@ -1002,6 +1003,92 @@ done:
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
|
||||
ngx_str_t *args, ngx_uint_t *flags)
|
||||
{
|
||||
u_char ch, *p;
|
||||
size_t len;
|
||||
|
||||
len = uri->len;
|
||||
p = uri->data;
|
||||
|
||||
if (len == 0 || p[0] == '?') {
|
||||
goto unsafe;
|
||||
}
|
||||
|
||||
if (p[0] == '.' && len == 3 && p[1] == '.' && (p[2] == '/'
|
||||
#if (NGX_WIN32)
|
||||
|| p[2] == '\\'
|
||||
#endif
|
||||
))
|
||||
{
|
||||
goto unsafe;
|
||||
}
|
||||
|
||||
for ( /* void */ ; len; len--) {
|
||||
|
||||
ch = *p++;
|
||||
|
||||
if (ch == '?') {
|
||||
args->len = len - 1;
|
||||
args->data = p;
|
||||
uri->len -= len;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ch == '\0') {
|
||||
*flags |= NGX_HTTP_ZERO_IN_URI;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch != '/'
|
||||
#if (NGX_WIN32)
|
||||
&& ch != '\\'
|
||||
#endif
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (len > 2) {
|
||||
|
||||
/* detect "/../" */
|
||||
|
||||
if (p[2] == '/') {
|
||||
goto unsafe;
|
||||
}
|
||||
|
||||
#if (NGX_WIN32)
|
||||
|
||||
if (p[2] == '\\') {
|
||||
goto unsafe;
|
||||
}
|
||||
|
||||
if (len > 3) {
|
||||
|
||||
/* detect "/.../" */
|
||||
|
||||
if (p[3] == '/' || p[3] == '\\') {
|
||||
goto unsafe;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
unsafe:
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"unsafe URI \"%V\" was detected", uri);
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name,
|
||||
ngx_str_t *value)
|
||||
@ -1059,6 +1146,7 @@ ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name,
|
||||
return i;
|
||||
|
||||
skip:
|
||||
|
||||
while (start < end) {
|
||||
ch = *start++;
|
||||
if (ch == ';' || ch == ',') {
|
||||
|
@ -112,12 +112,18 @@ ngx_http_header_t ngx_http_headers_in[] = {
|
||||
{ ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive),
|
||||
ngx_http_process_header_line },
|
||||
|
||||
#if (NGX_HTTP_PROXY)
|
||||
#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP)
|
||||
{ ngx_string("X-Forwarded-For"),
|
||||
offsetof(ngx_http_headers_in_t, x_forwarded_for),
|
||||
ngx_http_process_header_line },
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_REALIP)
|
||||
{ ngx_string("X-Real-IP"),
|
||||
offsetof(ngx_http_headers_in_t, x_real_ip),
|
||||
ngx_http_process_header_line },
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_HEADERS)
|
||||
{ ngx_string("Accept"), offsetof(ngx_http_headers_in_t, accept),
|
||||
ngx_http_process_header_line },
|
||||
@ -190,20 +196,21 @@ ngx_http_init_connection(ngx_connection_t *c)
|
||||
static
|
||||
void ngx_http_init_request(ngx_event_t *rev)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
socklen_t len;
|
||||
struct sockaddr_in sin;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_in_port_t *in_port;
|
||||
ngx_http_in_addr_t *in_addr;
|
||||
ngx_http_log_ctx_t *ctx;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_server_name_t *server_name;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_uint_t i;
|
||||
socklen_t len;
|
||||
struct sockaddr_in sin;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
ngx_http_in_port_t *in_port;
|
||||
ngx_http_in_addr_t *in_addr;
|
||||
ngx_http_log_ctx_t *ctx;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_server_name_t *server_name;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
#if (NGX_HTTP_SSL)
|
||||
ngx_http_ssl_srv_conf_t *sscf;
|
||||
ngx_http_ssl_srv_conf_t *sscf;
|
||||
#endif
|
||||
|
||||
#if (NGX_STAT_STUB)
|
||||
@ -377,13 +384,21 @@ void ngx_http_init_request(ngx_event_t *rev)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
|
||||
if (r->ctx == NULL) {
|
||||
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
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) {
|
||||
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
c->single_connection = 1;
|
||||
r->connection = c;
|
||||
|
||||
|
@ -40,6 +40,8 @@
|
||||
#define NGX_HTTP_PARSE_HEADER_ERROR 13
|
||||
#define NGX_HTTP_PARSE_INVALID_HEADER 13
|
||||
|
||||
#define NGX_HTTP_ZERO_IN_URI 1
|
||||
|
||||
|
||||
#define NGX_HTTP_OK 200
|
||||
#define NGX_HTTP_NO_CONTENT 204
|
||||
@ -150,10 +152,14 @@ typedef struct {
|
||||
|
||||
ngx_table_elt_t *keep_alive;
|
||||
|
||||
#if (NGX_HTTP_PROXY)
|
||||
#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP)
|
||||
ngx_table_elt_t *x_forwarded_for;
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_REALIP)
|
||||
ngx_table_elt_t *x_real_ip;
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_HEADERS)
|
||||
ngx_table_elt_t *accept;
|
||||
ngx_table_elt_t *accept_language;
|
||||
@ -320,7 +326,7 @@ struct ngx_http_request_s {
|
||||
ngx_http_handler_pt content_handler;
|
||||
ngx_uint_t access_code;
|
||||
|
||||
ngx_http_variable_value_t **variables;
|
||||
ngx_http_variable_value_t *variables;
|
||||
|
||||
size_t limit_rate;
|
||||
|
||||
@ -366,6 +372,16 @@ struct ngx_http_request_s {
|
||||
unsigned bypass_cache:1;
|
||||
unsigned no_cache:1;
|
||||
|
||||
#if (NGX_HTTP_REALIP)
|
||||
|
||||
/*
|
||||
* instead of using the request context data in ngx_http_realip_module
|
||||
* we use the single bit in the request structure
|
||||
*/
|
||||
unsigned realip_set:1;
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
unsigned cachable:1;
|
||||
#endif
|
||||
|
@ -220,14 +220,7 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
||||
"http client request body recv %z", n);
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
ngx_add_timer(c->read, clcf->client_body_timeout);
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
return NGX_AGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
@ -257,9 +250,20 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
||||
"http client request body rest %uz", rb->rest);
|
||||
|
||||
if (rb->rest) {
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
ngx_add_timer(c->read, clcf->client_body_timeout);
|
||||
|
||||
if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
if (c->read->timer_set) {
|
||||
ngx_del_timer(c->read);
|
||||
}
|
||||
|
||||
if (rb->temp_file) {
|
||||
|
||||
/* save the last part */
|
||||
|
@ -34,7 +34,7 @@ ngx_http_script_compile(ngx_http_script_compile_t *sc)
|
||||
{
|
||||
u_char ch;
|
||||
size_t size;
|
||||
ngx_int_t index;
|
||||
ngx_int_t index, *p;
|
||||
ngx_str_t name;
|
||||
uintptr_t *code;
|
||||
ngx_uint_t i, n, bracket;
|
||||
@ -42,6 +42,15 @@ ngx_http_script_compile(ngx_http_script_compile_t *sc)
|
||||
ngx_http_script_copy_code_t *copy;
|
||||
ngx_http_script_copy_capture_code_t *copy_capture;
|
||||
|
||||
if (sc->flushes && *sc->flushes == NULL) {
|
||||
n = sc->variables ? sc->variables : 1;
|
||||
*sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t));
|
||||
if (*sc->flushes == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (*sc->lengths == NULL) {
|
||||
n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
|
||||
+ sizeof(ngx_http_script_var_code_t))
|
||||
@ -167,6 +176,15 @@ ngx_http_script_compile(ngx_http_script_compile_t *sc)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (sc->flushes) {
|
||||
p = ngx_array_push(*sc->flushes);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*p = index;
|
||||
}
|
||||
|
||||
var_code = ngx_http_script_add_code(*sc->lengths,
|
||||
sizeof(ngx_http_script_var_code_t),
|
||||
NULL);
|
||||
@ -276,6 +294,24 @@ invalid_variable:
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_http_script_flush_no_cachable_variables(ngx_http_request_t *r,
|
||||
ngx_array_t *indices)
|
||||
{
|
||||
ngx_uint_t n, *index;
|
||||
|
||||
if (indices) {
|
||||
index = indices->elts;
|
||||
for (n = 0; n < indices->nelts; n++) {
|
||||
if (r->variables[index[n]].no_cachable) {
|
||||
r->variables[index[n]].valid = 0;
|
||||
r->variables[index[n]].not_found = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size)
|
||||
{
|
||||
@ -335,8 +371,8 @@ ngx_http_script_copy_code(ngx_http_script_engine_t *e)
|
||||
code = (ngx_http_script_copy_code_t *) e->ip;
|
||||
|
||||
if (!e->skip) {
|
||||
e->pos = ngx_cpymem(e->pos, e->ip + sizeof(ngx_http_script_copy_code_t),
|
||||
code->len);
|
||||
e->pos = ngx_copy(e->pos, e->ip + sizeof(ngx_http_script_copy_code_t),
|
||||
code->len);
|
||||
}
|
||||
|
||||
e->ip += sizeof(ngx_http_script_copy_code_t)
|
||||
@ -359,10 +395,15 @@ ngx_http_script_copy_var_len_code(ngx_http_script_engine_t *e)
|
||||
|
||||
e->ip += sizeof(ngx_http_script_var_code_t);
|
||||
|
||||
value = ngx_http_get_indexed_variable(e->request, code->index);
|
||||
if (e->flushed) {
|
||||
value = ngx_http_get_indexed_variable(e->request, code->index);
|
||||
|
||||
if (value && value != NGX_HTTP_VAR_NOT_FOUND) {
|
||||
return value->text.len;
|
||||
} else {
|
||||
value = ngx_http_get_flushed_variable(e->request, code->index);
|
||||
}
|
||||
|
||||
if (value && !value->not_found) {
|
||||
return value->len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -380,10 +421,16 @@ ngx_http_script_copy_var_code(ngx_http_script_engine_t *e)
|
||||
e->ip += sizeof(ngx_http_script_var_code_t);
|
||||
|
||||
if (!e->skip) {
|
||||
value = ngx_http_get_indexed_variable(e->request, code->index);
|
||||
|
||||
if (value && value != NGX_HTTP_VAR_NOT_FOUND) {
|
||||
e->pos = ngx_cpymem(e->pos, value->text.data, value->text.len);
|
||||
if (e->flushed) {
|
||||
value = ngx_http_get_indexed_variable(e->request, code->index);
|
||||
|
||||
} else {
|
||||
value = ngx_http_get_flushed_variable(e->request, code->index);
|
||||
}
|
||||
|
||||
if (value && !value->not_found) {
|
||||
e->pos = ngx_copy(e->pos, value->data, value->len);
|
||||
|
||||
if (e->log) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP,
|
||||
@ -440,9 +487,9 @@ ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e)
|
||||
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]);
|
||||
e->pos = ngx_copy(e->pos,
|
||||
&e->line.data[e->captures[code->n]],
|
||||
e->captures[code->n + 1] - e->captures[code->n]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -487,7 +534,8 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
|
||||
e->line = r->uri;
|
||||
} else {
|
||||
e->sp--;
|
||||
e->line = e->sp->text;
|
||||
e->line.len = e->sp->len;
|
||||
e->line.data = e->sp->data;
|
||||
}
|
||||
|
||||
rc = ngx_regex_exec(code->regex, &e->line, e->captures, code->ncaptures);
|
||||
@ -502,9 +550,8 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
|
||||
e->ncaptures = 0;
|
||||
|
||||
if (code->test) {
|
||||
e->sp->value = 0;
|
||||
e->sp->text.len = 0;
|
||||
e->sp->text.data = (u_char *) "";
|
||||
e->sp->len = 0;
|
||||
e->sp->data = (u_char *) "";
|
||||
e->sp++;
|
||||
|
||||
e->ip += sizeof(ngx_http_script_regex_code_t);
|
||||
@ -533,9 +580,8 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
|
||||
e->ncaptures = code->ncaptures;
|
||||
|
||||
if (code->test) {
|
||||
e->sp->value = 1;
|
||||
e->sp->text.len = 1;
|
||||
e->sp->text.data = (u_char *) "1";
|
||||
e->sp->len = 1;
|
||||
e->sp->data = (u_char *) "1";
|
||||
e->sp++;
|
||||
|
||||
e->ip += sizeof(ngx_http_script_regex_code_t);
|
||||
@ -634,7 +680,7 @@ ngx_http_script_regex_end_code(ngx_http_script_engine_t *e)
|
||||
|
||||
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->pos = ngx_copy(e->pos, r->args.data, r->args.len);
|
||||
}
|
||||
|
||||
e->buf.len = e->pos - e->buf.data;
|
||||
@ -665,7 +711,7 @@ ngx_http_script_regex_end_code(ngx_http_script_engine_t *e)
|
||||
|
||||
if (code->add_args && r->args.len) {
|
||||
*e->pos++ = '&';
|
||||
e->pos = ngx_cpymem(e->pos, r->args.data, r->args.len);
|
||||
e->pos = ngx_copy(e->pos, r->args.data, r->args.len);
|
||||
}
|
||||
|
||||
r->args.len = e->pos - e->args;
|
||||
@ -741,7 +787,7 @@ ngx_http_script_if_code(ngx_http_script_engine_t *e)
|
||||
|
||||
e->sp--;
|
||||
|
||||
if (e->sp->value) {
|
||||
if (e->sp->len && e->sp->data[0] != '0') {
|
||||
if (code->loc_conf) {
|
||||
e->request->loc_conf = code->loc_conf;
|
||||
ngx_http_update_location_config(e->request);
|
||||
@ -794,8 +840,8 @@ ngx_http_script_complex_value_code(ngx_http_script_engine_t *e)
|
||||
|
||||
e->pos = e->buf.data;
|
||||
|
||||
e->sp->value = 0;
|
||||
e->sp->text = e->buf;
|
||||
e->sp->data = e->buf.data;
|
||||
e->sp->len = e->buf.len;
|
||||
e->sp++;
|
||||
}
|
||||
|
||||
@ -812,9 +858,8 @@ ngx_http_script_value_code(ngx_http_script_engine_t *e)
|
||||
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->len = code->text_len;
|
||||
e->sp->data = (u_char *) code->text_data;
|
||||
e->sp++;
|
||||
}
|
||||
|
||||
@ -823,8 +868,6 @@ 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,
|
||||
@ -836,30 +879,13 @@ ngx_http_script_set_var_code(ngx_http_script_engine_t *e)
|
||||
|
||||
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;
|
||||
r->variables[code->index].len = e->sp->len;
|
||||
r->variables[code->index].valid = 1;
|
||||
r->variables[code->index].no_cachable = 0;
|
||||
r->variables[code->index].not_found = 0;
|
||||
r->variables[code->index].data = e->sp->data;
|
||||
}
|
||||
|
||||
|
||||
@ -876,20 +902,20 @@ ngx_http_script_var_code(ngx_http_script_engine_t *e)
|
||||
|
||||
e->ip += sizeof(ngx_http_script_var_code_t);
|
||||
|
||||
value = ngx_http_get_indexed_variable(e->request, code->index);
|
||||
value = ngx_http_get_flushed_variable(e->request, code->index);
|
||||
|
||||
if (value && !value->not_found) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
|
||||
"http script var: \"%V\"", value);
|
||||
|
||||
if (value && value != NGX_HTTP_VAR_NOT_FOUND) {
|
||||
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++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
e->sp->value = 0;
|
||||
e->sp->text.len = 0;
|
||||
e->sp->text.data = (u_char *) "";
|
||||
e->sp->data = (u_char *) "";
|
||||
e->sp->len = 0;
|
||||
e->sp++;
|
||||
}
|
||||
|
||||
|
@ -14,46 +14,49 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
u_char *ip;
|
||||
u_char *pos;
|
||||
ngx_http_variable_value_t *sp;
|
||||
u_char *ip;
|
||||
u_char *pos;
|
||||
ngx_http_variable_value_t *sp;
|
||||
|
||||
ngx_str_t buf;
|
||||
ngx_str_t line;
|
||||
ngx_str_t buf;
|
||||
ngx_str_t line;
|
||||
|
||||
/* the start of the rewritten arguments */
|
||||
u_char *args;
|
||||
u_char *args;
|
||||
|
||||
unsigned skip:1;
|
||||
unsigned quote:1;
|
||||
unsigned log:1;
|
||||
unsigned flushed:1;
|
||||
unsigned skip:1;
|
||||
unsigned quote:1;
|
||||
unsigned log:1;
|
||||
|
||||
int *captures;
|
||||
ngx_uint_t ncaptures;
|
||||
int *captures;
|
||||
ngx_uint_t ncaptures;
|
||||
|
||||
ngx_int_t status;
|
||||
ngx_http_request_t *request;
|
||||
ngx_int_t status;
|
||||
ngx_http_request_t *request;
|
||||
} ngx_http_script_engine_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_conf_t *cf;
|
||||
ngx_str_t *source;
|
||||
ngx_array_t **lengths;
|
||||
ngx_array_t **values;
|
||||
ngx_conf_t *cf;
|
||||
ngx_str_t *source;
|
||||
|
||||
ngx_uint_t variables;
|
||||
ngx_uint_t ncaptures;
|
||||
ngx_uint_t size;
|
||||
ngx_array_t **flushes;
|
||||
ngx_array_t **lengths;
|
||||
ngx_array_t **values;
|
||||
|
||||
void *main;
|
||||
ngx_uint_t variables;
|
||||
ngx_uint_t ncaptures;
|
||||
ngx_uint_t size;
|
||||
|
||||
unsigned compile_args:1;
|
||||
unsigned compile_null:1;
|
||||
unsigned complete_lengths:1;
|
||||
unsigned complete_values:1;
|
||||
void *main;
|
||||
|
||||
unsigned args:1;
|
||||
unsigned compile_args:1;
|
||||
unsigned compile_null:1;
|
||||
unsigned complete_lengths:1;
|
||||
unsigned complete_values:1;
|
||||
|
||||
unsigned args:1;
|
||||
} ngx_http_script_compile_t;
|
||||
|
||||
|
||||
@ -149,6 +152,8 @@ typedef struct {
|
||||
|
||||
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_flush_no_cachable_variables(ngx_http_request_t *r,
|
||||
ngx_array_t *indices);
|
||||
|
||||
void *ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes,
|
||||
size_t size);
|
||||
|
@ -67,12 +67,20 @@ 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 size_t ngx_http_upstream_log_response_time_getlen(ngx_http_request_t *r,
|
||||
uintptr_t data);
|
||||
static u_char *ngx_http_upstream_log_response_time(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 ngx_int_t ngx_http_upstream_add_variables(ngx_conf_t *cf);
|
||||
static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
||||
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);
|
||||
|
||||
@ -133,6 +141,12 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
|
||||
ngx_http_upstream_copy_multi_header_lines,
|
||||
offsetof(ngx_http_headers_out_t, cache_control), 1 },
|
||||
|
||||
{ ngx_string("Expires"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
offsetof(ngx_http_upstream_headers_in_t, expires),
|
||||
ngx_http_upstream_copy_header_line,
|
||||
offsetof(ngx_http_headers_out_t, expires), 1 },
|
||||
|
||||
{ ngx_string("Connection"),
|
||||
ngx_http_upstream_ignore_header_line, 0,
|
||||
ngx_http_upstream_ignore_header_line, 0, 0 },
|
||||
@ -173,7 +187,7 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
|
||||
|
||||
|
||||
ngx_http_module_t ngx_http_upstream_module_ctx = {
|
||||
ngx_http_upstream_add_log_formats, /* preconfiguration */
|
||||
ngx_http_upstream_add_variables, /* preconfiguration */
|
||||
NULL, /* postconfiguration */
|
||||
|
||||
ngx_http_upstream_create_main_conf, /* create main configuration */
|
||||
@ -205,14 +219,27 @@ ngx_module_t ngx_http_upstream_module = {
|
||||
|
||||
static ngx_http_log_op_name_t ngx_http_upstream_log_fmt_ops[] = {
|
||||
{ ngx_string("upstream_status"), 0, NULL,
|
||||
ngx_http_upstream_log_status_getlen,
|
||||
ngx_http_upstream_log_status },
|
||||
{ ngx_string("upstream_response_time"), NGX_TIME_T_LEN + 4, NULL, NULL,
|
||||
ngx_http_upstream_log_response_time },
|
||||
ngx_http_upstream_log_status_getlen,
|
||||
ngx_http_upstream_log_status },
|
||||
{ ngx_string("upstream_response_time"), 0, NULL,
|
||||
ngx_http_upstream_log_response_time_getlen,
|
||||
ngx_http_upstream_log_response_time },
|
||||
{ ngx_null_string, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
static ngx_http_variable_t ngx_http_upstream_vars[] = {
|
||||
|
||||
{ ngx_string("upstream_status"),
|
||||
ngx_http_upstream_status_variable, 0, 0, 0 },
|
||||
|
||||
{ ngx_string("upstream_response_time"),
|
||||
ngx_http_upstream_response_time_variable, 0, 0, 0 },
|
||||
|
||||
{ ngx_null_string, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
char *ngx_http_upstream_header_errors[] = {
|
||||
"upstream sent invalid header",
|
||||
"upstream sent too long header line"
|
||||
@ -509,29 +536,27 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
}
|
||||
}
|
||||
|
||||
if (r->request_body) {
|
||||
if (r->request_body->temp_file && r->main == r) {
|
||||
if (r->request_body && r->request_body->temp_file && r->main == r) {
|
||||
|
||||
/*
|
||||
* the r->request_body->buf can be reused for one request only,
|
||||
* the subrequests should allocate their own temporay bufs
|
||||
*/
|
||||
/*
|
||||
* 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) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
u->output.free->buf = r->request_body->buf;
|
||||
u->output.free->next = NULL;
|
||||
u->output.allocated = 1;
|
||||
|
||||
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;
|
||||
u->output.free = ngx_alloc_chain_link(r->pool);
|
||||
if (u->output.free == NULL) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
u->output.free->buf = r->request_body->buf;
|
||||
u->output.free->next = NULL;
|
||||
u->output.allocated = 1;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
u->request_sent = 0;
|
||||
@ -574,20 +599,19 @@ ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
|
||||
/* reinit the subrequest's ngx_output_chain() context */
|
||||
|
||||
if (r->request_body) {
|
||||
if (r->request_body->temp_file && r->main != r && 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;
|
||||
if (r->request_body && r->request_body->temp_file
|
||||
&& r->main != r && 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;
|
||||
@ -690,7 +714,6 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
}
|
||||
|
||||
c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_add_timer(c->read, u->conf->read_timeout);
|
||||
@ -751,7 +774,8 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
|
||||
{
|
||||
ssize_t n;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t i, key;
|
||||
ngx_str_t *uri, args;
|
||||
ngx_uint_t i, key, flags;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *h;
|
||||
ngx_connection_t *c;
|
||||
@ -982,9 +1006,21 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
|
||||
}
|
||||
}
|
||||
|
||||
ngx_http_internal_redirect(r,
|
||||
&r->upstream->headers_in.x_accel_redirect->value,
|
||||
NULL);
|
||||
uri = &r->upstream->headers_in.x_accel_redirect->value;
|
||||
args.len = 0;
|
||||
args.data = NULL;
|
||||
flags = 0;
|
||||
|
||||
if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags & NGX_HTTP_ZERO_IN_URI) {
|
||||
r->zero_in_uri = 1;
|
||||
}
|
||||
|
||||
ngx_http_internal_redirect(r, uri, &args);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1057,7 +1093,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
|
||||
u->header_sent = 1;
|
||||
|
||||
if (r->request_body->temp_file) {
|
||||
if (r->request_body && r->request_body->temp_file) {
|
||||
for (cl = r->pool->cleanup; cl; cl = cl->next) {
|
||||
if (cl->handler == ngx_pool_cleanup_file) {
|
||||
clf = cl->data;
|
||||
@ -1586,7 +1622,7 @@ 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;
|
||||
ngx_table_elt_t *ho, **ph;
|
||||
|
||||
ho = ngx_list_push(&r->headers_out.headers);
|
||||
if (ho == NULL) {
|
||||
@ -1595,6 +1631,11 @@ ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
|
||||
*ho = *h;
|
||||
|
||||
if (offset) {
|
||||
ph = (ngx_table_elt_t **) ((char *) &r->headers_out + offset);
|
||||
*ph = ho;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -1814,7 +1855,7 @@ ngx_http_upstream_log_status(ngx_http_request_t *r, u_char *buf,
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
if (u == NULL) {
|
||||
if (u == NULL || u->states.nelts == 0) {
|
||||
*buf = '-';
|
||||
return buf + 1;
|
||||
}
|
||||
@ -1840,6 +1881,18 @@ ngx_http_upstream_log_status(ngx_http_request_t *r, u_char *buf,
|
||||
}
|
||||
|
||||
|
||||
static size_t
|
||||
ngx_http_upstream_log_response_time_getlen(ngx_http_request_t *r,
|
||||
uintptr_t data)
|
||||
{
|
||||
if (r->upstream) {
|
||||
return r->upstream->states.nelts * (NGX_TIME_T_LEN + 4 + 2);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static u_char *
|
||||
ngx_http_upstream_log_response_time(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op)
|
||||
@ -1850,7 +1903,7 @@ ngx_http_upstream_log_response_time(ngx_http_request_t *r, u_char *buf,
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
if (u == NULL) {
|
||||
if (u == NULL || u->states.nelts == 0) {
|
||||
*buf = '-';
|
||||
return buf + 1;
|
||||
}
|
||||
@ -1905,10 +1958,21 @@ 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)
|
||||
ngx_http_upstream_add_variables(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_http_variable_t *var, *v;
|
||||
ngx_http_log_op_name_t *op;
|
||||
|
||||
for (v = ngx_http_upstream_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;
|
||||
}
|
||||
|
||||
for (op = ngx_http_upstream_log_fmt_ops; op->name.len; op++) { /* void */ }
|
||||
op->run = NULL;
|
||||
|
||||
@ -1924,6 +1988,118 @@ ngx_http_upstream_add_log_formats(ngx_conf_t *cf)
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_status_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
u_char *p;
|
||||
size_t len;
|
||||
ngx_uint_t i;
|
||||
ngx_http_upstream_t *u;
|
||||
ngx_http_upstream_state_t *state;
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
if (u == NULL || u->states.nelts == 0) {
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
len = u->states.nelts * (3 + 2);
|
||||
|
||||
p = ngx_palloc(r->pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
v->data = p;
|
||||
|
||||
i = 0;
|
||||
state = u->states.elts;
|
||||
|
||||
for ( ;; ) {
|
||||
if (state[i].status == 0) {
|
||||
*p++ = '-';
|
||||
|
||||
} else {
|
||||
p = ngx_sprintf(p, "%ui", state[i].status);
|
||||
}
|
||||
|
||||
if (++i == u->states.nelts) {
|
||||
break;
|
||||
}
|
||||
|
||||
*p++ = ',';
|
||||
*p++ = ' ';
|
||||
}
|
||||
|
||||
v->len = p - v->data;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
u_char *p;
|
||||
size_t len;
|
||||
ngx_uint_t i;
|
||||
ngx_http_upstream_t *u;
|
||||
ngx_http_upstream_state_t *state;
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
if (u == NULL || u->states.nelts == 0) {
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
len = u->states.nelts * (NGX_TIME_T_LEN + 4 + 2);
|
||||
|
||||
p = ngx_palloc(r->pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
v->data = p;
|
||||
|
||||
i = 0;
|
||||
state = u->states.elts;
|
||||
|
||||
for ( ;; ) {
|
||||
if (state[i].status == 0) {
|
||||
*p++ = '-';
|
||||
|
||||
} else {
|
||||
p = ngx_sprintf(p, "%d.%03d",
|
||||
state[i].response_time / 1000,
|
||||
state[i].response_time % 1000);
|
||||
}
|
||||
|
||||
if (++i == u->states.nelts) {
|
||||
break;
|
||||
}
|
||||
|
||||
*p++ = ',';
|
||||
*p++ = ' ';
|
||||
}
|
||||
|
||||
v->len = p - v->data;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_upstream_create_main_conf(ngx_conf_t *cf)
|
||||
{
|
||||
|
@ -83,7 +83,7 @@ typedef struct {
|
||||
|
||||
ngx_str_t schema;
|
||||
ngx_str_t uri;
|
||||
ngx_str_t *location;
|
||||
ngx_str_t location;
|
||||
ngx_str_t url; /* used in proxy_rewrite_location */
|
||||
} ngx_http_upstream_conf_t;
|
||||
|
||||
|
@ -10,34 +10,32 @@
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
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_headers(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_remote_port(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
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_http_variable_value_t *
|
||||
ngx_http_variable_request_method(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_remote_user(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_sent(ngx_http_request_t *r, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_unknown_header(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_host(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_remote_addr(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_remote_port(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_document_root(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_request_filename(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_request_method(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_remote_user(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
||||
|
||||
/*
|
||||
@ -95,8 +93,13 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
|
||||
{ ngx_string("request_uri"), ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, unparsed_uri), 0, 0 },
|
||||
|
||||
{ ngx_string("uri"), ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, uri),
|
||||
NGX_HTTP_VAR_NOCACHABLE, 0 },
|
||||
|
||||
{ ngx_string("document_uri"), ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, uri), 0, 0 },
|
||||
offsetof(ngx_http_request_t, uri),
|
||||
NGX_HTTP_VAR_NOCACHABLE, 0 },
|
||||
|
||||
{ ngx_string("request"), ngx_http_variable_request,
|
||||
offsetof(ngx_http_request_t, request_line), 0, 0 },
|
||||
@ -117,10 +120,6 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
|
||||
|
||||
{ ngx_string("remote_user"), ngx_http_variable_remote_user, 0, 0, 0 },
|
||||
|
||||
{ ngx_string("sent"), ngx_http_variable_sent, 0, 0, 0 },
|
||||
|
||||
{ ngx_string("apache_sent"), ngx_http_variable_sent, 1, 0, 0 },
|
||||
|
||||
{ ngx_null_string, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@ -233,7 +232,6 @@ ngx_http_variable_value_t *
|
||||
ngx_http_get_indexed_variable(ngx_http_request_t *r, ngx_uint_t index)
|
||||
{
|
||||
ngx_http_variable_t *v;
|
||||
ngx_http_variable_value_t *vv;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
||||
@ -244,27 +242,42 @@ ngx_http_get_indexed_variable(ngx_http_request_t *r, ngx_uint_t index)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (r->variables && r->variables[index]) {
|
||||
return r->variables[index];
|
||||
if (r->variables[index].not_found || r->variables[index].valid) {
|
||||
return &r->variables[index];
|
||||
}
|
||||
|
||||
v = cmcf->variables.elts;
|
||||
|
||||
vv = v[index].handler(r, v[index].data);
|
||||
if (v[index].handler(r, &r->variables[index], v[index].data) == NGX_OK) {
|
||||
|
||||
if (r->variables == NULL) {
|
||||
r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
|
||||
* sizeof(ngx_http_variable_value_t *));
|
||||
if (r->variables == NULL) {
|
||||
return NULL;
|
||||
if (v[index].flags & NGX_HTTP_VAR_NOCACHABLE) {
|
||||
r->variables[index].no_cachable = 1;
|
||||
}
|
||||
|
||||
return &r->variables[index];
|
||||
}
|
||||
|
||||
if (!(v[index].flags & NGX_HTTP_VAR_NOCACHABLE)) {
|
||||
r->variables[index] = vv;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ngx_http_variable_value_t *
|
||||
ngx_http_get_flushed_variable(ngx_http_request_t *r, ngx_uint_t index)
|
||||
{
|
||||
ngx_http_variable_value_t *v;
|
||||
|
||||
v = &r->variables[index];
|
||||
|
||||
if (v->valid) {
|
||||
if (!v->no_cachable) {
|
||||
return v;
|
||||
}
|
||||
|
||||
v->valid = 0;
|
||||
v->not_found = 0;
|
||||
}
|
||||
|
||||
return vv;
|
||||
return ngx_http_get_indexed_variable(r, index);
|
||||
}
|
||||
|
||||
|
||||
@ -273,6 +286,7 @@ 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_variable_value_t *vv;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
|
||||
@ -292,113 +306,133 @@ ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name)
|
||||
return ngx_http_get_indexed_variable(r, v[key].index);
|
||||
|
||||
} else {
|
||||
return v[key].handler(r, v[key].data);
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
|
||||
if (vv && v[key].handler(r, vv, v[key].data) == NGX_OK) {
|
||||
return vv;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(name->data, "http_", 5) == 0) {
|
||||
return ngx_http_variable_unknown_header(r, (uintptr_t) name);
|
||||
|
||||
if (ngx_http_variable_unknown_header(r, vv, (uintptr_t) name) == NGX_OK)
|
||||
{
|
||||
return vv;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"unknown \"%V\" variable", name);
|
||||
|
||||
return NGX_HTTP_VAR_NOT_FOUND;
|
||||
vv->not_found = 1;
|
||||
|
||||
return vv;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_request(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_variable_request(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
uintptr_t data)
|
||||
{
|
||||
ngx_str_t *s;
|
||||
ngx_http_variable_value_t *vv;
|
||||
ngx_str_t *s;
|
||||
|
||||
s = (ngx_str_t *) ((char *) r + data);
|
||||
|
||||
if (s->data == NULL) {
|
||||
return NGX_HTTP_VAR_NOT_FOUND;
|
||||
if (s->data) {
|
||||
v->len = s->len;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = s->data;
|
||||
|
||||
} else {
|
||||
v->not_found = 1;
|
||||
}
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = 0;
|
||||
vv->text = *s;
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_header(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_variable_header(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
uintptr_t data)
|
||||
{
|
||||
ngx_table_elt_t *h;
|
||||
ngx_http_variable_value_t *vv;
|
||||
ngx_table_elt_t *h;
|
||||
|
||||
h = *(ngx_table_elt_t **) ((char *) r + data);
|
||||
|
||||
if (h == NULL) {
|
||||
return NGX_HTTP_VAR_NOT_FOUND;
|
||||
if (h) {
|
||||
v->len = h->value.len;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = h->value.data;
|
||||
|
||||
} else {
|
||||
v->not_found = 1;
|
||||
}
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = 0;
|
||||
vv->text = h->value;
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_headers(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
uintptr_t data)
|
||||
{
|
||||
u_char *p;
|
||||
ngx_uint_t i;
|
||||
ngx_array_t *a;
|
||||
ngx_table_elt_t **h;
|
||||
ngx_http_variable_value_t *vv;
|
||||
size_t len;
|
||||
u_char *p;
|
||||
ngx_uint_t i;
|
||||
ngx_array_t *a;
|
||||
ngx_table_elt_t **h;
|
||||
|
||||
a = (ngx_array_t *) ((char *) r + data);
|
||||
|
||||
if (a->nelts == 0) {
|
||||
return NGX_HTTP_VAR_NOT_FOUND;
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = 0;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
h = a->elts;
|
||||
|
||||
if (a->nelts == 1) {
|
||||
vv->text = (*h)->value;
|
||||
return vv;
|
||||
v->len = (*h)->value.len;
|
||||
v->data = (*h)->value.data;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
vv->text.len = (size_t) - (ssize_t) (sizeof("; ") - 1);
|
||||
len = (size_t) - (ssize_t) (sizeof("; ") - 1);
|
||||
|
||||
for (i = 0; i < a->nelts; i++) {
|
||||
vv->text.len += h[i]->value.len + sizeof("; ") - 1;
|
||||
len += h[i]->value.len + sizeof("; ") - 1;
|
||||
}
|
||||
|
||||
vv->text.data = ngx_palloc(r->pool, vv->text.len);
|
||||
if (vv->text.data == NULL) {
|
||||
return NULL;
|
||||
p = ngx_palloc(r->pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
p = vv->text.data;
|
||||
v->len = len;
|
||||
v->data = p;
|
||||
|
||||
for (i = 0; /* void */ ; i++) {
|
||||
p = ngx_cpymem(p, h[i]->value.data, h[i]->value.len);
|
||||
p = ngx_copy(p, h[i]->value.data, h[i]->value.len);
|
||||
|
||||
if (i == a->nelts - 1) {
|
||||
break;
|
||||
@ -407,20 +441,20 @@ ngx_http_variable_headers(ngx_http_request_t *r, uintptr_t data)
|
||||
*p++ = ';'; *p++ = ' ';
|
||||
}
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_unknown_header(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_variable_unknown_header(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_str_t *var = (ngx_str_t *) data;
|
||||
|
||||
u_char ch;
|
||||
ngx_uint_t i, n;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *header;
|
||||
ngx_http_variable_value_t *vv;
|
||||
u_char ch;
|
||||
ngx_uint_t i, n;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *header;
|
||||
|
||||
part = &r->headers_in.headers.part;
|
||||
header = part->elts;
|
||||
@ -453,80 +487,72 @@ ngx_http_variable_unknown_header(ngx_http_request_t *r, uintptr_t data)
|
||||
}
|
||||
|
||||
if (n + 5 == var->len) {
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
v->len = header[i].value.len;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = header[i].value.data;
|
||||
|
||||
vv->value = 0;
|
||||
vv->text = header[i].value;
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_HTTP_VAR_NOT_FOUND;
|
||||
v->not_found = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_host(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_variable_host(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
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;
|
||||
v->len = r->headers_in.host_name_len;
|
||||
v->data = r->headers_in.host->value.data;
|
||||
|
||||
} else {
|
||||
vv->text = r->server_name;
|
||||
v->len = r->server_name.len;
|
||||
v->data = r->server_name.data;
|
||||
}
|
||||
|
||||
return vv;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_remote_addr(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_variable_remote_addr(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_http_variable_value_t *vv;
|
||||
v->len = r->connection->addr_text.len;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = r->connection->addr_text.data;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = 0;
|
||||
vv->text = r->connection->addr_text;
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_remote_port(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_variable_remote_port(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_uint_t port;
|
||||
struct sockaddr_in *sin;
|
||||
ngx_http_variable_value_t *vv;
|
||||
ngx_uint_t port;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
v->len = 0;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
vv->value = 0;
|
||||
vv->text.len = 0;
|
||||
|
||||
vv->text.data = ngx_palloc(r->pool, sizeof("65535") - 1);
|
||||
if (vv->text.data == NULL) {
|
||||
return NULL;
|
||||
v->data = ngx_palloc(r->pool, sizeof("65535") - 1);
|
||||
if (v->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/* AF_INET only */
|
||||
@ -537,34 +563,25 @@ ngx_http_variable_remote_port(ngx_http_request_t *r, uintptr_t data)
|
||||
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;
|
||||
v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
|
||||
}
|
||||
}
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_server_addr(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_variable_server_addr(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
socklen_t len;
|
||||
ngx_connection_t *c;
|
||||
struct sockaddr_in sin;
|
||||
ngx_http_variable_value_t *vv;
|
||||
socklen_t len;
|
||||
ngx_connection_t *c;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = 0;
|
||||
|
||||
vv->text.data = ngx_palloc(r->pool, INET_ADDRSTRLEN);
|
||||
if (vv->text.data == NULL) {
|
||||
return NULL;
|
||||
v->data = ngx_palloc(r->pool, INET_ADDRSTRLEN);
|
||||
if (v->data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
c = r->connection;
|
||||
@ -574,168 +591,126 @@ ngx_http_variable_server_addr(ngx_http_request_t *r, uintptr_t data)
|
||||
if (getsockname(c->fd, (struct sockaddr *) &sin, &len) == -1) {
|
||||
ngx_log_error(NGX_LOG_CRIT, c->log,
|
||||
ngx_socket_errno, "getsockname() failed");
|
||||
return NULL;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
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);
|
||||
v->len = ngx_inet_ntop(c->listening->family, &r->in_addr,
|
||||
v->data, INET_ADDRSTRLEN);
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_server_port(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_variable_server_port(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_http_variable_value_t *vv;
|
||||
v->len = r->port_text->len - 1;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = r->port_text->data + 1;
|
||||
|
||||
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;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_document_root(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_variable_document_root(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, 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;
|
||||
}
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
vv->value = 0;
|
||||
vv->text = clcf->root;
|
||||
v->len = clcf->root.len;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = clcf->root.data;
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_request_filename(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_variable_request_filename(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_http_variable_value_t *vv;
|
||||
ngx_str_t path;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = 0;
|
||||
|
||||
if (ngx_http_map_uri_to_path(r, &vv->text, 0) == NULL) {
|
||||
return NULL;
|
||||
if (ngx_http_map_uri_to_path(r, &path, 0) == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/* ngx_http_map_uri_to_path() allocates memory for terminating '\0' */
|
||||
|
||||
vv->text.len--;
|
||||
v->len = path.len - 1;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = path.data;
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_request_method(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_variable_request_method(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_http_variable_value_t *vv;
|
||||
if (r->method_name.data) {
|
||||
if (r->upstream && r->upstream->method.len) {
|
||||
v->len = r->upstream->method.len;
|
||||
v->data = r->upstream->method.data;
|
||||
|
||||
if (r->method_name.data == NULL) {
|
||||
return NGX_HTTP_VAR_NOT_FOUND;
|
||||
}
|
||||
} else {
|
||||
v->len = r->method_name.len;
|
||||
v->data = r->method_name.data;
|
||||
}
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = 0;
|
||||
|
||||
if (r->upstream && r->upstream->method.len) {
|
||||
vv->text = r->upstream->method;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
} else {
|
||||
vv->text = r->method_name;
|
||||
v->not_found = 1;
|
||||
}
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_remote_user(ngx_http_request_t *r, uintptr_t data)
|
||||
static ngx_int_t
|
||||
ngx_http_variable_remote_user(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_http_variable_value_t *vv;
|
||||
ngx_int_t rc;
|
||||
|
||||
rc = ngx_http_auth_basic_user(r);
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
return NGX_HTTP_VAR_NOT_FOUND;
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
return NULL;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
v->len = r->headers_in.user.len;
|
||||
v->valid = 1;
|
||||
v->no_cachable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = r->headers_in.user.data;
|
||||
|
||||
vv->value = 0;
|
||||
vv->text = r->headers_in.user;
|
||||
|
||||
return vv;
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_value_t *
|
||||
ngx_http_variable_sent(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
off_t sent;
|
||||
u_char *p;
|
||||
ngx_http_variable_value_t *vv;
|
||||
|
||||
vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
|
||||
if (vv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sent = r->connection->sent;
|
||||
|
||||
if (data) {
|
||||
sent -= r->header_size;
|
||||
|
||||
if (sent < 0) {
|
||||
sent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
p = ngx_palloc(r->pool, NGX_OFF_T_LEN);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vv->value = 0;
|
||||
vv->text.len = ngx_sprintf(p, "%O", sent) - p;
|
||||
vv->text.data = p;
|
||||
|
||||
return vv;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,18 +14,22 @@
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
#define NGX_HTTP_VAR_NOT_FOUND (ngx_http_variable_value_t *) -1
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_uint_t value;
|
||||
ngx_str_t text;
|
||||
unsigned len:29;
|
||||
|
||||
unsigned valid:1;
|
||||
unsigned no_cachable:1;
|
||||
unsigned not_found:1;
|
||||
|
||||
u_char *data;
|
||||
} ngx_http_variable_value_t;
|
||||
|
||||
#define ngx_http_variable(v) { sizeof(v) - 1, 1, 0, 0, (u_char *) v }
|
||||
|
||||
typedef struct ngx_http_variable_s ngx_http_variable_t;
|
||||
|
||||
typedef ngx_http_variable_value_t *
|
||||
(*ngx_http_get_variable_pt) (ngx_http_request_t *r, uintptr_t data);
|
||||
typedef ngx_int_t (*ngx_http_get_variable_pt) (ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
||||
|
||||
#define NGX_HTTP_VAR_CHANGABLE 1
|
||||
@ -34,11 +38,11 @@ typedef ngx_http_variable_value_t *
|
||||
|
||||
|
||||
struct ngx_http_variable_s {
|
||||
ngx_str_t name; /* must be first to build the hash */
|
||||
ngx_http_get_variable_pt handler;
|
||||
uintptr_t data;
|
||||
ngx_uint_t flags;
|
||||
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;
|
||||
ngx_uint_t index;
|
||||
};
|
||||
|
||||
|
||||
@ -47,9 +51,15 @@ ngx_http_variable_t *ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name,
|
||||
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_flushed_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);
|
||||
|
||||
#define ngx_http_clear_variable(r, index) r->variables0[index].text.data = NULL;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
@ -18,6 +18,9 @@ typedef struct {
|
||||
|
||||
ngx_str_t host_header;
|
||||
ngx_str_t uri;
|
||||
ngx_str_t header;
|
||||
|
||||
ngx_array_t *headers;
|
||||
} ngx_imap_auth_http_conf_t;
|
||||
|
||||
|
||||
@ -70,6 +73,8 @@ static void *ngx_imap_auth_http_create_conf(ngx_conf_t *cf);
|
||||
static char *ngx_imap_auth_http_merge_conf(ngx_conf_t *cf, void *parent,
|
||||
void *child);
|
||||
static char *ngx_imap_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||
static char *ngx_imap_auth_http_header(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
void *conf);
|
||||
|
||||
|
||||
static ngx_command_t ngx_imap_auth_http_commands[] = {
|
||||
@ -88,6 +93,13 @@ static ngx_command_t ngx_imap_auth_http_commands[] = {
|
||||
offsetof(ngx_imap_auth_http_conf_t, timeout),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("auth_http_header"),
|
||||
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE2,
|
||||
ngx_imap_auth_http_header,
|
||||
NGX_IMAP_SRV_CONF_OFFSET,
|
||||
0,
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
@ -991,12 +1003,12 @@ ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool,
|
||||
}
|
||||
|
||||
b->last = ngx_cpymem(b->last, "GET ", sizeof("GET ") - 1);
|
||||
b->last = ngx_cpymem(b->last, ahcf->uri.data, ahcf->uri.len);
|
||||
b->last = ngx_copy(b->last, ahcf->uri.data, ahcf->uri.len);
|
||||
b->last = ngx_cpymem(b->last, " HTTP/1.0" CRLF,
|
||||
sizeof(" HTTP/1.0" CRLF) - 1);
|
||||
|
||||
b->last = ngx_cpymem(b->last, "Host: ", sizeof("Host: ") - 1);
|
||||
b->last = ngx_cpymem(b->last, ahcf->host_header.data,
|
||||
b->last = ngx_copy(b->last, ahcf->host_header.data,
|
||||
ahcf->host_header.len);
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
@ -1004,11 +1016,11 @@ ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool,
|
||||
sizeof("Auth-Method: plain" CRLF) - 1);
|
||||
|
||||
b->last = ngx_cpymem(b->last, "Auth-User: ", sizeof("Auth-User: ") - 1);
|
||||
b->last = ngx_cpymem(b->last, s->login.data, s->login.len);
|
||||
b->last = ngx_copy(b->last, s->login.data, s->login.len);
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
b->last = ngx_cpymem(b->last, "Auth-Pass: ", sizeof("Auth-Pass: ") - 1);
|
||||
b->last = ngx_cpymem(b->last, s->passwd.data, s->passwd.len);
|
||||
b->last = ngx_copy(b->last, s->passwd.data, s->passwd.len);
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
b->last = ngx_cpymem(b->last, "Auth-Protocol: ",
|
||||
@ -1021,10 +1033,14 @@ ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool,
|
||||
s->login_attempt);
|
||||
|
||||
b->last = ngx_cpymem(b->last, "Client-IP: ", sizeof("Client-IP: ") - 1);
|
||||
b->last = ngx_cpymem(b->last, s->connection->addr_text.data,
|
||||
b->last = ngx_copy(b->last, s->connection->addr_text.data,
|
||||
s->connection->addr_text.len);
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
if (ahcf->header.len) {
|
||||
b->last = ngx_copy(b->last, ahcf->header.data, ahcf->header.len);
|
||||
}
|
||||
|
||||
/* add "\r\n" at the header end */
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
@ -1065,6 +1081,11 @@ ngx_imap_auth_http_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
ngx_imap_auth_http_conf_t *prev = parent;
|
||||
ngx_imap_auth_http_conf_t *conf = child;
|
||||
|
||||
u_char *p;
|
||||
size_t len;
|
||||
ngx_uint_t i;
|
||||
ngx_table_elt_t *header;
|
||||
|
||||
if (conf->peers == NULL) {
|
||||
conf->peers = prev->peers;
|
||||
conf->host_header = prev->host_header;
|
||||
@ -1073,6 +1094,34 @@ ngx_imap_auth_http_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
|
||||
ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
|
||||
|
||||
if (conf->headers == NULL) {
|
||||
conf->headers = prev->headers;
|
||||
conf->header = prev->header;
|
||||
}
|
||||
|
||||
if (conf->headers && conf->header.len == 0) {
|
||||
len = 0;
|
||||
header = conf->headers->elts;
|
||||
for (i = 0; i < conf->headers->nelts; i++) {
|
||||
len += header[i].key.len + 2 + header[i].value.len + 2;
|
||||
}
|
||||
|
||||
p = ngx_palloc(cf->pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
conf->header.len = len;
|
||||
conf->header.data = p;
|
||||
|
||||
for (i = 0; i < conf->headers->nelts; i++) {
|
||||
p = ngx_cpymem(p, header[i].key.data, header[i].key.len);
|
||||
*p++ = ':'; *p++ = ' ';
|
||||
p = ngx_cpymem(p, header[i].value.data, header[i].value.len);
|
||||
*p++ = CR; *p++ = LF;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
@ -1087,7 +1136,7 @@ ngx_imap_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
ngx_unix_domain_upstream_t unix_upstream;
|
||||
#endif
|
||||
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
url = &value[1];
|
||||
@ -1143,3 +1192,32 @@ ngx_imap_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_imap_auth_http_header(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_imap_auth_http_conf_t *ahcf = conf;
|
||||
|
||||
ngx_str_t *value;
|
||||
ngx_table_elt_t *header;
|
||||
|
||||
if (ahcf->headers == NULL) {
|
||||
ahcf->headers = ngx_array_create(cf->pool, 1, sizeof(ngx_table_elt_t));
|
||||
if (ahcf->headers == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
header = ngx_array_push(ahcf->headers);
|
||||
if (header == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
header->key = value[1];
|
||||
header->value = value[2];
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
@ -83,6 +83,12 @@ static ngx_command_t ngx_imap_ssl_commands[] = {
|
||||
ngx_imap_ssl_nosupported, 0, 0, ngx_imap_ssl_openssl097 },
|
||||
#endif
|
||||
|
||||
{ ngx_string("ssl_session_timeout"),
|
||||
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_sec_slot,
|
||||
NGX_IMAP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_imap_ssl_conf_t, session_timeout),
|
||||
NULL },
|
||||
|
||||
ngx_null_command
|
||||
};
|
||||
@ -140,6 +146,7 @@ ngx_imap_ssl_create_conf(ngx_conf_t *cf)
|
||||
*/
|
||||
|
||||
scf->enable = NGX_CONF_UNSET;
|
||||
scf->session_timeout = NGX_CONF_UNSET;
|
||||
scf->prefer_server_ciphers = NGX_CONF_UNSET;
|
||||
|
||||
return scf;
|
||||
@ -160,6 +167,9 @@ ngx_imap_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
ngx_conf_merge_value(conf->session_timeout,
|
||||
prev->session_timeout, 300);
|
||||
|
||||
ngx_conf_merge_value(conf->prefer_server_ciphers,
|
||||
prev->prefer_server_ciphers, 0);
|
||||
|
||||
@ -225,6 +235,8 @@ ngx_imap_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
SSL_CTX_set_session_id_context(conf->ssl.ctx, ngx_imap_session_id_ctx,
|
||||
sizeof(ngx_imap_session_id_ctx) - 1);
|
||||
|
||||
SSL_CTX_set_timeout(conf->ssl.ctx, conf->session_timeout);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ typedef struct {
|
||||
|
||||
ngx_uint_t protocols;
|
||||
|
||||
time_t session_timeout;
|
||||
|
||||
ngx_str_t certificate;
|
||||
ngx_str_t certificate_key;
|
||||
|
||||
|
@ -15,9 +15,10 @@ static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n,
|
||||
static void ngx_start_garbage_collector(ngx_cycle_t *cycle, ngx_int_t type);
|
||||
static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo);
|
||||
static ngx_uint_t ngx_reap_childs(ngx_cycle_t *cycle);
|
||||
static void ngx_master_exit(ngx_cycle_t *cycle);
|
||||
static void ngx_master_process_exit(ngx_cycle_t *cycle);
|
||||
static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data);
|
||||
static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority);
|
||||
static void ngx_worker_process_exit(ngx_cycle_t *cycle);
|
||||
static void ngx_channel_handler(ngx_event_t *ev);
|
||||
#if (NGX_THREADS)
|
||||
static void ngx_wakeup_worker_threads(ngx_cycle_t *cycle);
|
||||
@ -156,7 +157,7 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
|
||||
}
|
||||
|
||||
if (!live && (ngx_terminate || ngx_quit)) {
|
||||
ngx_master_exit(cycle);
|
||||
ngx_master_process_exit(cycle);
|
||||
}
|
||||
|
||||
if (ngx_terminate) {
|
||||
@ -283,7 +284,7 @@ ngx_single_process_cycle(ngx_cycle_t *cycle)
|
||||
}
|
||||
}
|
||||
|
||||
ngx_master_exit(cycle);
|
||||
ngx_master_process_exit(cycle);
|
||||
}
|
||||
|
||||
if (ngx_reconfigure) {
|
||||
@ -628,7 +629,7 @@ ngx_reap_childs(ngx_cycle_t *cycle)
|
||||
|
||||
|
||||
static void
|
||||
ngx_master_exit(ngx_cycle_t *cycle)
|
||||
ngx_master_process_exit(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
|
||||
@ -658,8 +659,6 @@ ngx_master_exit(ngx_cycle_t *cycle)
|
||||
static void
|
||||
ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_connection_t *c;
|
||||
#if (NGX_THREADS)
|
||||
ngx_int_t n;
|
||||
ngx_err_t err;
|
||||
@ -717,26 +716,7 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
|
||||
|
||||
|
||||
#if (NGX_THREADS)
|
||||
ngx_terminate = 1;
|
||||
|
||||
ngx_wakeup_worker_threads(cycle);
|
||||
#endif
|
||||
|
||||
if (ngx_debug_quit) {
|
||||
ngx_debug_point();
|
||||
}
|
||||
|
||||
/*
|
||||
* we do not destroy cycle->pool here because a signal handler
|
||||
* that uses cycle->log can be called at this point
|
||||
*/
|
||||
|
||||
#if 0
|
||||
ngx_destroy_pool(cycle->pool);
|
||||
#endif
|
||||
exit(0);
|
||||
ngx_worker_process_exit(cycle);
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
|
||||
@ -746,41 +726,7 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
|
||||
if (ngx_terminate) {
|
||||
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
|
||||
|
||||
#if (NGX_THREADS)
|
||||
ngx_wakeup_worker_threads(cycle);
|
||||
#endif
|
||||
|
||||
for (i = 0; ngx_modules[i]; i++) {
|
||||
if (ngx_modules[i]->exit_process) {
|
||||
ngx_modules[i]->exit_process(cycle);
|
||||
}
|
||||
}
|
||||
|
||||
c = cycle->connections;
|
||||
for (i = 0; i < cycle->connection_n; i++) {
|
||||
if (c[i].fd != -1
|
||||
&& c[i].read
|
||||
&& !c[i].read->accept
|
||||
&& !c[i].read->channel)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
||||
"open socket #%d left in %ui connection, "
|
||||
"aborting",
|
||||
c[i].fd, i);
|
||||
ngx_abort();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* we do not destroy cycle->pool here because a signal handler
|
||||
* that uses cycle->log can be called at this point
|
||||
*/
|
||||
|
||||
#if 0
|
||||
ngx_destroy_pool(cycle->pool);
|
||||
#endif
|
||||
|
||||
exit(0);
|
||||
ngx_worker_process_exit(cycle);
|
||||
}
|
||||
|
||||
if (ngx_quit) {
|
||||
@ -956,6 +902,56 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_worker_process_exit(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_connection_t *c;
|
||||
|
||||
#if (NGX_THREADS)
|
||||
ngx_terminate = 1;
|
||||
|
||||
ngx_wakeup_worker_threads(cycle);
|
||||
#endif
|
||||
|
||||
for (i = 0; ngx_modules[i]; i++) {
|
||||
if (ngx_modules[i]->exit_process) {
|
||||
ngx_modules[i]->exit_process(cycle);
|
||||
}
|
||||
}
|
||||
|
||||
c = cycle->connections;
|
||||
for (i = 0; i < cycle->connection_n; i++) {
|
||||
if (c[i].fd != -1
|
||||
&& c[i].read
|
||||
&& !c[i].read->accept
|
||||
&& !c[i].read->channel)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
||||
"open socket #%d left in %ui connection, "
|
||||
"aborting",
|
||||
c[i].fd, i);
|
||||
ngx_abort();
|
||||
}
|
||||
}
|
||||
|
||||
if (ngx_debug_quit) {
|
||||
ngx_debug_point();
|
||||
}
|
||||
|
||||
/*
|
||||
* we do not destroy cycle->pool here because a signal handler
|
||||
* that uses cycle->log can be called at this point
|
||||
*/
|
||||
|
||||
#if 0
|
||||
ngx_destroy_pool(cycle->pool);
|
||||
#endif
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_channel_handler(ngx_event_t *ev)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user