Compare commits

...

134 Commits

Author SHA1 Message Date
Igor Sysoev ee22c0a33b release-0.7.69 tag 2011-07-19 14:20:33 +00:00
Igor Sysoev 2c80cff285 nginx-0.7.69-RELEASE 2011-07-19 14:20:25 +00:00
Igor Sysoev e673d7c5c9 copy OpenSSL-0.9.8r LICENSE for nginx/Windows zip 2011-07-19 14:16:58 +00:00
Igor Sysoev 0346321da5 merge r3945:
fix segfault if cache key is larger than upstream buffer size
patch by Lanshun Zhou
2011-07-19 14:15:50 +00:00
Igor Sysoev 364399a29c bump version 2011-07-19 14:11:18 +00:00
Igor Sysoev 459ed367fc release-0.7.68 tag 2010-12-14 19:48:04 +00:00
Igor Sysoev 5e089f4eca nginx-0.7.68-RELEASE 2010-12-14 19:48:03 +00:00
Igor Sysoev 1613129672 merge r3797:
allocate last zero byte in ngx_crypt()
2010-12-14 19:35:44 +00:00
Igor Sysoev a9166b8255 merge r3681:
update r->buffered after processing SSI command,
the bug has been probably introduced in r2378
2010-12-14 19:34:29 +00:00
Igor Sysoev bbc52b9b28 merge r3676:
fix case of partially matched patterns on buffer border in sub_filter
2010-12-14 19:32:52 +00:00
Igor Sysoev 813d95d705 SSL related fixes:
*) merge r3675:
   fix recognition of SSLv2 Client Hello Packet large than 255 bytes
*) upgrade OpenSSL to 0.8.9q in nginx/Windows
2010-12-14 19:29:57 +00:00
Igor Sysoev aad4528125 merge r3659, r3825, r3826:
IPv6 related fixes:

*) fix IPv6 listen socket handling while reconfiguring
*) test wildcard tail hash existance for IPv6 addresses,
   the same fix for IPv4 addresses has been made in r2581
*) always run regex in server_name to get captures for IPv6 addresses,
   the same fix for IPv4 addresses has been made in r2584
2010-12-14 19:19:07 +00:00
Igor Sysoev 95c86bc8b4 set r->valid_unparsed_uri just after request line processing,
it allows to use X-Accel-Redirect'ed URI in a proxy_pass without URI part
this fix corresponds to r3616
2010-12-14 19:15:08 +00:00
Igor Sysoev d53c2ebaa3 bump version 2010-12-14 19:10:00 +00:00
Igor Sysoev 0fa6d231bc release-0.7.67 tag 2010-06-15 09:55:01 +00:00
Igor Sysoev 87fc2486af nginx-0.7.67-RELEASE 2010-06-15 09:55:00 +00:00
Igor Sysoev 86fa681d16 merge r3615:
do not free() stack allocated buffer
2010-06-15 09:51:58 +00:00
Igor Sysoev 784e96770e bump version 2010-06-15 09:50:55 +00:00
Igor Sysoev 31ada09e06 release-0.7.66 tag 2010-06-07 12:41:32 +00:00
Igor Sysoev 9e711c55b6 nginx-0.7.66-RELEASE 2010-06-07 12:41:31 +00:00
Igor Sysoev d8020e69f5 merge r3528:
remove r->zero_in_uri
2010-06-07 12:27:06 +00:00
Igor Sysoev 4bda43e5b9 merge r3518, r3527:
cache related fixes:

*) do not cache response if it has "no-store" or "private"
   in "Cache-Control" header
*) proxy_no_cache and fastcgi_no_cache
2010-06-07 12:23:23 +00:00
Igor Sysoev 7637e17aac merge r3502:
use lstat() for WebDAV DELETE, COPY, and MOVE to handle symlinks
2010-06-07 12:17:10 +00:00
Igor Sysoev f40f491092 merge r3498, r3499:
opening files fixes:

*) use non-blocking open() not to hang on FIFO files, etc.
*) do not log misleading errno in "not a regular file" error
2010-06-07 12:08:44 +00:00
Igor Sysoev 8b6279ef16 merge r3489, r3493:
*) MSVC8 compatibility with OpenSSL 1.0.0
*) fix building OpenSSL-1.0.0 on 64-bit Linux:
   make installs the libraries in lib64 directory

and build nginx/Windows against OpenSSL-0.9.8n
2010-06-07 11:55:20 +00:00
Igor Sysoev 8258c50bbb merge r3487, r3525:
rewrite fixes:

*) escape ampersand in argument while rewrite
*) autodetect redirect if URI is rewritten to a string starting with $scheme
2010-06-07 11:51:37 +00:00
Igor Sysoev f93f77f431 merge r3488:
revert partially r1555 and fix the error "memcached sent invalid trailer"
2010-06-07 11:49:03 +00:00
Igor Sysoev 64a572cb8c merge r3482:
do not set file time in ngx_copy_file() if the time is -1,
this fixes an issue when file is moved across devices
2010-06-07 11:48:19 +00:00
Igor Sysoev 584e7aefb0 merge r3515:
fix segfault: ngx_http_upstream_cleanup() cleans r->cleanup,
the bug had been introduced in r3426
2010-06-07 11:46:43 +00:00
Igor Sysoev b61109cc00 merge r3478:
reset a parsing state to parse correctly an upstream response,
if 400 or 414 response has been redirected to upstream
2010-06-07 11:45:04 +00:00
Igor Sysoev fc9853f61c merge r3477:
zlib 1.2.4 compatibility
2010-06-07 10:37:58 +00:00
Igor Sysoev 8b45b8d1b4 merge r3473, r3474, r3385, r3386, r3537:
signal processing stability:

*) use sys_errlist[] in signal handler instead
   of non Async-Signal-Safe strerror_r()
*) do not update time in the timer signal handler,
   since localtime_r() is not Async-Signal-Safe function
*) use previously cached GMT offset value to update time from a signal handler
*) change ngx_time_update() interface since there are no notification methods
   those return time
*) introduce ngx_time_sigsafe_update() to update the error log time only
*) change ngx_time_update() interface
2010-06-07 10:35:08 +00:00
Igor Sysoev bb699ffdb2 merge r3464, r3500, r3501:
*) make $request_method non-cacheable
*) make $arg_ variables non-cacheable
*) change processing variables accessed by SSI and perl module:
   *) the indexed variables are always flushed
   *) never show warning for not found variables
2010-06-07 10:26:50 +00:00
Igor Sysoev 9e81dfc1d4 merge r3460:
allow HTTPS referers
2010-06-07 10:15:21 +00:00
Igor Sysoev 54f0e8ae0a merge r3459, r3571:
Win32 fixes:

*) compare long file names in case-insensitive mode,
   the bug had been introduced in r3436
*) test default NTFS stream "::$DATA"
2010-06-07 10:14:11 +00:00
Igor Sysoev 5ff6279efa merge r3456, r3458, r3465:
SSL fixes:

*) decrease SSL handshake error level to info
*) Set SSL session context for "ssl_session_cache none".
   This fixes a bug when client certficate is used and nginx closes connection
   with the message: "SSL_GET_PREV_SESSION:session id context uninitialized".
*) add OpenSSL_add_all_algorithms(), this fixes the error
   "ASN1_item_verify:unknown message digest algorithm" occurred if
   client certificate is signed using sha256WithRSAEncryption
2010-06-07 10:09:14 +00:00
Igor Sysoev 8a0e2616c2 merge r3457:
fix a geo range if the range includes two or more /16 networks
and does not begin at /16 network boundary
2010-06-07 10:04:13 +00:00
Igor Sysoev 3baed8e663 merge r3454, r3455, r3486, r3496, r3519, r3523:
SSI fixes:

*) use content type of the parent request in SSI stub block output
   instead of default one
*) SSI %s timefmt has no timezone offset
*) change ngx_http_ssi_filter and ngx_http_charset_filter order
*) do not store an encoded variable value as a new cached variable value
*) fix SSI include stub for valid empty responses
*) allow to use $uid_got in SSI and perl module
2010-06-07 09:54:19 +00:00
Igor Sysoev f3a89a2cd3 merge r3452, r3462, r3471, r3472:
fix miscellaneous name bugs:

*) fix $upstream_http_ variable prefix length
*) use a right "Location" header name, however, it did not harm,
   since ngx_http_variable_sent_location() never use key name field
*) fix proxy_redirect name in error message
*) "proxy_redirect default" may not be used if a proxy_pass uses variables
2010-06-07 09:36:33 +00:00
Igor Sysoev e6365cd48e merge r3451, r3506:
mail related fixes:

*) delete surplus code
*) Zimbra IMAP server may return only 4 bytes: "+ \r\n"
2010-06-07 09:25:39 +00:00
Igor Sysoev edebdd6404 merge r3412, r3485:
*) allow a chunked body for 201 responses
*) chunked_transfer_encoding
2010-06-07 09:19:10 +00:00
Igor Sysoev b1a13a3501 merge r3399:
$geoip_city_continent_code, $geoip_latitude, $geoip_longitude
2010-06-07 09:06:39 +00:00
Igor Sysoev 974c49330c merge r3394, r3395:
force image filter conversion if JPEG application data consume more than 5%
2010-06-07 09:05:18 +00:00
Igor Sysoev 5427dc9ee5 merge r3368, r3392:
./configure related fixes:

*) test invalid --with-ld-opt in right place
*) do not add NGX_GCC_OPT twice: it is added later with -W
2010-06-07 09:01:46 +00:00
Igor Sysoev d916bacca5 merge r3318, r3449:
perl related fixes:

*) do not log error if $r->variable was not found
*) delete ngx_http_perl_cleanup_t unused since r909
2010-06-07 08:51:48 +00:00
Igor Sysoev 47762239ef merge r3316, r3317, r3420, r3421, r3453:
browsers related fixes:

*) add MSIE padding for Chrome too
*) disable keepalive for Safari:
       https://bugs.webkit.org/show_bug.cgi?id=5760
*) do not disable keepalive after POST requests for MSIE 7+
2010-06-04 17:47:04 +00:00
Igor Sysoev 68a58c361d bump version 2010-06-04 17:38:59 +00:00
Igor Sysoev 838eb01a8b release-0.7.65 tag 2010-02-01 16:09:16 +00:00
Igor Sysoev eee52d16e8 nginx-0.7.65-RELEASE 2010-02-01 16:09:15 +00:00
Igor Sysoev d13451937a merge r3406:
fix negative time in "Cache-Control" if "expires modified" sets time in the past
2010-02-01 15:56:45 +00:00
Igor Sysoev 6eb6500651 merge r3351, r3352:
perl exit fixes:

*) use global perl variable in perl_destruct()/perl_free()
   for non-mulitiplicity perl
*) add comment from r2716 commit message
2010-02-01 15:55:48 +00:00
Igor Sysoev d1378313b6 merge r3309, r3314, r3315, r3380:
gzip headers related fixes:

*) remove "Content-Encoding: gzip" in 304 response
   sent by ngx_http_gzip_static_module
*) refactor gzip_vary handling
*) test r->header_only last, since it's not actually
   frequent here: 304 and HEAD responses are not set it before the filter
2010-02-01 15:54:02 +00:00
Igor Sysoev ac11ecdcb2 merge r3294, r3305:
Fix a bug introduced in r2032: After a child process has read a terminate
message from a channel, the process tries to read the channel again.
The kernel (at least FreeBSD) may preempt the process and sends a SIGIO
signal to a master process. The master process sends a new terminate message,
the kernel switches again to the the child process, and the child process
reads the messages instead of an EAGAIN error. And this may repeat over
and over. Being that the child process can not exit the cycle and test
the termination flag set by the message handler.

The fix disallow the master process to send a new terminate message on
SIGIO signal reception. It may send the message only on SIGALARM signal.
2010-02-01 15:49:36 +00:00
Igor Sysoev 6f400f8a46 merge r3137, r3198, r3199, r3353, r3370, r3371, r3398, r3399:
cache related fixes:

*) do not pass buf with empty cached response,
   this fixes "zero size buf in output" alert
*) hide cacheable Set-Cookie and P3P FastCGI response headers
*) test comma separator in "Cache-Control"
*) a cache manager thread handle was overwritten by a cache loader thread
   handle, this caused an exit delay, the bug had been introduced in r3248
*) fix handling cached HTTP/0.9 response
*) log proxied HTTP/0.9 responses status as "009"
*) fix the "If-None-Match" header name
*) fix a cached zero-length body case
2010-02-01 15:46:14 +00:00
Igor Sysoev 9d87953f67 merge r3286:
use setproctitle("%s", title)
2010-02-01 15:32:57 +00:00
Igor Sysoev 7ac538bd2a merge r3283, r3284:
fix segfault if $limit_rate was logged
fix segfault in SSL if limit_rate is used
2010-02-01 15:20:43 +00:00
Igor Sysoev 8059c8bb5c merge r3282:
fix "if (!-x ...)"
2010-02-01 15:17:12 +00:00
Igor Sysoev 553388bca1 merge r3138, r3139, r3157, r3158, r3159, r3164, r3165,
r3202, r3203, r3383, r3388, r3417, r3418:

Win32 (mostly) and some Unix file related fixes:

*) preserve errno while ngx_free()
*) win32 ngx_file_info() utf8 support
*) delete Win95 code
*) log file name for read/write errors
*) test incomplete WriteFile()
*) handle short pwrite() to log an error cause: ENOSPC, EDQUOT, or EFBIG
*) uniform ngx_directio_on/off() interface with other file functions
*) do not create Win32 drive letter in ngx_create_full_path()
*) ignore EACCES errors for top level directories in ngx_create_full_path()
*) fix Win32 error messages when an temporary file replaces an existent file:
   *) do not rename an already renamed file
   *) now ngx_win32_rename_file() returns error code
   *) do not log failure inside ngx_win32_rename_file()
*) fix Win32 error message when an temporary file replaces an existent file:
   return at once if ngx_win32_rename_file() was not failed
   and do not try to delete already the renamed temporary file
*) skip URI trailing spaces under Win32
*) disable Win32 short file names
2010-02-01 15:06:25 +00:00
Igor Sysoev 45ccf9336a merge r3208, r3209:
ngx_http_parse_time() fixes:

*) use ngx_uint_t instead of int,
   strange to say this reduce function size by 16 bytes
*) ngx_http_parse_time() should support full 32-bit time
2010-02-01 14:55:53 +00:00
Igor Sysoev f846765797 merge r3201, r3204, r3411:
ngx_http_autoindex_module fixes:

*) reset cached dirent.d_type after stat()
   this fixes slash after link to a directory in ngx_http_autoindex_module;
*) use cached dirent.d_type as hint on all systems

   the issues has been introduced in r2235

*) fix ngx_utf8_cpystrn(): it did not fully copy utf-8 string
2010-02-01 14:52:25 +00:00
Igor Sysoev 651ae60661 merge r3200:
nginx did not close log file set by --error-log-path,
the bug was introduced in r2744
2010-02-01 14:44:43 +00:00
Igor Sysoev 324484a59c merge r3163, r3213:
*) fix discarding body
*) prevent handling discarded body as a pipelined request
2010-02-01 14:42:38 +00:00
Igor Sysoev 70a7d24817 merge r3155, r3156, r3160, r969, r3191, r3197, r3358:
SSL fixes:

*) $ssl_session_id
*) allow "make clean" for OpenSSL, the bug was introduced in r2874
*) disable SSLv2 and use only strong ciphers by default
*) decrease SSL handshake error level to info
2010-02-01 14:39:16 +00:00
Igor Sysoev 87706c49c3 merge r3148, r3152, r3161:
error processing fixes:

*) fail if file size was changed
*) low default connection errors level from alert to error
*) low ENAMETOOLONG logging level
2010-02-01 14:31:26 +00:00
Igor Sysoev 313e559485 merge r3147:
fix typo in addition_types directive name
2010-02-01 14:24:20 +00:00
Igor Sysoev a5b05e329f merge r3153, r3154, r3288, r3382:
request header processing fixes:

*) $host is always in low case:
   *) move low case convertation from ngx_http_find_virtual_server()
      to ngx_http_validate_host()
   *) add in ngx_http_validate_host() capability to copy host name in the pool
      allocated memory
*) fix segfault if there is single large_client_header_buffers
   and a request line fills it completely
*) default large_client_header_buffers' buffer size should be 8K as compatible
   with Apache's one
2010-02-01 14:16:45 +00:00
Igor Sysoev 841bb0752b merge r3039, r3145:
access_log fixes:

*) strict testing "access_log off"
*) allow to log invalid $request in access_log always,
   before it was logged only if error_log was set to info or debug level
2010-02-01 14:04:20 +00:00
Igor Sysoev 3f326eb3b5 merge r2990, r3324, r3384, r3419:
various proxy/FastCGI fixes:

*) do auto redirect for proxy_pass/fastcgi_pass with variables
*) allow "proxy_pass  http://$backend" without URI part
*) add conf/fastcgi.conf
*) delete u->cleanup mark, this fixes large values in $upstream_response_time,
   the bug had been introduced in r3246
2010-02-01 14:01:24 +00:00
Igor Sysoev d53377900f merge r3408:
update year
2010-02-01 13:53:14 +00:00
Igor Sysoev b4d638cfe6 bump version 2010-02-01 13:50:03 +00:00
Igor Sysoev 5b910b0880 release-0.7.64 tag 2009-11-16 15:29:47 +00:00
Igor Sysoev b0842a2a7d nginx-0.7.64-RELEASE 2009-11-16 15:29:46 +00:00
Igor Sysoev 09dd51fe1f r3301 merge:
disable SSL renegotiation (CVE-2009-3555)
2009-11-16 15:24:39 +00:00
Igor Sysoev d657043fe1 r3141 merge:
fix posix_memalign() error handling
2009-11-16 15:22:03 +00:00
Igor Sysoev 971e495c55 r3313 merge:
nginx sent gzipped responses to clients those do not support gzip,
if "gzip_static on" and "gzip_vary off"; the bug had been introduced in r3250
2009-11-16 15:16:47 +00:00
Igor Sysoev 0980938054 r3140, r3144, r3298, r3299, r3300, r3307, r3308 merge:
resolver fixes:

*) fix memory leak in resolver
*) fix resolver cache rbtree comparison
*) fix segfault in resolver:
   ngx_resolve_name_done() and ngx_resolve_addr_done() did not delete
   contexts from a resolver node waiting list.
*) fix "PTR ." case in address resolver
*) add quotes in an error message,
*) fix resolving an empty name (".")
*) use ngx_resolver_alloc() instead of ngx_resolver_calloc()
   since all fields are filled
2009-11-16 15:13:02 +00:00
Igor Sysoev e7d583d555 r3117, r3123, r3229 merge:
server name related merges:

*) If .domain.com, .sub.domain.com, and .domain-some.com were defined,
   then .sub.domain.com was matched by .domain.com: wildcard names hash
   was built incorrectly due to sorting order issue of "." vs "-".
   They were sorted as
       com.domain  com.domain-some  com.domain.sub
   while they should be sorted as
       com.domain  com.domain.sub   com.domain-some
   for correct hash building

*) test space between "~" and regex in server_name and invalid_referers

*) do not run regex for empty host name since regex always fails in this case,
   the bug had been introduced in r2196
2009-11-16 15:00:13 +00:00
Igor Sysoev acd17d7b4b bump version 2009-11-16 14:52:22 +00:00
Igor Sysoev d0be36af24 release-0.7.63 tag 2009-10-26 17:57:37 +00:00
Igor Sysoev 332c854d50 nginx-0.7.63-RELEASE 2009-10-26 17:57:36 +00:00
Igor Sysoev a2939c14c8 merge r3185:
fix building by gcc45
2009-10-26 17:46:25 +00:00
Igor Sysoev 648c01365f merge r3162, r3183:
WebDAV fixes:

*) check unsafe Destination
*) omit '\0' from "Location" header on MKCOL request
2009-10-26 17:45:55 +00:00
Igor Sysoev c2c30b26a2 merge r3079:
discard request body before returning 413 error,
this fixes custom 413 page redirection bug introduced in r1456
2009-10-26 17:40:07 +00:00
Igor Sysoev ddfa019fc2 merge r2976:
allow underscore in request method
2009-10-26 17:37:18 +00:00
Igor Sysoev 74007f8ed3 merge r3055, r3136:
gzip related fixes:

*) do not disable gzip for MSIE 6.0 SV1 in "gzip_disable msie6"
*) nginx always sent "Vary: Accept-Encoding",
   if both gzip_static and gzip_vary were on
2009-10-26 17:34:43 +00:00
Igor Sysoev 50e7dc1524 merge r3024, r3025, r3028, r3033, r3034, r3035, r3036:
allow cross device temporary files atomic copying
2009-10-26 17:32:17 +00:00
Igor Sysoev 7119a20a10 merge r3017, r3018, r3019, r3020, r3021, r3022, r3023, r3196:
cache management fixes:

*) separate cache loader process
*) use real file cache length, this fixes cache size counting for responses
   without "Content-Length" header and 304 responses.
2009-10-26 17:23:49 +00:00
Igor Sysoev aaf6f614ba merge r3004, r3005, r3006:
various header fixes:

*) allow to proxy_pass_header/fastcgi_pass_header "X-Accel-Redirect",
   "X-Accel-Limit-Rate", "X-Accel-Buffering", and "X-Accel-Charset"
*) fix handling "Last-Modified" and "Accept-Ranges" for upstream responses
*) clear "Accept-Ranges" for SSI responses
2009-10-26 17:13:44 +00:00
Igor Sysoev 9a7f7e4578 merge r3001, r3007, r3013:
fix variuos segfaults:

*) fix segfault if 400 or 414 errors are handled intricately
*) ngx_http_upstream_create() to cleanup the previous upstream after
   internal redirect
2009-10-26 17:09:27 +00:00
Igor Sysoev 8d1d7b5aaa merge r2999, r3118, r3134, r3135:
various image filter fixes and features:

*) variables support in image_filter
*) fix transparency in GIF
*) fix alpha-channel transparency in PNG
*) image_filter_transparency
2009-10-26 16:56:49 +00:00
Igor Sysoev 66e573174e merge r2995, r2996, r2997, r2998, r3003, r3141, r3210, r3211, r3232:
various SSL fixes and features:

*) $ssl_client_verify
*) "ssl_verify_client ask" was changed to "ssl_verify_client optional"
*) ssl_crl
*) delete OpenSSL pre-0.9.7 compatibility: the sources were not actually
   compatible with OpenSSL 0.9.6 since ssl_session_cache introduction
*) fix memory corruption in $ssl_client_cert
*) issue SNI warning instead of failure: this is too common case
*) use ngx_log_error(), since OpenSSL does not set an error on the failure
*) add SNI support in -V output
2009-10-26 16:53:34 +00:00
Igor Sysoev 55cec826e6 merge r2993:
geo module supports trusted proxies
2009-10-26 16:42:19 +00:00
Igor Sysoev 462ab8826d merge r2986, r2992, r3032:
ngx_http_geoip_module
2009-10-26 16:38:44 +00:00
Igor Sysoev 29db22923f merge r2973, r2974, r3184, r3192, r3186, r3187:
various limit_req and limit_conn fixes:

*) fix client write event handling in ngx_http_limit_req_module
*) make limit_req to conform to the leaky bucket algorithm
*) limit_req_log_level
*) limit_conn_log_level
2009-10-26 16:30:34 +00:00
Igor Sysoev 12138838b6 merge r2972, r2994, r3133, r3142, r3143, r3174, r3175, r3176:
various perl fixes:

*) fix ngx_http_send_special() for subrequests handled by perl
*) allow perl "sub{..."
*) restore environ, this fixes segfault on reconfiguration failure when
   perl module creates new environment
*) optimize error handling
*) use ngx_conf_set_str_array_slot() for perl_require
*) allow several perl_modules
2009-10-26 16:22:24 +00:00
Igor Sysoev 8cec66ecd4 merge r2920, r2934, r3116, r3119:
style fixes
2009-10-26 16:06:11 +00:00
Igor Sysoev c11383c4f2 merge r2903, r2911, r2912, r3002:
fix various failures handling
2009-10-26 15:54:29 +00:00
Igor Sysoev e87d9b3151 merge r2908:
limit_rate_after
2009-10-26 15:46:59 +00:00
Igor Sysoev b75b08ef6b merge r2890, r2891, r2892:
refactor ngx_http_charset_header_filter()
2009-10-26 15:37:54 +00:00
Igor Sysoev b6c39a5510 bump version 2009-10-26 15:32:50 +00:00
Igor Sysoev b47a13102d release-0.7.62 tag 2009-09-14 13:09:55 +00:00
Igor Sysoev 3b3894d6bf nginx-0.7.62-RELEASE 2009-09-14 13:09:54 +00:00
Igor Sysoev 05c22e7b4b merge r3047, r3048, r3049:
twice termination delay only after SIGALRM, otherwise many separate SIGCHLD
and SIGIO signals quickly increase delay to the level when SIGKILL is sent
2009-09-07 11:31:20 +00:00
Igor Sysoev 9973606ec4 r3040:
fix Linux "uname -r" version matching
2009-09-07 11:27:37 +00:00
Igor Sysoev a8b6c54f2c merge r3038:
process upstream ETag header
2009-09-07 11:27:07 +00:00
Igor Sysoev 896d915479 merge r3037:
the flags should be bit-wide only
2009-09-07 11:26:40 +00:00
Igor Sysoev 26b4d3a7cb merge r3076, r3077, r3080:
fix invalid header logging:

*) fix segfault when a header starts with "\rX"
   and logging is set to info or debug level
*) use %*s instead of %V
2009-09-07 11:11:24 +00:00
Igor Sysoev 4758710b63 merge r3011, r3012, r3026:
FastCGI fixes:

*) continue to parse available fastcgi record after a split header,
   this fixes the erroneous message "upstream prematurely closed connection
   while reading response header from upstream"
*) fix a garbage in a split fastcgi header
*) refactor fastcgi stderr handling
2009-09-07 10:12:49 +00:00
Igor Sysoev cec15be7b2 merge r2984, r2985, r3000:
XSLT filter fixes:

*) preserve XML wellFormed field before freeing memory
*) fix libxml2 error message
2009-09-07 10:05:36 +00:00
Igor Sysoev 79d498074b merge r2983:
name of file specified in --conf-path was not honored during installation
the bug had been appeared in r1353
2009-09-07 10:03:15 +00:00
Igor Sysoev 4645fa7c02 merge r2980, r2981, r2982:
win32 fixes:

*) ngx_http_set_exten() is always successful since 0.3.46
*) skip URI trailing dots under Win32
*) use caseless regex locations on caseless filesystems: MacOSX, Win32, Cygwin
2009-09-07 10:01:26 +00:00
Igor Sysoev d6b442b8d4 merge r2975:
handle Win32 ReadFile() EOF state in Unix way
2009-09-07 09:54:47 +00:00
Igor Sysoev 529827109f merge r2953, r2958, r3084:
*) $upstream_cache_status
*) clean cache updating state if a response has uncacheable code or
   cache prohibitive headers
2009-09-07 09:49:51 +00:00
Igor Sysoev 7e4621bfa3 handle "/../" case more reliably 2009-09-07 09:29:41 +00:00
Igor Sysoev 7d0fecc6cb merge r2991:
do not test "..." case since it's Win9x family feature only
2009-09-07 09:25:59 +00:00
Igor Sysoev 1ab7430cdb fix Win95 "/.../" handling for the record 2009-09-07 09:18:55 +00:00
Igor Sysoev ae1a33254a bump version 2009-09-07 09:15:47 +00:00
Igor Sysoev aa6b2514cf release-0.7.61 tag 2009-06-22 09:37:08 +00:00
Igor Sysoev 36f31e9e5e nginx-0.7.61-RELEASE 2009-06-22 09:37:07 +00:00
Igor Sysoev 0fd29f9f30 merge r2954:
fix segfault if there is error_page 401, proxy_intercept_errors is on
and backend does not return "WWW-Authenticate" header
2009-06-22 09:32:03 +00:00
Igor Sysoev d15bfa03e6 merge r2952:
ignore ngx_atomic_fetch_add() result
this fixes building at least by gcc 4.2.1 on Mac OS X 10.6
2009-06-22 09:31:33 +00:00
Igor Sysoev fea94dde50 merge r2950, r2951:
cache related fixes:

*) fix building --without-http-cache, broken in r2945
*) fix ./configure error message
2009-06-22 09:29:10 +00:00
Igor Sysoev 7e726e8111 bump version 2009-06-22 09:23:35 +00:00
Igor Sysoev 0e385d96b7 release-0.7.60 tag 2009-06-15 09:55:52 +00:00
Igor Sysoev 6752d8734a nginx-0.7.60-RELEASE 2009-06-15 09:55:51 +00:00
Igor Sysoev 4bf4a52828 merge r2897, r2898, r2899, r2901, r2902, r2904, r2905, r2906, r2907,
r2909, r2910, r2922, r2923, r2924, r2925, r2929:

various win32 fixes:

*) use no-threads for Unix builds only
*) Win32 returns ERROR_PATH_NOT_FOUND instead of ERROR_FILE_NOT_FOUND
*) add trailing zero to a file name in ngx_win32_rename_file()
*) fix logging in ngx_win32_rename_file()
*) allow shared memory segments more than 4G
*) fix memory leak in successful case
*) log shared memory name in failure case
*) test that zone has the same addresses in different processes
*) add drive letter for Win32 root path
*) log GetExitCodeProcess()'s errno
*) test premature process termination
*) fix debug logging
*) exit if no workers could not be started
*) do not quit old workers if no new workers could not be started
*) a signaller process should stop configuration processing just after
   it is able to get pid file, this allows to not open log files, etc.
*) win32 master process had aready closed listening sockets
2009-06-15 09:48:15 +00:00
Igor Sysoev ae6cd36c40 merge r2895, r2896, r2926, r2927, r2928, r2930, and r2936:
various proxy/fastcgi cache features and fixes:

*) report about proxy/fastcgi_store and proxy/fastcgi_cache incompatibility
*) delete useless r->cache->uses
*) proxy_cache_use_stale/fastcgi_cache_use_stale  updating
*) inherit proxy_set_header, proxy_hide_header, and fastcgi_hide_header
   only if cache settings are similar
*) add response file uniq while loading cold cache on demand
2009-06-15 09:30:59 +00:00
Igor Sysoev 7a2e47f51d merge r2919:
test GIF87a
2009-06-15 09:05:31 +00:00
Igor Sysoev f72368522d merge r2900:
fix XSLT filter in SSI subrequests
2009-06-15 09:02:09 +00:00
Igor Sysoev 4870682da7 merge r2935:
initialize use_event field in open file cache
the bug had been introduced in r2071
2009-06-15 08:58:16 +00:00
Igor Sysoev 2f2fb78ff8 merge r2893, r2894, and r2917:
various ./configure fixes:

*) use md5/sha1 in OpenSSL only if OpenSSL is used
*) stop ./configure at once on library failure
*) librt must be tested before creating Makefile
   the bug has been introduced in r2817
2009-06-15 08:49:53 +00:00
Igor Sysoev 8b3cfa8884 merge r2889, r2918, and r2921:
fix a pool growing and CPU usage for multi-requests keepalive connections:

*) keepalive_requests
*) try to reuse last 4 free large allocation links
*) do not test a pool block space if we can not allocated from
   the block 4 times
2009-06-15 08:43:10 +00:00
Igor Sysoev 743ecf05b6 bump version 2009-06-15 08:36:30 +00:00
Igor Sysoev fc357e1f79 stable-0.7 branch 2009-05-25 12:05:02 +00:00
144 changed files with 5590 additions and 1978 deletions

View File

@ -104,6 +104,7 @@ else
fi
CFLAGS="$CFLAGS $NGX_CC_OPT"
NGX_TEST_LD_OPT="$NGX_LD_OPT"
if [ "$NGX_PLATFORM" != win32 ]; then

View File

@ -51,8 +51,6 @@ esac
#NGX_GCC_OPT="-Os"
NGX_GCC_OPT="-O"
CFLAGS="$CFLAGS $NGX_GCC_OPT"
#CFLAGS="$CFLAGS -fomit-frame-pointer"
case $CPU in

View File

@ -125,7 +125,7 @@ ngx_objext="obj"
ngx_binext=".exe"
ngx_long_start='@<<
'
'
ngx_long_end='<<'
ngx_long_regex_cont=' \
'

View File

@ -39,7 +39,7 @@ END
ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS $ngx_feature_inc_path \
-o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
-o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_TEST_LD_OPT $ngx_feature_libs"
ngx_feature_inc_path=

View File

@ -101,8 +101,12 @@ install: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \
cp conf/fastcgi_params \
'\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi_params.default'
test -f '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi.conf' \
|| cp conf/fastcgi.conf '\$(DESTDIR)$NGX_CONF_PREFIX'
cp conf/fastcgi.conf '\$(DESTDIR)$NGX_CONF_PREFIX/fastcgi.conf.default'
test -f '\$(DESTDIR)$NGX_CONF_PATH' \
|| cp conf/nginx.conf '\$(DESTDIR)$NGX_CONF_PREFIX'
|| cp conf/nginx.conf '\$(DESTDIR)$NGX_CONF_PATH'
cp conf/nginx.conf '\$(DESTDIR)$NGX_CONF_PREFIX/nginx.conf.default'
test -d '\$(DESTDIR)`dirname "$NGX_PID_PATH"`' \

View File

@ -4,15 +4,29 @@
if [ $USE_PCRE = YES -o $PCRE != NONE ]; then
. auto/lib/pcre/conf
else
if [ $USE_PCRE = DISABLED -a $HTTP_REWRITE = YES ]; then
cat << END
$0: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option or you have to enable the PCRE support.
END
exit 1
fi
fi
if [ $USE_OPENSSL = YES ]; then
. auto/lib/openssl/conf
fi
if [ $USE_MD5 = YES ]; then
if [ $OPENSSL != NONE -a $OPENSSL != NO ]; then
if [ $USE_OPENSSL = YES ]; then
have=NGX_HAVE_OPENSSL_MD5_H . auto/have
have=NGX_OPENSSL_MD5 . auto/have
MD5=YES
@ -26,7 +40,7 @@ fi
if [ $USE_SHA1 = YES ]; then
if [ $OPENSSL != NONE -a $OPENSSL != NO ]; then
if [ $USE_OPENSSL = YES ]; then
have=NGX_HAVE_OPENSSL_SHA1_H . auto/have
SHA1=YES
SHA1_LIB=OpenSSL
@ -53,6 +67,9 @@ if [ $USE_PERL = YES ]; then
. auto/lib/perl/conf
fi
if [ $HTTP_GEOIP = YES ]; then
. auto/lib/geoip/conf
fi
if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then
. auto/lib/google-perftools/conf
fi

78
auto/lib/geoip/conf Normal file
View File

@ -0,0 +1,78 @@
# Copyright (C) Igor Sysoev
ngx_feature="GeoIP library"
ngx_feature_name=
ngx_feature_run=no
ngx_feature_incs=
ngx_feature_path=
ngx_feature_libs="-lGeoIP"
ngx_feature_test="GeoIP_open(NULL, 0)"
. auto/feature
if [ $ngx_found = no ]; then
# FreeBSD port
ngx_feature="GeoIP library in /usr/local/"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lGeoIP"
else
ngx_feature_libs="-L/usr/local/lib -lGeoIP"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# NetBSD port
ngx_feature="GeoIP library in /usr/pkg/"
ngx_feature_path="/usr/pkg/include/"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lGeoIP"
else
ngx_feature_libs="-L/usr/pkg/lib -lGeoIP"
fi
. auto/feature
fi
if [ $ngx_found = no ]; then
# MacPorts
ngx_feature="GeoIP library in /opt/local/"
ngx_feature_path="/opt/local/include"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lGeoIP"
else
ngx_feature_libs="-L/opt/local/lib -lGeoIP"
fi
. auto/feature
fi
if [ $ngx_found = yes ]; then
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
else
cat << END
$0: error: the GeoIP module requires the GeoIP library.
You can either do not enable the module or install the library.
END
exit 1
fi

View File

@ -30,4 +30,15 @@ fi
if [ $ngx_found = yes ]; then
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
else
cat << END
$0: error: the Google perftool module requires the Google perftools
library. You can either do not enable the module or install the library.
END
exit 1
fi

View File

@ -94,6 +94,18 @@ else
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
MD5=YES
MD5_LIB=$ngx_md5_lib
else
cat << END
$0: error: the HTTP cache module requires md5 functions
from OpenSSL library. You can either disable the module by using
--without-http-cache option, or install the OpenSSL library into the system,
or build the OpenSSL library statically from the source with nginx by using
--with-http_ssl_module --with-openssl=<path> options.
END
exit 1
fi
fi

View File

@ -19,16 +19,18 @@ if [ $OPENSSL != NONE ]; then
# libeay32.lib requires gdi32.lib
CORE_LIBS="$CORE_LIBS gdi32.lib"
# OpenSSL 1.0.0 requires crypt32.lib
CORE_LIBS="$CORE_LIBS crypt32.lib"
;;
*)
have=NGX_OPENSSL . auto/have
have=NGX_SSL . auto/have
CORE_INCS="$CORE_INCS $OPENSSL/openssl/include"
CORE_DEPS="$CORE_DEPS $OPENSSL/openssl/include/openssl/ssl.h"
CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libssl.a"
CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libcrypto.a"
CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"
CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"
CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"
CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a"
CORE_LIBS="$CORE_LIBS $NGX_LIBDL"
;;
esac
@ -66,6 +68,17 @@ else
have=NGX_SSL . auto/have
CORE_LIBS="$CORE_LIBS $ngx_feature_libs $NGX_LIBDL"
OPENSSL=YES
else
cat << END
$0: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using --with-openssl=<path> option.
END
exit 1
fi
;;

View File

@ -2,11 +2,6 @@
# Copyright (C) Igor Sysoev
case $USE_THREADS in
NO) OPENSSL_OPT="$OPENSSL_OPT no-threads" ;;
*) OPENSSL_OPT="$OPENSSL_OPT threads" ;;
esac
case "$CC" in
cl)
@ -21,7 +16,7 @@ END
;;
cl | bcc32)
bcc32)
ngx_opt=`echo "-DOPENSSL=\"$OPENSSL\" -DOPENSSL_OPT=\"$OPENSSL_OPT\"" \
| sed -e "s/\//$ngx_regex_dirsep/g"`
@ -45,26 +40,24 @@ END
;;
*)
case $USE_THREADS in
NO) OPENSSL_OPT="$OPENSSL_OPT no-threads" ;;
*) OPENSSL_OPT="$OPENSSL_OPT threads" ;;
esac
case $OPENSSL in
/*)
ngx_prefix="$OPENSSL/openssl"
;;
*)
ngx_prefix="$PWD/$OPENSSL/openssl"
;;
/*) ngx_prefix="$OPENSSL/.openssl" ;;
*) ngx_prefix="$PWD/$OPENSSL/.openssl" ;;
esac
cat << END >> $NGX_MAKEFILE
$OPENSSL/openssl/include/openssl/ssl.h: $NGX_MAKEFILE
$OPENSSL/.openssl/include/openssl/ssl.h: $NGX_MAKEFILE
cd $OPENSSL \\
&& \$(MAKE) clean \\
&& ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\
&& \$(MAKE) \\
&& \$(MAKE) install
&& \$(MAKE) install LIBDIR=lib
END

View File

@ -5,8 +5,7 @@
all:
cd $(OPENSSL)
perl Configure BC-32 no-shared --prefix=openssl -DNO_SYS_TYPES_H \
$(OPENSSL_OPT)
perl Configure BC-32 no-shared --prefix=openssl $(OPENSSL_OPT)
ms\do_nasm

View File

@ -5,8 +5,7 @@
all:
cd $(OPENSSL)
perl Configure VC-WIN32 no-shared --prefix=openssl -DNO_SYS_TYPES_H \
$(OPENSSL_OPT)
perl Configure VC-WIN32 no-shared --prefix=openssl $(OPENSSL_OPT)
ms\do_ms

View File

@ -161,6 +161,18 @@ else
CORE_INCS="$CORE_INCS $ngx_feature_path"
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
PCRE=YES
else
cat << END
$0: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.
END
exit 1
fi
fi

View File

@ -57,6 +57,17 @@ else
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
ZLIB=YES
ngx_found=no
else
cat << END
$0: error: the HTTP gzip module requires the zlib library.
You can either disable the module by using --without-http_gzip_module
option, or install the zlib library into the system, or build the zlib library
statically from the source with nginx by using --with-zlib=<path> option.
END
exit 1
fi
fi

View File

@ -53,7 +53,7 @@ END
$ZLIB/libz.a: $NGX_MAKEFILE
cd $ZLIB \\
&& \$(MAKE) clean \\
&& \$(MAKE) distclean \\
&& cp contrib/asm586/match.S . \\
&& CFLAGS="$ZLIB_OPT -DASMV" CC="\$(CC)" \\
./configure \\
@ -70,7 +70,7 @@ END
$ZLIB/libz.a: $NGX_MAKEFILE
cd $ZLIB \\
&& \$(MAKE) clean \\
&& \$(MAKE) distclean \\
&& cp contrib/asm686/match.S . \\
&& CFLAGS="$ZLIB_OPT -DASMV" CC="\$(CC)" \\
./configure \\
@ -103,7 +103,7 @@ if [ $done = NO ]; then
$ZLIB/libz.a: $NGX_MAKEFILE
cd $ZLIB \\
&& \$(MAKE) clean \\
&& \$(MAKE) distclean \\
&& CFLAGS="$ZLIB_OPT" CC="\$(CC)" \\
./configure \\
&& \$(MAKE) libz.a

View File

@ -101,8 +101,8 @@ fi
# ngx_http_range_header_filter
# ngx_http_gzip_filter
# ngx_http_postpone_filter
# ngx_http_charset_filter
# ngx_http_ssi_filter
# ngx_http_charset_filter
# ngx_http_xslt_filter
# ngx_http_image_filter_filter
# ngx_http_sub_filter
@ -130,12 +130,6 @@ if [ $HTTP_POSTPONE = YES ]; then
HTTP_SRCS="$HTTP_SRCS $HTTP_POSTPONE_FILTER_SRCS"
fi
if [ $HTTP_CHARSET = YES ]; then
have=NGX_HTTP_CHARSET . auto/have
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_CHARSET_FILTER_MODULE"
HTTP_SRCS="$HTTP_SRCS $HTTP_CHARSET_SRCS"
fi
if [ $HTTP_SSI = YES ]; then
have=NGX_HTTP_SSI . auto/have
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SSI_FILTER_MODULE"
@ -143,6 +137,12 @@ if [ $HTTP_SSI = YES ]; then
HTTP_SRCS="$HTTP_SRCS $HTTP_SSI_SRCS"
fi
if [ $HTTP_CHARSET = YES ]; then
have=NGX_HTTP_CHARSET . auto/have
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_CHARSET_FILTER_MODULE"
HTTP_SRCS="$HTTP_SRCS $HTTP_CHARSET_SRCS"
fi
if [ $HTTP_XSLT = YES ]; then
USE_LIBXSLT=YES
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_XSLT_FILTER_MODULE"
@ -240,6 +240,12 @@ if [ $HTTP_GEO = YES ]; then
HTTP_SRCS="$HTTP_SRCS $HTTP_GEO_SRCS"
fi
if [ $HTTP_GEOIP = YES ]; then
have=NGX_HTTP_GEOIP . auto/have
HTTP_MODULES="$HTTP_MODULES $HTTP_GEOIP_MODULE"
HTTP_SRCS="$HTTP_SRCS $HTTP_GEOIP_SRCS"
fi
if [ $HTTP_MAP = YES ]; then
have=NGX_HTTP_MAP . auto/have
HTTP_MODULES="$HTTP_MODULES $HTTP_MAP_MODULE"

View File

@ -71,6 +71,7 @@ HTTP_AUTOINDEX=YES
HTTP_RANDOM_INDEX=NO
HTTP_STATUS=NO
HTTP_GEO=YES
HTTP_GEOIP=NO
HTTP_MAP=YES
HTTP_REFERER=YES
HTTP_REWRITE=YES
@ -184,6 +185,7 @@ do
--with-http_addition_module) HTTP_ADDITION=YES ;;
--with-http_xslt_module) HTTP_XSLT=YES ;;
--with-http_image_filter_module) HTTP_IMAGE_FILTER=YES ;;
--with-http_geoip_module) HTTP_GEOIP=YES ;;
--with-http_sub_module) HTTP_SUB=YES ;;
--with-http_dav_module) HTTP_DAV=YES ;;
--with-http_flv_module) HTTP_FLV=YES ;;
@ -310,6 +312,7 @@ cat << END
--with-http_addition_module enable ngx_http_addition_module
--with-http_xslt_module enable ngx_http_xslt_module
--with-http_image_filter_module enable ngx_http_image_filter_module
--with-http_geoip_module enable ngx_http_geoip_module
--with-http_sub_module enable ngx_http_sub_module
--with-http_dav_module enable ngx_http_dav_module
--with-http_flv_module enable ngx_http_flv_module

View File

@ -252,3 +252,25 @@ if [ $ngx_found != yes ]; then
NGX_LIBDL="-ldl"
fi
fi
ngx_feature="sched_yield()"
ngx_feature_name="NGX_HAVE_SCHED_YIELD"
ngx_feature_run=no
ngx_feature_incs="#include <sched.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="sched_yield()"
. auto/feature
if [ $ngx_found != yes ]; then
ngx_feature="sched_yield() in librt"
ngx_feature_libs="-lrt"
. auto/feature
if [ $ngx_found = yes ]; then
CORE_LIBS="$CORE_LIBS -lrt"
fi
fi

View File

@ -18,7 +18,7 @@ CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
# Linux kernel version
version=$((`uname -r \
| sed 's/^\([^.]*\)\.\([^.]*\)\.\([^.-]*\).*/\1*256*256+\2*256+\3/'`))
| sed 's/^\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\1*256*256+\2*256+\3/'`))
version=${version:-0}

View File

@ -377,6 +377,10 @@ HTTP_GEO_MODULE=ngx_http_geo_module
HTTP_GEO_SRCS=src/http/modules/ngx_http_geo_module.c
HTTP_GEOIP_MODULE=ngx_http_geoip_module
HTTP_GEOIP_SRCS=src/http/modules/ngx_http_geoip_module.c
HTTP_MAP_MODULE=ngx_http_map_module
HTTP_MAP_SRCS=src/http/modules/ngx_http_map_module.c

View File

@ -74,65 +74,6 @@ esac
echo
if [ $HTTP_REWRITE = YES ]; then
if [ $USE_PCRE = DISABLED ]; then
cat << END
$0: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option or you have to enable the PCRE support.
END
exit 1
fi
if [ $PCRE = NONE -o $PCRE = NO ]; then
cat << END
$0: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.
END
exit 1
fi
fi
if [ $HTTP_GZIP = YES ]; then
if [ $ZLIB = NONE -o $ZLIB = NO ]; then
cat << END
$0: error: the HTTP gzip module requires the zlib library.
You can either disable the module by using --without-http_gzip_module
option, or install the zlib library into the system, or build the zlib library
statically from the source with nginx by using --with-zlib=<path> option.
END
exit 1
fi
fi
if [ $HTTP_SSL = YES ]; then
if [ $OPENSSL = NONE -o $OPENSSL = NO ]; then
cat << END
$0: error: the HTTP SSL module requires the OpenSSL library.
You can either do not enable the module, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using --with-openssl=<path> option.
END
exit 1
fi
fi
cat << END
nginx path prefix: "$NGX_PREFIX"
nginx binary file: "$NGX_SBIN_PATH"

View File

@ -133,6 +133,16 @@ ngx_feature_test="char buf[1024]; long n; n = strerror_r(1, buf, 1024);
. auto/feature
ngx_feature="sys_errlist[]"
ngx_feature_name="NGX_HAVE_SYS_ERRLIST"
ngx_feature_run=yes
ngx_feature_incs="#include <stdio.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="int n = sys_nerr; const char *p = sys_errlist[1];"
. auto/feature
ngx_feature="localtime_r()"
ngx_feature_name="NGX_HAVE_LOCALTIME_R"
ngx_feature_run=no
@ -163,28 +173,6 @@ ngx_feature_test="void *p; p = memalign(4096, 4096)"
. auto/feature
ngx_feature="sched_yield()"
ngx_feature_name="NGX_HAVE_SCHED_YIELD"
ngx_feature_run=no
ngx_feature_incs="#include <sched.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="sched_yield()"
. auto/feature
if [ $ngx_found != yes ]; then
ngx_feature="sched_yield() in librt"
ngx_feature_libs="-lrt"
. auto/feature
if [ $ngx_found = yes ]; then
CORE_LIBS="$CORE_LIBS -lrt"
fi
fi
ngx_feature="mmap(MAP_ANON|MAP_SHARED)"
ngx_feature_name="NGX_HAVE_MAP_ANON"
ngx_feature_run=yes

24
conf/fastcgi.conf Normal file
View File

@ -0,0 +1,24 @@
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2009 Igor Sysoev
* Copyright (C) 2002-2010 Igor Sysoev
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ NGINX = nginx-$(VER)
TEMP = tmp
OBJS = objs.msvc8
OPENSSL = openssl-0.9.8k
OPENSSL = openssl-0.9.8r
ZLIB = zlib-1.2.3
PCRE = pcre-7.9

View File

@ -238,6 +238,13 @@ main(int argc, char *const *argv)
if (ngx_show_configure) {
#ifdef NGX_COMPILER
ngx_log_stderr(0, "built by " NGX_COMPILER);
#endif
#if (NGX_SSL)
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
ngx_log_stderr(0, "TLS SNI support enabled");
#else
ngx_log_stderr(0, "TLS SNI support disabled");
#endif
#endif
ngx_log_stderr(0, "configure arguments:" NGX_CONFIGURE);
}
@ -330,6 +337,10 @@ main(int argc, char *const *argv)
return 0;
}
if (ngx_signal) {
return ngx_signal_process(cycle, ngx_signal);
}
ngx_os_status(cycle->log);
ngx_cycle = cycle;
@ -340,10 +351,6 @@ main(int argc, char *const *argv)
ngx_process = NGX_PROCESS_MASTER;
}
if (ngx_signal) {
return ngx_signal_process(cycle, ngx_signal);
}
#if !(NGX_WIN32)
if (ngx_init_signals(cycle->log) != NGX_OK) {
@ -373,6 +380,13 @@ main(int argc, char *const *argv)
}
}
if (log->file->fd != ngx_stderr) {
if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
ngx_close_file_n " built-in log failed");
}
}
ngx_use_stderr = 0;
if (ngx_process == NGX_PROCESS_SINGLE) {

View File

@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
#define nginx_version 7059
#define NGINX_VERSION "0.7.59"
#define nginx_version 7069
#define NGINX_VERSION "0.7.69"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"

View File

@ -75,13 +75,13 @@ typedef struct {
ngx_chain_t *free;
ngx_chain_t *busy;
unsigned sendfile;
unsigned directio;
unsigned sendfile:1;
unsigned directio:1;
#if (NGX_HAVE_ALIGNED_DIRECTIO)
unsigned unaligned;
unsigned unaligned:1;
#endif
unsigned need_in_memory;
unsigned need_in_temp;
unsigned need_in_memory:1;
unsigned need_in_temp:1;
ngx_pool_t *pool;
ngx_int_t allocated;

View File

@ -12,6 +12,7 @@
static ngx_int_t ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last);
static ngx_int_t ngx_conf_read_token(ngx_conf_t *cf);
static char *ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static ngx_int_t ngx_conf_test_full_name(ngx_str_t *name);
static void ngx_conf_flush_files(ngx_cycle_t *cycle);
@ -802,29 +803,15 @@ ngx_int_t
ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix)
{
size_t len;
u_char *p, *prefix;
ngx_str_t old;
u_char *p, *n, *prefix;
ngx_int_t rc;
#if (NGX_WIN32)
rc = ngx_conf_test_full_name(name);
if (name->len > 2
&& name->data[1] == ':'
&& ((name->data[0] >= 'a' && name->data[0] <= 'z')
|| (name->data[0] >= 'A' && name->data[0] <= 'Z')))
{
return NGX_OK;
if (rc == NGX_OK) {
return rc;
}
#else
if (name->data[0] == '/') {
return NGX_OK;
}
#endif
old = *name;
if (conf_prefix) {
len = cycle->conf_prefix.len;
prefix = cycle->conf_prefix.data;
@ -834,19 +821,79 @@ ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix)
prefix = cycle->prefix.data;
}
name->len = len + old.len;
name->data = ngx_pnalloc(cycle->pool, name->len + 1);
if (name->data == NULL) {
#if (NGX_WIN32)
if (rc == 2) {
len = rc;
}
#endif
n = ngx_pnalloc(cycle->pool, len + name->len + 1);
if (n == NULL) {
return NGX_ERROR;
}
p = ngx_cpymem(name->data, prefix, len);
ngx_cpystrn(p, old.data, old.len + 1);
p = ngx_cpymem(n, prefix, len);
ngx_cpystrn(p, name->data, name->len + 1);
name->len += len;
name->data = n;
return NGX_OK;
}
static ngx_int_t
ngx_conf_test_full_name(ngx_str_t *name)
{
#if (NGX_WIN32)
u_char c0, c1;
c0 = name->data[0];
if (name->len < 2) {
if (c0 == '/') {
return 2;
}
return NGX_DECLINED;
}
c1 = name->data[1];
if (c1 == ':') {
c0 |= 0x20;
if ((c0 >= 'a' && c0 <= 'z')) {
return NGX_OK;
}
return NGX_DECLINED;
}
if (c1 == '/') {
return NGX_OK;
}
if (c0 == '/') {
return 2;
}
return NGX_DECLINED;
#else
if (name->data[0] == '/') {
return NGX_OK;
}
return NGX_DECLINED;
#endif
}
ngx_open_file_t *
ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name)
{

View File

@ -603,6 +603,8 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle)
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
ngx_close_socket_n " %V failed", &ls[i].addr_text);
}
ls[i].fd = (ngx_socket_t) -1;
}
}
@ -915,12 +917,8 @@ ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
level = NGX_LOG_INFO;
break;
case NGX_ERROR_ERR:
level = NGX_LOG_ERR;
break;
default:
level = NGX_LOG_ALERT;
level = NGX_LOG_ERR;
}
} else {

View File

@ -135,6 +135,8 @@ struct ngx_connection_s {
ngx_atomic_uint_t number;
ngx_uint_t requests;
unsigned buffered:8;
unsigned log_error:3; /* ngx_connection_log_error_e */

View File

@ -63,7 +63,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
tp = ngx_timeofday();
tp->sec = 0;
ngx_time_update(0, 0);
ngx_time_update();
log = old_cycle->log;
@ -216,7 +216,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
if (module->create_conf) {
rv = module->create_conf(cycle);
if (rv == NGX_CONF_ERROR) {
if (rv == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
@ -255,11 +255,13 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
#endif
if (ngx_conf_param(&conf) != NGX_CONF_OK) {
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
@ -269,7 +271,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
cycle->conf_file.data);
}
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_CORE_MODULE) {
continue;
@ -281,12 +282,16 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index])
== NGX_CONF_ERROR)
{
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
}
}
if (ngx_process == NGX_PROCESS_SIGNALLER) {
return cycle;
}
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
@ -463,11 +468,8 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
goto failed;
}
if (!shm_zone[i].shm.exists) {
if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) {
goto failed;
}
if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) {
goto failed;
}
if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) {
@ -567,14 +569,12 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
}
}
if (ngx_process != NGX_PROCESS_SIGNALLER) {
if (ngx_open_listening_sockets(cycle) != NGX_OK) {
goto failed;
}
if (ngx_open_listening_sockets(cycle) != NGX_OK) {
goto failed;
}
if (!ngx_test_config) {
ngx_configure_listening_sockets(cycle);
}
if (!ngx_test_config) {
ngx_configure_listening_sockets(cycle);
}
@ -656,7 +656,8 @@ old_shm_zone_done:
ls = old_cycle->listening.elts;
for (i = 0; i < old_cycle->listening.nelts; i++) {
if (ls[i].remain) {
if (ls[i].remain || ls[i].fd == -1) {
continue;
}
@ -700,8 +701,8 @@ old_shm_zone_done:
if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) {
/*
* perl_destruct() frees environ if it is not the same as it was at
* perl_construct() time. So we have saved an previous cycle
* perl_destruct() frees environ, if it is not the same as it was at
* perl_construct() time, therefore we save the previous cycle
* environment before ngx_conf_parse() where it will be changed.
*/
@ -846,7 +847,7 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2)
sin61 = (struct sockaddr_in6 *) sa1;
sin62 = (struct sockaddr_in6 *) sa2;
if (sin61->sin6_port != sin61->sin6_port) {
if (sin61->sin6_port != sin62->sin6_port) {
return NGX_DECLINED;
}
@ -885,8 +886,21 @@ ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *zn)
sp = (ngx_slab_pool_t *) zn->shm.addr;
if (zn->shm.exists) {
if (sp == sp->addr) {
return NGX_OK;
}
ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
"shared zone \"%V\" has no equal addresses: %p vs %p",
&zn->shm.name, sp->addr, sp);
return NGX_ERROR;
}
sp->end = zn->shm.addr + zn->shm.size;
sp->min_shift = 3;
sp->addr = zn->shm.addr;
#if (NGX_HAVE_ATOMIC_OPS)

View File

@ -8,8 +8,9 @@
#include <ngx_core.h>
static ngx_atomic_uint_t ngx_temp_number;
static ngx_atomic_uint_t ngx_random_number;
static ngx_atomic_t temp_number = 0;
ngx_atomic_t *ngx_temp_number = &temp_number;
ngx_atomic_int_t ngx_random_number = 123456;
ssize_t
@ -99,13 +100,7 @@ ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool,
continue;
}
if ((path->level[0] == 0)
|| (err != NGX_ENOENT
#if (NGX_WIN32)
&& err != NGX_ENOTDIR
#endif
))
{
if ((path->level[0] == 0) || (err != NGX_ENOPATH)) {
ngx_log_error(NGX_LOG_CRIT, file->log, err,
ngx_open_tempfile_n " \"%s\" failed",
file->name.data);
@ -188,7 +183,15 @@ ngx_create_full_path(u_char *dir, ngx_uint_t access)
u_char *p, ch;
ngx_err_t err;
for (p = dir + 1; *p; p++) {
err = 0;
#if (NGX_WIN32)
p = dir + 3;
#else
p = dir + 1;
#endif
for ( /* void */ ; *p; p++) {
ch = *p;
if (ch != '/') {
@ -199,7 +202,14 @@ ngx_create_full_path(u_char *dir, ngx_uint_t access)
if (ngx_create_dir(dir, access) == NGX_FILE_ERROR) {
err = ngx_errno;
if (err != NGX_EEXIST) {
switch (err) {
case NGX_EEXIST:
err = 0;
case NGX_EACCES:
break;
default:
return err;
}
}
@ -207,26 +217,20 @@ ngx_create_full_path(u_char *dir, ngx_uint_t access)
*p = '/';
}
return 0;
}
void
ngx_init_temp_number(void)
{
ngx_temp_number = 0;
ngx_random_number = 123456;
return err;
}
ngx_atomic_uint_t
ngx_next_temp_number(ngx_uint_t collision)
{
if (collision) {
ngx_temp_number += ngx_random_number;
}
ngx_atomic_uint_t n, add;
return ngx_temp_number++;
add = collision ? ngx_random_number : 1;
n = ngx_atomic_fetch_add(ngx_temp_number, add);
return n + add;
}
@ -264,7 +268,8 @@ ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
path->len = 0;
path->manager = (ngx_path_manager_pt) cmd->post;
path->manager = NULL;
path->loader = NULL;
path->conf_file = cf->conf_file->file.name.data;
path->line = cf->conf_file->line;
@ -325,6 +330,7 @@ ngx_conf_merge_path_value(ngx_conf_t *cf, ngx_path_t **path, ngx_path_t *prev,
+ init->level[2] + (init->level[2] ? 1 : 0);
(*path)->manager = NULL;
(*path)->loader = NULL;
(*path)->conf_file = NULL;
if (ngx_add_path(cf, path) != NGX_OK) {
@ -528,7 +534,9 @@ ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user)
ngx_int_t
ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext)
{
ngx_err_t err;
u_char *name;
ngx_err_t err;
ngx_copy_file_t cf;
#if !(NGX_WIN32)
@ -558,7 +566,7 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext)
err = ngx_errno;
if (err == NGX_ENOENT) {
if (err == NGX_ENOPATH) {
if (!ext->create_path) {
goto failed;
@ -578,27 +586,67 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext)
}
err = ngx_errno;
goto failed;
}
#if (NGX_WIN32)
if (err == NGX_EEXIST) {
if (ngx_win32_rename_file(src, to, ext->log) == NGX_OK) {
err = ngx_win32_rename_file(src, to, ext->log);
if (ngx_rename_file(src->data, to->data) != NGX_FILE_ERROR) {
return NGX_OK;
}
err = ngx_errno;
} else {
err = 0;
if (err == 0) {
return NGX_OK;
}
}
#endif
if (err == NGX_EXDEV) {
cf.size = -1;
cf.buf_size = 0;
cf.access = ext->access;
cf.time = ext->time;
cf.log = ext->log;
name = ngx_alloc(to->len + 1 + 10 + 1, ext->log);
if (name == NULL) {
return NGX_ERROR;
}
(void) ngx_sprintf(name, "%*s.%010uD%Z", to->len, to->data,
(uint32_t) ngx_next_temp_number(0));
if (ngx_copy_file(src->data, name, &cf) == NGX_OK) {
if (ngx_rename_file(name, to->data) != NGX_FILE_ERROR) {
ngx_free(name);
if (ngx_delete_file(src->data) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,
ngx_delete_file_n " \"%s\" failed",
src->data);
return NGX_ERROR;
}
return NGX_OK;
}
ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,
ngx_rename_file_n " \"%s\" to \"%s\" failed",
name, to->data);
if (ngx_delete_file(name) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,
ngx_delete_file_n " \"%s\" failed", name);
}
}
ngx_free(name);
err = 0;
}
failed:
if (ext->delete_file) {
@ -608,18 +656,146 @@ failed:
}
}
if (err && ext->log_rename_error) {
if (err) {
ngx_log_error(NGX_LOG_CRIT, ext->log, err,
ngx_rename_file_n " \"%s\" to \"%s\" failed",
src->data, to->data);
}
ext->rename_error = err;
return NGX_ERROR;
}
ngx_int_t
ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
{
char *buf;
off_t size;
size_t len;
ssize_t n;
ngx_fd_t fd, nfd;
ngx_int_t rc;
ngx_file_info_t fi;
rc = NGX_ERROR;
buf = NULL;
nfd = NGX_INVALID_FILE;
fd = ngx_open_file(from, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
if (fd == NGX_INVALID_FILE) {
ngx_log_error(NGX_LOG_CRIT, cf->log, ngx_errno,
ngx_open_file_n " \"%s\" failed", from);
goto failed;
}
if (cf->size != -1) {
size = cf->size;
} else {
if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
ngx_fd_info_n " \"%s\" failed", from);
goto failed;
}
size = ngx_file_size(&fi);
}
len = cf->buf_size ? cf->buf_size : 65536;
if ((off_t) len > size) {
len = (size_t) size;
}
buf = ngx_alloc(len, cf->log);
if (buf == NULL) {
goto failed;
}
nfd = ngx_open_file(to, NGX_FILE_WRONLY, NGX_FILE_CREATE_OR_OPEN,
cf->access);
if (nfd == NGX_INVALID_FILE) {
ngx_log_error(NGX_LOG_CRIT, cf->log, ngx_errno,
ngx_open_file_n " \"%s\" failed", to);
goto failed;
}
while (size > 0) {
if ((off_t) len > size) {
len = (size_t) size;
}
n = ngx_read_fd(fd, buf, len);
if (n == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
ngx_read_fd_n " \"%s\" failed", from);
goto failed;
}
if ((size_t) n != len) {
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
ngx_read_fd_n " has read only %z of %uz from %s",
n, size, from);
goto failed;
}
n = ngx_write_fd(nfd, buf, len);
if (n == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
ngx_write_fd_n " \"%s\" failed", to);
goto failed;
}
if ((size_t) n != len) {
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
ngx_write_fd_n " has written only %z of %uz to %s",
n, size, to);
goto failed;
}
size -= n;
}
if (cf->time != -1) {
if (ngx_set_file_time(to, nfd, cf->time) != NGX_OK) {
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
ngx_set_file_time_n " \"%s\" failed", to);
goto failed;
}
}
rc = NGX_OK;
failed:
if (nfd != NGX_INVALID_FILE) {
if (ngx_close_file(nfd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
ngx_close_file_n " \"%s\" failed", to);
}
}
if (fd != NGX_INVALID_FILE) {
if (ngx_close_file(fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
ngx_close_file_n " \"%s\" failed", from);
}
}
if (buf) {
ngx_free(buf);
}
return rc;
}
/*
* ctx->init_handler() - see ctx->alloc
* ctx->file_handler() - file handler

View File

@ -30,6 +30,7 @@ struct ngx_file_s {
typedef time_t (*ngx_path_manager_pt) (void *data);
typedef void (*ngx_path_loader_pt) (void *data);
typedef struct {
@ -38,6 +39,7 @@ typedef struct {
size_t level[3];
ngx_path_manager_pt manager;
ngx_path_loader_pt loader;
void *data;
u_char *conf_file;
@ -71,16 +73,25 @@ typedef struct {
ngx_uint_t path_access;
time_t time;
ngx_fd_t fd;
ngx_err_t rename_error;
unsigned create_path:1;
unsigned delete_file:1;
unsigned log_rename_error:1;
ngx_log_t *log;
} ngx_ext_rename_file_t;
typedef struct {
off_t size;
size_t buf_size;
ngx_uint_t access;
time_t time;
ngx_log_t *log;
} ngx_copy_file_t;
typedef struct ngx_tree_ctx_s ngx_tree_ctx_t;
typedef ngx_int_t (*ngx_tree_init_handler_pt) (void *ctx, void *prev);
@ -115,9 +126,9 @@ ngx_int_t ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot);
ngx_int_t ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user);
ngx_int_t ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to,
ngx_ext_rename_file_t *ext);
ngx_int_t ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf);
ngx_int_t ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t *tree);
void ngx_init_temp_number(void);
ngx_atomic_uint_t ngx_next_temp_number(ngx_uint_t collision);
char *ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
@ -126,4 +137,8 @@ char *ngx_conf_merge_path_value(ngx_conf_t *cf, ngx_path_t **path,
char *ngx_conf_set_access_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
extern ngx_atomic_t *ngx_temp_number;
extern ngx_atomic_int_t ngx_random_number;
#endif /* _NGX_FILE_H_INCLUDED_ */

View File

@ -534,7 +534,7 @@ ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
next_name->key.len = names[n].key.len - len;
next_name->key.data = names[n].key.data + len;
next_name->key_hash= 0;
next_name->key_hash = 0;
next_name->value = names[n].value;
#if 0
@ -562,7 +562,7 @@ ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
next_name->key.len = names[i].key.len - dot_len;
next_name->key.data = names[i].key.data + dot_len;
next_name->key_hash= 0;
next_name->key_hash = 0;
next_name->value = names[i].value;
#if 0

View File

@ -360,6 +360,7 @@ create:
file->uses = 1;
file->count = 0;
file->use_event = 0;
file->event = NULL;
add_event:
@ -486,7 +487,14 @@ ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log)
}
if (!of->log) {
fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
/*
* Use non-blocking open() not to hang on FIFO files, etc.
* This flag has no effect on a regular files.
*/
fd = ngx_open_file(name, NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
NGX_FILE_OPEN, 0);
} else {
fd = ngx_open_file(name, NGX_FILE_APPEND, NGX_FILE_CREATE_OR_OPEN,
@ -524,7 +532,7 @@ ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log)
of->fd = fd;
if (of->directio <= ngx_file_size(&fi)) {
if (ngx_directio_on(fd) == -1) {
if (ngx_directio_on(fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
ngx_directio_on_n " \"%s\" failed", name);

View File

@ -314,12 +314,11 @@ ngx_output_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain,
#endif
cl->next = NULL;
*ll = cl;
ll = &cl->next;
}
*ll = NULL;
return NGX_OK;
}
@ -503,6 +502,7 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
if (src->pos == src->last) {
dst->flush = src->flush;
dst->last_buf = src->last_buf;
dst->last_in_chain = src->last_in_chain;
}
} else {
@ -510,7 +510,7 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
#if (NGX_HAVE_ALIGNED_DIRECTIO)
if (ctx->unaligned) {
if (ngx_directio_off(src->file->fd) == -1) {
if (ngx_directio_off(src->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno,
ngx_directio_off_n " \"%s\" failed",
src->file->name.data);
@ -528,7 +528,7 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
err = ngx_errno;
if (ngx_directio_on(src->file->fd) == -1) {
if (ngx_directio_on(src->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno,
ngx_directio_on_n " \"%s\" failed",
src->file->name.data);
@ -555,9 +555,7 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
ngx_read_file_n " read only %z of %O from \"%s\"",
n, size, src->file->name.data);
if (n == 0) {
return NGX_ERROR;
}
return NGX_ERROR;
}
dst->last += n;
@ -577,6 +575,7 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
if (src->file_pos == src->file_last) {
dst->flush = src->flush;
dst->last_buf = src->last_buf;
dst->last_in_chain = src->last_in_chain;
}
}

View File

@ -25,6 +25,7 @@ ngx_create_pool(size_t size, ngx_log_t *log)
p->d.last = (u_char *) p + sizeof(ngx_pool_t);
p->d.end = (u_char *) p + size;
p->d.next = NULL;
p->d.failed = 0;
size = size - sizeof(ngx_pool_t);
p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
@ -189,6 +190,7 @@ ngx_palloc_block(ngx_pool_t *pool, size_t size)
new->d.end = m + psize;
new->d.next = NULL;
new->d.failed = 0;
m += sizeof(ngx_pool_data_t);
m = ngx_align_ptr(m, NGX_ALIGNMENT);
@ -197,7 +199,7 @@ ngx_palloc_block(ngx_pool_t *pool, size_t size)
current = pool->current;
for (p = current; p->d.next; p = p->d.next) {
if ((size_t) (p->d.end - p->d.last) < NGX_ALIGNMENT) {
if (p->d.failed++ > 4) {
current = p->d.next;
}
}
@ -214,6 +216,7 @@ static void *
ngx_palloc_large(ngx_pool_t *pool, size_t size)
{
void *p;
ngx_uint_t n;
ngx_pool_large_t *large;
p = ngx_alloc(size, pool->log);
@ -221,6 +224,19 @@ ngx_palloc_large(ngx_pool_t *pool, size_t size)
return NULL;
}
n = 0;
for (large = pool->large; large; large = large->next) {
if (large->alloc == NULL) {
large->alloc = p;
return p;
}
if (n++ > 3) {
break;
}
}
large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
if (large == NULL) {
ngx_free(p);

View File

@ -46,6 +46,7 @@ typedef struct {
u_char *last;
u_char *end;
ngx_pool_t *next;
ngx_uint_t failed;
} ngx_pool_data_t;

View File

@ -464,6 +464,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
ctx->next = rn->waiting;
rn->waiting = ctx;
ctx->state = NGX_AGAIN;
return NGX_AGAIN;
}
@ -625,6 +626,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
ctx->next = rn->waiting;
rn->waiting = ctx;
ctx->state = NGX_AGAIN;
/* unlock addr mutex */
@ -1149,6 +1151,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
goto failed;
}
ngx_resolver_free(r, name.data);
if (code == 0 && nan == 0) {
code = 3; /* NXDOMAIN */
}
@ -1400,6 +1404,8 @@ failed:
/* unlock name mutex */
ngx_resolver_free(r, name.data);
return;
}
@ -1595,7 +1601,6 @@ static ngx_resolver_node_t *
ngx_resolver_lookup_name(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash)
{
ngx_int_t rc;
size_t len;
ngx_rbtree_node_t *node, *sentinel;
ngx_resolver_node_t *rn;
@ -1619,9 +1624,7 @@ ngx_resolver_lookup_name(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash)
do {
rn = (ngx_resolver_node_t *) node;
len = (name->len > (size_t) rn->nlen) ? rn->nlen : name->len;
rc = ngx_strncmp(name->data, rn->name, len);
rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
if (rc == 0) {
return rn;
@ -1675,7 +1678,6 @@ static void
ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp,
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
{
size_t len;
ngx_rbtree_node_t **p;
ngx_resolver_node_t *rn, *rn_temp;
@ -1694,10 +1696,8 @@ ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp,
rn = (ngx_resolver_node_t *) node;
rn_temp = (ngx_resolver_node_t *) temp;
len = (rn->nlen > rn_temp->nlen) ? rn_temp->nlen : rn->nlen;
p = (ngx_strncmp(rn->name, rn_temp->name, len) < 0)
? &temp->left : &temp->right;
p = (ngx_memn2cmp(rn->name, rn_temp->name, rn->nlen, rn_temp->nlen)
< 0) ? &temp->left : &temp->right;
}
if (*p == sentinel) {
@ -1719,15 +1719,16 @@ static ngx_int_t
ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
{
u_char *p, *s;
size_t len;
size_t len, nlen;
ngx_uint_t ident;
ngx_resolver_qs_t *qs;
ngx_resolver_query_t *query;
len = sizeof(ngx_resolver_query_t)
+ 1 + ctx->name.len + 1 + sizeof(ngx_resolver_qs_t);
nlen = ctx->name.len ? (1 + ctx->name.len + 1) : 1;
p = ngx_resolver_calloc(ctx->resolver, len);
len = sizeof(ngx_resolver_query_t) + nlen + sizeof(ngx_resolver_qs_t);
p = ngx_resolver_alloc(ctx->resolver, len);
if (p == NULL) {
return NGX_ERROR;
}
@ -1754,7 +1755,7 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
query->nns_hi = 0; query->nns_lo = 0;
query->nar_hi = 0; query->nar_lo = 0;
p += sizeof(ngx_resolver_query_t) + 1 + ctx->name.len + 1;
p += sizeof(ngx_resolver_query_t) + nlen;
qs = (ngx_resolver_qs_t *) p;
@ -1808,7 +1809,7 @@ ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
+ sizeof(".255.255.255.255.in-addr.arpa.") - 1
+ sizeof(ngx_resolver_qs_t);
p = ngx_resolver_calloc(ctx->resolver, len);
p = ngx_resolver_alloc(ctx->resolver, len);
if (p == NULL) {
return NGX_ERROR;
}
@ -1902,6 +1903,12 @@ done:
return NGX_OK;
}
if (len == -1) {
name->len = 0;
name->data = NULL;
return NGX_OK;
}
dst = ngx_resolver_alloc(r, len);
if (dst == NULL) {
return NGX_ERROR;

View File

@ -39,6 +39,7 @@ typedef struct {
u_char zero;
void *data;
void *addr;
} ngx_slab_pool_t;

View File

@ -30,12 +30,15 @@ ngx_cpystrn(u_char *dst, u_char *src, size_t n)
return dst;
}
for ( /* void */ ; --n; dst++, src++) {
while (--n) {
*dst = *src;
if (*dst == '\0') {
return dst;
}
dst++;
src++;
}
*dst = '\0';
@ -87,7 +90,7 @@ ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src)
*
* reserved:
* %t ptrdiff_t
* %S null-teminated wchar string
* %S null-terminated wchar string
* %C wchar
*/
@ -565,8 +568,8 @@ ngx_strcasecmp(u_char *s1, u_char *s2)
c1 = (ngx_uint_t) *s1++;
c2 = (ngx_uint_t) *s2++;
c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
if (c1 == c2) {
@ -591,8 +594,8 @@ ngx_strncasecmp(u_char *s1, u_char *s2, size_t n)
c1 = (ngx_uint_t) *s1++;
c2 = (ngx_uint_t) *s2++;
c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
if (c1 == c2) {
@ -680,7 +683,7 @@ ngx_strcasestrn(u_char *s1, char *s2, size_t n)
ngx_uint_t c1, c2;
c2 = (ngx_uint_t) *s2++;
c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
do {
do {
@ -690,7 +693,7 @@ ngx_strcasestrn(u_char *s1, char *s2, size_t n)
return NULL;
}
c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
} while (c1 != c2);
@ -712,7 +715,7 @@ ngx_strlcasestrn(u_char *s1, u_char *last, u_char *s2, size_t n)
ngx_uint_t c1, c2;
c2 = (ngx_uint_t) *s2++;
c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
last -= n;
do {
@ -723,7 +726,7 @@ ngx_strlcasestrn(u_char *s1, u_char *last, u_char *s2, size_t n)
c1 = (ngx_uint_t) *s1++;
c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
} while (c1 != c2);
@ -816,6 +819,37 @@ ngx_memn2cmp(u_char *s1, u_char *s2, size_t n1, size_t n2)
}
ngx_int_t
ngx_dns_strcmp(u_char *s1, u_char *s2)
{
ngx_uint_t c1, c2;
for ( ;; ) {
c1 = (ngx_uint_t) *s1++;
c2 = (ngx_uint_t) *s2++;
c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
if (c1 == c2) {
if (c1) {
continue;
}
return 0;
}
/* in ASCII '.' > '-', but we need '.' to be the lowest character */
c1 = (c1 == '.') ? ' ' : c1;
c2 = (c2 == '.') ? ' ' : c2;
return c1 - c2;
}
}
ngx_int_t
ngx_atoi(u_char *line, size_t n)
{
@ -1204,10 +1238,8 @@ ngx_utf8_cpystrn(u_char *dst, u_char *src, size_t n, size_t len)
break;
}
len--;
while (src < next) {
*++dst = *++src;
*dst++ = *src++;
len--;
}
}
@ -1245,13 +1277,13 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
};
/* " ", "#", "%", "+", "?", %00-%1F, %7F-%FF */
/* " ", "#", "%", "&", "+", "?", %00-%1F, %7F-%FF */
static uint32_t args[] = {
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
0x80000829, /* 1000 0000 0000 0000 0000 1000 0010 1001 */
0x80000869, /* 1000 0000 0000 0000 0000 1000 0110 1001 */
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
@ -1337,7 +1369,7 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
/* find the number of the characters to be escaped */
n = 0;
n = 0;
for (i = 0; i < size; i++) {
if (escape[*src >> 5] & (1 << (*src & 0x1f))) {

View File

@ -158,6 +158,7 @@ u_char *ngx_strlcasestrn(u_char *s1, u_char *last, u_char *s2, size_t n);
ngx_int_t ngx_rstrncmp(u_char *s1, u_char *s2, size_t n);
ngx_int_t ngx_rstrncasecmp(u_char *s1, u_char *s2, size_t n);
ngx_int_t ngx_memn2cmp(u_char *s1, u_char *s2, size_t n1, size_t n2);
ngx_int_t ngx_dns_strcmp(u_char *s1, u_char *s2);
ngx_int_t ngx_atoi(u_char *line, size_t n);
ssize_t ngx_atosz(u_char *line, size_t n);

View File

@ -28,6 +28,17 @@ volatile ngx_str_t ngx_cached_err_log_time;
volatile ngx_str_t ngx_cached_http_time;
volatile ngx_str_t ngx_cached_http_log_time;
#if !(NGX_WIN32)
/*
* locatime() and localtime_r() are not Async-Signal-Safe functions, therefore,
* they must not be called by a signal handler, so we use the cached
* GMT offset value. Fortunately the value is changed only two times a year.
*/
static ngx_int_t cached_gmtoff;
#endif
static ngx_time_t cached_time[NGX_TIME_SLOTS];
static u_char cached_err_log_time[NGX_TIME_SLOTS]
[sizeof("1970/09/28 12:00:00")];
@ -50,15 +61,17 @@ ngx_time_init(void)
ngx_cached_time = &cached_time[0];
ngx_time_update(0, 0);
ngx_time_update();
}
void
ngx_time_update(time_t sec, ngx_uint_t msec)
ngx_time_update(void)
{
u_char *p0, *p1, *p2;
ngx_tm_t tm, gmt;
time_t sec;
ngx_uint_t msec;
ngx_time_t *tp;
struct timeval tv;
@ -66,12 +79,10 @@ ngx_time_update(time_t sec, ngx_uint_t msec)
return;
}
if (sec == 0) {
ngx_gettimeofday(&tv);
ngx_gettimeofday(&tv);
sec = tv.tv_sec;
msec = tv.tv_usec / 1000;
}
sec = tv.tv_sec;
msec = tv.tv_usec / 1000;
ngx_current_msec = (ngx_msec_t) sec * 1000 + msec;
@ -112,12 +123,14 @@ ngx_time_update(time_t sec, ngx_uint_t msec)
#elif (NGX_HAVE_GMTOFF)
ngx_localtime(sec, &tm);
tp->gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);
cached_gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);
tp->gmtoff = cached_gmtoff;
#else
ngx_localtime(sec, &tm);
tp->gmtoff = ngx_timezone(tm.ngx_tm_isdst);
cached_gmtoff = ngx_timezone(tm.ngx_tm_isdst);
tp->gmtoff = cached_gmtoff;
#endif
@ -151,6 +164,57 @@ ngx_time_update(time_t sec, ngx_uint_t msec)
}
#if !(NGX_WIN32)
void
ngx_time_sigsafe_update(void)
{
u_char *p;
ngx_tm_t tm;
time_t sec;
ngx_time_t *tp;
struct timeval tv;
if (!ngx_trylock(&ngx_time_lock)) {
return;
}
ngx_gettimeofday(&tv);
sec = tv.tv_sec;
tp = &cached_time[slot];
if (tp->sec == sec) {
ngx_unlock(&ngx_time_lock);
return;
}
if (slot == NGX_TIME_SLOTS - 1) {
slot = 0;
} else {
slot++;
}
ngx_gmtime(sec + cached_gmtoff * 60, &tm);
p = &cached_err_log_time[slot][0];
(void) ngx_sprintf(p, "%4d/%02d/%02d %02d:%02d:%02d",
tm.ngx_tm_year, tm.ngx_tm_mon,
tm.ngx_tm_mday, tm.ngx_tm_hour,
tm.ngx_tm_min, tm.ngx_tm_sec);
ngx_memory_barrier();
ngx_cached_err_log_time.data = p;
ngx_unlock(&ngx_time_lock);
}
#endif
u_char *
ngx_http_time(u_char *buf, time_t t)
{

View File

@ -20,7 +20,8 @@ typedef struct {
void ngx_time_init(void);
void ngx_time_update(time_t sec, ngx_uint_t msec);
void ngx_time_update(void);
void ngx_time_sigsafe_update(void);
u_char *ngx_http_time(u_char *buf, time_t t);
u_char *ngx_http_cookie_time(u_char *buf, time_t t);
void ngx_gmtime(time_t t, ngx_tm_t *tp);

View File

@ -375,8 +375,8 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
err = 0;
}
if (flags & NGX_UPDATE_TIME) {
ngx_time_update(0, 0);
if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
ngx_time_update();
}
if (err) {
@ -550,7 +550,7 @@ ngx_devpoll_create_conf(ngx_cycle_t *cycle)
dpcf = ngx_palloc(cycle->pool, sizeof(ngx_devpoll_conf_t));
if (dpcf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
dpcf->changes = NGX_CONF_UNSET;

View File

@ -407,8 +407,8 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
err = 0;
}
if (flags & NGX_UPDATE_TIME) {
ngx_time_update(0, 0);
if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
ngx_time_update();
}
if (err) {
@ -552,7 +552,7 @@ ngx_epoll_create_conf(ngx_cycle_t *cycle)
epcf = ngx_palloc(cycle->pool, sizeof(ngx_epoll_conf_t));
if (epcf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
epcf->events = NGX_CONF_UNSET;

View File

@ -405,7 +405,7 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
err = ngx_errno;
if (flags & NGX_UPDATE_TIME) {
ngx_time_update(0, 0);
ngx_time_update();
}
if (n == -1) {
@ -439,7 +439,7 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
for (i = 0; i < events; i++) {
if (event_list[i].portev_source == PORT_SOURCE_TIMER) {
ngx_time_update(0, 0);
ngx_time_update();
continue;
}
@ -581,7 +581,7 @@ ngx_eventport_create_conf(ngx_cycle_t *cycle)
epcf = ngx_palloc(cycle->pool, sizeof(ngx_eventport_conf_t));
if (epcf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
epcf->events = NGX_CONF_UNSET;

View File

@ -163,7 +163,7 @@ ngx_iocp_timer(void *data)
for ( ;; ) {
Sleep(timer);
ngx_time_update(0, 0);
ngx_time_update();
#if 1
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer");
#endif
@ -258,7 +258,7 @@ ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
delta = ngx_current_msec;
if (flags & NGX_UPDATE_TIME) {
ngx_time_update(0, 0);
ngx_time_update();
}
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0,

View File

@ -543,8 +543,8 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
err = 0;
}
if (flags & NGX_UPDATE_TIME) {
ngx_time_update(0, 0);
if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
ngx_time_update();
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
@ -595,7 +595,7 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
#if (NGX_HAVE_TIMER_EVENT)
if (event_list[i].filter == EVFILT_TIMER) {
ngx_time_update(0, 0);
ngx_time_update();
continue;
}
@ -768,7 +768,7 @@ ngx_kqueue_create_conf(ngx_cycle_t *cycle)
kcf = ngx_palloc(cycle->pool, sizeof(ngx_kqueue_conf_t));
if (kcf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
kcf->changes = NGX_CONF_UNSET;

View File

@ -266,8 +266,8 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
err = 0;
}
if (flags & NGX_UPDATE_TIME) {
ngx_time_update(0, 0);
if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
ngx_time_update();
}
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,

View File

@ -323,7 +323,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
"rtsig signo:%d", signo);
if (flags & NGX_UPDATE_TIME) {
ngx_time_update(0, 0);
ngx_time_update();
}
if (err == NGX_EAGAIN) {
@ -349,7 +349,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
signo, si.si_fd, si.si_band);
if (flags & NGX_UPDATE_TIME) {
ngx_time_update(0, 0);
ngx_time_update();
}
rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
@ -419,7 +419,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
} else if (signo == SIGALRM) {
ngx_time_update(0, 0);
ngx_time_update();
return NGX_OK;
@ -671,7 +671,7 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
}
if (flags & NGX_UPDATE_TIME) {
ngx_time_update(0, 0);
ngx_time_update();
}
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
@ -691,7 +691,7 @@ ngx_rtsig_create_conf(ngx_cycle_t *cycle)
rtscf = ngx_palloc(cycle->pool, sizeof(ngx_rtsig_conf_t));
if (rtscf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
rtscf->signo = NGX_CONF_UNSET;

View File

@ -266,8 +266,8 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
err = 0;
}
if (flags & NGX_UPDATE_TIME) {
ngx_time_update(0, 0);
if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
ngx_time_update();
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,

View File

@ -273,7 +273,7 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
}
if (flags & NGX_UPDATE_TIME) {
ngx_time_update(0, 0);
ngx_time_update();
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,

View File

@ -43,7 +43,7 @@ ngx_uint_t ngx_event_flags;
ngx_event_actions_t ngx_event_actions;
ngx_atomic_t connection_counter = 1;
static ngx_atomic_t connection_counter = 1;
ngx_atomic_t *ngx_connection_counter = &connection_counter;
@ -429,6 +429,7 @@ ngx_event_module_init(ngx_cycle_t *cycle)
u_char *shared;
size_t size, cl;
ngx_shm_t shm;
ngx_time_t *tp;
ngx_core_conf_t *ccf;
ngx_event_conf_t *ecf;
@ -492,7 +493,8 @@ ngx_event_module_init(ngx_cycle_t *cycle)
cl = 128;
size = cl /* ngx_accept_mutex */
+ cl; /* ngx_connection_counter */
+ cl /* ngx_connection_counter */
+ cl; /* ngx_temp_number */
#if (NGX_STAT_STUB)
@ -526,23 +528,29 @@ ngx_event_module_init(ngx_cycle_t *cycle)
ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl);
#if (NGX_STAT_STUB)
ngx_stat_accepted = (ngx_atomic_t *) (shared + 2 * cl);
ngx_stat_handled = (ngx_atomic_t *) (shared + 3 * cl);
ngx_stat_requests = (ngx_atomic_t *) (shared + 4 * cl);
ngx_stat_active = (ngx_atomic_t *) (shared + 5 * cl);
ngx_stat_reading = (ngx_atomic_t *) (shared + 6 * cl);
ngx_stat_writing = (ngx_atomic_t *) (shared + 7 * cl);
#endif
(void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"counter: %p, %d",
ngx_connection_counter, *ngx_connection_counter);
ngx_temp_number = (ngx_atomic_t *) (shared + 2 * cl);
tp = ngx_timeofday();
ngx_random_number = (tp->msec << 16) + ngx_pid;
#if (NGX_STAT_STUB)
ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * cl);
ngx_stat_handled = (ngx_atomic_t *) (shared + 4 * cl);
ngx_stat_requests = (ngx_atomic_t *) (shared + 5 * cl);
ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl);
ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl);
ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl);
#endif
return NGX_OK;
}
@ -554,8 +562,6 @@ ngx_timer_signal_handler(int signo)
{
ngx_event_timer_alarm = 1;
ngx_time_update(0, 0);
#if 1
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal");
#endif
@ -1113,7 +1119,7 @@ ngx_event_create_conf(ngx_cycle_t *cycle)
ecf = ngx_palloc(cycle->pool, sizeof(ngx_event_conf_t));
if (ecf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
ecf->connections = NGX_CONF_UNSET_UINT;
@ -1128,7 +1134,7 @@ ngx_event_create_conf(ngx_cycle_t *cycle)
if (ngx_array_init(&ecf->debug_connection, cycle->pool, 4,
sizeof(ngx_event_debug_t)) == NGX_ERROR)
{
return NGX_CONF_ERROR;
return NULL;
}
#endif

View File

@ -75,7 +75,7 @@ ngx_event_accept(ngx_event_t *ev)
}
#if (NGX_STAT_STUB)
ngx_atomic_fetch_add(ngx_stat_accepted, 1);
(void) ngx_atomic_fetch_add(ngx_stat_accepted, 1);
#endif
ngx_accept_disabled = ngx_cycle->connection_n / 8
@ -93,7 +93,7 @@ ngx_event_accept(ngx_event_t *ev)
}
#if (NGX_STAT_STUB)
ngx_atomic_fetch_add(ngx_stat_active, 1);
(void) ngx_atomic_fetch_add(ngx_stat_active, 1);
#endif
c->pool = ngx_create_pool(ls->pool_size, ev->log);
@ -188,7 +188,7 @@ ngx_event_accept(ngx_event_t *ev)
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
#if (NGX_STAT_STUB)
ngx_atomic_fetch_add(ngx_stat_handled, 1);
(void) ngx_atomic_fetch_add(ngx_stat_handled, 1);
#endif
#if (NGX_THREADS)
@ -379,7 +379,7 @@ ngx_close_accepted_connection(ngx_connection_t *c)
}
#if (NGX_STAT_STUB)
ngx_atomic_fetch_add(ngx_stat_active, -1);
(void) ngx_atomic_fetch_add(ngx_stat_active, -1);
#endif
}

View File

@ -15,6 +15,8 @@ typedef struct {
static int ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where,
int ret);
static void ngx_ssl_handshake_handler(ngx_event_t *ev);
static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);
static void ngx_ssl_write_handler(ngx_event_t *wev);
@ -97,16 +99,14 @@ int ngx_ssl_session_cache_index;
ngx_int_t
ngx_ssl_init(ngx_log_t *log)
{
#if OPENSSL_VERSION_NUMBER >= 0x00907000
OPENSSL_config(NULL);
#endif
SSL_library_init();
SSL_load_error_strings();
#if (NGX_SSL_ENGINE)
ENGINE_load_builtin_engines();
#endif
OpenSSL_add_all_algorithms();
ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
@ -169,9 +169,7 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_D5_BUG);
SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_BLOCK_PADDING_BUG);
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
SSL_CTX_set_options(ssl->ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
#endif
SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_DH_USE);
@ -181,6 +179,8 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_read_ahead(ssl->ctx, 1);
SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback);
return NGX_OK;
}
@ -267,6 +267,51 @@ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
}
ngx_int_t
ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl)
{
X509_STORE *store;
X509_LOOKUP *lookup;
if (crl->len == 0) {
return NGX_OK;
}
if (ngx_conf_full_name(cf->cycle, crl, 1) != NGX_OK) {
return NGX_ERROR;
}
store = SSL_CTX_get_cert_store(ssl->ctx);
if (store == NULL) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"SSL_CTX_get_cert_store() failed");
return NGX_ERROR;
}
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
if (lookup == NULL) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"X509_STORE_add_lookup() failed");
return NGX_ERROR;
}
if (X509_LOOKUP_load_file(lookup, (char *) crl->data, X509_FILETYPE_PEM)
== 0)
{
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"X509_LOOKUP_load_file(\"%s\") failed", crl->data);
return NGX_ERROR;
}
X509_STORE_set_flags(store,
X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
return NGX_OK;
}
static int
ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
{
@ -311,6 +356,22 @@ ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
}
static void
ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
{
ngx_connection_t *c;
if (where & SSL_CB_HANDSHAKE_START) {
c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
if (c->ssl->handshaked) {
c->ssl->renegotiation = 1;
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL renegotiation");
}
}
}
ngx_int_t
ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl)
{
@ -500,6 +561,9 @@ ngx_ssl_handshake(ngx_connection_t *c)
#if (NGX_DEBUG)
{
char buf[129], *s, *d;
#if OPENSSL_VERSION_NUMBER >= 0x1000000fL
const
#endif
SSL_CIPHER *cipher;
cipher = SSL_get_current_cipher(c->ssl->connection);
@ -548,6 +612,11 @@ ngx_ssl_handshake(ngx_connection_t *c)
c->recv_chain = ngx_ssl_recv_chain;
c->send_chain = ngx_ssl_send_chain;
/* initial handshake done, disable renegotiation (CVE-2009-3555) */
if (c->ssl->connection->s3) {
c->ssl->connection->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;
}
return NGX_OK;
}
@ -750,6 +819,21 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n)
int sslerr;
ngx_err_t err;
if (c->ssl->renegotiation) {
/*
* disable renegotiation (CVE-2009-3555):
* OpenSSL (at least up to 0.9.8l) does not handle disabled
* renegotiation gracefully, so drop connection here
*/
ngx_log_error(NGX_LOG_NOTICE, c->log, 0, "SSL renegotiation disabled");
c->ssl->no_wait_shutdown = 1;
c->ssl->no_send_shutdown = 1;
return NGX_ERROR;
}
if (n > 0) {
if (c->ssl->saved_write_handler) {
@ -907,7 +991,7 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
for ( ;; ) {
while (in && buf->last < buf->end) {
while (in && buf->last < buf->end && send < limit) {
if (in->buf->last_buf || in->buf->flush) {
flush = 1;
}
@ -934,8 +1018,8 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
ngx_memcpy(buf->last, in->buf->pos, size);
buf->last += size;
in->buf->pos += size;
send += size;
if (in->buf->pos == in->buf->last) {
in = in->next;
@ -960,7 +1044,6 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
}
buf->pos += n;
send += n;
c->sent += n;
if (n < size) {
@ -1201,9 +1284,7 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
if (err == NGX_ECONNRESET
|| err == NGX_EPIPE
|| err == NGX_ENOTCONN
#if !(NGX_CRIT_ETIMEDOUT)
|| err == NGX_ETIMEDOUT
#endif
|| err == NGX_ECONNREFUSED
|| err == NGX_ENETDOWN
|| err == NGX_ENETUNREACH
@ -1232,10 +1313,15 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
/* handshake failures */
if (n == SSL_R_DIGEST_CHECK_FAILED /* 149 */
|| n == SSL_R_LENGTH_MISMATCH /* 159 */
|| n == SSL_R_NO_CIPHERS_PASSED /* 182 */
|| n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */
|| n == SSL_R_NO_SHARED_CIPHER /* 193 */
|| n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */
|| n == SSL_R_UNEXPECTED_MESSAGE /* 244 */
|| n == SSL_R_UNEXPECTED_RECORD /* 245 */
|| n == SSL_R_UNKNOWN_ALERT_TYPE /* 246 */
|| n == SSL_R_UNKNOWN_PROTOCOL /* 252 */
|| n == SSL_R_WRONG_VERSION_NUMBER /* 267 */
|| n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC /* 281 */
|| n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */
@ -1347,6 +1433,8 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
return NGX_OK;
}
SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len);
if (builtin_session_cache == NGX_SSL_NONE_SCACHE) {
/*
@ -1378,8 +1466,6 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
SSL_CTX_set_session_cache_mode(ssl->ctx, cache_mode);
SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len);
if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) {
if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) {
@ -1551,7 +1637,7 @@ ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
hash = ngx_crc32_short(sess->session_id, sess->session_id_length);
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"http ssl new session: %08XD:%d:%d",
"ssl new session: %08XD:%d:%d",
hash, sess->session_id_length, len);
sess_id->node.key = hash;
@ -1614,7 +1700,7 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
*copy = 0;
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"http ssl get session: %08XD:%d", hash, len);
"ssl get session: %08XD:%d", hash, len);
shm_zone = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn),
ngx_ssl_session_cache_index);
@ -1728,7 +1814,7 @@ ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
hash = ngx_crc32_short(id, len);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
"http ssl remove session: %08XD:%uz", hash, len);
"ssl remove session: %08XD:%uz", hash, len);
shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
@ -1891,6 +1977,40 @@ ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
}
ngx_int_t
ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
{
int len;
u_char *p, *buf;
SSL_SESSION *sess;
sess = SSL_get0_session(c->ssl->connection);
len = i2d_SSL_SESSION(sess, NULL);
buf = ngx_alloc(len, c->log);
if (buf == NULL) {
return NGX_ERROR;
}
s->len = 2 * len;
s->data = ngx_pnalloc(pool, 2 * len);
if (s->data == NULL) {
ngx_free(buf);
return NGX_ERROR;
}
p = buf;
i2d_SSL_SESSION(sess, &p);
ngx_hex_dump(s->data, buf, len);
ngx_free(buf);
return NGX_OK;
}
ngx_int_t
ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
{
@ -1974,7 +2094,7 @@ ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
p = s->data;
for (i = 0; i < len; i++) {
for (i = 0; i < cert.len - 1; i++) {
*p++ = cert.data[i];
if (cert.data[i] == LF) {
*p++ = '\t';
@ -2108,6 +2228,35 @@ ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
}
ngx_int_t
ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
{
X509 *cert;
if (SSL_get_verify_result(c->ssl->connection) != X509_V_OK) {
s->len = sizeof("FAILED") - 1;
s->data = (u_char *) "FAILED";
return NGX_OK;
}
cert = SSL_get_peer_certificate(c->ssl->connection);
if (cert) {
s->len = sizeof("SUCCESS") - 1;
s->data = (u_char *) "SUCCESS";
} else {
s->len = sizeof("NONE") - 1;
s->data = (u_char *) "NONE";
}
X509_free(cert);
return NGX_OK;
}
static void *
ngx_openssl_create_conf(ngx_cycle_t *cycle)
{
@ -2115,7 +2264,7 @@ ngx_openssl_create_conf(ngx_cycle_t *cycle)
oscf = ngx_pcalloc(cycle->pool, sizeof(ngx_openssl_conf_t));
if (oscf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*
@ -2131,7 +2280,6 @@ ngx_openssl_create_conf(ngx_cycle_t *cycle)
static char *
ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
#if (NGX_SSL_ENGINE)
ngx_openssl_conf_t *oscf = conf;
ENGINE *engine;
@ -2166,23 +2314,12 @@ ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ENGINE_free(engine);
return NGX_CONF_OK;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"ssl_engine\" directive is available only in "
"OpenSSL 0.9.7 and higher,");
return NGX_CONF_ERROR;
#endif
}
static void
ngx_openssl_exit(ngx_cycle_t *cycle)
{
#if (NGX_SSL_ENGINE)
EVP_cleanup();
ENGINE_cleanup();
#endif
}

View File

@ -13,12 +13,9 @@
#include <openssl/ssl.h>
#include <openssl/err.h>
#if OPENSSL_VERSION_NUMBER >= 0x00907000
#include <openssl/conf.h>
#include <openssl/engine.h>
#define NGX_SSL_ENGINE 1
#endif
#include <openssl/evp.h>
#define NGX_SSL_NAME "OpenSSL"
@ -45,6 +42,7 @@ typedef struct {
ngx_event_handler_pt saved_write_handler;
unsigned handshaked:1;
unsigned renegotiation:1;
unsigned buffer:1;
unsigned no_wait_shutdown:1;
unsigned no_send_shutdown:1;
@ -100,6 +98,7 @@ ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *cert, ngx_str_t *key);
ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *cert, ngx_int_t depth);
ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl);
ngx_int_t ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl);
ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
@ -121,6 +120,8 @@ ngx_int_t ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool,
@ -131,6 +132,8 @@ ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_handshake(ngx_connection_t *c);

View File

@ -201,7 +201,7 @@ ngx_http_access_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_access_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
return conf;

View File

@ -45,7 +45,7 @@ static ngx_command_t ngx_http_addition_commands[] = {
offsetof(ngx_http_addition_conf_t, after_body),
NULL },
{ ngx_string("addtion_types"),
{ ngx_string("addition_types"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_types_slot,
NGX_HTTP_LOC_CONF_OFFSET,
@ -212,7 +212,7 @@ ngx_http_addition_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_addition_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*

View File

@ -372,7 +372,7 @@ ngx_http_auth_basic_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_auth_basic_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
return conf;

View File

@ -145,7 +145,7 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
ngx_int_t rc, size;
ngx_str_t path;
ngx_dir_t dir;
ngx_uint_t i, level;
ngx_uint_t i, level, utf8;
ngx_pool_t *pool;
ngx_time_t *tp;
ngx_chain_t out;
@ -160,10 +160,6 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
if (r->zero_in_uri) {
return NGX_DECLINED;
}
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
return NGX_DECLINED;
}
@ -252,6 +248,16 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
filename = path.data;
filename[path.len] = '/';
if (r->headers_out.charset.len == 5
&& ngx_strncasecmp(r->headers_out.charset.data, (u_char *) "utf-8", 5)
== 0)
{
utf8 = 1;
} else {
utf8 = 0;
}
for ( ;; ) {
ngx_set_errno(0);
@ -335,7 +341,7 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len,
NGX_ESCAPE_HTML);
if (r->utf8) {
if (utf8) {
entry->utf_len = ngx_utf8_length(entry->name.data, entry->name.len);
} else {
entry->utf_len = len;
@ -622,7 +628,7 @@ ngx_http_autoindex_create_loc_conf(ngx_conf_t *cf)
conf = ngx_palloc(cf->pool, sizeof(ngx_http_autoindex_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
conf->enable = NGX_CONF_UNSET;

View File

@ -423,7 +423,7 @@ ngx_http_browser_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_browser_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*

View File

@ -9,8 +9,9 @@
#include <ngx_http.h>
#define NGX_HTTP_NO_CHARSET -2
#define NGX_HTTP_CHARSET_VAR 0x10000
#define NGX_HTTP_CHARSET_OFF -2
#define NGX_HTTP_NO_CHARSET -3
#define NGX_HTTP_CHARSET_VAR 0x10000
/* 1 byte length and up to 3 bytes for the UTF-8 encoding of the UCS-2 */
#define NGX_UTF_LEN 4
@ -61,6 +62,7 @@ typedef struct {
typedef struct {
u_char *table;
ngx_int_t charset;
ngx_str_t charset_name;
ngx_chain_t *busy;
ngx_chain_t *free_bufs;
@ -82,9 +84,16 @@ typedef struct {
} ngx_http_charset_conf_ctx_t;
static ngx_int_t ngx_http_charset_get_charset(ngx_http_charset_t *charsets,
ngx_uint_t n, ngx_str_t *charset);
static ngx_int_t ngx_http_charset_set_charset(ngx_http_request_t *r,
static ngx_int_t ngx_http_destination_charset(ngx_http_request_t *r,
ngx_str_t *name);
static ngx_int_t ngx_http_main_request_charset(ngx_http_request_t *r,
ngx_str_t *name);
static ngx_int_t ngx_http_source_charset(ngx_http_request_t *r,
ngx_str_t *name);
static ngx_int_t ngx_http_get_charset(ngx_http_request_t *r, ngx_str_t *name);
static ngx_inline void ngx_http_set_charset(ngx_http_request_t *r,
ngx_str_t *charset);
static ngx_int_t ngx_http_charset_ctx(ngx_http_request_t *r,
ngx_http_charset_t *charsets, ngx_int_t charset, ngx_int_t source_charset);
static ngx_uint_t ngx_http_charset_recode(ngx_buf_t *b, u_char *table);
static ngx_chain_t *ngx_http_charset_recode_from_utf8(ngx_pool_t *pool,
@ -207,207 +216,264 @@ static ngx_int_t
ngx_http_charset_header_filter(ngx_http_request_t *r)
{
ngx_int_t charset, source_charset;
ngx_str_t *mc, *from, *to, s;
ngx_uint_t n;
ngx_str_t dst, src;
ngx_http_charset_t *charsets;
ngx_http_charset_ctx_t *ctx;
ngx_http_variable_value_t *vv;
ngx_http_charset_loc_conf_t *lcf, *mlcf;
ngx_http_charset_main_conf_t *mcf;
mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
charsets = mcf->charsets.elts;
n = mcf->charsets.nelts;
/* destination charset */
if (r == r->main) {
if (!r->ignore_content_encoding
&& r->headers_out.content_encoding
&& r->headers_out.content_encoding->value.len)
{
return ngx_http_next_header_filter(r);
}
if (r->headers_out.content_type.len == 0) {
return ngx_http_next_header_filter(r);
}
if (r->headers_out.override_charset
&& r->headers_out.override_charset->len)
{
charset = ngx_http_charset_get_charset(charsets, n,
r->headers_out.override_charset);
if (charset == NGX_HTTP_NO_CHARSET) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"unknown charset \"%V\" to override",
r->headers_out.override_charset);
return ngx_http_next_header_filter(r);
}
} else {
mlcf = ngx_http_get_module_loc_conf(r,
ngx_http_charset_filter_module);
charset = mlcf->charset;
if (charset == NGX_HTTP_NO_CHARSET) {
return ngx_http_next_header_filter(r);
}
if (r->headers_out.charset.len) {
if (mlcf->override_charset == 0) {
return ngx_http_next_header_filter(r);
}
} else {
if (ngx_http_test_content_type(r, &mlcf->types) == NULL) {
return ngx_http_next_header_filter(r);
}
}
if (charset >= NGX_HTTP_CHARSET_VAR) {
vv = ngx_http_get_indexed_variable(r,
charset - NGX_HTTP_CHARSET_VAR);
if (vv == NULL || vv->not_found) {
return NGX_ERROR;
}
s.len = vv->len;
s.data = vv->data;
charset = ngx_http_charset_get_charset(charsets, n, &s);
}
}
charset = ngx_http_destination_charset(r, &dst);
} else {
ctx = ngx_http_get_module_ctx(r->main, ngx_http_charset_filter_module);
if (ctx == NULL) {
mc = &r->main->headers_out.charset;
if (mc->len == 0) {
return ngx_http_next_header_filter(r);
}
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
}
ngx_http_set_ctx(r->main, ctx, ngx_http_charset_filter_module);
charset = ngx_http_charset_get_charset(charsets, n, mc);
ctx->charset = charset;
} else {
charset = ctx->charset;
}
charset = ngx_http_main_request_charset(r, &dst);
}
/* source charset */
if (r->headers_out.charset.len == 0) {
lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module);
source_charset = lcf->source_charset;
if (source_charset >= NGX_HTTP_CHARSET_VAR) {
vv = ngx_http_get_indexed_variable(r,
source_charset - NGX_HTTP_CHARSET_VAR);
if (vv == NULL || vv->not_found) {
return NGX_ERROR;
}
s.len = vv->len;
s.data = vv->data;
source_charset = ngx_http_charset_get_charset(charsets, n, &s);
}
if (charset != NGX_HTTP_NO_CHARSET) {
return ngx_http_charset_set_charset(r, mcf->charsets.elts, charset,
source_charset);
}
if (source_charset == NGX_CONF_UNSET) {
return ngx_http_next_header_filter(r);
}
from = &charsets[source_charset].name;
to = &r->main->headers_out.charset;
goto no_charset_map;
if (charset == NGX_ERROR) {
return NGX_ERROR;
}
source_charset = ngx_http_charset_get_charset(charsets, n,
&r->headers_out.charset);
if (charset == NGX_DECLINED) {
return ngx_http_next_header_filter(r);
}
/* charset: charset index or NGX_HTTP_NO_CHARSET */
source_charset = ngx_http_source_charset(r, &src);
if (source_charset == NGX_ERROR) {
return NGX_ERROR;
}
/*
* source_charset: charset index, NGX_HTTP_NO_CHARSET,
* or NGX_HTTP_CHARSET_OFF
*/
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"charset: \"%V\" > \"%V\"", &src, &dst);
if (source_charset == NGX_HTTP_CHARSET_OFF) {
ngx_http_set_charset(r, &dst);
return ngx_http_next_header_filter(r);
}
if (charset == NGX_HTTP_NO_CHARSET
|| source_charset == NGX_HTTP_NO_CHARSET)
{
if (charset != source_charset
|| ngx_strcasecmp(r->main->headers_out.charset.data,
r->headers_out.charset.data)
!= 0)
if (source_charset != charset
|| ngx_strncasecmp(dst.data, src.data, dst.len) != 0)
{
from = &r->headers_out.charset;
to = (charset == NGX_HTTP_NO_CHARSET) ?
&r->main->headers_out.charset:
&charsets[charset].name;
goto no_charset_map;
}
ngx_http_set_charset(r, &dst);
return ngx_http_next_header_filter(r);
}
mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
charsets = mcf->charsets.elts;
if (source_charset != charset
&& (charsets[source_charset].tables == NULL
|| charsets[source_charset].tables[charset] == NULL))
{
from = &charsets[source_charset].name;
to = &charsets[charset].name;
goto no_charset_map;
}
r->headers_out.content_type.len = r->headers_out.content_type_len;
return ngx_http_charset_set_charset(r, mcf->charsets.elts, charset,
source_charset);
ngx_http_set_charset(r, &dst);
if (source_charset != charset) {
return ngx_http_charset_ctx(r, charsets, charset, source_charset);
}
return ngx_http_next_header_filter(r);
no_charset_map:
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"no \"charset_map\" between the charsets \"%V\" and \"%V\"",
from, to);
&src, &dst);
return ngx_http_next_header_filter(r);
}
static ngx_int_t
ngx_http_charset_get_charset(ngx_http_charset_t *charsets, ngx_uint_t n,
ngx_str_t *charset)
ngx_http_destination_charset(ngx_http_request_t *r, ngx_str_t *name)
{
ngx_uint_t i;
ngx_int_t charset;
ngx_http_charset_t *charsets;
ngx_http_variable_value_t *vv;
ngx_http_charset_loc_conf_t *mlcf;
ngx_http_charset_main_conf_t *mcf;
if (!r->ignore_content_encoding
&& r->headers_out.content_encoding
&& r->headers_out.content_encoding->value.len)
{
return NGX_DECLINED;
}
if (r->headers_out.content_type.len == 0) {
return NGX_DECLINED;
}
if (r->headers_out.override_charset
&& r->headers_out.override_charset->len)
{
*name = *r->headers_out.override_charset;
charset = ngx_http_get_charset(r, name);
if (charset != NGX_HTTP_NO_CHARSET) {
return charset;
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"unknown charset \"%V\" to override", name);
return NGX_DECLINED;
}
mlcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module);
charset = mlcf->charset;
if (charset == NGX_HTTP_CHARSET_OFF) {
return NGX_DECLINED;
}
if (r->headers_out.charset.len) {
if (mlcf->override_charset == 0) {
return NGX_DECLINED;
}
} else {
if (ngx_http_test_content_type(r, &mlcf->types) == NULL) {
return NGX_DECLINED;
}
}
if (charset < NGX_HTTP_CHARSET_VAR) {
mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
charsets = mcf->charsets.elts;
*name = charsets[charset].name;
return charset;
}
vv = ngx_http_get_indexed_variable(r, charset - NGX_HTTP_CHARSET_VAR);
if (vv == NULL || vv->not_found) {
return NGX_ERROR;
}
name->len = vv->len;
name->data = vv->data;
return ngx_http_get_charset(r, name);
}
static ngx_int_t
ngx_http_main_request_charset(ngx_http_request_t *r, ngx_str_t *src)
{
ngx_int_t charset;
ngx_str_t *main_charset;
ngx_http_charset_ctx_t *ctx;
ctx = ngx_http_get_module_ctx(r->main, ngx_http_charset_filter_module);
if (ctx) {
*src = ctx->charset_name;
return ctx->charset;
}
main_charset = &r->main->headers_out.charset;
if (main_charset->len == 0) {
return NGX_DECLINED;
}
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
}
ngx_http_set_ctx(r->main, ctx, ngx_http_charset_filter_module);
charset = ngx_http_get_charset(r, main_charset);
ctx->charset = charset;
ctx->charset_name = *main_charset;
*src = *main_charset;
return charset;
}
static ngx_int_t
ngx_http_source_charset(ngx_http_request_t *r, ngx_str_t *name)
{
ngx_int_t charset;
ngx_http_charset_t *charsets;
ngx_http_variable_value_t *vv;
ngx_http_charset_loc_conf_t *lcf;
ngx_http_charset_main_conf_t *mcf;
if (r->headers_out.charset.len) {
*name = r->headers_out.charset;
return ngx_http_get_charset(r, name);
}
lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module);
charset = lcf->source_charset;
if (charset == NGX_HTTP_CHARSET_OFF) {
name->len = 0;
return charset;
}
if (charset < NGX_HTTP_CHARSET_VAR) {
mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
charsets = mcf->charsets.elts;
*name = charsets[charset].name;
return charset;
}
vv = ngx_http_get_indexed_variable(r, charset - NGX_HTTP_CHARSET_VAR);
if (vv == NULL || vv->not_found) {
return NGX_ERROR;
}
name->len = vv->len;
name->data = vv->data;
return ngx_http_get_charset(r, name);
}
static ngx_int_t
ngx_http_get_charset(ngx_http_request_t *r, ngx_str_t *name)
{
ngx_uint_t i, n;
ngx_http_charset_t *charset;
ngx_http_charset_main_conf_t *mcf;
mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
charset = mcf->charsets.elts;
n = mcf->charsets.nelts;
for (i = 0; i < n; i++) {
if (charsets[i].name.len != charset->len) {
if (charset[i].name.len != name->len) {
continue;
}
if (ngx_strncasecmp(charsets[i].name.data, charset->data, charset->len)
== 0)
{
if (ngx_strncasecmp(charset[i].name.data, name->data, name->len) == 0) {
return i;
}
}
@ -416,11 +482,12 @@ ngx_http_charset_get_charset(ngx_http_charset_t *charsets, ngx_uint_t n,
}
static ngx_int_t
ngx_http_charset_set_charset(ngx_http_request_t *r,
ngx_http_charset_t *charsets, ngx_int_t charset, ngx_int_t source_charset)
static ngx_inline void
ngx_http_set_charset(ngx_http_request_t *r, ngx_str_t *charset)
{
ngx_http_charset_ctx_t *ctx;
if (r != r->main) {
return;
}
if (r->headers_out.status == NGX_HTTP_MOVED_PERMANENTLY
|| r->headers_out.status == NGX_HTTP_MOVED_TEMPORARILY)
@ -431,16 +498,18 @@ ngx_http_charset_set_charset(ngx_http_request_t *r,
*/
r->headers_out.charset.len = 0;
return ngx_http_next_header_filter(r);
return;
}
r->headers_out.charset = charsets[charset].name;
r->utf8 = charsets[charset].utf8;
r->headers_out.charset = *charset;
}
if (source_charset == NGX_CONF_UNSET || source_charset == charset) {
return ngx_http_next_header_filter(r);
}
static ngx_int_t
ngx_http_charset_ctx(ngx_http_request_t *r, ngx_http_charset_t *charsets,
ngx_int_t charset, ngx_int_t source_charset)
{
ngx_http_charset_ctx_t *ctx;
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t));
if (ctx == NULL) {
@ -451,6 +520,7 @@ ngx_http_charset_set_charset(ngx_http_request_t *r,
ctx->table = charsets[source_charset].tables[charset];
ctx->charset = charset;
ctx->charset_name = charsets[charset].name;
ctx->length = charsets[charset].length;
ctx->from_utf8 = charsets[source_charset].utf8;
ctx->to_utf8 = charsets[charset].utf8;
@ -1338,7 +1408,7 @@ ngx_http_set_charset_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (cmd->offset == offsetof(ngx_http_charset_loc_conf_t, charset)
&& ngx_strcmp(value[1].data, "off") == 0)
{
*cp = NGX_HTTP_NO_CHARSET;
*cp = NGX_HTTP_CHARSET_OFF;
return NGX_CONF_OK;
}
@ -1418,27 +1488,27 @@ ngx_http_charset_create_main_conf(ngx_conf_t *cf)
mcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_main_conf_t));
if (mcf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
if (ngx_array_init(&mcf->charsets, cf->pool, 2, sizeof(ngx_http_charset_t))
!= NGX_OK)
{
return NGX_CONF_ERROR;
return NULL;
}
if (ngx_array_init(&mcf->tables, cf->pool, 1,
sizeof(ngx_http_charset_tables_t))
!= NGX_OK)
{
return NGX_CONF_ERROR;
return NULL;
}
if (ngx_array_init(&mcf->recodes, cf->pool, 2,
sizeof(ngx_http_charset_recode_t))
!= NGX_OK)
{
return NGX_CONF_ERROR;
return NULL;
}
return mcf;
@ -1452,7 +1522,7 @@ ngx_http_charset_create_loc_conf(ngx_conf_t *cf)
lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_loc_conf_t));
if (lcf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*
@ -1489,14 +1559,12 @@ ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
}
ngx_conf_merge_value(conf->override_charset, prev->override_charset, 0);
ngx_conf_merge_value(conf->charset, prev->charset, NGX_HTTP_NO_CHARSET);
ngx_conf_merge_value(conf->charset, prev->charset, NGX_HTTP_CHARSET_OFF);
ngx_conf_merge_value(conf->source_charset, prev->source_charset,
NGX_HTTP_CHARSET_OFF);
if (conf->source_charset == NGX_CONF_UNSET) {
conf->source_charset = prev->source_charset;
}
if (conf->charset == NGX_HTTP_NO_CHARSET
|| conf->source_charset == NGX_CONF_UNSET
if (conf->charset == NGX_HTTP_CHARSET_OFF
|| conf->source_charset == NGX_HTTP_CHARSET_OFF
|| conf->charset == conf->source_charset)
{
return NGX_CONF_OK;

View File

@ -50,9 +50,10 @@ static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
static ngx_int_t
ngx_http_chunked_header_filter(ngx_http_request_t *r)
{
ngx_http_core_loc_conf_t *clcf;
if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED
|| r->headers_out.status == NGX_HTTP_NO_CONTENT
|| r->headers_out.status == NGX_HTTP_CREATED
|| r != r->main
|| (r->method & NGX_HTTP_HEAD))
{
@ -64,7 +65,14 @@ ngx_http_chunked_header_filter(ngx_http_request_t *r)
r->keepalive = 0;
} else {
r->chunked = 1;
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (clcf->chunked_transfer_encoding) {
r->chunked = 1;
} else {
r->keepalive = 0;
}
}
}

View File

@ -53,8 +53,6 @@ static ngx_int_t ngx_http_dav_copy_dir_time(ngx_tree_ctx_t *ctx,
ngx_str_t *path);
static ngx_int_t ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx,
ngx_str_t *path);
static ngx_int_t ngx_http_dav_copy_file(ngx_tree_ctx_t *ctx, u_char *from,
u_char *to);
static ngx_int_t ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt);
static ngx_int_t ngx_http_dav_error(ngx_log_t *log, ngx_err_t err,
@ -148,10 +146,6 @@ ngx_http_dav_handler(ngx_http_request_t *r)
ngx_int_t rc;
ngx_http_dav_loc_conf_t *dlcf;
if (r->zero_in_uri) {
return NGX_DECLINED;
}
dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
if (!(r->method & dlcf->methods)) {
@ -216,6 +210,8 @@ ngx_http_dav_put_handler(ngx_http_request_t *r)
ngx_http_map_uri_to_path(r, &path, &root, 0);
path.len--;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http put filename: \"%s\"", path.data);
@ -249,7 +245,6 @@ ngx_http_dav_put_handler(ngx_http_request_t *r)
ext.time = -1;
ext.create_path = dlcf->create_full_put_path;
ext.delete_file = 1;
ext.log_rename_error = 1;
ext.log = r->connection->log;
if (r->headers_in.date) {
@ -326,13 +321,13 @@ ok:
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http delete filename: \"%s\"", path.data);
if (ngx_file_info(path.data, &fi) == NGX_FILE_ERROR) {
if (ngx_link_info(path.data, &fi) == NGX_FILE_ERROR) {
err = ngx_errno;
rc = (err == NGX_ENOTDIR) ? NGX_HTTP_CONFLICT : NGX_HTTP_NOT_FOUND;
return ngx_http_dav_error(r->connection->log, err,
rc, ngx_file_info_n, path.data);
rc, ngx_link_info_n, path.data);
}
if (ngx_is_dir(&fi)) {
@ -359,7 +354,7 @@ ok:
/*
* we do not need to test (r->uri.data[r->uri.len - 1] == '/')
* because ngx_file_info("/file/") returned NGX_ENOTDIR above
* because ngx_link_info("/file/") returned NGX_ENOTDIR above
*/
depth = ngx_http_dav_depth(r, 0);
@ -491,6 +486,7 @@ ngx_http_dav_mkcol_handler(ngx_http_request_t *r, ngx_http_dav_loc_conf_t *dlcf)
p = ngx_http_map_uri_to_path(r, &path, &root, 0);
*(p - 1) = '\0';
r->uri.len--;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http mkcol path: \"%s\"", path.data);
@ -517,9 +513,10 @@ ngx_http_dav_copy_move_handler(ngx_http_request_t *r)
size_t len, root;
ngx_err_t err;
ngx_int_t rc, depth;
ngx_uint_t overwrite, slash, dir;
ngx_str_t path, uri;
ngx_uint_t overwrite, slash, dir, flags;
ngx_str_t path, uri, duri, args;
ngx_tree_ctx_t tree;
ngx_copy_file_t cf;
ngx_file_info_t fi;
ngx_table_elt_t *dest, *over;
ngx_ext_rename_file_t ext;
@ -594,6 +591,14 @@ invalid_destination:
destination_done:
duri.len = last - p;
duri.data = p;
flags = 0;
if (ngx_http_parse_unsafe_uri(r, &duri, &args, &flags) != NGX_OK) {
goto invalid_destination;
}
if ((r->uri.data[r->uri.len - 1] == '/' && *(last - 1) != '/')
|| (r->uri.data[r->uri.len - 1] != '/' && *(last - 1) == '/'))
{
@ -656,9 +661,7 @@ overwrite_done:
"http copy from: \"%s\"", path.data);
uri = r->uri;
r->uri.len = last - p;
r->uri.data = p;
r->uri = duri;
ngx_http_map_uri_to_path(r, &copy.path, &root, 0);
@ -678,12 +681,12 @@ overwrite_done:
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http copy to: \"%s\"", copy.path.data);
if (ngx_file_info(copy.path.data, &fi) == NGX_FILE_ERROR) {
if (ngx_link_info(copy.path.data, &fi) == NGX_FILE_ERROR) {
err = ngx_errno;
if (err != NGX_ENOENT) {
return ngx_http_dav_error(r->connection->log, err,
NGX_HTTP_NOT_FOUND, ngx_file_info_n,
NGX_HTTP_NOT_FOUND, ngx_link_info_n,
copy.path.data);
}
@ -712,9 +715,9 @@ overwrite_done:
dir = ngx_is_dir(&fi);
}
if (ngx_file_info(path.data, &fi) == NGX_FILE_ERROR) {
if (ngx_link_info(path.data, &fi) == NGX_FILE_ERROR) {
return ngx_http_dav_error(r->connection->log, ngx_errno,
NGX_HTTP_NOT_FOUND, ngx_file_info_n,
NGX_HTTP_NOT_FOUND, ngx_link_info_n,
path.data);
}
@ -791,43 +794,24 @@ overwrite_done:
ext.time = -1;
ext.create_path = 1;
ext.delete_file = 0;
ext.log_rename_error = 0;
ext.log = r->connection->log;
if (ngx_ext_rename_file(&path, &copy.path, &ext) == NGX_OK) {
return NGX_HTTP_NO_CONTENT;
}
if (ext.rename_error != NGX_EXDEV) {
if (ext.rename_error) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log,
ext.rename_error,
ngx_rename_file_n " \"%s\" to \"%s\" failed",
path.data, copy.path.data);
}
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
tree.size = ngx_file_size(&fi);
tree.mtime = ngx_file_mtime(&fi);
tree.access = dlcf->access;
tree.log = r->connection->log;
if (ngx_http_dav_copy_file(&tree, path.data, copy.path.data) == NGX_OK)
{
if (r->method == NGX_HTTP_MOVE) {
rc = ngx_http_dav_delete_path(r, &path, 0);
if (rc != NGX_OK) {
return rc;
}
}
cf.size = ngx_file_size(&fi);
cf.buf_size = 0;
cf.access = dlcf->access;
cf.time = ngx_file_mtime(&fi);
cf.log = r->connection->log;
if (ngx_copy_file(path.data, copy.path.data, &cf) == NGX_OK) {
return NGX_HTTP_NO_CONTENT;
}
}
@ -941,6 +925,7 @@ ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
{
u_char *p, *file;
size_t len;
ngx_copy_file_t cf;
ngx_http_dav_copy_ctx_t *copy;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
@ -961,7 +946,13 @@ ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
"http copy file to: \"%s\"", file);
(void) ngx_http_dav_copy_file(ctx, path->data, file);
cf.size = ctx->size;
cf.buf_size = 0;
cf.access = ctx->access;
cf.time = ctx->mtime;
cf.log = ctx->log;
(void) ngx_copy_file(path->data, file, &cf);
ngx_free(file);
@ -969,75 +960,6 @@ ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
}
static ngx_int_t
ngx_http_dav_copy_file(ngx_tree_ctx_t *ctx, u_char *from, u_char *to)
{
off_t size;
ssize_t n;
ngx_fd_t fd, cfd;
ngx_int_t rc;
u_char buf[NGX_HTTP_DAV_COPY_BLOCK];
fd = ngx_open_file(from, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
if (fd == NGX_INVALID_FILE) {
(void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_open_file_n,
from);
return NGX_ERROR;
}
cfd = ngx_open_file(to, NGX_FILE_WRONLY, NGX_FILE_CREATE_OR_OPEN,
ctx->access);
rc = NGX_ERROR;
if (cfd == NGX_INVALID_FILE) {
(void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_open_file_n, to);
goto failed;
}
for (size = ctx->size; size > 0; size -= n) {
n = ngx_read_fd(fd, buf, NGX_HTTP_DAV_COPY_BLOCK);
if (n == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
ngx_read_fd_n " \"%s\" failed", from);
goto failed;
}
if (ngx_write_fd(cfd, buf, n) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
ngx_write_fd_n " \"%s\" failed", to);
goto failed;
}
}
if (ngx_set_file_time(to, cfd, ctx->mtime) != NGX_OK) {
ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
ngx_set_file_time_n " \"%s\" failed", to);
goto failed;
}
if (ngx_close_file(cfd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
ngx_close_file_n " \"%s\" failed", to);
goto failed;
}
rc = NGX_OK;
failed:
if (ngx_close_file(fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
ngx_close_file_n " \"%s\" failed", from);
}
return rc;
}
static ngx_int_t
ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt)
{
@ -1154,7 +1076,7 @@ ngx_http_dav_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_dav_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*

View File

@ -178,6 +178,7 @@ static ngx_conf_bitmask_t ngx_http_fastcgi_next_upstream_masks[] = {
{ ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
{ ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
{ ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
{ ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
{ ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
{ ngx_null_string, 0 }
};
@ -332,6 +333,13 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
0,
&ngx_http_fastcgi_module },
{ ngx_string("fastcgi_no_cache"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_no_cache_set_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.no_cache),
NULL },
{ ngx_string("fastcgi_cache_valid"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_file_cache_valid_set_slot,
@ -522,6 +530,23 @@ static ngx_str_t ngx_http_fastcgi_hide_headers[] = {
};
#if (NGX_HTTP_CACHE)
static ngx_str_t ngx_http_fastcgi_hide_cache_headers[] = {
ngx_string("Status"),
ngx_string("X-Accel-Expires"),
ngx_string("X-Accel-Redirect"),
ngx_string("X-Accel-Limit-Rate"),
ngx_string("X-Accel-Buffering"),
ngx_string("X-Accel-Charset"),
ngx_string("Set-Cookie"),
ngx_string("P3P"),
ngx_null_string
};
#endif
static ngx_path_init_t ngx_http_fastcgi_temp_path = {
ngx_string(NGX_HTTP_FASTCGI_TEMP_PATH), { 1, 2, 0 }
};
@ -542,19 +567,16 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
if (f == NULL) {
return NGX_ERROR;
}
ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
if (u == NULL) {
if (ngx_http_upstream_create(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
r->upstream = u;
f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
if (f == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
@ -564,15 +586,11 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
}
}
u = r->upstream;
u->schema.len = sizeof("fastcgi://") - 1;
u->schema.data = (u_char *) "fastcgi://";
u->peer.log = r->connection->log;
u->peer.log_error = NGX_ERROR_ERR;
#if (NGX_THREADS)
u->peer.lock = &r->connection->lock;
#endif
u->output.tag = (ngx_buf_tag_t) &ngx_http_fastcgi_module;
u->conf = &flcf->upstream;
@ -1071,9 +1089,10 @@ ngx_http_fastcgi_reinit_request(ngx_http_request_t *r)
static ngx_int_t
ngx_http_fastcgi_process_header(ngx_http_request_t *r)
{
u_char *p, *start, *last, *part_start;
u_char *p, *msg, *start, *last,
*part_start, *part_end;
size_t size;
ngx_str_t *status_line, line, *pattern;
ngx_str_t *status_line, *pattern;
ngx_int_t rc, status;
ngx_buf_t buf;
ngx_uint_t i;
@ -1157,40 +1176,39 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
if (f->type == NGX_HTTP_FASTCGI_STDERR) {
if (f->length) {
line.data = u->buffer.pos;
msg = u->buffer.pos;
if (u->buffer.pos + f->length <= u->buffer.last) {
line.len = f->length;
u->buffer.pos += f->length;
f->length = 0;
f->state = ngx_http_fastcgi_st_padding;
} else {
line.len = u->buffer.last - u->buffer.pos;
f->length -= u->buffer.last - u->buffer.pos;
u->buffer.pos = u->buffer.last;
}
while (line.data[line.len - 1] == LF
|| line.data[line.len - 1] == CR
|| line.data[line.len - 1] == '.'
|| line.data[line.len - 1] == ' ')
{
line.len--;
for (p = u->buffer.pos - 1; msg < p; p--) {
if (*p != LF && *p != CR && *p != '.' && *p != ' ') {
break;
}
}
p++;
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"FastCGI sent in stderr: \"%V\"", &line);
"FastCGI sent in stderr: \"%*s\"", p - msg, msg);
flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
if (flcf->catch_stderr) {
pattern = flcf->catch_stderr->elts;
line.data[line.len - 1] = '\0';
for (i = 0; i < flcf->catch_stderr->nelts; i++) {
if (ngx_strstr(line.data, pattern[i].data)) {
if (ngx_strnstr(msg, (char *) pattern[i].data,
p - msg)
!= NULL)
{
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
}
}
@ -1243,6 +1261,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
for ( ;; ) {
part_start = u->buffer.pos;
part_end = u->buffer.last;
rc = ngx_http_parse_header_line(r, &u->buffer, 1);
@ -1443,7 +1462,11 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
part = ngx_array_push(f->split_parts);
part->start = part_start;
part->end = u->buffer.last;
part->end = part_end;
if (u->buffer.pos < u->buffer.last) {
continue;
}
return NGX_AGAIN;
}
@ -1453,9 +1476,9 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
static ngx_int_t
ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
{
u_char *m, *msg;
ngx_int_t rc;
ngx_buf_t *b, **prev;
ngx_str_t line;
ngx_chain_t *cl;
ngx_http_request_t *r;
ngx_http_fastcgi_ctx_t *f;
@ -1539,30 +1562,27 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
break;
}
line.data = f->pos;
msg = f->pos;
if (f->pos + f->length <= f->last) {
line.len = f->length;
f->pos += f->length;
f->length = 0;
f->state = ngx_http_fastcgi_st_padding;
} else {
line.len = f->last - f->pos;
f->length -= f->last - f->pos;
f->pos = f->last;
}
while (line.data[line.len - 1] == LF
|| line.data[line.len - 1] == CR
|| line.data[line.len - 1] == '.'
|| line.data[line.len - 1] == ' ')
{
line.len--;
for (m = f->pos - 1; msg < m; m--) {
if (*m != LF && *m != CR && *m != '.' && *m != ' ') {
break;
}
}
ngx_log_error(NGX_LOG_ERR, p->log, 0,
"FastCGI sent in stderr: \"%V\"", &line);
"FastCGI sent in stderr: \"%*s\"",
m + 1 - msg, msg);
if (f->pos == f->last) {
break;
@ -1833,7 +1853,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_fastcgi_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*
@ -1877,6 +1897,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
#if (NGX_HTTP_CACHE)
conf->upstream.cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
#endif
@ -1903,6 +1924,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
u_char *p;
size_t size;
uintptr_t *code;
ngx_str_t *h;
ngx_uint_t i;
ngx_keyval_t *src;
ngx_hash_init_t hash;
@ -1911,7 +1933,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
if (conf->upstream.store != 0) {
ngx_conf_merge_value(conf->upstream.store,
prev->upstream.store, 0);
prev->upstream.store, 0);
if (conf->upstream.store_lengths == NULL) {
conf->upstream.store_lengths = prev->upstream.store_lengths;
@ -2097,6 +2119,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
ngx_conf_merge_ptr_value(conf->upstream.no_cache,
prev->upstream.no_cache, NULL);
ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
prev->upstream.cache_valid, NULL);
@ -2123,10 +2148,18 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
hash.bucket_size = ngx_align(64, ngx_cacheline_size);
hash.name = "fastcgi_hide_headers_hash";
#if (NGX_HTTP_CACHE)
h = conf->upstream.cache ? ngx_http_fastcgi_hide_cache_headers:
ngx_http_fastcgi_hide_headers;
#else
h = ngx_http_fastcgi_hide_headers;
#endif
if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
&prev->upstream,
ngx_http_fastcgi_hide_headers,
&hash)
&prev->upstream, h, &hash)
!= NGX_OK)
{
return NGX_CONF_ERROR;
@ -2437,8 +2470,13 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = ngx_http_fastcgi_handler;
if (clcf->name.data[clcf->name.len - 1] == '/') {
clcf->auto_redirect = 1;
}
value = cf->args->elts;
url = &value[1];
@ -2474,10 +2512,6 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
if (clcf->name.data[clcf->name.len - 1] == '/') {
clcf->auto_redirect = 1;
}
return NGX_CONF_OK;
}
@ -2541,20 +2575,31 @@ ngx_http_fastcgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_str_t *value;
ngx_http_script_compile_t sc;
if (flcf->upstream.store != NGX_CONF_UNSET || flcf->upstream.store_lengths)
if (flcf->upstream.store != NGX_CONF_UNSET
|| flcf->upstream.store_lengths)
{
return "is duplicate";
}
value = cf->args->elts;
if (ngx_strcmp(value[1].data, "on") == 0) {
flcf->upstream.store = 1;
if (ngx_strcmp(value[1].data, "off") == 0) {
flcf->upstream.store = 0;
return NGX_CONF_OK;
}
if (ngx_strcmp(value[1].data, "off") == 0) {
flcf->upstream.store = 0;
#if (NGX_HTTP_CACHE)
if (flcf->upstream.cache != NGX_CONF_UNSET_PTR
&& flcf->upstream.cache != NULL)
{
return "is incompatible with \"fastcgi_cache\"";
}
#endif
if (ngx_strcmp(value[1].data, "on") == 0) {
flcf->upstream.store = 1;
return NGX_CONF_OK;
}
@ -2599,6 +2644,10 @@ ngx_http_fastcgi_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}
if (flcf->upstream.store > 0 || flcf->upstream.store_lengths) {
return "is incompatible with \"fastcgi_store\"";
}
flcf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0,
&ngx_http_fastcgi_module);
if (flcf->upstream.cache == NULL) {

View File

@ -80,10 +80,6 @@ ngx_http_flv_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
if (r->zero_in_uri) {
return NGX_DECLINED;
}
rc = ngx_http_discard_request_body(r);
if (rc != NGX_OK) {

View File

@ -35,6 +35,7 @@ typedef struct {
ngx_radix_tree_t *tree;
ngx_rbtree_t rbtree;
ngx_rbtree_node_t sentinel;
ngx_array_t *proxies;
ngx_pool_t *pool;
ngx_pool_t *temp_pool;
} ngx_http_geo_conf_ctx_t;
@ -46,12 +47,16 @@ typedef struct {
ngx_http_geo_high_ranges_t *high;
} u;
ngx_array_t *proxies;
ngx_int_t index;
} ngx_http_geo_ctx_t;
static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r,
ngx_http_geo_ctx_t *ctx);
static in_addr_t ngx_http_geo_real_addr(ngx_http_request_t *r,
ngx_http_geo_ctx_t *ctx);
static char *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);
static char *ngx_http_geo_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
@ -64,6 +69,10 @@ static char *ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
ngx_str_t *value);
static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf,
ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value);
static char *ngx_http_geo_add_proxy(ngx_conf_t *cf,
ngx_http_geo_conf_ctx_t *ctx, ngx_cidr_t *cidr);
static ngx_int_t ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net,
ngx_cidr_t *cidr);
static ngx_command_t ngx_http_geo_commands[] = {
@ -167,6 +176,50 @@ ngx_http_geo_range_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
static in_addr_t
ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
{
u_char *p, *ip;
size_t len;
in_addr_t addr;
ngx_uint_t i, n;
ngx_in_cidr_t *proxies;
ngx_table_elt_t *xfwd;
addr = ngx_http_geo_real_addr(r, ctx);
xfwd = r->headers_in.x_forwarded_for;
if (xfwd == NULL || ctx->proxies == NULL) {
return addr;
}
proxies = ctx->proxies->elts;
n = ctx->proxies->nelts;
for (i = 0; i < n; i++) {
if ((addr & proxies[i].mask) == proxies[i].addr) {
len = xfwd->value.len;
ip = xfwd->value.data;
for (p = ip + len - 1; p > ip; p--) {
if (*p == ' ' || *p == ',') {
p++;
len -= p - ip;
ip = p;
break;
}
}
return ntohl(ngx_inet_addr(ip, len));
}
}
return addr;
}
static in_addr_t
ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
{
struct sockaddr_in *sin;
ngx_http_variable_value_t *v;
@ -259,6 +312,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ctx.high = NULL;
ctx.tree = NULL;
ctx.proxies = NULL;
ctx.pool = cf->pool;
save = *cf;
@ -271,6 +325,8 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
*cf = save;
geo->proxies = ctx.proxies;
if (ctx.high) {
for (i = 0; i < 0x10000; i++) {
@ -341,6 +397,7 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
{
char *rv;
ngx_str_t *value, file;
ngx_cidr_t cidr;
ngx_http_geo_conf_ctx_t *ctx;
ctx = cf->ctx;
@ -393,6 +450,16 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
rv = ngx_conf_parse(cf, &file);
goto done;
} else if (ngx_strcmp(value[0].data, "proxy") == 0) {
if (ngx_http_geo_cidr_value(cf, &value[1], &cidr) != NGX_OK) {
goto failed;
}
rv = ngx_http_geo_add_proxy(cf, ctx, &cidr);
goto done;
}
@ -522,7 +589,7 @@ ngx_http_geo_add_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
ngx_array_t *a;
ngx_http_geo_range_t *range;
for (n = start; n <= end; n += 0x10000) {
for (n = start; n <= end; n = (n + 0x10000) & 0xffff0000) {
h = n >> 16;
@ -803,33 +870,8 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
del = 0;
}
if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
cidr.u.in.addr = 0xffffffff;
cidr.u.in.mask = 0xffffffff;
} else {
rc = ngx_ptocidr(net, &cidr);
if (rc == NGX_ERROR) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid network \"%V\"", net);
return NGX_CONF_ERROR;
}
if (cidr.family != AF_INET) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"geo\" supports IPv4 only");
return NGX_CONF_ERROR;
}
if (rc == NGX_DONE) {
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"low address bits of %V are meaningless",
net);
}
cidr.u.in.addr = ntohl(cidr.u.in.addr);
cidr.u.in.mask = ntohl(cidr.u.in.mask);
if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
return NGX_CONF_ERROR;
}
if (del) {
@ -864,7 +906,7 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
/* rc == NGX_BUSY */
old = (ngx_http_variable_value_t *)
old = (ngx_http_variable_value_t *)
ngx_radix32tree_find(ctx->tree, cidr.u.in.addr & cidr.u.in.mask);
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
@ -927,3 +969,64 @@ ngx_http_geo_value(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
return val;
}
static char *
ngx_http_geo_add_proxy(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
ngx_cidr_t *cidr)
{
ngx_in_cidr_t *c;
if (ctx->proxies == NULL) {
ctx->proxies = ngx_array_create(ctx->pool, 4, sizeof(ngx_in_cidr_t));
if (ctx->proxies == NULL) {
return NGX_CONF_ERROR;
}
}
c = ngx_array_push(ctx->proxies);
if (c == NULL) {
return NGX_CONF_ERROR;
}
c->addr = cidr->u.in.addr;
c->mask = cidr->u.in.mask;
return NGX_CONF_OK;
}
static ngx_int_t
ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
{
ngx_int_t rc;
if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
cidr->u.in.addr = 0xffffffff;
cidr->u.in.mask = 0xffffffff;
return NGX_OK;
}
rc = ngx_ptocidr(net, cidr);
if (rc == NGX_ERROR) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net);
return NGX_ERROR;
}
if (cidr->family != AF_INET) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"geo\" supports IPv4 only");
return NGX_ERROR;
}
if (rc == NGX_DONE) {
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"low address bits of %V are meaningless", net);
}
cidr->u.in.addr = ntohl(cidr->u.in.addr);
cidr->u.in.mask = ntohl(cidr->u.in.mask);
return NGX_OK;
}

View File

@ -0,0 +1,428 @@
/*
* Copyright (C) Igor Sysoev
*/
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
#include <GeoIP.h>
#include <GeoIPCity.h>
typedef struct {
GeoIP *country;
GeoIP *city;
} ngx_http_geoip_conf_t;
typedef struct {
ngx_str_t *name;
uintptr_t data;
} ngx_http_geoip_var_t;
typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr);
static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_geoip_city_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_geoip_city_float_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static GeoIPRecord *ngx_http_geoip_get_city_record(ngx_http_request_t *r);
static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf);
static void *ngx_http_geoip_create_conf(ngx_conf_t *cf);
static char *ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static void ngx_http_geoip_cleanup(void *data);
static ngx_command_t ngx_http_geoip_commands[] = {
{ ngx_string("geoip_country"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
ngx_http_geoip_country,
NGX_HTTP_MAIN_CONF_OFFSET,
0,
NULL },
{ ngx_string("geoip_city"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
ngx_http_geoip_city,
NGX_HTTP_MAIN_CONF_OFFSET,
0,
NULL },
ngx_null_command
};
static ngx_http_module_t ngx_http_geoip_module_ctx = {
ngx_http_geoip_add_variables, /* preconfiguration */
NULL, /* postconfiguration */
ngx_http_geoip_create_conf, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
NULL, /* create location configuration */
NULL /* merge location configuration */
};
ngx_module_t ngx_http_geoip_module = {
NGX_MODULE_V1,
&ngx_http_geoip_module_ctx, /* module context */
ngx_http_geoip_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
static ngx_http_variable_t ngx_http_geoip_vars[] = {
{ ngx_string("geoip_country_code"), NULL,
ngx_http_geoip_country_variable,
(uintptr_t) GeoIP_country_code_by_ipnum, 0, 0 },
{ ngx_string("geoip_country_code3"), NULL,
ngx_http_geoip_country_variable,
(uintptr_t) GeoIP_country_code3_by_ipnum, 0, 0 },
{ ngx_string("geoip_country_name"), NULL,
ngx_http_geoip_country_variable,
(uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 },
{ ngx_string("geoip_city_continent_code"), NULL,
ngx_http_geoip_city_variable,
offsetof(GeoIPRecord, continent_code), 0, 0 },
{ ngx_string("geoip_city_country_code"), NULL,
ngx_http_geoip_city_variable,
offsetof(GeoIPRecord, country_code), 0, 0 },
{ ngx_string("geoip_city_country_code3"), NULL,
ngx_http_geoip_city_variable,
offsetof(GeoIPRecord, country_code3), 0, 0 },
{ ngx_string("geoip_city_country_name"), NULL,
ngx_http_geoip_city_variable,
offsetof(GeoIPRecord, country_name), 0, 0 },
{ ngx_string("geoip_region"), NULL,
ngx_http_geoip_city_variable,
offsetof(GeoIPRecord, region), 0, 0 },
{ ngx_string("geoip_city"), NULL,
ngx_http_geoip_city_variable,
offsetof(GeoIPRecord, city), 0, 0 },
{ ngx_string("geoip_postal_code"), NULL,
ngx_http_geoip_city_variable,
offsetof(GeoIPRecord, postal_code), 0, 0 },
{ ngx_string("geoip_latitude"), NULL,
ngx_http_geoip_city_float_variable,
offsetof(GeoIPRecord, latitude), 0, 0 },
{ ngx_string("geoip_longitude"), NULL,
ngx_http_geoip_city_float_variable,
offsetof(GeoIPRecord, longitude), 0, 0 },
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
};
static ngx_int_t
ngx_http_geoip_country_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
ngx_http_geoip_variable_handler_pt handler =
(ngx_http_geoip_variable_handler_pt) data;
u_long addr;
const char *val;
struct sockaddr_in *sin;
ngx_http_geoip_conf_t *gcf;
gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
if (gcf->country == NULL) {
goto not_found;
}
if (r->connection->sockaddr->sa_family != AF_INET) {
goto not_found;
}
sin = (struct sockaddr_in *) r->connection->sockaddr;
addr = ntohl(sin->sin_addr.s_addr);
val = handler(gcf->country, addr);
if (val == NULL) {
goto not_found;
}
v->len = ngx_strlen(val);
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
v->data = (u_char *) val;
return NGX_OK;
not_found:
v->not_found = 1;
return NGX_OK;
}
static ngx_int_t
ngx_http_geoip_city_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
char *val;
size_t len;
GeoIPRecord *gr;
gr = ngx_http_geoip_get_city_record(r);
if (gr == NULL) {
goto not_found;
}
val = *(char **) ((char *) gr + data);
if (val == NULL) {
goto no_value;
}
len = ngx_strlen(val);
v->data = ngx_pnalloc(r->pool, len);
if (v->data == NULL) {
GeoIPRecord_delete(gr);
return NGX_ERROR;
}
ngx_memcpy(v->data, val, len);
v->len = len;
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
GeoIPRecord_delete(gr);
return NGX_OK;
no_value:
GeoIPRecord_delete(gr);
not_found:
v->not_found = 1;
return NGX_OK;
}
static ngx_int_t
ngx_http_geoip_city_float_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
float val;
GeoIPRecord *gr;
gr = ngx_http_geoip_get_city_record(r);
if (gr == NULL) {
v->not_found = 1;
return NGX_OK;
}
v->data = ngx_pnalloc(r->pool, NGX_INT64_LEN + 5);
if (v->data == NULL) {
GeoIPRecord_delete(gr);
return NGX_ERROR;
}
val = *(float *) ((char *) gr + data);
v->len = ngx_sprintf(v->data, "%.4f", val) - v->data;
GeoIPRecord_delete(gr);
return NGX_OK;
}
static GeoIPRecord *
ngx_http_geoip_get_city_record(ngx_http_request_t *r)
{
u_long addr;
struct sockaddr_in *sin;
ngx_http_geoip_conf_t *gcf;
gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
if (gcf->city && r->connection->sockaddr->sa_family == AF_INET) {
sin = (struct sockaddr_in *) r->connection->sockaddr;
addr = ntohl(sin->sin_addr.s_addr);
return GeoIP_record_by_ipnum(gcf->city, addr);
}
return NULL;
}
static ngx_int_t
ngx_http_geoip_add_variables(ngx_conf_t *cf)
{
ngx_http_variable_t *var, *v;
for (v = ngx_http_geoip_vars; v->name.len; v++) {
var = ngx_http_add_variable(cf, &v->name, v->flags);
if (var == NULL) {
return NGX_ERROR;
}
var->get_handler = v->get_handler;
var->data = v->data;
}
return NGX_OK;
}
static void *
ngx_http_geoip_create_conf(ngx_conf_t *cf)
{
ngx_pool_cleanup_t *cln;
ngx_http_geoip_conf_t *conf;
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_geoip_conf_t));
if (conf == NULL) {
return NULL;
}
cln = ngx_pool_cleanup_add(cf->pool, 0);
if (cln == NULL) {
return NULL;
}
cln->handler = ngx_http_geoip_cleanup;
cln->data = conf;
return conf;
}
static char *
ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_geoip_conf_t *gcf = conf;
ngx_str_t *value;
if (gcf->country) {
return "is duplicate";
}
value = cf->args->elts;
gcf->country = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
if (gcf->country == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"GeoIO_open(\"%V\") failed", &value[1]);
return NGX_CONF_ERROR;
}
switch (gcf->country->databaseType) {
case GEOIP_COUNTRY_EDITION:
case GEOIP_PROXY_EDITION:
case GEOIP_NETSPEED_EDITION:
return NGX_CONF_OK;
default:
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid GeoIP database \"%V\" type:%d",
&value[1], gcf->country->databaseType);
return NGX_CONF_ERROR;
}
}
static char *
ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_geoip_conf_t *gcf = conf;
ngx_str_t *value;
if (gcf->city) {
return "is duplicate";
}
value = cf->args->elts;
gcf->city = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
if (gcf->city == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"GeoIO_open(\"%V\") failed", &value[1]);
return NGX_CONF_ERROR;
}
switch (gcf->city->databaseType) {
case GEOIP_CITY_EDITION_REV0:
case GEOIP_CITY_EDITION_REV1:
return NGX_CONF_OK;
default:
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid GeoIP City database \"%V\" type:%d",
&value[1], gcf->city->databaseType);
return NGX_CONF_ERROR;
}
}
static void
ngx_http_geoip_cleanup(void *data)
{
ngx_http_geoip_conf_t *gcf = data;
if (gcf->country) {
GeoIP_delete(gcf->country);
}
if (gcf->city) {
GeoIP_delete(gcf->city);
}
}

View File

@ -246,17 +246,27 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
|| (r->headers_out.status != NGX_HTTP_OK
&& r->headers_out.status != NGX_HTTP_FORBIDDEN
&& r->headers_out.status != NGX_HTTP_NOT_FOUND)
|| r->header_only
|| (r->headers_out.content_encoding
&& r->headers_out.content_encoding->value.len)
|| (r->headers_out.content_length_n != -1
&& r->headers_out.content_length_n < conf->min_length)
|| ngx_http_test_content_type(r, &conf->types) == NULL
|| ngx_http_gzip_ok(r) != NGX_OK)
|| r->header_only)
{
return ngx_http_next_header_filter(r);
}
r->gzip_vary = 1;
if (!r->gzip_tested) {
if (ngx_http_gzip_ok(r) != NGX_OK) {
return ngx_http_next_header_filter(r);
}
} else if (!r->gzip_ok) {
return ngx_http_next_header_filter(r);
}
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gzip_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
@ -1069,7 +1079,7 @@ ngx_http_gzip_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_gzip_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*

View File

@ -89,13 +89,17 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
if (r->zero_in_uri) {
gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module);
if (!gzcf->enable) {
return NGX_DECLINED;
}
gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module);
rc = ngx_http_gzip_ok(r);
if (!gzcf->enable || ngx_http_gzip_ok(r) != NGX_OK) {
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (!clcf->gzip_vary && rc != NGX_OK) {
return NGX_DECLINED;
}
@ -116,8 +120,6 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
"http filename: \"%s\"", path.data);
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
of.directio = clcf->directio;
@ -157,6 +159,12 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
r->gzip_vary = 1;
if (rc != NGX_OK) {
return NGX_DECLINED;
}
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", of.fd);
if (of.is_dir) {
@ -167,7 +175,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
#if !(NGX_WIN32) /* the not regular files are probably Unix specific */
if (!of.is_file) {
ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
ngx_log_error(NGX_LOG_CRIT, log, 0,
"\"%s\" is not a regular file", path.data);
return NGX_HTTP_NOT_FOUND;
@ -251,7 +259,7 @@ ngx_http_gzip_static_create_conf(ngx_conf_t *cf)
conf = ngx_palloc(cf->pool, sizeof(ngx_http_gzip_static_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
conf->enable = NGX_CONF_UNSET;

View File

@ -291,7 +291,7 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
ngx_http_time(expires->value.data, expires_time);
if (conf->expires_time < 0) {
if (conf->expires_time < 0 || max_age < 0) {
cc->value.len = sizeof("no-cache") - 1;
cc->value.data = (u_char *) "no-cache";
@ -421,7 +421,7 @@ ngx_http_headers_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_headers_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*

View File

@ -40,6 +40,11 @@ typedef struct {
ngx_uint_t height;
ngx_int_t jpeg_quality;
ngx_flag_t transparency;
ngx_http_complex_value_t *wcv;
ngx_http_complex_value_t *hcv;
size_t buffer_size;
} ngx_http_image_filter_conf_t;
@ -53,8 +58,12 @@ typedef struct {
ngx_uint_t width;
ngx_uint_t height;
ngx_uint_t max_width;
ngx_uint_t max_height;
ngx_uint_t phase;
ngx_uint_t type;
ngx_uint_t force;
} ngx_http_image_filter_ctx_t;
@ -80,6 +89,9 @@ static gdImagePtr ngx_http_image_new(ngx_http_request_t *r, int w, int h,
static u_char *ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type,
gdImagePtr img, int *size);
static void ngx_http_image_cleanup(void *data);
static ngx_uint_t ngx_http_image_filter_get_value(ngx_http_request_t *r,
ngx_http_complex_value_t *cv, ngx_uint_t v);
static ngx_uint_t ngx_http_image_filter_value(ngx_str_t *value);
static void *ngx_http_image_filter_create_conf(ngx_conf_t *cf);
@ -106,6 +118,13 @@ static ngx_command_t ngx_http_image_filter_commands[] = {
offsetof(ngx_http_image_filter_conf_t, jpeg_quality),
NULL },
{ ngx_string("image_filter_transparency"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_image_filter_conf_t, transparency),
NULL },
{ ngx_string("image_filter_buffer"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_size_slot,
@ -383,11 +402,12 @@ ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in)
return NGX_HTTP_IMAGE_JPEG;
} else if (p[0] == 'G' && p[1] == 'I' && p[2] == 'F' && p[3] == '8'
&& p[4] == '9' && p[5] == 'a')
&& p[5] == 'a')
{
/* GIF */
return NGX_HTTP_IMAGE_GIF;
if (p[4] == '9' || p[4] == '7') {
/* GIF */
return NGX_HTTP_IMAGE_GIF;
}
} else if (p[0] == 0x89 && p[1] == 'P' && p[2] == 'N' && p[3] == 'G'
&& p[4] == 0x0d && p[5] == 0x0a && p[6] == 0x1a && p[7] == 0x0a)
@ -453,7 +473,6 @@ ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in)
static ngx_buf_t *
ngx_http_image_process(ngx_http_request_t *r)
{
ngx_buf_t *b;
ngx_int_t rc;
ngx_http_image_filter_ctx_t *ctx;
ngx_http_image_filter_conf_t *conf;
@ -467,20 +486,29 @@ ngx_http_image_process(ngx_http_request_t *r)
conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
if (conf->filter == NGX_HTTP_IMAGE_SIZE) {
b = ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL);
} else if (rc == NGX_OK
&& ctx->width <= conf->width
&& ctx->height <= conf->height)
{
b = ngx_http_image_asis(r, ctx);
} else {
b = ngx_http_image_resize(r, ctx);
return ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL);
}
return b;
ctx->max_width = ngx_http_image_filter_get_value(r, conf->wcv, conf->width);
if (ctx->max_width == 0) {
return NULL;
}
ctx->max_height = ngx_http_image_filter_get_value(r, conf->hcv,
conf->height);
if (ctx->max_height == 0) {
return NULL;
}
if (rc == NGX_OK
&& ctx->width <= ctx->max_width
&& ctx->height <= ctx->max_height
&& !ctx->force)
{
return ngx_http_image_asis(r, ctx);
}
return ngx_http_image_resize(r, ctx);
}
@ -575,6 +603,7 @@ static ngx_int_t
ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
{
u_char *p, *last;
size_t len, app;
ngx_uint_t width, height;
p = ctx->image;
@ -585,26 +614,38 @@ ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
p += 2;
last = ctx->image + ctx->length - 10;
width = 0;
height = 0;
app = 0;
while (p < last) {
if (p[0] == 0xff && p[1] != 0xff) {
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"JPEG: %02xd %02xd", *p, *(p + 1));
"JPEG: %02xd %02xd", p[0], p[1]);
p++;
if (*p == 0xc0 || *p == 0xc1 || *p == 0xc2 || *p == 0xc3
|| *p == 0xc9 || *p == 0xca || *p == 0xcb)
if ((*p == 0xc0 || *p == 0xc1 || *p == 0xc2 || *p == 0xc3
|| *p == 0xc9 || *p == 0xca || *p == 0xcb)
&& (width == 0 || height == 0))
{
goto found;
width = p[6] * 256 + p[7];
height = p[4] * 256 + p[5];
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"JPEG: %02xd %02xd", p[1], p[2]);
p += p[1] * 256 + p[2];
len = p[1] * 256 + p[2];
if (*p >= 0xe1 && *p <= 0xef) {
/* application data, e.g., EXIF, Adobe XMP, etc. */
app += len;
}
p += len;
continue;
}
@ -612,12 +653,16 @@ ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
p++;
}
return NGX_DECLINED;
if (width == 0 || height == 0) {
return NGX_DECLINED;
}
found:
width = p[6] * 256 + p[7];
height = p[4] * 256 + p[5];
if (ctx->length / 20 < app) {
/* force conversion if application data consume more than 5% */
ctx->force = 1;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"app data size: %uz", app);
}
break;
@ -661,8 +706,9 @@ ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
static ngx_buf_t *
ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
{
int sx, sy, dx, dy, ox, oy,
colors, transparent, size;
int sx, sy, dx, dy, ox, oy, size,
colors, palette, transparent,
red, green, blue;
u_char *out;
ngx_buf_t *b;
ngx_uint_t resize;
@ -681,29 +727,54 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
if ((ngx_uint_t) sx <= conf->width && (ngx_uint_t) sy <= conf->height) {
if (!ctx->force
&& (ngx_uint_t) sx <= ctx->max_width
&& (ngx_uint_t) sy <= ctx->max_height)
{
gdImageDestroy(src);
return ngx_http_image_asis(r, ctx);
}
colors = gdImageColorsTotal(src);
transparent = gdImageGetTransparent(src);
if (colors && conf->transparency) {
transparent = gdImageGetTransparent(src);
if (transparent != -1) {
palette = colors;
red = gdImageRed(src, transparent);
green = gdImageGreen(src, transparent);
blue = gdImageBlue(src, transparent);
goto transparent;
}
}
palette = 0;
transparent = -1;
red = 0;
green = 0;
blue = 0;
transparent:
gdImageColorTransparent(src, -1);
dx = sx;
dy = sy;
if (conf->filter == NGX_HTTP_IMAGE_RESIZE) {
if ((ngx_uint_t) dx > conf->width) {
dy = dy * conf->width / dx;
if ((ngx_uint_t) dx > ctx->max_width) {
dy = dy * ctx->max_width / dx;
dy = dy ? dy : 1;
dx = conf->width;
dx = ctx->max_width;
}
if ((ngx_uint_t) dy > conf->height) {
dx = dx * conf->height / dy;
if ((ngx_uint_t) dy > ctx->max_height) {
dx = dx * ctx->max_height / dy;
dx = dx ? dx : 1;
dy = conf->height;
dy = ctx->max_height;
}
resize = 1;
@ -712,34 +783,44 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
resize = 0;
if ((ngx_uint_t) (dx * 100 / dy) < conf->width * 100 / conf->height) {
if ((ngx_uint_t) dx > conf->width) {
dy = dy * conf->width / dx;
if ((ngx_uint_t) (dx * 100 / dy)
< ctx->max_width * 100 / ctx->max_height)
{
if ((ngx_uint_t) dx > ctx->max_width) {
dy = dy * ctx->max_width / dx;
dy = dy ? dy : 1;
dx = conf->width;
dx = ctx->max_width;
resize = 1;
}
} else {
if ((ngx_uint_t) dy > conf->height) {
dx = dx * conf->height / dy;
if ((ngx_uint_t) dy > ctx->max_height) {
dx = dx * ctx->max_height / dy;
dx = dx ? dx : 1;
dy = conf->height;
dy = ctx->max_height;
resize = 1;
}
}
}
if (resize) {
dst = ngx_http_image_new(r, dx, dy, colors);
dst = ngx_http_image_new(r, dx, dy, palette);
if (dst == NULL) {
gdImageDestroy(src);
return NULL;
}
if (colors == 0) {
gdImageSaveAlpha(dst, 1);
gdImageAlphaBlending(dst, 0);
}
gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy);
if (colors) {
gdImageTrueColorToPalette(dst, 1, 256);
}
gdImageDestroy(src);
} else {
@ -750,15 +831,15 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
src = dst;
if ((ngx_uint_t) dx > conf->width) {
ox = dx - conf->width;
if ((ngx_uint_t) dx > ctx->max_width) {
ox = dx - ctx->max_width;
} else {
ox = 0;
}
if ((ngx_uint_t) dy > conf->height) {
oy = dy - conf->height;
if ((ngx_uint_t) dy > ctx->max_height) {
oy = dy - ctx->max_height;
} else {
oy = 0;
@ -780,13 +861,24 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
"image crop: %d x %d @ %d x %d",
dx, dy, ox, oy);
if (colors == 0) {
gdImageSaveAlpha(dst, 1);
gdImageAlphaBlending(dst, 0);
}
gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy);
if (colors) {
gdImageTrueColorToPalette(dst, 1, 256);
}
gdImageDestroy(src);
}
}
gdImageColorTransparent(dst, transparent);
if (transparent != -1 && colors) {
gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
}
out = ngx_http_image_out(r, ctx->type, dst, &size);
@ -940,6 +1032,43 @@ ngx_http_image_cleanup(void *data)
}
static ngx_uint_t
ngx_http_image_filter_get_value(ngx_http_request_t *r,
ngx_http_complex_value_t *cv, ngx_uint_t v)
{
ngx_str_t val;
if (cv == NULL) {
return v;
}
if (ngx_http_complex_value(r, cv, &val) != NGX_OK) {
return 0;
}
return ngx_http_image_filter_value(&val);
}
static ngx_uint_t
ngx_http_image_filter_value(ngx_str_t *value)
{
ngx_int_t n;
if (value->len == 1 && value->data[0] == '-') {
return (ngx_uint_t) -1;
}
n = ngx_atoi(value->data, value->len);
if (n > 0) {
return (ngx_uint_t) n;
}
return 0;
}
static void *
ngx_http_image_filter_create_conf(ngx_conf_t *cf)
{
@ -947,11 +1076,12 @@ ngx_http_image_filter_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_image_filter_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
conf->filter = NGX_CONF_UNSET_UINT;
conf->jpeg_quality = NGX_CONF_UNSET;
conf->transparency = NGX_CONF_UNSET;
conf->buffer_size = NGX_CONF_UNSET_SIZE;
return conf;
@ -973,12 +1103,16 @@ ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
conf->filter = prev->filter;
conf->width = prev->width;
conf->height = prev->height;
conf->wcv = prev->wcv;
conf->hcv = prev->hcv;
}
}
/* 75 is libjpeg default quality */
ngx_conf_merge_value(conf->jpeg_quality, prev->jpeg_quality, 75);
ngx_conf_merge_value(conf->transparency, prev->transparency, 1);
ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
1 * 1024 * 1024);
@ -991,9 +1125,11 @@ ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_image_filter_conf_t *imcf = conf;
ngx_str_t *value;
ngx_int_t n;
ngx_uint_t i;
ngx_str_t *value;
ngx_int_t n;
ngx_uint_t i;
ngx_http_complex_value_t cv;
ngx_http_compile_complex_value_t ccv;
value = cf->args->elts;
@ -1026,32 +1162,60 @@ ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
goto failed;
}
i++;
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
if (value[i].len == 1 && value[i].data[0] == '-') {
imcf->width = (ngx_uint_t) -1;
ccv.cf = cf;
ccv.value = &value[++i];
ccv.complex_value = &cv;
} else {
n = ngx_atoi(value[i].data, value[i].len);
if (n == NGX_ERROR) {
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
return NGX_CONF_ERROR;
}
if (cv.lengths == NULL) {
n = ngx_http_image_filter_value(&value[i]);
if (n == 0) {
goto failed;
}
imcf->width = (ngx_uint_t) n;
}
i++;
if (value[i].len == 1 && value[i].data[0] == '-') {
imcf->height = (ngx_uint_t) -1;
} else {
n = ngx_atoi(value[i].data, value[i].len);
if (n == NGX_ERROR) {
imcf->wcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
if (imcf->wcv == NULL) {
return NGX_CONF_ERROR;
}
*imcf->wcv = cv;
}
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
ccv.cf = cf;
ccv.value = &value[++i];
ccv.complex_value = &cv;
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
return NGX_CONF_ERROR;
}
if (cv.lengths == NULL) {
n = ngx_http_image_filter_value(&value[i]);
if (n == 0) {
goto failed;
}
imcf->height = (ngx_uint_t) n;
} else {
imcf->hcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
if (imcf->hcv == NULL) {
return NGX_CONF_ERROR;
}
*imcf->hcv = cv;
}
return NGX_CONF_OK;

View File

@ -116,10 +116,6 @@ ngx_http_index_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
if (r->zero_in_uri) {
return NGX_DECLINED;
}
ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
@ -222,7 +218,10 @@ ngx_http_index_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
if (of.err == NGX_ENOTDIR || of.err == NGX_EACCES) {
if (of.err == NGX_ENOTDIR
|| of.err == NGX_ENAMETOOLONG
|| of.err == NGX_EACCES)
{
return ngx_http_index_error(r, clcf, path.data, of.err);
}
@ -366,7 +365,7 @@ ngx_http_index_create_loc_conf(ngx_conf_t *cf)
conf = ngx_palloc(cf->pool, sizeof(ngx_http_index_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
conf->indices = NULL;

View File

@ -42,7 +42,10 @@ typedef struct {
ngx_shm_zone_t *shm_zone;
/* integer value, 1 corresponds to 0.001 r/s */
ngx_uint_t burst;
ngx_uint_t nodelay;/* unsigned nodelay:1 */
ngx_uint_t limit_log_level;
ngx_uint_t delay_log_level;
ngx_uint_t nodelay; /* unsigned nodelay:1 */
} ngx_http_limit_req_conf_t;
@ -62,6 +65,15 @@ static char *ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd,
static ngx_int_t ngx_http_limit_req_init(ngx_conf_t *cf);
static ngx_conf_enum_t ngx_http_limit_req_log_levels[] = {
{ ngx_string("info"), NGX_LOG_INFO },
{ ngx_string("notice"), NGX_LOG_NOTICE },
{ ngx_string("warn"), NGX_LOG_WARN },
{ ngx_string("error"), NGX_LOG_ERR },
{ ngx_null_string, 0 }
};
static ngx_command_t ngx_http_limit_req_commands[] = {
{ ngx_string("limit_req_zone"),
@ -78,6 +90,13 @@ static ngx_command_t ngx_http_limit_req_commands[] = {
0,
NULL },
{ ngx_string("limit_req_log_level"),
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_limit_req_conf_t, limit_log_level),
&ngx_http_limit_req_log_levels },
ngx_null_command
};
@ -181,12 +200,12 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
}
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"limit_req: %i %ui.%03ui", rc, excess / 1000, excess % 1000);
"limit_req: %i %ui.%03ui", rc, excess / 1000, excess % 1000);
if (rc == NGX_BUSY) {
ngx_shmtx_unlock(&ctx->shpool->mutex);
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
ngx_log_error(lrcf->limit_log_level, r->connection->log, 0,
"limiting requests, excess: %ui.%03ui by zone \"%V\"",
excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name);
@ -200,7 +219,7 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
ngx_log_error(lrcf->delay_log_level, r->connection->log, 0,
"delaying request, excess: %ui.%03ui, by zone \"%V\"",
excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name);
@ -263,8 +282,23 @@ done:
static void
ngx_http_limit_req_delay(ngx_http_request_t *r)
{
ngx_event_t *wev;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"limit_req delay");
"limit_req delay");
wev = r->connection->write;
if (!wev->timedout) {
if (ngx_handle_write_event(wev, 0) != NGX_OK) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
}
return;
}
wev->timedout = 0;
if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
@ -368,15 +402,16 @@ ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf, ngx_uint_t hash,
excess = 0;
}
if ((ngx_uint_t) excess > lrcf->burst) {
*lrp = lr;
return NGX_BUSY;
}
lr->excess = excess;
lr->last = now;
*lrp = lr;
if ((ngx_uint_t) excess > lrcf->burst) {
return NGX_BUSY;
}
if (excess) {
return NGX_AGAIN;
}
@ -522,7 +557,7 @@ ngx_http_limit_req_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_req_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*
@ -533,6 +568,8 @@ ngx_http_limit_req_create_conf(ngx_conf_t *cf)
* conf->nodelay = 0;
*/
conf->limit_log_level = NGX_CONF_UNSET_UINT;
return conf;
}
@ -547,6 +584,12 @@ ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent, void *child)
*conf = *prev;
}
ngx_conf_merge_uint_value(conf->limit_log_level, prev->limit_log_level,
NGX_LOG_ERR);
conf->delay_log_level = (conf->limit_log_level == NGX_LOG_INFO) ?
NGX_LOG_INFO : conf->limit_log_level + 1;
return NGX_CONF_OK;
}

View File

@ -33,6 +33,7 @@ typedef struct {
typedef struct {
ngx_shm_zone_t *shm_zone;
ngx_uint_t conn;
ngx_uint_t log_level;
} ngx_http_limit_zone_conf_t;
@ -48,6 +49,15 @@ static char *ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd,
static ngx_int_t ngx_http_limit_zone_init(ngx_conf_t *cf);
static ngx_conf_enum_t ngx_http_limit_conn_log_levels[] = {
{ ngx_string("info"), NGX_LOG_INFO },
{ ngx_string("notice"), NGX_LOG_NOTICE },
{ ngx_string("warn"), NGX_LOG_WARN },
{ ngx_string("error"), NGX_LOG_ERR },
{ ngx_null_string, 0 }
};
static ngx_command_t ngx_http_limit_zone_commands[] = {
{ ngx_string("limit_zone"),
@ -64,6 +74,13 @@ static ngx_command_t ngx_http_limit_zone_commands[] = {
0,
NULL },
{ ngx_string("limit_conn_log_level"),
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_limit_zone_conf_t, log_level),
&ngx_http_limit_conn_log_levels },
ngx_null_command
};
@ -189,7 +206,7 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r)
ngx_shmtx_unlock(&shpool->mutex);
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
ngx_log_error(lzcf->log_level, r->connection->log, 0,
"limiting connections by zone \"%V\"",
&lzcf->shm_zone->shm.name);
@ -381,7 +398,7 @@ ngx_http_limit_zone_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_zone_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*
@ -391,6 +408,8 @@ ngx_http_limit_zone_create_conf(ngx_conf_t *cf)
* conf->conn = 0;
*/
conf->log_level = NGX_CONF_UNSET_UINT;
return conf;
}
@ -405,6 +424,8 @@ ngx_http_limit_zone_merge_conf(ngx_conf_t *cf, void *parent, void *child)
*conf = *prev;
}
ngx_conf_merge_uint_value(conf->log_level, prev->log_level, NGX_LOG_ERR);
return NGX_CONF_OK;
}

View File

@ -542,8 +542,25 @@ ngx_http_log_request_time(ngx_http_request_t *r, u_char *buf,
static u_char *
ngx_http_log_status(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
{
return ngx_sprintf(buf, "%ui",
r->err_status ? r->err_status : r->headers_out.status);
ngx_uint_t status;
if (r->err_status) {
status = r->err_status;
} else if (r->headers_out.status) {
status = r->headers_out.status;
} else if (r->http_version == NGX_HTTP_VERSION_9) {
*buf++ = '0';
*buf++ = '0';
*buf++ = '9';
return buf;
} else {
status = 0;
}
return ngx_sprintf(buf, "%ui", status);
}
@ -676,7 +693,7 @@ ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
/* find the number of the characters to be escaped */
n = 0;
n = 0;
for (i = 0; i < size; i++) {
if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
@ -714,18 +731,18 @@ ngx_http_log_create_main_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_main_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
if (ngx_array_init(&conf->formats, cf->pool, 4, sizeof(ngx_http_log_fmt_t))
!= NGX_OK)
{
return NGX_CONF_ERROR;
return NULL;
}
fmt = ngx_array_push(&conf->formats);
if (fmt == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
fmt->name.len = sizeof("combined") - 1;
@ -735,7 +752,7 @@ ngx_http_log_create_main_conf(ngx_conf_t *cf)
fmt->ops = ngx_array_create(cf->pool, 16, sizeof(ngx_http_log_op_t));
if (fmt->ops == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
return conf;
@ -749,7 +766,7 @@ ngx_http_log_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
conf->open_file_cache = NGX_CONF_UNSET_PTR;
@ -837,7 +854,13 @@ ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (ngx_strcmp(value[1].data, "off") == 0) {
llcf->off = 1;
return NGX_CONF_OK;
if (cf->args->nelts == 2) {
return NGX_CONF_OK;
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid parameter \"%V\"", &value[2]);
return NGX_CONF_ERROR;
}
if (llcf->logs == NULL) {

View File

@ -160,7 +160,7 @@ ngx_http_map_create_conf(ngx_conf_t *cf)
mcf = ngx_palloc(cf->pool, sizeof(ngx_http_map_conf_t));
if (mcf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
mcf->hash_max_size = NGX_CONF_UNSET_UINT;
@ -337,7 +337,7 @@ ngx_http_map_cmp_dns_wildcards(const void *one, const void *two)
first = (ngx_hash_key_t *) one;
second = (ngx_hash_key_t *) two;
return ngx_strcmp(first->key.data, second->key.data);
return ngx_dns_strcmp(first->key.data, second->key.data);
}

View File

@ -176,24 +176,19 @@ ngx_http_memcached_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
if (u == NULL) {
if (ngx_http_upstream_create(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
u = r->upstream;
u->schema.len = sizeof("memcached://") - 1;
u->schema.data = (u_char *) "memcached://";
u->peer.log = r->connection->log;
u->peer.log_error = NGX_ERROR_ERR;
#if (NGX_THREADS)
u->peer.lock = &r->connection->lock;
#endif
u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module;
mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
u->conf = &mlcf->upstream;
u->create_request = ngx_http_memcached_create_request;
@ -202,8 +197,6 @@ ngx_http_memcached_handler(ngx_http_request_t *r)
u->abort_request = ngx_http_memcached_abort_request;
u->finalize_request = ngx_http_memcached_finalize_request;
r->upstream = u;
ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t));
if (ctx == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
@ -430,15 +423,20 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
if (ngx_strncmp(b->last,
ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END - ctx->rest,
ctx->rest)
bytes)
!= 0)
{
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
"memcached sent invalid trailer");
u->length = 0;
ctx->rest = 0;
return NGX_OK;
}
u->length = 0;
ctx->rest = 0;
u->length -= bytes;
ctx->rest -= bytes;
return NGX_OK;
}
@ -513,7 +511,7 @@ ngx_http_memcached_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_memcached_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*

View File

@ -88,6 +88,11 @@ ngx_http_not_modified_header_filter(ngx_http_request_t *r)
ngx_http_clear_content_length(r);
ngx_http_clear_accept_ranges(r);
if (r->headers_out.content_encoding) {
r->headers_out.content_encoding->hash = 0;
r->headers_out.content_encoding = NULL;
}
return ngx_http_next_header_filter(r);
}

View File

@ -167,6 +167,7 @@ static ngx_conf_bitmask_t ngx_http_proxy_next_upstream_masks[] = {
{ ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
{ ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 },
{ ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
{ ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
{ ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
{ ngx_null_string, 0 }
};
@ -356,6 +357,13 @@ static ngx_command_t ngx_http_proxy_commands[] = {
0,
&ngx_http_proxy_module },
{ ngx_string("proxy_no_cache"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_no_cache_set_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_proxy_loc_conf_t, upstream.no_cache),
NULL },
{ ngx_string("proxy_cache_valid"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_file_cache_valid_set_slot,
@ -529,7 +537,7 @@ static ngx_keyval_t ngx_http_proxy_cache_headers[] = {
{ ngx_string("Expect"), ngx_string("") },
{ ngx_string("If-Modified-Since"), ngx_string("") },
{ ngx_string("If-Unmodified-Since"), ngx_string("") },
{ ngx_string("If-Match-None"), ngx_string("") },
{ ngx_string("If-None-Match"), ngx_string("") },
{ ngx_string("If-Match"), ngx_string("") },
{ ngx_string("Range"), ngx_string("") },
{ ngx_string("If-Range"), ngx_string("") },
@ -589,13 +597,10 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
ngx_http_proxy_ctx_t *ctx;
ngx_http_proxy_loc_conf_t *plcf;
u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
if (u == NULL) {
if (ngx_http_upstream_create(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
r->upstream = u;
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
@ -605,6 +610,8 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
u = r->upstream;
if (plcf->proxy_lengths == 0) {
ctx->vars = plcf->vars;
u->schema = plcf->vars.schema;
@ -618,12 +625,6 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
}
}
u->peer.log = r->connection->log;
u->peer.log_error = NGX_ERROR_ERR;
#if (NGX_THREADS)
u->peer.lock = &r->connection->lock;
#endif
u->output.tag = (ngx_buf_tag_t) &ngx_http_proxy_module;
u->conf = &plcf->upstream;
@ -636,6 +637,7 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
u->process_header = ngx_http_proxy_process_status_line;
u->abort_request = ngx_http_proxy_abort_request;
u->finalize_request = ngx_http_proxy_finalize_request;
r->state = 0;
if (plcf->redirects) {
u->rewrite_redirect = ngx_http_proxy_rewrite_redirect;
@ -723,17 +725,22 @@ ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx,
return NGX_ERROR;
}
if (url.uri.len && url.uri.data[0] == '?') {
p = ngx_pnalloc(r->pool, url.uri.len + 1);
if (p == NULL) {
return NGX_ERROR;
if (url.uri.len) {
if (url.uri.data[0] == '?') {
p = ngx_pnalloc(r->pool, url.uri.len + 1);
if (p == NULL) {
return NGX_ERROR;
}
*p++ = '/';
ngx_memcpy(p, url.uri.data, url.uri.len);
url.uri.len++;
url.uri.data = p - 1;
}
*p++ = '/';
ngx_memcpy(p, url.uri.data, url.uri.len);
url.uri.len++;
url.uri.data = p - 1;
} else {
url.uri = r->unparsed_uri;
}
ctx->vars.key_start = u->schema;
@ -1192,6 +1199,7 @@ ngx_http_proxy_reinit_request(ngx_http_request_t *r)
ctx->status_end = NULL;
r->upstream->process_header = ngx_http_proxy_process_status_line;
r->state = 0;
return NGX_OK;
}
@ -1224,7 +1232,6 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
if (r->cache) {
r->http_version = NGX_HTTP_VERSION_9;
u->headers_in.status_n = NGX_HTTP_OK;
return NGX_OK;
}
@ -1240,7 +1247,6 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
#endif
r->http_version = NGX_HTTP_VERSION_9;
u->headers_in.status_n = NGX_HTTP_OK;
u->state->status = NGX_HTTP_OK;
return NGX_OK;
@ -1883,7 +1889,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*
@ -1909,7 +1915,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
* conf->body_set_len = NULL;
* conf->body_set = NULL;
* conf->body_source = { 0, NULL };
* conf->rewrite_locations = NULL;
* conf->redirects = NULL;
*/
conf->upstream.store = NGX_CONF_UNSET;
@ -1934,6 +1940,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
#if (NGX_HTTP_CACHE)
conf->upstream.cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
#endif
@ -1973,7 +1980,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
if (conf->upstream.store != 0) {
ngx_conf_merge_value(conf->upstream.store,
prev->upstream.store, 0);
prev->upstream.store, 0);
if (conf->upstream.store_lengths == NULL) {
conf->upstream.store_lengths = prev->upstream.store_lengths;
@ -2158,6 +2165,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|NGX_HTTP_UPSTREAM_FT_OFF;
}
ngx_conf_merge_ptr_value(conf->upstream.no_cache,
prev->upstream.no_cache, NULL);
ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
prev->upstream.cache_valid, NULL);
@ -2341,7 +2351,12 @@ ngx_http_proxy_merge_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf,
conf->headers_source = prev->headers_source;
}
if (conf->headers_set_hash.buckets) {
if (conf->headers_set_hash.buckets
#if (NGX_HTTP_CACHE)
&& ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL))
#endif
)
{
return NGX_OK;
}
@ -2586,6 +2601,12 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = ngx_http_proxy_handler;
if (clcf->name.data[clcf->name.len - 1] == '/') {
clcf->auto_redirect = 1;
}
value = cf->args->elts;
url = &value[1];
@ -2614,8 +2635,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
#endif
clcf->handler = ngx_http_proxy_handler;
return NGX_CONF_OK;
}
@ -2662,8 +2681,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_http_proxy_set_vars(&u, &plcf->vars);
clcf->handler = ngx_http_proxy_handler;
plcf->location = clcf->name;
if (clcf->named
@ -2687,10 +2704,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
plcf->url = *url;
if (clcf->name.data[clcf->name.len - 1] == '/') {
clcf->auto_redirect = 1;
}
return NGX_CONF_OK;
}
@ -2747,9 +2760,16 @@ ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
if (ngx_strcmp(value[1].data, "default") == 0) {
if (plcf->proxy_lengths) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"proxy_redirect default\" may not be used "
"with \"proxy_pass\" directive with variables");
return NGX_CONF_ERROR;
}
if (plcf->url.data == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"proxy_rewrite_location default\" must go "
"\"proxy_redirect default\" must go "
"after the \"proxy_pass\" directive");
return NGX_CONF_ERROR;
}
@ -2809,20 +2829,31 @@ ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_str_t *value;
ngx_http_script_compile_t sc;
if (plcf->upstream.store != NGX_CONF_UNSET || plcf->upstream.store_lengths)
if (plcf->upstream.store != NGX_CONF_UNSET
|| plcf->upstream.store_lengths)
{
return "is duplicate";
}
value = cf->args->elts;
if (ngx_strcmp(value[1].data, "on") == 0) {
plcf->upstream.store = 1;
if (ngx_strcmp(value[1].data, "off") == 0) {
plcf->upstream.store = 0;
return NGX_CONF_OK;
}
if (ngx_strcmp(value[1].data, "off") == 0) {
plcf->upstream.store = 0;
#if (NGX_HTTP_CACHE)
if (plcf->upstream.cache != NGX_CONF_UNSET_PTR
&& plcf->upstream.cache != NULL)
{
return "is incompatible with \"proxy_cache\"";
}
#endif
if (ngx_strcmp(value[1].data, "on") == 0) {
plcf->upstream.store = 1;
return NGX_CONF_OK;
}
@ -2867,6 +2898,10 @@ ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}
if (plcf->upstream.store > 0 || plcf->upstream.store_lengths) {
return "is incompatible with \"proxy_store\"";
}
plcf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0,
&ngx_http_proxy_module);
if (plcf->upstream.cache == NULL) {

View File

@ -86,10 +86,6 @@ ngx_http_random_index_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
if (r->zero_in_uri) {
return NGX_DECLINED;
}
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) {
return NGX_DECLINED;
}
@ -175,7 +171,7 @@ ngx_http_random_index_handler(ngx_http_request_t *r)
len = ngx_de_namelen(&dir);
if (!dir.valid_type) {
if (dir.type == 0 || ngx_de_is_link(&dir)) {
/* 1 byte for '/' and 1 byte for terminating '\0' */
@ -280,7 +276,7 @@ ngx_http_random_index_create_loc_conf(ngx_conf_t *cf)
conf = ngx_palloc(cf->pool, sizeof(ngx_http_random_index_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
conf->enable = NGX_CONF_UNSET;

View File

@ -360,7 +360,7 @@ ngx_http_realip_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_realip_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*

View File

@ -124,18 +124,27 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
len = r->headers_in.referer->value.len;
ref = r->headers_in.referer->value.data;
if (len < sizeof("http://i.ru") - 1
|| (ngx_strncasecmp(ref, (u_char *) "http://", 7) != 0))
{
if (rlcf->blocked_referer) {
goto valid;
}
if (len >= sizeof("http://i.ru") - 1) {
last = ref + len;
goto invalid;
if (ngx_strncasecmp(ref, (u_char *) "http://", 7) == 0) {
ref += 7;
goto valid_scheme;
} else if (ngx_strncasecmp(ref, (u_char *) "https://", 8) == 0) {
ref += 8;
goto valid_scheme;
}
}
last = ref + len;
ref += 7;
if (rlcf->blocked_referer) {
goto valid;
}
goto invalid;
valid_scheme:
i = 0;
key = 0;
@ -221,7 +230,7 @@ ngx_http_referer_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_referer_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
#if (NGX_PCRE)
@ -506,6 +515,11 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
ngx_regex_elt_t *re;
u_char errstr[NGX_MAX_CONF_ERRSTR];
if (name->len == 1) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty regex in \"%V\"", name);
return NGX_CONF_ERROR;
}
if (rlcf->regex == NGX_CONF_UNSET_PTR) {
rlcf->regex = ngx_array_create(cf->pool, 2, sizeof(ngx_regex_elt_t));
if (rlcf->regex == NULL) {
@ -562,5 +576,5 @@ ngx_http_cmp_referer_wildcards(const void *one, const void *two)
first = (ngx_hash_key_t *) one;
second = (ngx_hash_key_t *) two;
return ngx_strcmp(first->key.data, second->key.data);
return ngx_dns_strcmp(first->key.data, second->key.data);
}

View File

@ -220,7 +220,7 @@ ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_rewrite_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
conf->stack_size = NGX_CONF_UNSET_UINT;
@ -340,13 +340,10 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
last = 0;
if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0) {
regex->status = NGX_HTTP_MOVED_TEMPORARILY;
regex->redirect = 1;
last = 1;
}
if (ngx_strncmp(value[2].data, "https://", sizeof("https://") - 1) == 0) {
if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0
|| ngx_strncmp(value[2].data, "https://", sizeof("https://") - 1) == 0
|| ngx_strncmp(value[2].data, "$scheme", sizeof("$scheme") - 1) == 0)
{
regex->status = NGX_HTTP_MOVED_TEMPORARILY;
regex->redirect = 1;
last = 1;
@ -446,7 +443,7 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
*code = (uintptr_t) NULL;
*code = NULL;
}
regex->next = (u_char *) lcf->codes->elts + lcf->codes->nelts
@ -568,7 +565,7 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if_code = ngx_array_push_n(lcf->codes, sizeof(ngx_http_script_if_code_t));
if (if_code == NULL) {
return NULL;
return NGX_CONF_ERROR;
}
if_code->code = ngx_http_script_if_code;

View File

@ -152,7 +152,7 @@ ngx_http_secure_link_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_secure_link_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*

View File

@ -14,7 +14,6 @@
#define NGX_HTTP_SSI_ADD_PREFIX 1
#define NGX_HTTP_SSI_ADD_ZERO 2
#define NGX_HTTP_SSI_EXPR_TEST 4
typedef struct {
@ -71,6 +70,8 @@ typedef enum {
static ngx_int_t ngx_http_ssi_output(ngx_http_request_t *r,
ngx_http_ssi_ctx_t *ctx);
static void ngx_http_ssi_buffered(ngx_http_request_t *r,
ngx_http_ssi_ctx_t *ctx);
static ngx_int_t ngx_http_ssi_parse(ngx_http_request_t *r,
ngx_http_ssi_ctx_t *ctx);
static ngx_str_t *ngx_http_ssi_get_variable(ngx_http_request_t *r,
@ -360,6 +361,7 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r)
if (r == r->main) {
ngx_http_clear_content_length(r);
ngx_http_clear_last_modified(r);
ngx_http_clear_accept_ranges(r);
}
return ngx_http_next_header_filter(r);
@ -797,6 +799,7 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
if (rc == NGX_DONE || rc == NGX_AGAIN || rc == NGX_ERROR) {
ngx_http_ssi_buffered(r, ctx);
return rc;
}
}
@ -949,14 +952,21 @@ ngx_http_ssi_output(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
}
}
ngx_http_ssi_buffered(r, ctx);
return rc;
}
static void
ngx_http_ssi_buffered(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
{
if (ctx->in || ctx->buf) {
r->buffered |= NGX_HTTP_SSI_BUFFERED;
} else {
r->buffered &= ~NGX_HTTP_SSI_BUFFERED;
}
return rc;
}
@ -1700,8 +1710,7 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
val = ngx_http_ssi_get_variable(r, &var, key);
if (val == NULL) {
vv = ngx_http_get_variable(r, &var, key,
flags & NGX_HTTP_SSI_EXPR_TEST);
vv = ngx_http_get_variable(r, &var, key);
if (vv == NULL) {
return NGX_ERROR;
}
@ -1907,7 +1916,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
args.len = 0;
args.data = NULL;
flags = 0;
flags = NGX_HTTP_LOG_UNSAFE;
if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
return NGX_HTTP_SSI_ERROR;
@ -2060,9 +2069,9 @@ ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data, ngx_int_t rc)
out = data;
if (!r->header_sent) {
if (ngx_http_set_content_type(r) != NGX_OK) {
return NGX_ERROR;
}
r->headers_out.content_type_len =
r->parent->headers_out.content_type_len;
r->headers_out.content_type = r->parent->headers_out.content_type;
if (ngx_http_send_header(r) == NGX_ERROR) {
return NGX_ERROR;
@ -2109,7 +2118,7 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
value = ngx_http_ssi_get_variable(r, var, key);
if (value == NULL) {
vv = ngx_http_get_variable(r, var, key, 1);
vv = ngx_http_get_variable(r, var, key);
if (vv == NULL) {
return NGX_HTTP_SSI_ERROR;
@ -2160,10 +2169,9 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
}
}
switch (ctx->encoding) {
p = value->data;
case NGX_HTTP_SSI_NO_ENCODING:
break;
switch (ctx->encoding) {
case NGX_HTTP_SSI_URL_ENCODING:
len = 2 * ngx_escape_uri(NULL, value->data, value->len,
@ -2176,11 +2184,9 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
}
(void) ngx_escape_uri(p, value->data, value->len, NGX_ESCAPE_HTML);
value->len += len;
value->data = p;
}
len += value->len;
break;
case NGX_HTTP_SSI_ENTITY_ENCODING:
@ -2193,11 +2199,13 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
}
(void) ngx_escape_html(p, value->data, value->len);
value->len += len;
value->data = p;
}
len += value->len;
break;
default: /* NGX_HTTP_SSI_NO_ENCODING */
len = value->len;
break;
}
@ -2212,8 +2220,8 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
}
b->memory = 1;
b->pos = value->data;
b->last = value->data + value->len;
b->pos = p;
b->last = p + len;
cl->buf = b;
cl->next = NULL;
@ -2361,7 +2369,7 @@ ngx_http_ssi_if(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
p++;
}
flags = (p == last) ? NGX_HTTP_SSI_EXPR_TEST : 0;
flags = 0;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"left: \"%V\"", &left);
@ -2613,8 +2621,7 @@ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
return NGX_ERROR;
}
v->len = ngx_sprintf(v->data, "%T", tp->sec + (gmt ? 0 : tp->gmtoff))
- v->data;
v->len = ngx_sprintf(v->data, "%T", tp->sec) - v->data;
return NGX_OK;
}
@ -2689,14 +2696,14 @@ ngx_http_ssi_create_main_conf(ngx_conf_t *cf)
smcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssi_main_conf_t));
if (smcf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
smcf->commands.pool = cf->pool;
smcf->commands.temp_pool = cf->temp_pool;
if (ngx_hash_keys_array_init(&smcf->commands, NGX_HASH_SMALL) != NGX_OK) {
return NGX_CONF_ERROR;
return NULL;
}
return smcf;
@ -2736,7 +2743,7 @@ ngx_http_ssi_create_loc_conf(ngx_conf_t *cf)
slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssi_loc_conf_t));
if (slcf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*

View File

@ -13,7 +13,7 @@ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
ngx_pool_t *pool, ngx_str_t *s);
#define NGX_DEFAULT_CIPHERS "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
#define NGX_DEFAULT_CIPHERS "HIGH:!ADH:!MD5"
static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
@ -31,15 +31,6 @@ static char *ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
static char *ngx_http_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char ngx_http_ssl_openssl097[] = "OpenSSL 0.9.7 and higher";
#endif
static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = {
{ ngx_string("SSLv2"), NGX_SSL_SSLv2 },
@ -52,7 +43,7 @@ static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = {
static ngx_conf_enum_t ngx_http_ssl_verify[] = {
{ ngx_string("off"), 0 },
{ ngx_string("on"), 1 },
{ ngx_string("ask"), 2 },
{ ngx_string("optional"), 2 },
{ ngx_null_string, 0 }
};
@ -124,14 +115,10 @@ static ngx_command_t ngx_http_ssl_commands[] = {
{ ngx_string("ssl_prefer_server_ciphers"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
ngx_conf_set_flag_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_ssl_srv_conf_t, prefer_server_ciphers),
NULL },
#else
ngx_http_ssl_nosupported, 0, 0, ngx_http_ssl_openssl097 },
#endif
{ ngx_string("ssl_session_cache"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12,
@ -147,6 +134,13 @@ static ngx_command_t ngx_http_ssl_commands[] = {
offsetof(ngx_http_ssl_srv_conf_t, session_timeout),
NULL },
{ ngx_string("ssl_crl"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_ssl_srv_conf_t, crl),
NULL },
ngx_null_command
};
@ -190,6 +184,9 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = {
{ ngx_string("ssl_cipher"), NULL, ngx_http_ssl_static_variable,
(uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGEABLE, 0 },
{ ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 },
{ ngx_string("ssl_client_cert"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 },
@ -206,6 +203,9 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = {
{ ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 },
{ ngx_string("ssl_client_verify"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 },
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
};
@ -302,7 +302,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
sscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssl_srv_conf_t));
if (sscf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*
@ -313,6 +313,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
* sscf->certificate_key = { 0, NULL };
* sscf->dhparam = { 0, NULL };
* sscf->client_certificate = { 0, NULL };
* sscf->crl = { 0, NULL };
* sscf->ciphers.len = 0;
* sscf->ciphers.data = NULL;
* sscf->shm_zone = NULL;
@ -346,8 +347,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
prev->prefer_server_ciphers, 0);
ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
(NGX_CONF_BITMASK_SET
|NGX_SSL_SSLv2|NGX_SSL_SSLv3|NGX_SSL_TLSv1));
(NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3|NGX_SSL_TLSv1));
ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);
@ -359,6 +359,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
"");
ngx_conf_merge_str_value(conf->crl, prev->crl, "");
ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
@ -407,9 +408,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_ssl_servername)
== 0)
{
ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
"SSL_CTX_set_tlsext_servername_callback() failed");
return NGX_CONF_ERROR;
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
"nginx was built with SNI support, however, now it is linked "
"dynamically to an OpenSSL library which has no tlsext support, "
"therefore SNI is not available");
}
#endif
@ -453,16 +455,16 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
{
return NGX_CONF_ERROR;
}
}
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
return NGX_CONF_ERROR;
}
}
if (conf->prefer_server_ciphers) {
SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
}
#endif
/* a temporary 512-bit RSA key is required for export versions of MSIE */
if (ngx_ssl_generate_rsa512_key(&conf->ssl) != NGX_OK) {
return NGX_CONF_ERROR;
@ -620,18 +622,3 @@ invalid:
return NGX_CONF_ERROR;
}
#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
static char *
ngx_http_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"%V\" directive is available only in %s,",
&cmd->name, cmd->post);
return NGX_CONF_ERROR;
}
#endif

View File

@ -33,6 +33,7 @@ typedef struct {
ngx_str_t certificate_key;
ngx_str_t dhparam;
ngx_str_t client_certificate;
ngx_str_t crl;
ngx_str_t ciphers;

View File

@ -66,10 +66,6 @@ ngx_http_static_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
if (r->zero_in_uri) {
return NGX_DECLINED;
}
log = r->connection->log;
/*
@ -188,7 +184,7 @@ ngx_http_static_handler(ngx_http_request_t *r)
#if !(NGX_WIN32) /* the not regular files are probably Unix specific */
if (!of.is_file) {
ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
ngx_log_error(NGX_LOG_CRIT, log, 0,
"\"%s\" is not a regular file", path.data);
return NGX_HTTP_NOT_FOUND;

View File

@ -29,6 +29,8 @@ typedef enum {
typedef struct {
ngx_str_t match;
ngx_str_t saved;
ngx_str_t looked;
ngx_uint_t once; /* unsigned once:1 */
@ -47,8 +49,6 @@ typedef struct {
ngx_str_t sub;
ngx_uint_t state;
size_t saved;
size_t looked;
} ngx_http_sub_ctx_t;
@ -147,6 +147,16 @@ ngx_http_sub_header_filter(ngx_http_request_t *r)
return NGX_ERROR;
}
ctx->saved.data = ngx_pnalloc(r->pool, slcf->match.len);
if (ctx->saved.data == NULL) {
return NGX_ERROR;
}
ctx->looked.data = ngx_pnalloc(r->pool, slcf->match.len);
if (ctx->looked.data == NULL) {
return NGX_ERROR;
}
ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module);
ctx->match = slcf->match;
@ -226,13 +236,13 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
while (ctx->pos < ctx->buf->last) {
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"saved: %d state: %d", ctx->saved, ctx->state);
"saved: \"%V\" state: %d", &ctx->saved, ctx->state);
rc = ngx_http_sub_parse(r, ctx);
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"parse: %d, looked: %d %p-%p",
rc, ctx->looked, ctx->copy_start, ctx->copy_end);
"parse: %d, looked: \"%V\" %p-%p",
rc, &ctx->looked, ctx->copy_start, ctx->copy_end);
if (rc == NGX_ERROR) {
return rc;
@ -241,9 +251,9 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
if (ctx->copy_start != ctx->copy_end) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"saved: %d", ctx->saved);
"saved: \"%V\"", &ctx->saved);
if (ctx->saved) {
if (ctx->saved.len) {
if (ctx->free) {
cl = ctx->free;
@ -265,14 +275,19 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
cl->buf = b;
}
b->pos = ngx_pnalloc(r->pool, ctx->saved.len);
if (b->pos == NULL) {
return NGX_ERROR;
}
ngx_memcpy(b->pos, ctx->saved.data, ctx->saved.len);
b->last = b->pos + ctx->saved.len;
b->memory = 1;
b->pos = ctx->match.data;
b->last = ctx->match.data + ctx->saved;
*ctx->last_out = cl;
ctx->last_out = &cl->next;
ctx->saved = 0;
ctx->saved.len = 0;
}
if (ctx->free) {
@ -405,7 +420,8 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
ctx->buf = NULL;
ctx->saved = ctx->looked;
ctx->saved.len = ctx->looked.len;
ngx_memcpy(ctx->saved.data, ctx->looked.data, ctx->looked.len);
}
if (ctx->out == NULL && ctx->busy == NULL) {
@ -496,7 +512,7 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
ctx->copy_start = ctx->pos;
ctx->copy_end = ctx->buf->last;
ctx->pos = ctx->buf->last;
ctx->looked = 0;
ctx->looked.len = 0;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "once");
@ -504,7 +520,7 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
}
state = ctx->state;
looked = ctx->looked;
looked = ctx->looked.len;
last = ctx->buf->last;
copy_end = ctx->copy_end;
@ -522,6 +538,7 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
for ( ;; ) {
if (ch == match) {
copy_end = p;
ctx->looked.data[0] = *p;
looked = 1;
state = sub_match_state;
@ -538,7 +555,7 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
ctx->state = state;
ctx->pos = p;
ctx->looked = looked;
ctx->looked.len = looked;
ctx->copy_end = p;
if (ctx->copy_start == NULL) {
@ -555,16 +572,17 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
/* state == sub_match_state */
if (ch == ctx->match.data[looked]) {
ctx->looked.data[looked] = *p;
looked++;
if (looked == ctx->match.len) {
if ((size_t) (p - ctx->pos) < looked) {
ctx->saved = 0;
ctx->saved.len = 0;
}
ctx->state = sub_start_state;
ctx->pos = p + 1;
ctx->looked = 0;
ctx->looked.len = 0;
ctx->copy_end = copy_end;
if (ctx->copy_start == NULL && copy_end) {
@ -576,6 +594,7 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
} else if (ch == ctx->match.data[0]) {
copy_end = p;
ctx->looked.data[0] = *p;
looked = 1;
} else {
@ -587,7 +606,7 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
ctx->state = state;
ctx->pos = p;
ctx->looked = looked;
ctx->looked.len = looked;
ctx->copy_end = (state == sub_start_state) ? p : copy_end;
@ -638,7 +657,7 @@ ngx_http_sub_create_conf(ngx_conf_t *cf)
slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_sub_loc_conf_t));
if (slcf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*

View File

@ -545,7 +545,7 @@ ngx_http_userid_add_variables(ngx_conf_t *cf)
{
ngx_http_variable_t *var;
var = ngx_http_add_variable(cf, &ngx_http_userid_got, NGX_HTTP_VAR_NOHASH);
var = ngx_http_add_variable(cf, &ngx_http_userid_got, 0);
if (var == NULL) {
return NGX_ERROR;
}
@ -570,7 +570,7 @@ ngx_http_userid_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_userid_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*

View File

@ -194,7 +194,7 @@ ngx_module_t ngx_http_xslt_filter_module = {
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
ngx_http_xslt_filter_exit, /* exit process */
ngx_http_xslt_filter_exit, /* exit process */
ngx_http_xslt_filter_exit, /* exit master */
NGX_MODULE_V1_PADDING
};
@ -247,6 +247,7 @@ ngx_http_xslt_header_filter(ngx_http_request_t *r)
static ngx_int_t
ngx_http_xslt_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
int wellFormed;
ngx_chain_t *cl;
ngx_http_xslt_filter_ctx_t *ctx;
@ -280,7 +281,7 @@ ngx_http_xslt_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
return ngx_http_xslt_send(r, ctx, NULL);
}
if (cl->buf->last_buf) {
if (cl->buf->last_buf || cl->buf->last_in_chain) {
ctx->doc = ctx->ctxt->myDoc;
@ -288,9 +289,11 @@ ngx_http_xslt_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
ctx->doc->extSubset = NULL;
#endif
wellFormed = ctx->ctxt->wellFormed;
xmlFreeParserCtxt(ctx->ctxt);
if (ctx->ctxt->wellFormed) {
if (wellFormed) {
return ngx_http_xslt_send(r, ctx,
ngx_http_xslt_apply_stylesheet(r, ctx));
}
@ -401,7 +404,7 @@ ngx_http_xslt_add_chunk(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
sax->endElementNs = ngx_http_xslt_sax_end_element;
sax->characters = ngx_http_xslt_sax_characters;
sax->ignorableWhitespace = ngx_http_xslt_sax_characters;
sax->ignorableWhitespace = ngx_http_xslt_sax_characters;
sax->cdataBlock = ngx_http_xslt_sax_cdata_block;
sax->getEntity = ngx_http_xslt_sax_get_entity;
sax->resolveEntity = ngx_http_xslt_sax_resolve_entity;
@ -427,8 +430,8 @@ ngx_http_xslt_add_chunk(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
ctx->request = r;
}
err = xmlParseChunk(ctx->ctxt, (char *) b->pos,
(int) (b->last - b->pos), b->last_buf);
err = xmlParseChunk(ctx->ctxt, (char *) b->pos, (int) (b->last - b->pos),
(b->last_buf) || (b->last_in_chain));
if (err == 0) {
b->pos = b->last;
@ -717,7 +720,7 @@ ngx_http_xslt_sax_error(void *data, const char *msg, ...)
while (--n && (buf[n] == CR || buf[n] == LF)) { /* void */ }
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
"libxml2 error: \"%*s\"", n, buf);
"libxml2 error: \"%*s\"", n + 1, buf);
}
@ -812,7 +815,6 @@ ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
b->pos = buf;
b->last = buf + len;
b->memory = 1;
b->last_buf = 1;
if (encoding) {
r->headers_out.charset.len = ngx_strlen(encoding);
@ -823,6 +825,8 @@ ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
return b;
}
b->last_buf = 1;
if (type) {
len = ngx_strlen(type);
@ -1168,7 +1172,7 @@ ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf)
conf = ngx_palloc(cf->pool, sizeof(ngx_http_xslt_filter_main_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
if (ngx_array_init(&conf->dtd_files, cf->pool, 1,
@ -1196,7 +1200,7 @@ ngx_http_xslt_filter_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_xslt_filter_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*

View File

@ -47,7 +47,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
our $VERSION = '0.7.59';
our $VERSION = '0.7.69';
require XSLoader;
XSLoader::load('nginx', $VERSION);

View File

@ -847,7 +847,7 @@ variable(r, name, value = NULL)
#endif
vv = ngx_http_get_variable(r, &var, hash, 1);
vv = ngx_http_get_variable(r, &var, hash);
if (vv == NULL) {
XSRETURN_UNDEF;
}
@ -901,9 +901,6 @@ variable(r, name, value = NULL)
XSRETURN_UNDEF;
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"variable \"%V\" not found", &var);
XSRETURN_UNDEF;
}

View File

@ -13,8 +13,8 @@
typedef struct {
PerlInterpreter *perl;
HV *nginx;
ngx_str_t modules;
ngx_array_t requires;
ngx_array_t *modules;
ngx_array_t *requires;
} ngx_http_perl_main_conf_t;
@ -30,12 +30,6 @@ typedef struct {
} ngx_http_perl_variable_t;
typedef struct {
SV *sv;
PerlInterpreter *perl;
} ngx_http_perl_cleanup_t;
#if (NGX_HTTP_SSI)
static ngx_int_t ngx_http_perl_ssi(ngx_http_request_t *r,
ngx_http_ssi_ctx_t *ssi_ctx, ngx_str_t **params);
@ -57,8 +51,6 @@ static char *ngx_http_perl_init_main_conf(ngx_conf_t *cf, void *conf);
static void *ngx_http_perl_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_perl_merge_loc_conf(ngx_conf_t *cf, void *parent,
void *child);
static char *ngx_http_perl_require(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
@ -74,16 +66,16 @@ static ngx_command_t ngx_http_perl_commands[] = {
{ ngx_string("perl_modules"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
ngx_conf_set_str_array_slot,
NGX_HTTP_MAIN_CONF_OFFSET,
offsetof(ngx_http_perl_main_conf_t, modules),
NULL },
{ ngx_string("perl_require"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
ngx_http_perl_require,
ngx_conf_set_str_array_slot,
NGX_HTTP_MAIN_CONF_OFFSET,
0,
offsetof(ngx_http_perl_main_conf_t, requires),
NULL },
{ ngx_string("perl"),
@ -154,12 +146,13 @@ static ngx_http_ssi_command_t ngx_http_perl_ssi_command = {
#endif
static ngx_str_t ngx_null_name = ngx_null_string;
static HV *nginx_stash;
static ngx_str_t ngx_null_name = ngx_null_string;
static HV *nginx_stash;
#if (NGX_HAVE_PERL_MULTIPLICITY)
static ngx_uint_t ngx_perl_term;
static ngx_uint_t ngx_perl_term;
#else
static PerlInterpreter *perl;
#endif
@ -175,10 +168,6 @@ ngx_http_perl_xs_init(pTHX)
static ngx_int_t
ngx_http_perl_handler(ngx_http_request_t *r)
{
if (r->zero_in_uri) {
return NGX_HTTP_NOT_FOUND;
}
ngx_http_perl_handle_request(r);
return NGX_DONE;
@ -458,27 +447,42 @@ ngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ssi_ctx,
static char *
ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
{
ngx_str_t *m;
ngx_uint_t i;
#if (NGX_HAVE_PERL_MULTIPLICITY)
ngx_pool_cleanup_t *cln;
ngx_pool_cleanup_t *cln;
cln = ngx_pool_cleanup_add(cf->pool, 0);
if (cln == NULL) {
return NGX_CONF_ERROR;
}
#else
static PerlInterpreter *perl;
#endif
#ifdef NGX_PERL_MODULES
if (pmcf->modules.data == NULL) {
pmcf->modules.data = NGX_PERL_MODULES;
if (pmcf->modules == NGX_CONF_UNSET_PTR) {
pmcf->modules = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
if (pmcf->modules == NULL) {
return NGX_CONF_ERROR;
}
m = ngx_array_push(pmcf->modules);
if (m == NULL) {
return NGX_CONF_ERROR;
}
m->len = sizeof(NGX_PERL_MODULES) - 1;
m->data = NGX_PERL_MODULES;
}
#endif
if (pmcf->modules.data) {
if (ngx_conf_full_name(cf->cycle, &pmcf->modules, 0) != NGX_OK) {
return NGX_CONF_ERROR;
if (pmcf->modules != NGX_CONF_UNSET_PTR) {
m = pmcf->modules->elts;
for (i = 0; i < pmcf->modules->nelts; i++) {
if (ngx_conf_full_name(cf->cycle, &m[i], 0) != NGX_OK) {
return NGX_CONF_ERROR;
}
}
}
@ -490,7 +494,7 @@ ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
return NGX_CONF_ERROR;
}
if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log)
if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log)
!= NGX_OK)
{
return NGX_CONF_ERROR;
@ -538,7 +542,9 @@ ngx_http_perl_create_interpreter(ngx_conf_t *cf,
int n;
STRLEN len;
SV *sv;
char *ver, *embedding[6];
char *ver, **embedding;
ngx_str_t *m;
ngx_uint_t i;
PerlInterpreter *perl;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "create perl interpreter");
@ -564,15 +570,21 @@ ngx_http_perl_create_interpreter(ngx_conf_t *cf,
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
#endif
n = (pmcf->modules != NGX_CONF_UNSET_PTR) ? pmcf->modules->nelts * 2 : 0;
embedding = ngx_palloc(cf->pool, (4 + n) * sizeof(char *));
if (embedding == NULL) {
goto fail;
}
embedding[0] = "";
if (pmcf->modules.data) {
embedding[1] = "-I";
embedding[2] = (char *) pmcf->modules.data;
n = 3;
} else {
n = 1;
if (n++) {
m = pmcf->modules->elts;
for (i = 0; i < pmcf->modules->nelts; i++) {
embedding[2 * i + 1] = "-I";
embedding[2 * i + 2] = (char *) m[i].data;
}
}
embedding[n++] = "-Mnginx";
@ -596,7 +608,7 @@ ngx_http_perl_create_interpreter(ngx_conf_t *cf,
goto fail;
}
if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log) != NGX_OK) {
if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log) != NGX_OK) {
goto fail;
}
@ -617,26 +629,28 @@ fail:
static ngx_int_t
ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log)
{
char **script;
u_char *err;
STRLEN len;
ngx_str_t err;
ngx_str_t *script;
ngx_uint_t i;
if (requires == NGX_CONF_UNSET_PTR) {
return NGX_OK;
}
script = requires->elts;
for (i = 0; i < requires->nelts; i++) {
require_pv(script[i]);
require_pv((char *) script[i].data);
if (SvTRUE(ERRSV)) {
err.data = (u_char *) SvPV(ERRSV, len);
for (len--; err.data[len] == LF || err.data[len] == CR; len--) {
/* void */
}
err.len = len + 1;
err = (u_char *) SvPV(ERRSV, len);
while (--len && (err[len] == CR || err[len] == LF)) { /* void */ }
ngx_log_error(NGX_LOG_EMERG, log, 0,
"require_pv(\"%s\") failed: \"%V\"", script[i], &err);
"require_pv(\"%s\") failed: \"%*s\"",
script[i].data, len + 1, err);
return NGX_ERROR;
}
@ -653,8 +667,8 @@ ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, HV *nginx, SV *sub,
SV *sv;
int n, status;
char *line;
u_char *err;
STRLEN len, n_a;
ngx_str_t err;
ngx_uint_t i;
ngx_connection_t *c;
@ -724,14 +738,11 @@ ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, HV *nginx, SV *sub,
if (SvTRUE(ERRSV)) {
err.data = (u_char *) SvPV(ERRSV, len);
for (len--; err.data[len] == LF || err.data[len] == CR; len--) {
/* void */
}
err.len = len + 1;
err = (u_char *) SvPV(ERRSV, len);
while (--len && (err[len] == CR || err[len] == LF)) { /* void */ }
ngx_log_error(NGX_LOG_ERR, c->log, 0,
"call_sv(\"%V\") failed: \"%V\"", handler, &err);
"call_sv(\"%V\") failed: \"%*s\"", handler, len + 1, err);
if (rv) {
return NGX_ERROR;
@ -765,7 +776,10 @@ ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv)
}
}
if (ngx_strncmp(p, "sub ", 4) == 0 || ngx_strncmp(p, "use ", 4) == 0) {
if (ngx_strncmp(p, "sub ", 4) == 0
|| ngx_strncmp(p, "sub{", 4) == 0
|| ngx_strncmp(p, "use ", 4) == 0)
{
*sv = eval_pv((char *) p, FALSE);
/* eval_pv() does not set ERRSV on failure */
@ -784,15 +798,12 @@ ngx_http_perl_create_main_conf(ngx_conf_t *cf)
pmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_main_conf_t));
if (pmcf == NULL) {
return NGX_CONF_ERROR;
}
if (ngx_array_init(&pmcf->requires, cf->pool, 1, sizeof(u_char *))
!= NGX_OK)
{
return NULL;
}
pmcf->modules = NGX_CONF_UNSET_PTR;
pmcf->requires = NGX_CONF_UNSET_PTR;
return pmcf;
}
@ -869,7 +880,7 @@ ngx_http_perl_create_loc_conf(ngx_conf_t *cf)
plcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_loc_conf_t));
if (plcf == NULL) {
return NGX_CONF_ERROR;
return NULL;
}
/*
@ -897,28 +908,6 @@ ngx_http_perl_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
}
static char *
ngx_http_perl_require(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_perl_main_conf_t *pmcf = conf;
u_char **p;
ngx_str_t *value;
value = cf->args->elts;
p = ngx_array_push(&pmcf->requires);
if (p == NULL) {
return NGX_CONF_ERROR;
}
*p = value[1].data;
return NGX_CONF_OK;
}
static char *
ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
@ -1068,19 +1057,21 @@ ngx_http_perl_exit(ngx_cycle_t *cycle)
{
#if (NGX_HAVE_PERL_MULTIPLICITY)
/*
* the master exit hook is run before global pool cleanup,
* therefore just set flag here
*/
ngx_perl_term = 1;
#else
ngx_http_perl_main_conf_t *pmcf;
pmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_perl_module);
if (pmcf && nginx_stash) {
if (nginx_stash) {
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cycle->log, 0, "perl term");
(void) perl_destruct(pmcf->perl);
(void) perl_destruct(perl);
perl_free(pmcf->perl);
perl_free(perl);
PERL_SYS_TERM();
}

View File

@ -1601,7 +1601,7 @@ ngx_http_cmp_dns_wildcards(const void *one, const void *two)
first = (ngx_hash_key_t *) one;
second = (ngx_hash_key_t *) two;
return ngx_strcmp(first->key.data, second->key.data);
return ngx_dns_strcmp(first->key.data, second->key.data);
}
@ -1831,8 +1831,12 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport,
if (addr[i].hash.buckets == NULL
&& (addr[i].wc_head == NULL
|| addr[i].wc_head->hash.buckets == NULL)
&& (addr[i].wc_head == NULL
|| addr[i].wc_head->hash.buckets == NULL))
&& (addr[i].wc_tail == NULL
|| addr[i].wc_tail->hash.buckets == NULL)
#if (NGX_PCRE)
&& addr[i].nregex == 0
#endif
)
{
continue;
}

Some files were not shown because too many files have changed in this diff Show More