Compare commits

...

173 Commits

Author SHA1 Message Date
Igor Sysoev ff8cfc0b45 release-0.5.38 tag 2009-09-14 13:17:17 +00:00
Igor Sysoev b55c3bd75f nginx-0.5.38-RELEASE 2009-09-14 13:17:16 +00:00
Igor Sysoev 60f79b0cfd merge r3092:
handle "/../" case more reliably
2009-09-07 12:03:14 +00:00
Igor Sysoev 4edf193b41 merge r3076, r3080:
fix segfault when a header starts with "\rX"
and logging is set to info or debug level
2009-09-07 12:02:37 +00:00
Igor Sysoev b6c2d1a5d6 bump version 2009-09-07 12:00:25 +00:00
Igor Sysoev e7af3c349d release-0.5.37 tag 2008-07-07 12:09:03 +00:00
Igor Sysoev c32036746d nginx-0.5.37-RELEASE 2008-07-07 12:09:02 +00:00
Igor Sysoev 29e7a067b3 r2080 merge:
fix error when response parsed by sub filter, then by SSI filter
and some response parts are output as file buffers
2008-07-07 12:01:35 +00:00
Igor Sysoev 340f9a268b r2067 merge:
fix bug when inactive subrequest is truncated,
if output_buffers are less than subrequest size
2008-07-07 11:59:59 +00:00
Igor Sysoev 321d1a2cfb r1901, r1902, r2032 merge:
bugfixes in channel:

*) avoid endless loop if epoll is used
*) use CMSG_LEN(), this fixes an alert
   "sendmsg() failed (9: Bad file descriptor)" on some 64-bit platforms
*) read channel until EAGAIN
2008-07-07 11:58:55 +00:00
Igor Sysoev 8ad79171b9 r2019 merge:
fix building on modern Fedora 9 caused by IOV_MAX
2008-07-07 11:50:42 +00:00
Igor Sysoev 05e3ebfd2a r2015 merge:
avoid recursive loop
2008-07-07 11:50:21 +00:00
Igor Sysoev 55ff3d4e84 bump version 2008-07-07 11:49:18 +00:00
Igor Sysoev 69b5d6657d release-0.5.36 tag 2008-05-04 11:17:14 +00:00
Igor Sysoev 583ddf1405 nginx-0.5.36-RELEASE 2008-05-04 11:17:13 +00:00
Igor Sysoev 5fa7846941 r1979 merge:
reset looked at match
2008-05-04 10:11:23 +00:00
Igor Sysoev 7560165df1 r1969 merge:
fix segfault
2008-05-04 10:08:36 +00:00
Igor Sysoev e9e15f8a13 r1894 merge:
fix segfault if empty stub block is used second time
2008-05-04 10:05:29 +00:00
Igor Sysoev b80397bd24 r1886 merge:
test response length in proxy/fastcgi_store
2008-05-04 10:04:21 +00:00
Igor Sysoev b811a5c388 r1862, r1866, r1869, r1874 merge:
*) revert SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, removed in r1852
*) fix bogus crit log message "SSL_shutdown() failed" introduced in r1852
*) pull all errors
2008-05-04 09:47:59 +00:00
Igor Sysoev 73d987a411 r1699, r1700, r1701, r1702, r1707 merge:
upstream parse_header fix and optimization,
fix fastcgi_catch_stderr segfault merged in r1524:

*) return NGX_HTTP_UPSTREAM_INVALID_HEADER for invalid status
*) return NGX_ERROR instead of NGX_HTTP_INTERNAL_SERVER_ERROR
   in u->parse_header()
*) return NGX_HTTP_UPSTREAM_INVALID_HEADER instead of NGX_HTTP_BAD_GATEWAY
   to go to a next upstream on invalid_header condition
*) now ngx_conf_set_str_array_slot() tests NGX_CONF_UNSET_PTR
   this fixes fastcgi_catch_stderr segfault
*) ngx_http_upstream_hide_headers_hash()
*) proxy/fastcgi pass_header/hide_header use
   ngx_http_upstream_hide_headers_hash()
2008-05-04 09:29:43 +00:00
Igor Sysoev c8795dae87 r1871, r1940 merge:
fix building --test-build-rtsig and --test-build-eventport on FreeBSD 7
2008-05-04 09:20:53 +00:00
Igor Sysoev 64763c5e44 bump version 2008-01-08 17:50:03 +00:00
Igor Sysoev 80da2c2708 release-0.5.35 tag 2008-01-08 17:42:11 +00:00
Igor Sysoev 7c957e784c nginx-0.5.35-RELEASE 2008-01-08 17:42:10 +00:00
Igor Sysoev 3b28854a2b r1755, r1756, r1757 merge:
*) SSL_shutdown() never returns -1, on error it returns 0.
   This fixes incidental "bad write retry" errors.
*) cleaning stale global SSL error
*) remove SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, we never need it
2008-01-08 17:30:39 +00:00
Igor Sysoev e96e6e5271 r1763 merge:
fix STARTTLS prompt in SMTP
2008-01-08 17:24:36 +00:00
Igor Sysoev 0afa1ec458 r1739 merge:
fix merge_slashes
2008-01-08 17:23:25 +00:00
Igor Sysoev f111133e2e r1709 merge:
large_client_header_buffers did not free()ed before keep-alive
2008-01-08 17:22:10 +00:00
Igor Sysoev 3e6bbafb66 r1658 merge:
improve throughput with large limit_rate
2008-01-08 17:13:54 +00:00
Igor Sysoev 26181301e9 r1652 merge:
use usec and pid as start value
2008-01-08 17:09:49 +00:00
Igor Sysoev c4773f2a3c r1646 merge:
the simple expression has the same precision without overflow
2008-01-08 17:09:08 +00:00
Igor Sysoev 0f965a8cd0 r1632 merge:
omit unnecessary test, because NGX_ERROR == -1,
but r->headers_out.last_modified_time != -1 at this point
2008-01-08 16:56:14 +00:00
Igor Sysoev 70f3ec2922 r1631 merge:
If-Range support
2008-01-08 16:55:05 +00:00
Igor Sysoev 966315a1e9 r1617 merge:
set status in correct place
2008-01-08 16:52:00 +00:00
Igor Sysoev bf139b1f7f r1606 merge:
use uname(2) instead of /proc/, this allows to run nginx in chroot
2008-01-08 16:47:55 +00:00
Igor Sysoev f6bfdaf2f4 r1605, r1673 merge:
divide special response handling into several functions
fix "?" escaping introduced in r1526
2008-01-08 16:42:02 +00:00
Igor Sysoev 7906a3e0e7 2008 year 2008-01-08 13:07:37 +00:00
Igor Sysoev b6aa9ee289 bump version 2007-12-13 10:55:18 +00:00
Igor Sysoev 81fd596e29 release-0.5.34 tag 2007-12-13 10:49:27 +00:00
Igor Sysoev fa10dd869a nginx-0.5.34-RELEASE 2007-12-13 10:49:26 +00:00
Igor Sysoev cb5f545b0d r1678, r1679 merge:
*) copy protocol value when large request line is copied,
   this fixes error "fastcgi: the request record is too big"
*) log how big fastcgi record
2007-12-12 21:11:21 +00:00
Igor Sysoev 2514b3962a r1677 merge:
do not allow plain 0.9 request to HTTPS
2007-12-12 21:09:17 +00:00
Igor Sysoev 82e19b3fa9 r1667 merge:
delete unneeded declaration
2007-12-12 21:08:20 +00:00
Igor Sysoev 8ae336f5ad r1657 merge:
log entire request line instead of URI only
2007-12-12 21:05:17 +00:00
Igor Sysoev 142d14d203 r1630 merge:
do not encode already encoded characters in msie_refresh
2007-12-12 21:03:01 +00:00
Igor Sysoev 97cc2c55fe r1627 merge:
fix gzip and SSL
2007-12-12 21:01:43 +00:00
Igor Sysoev dc291bf4f6 r1626 merge:
fix segfaults
2007-12-12 20:59:58 +00:00
Igor Sysoev e301eca9b5 r1604 merge:
compatibility with mget: space after HTTP/1.1
2007-12-12 20:58:34 +00:00
Igor Sysoev 14c25da2eb r1594 merge:
unescape SSI include
2007-12-12 20:56:13 +00:00
Igor Sysoev e448698e1a r1593, r1595 merge:
server_tokens
2007-12-12 20:53:06 +00:00
Igor Sysoev 763e61004a r1591 merge:
fix segfault
2007-12-12 20:50:46 +00:00
Igor Sysoev 721df7ef24 r1587, r1588, r1589, r1590, r1592, r1599, r1629, r1636, r1674, r1681,
r1682, r1683 merge:

typo and style fixes
2007-12-12 20:49:45 +00:00
Igor Sysoev 7c99942b42 merge_slashes 2007-12-12 20:43:39 +00:00
Igor Sysoev ab2aecb398 r1585 merge:
allow full URL without URI part: "GET http://host HTTP/1.0"
2007-12-12 20:42:47 +00:00
Igor Sysoev a8545c11c4 r1584 merge:
gzip_vary
2007-12-12 20:41:22 +00:00
Igor Sysoev d6e4741aa8 r1577, r1582 merge:
Cygwin support
2007-12-12 20:38:44 +00:00
Igor Sysoev 2e98f272c7 r1576, r1578, r1579 merge:
avoid segfault if poll is used and endless loop if select is used
2007-12-12 20:35:32 +00:00
Igor Sysoev ee84366663 r1573, r1574, r1575 merge:
ngx_md5.h and ngx_sha1.h
2007-12-12 17:09:50 +00:00
Igor Sysoev c86eef6299 r1568 merge:
memcached did not set $upstream_response_time
2007-12-12 16:58:44 +00:00
Igor Sysoev 6d347fa2c3 r1567 merge:
fix segfault when $date_local or $date_gmt are used outside ssi module
2007-12-12 16:58:13 +00:00
Igor Sysoev 281a70c61c r1566 merge:
fix English grammar
2007-12-12 16:57:36 +00:00
Igor Sysoev 872ff5410e r1564 merge:
style fix: remove double semicolons
2007-12-12 16:54:53 +00:00
Igor Sysoev 8552e3741f r1563 merge:
allow access_log inside limit_except
2007-12-12 16:54:25 +00:00
Igor Sysoev 984293b7a7 r1562 merge:
%v fix lost in r1407
2007-12-12 16:53:16 +00:00
Igor Sysoev 2684d952f8 r1560 merge:
use pool instead of ngx_conf_t
2007-12-12 16:51:43 +00:00
Igor Sysoev 919798169d r1559, r1565 merge:
optimizations
2007-12-12 16:49:38 +00:00
Igor Sysoev 9a95869ac4 bump version 2007-11-07 14:38:41 +00:00
Igor Sysoev 76fe404739 release-0.5.33 tag 2007-11-07 14:31:57 +00:00
Igor Sysoev 9d5ff02c8b nginx-0.5.33-RELEASE 2007-11-07 14:31:56 +00:00
Igor Sysoev a1876613aa r1477, r1478, r1479, r1480, r1481, r1482, r1483, r1484, r1485, r1486,
r1487, r1488, r1494, r1495, r1499 merge:

*) ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
*) smtp_client_buffer and smtp_greeting_delay
2007-11-07 14:24:55 +00:00
Igor Sysoev 2163a4a058 r1556, r1558 merge:
sub_filter fixes:

*) fix empty string replacement in sub_filter
*) add sub_filter parser fix similar to r1261 in SSI parser
*) fix case when pattern is split between two buffers:
   it had been fixed in SSI parser long ago
2007-11-07 13:59:32 +00:00
Igor Sysoev b2f5beaa06 r1355, r1471, r1600 merge:
make 64-bit ngx_int_t on 64-bit platforms
2007-11-07 13:54:40 +00:00
Igor Sysoev 7586d58399 r1386, r1388, r1389, r1580, r1581 merge:
regex in server_name and valid_referers
2007-11-07 13:46:29 +00:00
Igor Sysoev 09ba4853d2 r1254, r1416, r1493 merge:
the "www.example.*" wildcard hash support
2007-11-07 13:39:53 +00:00
Igor Sysoev 1687d189d6 r1553, r1554 merge:
ngx_strnstr()
2007-10-29 15:10:31 +00:00
Igor Sysoev ca7705fc99 r1548 merge:
add time and length to a HEAD request
2007-10-29 15:08:43 +00:00
Igor Sysoev 92f28e3d31 r1547 merge:
omit trailing zero in directory name
2007-10-29 15:08:01 +00:00
Igor Sysoev 7ad9f14c74 r1545, r1546 merge:
ngx_escape_html(), SSI echo encoding
2007-10-29 15:03:04 +00:00
Igor Sysoev e0f4baa71a r1542, r1543, r1544, r1549, r1550, r1551, r1555 merge:
*) ngx_strstrn() and ngx_strcasestrn()
*) fix memcached END test
2007-10-29 14:52:51 +00:00
Igor Sysoev d8f7a2530d r1492 merge:
log starttls
2007-10-29 14:35:37 +00:00
Igor Sysoev 8c08a6115f r1491 merge:
add rpath for Solaris
2007-10-29 14:32:18 +00:00
Igor Sysoev 814b1095e2 bump version 2007-09-24 04:19:28 +00:00
Igor Sysoev 94a30a8ea7 release-0.5.32 tag 2007-09-24 04:11:21 +00:00
Igor Sysoev 17a957c6f6 nginx-0.5.32-RELEASE 2007-09-24 04:11:20 +00:00
Igor Sysoev 67abd13c05 r1500 merge:
fix file leak for HEAD requests
2007-09-23 19:30:51 +00:00
Igor Sysoev cd46141e2b r1490 merge:
u_char* is enough to keep file name
2007-09-23 19:29:22 +00:00
Igor Sysoev 8e79f6fbf8 r1489 merge:
the "proxy_hide_header" and "fastcgi_hide_header" directives did not
hide response header lines whose name was longer than 32 characters
2007-09-23 19:28:29 +00:00
Igor Sysoev 93b7540ff5 r1445 merge:
allow to append charset to the "Content-Type" header
2007-09-23 19:26:53 +00:00
Igor Sysoev 1bb036cd84 r1473 merge:
decrement active connection counter in mail proxy
2007-09-23 19:25:28 +00:00
Igor Sysoev a142ff6a3a r1472 merge:
response to the HEAD request should be a header only
2007-09-23 19:24:13 +00:00
Igor Sysoev a69878f1fc r1470 merge:
connection error should be logged with "connecting to upstream" action,
the bug was introduced in r1154
2007-09-23 19:23:30 +00:00
Igor Sysoev f5ef42b0d3 r1469 merge:
read EOF of header only responses in non-buffered proxying
2007-09-23 19:21:45 +00:00
Igor Sysoev ed6903a15d r1468 merge:
there may be several "Connection" header lines and each may have several tokens
2007-09-23 19:20:45 +00:00
Igor Sysoev ff31837caf r1467 merge:
escape internal request URI in proxy_pass
2007-09-23 19:19:14 +00:00
Igor Sysoev bed8eaacf4 r1465 merge:
style fix
2007-09-23 19:18:22 +00:00
Igor Sysoev 4f2f70c7cd r1453 merge:
change ngx_conf_merge_ptr_value() and update fastcgi_catch_stderr
2007-09-23 19:15:42 +00:00
Igor Sysoev 223a42cbec r1442, r1443, r1446, r1451 merge:
update comments and style fixes
2007-09-23 19:10:46 +00:00
Igor Sysoev 93666c389e r1441 merge:
use ev->log, because ev->data may be connection stub only
2007-09-23 19:03:57 +00:00
Igor Sysoev cffa71db74 r1438 merge:
destroy ngx_cycle->pool on exit
2007-09-23 19:01:48 +00:00
Igor Sysoev 731f992260 r1436 merge:
win32 ngx_is_exec() stub
2007-09-23 19:00:07 +00:00
Igor Sysoev ce69390c00 r1436 merge:
log socket number
2007-09-23 18:59:07 +00:00
Igor Sysoev f2319c1b65 r1435 merge:
If-Modified-Since should be unique header line
2007-09-23 18:58:17 +00:00
Igor Sysoev 92a7aff502 r1432, r1433, r1434 merge:
/dev/poll segfault fix and guard code
2007-09-23 18:57:26 +00:00
Igor Sysoev e355d9c3af r1428 merge:
return 400 response
2007-09-22 19:34:16 +00:00
Igor Sysoev fee8fa15f5 r1409, r1413 merge:
set delay only when almost whole sendfile_max_chunk was transferred
2007-09-22 19:23:34 +00:00
Igor Sysoev d0505ea2bb r1407 merge:
use %v for ngx_variable_value_t in ngx_sprintf(),
this fixes nginx on FreeBSD/sparc64
2007-09-22 19:18:36 +00:00
Igor Sysoev 2ee2bc5fc6 r1406 merge:
escape " ", "%", and %00-%1F in login and password
2007-09-22 19:15:01 +00:00
Igor Sysoev 90964473e4 r1405 merge:
set worker_priority, worker_rlimit_nofile, worker_rlimit_core, and
worker_rlimit_sigpending without super-user privileges testing
2007-09-22 19:12:53 +00:00
Igor Sysoev 6e6b63ad8e r1404 merge:
auto redirect lost arguments
2007-09-22 19:10:53 +00:00
Igor Sysoev 03465b9370 r1398 merge:
upstream sendfile bit was overridden by r->connection->sendfile
2007-09-22 19:08:42 +00:00
Igor Sysoev 0e37b1c1e3 r1394 merge:
rename upgrade to upgrade1
use -QUIT instead of -WINCH
2007-09-22 19:06:46 +00:00
Igor Sysoev 0d3b197fcb r1381 merge:
ignore meaningless bits in CIDR and warn about them
2007-09-22 19:02:39 +00:00
Igor Sysoev 5808a898f5 r1378 merge:
set default listen() backlog to 511 on all platforms except FreeBSD
2007-09-22 18:59:05 +00:00
Igor Sysoev 53da077a78 r1364, r1365, r1366, r1367 merge:
add_header changes:
"Last-Modified", "Cache-Control" and "Expires" headers use specific handlers
2007-09-22 18:54:28 +00:00
Igor Sysoev f0237bfba3 r1340, r1341 merge:
fix case when two directives
    proxy_pass   http://backend;
    proxy_pass   https://backend;
both use one port - 80 or 443, that was defined first.
2007-09-22 18:44:30 +00:00
Igor Sysoev d8ea8ca5f8 r1391, r1392, r1393 merge:
auth_http related changes:
*) stop configuration on error
*) allow "http://" in auth_http URL
*) test http_auth absence
2007-09-22 18:41:35 +00:00
Igor Sysoev 8e2c9a3126 r1324 merge:
IMAP AUTHENTICATE
patch by Maxim Dounin
2007-09-22 18:36:23 +00:00
Igor Sysoev d8d4d64a75 r1323 merge:
SMTP STARTTLS
patch by Maxim Dounin
2007-09-22 18:35:18 +00:00
Igor Sysoev 8b655ab2dd r1284 merge:
proxy_ignore_client_abort, fastcgi_ignore_client_abort, and so on were
broken by r1111
2007-09-22 18:31:26 +00:00
Igor Sysoev b132258d73 r1444 merge:
style fix
2007-09-01 09:55:41 +00:00
Igor Sysoev 8f5466261d r1440 merge:
style fix
2007-09-01 09:55:04 +00:00
Igor Sysoev a54eea5a08 r1439 merge:
fix typo
2007-09-01 09:53:10 +00:00
Igor Sysoev 6ba2e6522f r1272 merge:
add comment
2007-09-01 09:51:57 +00:00
Igor Sysoev a6d70e05ef r1414 merge:
add svg mime type
2007-08-26 13:42:04 +00:00
Igor Sysoev 63387a60e5 bump version 2007-08-21 19:46:20 +00:00
Igor Sysoev 288c7f86fd release-0.5.31 tag 2007-08-15 12:47:27 +00:00
Igor Sysoev 96dcd68f7a nginx-0.5.31-RELEASE 2007-08-15 12:47:26 +00:00
Igor Sysoev 773b0ae920 r1387 merge:
fix building by bcc without PCRE
2007-08-14 20:03:00 +00:00
Igor Sysoev fc18feef28 r1354 merge:
named location
2007-08-14 20:02:09 +00:00
Igor Sysoev 4b8574c891 bump version 2007-08-11 10:17:02 +00:00
Igor Sysoev 64c07187a0 r1376 merge:
add debug info for Sun Studio
2007-08-11 10:13:37 +00:00
Igor Sysoev 19994e9acc r1297 merge:
dav_access uses ngx_conf_set_access_slot()
2007-08-11 10:12:22 +00:00
Igor Sysoev 5dc1930cce r1292, r1296 merge:
proxy_store and fastcgi_store, proxy_store_access and fastcgi_store_access
2007-08-11 10:11:33 +00:00
Igor Sysoev cc5999a68c release-0.5.30 tag 2007-07-30 09:14:35 +00:00
Igor Sysoev b473bf5b46 nginx-0.5.30-RELEASE 2007-07-30 09:14:34 +00:00
Igor Sysoev cf18290f42 r1352 merge:
$is_args
2007-07-29 18:55:59 +00:00
Igor Sysoev 8bb450b5e4 r1351 merge:
allow to set $args
2007-07-29 18:55:24 +00:00
Igor Sysoev b66b8c0906 r1258, r1259 merge:
set worker's perl $$
2007-07-29 17:31:00 +00:00
Igor Sysoev 42c91afe85 r1343 merge:
fix case when client has closed connection but upstream buffer is not empty
2007-07-29 17:29:06 +00:00
Igor Sysoev 988bede80f r1333, r1334 merge:
omit unnecessary code,
escape space, etc in $memcached_key
2007-07-29 17:27:10 +00:00
Igor Sysoev f488e98593 r1285 merge:
fix segfault when session was freed twice
2007-07-29 17:25:06 +00:00
Igor Sysoev aaa44dd224 r1344 merge:
fix building on amd64 by Sun Studio 11 and more early versions
2007-07-29 17:22:59 +00:00
Igor Sysoev 2ac6766577 bump version 2007-07-24 14:36:21 +00:00
Igor Sysoev aef26c77db release-0.5.29 tag 2007-07-23 07:59:00 +00:00
Igor Sysoev 969f51c3c8 nginx-0.5.29-RELEASE 2007-07-23 07:58:59 +00:00
Igor Sysoev d1d9811cf3 r1330, r1331 merge:
$nginx_version
2007-07-22 13:17:41 +00:00
Igor Sysoev 7b0af7b8b3 r1277 merge:
fix headers split in FastCGI records
2007-07-22 09:05:43 +00:00
Igor Sysoev 10f0b17058 r1306, r1307, r1308, r1309, r1310, r1311, r1322, r1325 merge:
Sun Studio related fixes
2007-07-22 08:47:45 +00:00
Igor Sysoev 03e366afc3 r1318, r1319, r1320, r1321 merge:
fix various bugs found by Coverity's Scan
2007-07-22 08:40:39 +00:00
Igor Sysoev 3e6256935f bump version 2007-07-22 08:35:56 +00:00
Igor Sysoev 0a647dc34d release-0.5.28 tag 2007-07-17 10:01:18 +00:00
Igor Sysoev 01d30b7b65 nginx-0.5.28-RELEASE 2007-07-17 10:01:17 +00:00
Igor Sysoev 32ad363a2c r1299 merge:
msie_refresh should escape at least '"' to prevent XSS
2007-07-17 09:34:23 +00:00
Igor Sysoev 149fdb18d8 r1298 merge:
"?" should not be escaped
2007-07-13 10:48:48 +00:00
Igor Sysoev 0e254f6bbb r1290, r1291 merge:
style fixes
2007-07-13 10:47:26 +00:00
Igor Sysoev ec6ef43624 r1289 merge:
reset errno
2007-07-13 10:46:16 +00:00
Igor Sysoev 96e7062852 r1288 merge:
fix segfault when event port returns POLLERR without POLLIN or POLLOUT
2007-07-13 10:45:33 +00:00
Igor Sysoev 129dd82d2a r1287 merge:
fix segfault when CRAM-MD5 is not enabled but client tries it
2007-07-13 10:44:36 +00:00
Igor Sysoev 11ade0fb6a r1286 merge:
fix memory allocation for auth_http_header
2007-07-13 10:43:35 +00:00
Igor Sysoev ea7cf4cf90 bump version 2007-07-09 10:34:14 +00:00
Igor Sysoev 20f18b4d2e release-0.5.27 tag 2007-07-09 06:53:55 +00:00
Igor Sysoev 152003567d nginx-0.5.27-RELEASE 2007-07-09 06:53:54 +00:00
Igor Sysoev 08f9992a63 r1275 merge:
omit unnecessary conditions
2007-07-09 06:06:15 +00:00
Igor Sysoev 4a7cc46f8c r1273 merge:
when the FastCGI header was split in records,
nginx passed garbage in the header to a client
2007-07-08 09:18:06 +00:00
Igor Sysoev 890a7407c7 r1260 merge:
if subrequest response was buffered in file, then subrequest was finalized
with 0 code, ngx_http_writer() was not set, and response part in file was lost
2007-07-05 11:42:11 +00:00
Igor Sysoev 61092efcfa r1262 merge:
if a subrequest was finished and SSI was in middle of SSI command parsing
and the command was a fast subrequest then the second subrequest output
was just after first subrequest output and response part of main request
between the subrequests went after the second subrequest.
2007-07-05 11:36:16 +00:00
Igor Sysoev f14fcc5d23 bump version 2007-06-17 19:27:11 +00:00
Igor Sysoev 5f819d85df release-0.5.26 tag 2007-06-17 19:07:56 +00:00
Igor Sysoev f989298c90 nginx-0.5.26-RELEASE 2007-06-17 19:07:55 +00:00
Igor Sysoev 3702756e0d r1261 merge:
if "<!--" was on edge of buf, then ssi_sharp_state was saved in ctx->saved
and if it was not reset, then any '#' was treated as SSI command start
2007-06-17 18:52:06 +00:00
Igor Sysoev 7474f1ea93 bump version 2007-06-11 19:31:55 +00:00
Igor Sysoev 93e8ad64c7 stable 0.5 branch 2007-06-11 19:25:52 +00:00
145 changed files with 8598 additions and 4093 deletions

View File

@ -2,8 +2,10 @@
# Copyright (C) Igor Sysoev
# Sun C 5.7 Patch 117837-04 2005/05/11
# Sun C 5.8 2005/10/13
# Sun C 5.7 Patch 117837-04 2005/05/11 Sun Studio 10
# Sun C 5.8 2005/10/13 Sun Studio 11
# Sun C 5.9 SunOS_i386 2007/05/03 Sun Studio 12
# Sun C 5.9 SunOS_sparc 2007/05/03
NGX_SUNC_VER=`$CC -V 2>&1 | grep 'Sun C' 2>&1 \
| sed -e 's/^.* Sun C \(.*\)/\1/'`
@ -13,6 +15,33 @@ echo " + Sun C version: $NGX_SUNC_VER"
have=NGX_COMPILER value="\"Sun C $NGX_SUNC_VER\"" . auto/define
cat << END > $NGX_AUTOTEST.c
int main() { printf("%d", __SUNPRO_C); }
END
eval "$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
if [ -x $NGX_AUTOTEST ]; then
ngx_sunc_ver=`$NGX_AUTOTEST`
fi
rm $NGX_AUTOTEST*
# 1424 == 0x590, Sun Studio 12
if [ "$ngx_sunc_ver" -ge 1424 ]; then
ngx_sparc32="-m32"
ngx_sparc64="-m64"
ngx_amd64="-m64"
else
ngx_sparc32="-xarch=v8plus"
ngx_sparc64="-xarch=v9"
ngx_amd64="-xarch=amd64"
fi
case "$NGX_MACHINE" in
i86pc)
@ -35,9 +64,6 @@ case "$NGX_MACHINE" in
;;
sun4u | sun4v)
# "-xarch=v9" enables the "casa" assembler instruction
CFLAGS="$CFLAGS -xarch=v9"
CORE_LINK="$CORE_LINK -xarch=v9"
NGX_AUX=" src/os/unix/ngx_sunpro_sparc64.il"
;;
@ -46,7 +72,9 @@ esac
# optimizations
CFLAGS="$CFLAGS -fast"
IPO=-xipo
CFLAGS="$CFLAGS -fast $IPO"
CORE_LINK="$CORE_LINK -fast $IPO"
case $CPU in
@ -81,11 +109,29 @@ case $CPU in
CPU_OPT="$CPU_OPT -xcache=64/64/2:1024/64/16"
;;
sparc32)
# build 32-bit UltraSparc binary
CPU_OPT="$ngx_sparc32"
CORE_LINK="$CORE_LINK $ngx_sparc32"
CC_AUX_FLAGS="$CC_AUX_FLAGS $ngx_sparc32"
NGX_CPU_CACHE_LINE=64
;;
sparc64)
# build 64-bit UltraSparc binary
CPU_OPT="$ngx_sparc64"
CORE_LINK="$CORE_LINK $ngx_sparc64"
CC_AUX_FLAGS="$CC_AUX_FLAGS $ngx_sparc64"
NGX_CPU_CACHE_LINE=64
;;
amd64)
# build 64-bit amd64 binary
CPU_OPT="-xarch=amd64"
CORE_LINK="$CORE_LINK -xarch=amd64"
CPU_OPT="$ngx_amd64"
CORE_LINK="$CORE_LINK $ngx_amd64"
CC_AUX_FLAGS="$CC_AUX_FLAGS $ngx_amd64"
NGX_AUX=" src/os/unix/ngx_sunpro_amd64.il"
NGX_CPU_CACHE_LINE=64
;;
esac
@ -95,17 +141,20 @@ CFLAGS="$CFLAGS $CPU_OPT"
if [ ".$PCRE_OPT" = "." ]; then
PCRE_OPT="-fast $CPU_OPT"
PCRE_OPT="-fast $IPO $CPU_OPT"
fi
if [ ".$MD5_OPT" = "." ]; then
MD5_OPT="-fast $CPU_OPT"
MD5_OPT="-fast $IPO $CPU_OPT"
fi
if [ ".$ZLIB_OPT" = "." ]; then
ZLIB_OPT="-fast $CPU_OPT"
ZLIB_OPT="-fast $IPO $CPU_OPT"
fi
# stop on warning
CFLAGS="$CFLAGS -errwarn=%all"
# debug
CFLAGS="$CFLAGS -g"

View File

@ -6,3 +6,5 @@ ngx_include="unistd.h"; . auto/include
ngx_include="inttypes.h"; . auto/include
ngx_include="limits.h"; . auto/include
ngx_include="sys/filio.h"; . auto/include
ngx_include="crypt.h"; . auto/include
ngx_include="malloc.h"; . auto/include

View File

@ -55,15 +55,24 @@ clean:
upgrade:
$NGX_SBIN_PATH -t
# upgrade compatibility from 0.1.x to 0.2.x
kill -USR2 \`cat $NGX_PID_PATH\`
sleep 1
test -f $NGX_PID_PATH.oldbin
kill -QUIT \`cat $NGX_PID_PATH.oldbin\`
upgrade1:
# upgrade 0.1.x to 0.2+
$NGX_SBIN_PATH -t
cp $NGX_PID_PATH $NGX_PID_PATH.oldbin
kill -USR2 \`cat $NGX_PID_PATH\`
sleep 1
test -f $NGX_PID_PATH.oldbin
# upgrade compatibility from 0.1.x to 0.2.x
cp $NGX_PID_PATH $NGX_PID_PATH.newbin
kill -WINCH \`cat $NGX_PID_PATH.oldbin\`
kill -QUIT \`cat $NGX_PID_PATH.oldbin\`
END

View File

@ -17,7 +17,7 @@ if [ $PCRE != NONE ]; then
CORE_LIBS="$CORE_LIBS $PCRE/pcre.lib"
;;
icc* | sunc )
icc* )
have=NGX_PCRE . auto/have
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
@ -25,13 +25,18 @@ if [ $PCRE != NONE ]; then
echo $ngx_n "checking for PCRE library ...$ngx_c"
if [ -e $PCRE/pcre.h ]; then
if [ -f $PCRE/pcre.h ]; then
ngx_pcre_ver=`grep PCRE_MAJOR $PCRE/pcre.h \
| sed -e 's/^.*PCRE_MAJOR.* \(.*\)$/\1/'`
else
else if [ -f $PCRE/configure.in ]; then
ngx_pcre_ver=`grep PCRE_MAJOR= $PCRE/configure.in \
| sed -e 's/^.*=\(.*\)$/\1/'`
else
ngx_pcre_ver=`grep pcre_major, $PCRE/configure.ac \
| sed -e 's/^.*pcre_major,.*\[\(.*\)\].*$/\1/'`
fi
fi
echo " $ngx_pcre_ver major version found"
@ -72,7 +77,6 @@ if [ $PCRE != NONE ]; then
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre.a"
#CORE_LIBS="$CORE_LIBS -L $PCRE/.libs -lpcre"
;;
esac
@ -106,7 +110,13 @@ else
ngx_feature_run=no
ngx_feature_incs="#include <pcre.h>"
ngx_feature_path="/usr/local/include"
ngx_feature_libs="-L /usr/local/lib -lpcre"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lpcre"
else
ngx_feature_libs="-L/usr/local/lib -lpcre"
fi
ngx_feature_test="pcre *re;
re = pcre_compile(NULL, 0, NULL, 0, NULL)"
. auto/feature
@ -155,7 +165,13 @@ else
ngx_feature_run=no
ngx_feature_incs="#include <pcre.h>"
ngx_feature_path="/usr/pkg/include"
ngx_feature_libs="-L /usr/pkg/lib -lpcre"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lpcre"
else
ngx_feature_libs="-L/usr/pkg/lib -lpcre"
fi
ngx_feature_test="pcre *re;
re = pcre_compile(NULL, 0, NULL, 0, NULL)"
. auto/feature
@ -180,7 +196,13 @@ else
ngx_feature_run=no
ngx_feature_incs="#include <pcre.h>"
ngx_feature_path="/opt/local/include"
ngx_feature_libs="-L/opt/local/lib -lpcre"
if [ $NGX_RPATH = YES ]; then
ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lpcre"
else
ngx_feature_libs="-L/opt/local/lib -lpcre"
fi
ngx_feature_test="pcre *re;
re = pcre_compile(NULL, 0, NULL, 0, NULL)"
. auto/feature

View File

@ -308,8 +308,6 @@ fi
if [ $MAIL_SSL = YES ]; then
MAIL_DEPS="$MAIL_DEPS $MAIL_SSL_DEPS"
MAIL_SRCS="$MAIL_SRCS $MAIL_SSL_SRCS"
have=NGX_MAIL_SSL . auto/have
USE_OPENSSL=YES
fi
@ -341,6 +339,26 @@ if [ $MAIL = YES ]; then
if [ $MAIL_SSL = YES ]; then
modules="$modules $MAIL_SSL_MODULE"
MAIL_DEPS="$MAIL_DEPS $MAIL_SSL_DEPS"
MAIL_SRCS="$MAIL_SRCS $MAIL_SSL_SRCS"
fi
if [ $MAIL_POP3 = YES ]; then
modules="$modules $MAIL_POP3_MODULE"
MAIL_DEPS="$MAIL_DEPS $MAIL_POP3_DEPS"
MAIL_SRCS="$MAIL_SRCS $MAIL_POP3_SRCS"
fi
if [ $MAIL_IMAP = YES ]; then
modules="$modules $MAIL_IMAP_MODULE"
MAIL_DEPS="$MAIL_DEPS $MAIL_IMAP_DEPS"
MAIL_SRCS="$MAIL_SRCS $MAIL_IMAP_SRCS"
fi
if [ $MAIL_SMTP = YES ]; then
modules="$modules $MAIL_SMTP_MODULE"
MAIL_DEPS="$MAIL_DEPS $MAIL_SMTP_DEPS"
MAIL_SRCS="$MAIL_SRCS $MAIL_SMTP_SRCS"
fi
modules="$modules $MAIL_AUTH_HTTP_MODULE"

View File

@ -22,6 +22,8 @@ NGX_CC_OPT=
NGX_LD_OPT=
CPU=NO
NGX_RPATH=NO
NGX_TEST_BUILD_DEVPOLL=NO
NGX_TEST_BUILD_EVENTPORT=NO
NGX_TEST_BUILD_EPOLL=NO
@ -80,6 +82,9 @@ HTTP_STUB_STATUS=NO
MAIL=NO
MAIL_SSL=NO
MAIL_POP3=YES
MAIL_IMAP=YES
MAIL_SMTP=YES
NGX_ADDONS=
@ -189,6 +194,9 @@ do
# STUB
--with-imap) MAIL=YES ;;
--with-imap_ssl_module) MAIL_SSL=YES ;;
--without-mail_pop3_module) MAIL_POP3=NO ;;
--without-mail_imap_module) MAIL_IMAP=NO ;;
--without-mail_smtp_module) MAIL_SMTP=NO ;;
--add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;;
@ -299,8 +307,11 @@ cat << END
--without-http disable HTTP server
--with-mail enable IMAP4/POP3/SMTP proxy module
--with-mail enable POP3/IMAP4/SMTP proxy module
--with-mail_ssl_module enable ngx_mail_ssl_module
--without-mail_pop3_module disable ngx_mail_pop3_module
--without-mail_imap_module disable ngx_mail_imap_module
--without-mail_smtp_module disable ngx_mail_smtp_module
--add-module=PATH enable an external module

View File

@ -9,6 +9,8 @@ CORE_DEPS="$UNIX_DEPS $SOLARIS_DEPS"
CORE_SRCS="$UNIX_SRCS $SOLARIS_SRCS "
CORE_LIBS="$CORE_LIBS -lsocket -lnsl -lrt"
NGX_RPATH=YES
# Solaris's make does not support a blank line between target and rules
ngx_spacer=

View File

@ -21,6 +21,8 @@ CORE_DEPS="src/core/nginx.h \
src/core/ngx_file.h \
src/core/ngx_crc.h \
src/core/ngx_crc32.h \
src/core/ngx_md5.h \
src/core/ngx_sha1.h \
src/core/ngx_rbtree.h \
src/core/ngx_radix_tree.h \
src/core/ngx_slab.h \
@ -423,6 +425,21 @@ MAIL_SRCS="src/mail/ngx_mail.c \
src/mail/ngx_mail_handler.c \
src/mail/ngx_mail_parse.c"
MAIL_POP3_MODULE="ngx_mail_pop3_module"
MAIL_POP3_DEPS="src/mail/ngx_mail_pop3_module.h"
MAIL_POP3_SRCS="src/mail/ngx_mail_pop3_module.c \
src/mail/ngx_mail_pop3_handler.c"
MAIL_IMAP_MODULE="ngx_mail_imap_module"
MAIL_IMAP_DEPS="src/mail/ngx_mail_imap_module.h"
MAIL_IMAP_SRCS="src/mail/ngx_mail_imap_module.c \
src/mail/ngx_mail_imap_handler.c"
MAIL_SMTP_MODULE="ngx_mail_smtp_module"
MAIL_SMTP_DEPS="src/mail/ngx_mail_smtp_module.h"
MAIL_SMTP_SRCS="src/mail/ngx_mail_smtp_module.c \
src/mail/ngx_mail_smtp_handler.c"
MAIL_SSL_MODULE="ngx_mail_ssl_module"
MAIL_SSL_DEPS="src/mail/ngx_mail_ssl_module.h"
MAIL_SSL_SRCS="src/mail/ngx_mail_ssl_module.c"

View File

@ -36,5 +36,6 @@ if [ $found = no ]; then
found="uint`expr 8 \* $ngx_ptr_size`_t"
echo ", $found used"
echo "typedef $found uintptr_t;" >> $NGX_AUTO_CONFIG_H
echo "typedef $found uintptr_t;" >> $NGX_AUTO_CONFIG_H
echo "typedef $found intptr_t;" | sed -e 's/u//g' >> $NGX_AUTO_CONFIG_H
fi

View File

@ -11,7 +11,7 @@ fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;

View File

@ -20,6 +20,7 @@ types {
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
image/svg+xml svg;
application/java-archive jar war ear;
application/mac-binhex40 hqx;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2007 Igor Sysoev
* Copyright (C) 2002-2008 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

@ -438,6 +438,9 @@ ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last)
}
var = ngx_array_push(&ccf->env);
if (var == NULL) {
return NULL;
}
var->len = 2;
var->data = (u_char *) "TZ";
@ -796,6 +799,7 @@ ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
if (ccf->user == (uid_t) NGX_CONF_UNSET_UINT && geteuid() == 0) {
ngx_set_errno(0);
pwd = getpwnam(NGX_USER);
if (pwd == NULL) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
@ -806,6 +810,7 @@ ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
ccf->username = NGX_USER;
ccf->user = pwd->pw_uid;
ngx_set_errno(0);
grp = getgrnam(NGX_GROUP);
if (grp == NULL) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
@ -920,6 +925,7 @@ ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ccf->username = (char *) value[1].data;
ngx_set_errno(0);
pwd = getpwnam((const char *) value[1].data);
if (pwd == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
@ -931,6 +937,7 @@ ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
group = (char *) ((cf->args->nelts == 2) ? value[1].data : value[2].data);
ngx_set_errno(0);
grp = getgrnam(group);
if (grp == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,

View File

@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
#define NGINX_VERSION "0.5.25"
#define NGINX_VERSION "0.5.38"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"

View File

@ -117,7 +117,7 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
cf->conf_file->file.name.len = filename->len;
cf->conf_file->file.name.data = filename->data;
cf->conf_file->file.offset = 0;
cf->conf_file->file.log = cf->log;;
cf->conf_file->file.log = cf->log;
cf->conf_file->line = 1;
block = 0;
@ -366,7 +366,7 @@ not_allowed:
invalid:
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid number arguments in \"%s\" directive",
"invalid number of arguments in \"%s\" directive",
name->data);
return NGX_ERROR;
@ -925,7 +925,7 @@ ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
a = (ngx_array_t **) (p + cmd->offset);
if (*a == NULL) {
if (*a == NGX_CONF_UNSET_PTR) {
*a = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
if (*a == NULL) {
return NGX_CONF_ERROR;

View File

@ -257,8 +257,8 @@ char *ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data);
}
#define ngx_conf_merge_ptr_value(conf, prev, default) \
if (conf == NULL) { \
conf = (prev == NULL) ? default : prev; \
if (conf == NGX_CONF_UNSET_PTR) { \
conf = (prev == NGX_CONF_UNSET_PTR) ? default : prev; \
}
#define ngx_conf_merge_uint_value(conf, prev, default) \

View File

@ -70,31 +70,20 @@
#endif
typedef intptr_t ngx_int_t;
typedef uintptr_t ngx_uint_t;
typedef intptr_t ngx_flag_t;
/* TODO: platform specific: array[NGX_INVALID_ARRAY_INDEX] must cause SIGSEGV */
#define NGX_INVALID_ARRAY_INDEX 0x80000000
#if 1
/* STUB: autoconf */
typedef int ngx_int_t;
typedef u_int ngx_uint_t;
typedef int ngx_flag_t;
#define NGX_INT_T_LEN sizeof("-2147483648") - 1
#else
typedef long ngx_int_t;
typedef u_long ngx_uint_t;
typedef long ngx_flag_t;
#define NGX_INT_T_LEN sizeof("-9223372036854775808") - 1
#endif
#define NGX_INT32_LEN sizeof("-2147483648") - 1
#define NGX_INT64_LEN sizeof("-9223372036854775808") - 1
#if (NGX_PTR_SIZE == 4)
#define NGX_INT_T_LEN NGX_INT32_LEN
#else
#define NGX_INT_T_LEN NGX_INT64_LEN
#endif
#ifndef NGX_ALIGNMENT
#define NGX_ALIGNMENT sizeof(unsigned long) /* platform word */
@ -108,6 +97,10 @@ typedef long ngx_flag_t;
#define ngx_abort abort
/* TODO: platform specific: array[NGX_INVALID_ARRAY_INDEX] must cause SIGSEGV */
#define NGX_INVALID_ARRAY_INDEX 0x80000000
/* TODO: auto_conf: ngx_inline inline __inline __inline__ */
#ifndef ngx_inline
#define ngx_inline inline

View File

@ -123,7 +123,7 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
ntohs(sin->sin_port))
- ls[i].addr_text.data;
ls[i].backlog = -1;
ls[i].backlog = NGX_LISTEN_BACKLOG;
olen = sizeof(int);
@ -735,7 +735,7 @@ ngx_close_connection(ngx_connection_t *c)
/* we use ngx_cycle->log because c->log was in c->pool */
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
ngx_close_socket_n " failed");
ngx_close_socket_n " %d failed", fd);
}
}

View File

@ -293,6 +293,68 @@ ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
char *
ngx_conf_set_access_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *confp = conf;
u_char *p;
ngx_str_t *value;
ngx_uint_t i, right, shift, *access;
access = (ngx_uint_t *) (confp + cmd->offset);
if (*access != NGX_CONF_UNSET_UINT) {
return "is duplicate";
}
value = cf->args->elts;
*access = 0600;
for (i = 1; i < cf->args->nelts; i++) {
p = value[i].data;
if (ngx_strncmp(p, "user:", sizeof("user:") - 1) == 0) {
shift = 6;
p += sizeof("user:") - 1;
} else if (ngx_strncmp(p, "group:", sizeof("group:") - 1) == 0) {
shift = 3;
p += sizeof("group:") - 1;
} else if (ngx_strncmp(p, "all:", sizeof("all:") - 1) == 0) {
shift = 0;
p += sizeof("all:") - 1;
} else {
goto invalid;
}
if (ngx_strcmp(p, "rw") == 0) {
right = 6;
} else if (ngx_strcmp(p, "r") == 0) {
right = 4;
} else {
goto invalid;
}
*access |= right << shift;
}
return NGX_CONF_OK;
invalid:
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid value \"%V\"", &value[i]);
return NGX_CONF_ERROR;
}
ngx_int_t
ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot)
{
@ -456,6 +518,9 @@ ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t *tree)
}
ctx->data = data;
} else {
data = NULL;
}
for ( ;; ) {
@ -581,8 +646,8 @@ done:
ngx_free(buf.data);
}
if (ctx->alloc) {
ngx_free(ctx->data);
if (data) {
ngx_free(data);
ctx->data = prev;
}

View File

@ -95,6 +95,7 @@ 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);
char *ngx_conf_set_access_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
#define ngx_conf_merge_path_value(curr, prev, path, l1, l2, l3, clean, cf) \

View File

@ -53,7 +53,7 @@ ngx_hash_find(ngx_hash_t *hash, ngx_uint_t key, u_char *name, size_t len)
void *
ngx_hash_find_wildcard(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
ngx_hash_find_wc_head(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
{
void *value;
ngx_uint_t i, n, key;
@ -63,7 +63,7 @@ ngx_hash_find_wildcard(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
line.len = len;
line.data = name;
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wc:\"%V\"", &line);
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wch:\"%V\"", &line);
#endif
n = len;
@ -112,7 +112,7 @@ ngx_hash_find_wildcard(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
}
}
value = ngx_hash_find_wildcard(hwc, name, n - 1);
value = ngx_hash_find_wc_head(hwc, name, n - 1);
if (value) {
return value;
@ -128,6 +128,104 @@ ngx_hash_find_wildcard(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
}
void *
ngx_hash_find_wc_tail(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
{
void *value;
ngx_uint_t i, key;
#if 0
ngx_str_t line;
line.len = len;
line.data = name;
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wct:\"%V\"", &line);
#endif
key = 0;
for (i = 0; i < len; i++) {
if (name[i] == '.') {
break;
}
key = ngx_hash(key, name[i]);
}
if (i == len) {
return NULL;
}
#if 0
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "key:\"%ui\"", key);
#endif
value = ngx_hash_find(&hwc->hash, key, name, i);
if (value) {
/*
* the 2 low bits of value have the special meaning:
* 00 - value is data pointer,
* 01 - value is pointer to wildcard hash allowing "example.*".
*/
if ((uintptr_t) value & 1) {
i++;
hwc = (ngx_hash_wildcard_t *) ((uintptr_t) value & (uintptr_t) ~3);
value = ngx_hash_find_wc_tail(hwc, &name[i], len - i);
if (value) {
return value;
}
return hwc->value;
}
return value;
}
return hwc->value;
}
void *
ngx_hash_find_combined(ngx_hash_combined_t *hash, ngx_uint_t key, u_char *name,
size_t len)
{
void *value;
if (hash->hash.buckets) {
value = ngx_hash_find(&hash->hash, key, name, len);
if (value) {
return value;
}
}
if (hash->wc_head && hash->wc_head->hash.buckets) {
value = ngx_hash_find_wc_head(hash->wc_head, name, len);
if (value) {
return value;
}
}
if (hash->wc_tail && hash->wc_tail->hash.buckets) {
value = ngx_hash_find_wc_tail(hash->wc_tail, name, len);
if (value) {
return value;
}
}
return NULL;
}
#define NGX_HASH_ELT_SIZE(name) \
(sizeof(void *) + ngx_align((name)->key.len + 1, sizeof(void *)))
@ -544,7 +642,14 @@ ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type)
return NGX_ERROR;
}
if (ngx_array_init(&ha->dns_wildcards, ha->temp_pool, asize,
if (ngx_array_init(&ha->dns_wc_head, ha->temp_pool, asize,
sizeof(ngx_hash_key_t))
!= NGX_OK)
{
return NGX_ERROR;
}
if (ngx_array_init(&ha->dns_wc_tail, ha->temp_pool, asize,
sizeof(ngx_hash_key_t))
!= NGX_OK)
{
@ -556,9 +661,15 @@ ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type)
return NGX_ERROR;
}
ha->dns_wildcards_hash = ngx_pcalloc(ha->temp_pool,
sizeof(ngx_array_t) * ha->hsize);
if (ha->dns_wildcards_hash == NULL) {
ha->dns_wc_head_hash = ngx_pcalloc(ha->temp_pool,
sizeof(ngx_array_t) * ha->hsize);
if (ha->dns_wc_head_hash == NULL) {
return NGX_ERROR;
}
ha->dns_wc_tail_hash = ngx_pcalloc(ha->temp_pool,
sizeof(ngx_array_t) * ha->hsize);
if (ha->dns_wc_tail_hash == NULL) {
return NGX_ERROR;
}
@ -571,37 +682,144 @@ ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value,
ngx_uint_t flags)
{
size_t len;
u_char *reverse;
u_char *p;
ngx_str_t *name;
ngx_uint_t i, k, n, skip;
ngx_uint_t i, k, n, skip, last;
ngx_array_t *keys, *hwc;
ngx_hash_key_t *hk;
if (!(flags & NGX_HASH_WILDCARD_KEY)) {
last = key->len;
/* exact hash */
if (flags & NGX_HASH_WILDCARD_KEY) {
k = 0;
/*
* supported wildcards:
* "*.example.com", ".example.com", and "www.example.*"
*/
n = 0;
for (i = 0; i < key->len; i++) {
if (!(flags & NGX_HASH_READONLY_KEY)) {
key->data[i] = ngx_tolower(key->data[i]);
if (key->data[i] == '*') {
if (++n > 1) {
return NGX_DECLINED;
}
}
if (key->data[i] == '.' && key->data[i + 1] == '.') {
return NGX_DECLINED;
}
k = ngx_hash(k, key->data[i]);
}
k %= ha->hsize;
if (key->len > 1 && key->data[0] == '.') {
skip = 1;
goto wildcard;
}
/* check conflicts in exact hash */
if (key->len > 2) {
if (key->data[0] == '*' && key->data[1] == '.') {
skip = 2;
goto wildcard;
}
if (key->data[i - 2] == '.' && key->data[i - 1] == '*') {
skip = 0;
last -= 2;
goto wildcard;
}
}
if (n) {
return NGX_DECLINED;
}
}
/* exact hash */
k = 0;
for (i = 0; i < last; i++) {
if (!(flags & NGX_HASH_READONLY_KEY)) {
key->data[i] = ngx_tolower(key->data[i]);
}
k = ngx_hash(k, key->data[i]);
}
k %= ha->hsize;
/* check conflicts in exact hash */
name = ha->keys_hash[k].elts;
if (name) {
for (i = 0; i < ha->keys_hash[k].nelts; i++) {
if (last != name[i].len) {
continue;
}
if (ngx_strncmp(key->data, name[i].data, last) == 0) {
return NGX_BUSY;
}
}
} else {
if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,
sizeof(ngx_str_t))
!= NGX_OK)
{
return NGX_ERROR;
}
}
name = ngx_array_push(&ha->keys_hash[k]);
if (name == NULL) {
return NGX_ERROR;
}
*name = *key;
hk = ngx_array_push(&ha->keys);
if (hk == NULL) {
return NGX_ERROR;
}
hk->key = *key;
hk->key_hash = ngx_hash_key(key->data, last);
hk->value = value;
return NGX_OK;
wildcard:
/* wildcard hash */
k = 0;
for (i = skip; i < last; i++) {
key->data[i] = ngx_tolower(key->data[i]);
k = ngx_hash(k, key->data[i]);
}
k %= ha->hsize;
if (skip == 1) {
/* check conflicts in exact hash for ".example.com" */
name = ha->keys_hash[k].elts;
if (name) {
len = last - skip;
for (i = 0; i < ha->keys_hash[k].nelts; i++) {
if (key->len != name[i].len) {
if (len != name[i].len) {
continue;
}
if (ngx_strncmp(key->data, name[i].data, key->len) == 0) {
if (ngx_strncmp(&key->data[1], name[i].data, len) == 0) {
return NGX_BUSY;
}
}
@ -620,92 +838,36 @@ ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value,
return NGX_ERROR;
}
*name = *key;
hk = ngx_array_push(&ha->keys);
if (hk == NULL) {
name->len = last - 1;
name->data = ngx_palloc(ha->temp_pool, name->len);
if (name->data == NULL) {
return NGX_ERROR;
}
hk->key = *key;
hk->key_hash = ngx_hash_key(key->data, key->len);
hk->value = value;
ngx_memcpy(name->data, &key->data[1], name->len);
}
} else {
/* wildcard hash */
skip = (key->data[0] == '*') ? 2 : 1;
k = 0;
for (i = skip; i < key->len; i++) {
key->data[i] = ngx_tolower(key->data[i]);
k = ngx_hash(k, key->data[i]);
}
k %= ha->hsize;
if (skip == 1) {
/* check conflicts in exact hash for ".example.com" */
name = ha->keys_hash[k].elts;
if (name) {
len = key->len - skip;
for (i = 0; i < ha->keys_hash[k].nelts; i++) {
if (len != name[i].len) {
continue;
}
if (ngx_strncmp(&key->data[1], name[i].data, len) == 0) {
return NGX_BUSY;
}
}
} else {
if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,
sizeof(ngx_str_t))
!= NGX_OK)
{
return NGX_ERROR;
}
}
name = ngx_array_push(&ha->keys_hash[k]);
if (name == NULL) {
return NGX_ERROR;
}
name->len = key->len - 1;
name->data = ngx_palloc(ha->temp_pool, name->len);
if (name->data == NULL) {
return NGX_ERROR;
}
ngx_memcpy(name->data, &key->data[1], name->len);
}
if (skip) {
/*
* convert "*.example.com" to "com.example.\0"
* and ".example.com" to "com.example\0"
*/
reverse = ngx_palloc(ha->temp_pool, key->len);
if (reverse == NULL) {
p = ngx_palloc(ha->temp_pool, last);
if (p == NULL) {
return NGX_ERROR;
}
len = 0;
n = 0;
for (i = key->len - 1; i; i--) {
for (i = last - 1; i; i--) {
if (key->data[i] == '.') {
ngx_memcpy(&reverse[n], &key->data[i + 1], len);
ngx_memcpy(&p[n], &key->data[i + 1], len);
n += len;
reverse[n++] = '.';
p[n++] = '.';
len = 0;
continue;
}
@ -714,63 +876,80 @@ ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value,
}
if (len) {
ngx_memcpy(&reverse[n], &key->data[1], len);
ngx_memcpy(&p[n], &key->data[1], len);
n += len;
}
reverse[n] = '\0';
p[n] = '\0';
hwc = &ha->dns_wc_head;
keys = &ha->dns_wc_head_hash[k];
hk = ngx_array_push(&ha->dns_wildcards);
if (hk == NULL) {
} else {
/* convert "www.example.*" to "www.example\0" */
last++;
p = ngx_palloc(ha->temp_pool, last);
if (p == NULL) {
return NGX_ERROR;
}
hk->key.len = key->len - 1;
hk->key.data = reverse;
hk->key_hash = 0;
hk->value = value;
ngx_cpystrn(p, key->data, last);
/* check conflicts in wildcard hash */
name = ha->dns_wildcards_hash[k].elts;
if (name) {
len = key->len - skip;
for (i = 0; i < ha->dns_wildcards_hash[k].nelts; i++) {
if (len != name[i].len) {
continue;
}
if (ngx_strncmp(key->data + skip, name[i].data, len) == 0) {
return NGX_BUSY;
}
}
} else {
if (ngx_array_init(&ha->dns_wildcards_hash[k], ha->temp_pool, 4,
sizeof(ngx_str_t))
!= NGX_OK)
{
return NGX_ERROR;
}
}
name = ngx_array_push(&ha->dns_wildcards_hash[k]);
if (name == NULL) {
return NGX_ERROR;
}
name->len = key->len - skip;
name->data = ngx_palloc(ha->temp_pool, name->len);
if (name->data == NULL) {
return NGX_ERROR;
}
ngx_memcpy(name->data, key->data + skip, name->len);
hwc = &ha->dns_wc_tail;
keys = &ha->dns_wc_tail_hash[k];
}
hk = ngx_array_push(hwc);
if (hk == NULL) {
return NGX_ERROR;
}
hk->key.len = last - 1;
hk->key.data = p;
hk->key_hash = 0;
hk->value = value;
/* check conflicts in wildcard hash */
name = keys->elts;
if (name) {
len = last - skip;
for (i = 0; i < keys->nelts; i++) {
if (len != name[i].len) {
continue;
}
if (ngx_strncmp(key->data + skip, name[i].data, len) == 0) {
return NGX_BUSY;
}
}
} else {
if (ngx_array_init(keys, ha->temp_pool, 4, sizeof(ngx_str_t)) != NGX_OK)
{
return NGX_ERROR;
}
}
name = ngx_array_push(keys);
if (name == NULL) {
return NGX_ERROR;
}
name->len = last - skip;
name->data = ngx_palloc(ha->temp_pool, name->len);
if (name->data == NULL) {
return NGX_ERROR;
}
ngx_memcpy(name->data, key->data + skip, name->len);
return NGX_OK;
}

View File

@ -41,6 +41,13 @@ typedef struct {
typedef ngx_uint_t (*ngx_hash_key_pt) (u_char *data, size_t len);
typedef struct {
ngx_hash_t hash;
ngx_hash_wildcard_t *wc_head;
ngx_hash_wildcard_t *wc_tail;
} ngx_hash_combined_t;
typedef struct {
ngx_hash_t *hash;
ngx_hash_key_pt key;
@ -73,8 +80,11 @@ typedef struct {
ngx_array_t keys;
ngx_array_t *keys_hash;
ngx_array_t dns_wildcards;
ngx_array_t *dns_wildcards_hash;
ngx_array_t dns_wc_head;
ngx_array_t *dns_wc_head_hash;
ngx_array_t dns_wc_tail;
ngx_array_t *dns_wc_tail_hash;
} ngx_hash_keys_arrays_t;
@ -87,8 +97,10 @@ typedef struct {
void *ngx_hash_find(ngx_hash_t *hash, ngx_uint_t key, u_char *name, size_t len);
void *ngx_hash_find_wildcard(ngx_hash_wildcard_t *hwc, u_char *name,
size_t len);
void *ngx_hash_find_wc_head(ngx_hash_wildcard_t *hwc, u_char *name, size_t len);
void *ngx_hash_find_wc_tail(ngx_hash_wildcard_t *hwc, u_char *name, size_t len);
void *ngx_hash_find_combined(ngx_hash_combined_t *hash, ngx_uint_t key,
u_char *name, size_t len);
ngx_int_t ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
ngx_uint_t nelts);

View File

@ -214,12 +214,18 @@ ngx_ptocidr(ngx_str_t *text, void *cidr)
in_cidr->mask = htonl((ngx_uint_t) (0 - (1 << (32 - m))));
return NGX_OK;
if (in_cidr->addr == (in_cidr->addr & in_cidr->mask)) {
return NGX_OK;
}
in_cidr->addr &= in_cidr->mask;
return NGX_DONE;
}
ngx_int_t
ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u)
{
u_char *p, *host, *port_start;
size_t len, port_len;
@ -267,12 +273,12 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
return NGX_ERROR;
}
u->addrs = ngx_pcalloc(cf->pool, sizeof(ngx_peer_addr_t));
u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
if (u->addrs == NULL) {
return NGX_ERROR;
}
saun = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_un));
saun = ngx_pcalloc(pool, sizeof(struct sockaddr_un));
if (saun == NULL) {
return NGX_ERROR;
}
@ -402,12 +408,12 @@ no_port:
if (u->host.len) {
host = ngx_palloc(cf->temp_pool, u->host.len + 1);
if (host == NULL) {
return NGX_ERROR;
}
host = ngx_alloc(u->host.len + 1, pool->log);
if (host == NULL) {
return NGX_ERROR;
}
(void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
(void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
u->addr.in_addr = inet_addr((const char *) host);
@ -415,6 +421,7 @@ no_port:
h = gethostbyname((const char *) host);
if (h == NULL || h->h_addr_list[0] == NULL) {
ngx_free(host);
u->err = "host not found";
return NGX_ERROR;
}
@ -422,6 +429,8 @@ no_port:
u->addr.in_addr = *(in_addr_t *) (h->h_addr_list[0]);
}
ngx_free(host);
} else {
u->addr.in_addr = INADDR_ANY;
}
@ -447,7 +456,7 @@ no_port:
return NGX_ERROR;
}
if (ngx_inet_resolve_host(cf, u) != NGX_OK) {
if (ngx_inet_resolve_host(pool, u) != NGX_OK) {
return NGX_ERROR;
}
@ -456,7 +465,7 @@ no_port:
ngx_int_t
ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
{
u_char *p, *host;
size_t len;
@ -465,7 +474,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
struct hostent *h;
struct sockaddr_in *sin;
host = ngx_palloc(cf->temp_pool, u->host.len + 1);
host = ngx_alloc(u->host.len + 1, pool->log);
if (host == NULL) {
return NGX_ERROR;
}
@ -479,6 +488,8 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
if (in_addr == INADDR_NONE) {
h = gethostbyname((char *) host);
ngx_free(host);
if (h == NULL || h->h_addr_list[0] == NULL) {
u->err = "host not found";
return NGX_ERROR;
@ -493,7 +504,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
/* MP: ngx_shared_palloc() */
u->addrs = ngx_pcalloc(cf->pool, i * sizeof(ngx_peer_addr_t));
u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_peer_addr_t));
if (u->addrs == NULL) {
return NGX_ERROR;
}
@ -502,7 +513,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
for (i = 0; h->h_addr_list[i] != NULL; i++) {
sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
if (sin == NULL) {
return NGX_ERROR;
}
@ -516,7 +527,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1;
p = ngx_palloc(cf->pool, len);
p = ngx_palloc(pool, len);
if (p == NULL) {
return NGX_ERROR;
}
@ -529,14 +540,16 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
} else {
ngx_free(host);
/* MP: ngx_shared_palloc() */
u->addrs = ngx_pcalloc(cf->pool, sizeof(ngx_peer_addr_t));
u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
if (u->addrs == NULL) {
return NGX_ERROR;
}
sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
if (sin == NULL) {
return NGX_ERROR;
}
@ -550,7 +563,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
u->addrs[0].sockaddr = (struct sockaddr *) sin;
u->addrs[0].socklen = sizeof(struct sockaddr_in);
p = ngx_palloc(cf->pool, u->host.len + sizeof(":65536") - 1);
p = ngx_palloc(pool, u->host.len + sizeof(":65536") - 1);
if (p == NULL) {
return NGX_ERROR;
}

View File

@ -61,8 +61,8 @@ typedef struct {
size_t ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text, size_t len);
size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr);
ngx_int_t ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u);
ngx_int_t ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u);
ngx_int_t ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u);
ngx_int_t ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u);

40
src/core/ngx_md5.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright (C) Igor Sysoev
*/
#ifndef _NGX_MD5_H_INCLUDED_
#define _NGX_MD5_H_INCLUDED_
#include <ngx_config.h>
#include <ngx_core.h>
#if (NGX_HAVE_OPENSSL_MD5_H)
#include <openssl/md5.h>
#else
#include <md5.h>
#endif
typedef MD5_CTX ngx_md5_t;
#if (NGX_OPENSSL_MD5)
#define ngx_md5_init MD5_Init
#define ngx_md5_update MD5_Update
#define ngx_md5_final MD5_Final
#else
#define ngx_md5_init MD5Init
#define ngx_md5_update MD5Update
#define ngx_md5_final MD5Final
#endif
#endif /* _NGX_MD5_H_INCLUDED_ */

View File

@ -163,6 +163,7 @@ ngx_palloc(ngx_pool_t *pool, size_t size)
large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
if (large == NULL) {
ngx_free(p);
return NULL;
}

30
src/core/ngx_sha1.h Normal file
View File

@ -0,0 +1,30 @@
/*
* Copyright (C) Igor Sysoev
*/
#ifndef _NGX_SHA1_H_INCLUDED_
#define _NGX_SHA1_H_INCLUDED_
#include <ngx_config.h>
#include <ngx_core.h>
#if (NGX_HAVE_OPENSSL_SHA1_H)
#include <openssl/sha.h>
#else
#include <sha.h>
#endif
typedef SHA_CTX ngx_sha1_t;
#define ngx_sha1_init SHA1_Init
#define ngx_sha1_update SHA1_Update
#define ngx_sha1_final SHA1_Final
#endif /* _NGX_SHA1_H_INCLUDED_ */

View File

@ -111,10 +111,7 @@ ngx_slab_init(ngx_slab_pool_t *pool)
p += n * sizeof(ngx_slab_page_t);
/* STUB: possible overflow on 64-bit platform */
pages = (ngx_uint_t) ((uint64_t) size * ngx_pagesize
/ (ngx_pagesize + sizeof(ngx_slab_page_t))
/ ngx_pagesize);
pages = (ngx_uint_t) (size / (ngx_pagesize + sizeof(ngx_slab_page_t)));
ngx_memzero(p, pages * sizeof(ngx_slab_page_t));

View File

@ -59,8 +59,9 @@ ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src)
* %P ngx_pid_t
* %M ngx_msec_t
* %r rlim_t
* %p pointer
* %V pointer to ngx_str_t
* %p void *
* %V ngx_str_t *
* %v ngx_variable_value_t *
* %s null-terminated string
* %Z '\0'
* %N '\n'
@ -105,21 +106,22 @@ ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...)
u_char *
ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
{
u_char *p, zero, *last, temp[NGX_INT64_LEN + 1];
u_char *p, zero, *last, temp[NGX_INT64_LEN + 1];
/*
* really we need temp[NGX_INT64_LEN] only,
* but icc issues the warning
*/
int d;
size_t len;
uint32_t ui32;
int64_t i64;
uint64_t ui64;
ngx_msec_t ms;
ngx_str_t *s;
ngx_uint_t width, sign, hexadecimal, max_width;
static u_char hex[] = "0123456789abcdef";
static u_char HEX[] = "0123456789ABCDEF";
int d;
size_t len;
uint32_t ui32;
int64_t i64;
uint64_t ui64;
ngx_msec_t ms;
ngx_uint_t width, sign, hexadecimal, max_width;
ngx_str_t *v;
ngx_variable_value_t *vv;
static u_char hex[] = "0123456789abcdef";
static u_char HEX[] = "0123456789ABCDEF";
if (max == 0) {
return buf;
@ -188,12 +190,23 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
switch (*fmt) {
case 'V':
s = va_arg(args, ngx_str_t *);
v = va_arg(args, ngx_str_t *);
len = s->len & 0xffff;
len = v->len;
len = (buf + len < last) ? len : (size_t) (last - buf);
buf = ngx_cpymem(buf, s->data, len);
buf = ngx_cpymem(buf, v->data, len);
fmt++;
continue;
case 'v':
vv = va_arg(args, ngx_variable_value_t *);
len = vv->len;
len = (buf + len < last) ? len : (size_t) (last - buf);
buf = ngx_cpymem(buf, vv->data, len);
fmt++;
continue;
@ -429,7 +442,7 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
/*
* We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII string only,
* We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII strings only,
* and implement our own ngx_strcasecmp()/ngx_strncasecmp()
* to avoid libc locale overhead. Besides, we use the ngx_uint_t's
* instead of the u_char's, because they are slightly faster.
@ -490,6 +503,95 @@ ngx_strncasecmp(u_char *s1, u_char *s2, size_t n)
}
u_char *
ngx_strnstr(u_char *s1, char *s2, size_t len)
{
u_char c1, c2;
size_t n;
c2 = *(u_char *) s2++;
n = ngx_strlen(s2);
do {
do {
if (len-- == 0) {
return NULL;
}
c1 = *s1++;
if (c1 == 0) {
return NULL;
}
} while (c1 != c2);
if (n > len) {
return NULL;
}
} while (ngx_strncmp(s1, (u_char *) s2, n) != 0);
return --s1;
}
/*
* ngx_strstrn() and ngx_strcasestrn() are intended to search for static
* substring with known length in null-terminated string. The argument n
* must be length of the second substring - 1.
*/
u_char *
ngx_strstrn(u_char *s1, char *s2, size_t n)
{
u_char c1, c2;
c2 = *(u_char *) s2++;
do {
do {
c1 = *s1++;
if (c1 == 0) {
return NULL;
}
} while (c1 != c2);
} while (ngx_strncmp(s1, (u_char *) s2, n) != 0);
return --s1;
}
u_char *
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;
do {
do {
c1 = (ngx_uint_t) *s1++;
if (c1 == 0) {
return NULL;
}
c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
} while (c1 != c2);
} while (ngx_strncasecmp(s1, (u_char *) s2, n) != 0);
return --s1;
}
ngx_int_t
ngx_rstrncmp(u_char *s1, u_char *s2, size_t n)
{
@ -1019,13 +1121,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 html[] = {
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
0x800000ad, /* 0000 0000 0000 0000 0000 0000 1010 1101 */
0x000000ad, /* 0000 0000 0000 0000 0000 0000 1010 1101 */
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
@ -1039,18 +1141,53 @@ 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 */
switch (type) {
case NGX_ESCAPE_HTML:
escape = html;
break;
case NGX_ESCAPE_ARGS:
escape = args;
break;
default:
escape = uri;
break;
}
static uint32_t refresh[] = {
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
0x00000085, /* 0000 0000 0000 0000 0000 0000 1000 0101 */
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
};
/* " ", "%", %00-%1F */
static uint32_t memcached[] = {
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
0x00000021, /* 0000 0000 0000 0000 0000 0000 0010 0001 */
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
};
/* mail_auth is the same as memcached */
static uint32_t *map[] =
{ uri, args, html, refresh, memcached, memcached };
escape = map[type];
if (dst == NULL) {
@ -1106,7 +1243,9 @@ ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type)
switch (state) {
case sw_usual:
if (ch == '?' && type == NGX_UNESCAPE_URI) {
if (ch == '?'
&& (type & (NGX_UNESCAPE_URI|NGX_UNESCAPE_REDIRECT)))
{
*d++ = ch;
goto done;
}
@ -1149,7 +1288,7 @@ ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type)
if (ch >= '0' && ch <= '9') {
ch = (u_char) ((decoded << 4) + ch - '0');
if (type == NGX_UNESCAPE_URI) {
if (type & NGX_UNESCAPE_REDIRECT) {
if (ch > '%' && ch < 0x7f) {
*d++ = ch;
break;
@ -1169,7 +1308,17 @@ ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type)
if (c >= 'a' && c <= 'f') {
ch = (u_char) ((decoded << 4) + c - 'a' + 10);
if (type == NGX_UNESCAPE_URI) {
if (type & NGX_UNESCAPE_URI) {
if (ch == '?') {
*d++ = ch;
goto done;
}
*d++ = ch;
break;
}
if (type & NGX_UNESCAPE_REDIRECT) {
if (ch == '?') {
*d++ = ch;
goto done;
@ -1202,6 +1351,67 @@ done:
}
uintptr_t
ngx_escape_html(u_char *dst, u_char *src, size_t size)
{
u_char ch;
ngx_uint_t i, len;
if (dst == NULL) {
len = 0;
for (i = 0; i < size; i++) {
switch (*src++) {
case '<':
len += sizeof("&lt;") - 2;
break;
case '>':
len += sizeof("&gt;") - 2;
break;
case '&':
len += sizeof("&amp;") - 2;
break;
default:
break;
}
}
return (uintptr_t) len;
}
for (i = 0; i < size; i++) {
ch = *src++;
switch (ch) {
case '<':
*dst++ = '&'; *dst++ = 'l'; *dst++ = 't'; *dst++ = ';';
break;
case '>':
*dst++ = '&'; *dst++ = 'g'; *dst++ = 't'; *dst++ = ';';
break;
case '&':
*dst++ = '&'; *dst++ = 'a'; *dst++ = 'm'; *dst++ = 'p';
*dst++ = ';';
break;
default:
*dst++ = ch;
break;
}
}
return (uintptr_t) dst;
}
/* ngx_sort() is implemented as insertion sort because we need stable sort */
void

View File

@ -13,17 +13,28 @@
typedef struct {
size_t len;
u_char *data;
size_t len;
u_char *data;
} ngx_str_t;
typedef struct {
ngx_str_t key;
ngx_str_t value;
ngx_str_t key;
ngx_str_t value;
} ngx_keyval_t;
typedef struct {
unsigned len:29;
unsigned valid:1;
unsigned no_cacheable:1;
unsigned not_found:1;
u_char *data;
} ngx_variable_value_t;
#define ngx_string(str) { sizeof(str) - 1, (u_char *) str }
#define ngx_null_string { 0, NULL }
@ -115,6 +126,11 @@ u_char *ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args);
ngx_int_t ngx_strcasecmp(u_char *s1, u_char *s2);
ngx_int_t ngx_strncasecmp(u_char *s1, u_char *s2, size_t n);
u_char *ngx_strnstr(u_char *s1, char *s2, size_t n);
u_char *ngx_strstrn(u_char *s1, char *s2, size_t n);
u_char *ngx_strcasestrn(u_char *s1, 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);
@ -139,24 +155,30 @@ size_t ngx_utf_length(u_char *p, size_t n);
u_char *ngx_utf_cpystrn(u_char *dst, u_char *src, size_t n);
#define NGX_ESCAPE_URI 0
#define NGX_ESCAPE_ARGS 1
#define NGX_ESCAPE_HTML 2
#define NGX_ESCAPE_URI 0
#define NGX_ESCAPE_ARGS 1
#define NGX_ESCAPE_HTML 2
#define NGX_ESCAPE_REFRESH 3
#define NGX_ESCAPE_MEMCACHED 4
#define NGX_ESCAPE_MAIL_AUTH 5
#define NGX_UNESCAPE_URI 1
#define NGX_UNESCAPE_URI 1
#define NGX_UNESCAPE_REDIRECT 2
uintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size,
ngx_uint_t type);
void ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type);
uintptr_t ngx_escape_html(u_char *dst, u_char *src, size_t size);
void ngx_sort(void *base, size_t n, size_t size,
int (*cmp)(const void *, const void *));
#define ngx_qsort qsort
#define ngx_qsort qsort
#define ngx_value_helper(n) #n
#define ngx_value(n) ngx_value_helper(n)
#define ngx_value_helper(n) #n
#define ngx_value(n) ngx_value_helper(n)
#endif /* _NGX_STRING_H_INCLUDED_ */

View File

@ -16,9 +16,11 @@
static ngx_int_t ngx_aio_init(ngx_cycle_t *cycle, ngx_msec_t timer);
static void ngx_aio_done(ngx_cycle_t *cycle);
static ngx_int_t ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags);
static ngx_int_t ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags);
static ngx_int_t ngx_aio_del_connection(ngx_connection_t *c, u_int flags);
static ngx_int_t ngx_aio_add_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_aio_del_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_aio_del_connection(ngx_connection_t *c, ngx_uint_t flags);
static ngx_int_t ngx_aio_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags);
@ -100,21 +102,21 @@ ngx_aio_done(ngx_cycle_t *cycle)
/* the event adding and deleting are needed for the listening sockets */
static ngx_int_t
ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags)
ngx_aio_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
return ngx_kqueue_module_ctx.actions.add(ev, event, flags);
}
static ngx_int_t
ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags)
ngx_aio_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
return ngx_kqueue_module_ctx.actions.del(ev, event, flags);
}
static ngx_int_t
ngx_aio_del_connection(ngx_connection_t *c, u_int flags)
ngx_aio_del_connection(ngx_connection_t *c, ngx_uint_t flags)
{
int rc;

View File

@ -15,6 +15,7 @@
#define POLLREMOVE 0x0800
#define DP_POLL 0xD001
#define DP_ISPOLLED 0xD002
struct dvpoll {
struct pollfd *dp_fds;
@ -26,16 +27,19 @@ struct dvpoll {
typedef struct {
u_int changes;
u_int events;
ngx_uint_t changes;
ngx_uint_t events;
} ngx_devpoll_conf_t;
static ngx_int_t ngx_devpoll_init(ngx_cycle_t *cycle, ngx_msec_t timer);
static void ngx_devpoll_done(ngx_cycle_t *cycle);
static ngx_int_t ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags);
static ngx_int_t ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags);
static ngx_int_t ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags);
static ngx_int_t ngx_devpoll_add_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_devpoll_del_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_devpoll_set_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_devpoll_process_events(ngx_cycle_t *cycle,
ngx_msec_t timer, ngx_uint_t flags);
@ -44,7 +48,7 @@ static char *ngx_devpoll_init_conf(ngx_cycle_t *cycle, void *conf);
static int dp = -1;
static struct pollfd *change_list, *event_list;
static u_int nchanges, max_changes, nevents;
static ngx_uint_t nchanges, max_changes, nevents;
static ngx_event_t **change_index;
@ -208,7 +212,7 @@ ngx_devpoll_done(ngx_cycle_t *cycle)
static ngx_int_t
ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags)
ngx_devpoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
#if (NGX_DEBUG)
ngx_connection_t *c;
@ -221,7 +225,7 @@ ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags)
#if (NGX_DEBUG)
c = ev->data;
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"devpoll add event: fd:%d ev:%04Xd", c->fd, event);
"devpoll add event: fd:%d ev:%04Xi", c->fd, event);
#endif
ev->active = 1;
@ -231,7 +235,7 @@ ngx_devpoll_add_event(ngx_event_t *ev, int event, u_int flags)
static ngx_int_t
ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags)
ngx_devpoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
ngx_event_t *e;
ngx_connection_t *c;
@ -243,7 +247,7 @@ ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags)
#endif
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"devpoll del event: fd:%d ev:%04Xd", c->fd, event);
"devpoll del event: fd:%d ev:%04Xi", c->fd, event);
if (ngx_devpoll_set_event(ev, POLLREMOVE, flags) == NGX_ERROR) {
return NGX_ERROR;
@ -252,10 +256,16 @@ ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags)
ev->active = 0;
if (flags & NGX_CLOSE_EVENT) {
e = (event == POLLIN) ? c->write : c->read;
if (e) {
e->active = 0;
}
return NGX_OK;
}
/* restore the paired event if it exists */
/* restore the pair event if it exists */
if (event == POLLIN) {
e = c->write;
@ -275,7 +285,7 @@ ngx_devpoll_del_event(ngx_event_t *ev, int event, u_int flags)
static ngx_int_t
ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags)
ngx_devpoll_set_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
size_t n;
ngx_connection_t *c;
@ -283,7 +293,7 @@ ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags)
c = ev->data;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"devpoll fd:%d ev:%04Xd fl:%04Xd", c->fd, event, flags);
"devpoll fd:%d ev:%04Xi fl:%04Xi", c->fd, event, flags);
if (nchanges >= max_changes) {
ngx_log_error(NGX_LOG_WARN, ev->log, 0,
@ -300,7 +310,7 @@ ngx_devpoll_set_event(ngx_event_t *ev, int event, u_int flags)
}
change_list[nchanges].fd = c->fd;
change_list[nchanges].events = event;
change_list[nchanges].events = (short) event;
change_list[nchanges].revents = 0;
change_index[nchanges] = ev;
@ -327,13 +337,15 @@ ngx_int_t
ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags)
{
int events, revents;
int events, revents, rc;
size_t n;
ngx_fd_t fd;
ngx_err_t err;
ngx_int_t i;
ngx_uint_t level;
ngx_event_t *rev, *wev, **queue;
ngx_connection_t *c;
struct pollfd pfd;
struct dvpoll dvp;
/* NGX_TIMER_INFINITE == INFTIM */
@ -353,7 +365,7 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
}
dvp.dp_fds = event_list;
dvp.dp_nfds = nevents;
dvp.dp_nfds = (int) nevents;
dvp.dp_timeout = timer;
events = ioctl(dp, DP_POLL, &dvp);
@ -398,34 +410,77 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_mutex_lock(ngx_posted_events_mutex);
for (i = 0; i < events; i++) {
c = ngx_cycle->files[event_list[i].fd];
if (c->fd == -1) {
if (c->read->closed) {
continue;
fd = event_list[i].fd;
revents = event_list[i].revents;
c = ngx_cycle->files[fd];
if (c == NULL || c->fd == -1) {
pfd.fd = fd;
pfd.events = 0;
pfd.revents = 0;
rc = ioctl(dp, DP_ISPOLLED, &pfd);
switch (rc) {
case -1:
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"ioctl(DP_ISPOLLED) failed for socket %d, event",
fd, revents);
break;
case 0:
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"phantom event %04Xd for closed and removed socket %d",
revents, fd);
break;
default:
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"unexpected event %04Xd for closed and removed socket %d, ",
"ioctl(DP_ISPOLLED) returned rc:%d, fd:%d, event %04Xd",
revents, fd, rc, pfd.fd, pfd.revents);
pfd.fd = fd;
pfd.events = POLLREMOVE;
pfd.revents = 0;
if (write(dp, &pfd, sizeof(struct pollfd))
!= (ssize_t) sizeof(struct pollfd))
{
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"write(/dev/poll) for %d failed, fd");
}
if (close(fd) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"close(%d) failed", fd);
}
break;
}
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected event");
continue;
}
revents = event_list[i].revents;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"devpoll: fd:%d, ev:%04Xd, rev:%04Xd",
event_list[i].fd, event_list[i].events, revents);
fd, event_list[i].events, revents);
if (revents & (POLLERR|POLLHUP|POLLNVAL)) {
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"ioctl(DP_POLL) error fd:%d ev:%04Xd rev:%04Xd",
event_list[i].fd, event_list[i].events, revents);
fd, event_list[i].events, revents);
}
if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"strange ioctl(DP_POLL) events "
"fd:%d ev:%04Xd rev:%04Xd",
event_list[i].fd, event_list[i].events, revents);
fd, event_list[i].events, revents);
}
if ((revents & (POLLERR|POLLHUP|POLLNVAL))

View File

@ -66,16 +66,19 @@ int epoll_wait(int epfd, struct epoll_event *events, int nevents, int timeout)
typedef struct {
u_int events;
ngx_uint_t events;
} ngx_epoll_conf_t;
static ngx_int_t ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer);
static void ngx_epoll_done(ngx_cycle_t *cycle);
static ngx_int_t ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags);
static ngx_int_t ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags);
static ngx_int_t ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_epoll_del_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_epoll_add_connection(ngx_connection_t *c);
static ngx_int_t ngx_epoll_del_connection(ngx_connection_t *c, u_int flags);
static ngx_int_t ngx_epoll_del_connection(ngx_connection_t *c,
ngx_uint_t flags);
static ngx_int_t ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags);
@ -84,7 +87,7 @@ static char *ngx_epoll_init_conf(ngx_cycle_t *cycle, void *conf);
static int ep = -1;
static struct epoll_event *event_list;
static u_int nevents;
static ngx_uint_t nevents;
static ngx_str_t epoll_name = ngx_string("epoll");
@ -205,7 +208,7 @@ ngx_epoll_done(ngx_cycle_t *cycle)
static ngx_int_t
ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags)
ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
int op;
uint32_t events, prev;
@ -240,7 +243,7 @@ ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags)
op = EPOLL_CTL_ADD;
}
ee.events = events | flags;
ee.events = events | (uint32_t) flags;
ee.data.ptr = (void *) ((uintptr_t) c | ev->instance);
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
@ -263,7 +266,7 @@ ngx_epoll_add_event(ngx_event_t *ev, int event, u_int flags)
static ngx_int_t
ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags)
ngx_epoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
int op;
uint32_t prev;
@ -295,7 +298,7 @@ ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags)
if (e->active) {
op = EPOLL_CTL_MOD;
ee.events = prev | flags;
ee.events = prev | (uint32_t) flags;
ee.data.ptr = (void *) ((uintptr_t) c | ev->instance);
} else {
@ -345,10 +348,10 @@ ngx_epoll_add_connection(ngx_connection_t *c)
static ngx_int_t
ngx_epoll_del_connection(ngx_connection_t *c, u_int flags)
ngx_epoll_del_connection(ngx_connection_t *c, ngx_uint_t flags)
{
int op;
struct epoll_event ee;
int op;
struct epoll_event ee;
/*
* when the file descriptor is closed the epoll automatically deletes
@ -399,7 +402,7 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"epoll timer: %M", timer);
events = epoll_wait(ep, event_list, nevents, timer);
events = epoll_wait(ep, event_list, (int) nevents, timer);
if (events == -1) {
err = ngx_errno;

View File

@ -40,11 +40,15 @@ typedef struct port_notify {
void *portnfy_user; /* user defined */
} port_notify_t;
typedef struct itimerspec { /* definition per POSIX.4 */
struct timespec it_interval; /* timer period */
struct timespec it_value; /* timer expiration */
#if (__FreeBSD_version < 700005)
typedef struct itimerspec { /* definition per POSIX.4 */
struct timespec it_interval;/* timer period */
struct timespec it_value; /* timer expiration */
} itimerspec_t;
#endif
int port_create(void)
{
return -1;
@ -87,16 +91,16 @@ int timer_delete(timer_t timerid)
typedef struct {
u_int events;
ngx_uint_t events;
} ngx_eventport_conf_t;
static ngx_int_t ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer);
static void ngx_eventport_done(ngx_cycle_t *cycle);
static ngx_int_t ngx_eventport_add_event(ngx_event_t *ev, int event,
u_int flags);
static ngx_int_t ngx_eventport_del_event(ngx_event_t *ev, int event,
u_int flags);
static ngx_int_t ngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_eventport_process_events(ngx_cycle_t *cycle,
ngx_msec_t timer, ngx_uint_t flags);
@ -105,8 +109,8 @@ static char *ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf);
static int ep = -1;
static port_event_t *event_list;
static u_int nevents;
static timer_t event_timer = -1;
static ngx_uint_t nevents;
static timer_t event_timer = (timer_t) -1;
static ngx_str_t eventport_name = ngx_string("eventport");
@ -237,13 +241,13 @@ ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer)
static void
ngx_eventport_done(ngx_cycle_t *cycle)
{
if (event_timer != -1) {
if (event_timer != (timer_t) -1) {
if (timer_delete(event_timer) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"timer_delete() failed");
}
event_timer = -1;
event_timer = (timer_t) -1;
}
if (close(ep) == -1) {
@ -261,9 +265,9 @@ ngx_eventport_done(ngx_cycle_t *cycle)
static ngx_int_t
ngx_eventport_add_event(ngx_event_t *ev, int event, u_int flags)
ngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
int events, prev;
ngx_int_t events, prev;
ngx_event_t *e;
ngx_connection_t *c;
@ -291,7 +295,7 @@ ngx_eventport_add_event(ngx_event_t *ev, int event, u_int flags)
}
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"eventport add event: fd:%d ev:%04Xd", c->fd, events);
"eventport add event: fd:%d ev:%04Xi", c->fd, events);
if (port_associate(ep, PORT_SOURCE_FD, c->fd, events,
(void *) ((uintptr_t) ev | ev->instance))
@ -310,7 +314,7 @@ ngx_eventport_add_event(ngx_event_t *ev, int event, u_int flags)
static ngx_int_t
ngx_eventport_del_event(ngx_event_t *ev, int event, u_int flags)
ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
ngx_event_t *e;
ngx_connection_t *c;
@ -340,7 +344,7 @@ ngx_eventport_del_event(ngx_event_t *ev, int event, u_int flags)
if (e->oneshot) {
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"eventport change event: fd:%d ev:%04Xd", c->fd, event);
"eventport change event: fd:%d ev:%04Xi", c->fd, event);
if (port_associate(ep, PORT_SOURCE_FD, c->fd, event,
(void *) ((uintptr_t) ev | ev->instance))
@ -396,7 +400,7 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
events = 1;
n = port_getn(ep, event_list, nevents, &events, tp);
n = port_getn(ep, event_list, (u_int) nevents, &events, tp);
err = ngx_errno;
@ -514,6 +518,10 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
} else {
rev->handler(rev);
if (ev->closed) {
continue;
}
}
if (rev->accept) {

View File

@ -13,8 +13,9 @@
static ngx_int_t ngx_iocp_init(ngx_cycle_t *cycle, ngx_msec_t timer);
static ngx_thread_value_t __stdcall ngx_iocp_timer(void *data);
static void ngx_iocp_done(ngx_cycle_t *cycle);
static ngx_int_t ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key);
static ngx_int_t ngx_iocp_del_connection(ngx_connection_t *c, u_int flags);
static ngx_int_t ngx_iocp_add_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t key);
static ngx_int_t ngx_iocp_del_connection(ngx_connection_t *c, ngx_uint_t flags);
static ngx_int_t ngx_iocp_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags);
static void *ngx_iocp_create_conf(ngx_cycle_t *cycle);
@ -186,7 +187,7 @@ ngx_iocp_done(ngx_cycle_t *cycle)
static ngx_int_t
ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key)
ngx_iocp_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t key)
{
ngx_connection_t *c;
@ -196,7 +197,7 @@ ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key)
c->write->active = 1;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"iocp add: fd:%d k:%d ov:%p", c->fd, key, &ev->ovlp);
"iocp add: fd:%d k:%ui ov:%p", c->fd, key, &ev->ovlp);
if (CreateIoCompletionPort((HANDLE) c->fd, iocp, key, 0) == NULL) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
@ -209,7 +210,7 @@ ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key)
static ngx_int_t
ngx_iocp_del_connection(ngx_connection_t *c, u_int flags)
ngx_iocp_del_connection(ngx_connection_t *c, ngx_uint_t flags)
{
#if 0
if (flags & NGX_CLOSE_EVENT) {

View File

@ -11,16 +11,19 @@
typedef struct {
int changes;
int events;
ngx_uint_t changes;
ngx_uint_t events;
} ngx_kqueue_conf_t;
static ngx_int_t ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer);
static void ngx_kqueue_done(ngx_cycle_t *cycle);
static ngx_int_t ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags);
static ngx_int_t ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags);
static ngx_int_t ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags);
static ngx_int_t ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_kqueue_del_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter,
ngx_uint_t flags);
static ngx_int_t ngx_kqueue_process_changes(ngx_cycle_t *cycle, ngx_uint_t try);
static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags);
@ -43,7 +46,7 @@ int ngx_kqueue = -1;
static struct kevent *change_list, *change_list0, *change_list1;
static struct kevent *event_list;
static int max_changes, nchanges, nevents;
static ngx_uint_t max_changes, nchanges, nevents;
#if (NGX_THREADS)
static ngx_mutex_t *list_mutex;
@ -151,7 +154,9 @@ ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer)
ts.tv_sec = 0;
ts.tv_nsec = 0;
if (kevent(ngx_kqueue, change_list, nchanges, NULL, 0, &ts) == -1) {
if (kevent(ngx_kqueue, change_list, (int) nchanges, NULL, 0, &ts)
== -1)
{
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"kevent() failed");
return NGX_ERROR;
@ -273,7 +278,7 @@ ngx_kqueue_done(ngx_cycle_t *cycle)
static ngx_int_t
ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
ngx_int_t rc;
#if 0
@ -289,7 +294,7 @@ ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
#if 0
if (ev->index < (u_int) nchanges
if (ev->index < nchanges
&& ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1)
== (uintptr_t) ev)
{
@ -301,10 +306,10 @@ ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
*/
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"kevent activated: %d: ft:%d",
"kevent activated: %d: ft:%i",
ngx_event_ident(ev->data), event);
if (ev->index < (u_int) --nchanges) {
if (ev->index < --nchanges) {
e = (ngx_event_t *)
((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1);
change_list[ev->index] = change_list[nchanges];
@ -337,7 +342,7 @@ ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
static ngx_int_t
ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
ngx_kqueue_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
ngx_int_t rc;
ngx_event_t *e;
@ -347,19 +352,19 @@ ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
ngx_mutex_lock(list_mutex);
if (ev->index < (u_int) nchanges
if (ev->index < nchanges
&& ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1)
== (uintptr_t) ev)
{
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"kevent deleted: %d: ft:%d",
"kevent deleted: %d: ft:%i",
ngx_event_ident(ev->data), event);
/* if the event is still not passed to a kernel we will not pass it */
nchanges--;
if (ev->index < (u_int) nchanges) {
if (ev->index < nchanges) {
e = (ngx_event_t *)
((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1);
change_list[ev->index] = change_list[nchanges];
@ -396,7 +401,7 @@ ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags)
static ngx_int_t
ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter, ngx_uint_t flags)
{
struct kevent *kev;
struct timespec ts;
@ -404,8 +409,8 @@ ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
c = ev->data;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
"kevent set event: %d: ft:%d fl:%04Xd",
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"kevent set event: %d: ft:%i fl:%04Xi",
c->fd, filter, flags);
if (nchanges >= max_changes) {
@ -415,7 +420,9 @@ ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
ts.tv_sec = 0;
ts.tv_nsec = 0;
if (kevent(ngx_kqueue, change_list, nchanges, NULL, 0, &ts) == -1) {
if (kevent(ngx_kqueue, change_list, (int) nchanges, NULL, 0, &ts)
== -1)
{
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "kevent() failed");
return NGX_ERROR;
}
@ -426,8 +433,8 @@ ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
kev = &change_list[nchanges];
kev->ident = c->fd;
kev->filter = filter;
kev->flags = flags;
kev->filter = (short) filter;
kev->flags = (u_short) flags;
kev->udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ev | ev->instance);
if (filter == EVFILT_VNODE) {
@ -482,7 +489,7 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
n = 0;
} else {
n = nchanges;
n = (int) nchanges;
nchanges = 0;
}
@ -510,7 +517,7 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"kevent timer: %M, changes: %d", timer, n);
events = kevent(ngx_kqueue, change_list, n, event_list, nevents, tp);
events = kevent(ngx_kqueue, change_list, n, event_list, (int) nevents, tp);
if (events == -1) {
err = ngx_errno;
@ -696,7 +703,7 @@ ngx_kqueue_process_changes(ngx_cycle_t *cycle, ngx_uint_t try)
change_list = change_list0;
}
n = nchanges;
n = (int) nchanges;
nchanges = 0;
ngx_mutex_unlock(list_mutex);
@ -758,8 +765,8 @@ ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf)
{
ngx_kqueue_conf_t *kcf = conf;
ngx_conf_init_value(kcf->changes, 512);
ngx_conf_init_value(kcf->events, 512);
ngx_conf_init_uint_value(kcf->changes, 512);
ngx_conf_init_uint_value(kcf->events, 512);
return NGX_CONF_OK;
}

View File

@ -13,5 +13,4 @@ extern ngx_module_t ngx_kqueue_module;
extern ngx_event_module_t ngx_kqueue_module_ctx;
#endif /* _NGX_KQUEUE_MODULE_H_INCLUDED_ */

View File

@ -11,15 +11,17 @@
static ngx_int_t ngx_poll_init(ngx_cycle_t *cycle, ngx_msec_t timer);
static void ngx_poll_done(ngx_cycle_t *cycle);
static ngx_int_t ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags);
static ngx_int_t ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags);
static ngx_int_t ngx_poll_add_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_poll_del_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags);
static char *ngx_poll_init_conf(ngx_cycle_t *cycle, void *conf);
static struct pollfd *event_list;
static int nevents;
static ngx_int_t nevents;
static ngx_str_t poll_name = ngx_string("poll");
@ -108,7 +110,7 @@ ngx_poll_done(ngx_cycle_t *cycle)
static ngx_int_t
ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags)
ngx_poll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
ngx_event_t *e;
ngx_connection_t *c;
@ -119,7 +121,7 @@ ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags)
if (ev->index != NGX_INVALID_INDEX) {
ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
"poll event fd:%d ev:%d is already set", c->fd, event);
"poll event fd:%d ev:%i is already set", c->fd, event);
return NGX_OK;
}
@ -137,11 +139,11 @@ ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags)
}
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"poll add event: fd:%d ev:%d", c->fd, event);
"poll add event: fd:%d ev:%i", c->fd, event);
if (e == NULL || e->index == NGX_INVALID_INDEX) {
event_list[nevents].fd = c->fd;
event_list[nevents].events = event;
event_list[nevents].events = (short) event;
event_list[nevents].revents = 0;
ev->index = nevents;
@ -149,9 +151,9 @@ ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags)
} else {
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"poll add index: %d", e->index);
"poll add index: %i", e->index);
event_list[e->index].events |= event;
event_list[e->index].events |= (short) event;
ev->index = e->index;
}
@ -160,7 +162,7 @@ ngx_poll_add_event(ngx_event_t *ev, int event, u_int flags)
static ngx_int_t
ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags)
ngx_poll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
ngx_event_t *e;
ngx_connection_t *c;
@ -171,7 +173,7 @@ ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags)
if (ev->index == NGX_INVALID_INDEX) {
ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
"poll event fd:%d ev:%d is already deleted",
"poll event fd:%d ev:%i is already deleted",
c->fd, event);
return NGX_OK;
}
@ -190,15 +192,15 @@ ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags)
}
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"poll del event: fd:%d ev:%d", c->fd, event);
"poll del event: fd:%d ev:%i", c->fd, event);
if (e == NULL || e->index == NGX_INVALID_INDEX) {
nevents--;
if (ev->index < (u_int) nevents) {
if (ev->index < (ngx_uint_t) nevents) {
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"index: copy event %d to %d", nevents, ev->index);
"index: copy event %ui to %i", nevents, ev->index);
event_list[ev->index] = event_list[nevents];
@ -209,11 +211,11 @@ ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags)
"unexpected last event");
} else {
if (c->read->index == (u_int) nevents) {
if (c->read->index == (ngx_uint_t) nevents) {
c->read->index = ev->index;
}
if (c->write->index == (u_int) nevents) {
if (c->write->index == (ngx_uint_t) nevents) {
c->write->index = ev->index;
}
}
@ -221,9 +223,9 @@ ngx_poll_del_event(ngx_event_t *ev, int event, u_int flags)
} else {
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"poll del index: %d", e->index);
"poll del index: %i", e->index);
event_list[e->index].events &= ~event;
event_list[e->index].events &= (short) ~event;
}
ev->index = NGX_INVALID_INDEX;

View File

@ -11,9 +11,14 @@
#if (NGX_TEST_BUILD_RTSIG)
#define F_SETSIG 10
#ifdef SIGRTMIN
#define si_fd _reason.__spare__.__spare2__[0]
#else
#define SIGRTMIN 33
#define si_fd __spare__[0]
#endif
#define F_SETSIG 10
#define KERN_RTSIGNR 30
#define KERN_RTSIGMAX 31
@ -29,10 +34,10 @@ int ngx_linux_rtsig_max;
typedef struct {
int signo;
ngx_int_t overflow_events;
ngx_int_t overflow_test;
ngx_int_t overflow_threshold;
ngx_uint_t signo;
ngx_uint_t overflow_events;
ngx_uint_t overflow_test;
ngx_uint_t overflow_threshold;
} ngx_rtsig_conf_t;
@ -41,7 +46,8 @@ extern ngx_event_module_t ngx_poll_module_ctx;
static ngx_int_t ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer);
static void ngx_rtsig_done(ngx_cycle_t *cycle);
static ngx_int_t ngx_rtsig_add_connection(ngx_connection_t *c);
static ngx_int_t ngx_rtsig_del_connection(ngx_connection_t *c, u_int flags);
static ngx_int_t ngx_rtsig_del_connection(ngx_connection_t *c,
ngx_uint_t flags);
static ngx_int_t ngx_rtsig_process_events(ngx_cycle_t *cycle,
ngx_msec_t timer, ngx_uint_t flags);
static ngx_int_t ngx_rtsig_process_overflow(ngx_cycle_t *cycle,
@ -143,8 +149,8 @@ ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer)
rtscf = ngx_event_get_conf(cycle->conf_ctx, ngx_rtsig_module);
sigemptyset(&set);
sigaddset(&set, rtscf->signo);
sigaddset(&set, rtscf->signo + 1);
sigaddset(&set, (int) rtscf->signo);
sigaddset(&set, (int) rtscf->signo + 1);
sigaddset(&set, SIGIO);
sigaddset(&set, SIGALRM);
@ -188,7 +194,7 @@ ngx_rtsig_done(ngx_cycle_t *cycle)
static ngx_int_t
ngx_rtsig_add_connection(ngx_connection_t *c)
{
int signo;
ngx_uint_t signo;
ngx_rtsig_conf_t *rtscf;
if (c->read->accept && c->read->disabled) {
@ -211,7 +217,7 @@ ngx_rtsig_add_connection(ngx_connection_t *c)
signo = rtscf->signo + c->read->instance;
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"rtsig add connection: fd:%d signo:%d", c->fd, signo);
"rtsig add connection: fd:%d signo:%ui", c->fd, signo);
if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC) == -1) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
@ -219,7 +225,7 @@ ngx_rtsig_add_connection(ngx_connection_t *c)
return NGX_ERROR;
}
if (fcntl(c->fd, F_SETSIG, signo) == -1) {
if (fcntl(c->fd, F_SETSIG, (int) signo) == -1) {
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
"fcntl(F_SETSIG) failed");
return NGX_ERROR;
@ -247,7 +253,7 @@ ngx_rtsig_add_connection(ngx_connection_t *c)
static ngx_int_t
ngx_rtsig_del_connection(ngx_connection_t *c, u_int flags)
ngx_rtsig_del_connection(ngx_connection_t *c, ngx_uint_t flags)
{
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"rtsig del connection: fd:%d", c->fd);
@ -348,7 +354,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
if (signo == rtscf->signo || signo == rtscf->signo + 1) {
if (signo == (int) rtscf->signo || signo == (int) rtscf->signo + 1) {
if (overflow && (ngx_uint_t) si.si_fd > overflow_current) {
return NGX_OK;
@ -363,7 +369,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
return NGX_OK;
}
instance = signo - rtscf->signo;
instance = signo - (int) rtscf->signo;
rev = c->read;
@ -459,8 +465,8 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
{
int name[2], rtsig_max, rtsig_nr, events, ready;
size_t len;
ngx_int_t tested, n, i;
ngx_err_t err;
ngx_uint_t tested, n, i;
ngx_event_t *rev, *wev, **queue;
ngx_connection_t *c;
ngx_rtsig_conf_t *rtscf;
@ -638,7 +644,7 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
* "/proc/sys/kernel/rtsig-max" / "rtsig_overflow_threshold"
*/
if (rtsig_max / rtscf->overflow_threshold < rtsig_nr) {
if (rtsig_max / (int) rtscf->overflow_threshold < rtsig_nr) {
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"rtsig queue state: %d/%d",
rtsig_nr, rtsig_max);
@ -703,19 +709,18 @@ ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf)
ngx_rtsig_conf_t *rtscf = conf;
/* LinuxThreads use the first 3 RT signals */
ngx_conf_init_value(rtscf->signo, SIGRTMIN + 10);
ngx_conf_init_uint_value(rtscf->signo, SIGRTMIN + 10);
ngx_conf_init_value(rtscf->overflow_events, 16);
ngx_conf_init_value(rtscf->overflow_test, 32);
ngx_conf_init_value(rtscf->overflow_threshold, 10);
ngx_conf_init_uint_value(rtscf->overflow_events, 16);
ngx_conf_init_uint_value(rtscf->overflow_test, 32);
ngx_conf_init_uint_value(rtscf->overflow_threshold, 10);
return NGX_CONF_OK;
}
static char *
ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf,
void *post, void *data)
ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf, void *post, void *data)
{
if (ngx_linux_rtsig_max) {
return ngx_conf_check_num_bounds(cf, post, data);

View File

@ -12,8 +12,10 @@
static ngx_int_t ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer);
static void ngx_select_done(ngx_cycle_t *cycle);
static ngx_int_t ngx_select_add_event(ngx_event_t *ev, int event, u_int flags);
static ngx_int_t ngx_select_del_event(ngx_event_t *ev, int event, u_int flags);
static ngx_int_t ngx_select_add_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_select_del_event(ngx_event_t *ev, ngx_int_t event,
ngx_uint_t flags);
static ngx_int_t ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags);
static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf);
@ -25,10 +27,10 @@ static fd_set work_read_fd_set;
static fd_set work_write_fd_set;
#if (NGX_WIN32)
static int max_read;
static int max_write;
static ngx_uint_t max_read;
static ngx_uint_t max_write;
#else
static int max_fd;
static ngx_int_t max_fd;
#endif
static ngx_uint_t nevents;
@ -129,18 +131,18 @@ ngx_select_done(ngx_cycle_t *cycle)
static ngx_int_t
ngx_select_add_event(ngx_event_t *ev, int event, u_int flags)
ngx_select_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
ngx_connection_t *c;
c = ev->data;
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"select add event fd:%d ev:%d", c->fd, event);
"select add event fd:%d ev:%i", c->fd, event);
if (ev->index != NGX_INVALID_INDEX) {
ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
"select event fd:%d ev:%d is already set", c->fd, event);
"select event fd:%d ev:%i is already set", c->fd, event);
return NGX_OK;
}
@ -190,7 +192,7 @@ ngx_select_add_event(ngx_event_t *ev, int event, u_int flags)
static ngx_int_t
ngx_select_del_event(ngx_event_t *ev, int event, u_int flags)
ngx_select_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
{
ngx_connection_t *c;
@ -203,7 +205,7 @@ ngx_select_del_event(ngx_event_t *ev, int event, u_int flags)
}
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"select del event fd:%d ev:%d", c->fd, event);
"select del event fd:%d ev:%i", c->fd, event);
#if (NGX_WIN32)
@ -231,7 +233,7 @@ ngx_select_del_event(ngx_event_t *ev, int event, u_int flags)
#endif
if (ev->index < (u_int) --nevents) {
if (ev->index < --nevents) {
event_index[ev->index] = event_index[nevents];
event_index[ev->index]->index = ev->index;
}

View File

@ -276,7 +276,7 @@ ngx_process_events_and_timers(ngx_cycle_t *cycle)
ngx_int_t
ngx_handle_read_event(ngx_event_t *rev, u_int flags)
ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
{
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
@ -1038,8 +1038,9 @@ ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#if (NGX_DEBUG)
ngx_event_conf_t *ecf = conf;
ngx_event_debug_t *dc;
ngx_int_t rc;
ngx_str_t *value;
ngx_event_debug_t *dc;
struct hostent *h;
ngx_inet_cidr_t in_cidr;
@ -1056,13 +1057,21 @@ ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (dc->addr != INADDR_NONE) {
dc->mask = 0xffffffff;
return NGX_OK;
return NGX_CONF_OK;
}
if (ngx_ptocidr(&value[1], &in_cidr) == NGX_OK) {
rc = ngx_ptocidr(&value[1], &in_cidr);
if (rc == NGX_DONE) {
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"low address bits of %V are meaningless", &value[1]);
rc = NGX_OK;
}
if (rc == NGX_OK) {
dc->mask = in_cidr.mask;
dc->addr = in_cidr.addr;
return NGX_OK;
return NGX_CONF_OK;
}
h = gethostbyname((char *) value[1].data);
@ -1084,7 +1093,7 @@ ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#endif
return NGX_OK;
return NGX_CONF_OK;
}

View File

@ -41,7 +41,7 @@ struct ngx_event_s {
unsigned accept:1;
/* used to detect the stale events in kqueue, rt signals and epoll */
/* used to detect the stale events in kqueue, rtsig, and epoll */
unsigned instance:1;
/*
@ -126,7 +126,7 @@ struct ngx_event_s {
#endif
u_int index;
ngx_uint_t index;
ngx_log_t *log;
@ -182,7 +182,7 @@ struct ngx_event_s {
/* event should not cross cache line in SMP */
int padding[NGX_EVENT_T_PADDING];
uint32_t padding[NGX_EVENT_T_PADDING];
#endif
#endif
};
@ -195,14 +195,14 @@ typedef struct {
typedef struct {
ngx_int_t (*add)(ngx_event_t *ev, int event, u_int flags);
ngx_int_t (*del)(ngx_event_t *ev, int event, u_int flags);
ngx_int_t (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
ngx_int_t (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
ngx_int_t (*enable)(ngx_event_t *ev, int event, u_int flags);
ngx_int_t (*disable)(ngx_event_t *ev, int event, u_int flags);
ngx_int_t (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
ngx_int_t (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
ngx_int_t (*add_conn)(ngx_connection_t *c);
ngx_int_t (*del_conn)(ngx_connection_t *c, u_int flags);
ngx_int_t (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);
ngx_int_t (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t nowait);
ngx_int_t (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer,
@ -247,8 +247,7 @@ extern ngx_event_actions_t ngx_event_actions;
#define NGX_USE_LOWAT_EVENT 0x00000010
/*
* The event filter requires to do i/o operation until EAGAIN:
* epoll, rt signals.
* The event filter requires to do i/o operation until EAGAIN: epoll, rtsig.
*/
#define NGX_USE_GREEDY_EVENT 0x00000020
@ -258,7 +257,7 @@ extern ngx_event_actions_t ngx_event_actions;
#define NGX_USE_EPOLL_EVENT 0x00000040
/*
* No need to add or delete the event filters: rt signals.
* No need to add or delete the event filters: rtsig.
*/
#define NGX_USE_RTSIG_EVENT 0x00000080
@ -276,13 +275,13 @@ extern ngx_event_actions_t ngx_event_actions;
/*
* The event filter has no opaque data and requires file descriptors table:
* poll, /dev/poll, rt signals.
* poll, /dev/poll, rtsig.
*/
#define NGX_USE_FD_EVENT 0x00000400
/*
* The event module handles periodic or absolute timer event by itself:
* kqueue in FreeBSD 4.4 and NetBSD 2.0, Solaris 10's event ports.
* kqueue in FreeBSD 4.4, NetBSD 2.0, and MacOSX 10.4, Solaris 10's event ports.
*/
#define NGX_USE_TIMER_EVENT 0x00000800
@ -290,17 +289,26 @@ extern ngx_event_actions_t ngx_event_actions;
* All event filters on file descriptor are deleted after a notification:
* Solaris 10's event ports.
*/
#define NGX_USE_EVENTPORT_EVENT 0x00001000
#define NGX_USE_EVENTPORT_EVENT 0x00001000
/*
* The event filter is deleted before the closing file.
* Has no meaning for select, poll, kqueue, epoll.
* /dev/poll: we need to flush POLLREMOVE event before closing file
* The event filter is deleted just before the closing file.
* Has no meaning for select and poll.
* kqueue, epoll, rtsig, eventport: allows to avoid explicit delete,
* because filter automatically is deleted
* on file close,
*
* /dev/poll: we need to flush POLLREMOVE event
* before closing file.
*/
#define NGX_CLOSE_EVENT 1
/*
* disable temporarily event filter, this may avoid locks
* in kernel malloc()/free(): kqueue.
*/
#define NGX_DISABLE_EVENT 2
@ -489,7 +497,7 @@ u_char *ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len);
void ngx_process_events_and_timers(ngx_cycle_t *cycle);
ngx_int_t ngx_handle_read_event(ngx_event_t *rev, u_int flags);
ngx_int_t ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags);
ngx_int_t ngx_handle_write_event(ngx_event_t *wev, size_t lowat);

View File

@ -9,7 +9,7 @@
#include <ngx_event.h>
static int ngx_event_busy_lock_look_cachable(ngx_event_busy_lock_t *bl,
static ngx_int_t ngx_event_busy_lock_look_cacheable(ngx_event_busy_lock_t *bl,
ngx_event_busy_lock_ctx_t *ctx);
static void ngx_event_busy_lock_handler(ngx_event_t *ev);
static void ngx_event_busy_lock_posted_handler(ngx_event_t *ev);
@ -65,14 +65,14 @@ ngx_event_busy_lock(ngx_event_busy_lock_t *bl, ngx_event_busy_lock_ctx_t *ctx)
ngx_int_t
ngx_event_busy_lock_cachable(ngx_event_busy_lock_t *bl,
ngx_event_busy_lock_cacheable(ngx_event_busy_lock_t *bl,
ngx_event_busy_lock_ctx_t *ctx)
{
ngx_int_t rc;
ngx_mutex_lock(bl->mutex);
rc = ngx_event_busy_lock_look_cachable(bl, ctx);
rc = ngx_event_busy_lock_look_cacheable(bl, ctx);
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->event->log, 0,
"event busy lock: %d w:%d mw:%d",
@ -201,14 +201,14 @@ ngx_event_busy_lock_cancel(ngx_event_busy_lock_t *bl,
static ngx_int_t
ngx_event_busy_lock_look_cachable(ngx_event_busy_lock_t *bl,
ngx_event_busy_lock_look_cacheable(ngx_event_busy_lock_t *bl,
ngx_event_busy_lock_ctx_t *ctx)
{
ngx_int_t free;
ngx_uint_t i, bit, cachable, mask;
ngx_uint_t i, bit, cacheable, mask;
bit = 0;
cachable = 0;
cacheable = 0;
free = -1;
#if (NGX_SUPPRESS_WARN)
@ -227,14 +227,14 @@ ngx_event_busy_lock_look_cachable(ngx_event_busy_lock_t *bl,
ctx->slot = i;
return NGX_AGAIN;
}
cachable++;
cacheable++;
} else if (free == -1) {
free = i;
}
if (cachable == bl->cachable) {
if (free == -1 && cachable < bl->max_busy) {
if (cacheable == bl->cacheable) {
if (free == -1 && cacheable < bl->max_busy) {
free = i + 1;
}
@ -259,7 +259,7 @@ ngx_event_busy_lock_look_cachable(ngx_event_busy_lock_t *bl,
bl->md5_mask[free / 8] |= 1 << (free & 7);
ctx->slot = free;
bl->cachable++;
bl->cacheable++;
bl->busy++;
return NGX_OK;

View File

@ -34,7 +34,7 @@ struct ngx_event_busy_lock_ctx_s {
typedef struct {
u_char *md5_mask;
char *md5;
ngx_uint_t cachable;
ngx_uint_t cacheable;
ngx_uint_t busy;
ngx_uint_t max_busy;
@ -53,7 +53,7 @@ typedef struct {
ngx_int_t ngx_event_busy_lock(ngx_event_busy_lock_t *bl,
ngx_event_busy_lock_ctx_t *ctx);
ngx_int_t ngx_event_busy_lock_cachable(ngx_event_busy_lock_t *bl,
ngx_int_t ngx_event_busy_lock_cacheable(ngx_event_busy_lock_t *bl,
ngx_event_busy_lock_ctx_t *ctx);
void ngx_event_busy_unlock(ngx_event_busy_lock_t *bl,
ngx_event_busy_lock_ctx_t *ctx);

View File

@ -14,7 +14,7 @@ ngx_int_t
ngx_event_connect_peer(ngx_peer_connection_t *pc)
{
int rc;
u_int event;
ngx_int_t event;
ngx_err_t err;
ngx_uint_t level;
ngx_socket_t s;
@ -85,6 +85,8 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
c->recv_chain = ngx_recv_chain;
c->send_chain = ngx_send_chain;
c->sendfile = 1;
c->log_error = pc->log_error;
if (pc->sockaddr->sa_family != AF_INET) {

View File

@ -13,50 +13,56 @@
#include <ngx_event.h>
#define NGX_PEER_KEEPALIVE 1
#define NGX_PEER_NEXT 2
#define NGX_PEER_FAILED 4
#define NGX_PEER_KEEPALIVE 1
#define NGX_PEER_NEXT 2
#define NGX_PEER_FAILED 4
typedef struct ngx_peer_connection_s ngx_peer_connection_t;
typedef ngx_int_t (*ngx_event_get_peer_pt)(ngx_peer_connection_t *pc,
void *data);
#if (NGX_SSL)
typedef void (*ngx_event_save_peer_pt)(ngx_peer_connection_t *pc, void *data);
#endif
typedef void (*ngx_event_free_peer_pt)(ngx_peer_connection_t *pc, void *data,
ngx_uint_t state);
#if (NGX_SSL)
typedef ngx_int_t (*ngx_event_set_peer_session_pt)(ngx_peer_connection_t *pc,
void *data);
typedef void (*ngx_event_save_peer_session_pt)(ngx_peer_connection_t *pc,
void *data);
#endif
struct ngx_peer_connection_s {
ngx_connection_t *connection;
ngx_connection_t *connection;
struct sockaddr *sockaddr;
socklen_t socklen;
ngx_str_t *name;
struct sockaddr *sockaddr;
socklen_t socklen;
ngx_str_t *name;
ngx_uint_t tries;
ngx_uint_t tries;
ngx_event_get_peer_pt get;
ngx_event_free_peer_pt free;
void *data;
ngx_event_get_peer_pt get;
ngx_event_free_peer_pt free;
void *data;
#if (NGX_SSL)
ngx_ssl_session_t *ssl_session;
ngx_event_save_peer_pt save_session;
ngx_event_set_peer_session_pt set_session;
ngx_event_save_peer_session_pt save_session;
#endif
#if (NGX_THREADS)
ngx_atomic_t *lock;
ngx_atomic_t *lock;
#endif
int rcvbuf;
int rcvbuf;
ngx_log_t *log;
ngx_log_t *log;
unsigned cached:1;
unsigned log_error:2; /* ngx_connection_log_error_e */
unsigned cached:1;
/* ngx_connection_log_error_e */
unsigned log_error:2;
};

View File

@ -22,6 +22,7 @@ static void ngx_ssl_read_handler(ngx_event_t *rev);
static void ngx_ssl_shutdown_handler(ngx_event_t *ev);
static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr,
ngx_err_t err, char *text);
static void ngx_ssl_clear_error(ngx_log_t *log);
static ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone,
void *data);
@ -186,6 +187,11 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]);
}
/*
* we need this option because in ngx_ssl_send_chain()
* we may switch to a buffered write and may copy leftover part of
* previously unbuffered data to our internal buffer
*/
SSL_CTX_set_mode(ssl->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
SSL_CTX_set_read_ahead(ssl->ctx, 1);
@ -404,6 +410,8 @@ ngx_ssl_handshake(ngx_connection_t *c)
int n, sslerr;
ngx_err_t err;
ngx_ssl_clear_error(c->log);
n = SSL_do_handshake(c->ssl->connection);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n);
@ -602,6 +610,8 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
bytes = 0;
ngx_ssl_clear_error(c->log);
/*
* SSL_read() may return data in parts, so try to read
* until SSL_read() would return no data
@ -784,7 +794,7 @@ ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
/* the maximum limit size is the maximum uint32_t value - the page size */
if (limit == 0 || limit > NGX_MAX_UINT32_VALUE - ngx_pagesize) {
if (limit == 0 || limit > (off_t) (NGX_MAX_UINT32_VALUE - ngx_pagesize)) {
limit = NGX_MAX_UINT32_VALUE - ngx_pagesize;
}
@ -882,6 +892,8 @@ ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
int n, sslerr;
ngx_err_t err;
ngx_ssl_clear_error(c->log);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size);
n = SSL_write(c->ssl->connection, data, size);
@ -965,9 +977,8 @@ ngx_ssl_read_handler(ngx_event_t *rev)
ngx_int_t
ngx_ssl_shutdown(ngx_connection_t *c)
{
int n, sslerr, mode;
ngx_err_t err;
ngx_uint_t again;
int n, sslerr, mode;
ngx_err_t err;
if (c->timedout) {
mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
@ -986,40 +997,31 @@ ngx_ssl_shutdown(ngx_connection_t *c)
SSL_set_shutdown(c->ssl->connection, mode);
again = 0;
ngx_ssl_clear_error(c->log);
n = SSL_shutdown(c->ssl->connection);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
sslerr = 0;
for ( ;; ) {
n = SSL_shutdown(c->ssl->connection);
/* SSL_shutdown() never return -1, on error it return 0 */
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
if (n == 1 || (n == 0 && c->timedout)) {
SSL_free(c->ssl->connection);
c->ssl = NULL;
return NGX_OK;
}
if (n == 0) {
again = 1;
break;
}
break;
}
if (!again) {
if (n != 1 && ERR_peek_error()) {
sslerr = SSL_get_error(c->ssl->connection, n);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"SSL_get_error: %d", sslerr);
}
if (again
|| sslerr == SSL_ERROR_WANT_READ
|| sslerr == SSL_ERROR_WANT_WRITE)
{
if (n == 1 || sslerr == 0 || sslerr == SSL_ERROR_ZERO_RETURN) {
SSL_free(c->ssl->connection);
c->ssl = NULL;
return NGX_OK;
}
if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
c->read->handler = ngx_ssl_shutdown_handler;
c->write->handler = ngx_ssl_shutdown_handler;
@ -1031,7 +1033,7 @@ ngx_ssl_shutdown(ngx_connection_t *c)
return NGX_ERROR;
}
if (again || sslerr == SSL_ERROR_WANT_READ) {
if (sslerr == SSL_ERROR_WANT_READ) {
ngx_add_timer(c->read, 30000);
}
@ -1112,12 +1114,24 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
}
static void
ngx_ssl_clear_error(ngx_log_t *log)
{
while (ERR_peek_error()) {
ngx_ssl_error(NGX_LOG_ALERT, log, 0, "ignoring stale global SSL error");
}
ERR_clear_error();
}
void ngx_cdecl
ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
{
u_long n;
va_list args;
u_char errstr[NGX_MAX_CONF_ERRSTR], *p, *last;
u_long n;
va_list args;
u_char *p, *last;
u_char errstr[NGX_MAX_CONF_ERRSTR];
last = errstr + NGX_MAX_CONF_ERRSTR;
@ -1127,7 +1141,7 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p);
while (p < last) {
for ( ;; ) {
n = ERR_get_error();
@ -1135,6 +1149,10 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
break;
}
if (p >= last) {
continue;
}
*p++ = ' ';
ERR_error_string_n(n, (char *) p, last - p);
@ -1588,7 +1606,7 @@ ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
}
if (n++ != 0 && sess_id->expire > tp->sec) {
break;
return;
}
sess_id->next->prev = sess_id->prev;

View File

@ -21,7 +21,7 @@ static ngx_int_t ngx_event_pipe_drain_chains(ngx_event_pipe_t *p);
ngx_int_t
ngx_event_pipe(ngx_event_pipe_t *p, int do_write)
ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write)
{
u_int flags;
ngx_event_t *rev, *wev;
@ -192,7 +192,7 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
chain->buf = b;
chain->next = NULL;
} else if (!p->cachable
} else if (!p->cacheable
&& p->downstream->data == p->output_ctx
&& p->downstream->write->ready
&& !p->downstream->write->delayed)
@ -209,7 +209,7 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
break;
} else if (p->cachable
} else if (p->cacheable
|| p->temp_file->offset < p->max_temp_file_size)
{
@ -406,7 +406,7 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
}
}
if (p->cachable && p->in) {
if (p->cacheable && p->in) {
if (ngx_event_pipe_write_chain_to_temp_file(p) == NGX_ABORT) {
return NGX_ABORT;
}
@ -421,6 +421,7 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
{
u_char *prev;
size_t bsize;
ngx_int_t rc;
ngx_uint_t flush, prev_last_shadow;
ngx_chain_t *out, **ll, *cl;
ngx_connection_t *downstream;
@ -451,7 +452,13 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
cl->buf->recycled = 0;
}
if (p->output_filter(p->output_ctx, p->out) == NGX_ERROR) {
rc = p->output_filter(p->output_ctx, p->out);
if (downstream->destroyed) {
return NGX_ABORT;
}
if (rc == NGX_ERROR) {
p->downstream_error = 1;
return ngx_event_pipe_drain_chains(p);
}
@ -467,12 +474,13 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
cl->buf->recycled = 0;
}
if (p->output_filter(p->output_ctx, p->in) == NGX_ERROR) {
rc = p->output_filter(p->output_ctx, p->in);
if (downstream->destroyed) {
return NGX_ABORT;
}
if (downstream->destroyed) {
return NGX_ABORT;
}
if (rc == NGX_ERROR) {
p->downstream_error = 1;
return ngx_event_pipe_drain_chains(p);
}
@ -542,7 +550,7 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
ngx_event_pipe_free_shadow_raw_buf(&p->free_raw_bufs, cl->buf);
} else if (!p->cachable && p->in) {
} else if (!p->cacheable && p->in) {
cl = p->in;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
@ -602,7 +610,13 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
break;
}
if (p->output_filter(p->output_ctx, out) == NGX_ERROR) {
rc = p->output_filter(p->output_ctx, out);
if (downstream->destroyed) {
return NGX_ABORT;
}
if (rc == NGX_ERROR) {
p->downstream_error = 1;
return ngx_event_pipe_drain_chains(p);
}
@ -612,7 +626,7 @@ ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p)
for (cl = p->free; cl; cl = cl->next) {
if (cl->buf->temp_file) {
if (p->cachable || !p->cyclic_temp_file) {
if (p->cacheable || !p->cyclic_temp_file) {
continue;
}
@ -659,7 +673,7 @@ ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p)
out = p->in;
}
if (!p->cachable) {
if (!p->cacheable) {
size = 0;
cl = out;

View File

@ -47,7 +47,7 @@ struct ngx_event_pipe_s {
void *output_ctx;
unsigned read:1;
unsigned cachable:1;
unsigned cacheable:1;
unsigned single_buf:1;
unsigned free_bufs:1;
unsigned upstream_done:1;
@ -86,7 +86,7 @@ struct ngx_event_pipe_s {
};
ngx_int_t ngx_event_pipe(ngx_event_pipe_t *p, int do_write);
ngx_int_t ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write);
ngx_int_t ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf);
ngx_int_t ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b);

View File

@ -137,6 +137,7 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_access_loc_conf_t *alcf = conf;
ngx_int_t rc;
ngx_str_t *value;
ngx_inet_cidr_t in_cidr;
ngx_http_access_rule_t *rule;
@ -173,12 +174,19 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}
if (ngx_ptocidr(&value[1], &in_cidr) == NGX_ERROR) {
rc = ngx_ptocidr(&value[1], &in_cidr);
if (rc == NGX_ERROR) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
&value[1]);
return NGX_CONF_ERROR;
}
if (rc == NGX_DONE) {
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"low address bits of %V are meaningless", &value[1]);
}
rule->mask = in_cidr.mask;
rule->addr = in_cidr.addr;

View File

@ -236,6 +236,11 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
if (ngx_close_dir(&dir) == NGX_ERROR) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
ngx_close_dir_n " \"%V\" failed", &path);
}
return rc;
}

View File

@ -397,7 +397,7 @@ ngx_http_browser_add_variable(ngx_conf_t *cf)
for (var = ngx_http_browsers; var->name.len; var++) {
v = ngx_http_add_variable(cf, &var->name, NGX_HTTP_VAR_CHANGABLE);
v = ngx_http_add_variable(cf, &var->name, NGX_HTTP_VAR_CHANGEABLE);
if (v == NULL) {
return NGX_ERROR;
}
@ -673,7 +673,7 @@ ngx_http_modern_browser_value(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
bcf->modern_browser_value->len = value[1].len;
bcf->modern_browser_value->valid = 1;
bcf->modern_browser_value->no_cachable = 0;
bcf->modern_browser_value->no_cacheable = 0;
bcf->modern_browser_value->not_found = 0;
bcf->modern_browser_value->data = value[1].data;
@ -698,7 +698,7 @@ ngx_http_ancient_browser_value(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
bcf->ancient_browser_value->len = value[1].len;
bcf->ancient_browser_value->valid = 1;
bcf->ancient_browser_value->no_cachable = 0;
bcf->ancient_browser_value->no_cacheable = 0;
bcf->ancient_browser_value->not_found = 0;
bcf->ancient_browser_value->data = value[1].data;

View File

@ -187,7 +187,7 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
{
u_char *ct;
ngx_int_t charset, source_charset;
ngx_str_t *mc, *from, *to;
ngx_str_t *mc, *from, *to, s;
ngx_uint_t n;
ngx_http_charset_t *charsets;
ngx_http_charset_ctx_t *ctx;
@ -256,8 +256,10 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
return NGX_ERROR;
}
charset = ngx_http_charset_get_charset(charsets, n,
(ngx_str_t *) vv);
s.len = vv->len;
s.data = vv->data;
charset = ngx_http_charset_get_charset(charsets, n, &s);
}
}
@ -303,8 +305,10 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
return NGX_ERROR;
}
source_charset = ngx_http_charset_get_charset(charsets, n,
(ngx_str_t *) vv);
s.len = vv->len;
s.data = vv->data;
source_charset = ngx_http_charset_get_charset(charsets, n, &s);
}
if (charset != NGX_HTTP_NO_CHARSET) {
@ -362,8 +366,8 @@ ngx_http_charset_header_filter(ngx_http_request_t *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);
"no \"charset_map\" between the charsets \"%V\" and \"%V\"",
from, to);
return ngx_http_next_header_filter(r);
}
@ -373,17 +377,16 @@ static ngx_int_t
ngx_http_charset_get_charset(ngx_http_charset_t *charsets, ngx_uint_t n,
ngx_str_t *charset)
{
size_t len;
ngx_uint_t i;
len = charset->len & 0xffff;
for (i = 0; i < n; i++) {
if (charsets[i].name.len != len) {
if (charsets[i].name.len != charset->len) {
continue;
}
if (ngx_strncasecmp(charsets[i].name.data, charset->data, len) == 0) {
if (ngx_strncasecmp(charsets[i].name.data, charset->data, charset->len)
== 0)
{
return i;
}
}
@ -1459,6 +1462,12 @@ ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_OK;
}
if (conf->source_charset >= NGX_HTTP_CHARSET_VAR
|| conf->charset >= NGX_HTTP_CHARSET_VAR)
{
return NGX_CONF_OK;
}
mcf = ngx_http_conf_get_module_main_conf(cf,
ngx_http_charset_filter_module);
recode = mcf->recodes.elts;
@ -1516,9 +1525,8 @@ ngx_http_charset_postconfiguration(ngx_conf_t *cf)
}
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
" no \"charset_map\" between the charsets "
"\"%V\" and \"%V\"",
&charset[c].name, &charset[recode[i].dst].name);
"no \"charset_map\" between the charsets \"%V\" and \"%V\"",
&charset[c].name, &charset[recode[i].dst].name);
return NGX_ERROR;
next:

View File

@ -57,8 +57,6 @@ 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,
ngx_int_t not_found, char *failed, u_char *path);
static ngx_int_t ngx_http_dav_location(ngx_http_request_t *r, u_char *path);
static char *ngx_http_dav_access(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static void *ngx_http_dav_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_dav_merge_loc_conf(ngx_conf_t *cf,
void *parent, void *child);
@ -94,9 +92,9 @@ static ngx_command_t ngx_http_dav_commands[] = {
{ ngx_string("dav_access"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
ngx_http_dav_access,
ngx_conf_set_access_slot,
NGX_HTTP_LOC_CONF_OFFSET,
0,
offsetof(ngx_http_dav_loc_conf_t, access),
NULL },
ngx_null_command
@ -239,9 +237,7 @@ ngx_http_dav_put_handler(ngx_http_request_t *r)
#if !(NGX_WIN32)
if (ngx_change_file_access(temp->data, dlcf->access)
== NGX_FILE_ERROR)
{
if (ngx_change_file_access(temp->data, dlcf->access) == NGX_FILE_ERROR) {
err = ngx_errno;
not_found = NGX_HTTP_INTERNAL_SERVER_ERROR;
failed = ngx_change_file_access_n;
@ -1108,66 +1104,6 @@ ngx_http_dav_location(ngx_http_request_t *r, u_char *path)
}
static char *
ngx_http_dav_access(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_dav_loc_conf_t *lcf = conf;
u_char *p;
ngx_str_t *value;
ngx_uint_t i, right, shift;
if (lcf->access != NGX_CONF_UNSET_UINT) {
return "is duplicate";
}
value = cf->args->elts;
lcf->access = 0600;
for (i = 1; i < cf->args->nelts; i++) {
p = value[i].data;
if (ngx_strncmp(p, "user:", sizeof("user:") - 1) == 0) {
shift = 6;
p += sizeof("user:") - 1;
} else if (ngx_strncmp(p, "group:", sizeof("group:") - 1) == 0) {
shift = 3;
p += sizeof("group:") - 1;
} else if (ngx_strncmp(p, "all:", sizeof("all:") - 1) == 0) {
shift = 0;
p += sizeof("all:") - 1;
} else {
goto invalid;
}
if (ngx_strcmp(p, "rw") == 0) {
right = 6;
} else if (ngx_strcmp(p, "r") == 0) {
right = 4;
} else {
goto invalid;
}
lcf->access |= right << shift;
}
return NGX_CONF_OK;
invalid:
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid value \"%V\"", &value[i]);
return NGX_CONF_ERROR;
}
static void *
ngx_http_dav_create_loc_conf(ngx_conf_t *cf)
{

View File

@ -127,12 +127,10 @@ ngx_http_empty_gif_handler(ngx_http_request_t *r)
if (r->method == NGX_HTTP_HEAD) {
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = sizeof(ngx_empty_gif);
r->headers_out.last_modified_time = 23349600;
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
return rc;
}
return ngx_http_send_header(r);
}
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));

View File

@ -37,6 +37,12 @@ typedef enum {
} ngx_http_fastcgi_state_e;
typedef struct {
u_char *start;
u_char *end;
} ngx_http_fastcgi_split_part_t;
typedef struct {
ngx_http_fastcgi_state_e state;
u_char *pos;
@ -45,7 +51,9 @@ typedef struct {
size_t length;
size_t padding;
ngx_uint_t fastcgi_stdout;
ngx_uint_t fastcgi_stdout; /* unsigned :1 */
ngx_array_t *split_parts;
} ngx_http_fastcgi_ctx_t;
@ -116,6 +124,8 @@ static ngx_int_t ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
static char *ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_fastcgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post,
void *data);
@ -192,6 +202,20 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
offsetof(ngx_http_fastcgi_loc_conf_t, index),
NULL },
{ ngx_string("fastcgi_store"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_http_fastcgi_store,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL },
{ ngx_string("fastcgi_store_access"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
ngx_conf_set_access_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.store_access),
NULL },
{ ngx_string("fastcgi_ignore_client_abort"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@ -408,7 +432,7 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
if (r->subrequest_in_memory) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
"ngx_http_fastcgi_module does not support "
"subrequest in memeory");
"subrequest in memory");
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
@ -481,7 +505,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
if (flcf->params_len) {
ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
ngx_http_script_flush_no_cachable_variables(r, flcf->flushes);
ngx_http_script_flush_no_cacheable_variables(r, flcf->flushes);
le.flushed = 1;
le.ip = flcf->params_len->elts;
@ -527,7 +551,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
if (len > 65535) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
"fastcgi: the request record is too big");
"fastcgi request record is too big: %uz", len);
return NGX_ERROR;
}
@ -840,15 +864,18 @@ 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 *start, *last;
u_char *p, *start, *last, *part_start;
size_t size;
ngx_str_t *status_line, line, *pattern;
ngx_int_t rc, status;
ngx_buf_t buf;
ngx_uint_t i;
ngx_table_elt_t *h;
ngx_http_upstream_t *u;
ngx_http_fastcgi_ctx_t *f;
ngx_http_upstream_header_t *hh;
ngx_http_fastcgi_loc_conf_t *flcf;
ngx_http_fastcgi_split_part_t *part;
ngx_http_upstream_main_conf_t *umcf;
f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
@ -858,7 +885,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
if (f == NULL) {
f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
if (f == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
return NGX_ERROR;
}
ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
@ -966,7 +993,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
for (i = 0; i < flcf->catch_stderr->nelts; i++) {
if (ngx_strstr(line.data, pattern[i].data)) {
return NGX_HTTP_BAD_GATEWAY;
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
}
}
}
@ -1017,6 +1044,8 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
for ( ;; ) {
part_start = u->buffer.pos;
rc = ngx_http_parse_header_line(r, &u->buffer);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@ -1032,33 +1061,81 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
h = ngx_list_push(&u->headers_in.headers);
if (h == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
return NGX_ERROR;
}
if (f->split_parts && f->split_parts->nelts) {
part = f->split_parts->elts;
size = u->buffer.pos - part_start;
for (i = 0; i < f->split_parts->nelts; i++) {
size += part[i].end - part[i].start;
}
p = ngx_palloc(r->pool, size);
if (p == NULL) {
return NGX_ERROR;
}
buf.pos = p;
for (i = 0; i < f->split_parts->nelts; i++) {
p = ngx_cpymem(p, part[i].start,
part[i].end - part[i].start);
}
p = ngx_cpymem(p, part_start, u->buffer.pos - part_start);
buf.last = p;
f->split_parts->nelts = 0;
rc = ngx_http_parse_header_line(r, &buf);
h->key.len = r->header_name_end - r->header_name_start;
h->key.data = r->header_name_start;
h->key.data[h->key.len] = '\0';
h->value.len = r->header_end - r->header_start;
h->value.data = r->header_start;
h->value.data[h->value.len] = '\0';
h->lowcase_key = ngx_palloc(r->pool, h->key.len);
if (h->lowcase_key == NULL) {
return NGX_ERROR;
}
} else {
h->key.len = r->header_name_end - r->header_name_start;
h->value.len = r->header_end - r->header_start;
h->key.data = ngx_palloc(r->pool,
h->key.len + 1 + h->value.len + 1
+ h->key.len);
if (h->key.data == NULL) {
return NGX_ERROR;
}
h->value.data = h->key.data + h->key.len + 1;
h->lowcase_key = h->key.data + h->key.len + 1
+ h->value.len + 1;
ngx_cpystrn(h->key.data, r->header_name_start,
h->key.len + 1);
ngx_cpystrn(h->value.data, r->header_start,
h->value.len + 1);
}
h->hash = r->header_hash;
h->key.len = r->header_name_end - r->header_name_start;
h->value.len = r->header_end - r->header_start;
h->key.data = ngx_palloc(r->pool,
h->key.len + 1 + h->value.len + 1 + h->key.len);
if (h->key.data == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
h->value.data = h->key.data + h->key.len + 1;
h->lowcase_key = h->key.data + h->key.len + 1
+ h->value.len + 1;
ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
if (h->key.len == r->lowcase_index) {
ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
} else {
for (i = 0; i < h->key.len; i++) {
h->lowcase_key[i] = ngx_tolower(h->lowcase_key[i]);
h->lowcase_key[i] = ngx_tolower(h->key.data[i]);
}
}
@ -1066,7 +1143,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
h->lowcase_key, h->key.len);
if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
return NGX_ERROR;
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@ -1095,7 +1172,10 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
status = ngx_atoi(status_line->data, 3);
if (status == NGX_ERROR) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"upstream sent invalid status \"%V\"",
status_line);
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
}
u->headers_in.status_n = status;
@ -1109,8 +1189,8 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
u->state->status = u->headers_in.status_n;
#if 0
if (u->cachable) {
u->cachable = ngx_http_upstream_is_cachable(r);
if (u->cacheable) {
u->cacheable = ngx_http_upstream_is_cacheable(r);
}
#endif
@ -1123,7 +1203,6 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
"upstream sent invalid header");
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
}
if (last) {
@ -1144,16 +1223,29 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
return NGX_OK;
}
if (u->buffer.pos == u->buffer.last) {
if (rc == NGX_OK) {
return NGX_AGAIN;
}
if (rc == NGX_AGAIN) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
"upstream split a header line in FastCGI records");
/* rc == NGX_AGAIN */
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"upstream split a header line in FastCGI records");
if (f->split_parts == NULL) {
f->split_parts = ngx_array_create(r->pool, 1,
sizeof(ngx_http_fastcgi_split_part_t));
if (f->split_parts == NULL) {
return NGX_ERROR;
}
}
part = ngx_array_push(f->split_parts);
part->start = part_start;
part->end = u->buffer.last;
return NGX_AGAIN;
}
}
@ -1521,7 +1613,7 @@ ngx_http_fastcgi_add_variables(ngx_conf_t *cf)
ngx_http_variable_t *var;
var = ngx_http_add_variable(cf, &ngx_http_fastcgi_script_name,
NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHABLE);
NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE);
if (var == NULL) {
return NGX_ERROR;
}
@ -1549,17 +1641,18 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
* conf->upstream.next_upstream = 0;
* conf->upstream.temp_path = NULL;
* conf->upstream.hide_headers_hash = { NULL, 0 };
* conf->upstream.hide_headers = NULL;
* conf->upstream.pass_headers = NULL;
* conf->upstream.catch_stderr = NULL;
* conf->upstream.schema = { 0, NULL };
* conf->upstream.uri = { 0, NULL };
* conf->upstream.location = NULL;
* conf->upstream.store_lengths = NULL;
* conf->upstream.store_values = NULL;
*
* conf->index.len = 0;
* conf->index.data = NULL;
*/
conf->upstream.store = NGX_CONF_UNSET;
conf->upstream.store_access = NGX_CONF_UNSET_UINT;
conf->upstream.buffering = NGX_CONF_UNSET;
conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
@ -1577,11 +1670,16 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
conf->upstream.pass_request_body = NGX_CONF_UNSET;
conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
conf->upstream.intercept_errors = NGX_CONF_UNSET;
/* "fastcgi_cyclic_temp_file" is disabled */
conf->upstream.cyclic_temp_file = 0;
conf->catch_stderr = NGX_CONF_UNSET_PTR;
return conf;
}
@ -1595,15 +1693,25 @@ 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 *header;
ngx_uint_t i, j;
ngx_array_t hide_headers;
ngx_uint_t i;
ngx_keyval_t *src;
ngx_hash_key_t *hk;
ngx_hash_init_t hash;
ngx_http_script_compile_t sc;
ngx_http_script_copy_code_t *copy;
if (conf->upstream.store != 0) {
ngx_conf_merge_value(conf->upstream.store,
prev->upstream.store, 0);
if (conf->upstream.store_lengths == NULL) {
conf->upstream.store_lengths = prev->upstream.store_lengths;
conf->upstream.store_values = prev->upstream.store_values;
}
}
ngx_conf_merge_uint_value(conf->upstream.store_access,
prev->upstream.store_access, 0600);
ngx_conf_merge_value(conf->upstream.buffering,
prev->upstream.buffering, 1);
@ -1748,108 +1856,19 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_str_value(conf->index, prev->index, "");
if (conf->upstream.hide_headers == NULL
&& conf->upstream.pass_headers == NULL)
{
conf->upstream.hide_headers = prev->upstream.hide_headers;
conf->upstream.pass_headers = prev->upstream.pass_headers;
conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash;
hash.max_size = 512;
hash.bucket_size = ngx_align(64, ngx_cacheline_size);
hash.name = "fastcgi_hide_headers_hash";
if (conf->upstream.hide_headers_hash.buckets) {
goto peers;
}
} else {
if (conf->upstream.hide_headers == NULL) {
conf->upstream.hide_headers = prev->upstream.hide_headers;
}
if (conf->upstream.pass_headers == NULL) {
conf->upstream.pass_headers = prev->upstream.pass_headers;
}
}
if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
&prev->upstream,
ngx_http_fastcgi_hide_headers,
&hash)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
for (header = ngx_http_fastcgi_hide_headers; header->len; header++) {
hk = ngx_array_push(&hide_headers);
if (hk == NULL) {
return NGX_CONF_ERROR;
}
hk->key = *header;
hk->key_hash = ngx_hash_key_lc(header->data, header->len);
hk->value = (void *) 1;
}
if (conf->upstream.hide_headers) {
header = conf->upstream.hide_headers->elts;
for (i = 0; i < conf->upstream.hide_headers->nelts; i++) {
hk = hide_headers.elts;
for (j = 0; j < hide_headers.nelts; j++) {
if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
goto exist;
}
}
hk = ngx_array_push(&hide_headers);
if (hk == NULL) {
return NGX_CONF_ERROR;
}
hk->key = header[i];
hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len);
hk->value = (void *) 1;
exist:
continue;
}
}
if (conf->upstream.pass_headers) {
hk = hide_headers.elts;
header = conf->upstream.pass_headers->elts;
for (i = 0; i < conf->upstream.pass_headers->nelts; i++) {
for (j = 0; j < hide_headers.nelts; j++) {
if (hk[j].key.data == NULL) {
continue;
}
if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
hk[j].key.data = NULL;
break;
}
}
}
}
hash.hash = &conf->upstream.hide_headers_hash;
hash.key = ngx_hash_key_lc;
hash.max_size = 512;
hash.bucket_size = ngx_align(64, ngx_cacheline_size);
hash.name = "fastcgi_hide_headers_hash";
hash.pool = cf->pool;
hash.temp_pool = NULL;
if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) {
return NGX_CONF_ERROR;
}
peers:
if (conf->upstream.upstream == NULL) {
conf->upstream.upstream = prev->upstream.upstream;
conf->upstream.schema = prev->upstream.schema;
@ -1997,7 +2016,7 @@ ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
if (r->uri.len) {
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
@ -2021,7 +2040,7 @@ ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
} else {
v->len = 0;
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
v->data = NULL;
@ -2074,6 +2093,52 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
static char *
ngx_http_fastcgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_fastcgi_loc_conf_t *flcf = conf;
ngx_str_t *value;
ngx_http_script_compile_t sc;
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;
return NGX_CONF_OK;
}
if (ngx_strcmp(value[1].data, "off") == 0) {
flcf->upstream.store = 0;
return NGX_CONF_OK;
}
/* include the terminating '\0' into script */
value[1].len++;
ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
sc.cf = cf;
sc.source = &value[1];
sc.lengths = &flcf->upstream.store_lengths;
sc.values = &flcf->upstream.store_values;
sc.variables = ngx_http_script_variables_count(&value[1]);
sc.complete_lengths = 1;
sc.complete_values = 1;
if (ngx_http_script_compile(&sc) != NGX_OK) {
return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
static char *
ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post, void *data)
{

View File

@ -167,7 +167,7 @@ ngx_http_flv_handler(ngx_http_request_t *r)
i = 1;
if (r->args.len) {
p = (u_char *) ngx_strstr(r->args.data, "start=");
p = (u_char *) ngx_strnstr(r->args.data, "start=", r->args.len);
if (p) {
p += 6;

View File

@ -86,7 +86,7 @@ ngx_http_geo_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
*v = *vv;
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http geo: %V %V", &r->connection->addr_text, v);
"http geo: %V %v", &r->connection->addr_text, v);
return NGX_OK;
}
@ -100,8 +100,8 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_conf_t save;
ngx_pool_t *pool;
ngx_radix_tree_t *tree;
ngx_http_variable_t *var;
ngx_http_geo_conf_ctx_t ctx;
ngx_http_variable_t *var;
value = cf->args->elts;
@ -116,7 +116,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
name.data++;
}
var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGABLE);
var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
if (var == NULL) {
return NGX_CONF_ERROR;
}
@ -212,12 +212,20 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
cidrin.mask = 0;
} else {
if (ngx_ptocidr(&value[0], &cidrin) == NGX_ERROR) {
rc = ngx_ptocidr(&value[0], &cidrin);
if (rc == NGX_ERROR) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid parameter \"%V\"", &value[0]);
return NGX_CONF_ERROR;
}
if (rc == NGX_DONE) {
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"low address bits of %V are meaningless",
&value[0]);
}
cidrin.addr = ntohl(cidrin.addr);
cidrin.mask = ntohl(cidrin.mask);
}
@ -249,7 +257,7 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
}
var->valid = 1;
var->no_cachable = 0;
var->no_cacheable = 0;
var->not_found = 0;
v = ngx_array_push(&ctx->values);
@ -277,9 +285,8 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
ngx_radix32tree_find(ctx->tree, cidrin.addr & cidrin.mask);
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"duplicate parameter \"%V\", value: \"%V\", "
"old value: \"%V\"",
&value[0], var, old);
"duplicate parameter \"%V\", value: \"%v\", old value: \"%v\"",
&value[0], var, old);
rc = ngx_radix32tree_delete(ctx->tree, cidrin.addr, cidrin.mask);

View File

@ -14,6 +14,7 @@
typedef struct {
ngx_flag_t enable;
ngx_flag_t no_buffer;
ngx_flag_t vary;
ngx_array_t *types; /* array of ngx_str_t */
@ -192,6 +193,13 @@ static ngx_command_t ngx_http_gzip_filter_commands[] = {
offsetof(ngx_http_gzip_conf_t, min_length),
NULL },
{ ngx_string("gzip_vary"),
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_gzip_conf_t, vary),
NULL },
ngx_null_command
};
@ -261,6 +269,7 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
{
ngx_str_t *type;
ngx_uint_t i;
ngx_table_elt_t *header;
ngx_http_gzip_ctx_t *ctx;
ngx_http_gzip_conf_t *conf;
@ -279,7 +288,9 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
|| r->headers_in.accept_encoding == NULL
|| (r->headers_out.content_length_n != -1
&& r->headers_out.content_length_n < conf->min_length)
|| ngx_strstr(r->headers_in.accept_encoding->value.data, "gzip") == NULL
|| ngx_strcasestrn(r->headers_in.accept_encoding->value.data,
"gzip", 4 - 1)
== NULL
)
{
return ngx_http_next_header_filter(r);
@ -334,16 +345,31 @@ found:
ctx->request = r;
r->headers_out.content_encoding = ngx_list_push(&r->headers_out.headers);
if (r->headers_out.content_encoding == NULL) {
header = ngx_list_push(&r->headers_out.headers);
if (header == NULL) {
return NGX_ERROR;
}
r->headers_out.content_encoding->hash = 1;
r->headers_out.content_encoding->key.len = sizeof("Content-Encoding") - 1;
r->headers_out.content_encoding->key.data = (u_char *) "Content-Encoding";
r->headers_out.content_encoding->value.len = sizeof("gzip") - 1;
r->headers_out.content_encoding->value.data = (u_char *) "gzip";
header->hash = 1;
header->key.len = sizeof("Content-Encoding") - 1;
header->key.data = (u_char *) "Content-Encoding";
header->value.len = sizeof("gzip") - 1;
header->value.data = (u_char *) "gzip";
r->headers_out.content_encoding = header;
if (conf->vary) {
header = ngx_list_push(&r->headers_out.headers);
if (header == NULL) {
return NGX_ERROR;
}
header->hash = 1;
header->key.len = sizeof("Vary") - 1;
header->key.data = (u_char *) "Vary";
header->value.len = sizeof("Accept-Encoding") - 1;
header->value.data = (u_char *) "Accept-Encoding";
}
ctx->length = r->headers_out.content_length_n;
@ -811,12 +837,15 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
}
if (last == NGX_AGAIN && !ctx->done) {
return NGX_AGAIN;
}
if (ctx->out == NULL) {
if (ctx->out == NULL && ctx->busy == NULL) {
return NGX_OK;
if (last == NGX_AGAIN) {
return NGX_AGAIN;
}
if (ctx->busy == NULL) {
return NGX_OK;
}
}
last = ngx_http_next_body_filter(r, ctx->out);
@ -938,7 +967,7 @@ ngx_http_gzip_ratio_variable(ngx_http_request_t *r,
ngx_http_gzip_ctx_t *ctx;
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module);
@ -994,6 +1023,7 @@ ngx_http_gzip_create_conf(ngx_conf_t *cf)
conf->enable = NGX_CONF_UNSET;
conf->no_buffer = NGX_CONF_UNSET;
conf->vary = NGX_CONF_UNSET;
conf->http_version = NGX_CONF_UNSET_UINT;
@ -1029,6 +1059,7 @@ ngx_http_gzip_merge_conf(ngx_conf_t *cf, void *parent, void *child)
MAX_MEM_LEVEL - 1);
ngx_conf_merge_value(conf->min_length, prev->min_length, 20);
ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0);
ngx_conf_merge_value(conf->vary, prev->vary, 0);
if (conf->types == NULL) {
if (prev->types == NULL) {

View File

@ -9,17 +9,31 @@
#include <ngx_http.h>
typedef struct {
ngx_table_elt_t value;
ngx_array_t *lengths;
ngx_array_t *values;
} ngx_http_header_val_t;
typedef struct ngx_http_header_val_s ngx_http_header_val_t;
typedef ngx_int_t (*ngx_http_set_header_pt)(ngx_http_request_t *r,
ngx_http_header_val_t *hv, ngx_str_t *value);
typedef struct {
time_t expires;
ngx_str_t cache_control;
ngx_array_t *headers;
ngx_str_t name;
ngx_uint_t offset;
ngx_http_set_header_pt handler;
} ngx_http_set_header_t;
struct ngx_http_header_val_s {
ngx_table_elt_t value;
ngx_uint_t offset;
ngx_http_set_header_pt handler;
ngx_array_t *lengths;
ngx_array_t *values;
};
typedef struct {
time_t expires;
ngx_array_t *headers;
} ngx_http_headers_conf_t;
@ -29,6 +43,13 @@ typedef struct {
#define NGX_HTTP_EXPIRES_MAX -2147483644
static ngx_int_t ngx_http_set_expires(ngx_http_request_t *r,
ngx_http_headers_conf_t *conf);
static ngx_int_t ngx_http_add_cache_control(ngx_http_request_t *r,
ngx_http_header_val_t *hv, ngx_str_t *value);
static ngx_int_t ngx_http_set_last_modified(ngx_http_request_t *r,
ngx_http_header_val_t *hv, ngx_str_t *value);
static void *ngx_http_headers_create_conf(ngx_conf_t *cf);
static char *ngx_http_headers_merge_conf(ngx_conf_t *cf,
void *parent, void *child);
@ -39,6 +60,18 @@ static char *ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static ngx_http_set_header_t ngx_http_set_headers[] = {
{ ngx_string("Cache-Control"), 0, ngx_http_add_cache_control },
{ ngx_string("Last-Modified"),
offsetof(ngx_http_headers_out_t, last_modified),
ngx_http_set_last_modified },
{ ngx_null_string, 0, NULL }
};
static ngx_command_t ngx_http_headers_filter_commands[] = {
{ ngx_string("expires"),
@ -98,13 +131,15 @@ static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
static ngx_int_t
ngx_http_headers_filter(ngx_http_request_t *r)
{
size_t len;
ngx_str_t value;
ngx_uint_t i;
ngx_table_elt_t *expires, *cc, **ccp, *out;
ngx_http_header_val_t *h;
ngx_http_headers_conf_t *conf;
if (r != r->main
conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module);
if ((conf->expires == NGX_HTTP_EXPIRES_OFF && conf->headers == NULL)
|| r != r->main
|| (r->headers_out.status != NGX_HTTP_OK
&& r->headers_out.status != NGX_HTTP_NO_CONTENT
&& r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY
@ -114,124 +149,73 @@ ngx_http_headers_filter(ngx_http_request_t *r)
return ngx_http_next_header_filter(r);
}
conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module);
if (conf->expires != NGX_HTTP_EXPIRES_OFF) {
expires = r->headers_out.expires;
if (expires == NULL) {
expires = ngx_list_push(&r->headers_out.headers);
if (expires == NULL) {
return NGX_ERROR;
}
r->headers_out.expires = expires;
expires->hash = 1;
expires->key.len = sizeof("Expires") - 1;
expires->key.data = (u_char *) "Expires";
if (ngx_http_set_expires(r, conf) != NGX_OK) {
return NGX_ERROR;
}
}
len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT");
expires->value.len = len - 1;
if (conf->headers) {
h = conf->headers->elts;
for (i = 0; i < conf->headers->nelts; i++) {
ccp = r->headers_out.cache_control.elts;
if (ccp == NULL) {
if (ngx_array_init(&r->headers_out.cache_control, r->pool,
1, sizeof(ngx_table_elt_t *))
!= NGX_OK)
{
return NGX_ERROR;
}
ccp = ngx_array_push(&r->headers_out.cache_control);
if (ccp == NULL) {
return NGX_ERROR;
}
cc = ngx_list_push(&r->headers_out.headers);
if (cc == NULL) {
return NGX_ERROR;
}
cc->hash = 1;
cc->key.len = sizeof("Cache-Control") - 1;
cc->key.data = (u_char *) "Cache-Control";
*ccp = cc;
} else {
for (i = 1; i < r->headers_out.cache_control.nelts; i++) {
ccp[i]->hash = 0;
}
cc = ccp[0];
}
if (conf->expires == NGX_HTTP_EXPIRES_EPOCH) {
expires->value.data = (u_char *) "Thu, 01 Jan 1970 00:00:01 GMT";
cc->value.len = sizeof("no-cache") - 1;
cc->value.data = (u_char *) "no-cache";
} else if (conf->expires == NGX_HTTP_EXPIRES_MAX) {
expires->value.data = (u_char *) "Thu, 31 Dec 2037 23:55:55 GMT";
/* 10 years */
cc->value.len = sizeof("max-age=315360000") - 1;
cc->value.data = (u_char *) "max-age=315360000";
} else {
expires->value.data = ngx_palloc(r->pool, len);
if (expires->value.data == NULL) {
return NGX_ERROR;
}
if (conf->expires == 0) {
ngx_memcpy(expires->value.data, ngx_cached_http_time.data,
ngx_cached_http_time.len + 1);
cc->value.len = sizeof("max-age=0") - 1;
cc->value.data = (u_char *) "max-age=0";
if (h[i].lengths == NULL) {
value = h[i].value.value;
} else {
ngx_http_time(expires->value.data, ngx_time() + conf->expires);
if (conf->expires < 0) {
cc->value.len = sizeof("no-cache") - 1;
cc->value.data = (u_char *) "no-cache";
} else {
cc->value.data = ngx_palloc(r->pool, sizeof("max-age=")
+ NGX_TIME_T_LEN + 1);
if (cc->value.data == NULL) {
return NGX_ERROR;
}
cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T",
conf->expires)
- cc->value.data;
if (ngx_http_script_run(r, &value, h[i].lengths->elts, 0,
h[i].values->elts)
== NULL)
{
return NGX_ERROR;
}
}
if (h[i].handler(r, &h[i], &value) != NGX_OK) {
return NGX_ERROR;
}
}
}
if (conf->cache_control.len) {
return ngx_http_next_header_filter(r);
}
ccp = r->headers_out.cache_control.elts;
if (ccp == NULL) {
static ngx_int_t
ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
{
size_t len;
ngx_uint_t i;
ngx_table_elt_t *expires, *cc, **ccp;
if (ngx_array_init(&r->headers_out.cache_control, r->pool,
1, sizeof(ngx_table_elt_t *))
!= NGX_OK)
{
return NGX_ERROR;
}
expires = r->headers_out.expires;
if (expires == NULL) {
expires = ngx_list_push(&r->headers_out.headers);
if (expires == NULL) {
return NGX_ERROR;
}
r->headers_out.expires = expires;
expires->hash = 1;
expires->key.len = sizeof("Expires") - 1;
expires->key.data = (u_char *) "Expires";
}
len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT");
expires->value.len = len - 1;
ccp = r->headers_out.cache_control.elts;
if (ccp == NULL) {
if (ngx_array_init(&r->headers_out.cache_control, r->pool,
1, sizeof(ngx_table_elt_t *))
!= NGX_OK)
{
return NGX_ERROR;
}
ccp = ngx_array_push(&r->headers_out.cache_control);
@ -247,37 +231,161 @@ ngx_http_headers_filter(ngx_http_request_t *r)
cc->hash = 1;
cc->key.len = sizeof("Cache-Control") - 1;
cc->key.data = (u_char *) "Cache-Control";
cc->value = conf->cache_control;
*ccp = cc;
} else {
for (i = 1; i < r->headers_out.cache_control.nelts; i++) {
ccp[i]->hash = 0;
}
cc = ccp[0];
}
if (conf->headers) {
h = conf->headers->elts;
for (i = 0; i < conf->headers->nelts; i++) {
out = ngx_list_push(&r->headers_out.headers);
if (out == NULL) {
return NGX_ERROR;
}
if (conf->expires == NGX_HTTP_EXPIRES_EPOCH) {
expires->value.data = (u_char *) "Thu, 01 Jan 1970 00:00:01 GMT";
out->hash = h[i].value.hash;
out->key = h[i].value.key;
cc->value.len = sizeof("no-cache") - 1;
cc->value.data = (u_char *) "no-cache";
if (h[i].lengths == NULL) {
out->value = h[i].value.value;
continue;
}
return NGX_OK;
}
if (ngx_http_script_run(r, &out->value, h[i].lengths->elts, 0,
h[i].values->elts)
== NULL)
{
return NGX_ERROR;
}
if (conf->expires == NGX_HTTP_EXPIRES_MAX) {
expires->value.data = (u_char *) "Thu, 31 Dec 2037 23:55:55 GMT";
/* 10 years */
cc->value.len = sizeof("max-age=315360000") - 1;
cc->value.data = (u_char *) "max-age=315360000";
return NGX_OK;
}
expires->value.data = ngx_palloc(r->pool, len);
if (expires->value.data == NULL) {
return NGX_ERROR;
}
if (conf->expires == 0) {
ngx_memcpy(expires->value.data, ngx_cached_http_time.data,
ngx_cached_http_time.len + 1);
cc->value.len = sizeof("max-age=0") - 1;
cc->value.data = (u_char *) "max-age=0";
return NGX_OK;
}
ngx_http_time(expires->value.data, ngx_time() + conf->expires);
if (conf->expires < 0) {
cc->value.len = sizeof("no-cache") - 1;
cc->value.data = (u_char *) "no-cache";
return NGX_OK;
}
cc->value.data = ngx_palloc(r->pool,
sizeof("max-age=") + NGX_TIME_T_LEN + 1);
if (cc->value.data == NULL) {
return NGX_ERROR;
}
cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T", conf->expires)
- cc->value.data;
return NGX_OK;
}
static ngx_int_t
ngx_http_add_header(ngx_http_request_t *r, ngx_http_header_val_t *hv,
ngx_str_t *value)
{
ngx_table_elt_t *h;
h = ngx_list_push(&r->headers_out.headers);
if (h == NULL) {
return NGX_ERROR;
}
h->hash = hv->value.hash;
h->key = hv->value.key;
h->value = *value;
return NGX_OK;
}
static ngx_int_t
ngx_http_add_cache_control(ngx_http_request_t *r, ngx_http_header_val_t *hv,
ngx_str_t *value)
{
ngx_table_elt_t *cc, **ccp;
ccp = r->headers_out.cache_control.elts;
if (ccp == NULL) {
if (ngx_array_init(&r->headers_out.cache_control, r->pool,
1, sizeof(ngx_table_elt_t *))
!= NGX_OK)
{
return NGX_ERROR;
}
}
return ngx_http_next_header_filter(r);
ccp = ngx_array_push(&r->headers_out.cache_control);
if (ccp == NULL) {
return NGX_ERROR;
}
cc = ngx_list_push(&r->headers_out.headers);
if (cc == NULL) {
return NGX_ERROR;
}
cc->hash = 1;
cc->key.len = sizeof("Cache-Control") - 1;
cc->key.data = (u_char *) "Cache-Control";
cc->value = *value;
*ccp = cc;
return NGX_OK;
}
static ngx_int_t
ngx_http_set_last_modified(ngx_http_request_t *r, ngx_http_header_val_t *hv,
ngx_str_t *value)
{
ngx_table_elt_t *h, **old;
if (hv->offset) {
old = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset);
} else {
old = NULL;
}
if (old == NULL || *old == NULL) {
h = ngx_list_push(&r->headers_out.headers);
if (h == NULL) {
return NGX_ERROR;
}
} else {
h = *old;
}
h->hash = hv->value.hash;
h->key = hv->value.key;
h->value = *value;
r->headers_out.last_modified_time = -1;
return NGX_OK;
}
@ -294,8 +402,6 @@ ngx_http_headers_create_conf(ngx_conf_t *cf)
/*
* set by ngx_pcalloc():
*
* conf->cache_control.len = 0;
* conf->cache_control.data = NULL;
* conf->headers = NULL;
*/
@ -313,11 +419,7 @@ ngx_http_headers_merge_conf(ngx_conf_t *cf, void *parent, void *child)
if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
conf->expires = (prev->expires == NGX_HTTP_EXPIRES_UNSET) ?
NGX_HTTP_EXPIRES_OFF : prev->expires;
}
if (conf->cache_control.data == NULL) {
conf->cache_control = prev->cache_control;
NGX_HTTP_EXPIRES_OFF : prev->expires;
}
if (conf->headers == NULL) {
@ -406,16 +508,13 @@ ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_int_t n;
ngx_str_t *value;
ngx_uint_t i;
ngx_http_header_val_t *h;
ngx_http_set_header_t *sh;
ngx_http_script_compile_t sc;
value = cf->args->elts;
if (ngx_strcasecmp(value[1].data, (u_char *) "cache-control") == 0) {
hcf->cache_control = value[2];
return NGX_CONF_OK;
}
if (hcf->headers == NULL) {
hcf->headers = ngx_array_create(cf->pool, 1,
sizeof(ngx_http_header_val_t));
@ -432,9 +531,22 @@ ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
h->value.hash = 1;
h->value.key = value[1];
h->value.value = value[2];
h->offset = 0;
h->handler = ngx_http_add_header;
h->lengths = NULL;
h->values = NULL;
sh = ngx_http_set_headers;
for (i = 0; sh[i].name.len; i++) {
if (ngx_strcasecmp(value[1].data, sh[i].name.data) != 0) {
continue;
}
h->offset = sh[i].offset;
h->handler = sh[i].handler;
break;
}
n = ngx_http_script_variables_count(&value[2]);
if (n == 0) {

View File

@ -141,7 +141,7 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r)
if (len > 255) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"the value of the \"%V\" variable "
"is more than 255 bytes: \"%V\"",
"is more than 255 bytes: \"%v\"",
&ctx->var, vv);
return NGX_DECLINED;
}

View File

@ -114,7 +114,7 @@ static ngx_command_t ngx_http_log_commands[] = {
{ ngx_string("access_log"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_TAKE123,
|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE123,
ngx_http_log_set_log,
NGX_HTTP_LOC_CONF_OFFSET,
0,
@ -423,6 +423,11 @@ ngx_http_log_bytes_sent(ngx_http_request_t *r, u_char *buf,
}
/*
* although there is a real $body_bytes_sent variable,
* this log operation code function is more optimized for logging
*/
static u_char *
ngx_http_log_body_bytes_sent(ngx_http_request_t *r, u_char *buf,
ngx_http_log_op_t *op)

View File

@ -26,8 +26,7 @@ typedef struct {
typedef struct {
ngx_hash_t hash;
ngx_hash_wildcard_t *dns_wildcards;
ngx_hash_combined_t hash;
ngx_int_t index;
ngx_http_variable_value_t *default_value;
ngx_uint_t hostnames; /* unsigned hostnames:1 */
@ -142,32 +141,17 @@ ngx_http_map_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
key = ngx_hash(key, name[i]);
}
value = NULL;
if (map->hash.buckets) {
value = ngx_hash_find(&map->hash, key, name, len);
}
value = ngx_hash_find_combined(&map->hash, key, name, len);
if (value) {
*v = *value;
} else {
if (map->dns_wildcards && map->dns_wildcards->hash.buckets) {
value = ngx_hash_find_wildcard(map->dns_wildcards, name, len);
if (value) {
*v = *value;
} else {
*v = *map->default_value;
}
} else {
*v = *map->default_value;
}
*v = *map->default_value;
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http map: \"%V\" \"%V\"", vv, v);
"http map: \"%v\" \"%v\"", vv, v);
return NGX_OK;
}
@ -237,7 +221,7 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
name.len--;
name.data++;
var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGABLE);
var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
if (var == NULL) {
return NGX_CONF_ERROR;
}
@ -282,6 +266,9 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return rv;
}
map->default_value = ctx.default_value ? ctx.default_value:
&ngx_http_variable_null_value;
hash.key = ngx_hash_key_lc;
hash.max_size = mcf->hash_max_size;
hash.bucket_size = mcf->hash_bucket_size;
@ -289,7 +276,7 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
hash.pool = cf->pool;
if (ctx.keys.keys.nelts) {
hash.hash = &map->hash;
hash.hash = &map->hash.hash;
hash.temp_pool = NULL;
if (ngx_hash_init(&hash, ctx.keys.keys.elts, ctx.keys.keys.nelts)
@ -300,27 +287,44 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
map->default_value = ctx.default_value ? ctx.default_value:
&ngx_http_variable_null_value;
if (ctx.keys.dns_wc_head.nelts) {
if (ctx.keys.dns_wildcards.nelts) {
ngx_qsort(ctx.keys.dns_wildcards.elts,
(size_t) ctx.keys.dns_wildcards.nelts,
ngx_qsort(ctx.keys.dns_wc_head.elts,
(size_t) ctx.keys.dns_wc_head.nelts,
sizeof(ngx_hash_key_t), ngx_http_map_cmp_dns_wildcards);
hash.hash = NULL;
hash.temp_pool = pool;
if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wildcards.elts,
ctx.keys.dns_wildcards.nelts)
if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wc_head.elts,
ctx.keys.dns_wc_head.nelts)
!= NGX_OK)
{
ngx_destroy_pool(pool);
return NGX_CONF_ERROR;
}
map->dns_wildcards = (ngx_hash_wildcard_t *) hash.hash;
map->hash.wc_head = (ngx_hash_wildcard_t *) hash.hash;
}
if (ctx.keys.dns_wc_tail.nelts) {
ngx_qsort(ctx.keys.dns_wc_tail.elts,
(size_t) ctx.keys.dns_wc_tail.nelts,
sizeof(ngx_hash_key_t), ngx_http_map_cmp_dns_wildcards);
hash.hash = NULL;
hash.temp_pool = pool;
if (ngx_hash_wildcard_init(&hash, ctx.keys.dns_wc_tail.elts,
ctx.keys.dns_wc_tail.nelts)
!= NGX_OK)
{
ngx_destroy_pool(pool);
return NGX_CONF_ERROR;
}
map->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
}
ngx_destroy_pool(pool);
@ -344,10 +348,9 @@ ngx_http_map_cmp_dns_wildcards(const void *one, const void *two)
static char *
ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
{
u_char ch;
ngx_int_t rc;
ngx_str_t *value, file;
ngx_uint_t i, key, flags;
ngx_uint_t i, key;
ngx_http_map_conf_ctx_t *ctx;
ngx_http_variable_value_t *var, **vp;
@ -427,7 +430,7 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
}
var->valid = 1;
var->no_cachable = 0;
var->no_cacheable = 0;
var->not_found = 0;
vp = ngx_array_push(&ctx->values_hash[key]);
@ -439,50 +442,36 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
found:
ch = value[0].data[0];
if (ngx_strcmp(value[0].data, "default") == 0) {
if ((ch != '*' && ch != '.') || ctx->hostnames == 0) {
if (ngx_strcmp(value[0].data, "default") == 0) {
if (ctx->default_value) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"duplicate default map parameter");
return NGX_CONF_ERROR;
}
ctx->default_value = var;
return NGX_CONF_OK;
}
if (value[0].len && ch == '!') {
value[0].len--;
value[0].data++;
}
flags = 0;
} else {
if ((ch == '*' && (value[0].len < 3 || value[0].data[1] != '.'))
|| (ch == '.' && value[0].len < 2))
{
if (ctx->default_value) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid DNS wildcard \"%V\"", &value[0]);
"duplicate default map parameter");
return NGX_CONF_ERROR;
}
flags = NGX_HASH_WILDCARD_KEY;
ctx->default_value = var;
return NGX_CONF_OK;
}
rc = ngx_hash_add_key(&ctx->keys, &value[0], var, flags);
if (value[0].len && value[0].data[0] == '!') {
value[0].len--;
value[0].data++;
}
rc = ngx_hash_add_key(&ctx->keys, &value[0], var,
(ctx->hostnames) ? NGX_HASH_WILDCARD_KEY : 0);
if (rc == NGX_OK) {
return NGX_CONF_OK;
}
if (rc == NGX_DECLINED) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid hostname or wildcard \"%V\"", &value[0]);
}
if (rc == NGX_BUSY) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"conflicting parameter \"%V\"", &value[0]);

View File

@ -226,6 +226,7 @@ static ngx_int_t
ngx_http_memcached_create_request(ngx_http_request_t *r)
{
size_t len;
uintptr_t escape;
ngx_buf_t *b;
ngx_chain_t *cl;
ngx_http_memcached_ctx_t *ctx;
@ -242,10 +243,9 @@ ngx_http_memcached_create_request(ngx_http_request_t *r)
return NGX_ERROR;
}
len = sizeof("get ") - 1 + vv->len + sizeof(CRLF) - 1;
if (vv->len) {
len += 1 + vv->len;
}
escape = 2 * ngx_escape_uri(NULL, vv->data, vv->len, NGX_ESCAPE_MEMCACHED);
len = sizeof("get ") - 1 + vv->len + escape + sizeof(CRLF) - 1;
b = ngx_create_temp_buf(r->pool, len);
if (b == NULL) {
@ -268,7 +268,13 @@ ngx_http_memcached_create_request(ngx_http_request_t *r)
ctx->key.data = b->last;
b->last = ngx_copy(b->last, vv->data, vv->len);
if (escape == 0) {
b->last = ngx_copy(b->last, vv->data, vv->len);
} else {
b->last = (u_char *) ngx_escape_uri(b->last, vv->data, vv->len,
NGX_ESCAPE_MEMCACHED);
}
ctx->key.len = b->last - ctx->key.data;
@ -365,6 +371,7 @@ found:
}
u->headers_in.status_n = 200;
u->state->status = 200;
u->buffer.pos = p + 1;
return NGX_OK;
@ -375,6 +382,7 @@ found:
"key: \"%V\" was not found by memcached", &ctx->key);
u->headers_in.status_n = 404;
u->state->status = 404;
return NGX_OK;
}
@ -419,16 +427,16 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
if (u->length == ctx->rest) {
if (ngx_strncmp(b->last,
ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END
- ctx->rest,
bytes) != 0)
ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END - ctx->rest,
ctx->rest)
!= 0)
{
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
"memcached sent invalid trailer");
}
u->length -= bytes;
ctx->rest -= bytes;
u->length = 0;
ctx->rest = 0;
return NGX_OK;
}
@ -447,7 +455,8 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
*ll = cl;
cl->buf->pos = b->last;
last = b->last;
cl->buf->pos = last;
b->last += bytes;
cl->buf->last = b->last;
@ -455,20 +464,19 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
"memcached filter bytes:%z size:%z length:%z rest:%z",
bytes, b->last - b->pos, u->length, ctx->rest);
if (b->last - b->pos <= (ssize_t) (u->length - NGX_HTTP_MEMCACHED_END)) {
if (bytes <= (ssize_t) (u->length - NGX_HTTP_MEMCACHED_END)) {
u->length -= bytes;
return NGX_OK;
}
last = b->pos + u->length - NGX_HTTP_MEMCACHED_END;
last += u->length - NGX_HTTP_MEMCACHED_END;
if (ngx_strncmp(last, ngx_http_memcached_end, b->last - last) != 0) {
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
"memcached sent invalid trailer");
}
ctx->rest = u->length - (b->last - b->pos);
ctx->rest -= b->last - last;
b->last = last;
cl->buf->last = last;
u->length = ctx->rest;

View File

@ -70,7 +70,7 @@ ngx_int_t ngx_http_not_modified_header_filter(ngx_http_request_t *r)
* I think that the equality of the dates is correcter
*/
if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) {
if (ims == r->headers_out.last_modified_time) {
r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
r->headers_out.content_type.len = 0;
ngx_http_clear_content_length(r);

View File

@ -105,6 +105,8 @@ static char *ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data);
@ -154,6 +156,20 @@ static ngx_command_t ngx_http_proxy_commands[] = {
0,
NULL },
{ ngx_string("proxy_store"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_http_proxy_store,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL },
{ ngx_string("proxy_store_access"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
ngx_conf_set_access_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_proxy_loc_conf_t, upstream.store_access),
NULL },
{ ngx_string("proxy_buffering"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@ -404,10 +420,10 @@ static ngx_str_t ngx_http_proxy_hide_headers[] = {
static ngx_http_variable_t ngx_http_proxy_vars[] = {
{ ngx_string("proxy_host"), NULL, ngx_http_proxy_host_variable, 0,
NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOHASH, 0 },
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOHASH, 0 },
{ ngx_string("proxy_port"), NULL, ngx_http_proxy_port_variable, 0,
NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOHASH, 0 },
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOHASH, 0 },
{ ngx_string("proxy_add_x_forwarded_for"), NULL,
ngx_http_proxy_add_x_forwarded_for_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
@ -537,7 +553,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
} else {
unparsed_uri = 0;
if (r->quoted_uri) {
if (r->quoted_uri || r->internal) {
escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len,
r->uri.len - loc_len, NGX_ESCAPE_URI);
}
@ -545,7 +561,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r)
len += r->uri.len - loc_len + escape + sizeof("?") - 1 + r->args.len;
}
ngx_http_script_flush_no_cachable_variables(r, plcf->flushes);
ngx_http_script_flush_no_cacheable_variables(r, plcf->flushes);
if (plcf->body_set_len) {
le.ip = plcf->body_set_len->elts;
@ -822,7 +838,7 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
if (p == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
return NGX_ERROR;
}
rc = ngx_http_proxy_parse_status_line(r, p);
@ -844,7 +860,8 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
#endif
r->http_version = NGX_HTTP_VERSION_9;
p->status = NGX_HTTP_OK;
u->headers_in.status_n = NGX_HTTP_OK;
u->state->status = NGX_HTTP_OK;
return NGX_OK;
}
@ -856,7 +873,7 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
u->headers_in.status_line.data = ngx_palloc(r->pool,
u->headers_in.status_line.len);
if (u->headers_in.status_line.data == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
return NGX_ERROR;
}
ngx_memcpy(u->headers_in.status_line.data, p->status_start,
@ -1100,7 +1117,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
h = ngx_list_push(&r->upstream->headers_in.headers);
if (h == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
return NGX_ERROR;
}
h->hash = r->header_hash;
@ -1111,7 +1128,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
h->key.data = ngx_palloc(r->pool,
h->key.len + 1 + h->value.len + 1 + h->key.len);
if (h->key.data == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
return NGX_ERROR;
}
h->value.data = h->key.data + h->key.len + 1;
@ -1125,7 +1142,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
} else {
for (i = 0; i < h->key.len; i++) {
h->lowcase_key[i] = ngx_tolower(h->lowcase_key[i]);
h->lowcase_key[i] = ngx_tolower(h->key.data[i]);
}
}
@ -1133,7 +1150,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
h->lowcase_key, h->key.len);
if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
return NGX_ERROR;
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@ -1158,7 +1175,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
if (r->upstream->headers_in.server == NULL) {
h = ngx_list_push(&r->upstream->headers_in.headers);
if (h == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
return NGX_ERROR;
}
h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(
@ -1174,7 +1191,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
if (r->upstream->headers_in.date == NULL) {
h = ngx_list_push(&r->upstream->headers_in.headers);
if (h == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
return NGX_ERROR;
}
h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e');
@ -1233,7 +1250,7 @@ ngx_http_proxy_host_variable(ngx_http_request_t *r,
v->len = plcf->host_header.len;
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
v->data = plcf->host_header.data;
@ -1251,7 +1268,7 @@ ngx_http_proxy_port_variable(ngx_http_request_t *r,
v->len = plcf->port.len;
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
v->data = plcf->port.data;
@ -1266,7 +1283,7 @@ ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
u_char *p;
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
if (r->headers_in.x_forwarded_for == NULL) {
@ -1310,7 +1327,7 @@ ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r,
}
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
v->data = ngx_palloc(r->connection->pool, NGX_SIZE_T_LEN);
@ -1485,11 +1502,11 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
* conf->upstream.next_upstream = 0;
* conf->upstream.temp_path = NULL;
* conf->upstream.hide_headers_hash = { NULL, 0 };
* conf->upstream.hide_headers = NULL;
* conf->upstream.pass_headers = NULL;
* conf->upstream.schema = { 0, NULL };
* conf->upstream.uri = { 0, NULL };
* conf->upstream.location = NULL;
* conf->upstream.store_lengths = NULL;
* conf->upstream.store_values = NULL;
*
* conf->method = NULL;
* conf->headers_source = NULL;
@ -1502,6 +1519,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
* conf->rewrite_locations = NULL;
*/
conf->upstream.store = NGX_CONF_UNSET;
conf->upstream.store_access = NGX_CONF_UNSET_UINT;
conf->upstream.buffering = NGX_CONF_UNSET;
conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
@ -1519,6 +1538,9 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
conf->upstream.pass_request_headers = NGX_CONF_UNSET;
conf->upstream.pass_request_body = NGX_CONF_UNSET;
conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
conf->upstream.intercept_errors = NGX_CONF_UNSET;
/* "proxy_cyclic_temp_file" is disabled */
@ -1543,9 +1565,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
u_char *p;
size_t size;
uintptr_t *code;
ngx_str_t *header;
ngx_uint_t i, j;
ngx_array_t hide_headers;
ngx_uint_t i;
ngx_keyval_t *src, *s, *h;
ngx_hash_key_t *hk;
ngx_hash_init_t hash;
@ -1553,6 +1573,19 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_script_compile_t sc;
ngx_http_script_copy_code_t *copy;
if (conf->upstream.store != 0) {
ngx_conf_merge_value(conf->upstream.store,
prev->upstream.store, 0);
if (conf->upstream.store_lengths == NULL) {
conf->upstream.store_lengths = prev->upstream.store_lengths;
conf->upstream.store_values = prev->upstream.store_values;
}
}
ngx_conf_merge_uint_value(conf->upstream.store_access,
prev->upstream.store_access, 0600);
ngx_conf_merge_value(conf->upstream.buffering,
prev->upstream.buffering, 1);
@ -1741,107 +1774,18 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
conf->headers_hash_bucket_size = ngx_align(conf->headers_hash_bucket_size,
ngx_cacheline_size);
if (conf->upstream.hide_headers == NULL
&& conf->upstream.pass_headers == NULL)
{
conf->upstream.hide_headers = prev->upstream.hide_headers;
conf->upstream.pass_headers = prev->upstream.pass_headers;
conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash;
hash.max_size = conf->headers_hash_max_size;
hash.bucket_size = conf->headers_hash_bucket_size;
hash.name = "proxy_headers_hash";
if (conf->upstream.hide_headers_hash.buckets) {
goto peers;
}
} else {
if (conf->upstream.hide_headers == NULL) {
conf->upstream.hide_headers = prev->upstream.hide_headers;
}
if (conf->upstream.pass_headers == NULL) {
conf->upstream.pass_headers = prev->upstream.pass_headers;
}
}
if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
&prev->upstream,
ngx_http_proxy_hide_headers, &hash)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
for (header = ngx_http_proxy_hide_headers; header->len; header++) {
hk = ngx_array_push(&hide_headers);
if (hk == NULL) {
return NGX_CONF_ERROR;
}
hk->key = *header;
hk->key_hash = ngx_hash_key_lc(header->data, header->len);
hk->value = (void *) 1;
}
if (conf->upstream.hide_headers) {
header = conf->upstream.hide_headers->elts;
for (i = 0; i < conf->upstream.hide_headers->nelts; i++) {
hk = hide_headers.elts;
for (j = 0; j < hide_headers.nelts; j++) {
if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
goto exist;
}
}
hk = ngx_array_push(&hide_headers);
if (hk == NULL) {
return NGX_CONF_ERROR;
}
hk->key = header[i];
hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len);
hk->value = (void *) 1;
exist:
continue;
}
}
if (conf->upstream.pass_headers) {
hk = hide_headers.elts;
header = conf->upstream.pass_headers->elts;
for (i = 0; i < conf->upstream.pass_headers->nelts; i++) {
for (j = 0; j < hide_headers.nelts; j++) {
if (hk[j].key.data == NULL) {
continue;
}
if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
hk[j].key.data = NULL;
break;
}
}
}
}
hash.hash = &conf->upstream.hide_headers_hash;
hash.key = ngx_hash_key_lc;
hash.max_size = conf->headers_hash_max_size;
hash.bucket_size = conf->headers_hash_bucket_size;
hash.name = "proxy_headers_hash";
hash.pool = cf->pool;
hash.temp_pool = NULL;
if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) {
return NGX_CONF_ERROR;
}
peers:
if (conf->upstream.upstream == NULL) {
conf->upstream.upstream = prev->upstream.upstream;
@ -2204,6 +2148,7 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (port == 80) {
plcf->port.len = sizeof("80") - 1;
plcf->port.data = (u_char *) "80";
} else {
plcf->port.len = sizeof("443") - 1;
plcf->port.data = (u_char *) "443";
@ -2242,13 +2187,17 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
plcf->upstream.location = clcf->name;
if (clcf->named
#if (NGX_PCRE)
if (clcf->regex || clcf->noname) {
|| clcf->regex
#endif
|| clcf->noname)
{
if (plcf->upstream.uri.len) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"proxy_pass\" may not have URI part in "
"location given by regular expression, "
"or inside named location, "
"or inside the \"if\" statement, "
"or inside the \"limit_except\" block");
return NGX_CONF_ERROR;
@ -2257,8 +2206,6 @@ ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
plcf->upstream.location.len = 0;
}
#endif
plcf->upstream.url = *url;
if (clcf->name.data[clcf->name.len - 1] == '/') {
@ -2359,6 +2306,52 @@ ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
static char *
ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_proxy_loc_conf_t *plcf = conf;
ngx_str_t *value;
ngx_http_script_compile_t sc;
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;
return NGX_CONF_OK;
}
if (ngx_strcmp(value[1].data, "off") == 0) {
plcf->upstream.store = 0;
return NGX_CONF_OK;
}
/* include the terminating '\0' into script */
value[1].len++;
ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
sc.cf = cf;
sc.source = &value[1];
sc.lengths = &plcf->upstream.store_lengths;
sc.values = &plcf->upstream.store_values;
sc.variables = ngx_http_script_variables_count(&value[1]);
sc.complete_lengths = 1;
sc.complete_values = 1;
if (ngx_http_script_compile(&sc) != NGX_OK) {
return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
}
static char *
ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data)
{

View File

@ -134,6 +134,7 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
u_char *p;
size_t len;
off_t start, end;
time_t if_range;
ngx_int_t rc;
ngx_uint_t suffix, i;
ngx_atomic_uint_t boundary;
@ -156,18 +157,21 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
(u_char *) "bytes=", 6)
!= 0)
{
r->headers_out.accept_ranges = ngx_list_push(&r->headers_out.headers);
if (r->headers_out.accept_ranges == NULL) {
return NGX_ERROR;
goto next_filter;
}
if (r->headers_in.if_range && r->headers_out.last_modified_time != -1) {
if_range = ngx_http_parse_time(r->headers_in.if_range->value.data,
r->headers_in.if_range->value.len);
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http ir:%d lm:%d",
if_range, r->headers_out.last_modified_time);
if (if_range != r->headers_out.last_modified_time) {
goto next_filter;
}
r->headers_out.accept_ranges->hash = 1;
r->headers_out.accept_ranges->key.len = sizeof("Accept-Ranges") - 1;
r->headers_out.accept_ranges->key.data = (u_char *) "Accept-Ranges";
r->headers_out.accept_ranges->value.len = sizeof("bytes") - 1;
r->headers_out.accept_ranges->value.data = (u_char *) "bytes";
return ngx_http_next_header_filter(r);
}
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_range_filter_ctx_t));
@ -460,6 +464,21 @@ ngx_http_range_header_filter(ngx_http_request_t *r)
r->headers_out.content_length = NULL;
}
return ngx_http_next_header_filter(r);
next_filter:
r->headers_out.accept_ranges = ngx_list_push(&r->headers_out.headers);
if (r->headers_out.accept_ranges == NULL) {
return NGX_ERROR;
}
r->headers_out.accept_ranges->hash = 1;
r->headers_out.accept_ranges->key.len = sizeof("Accept-Ranges") - 1;
r->headers_out.accept_ranges->key.data = (u_char *) "Accept-Ranges";
r->headers_out.accept_ranges->value.len = sizeof("bytes") - 1;
r->headers_out.accept_ranges->value.data = (u_char *) "bytes";
return ngx_http_next_header_filter(r);
}

View File

@ -188,6 +188,7 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_realip_loc_conf_t *rlcf = conf;
ngx_int_t rc;
ngx_str_t *value;
ngx_inet_cidr_t in_cidr;
ngx_http_realip_from_t *from;
@ -215,12 +216,19 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}
if (ngx_ptocidr(&value[1], &in_cidr) == NGX_ERROR) {
rc = ngx_ptocidr(&value[1], &in_cidr);
if (rc == NGX_ERROR) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
&value[1]);
return NGX_CONF_ERROR;
}
if (rc == NGX_DONE) {
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"low address bits of %V are meaningless", &value[1]);
}
from->mask = in_cidr.mask;
from->addr = in_cidr.addr;

View File

@ -11,9 +11,26 @@
#define NGX_HTTP_REFERER_NO_URI_PART ((void *) 4)
#if (NGX_PCRE)
typedef struct {
ngx_hash_t hash;
ngx_hash_wildcard_t *dns_wildcards;
ngx_regex_t *regex;
ngx_str_t name;
} ngx_http_referer_regex_t;
#else
#define ngx_regex_t void
#endif
typedef struct {
ngx_hash_combined_t hash;
#if (NGX_PCRE)
ngx_array_t *regex;
#endif
ngx_flag_t no_referer;
ngx_flag_t blocked_referer;
@ -29,6 +46,8 @@ static char *ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
ngx_str_t *value, ngx_str_t *uri);
static char *ngx_http_add_regex_referer(ngx_conf_t *cf,
ngx_http_referer_conf_t *rlcf, ngx_str_t *name, ngx_regex_t *regex);
static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one,
const void *two);
@ -81,16 +100,28 @@ static ngx_int_t
ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
uintptr_t data)
{
u_char *p, *ref, *last;
size_t len;
ngx_str_t *uri;
ngx_uint_t i, key;
ngx_http_referer_conf_t *rlcf;
u_char buf[256];
u_char *p, *ref, *last;
size_t len;
ngx_str_t *uri;
ngx_uint_t i, key;
ngx_http_referer_conf_t *rlcf;
u_char buf[256];
#if (NGX_PCRE)
ngx_int_t n;
ngx_str_t referer;
ngx_http_referer_regex_t *regex;
#endif
rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module);
if (rlcf->hash.buckets == NULL && rlcf->dns_wildcards == NULL) {
if (rlcf->hash.hash.buckets == NULL
&& rlcf->hash.wc_head == NULL
&& rlcf->hash.wc_tail == NULL
#if (NGX_PCRE)
&& rlcf->regex == NULL
#endif
)
{
goto valid;
}
@ -133,21 +164,43 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
}
}
len = p - ref;
uri = ngx_hash_find_combined(&rlcf->hash, key, buf, p - ref);
if (rlcf->hash.buckets) {
uri = ngx_hash_find(&rlcf->hash, key, buf, len);
if (uri) {
goto uri;
if (uri) {
goto uri;
}
#if (NGX_PCRE)
if (rlcf->regex) {
referer.len = len - 7;
referer.data = ref;
regex = rlcf->regex->elts;
for (i = 0; i < rlcf->regex->nelts; i++) {
n = ngx_regex_exec(regex[i].regex, &referer, NULL, 0);
if (n == NGX_REGEX_NO_MATCHED) {
continue;
}
if (n < 0) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
ngx_regex_exec_n
" failed: %d on \"%V\" using \"%V\"",
n, &referer, &regex[i].name);
return NGX_ERROR;
}
/* match */
goto valid;
}
}
if (rlcf->dns_wildcards) {
uri = ngx_hash_find_wildcard(rlcf->dns_wildcards, buf, len);
if (uri) {
goto uri;
}
}
#endif
invalid:
@ -208,7 +261,6 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
if (conf->keys == NULL) {
conf->hash = prev->hash;
conf->dns_wildcards = prev->dns_wildcards;
ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0);
ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0);
@ -217,7 +269,9 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
}
if ((conf->no_referer == 1 || conf->blocked_referer == 1)
&& conf->keys->keys.nelts == 0 && conf->keys->dns_wildcards.nelts == 0)
&& conf->keys->keys.nelts == 0
&& conf->keys->dns_wc_head.nelts == 0
&& conf->keys->dns_wc_tail.nelts == 0)
{
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"the \"none\" or \"blocked\" referers are specified "
@ -233,7 +287,7 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
hash.pool = cf->pool;
if (conf->keys->keys.nelts) {
hash.hash = &conf->hash;
hash.hash = &conf->hash.hash;
hash.temp_pool = NULL;
if (ngx_hash_init(&hash, conf->keys->keys.elts, conf->keys->keys.nelts)
@ -243,24 +297,44 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
}
}
if (conf->keys->dns_wildcards.nelts) {
if (conf->keys->dns_wc_head.nelts) {
ngx_qsort(conf->keys->dns_wildcards.elts,
(size_t) conf->keys->dns_wildcards.nelts,
ngx_qsort(conf->keys->dns_wc_head.elts,
(size_t) conf->keys->dns_wc_head.nelts,
sizeof(ngx_hash_key_t),
ngx_http_cmp_referer_wildcards);
hash.hash = NULL;
hash.temp_pool = cf->temp_pool;
if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wildcards.elts,
conf->keys->dns_wildcards.nelts)
if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_head.elts,
conf->keys->dns_wc_head.nelts)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
conf->dns_wildcards = (ngx_hash_wildcard_t *) hash.hash;
conf->hash.wc_head = (ngx_hash_wildcard_t *) hash.hash;
}
if (conf->keys->dns_wc_tail.nelts) {
ngx_qsort(conf->keys->dns_wc_tail.elts,
(size_t) conf->keys->dns_wc_tail.nelts,
sizeof(ngx_hash_key_t),
ngx_http_cmp_referer_wildcards);
hash.hash = NULL;
hash.temp_pool = cf->temp_pool;
if (ngx_hash_wildcard_init(&hash, conf->keys->dns_wc_tail.elts,
conf->keys->dns_wc_tail.nelts)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
conf->hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
}
if (conf->no_referer == NGX_CONF_UNSET) {
@ -293,7 +367,7 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
name.data = (u_char *) "invalid_referer";
var = ngx_http_add_variable(cf, &name,
NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOHASH);
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOHASH);
if (var == NULL) {
return NGX_CONF_ERROR;
}
@ -342,6 +416,21 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
sn = cscf->server_names.elts;
for (n = 0; n < cscf->server_names.nelts; n++) {
#if (NGX_PCRE)
if (sn[n].regex) {
if (ngx_http_add_regex_referer(cf, rlcf, &sn[n].name,
sn[n].regex)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
continue;
}
#endif
if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name, &uri)
!= NGX_OK)
{
@ -352,6 +441,15 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
if (value[i].data[0] == '~') {
if (ngx_http_add_regex_referer(cf, rlcf, &value[i], NULL) != NGX_OK)
{
return NGX_CONF_ERROR;
}
continue;
}
p = (u_char *) ngx_strchr(value[i].data, '/');
if (p) {
@ -373,23 +471,8 @@ static char *
ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
ngx_str_t *value, ngx_str_t *uri)
{
u_char ch;
ngx_int_t rc;
ngx_str_t *u;
ngx_uint_t flags;
ch = value->data[0];
if ((ch == '*' && (value->len < 3 || value->data[1] != '.'))
|| (ch == '.' && value->len < 2))
{
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid DNS wildcard \"%V\"", value);
return NGX_CONF_ERROR;
}
flags = (ch == '*' || ch == '.') ? NGX_HASH_WILDCARD_KEY : 0;
ngx_int_t rc;
ngx_str_t *u;
if (uri->len == 0) {
u = NGX_HTTP_REFERER_NO_URI_PART;
@ -403,12 +486,17 @@ ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
*u = *uri;
}
rc = ngx_hash_add_key(keys, value, u, flags);
rc = ngx_hash_add_key(keys, value, u, NGX_HASH_WILDCARD_KEY);
if (rc == NGX_OK) {
return NGX_CONF_OK;
}
if (rc == NGX_DECLINED) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid hostname or wildcard \"%V\"", value);
}
if (rc == NGX_BUSY) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"conflicting parameter \"%V\"", value);
@ -418,6 +506,64 @@ ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
}
static char *
ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
ngx_str_t *name, ngx_regex_t *regex)
{
#if (NGX_PCRE)
ngx_str_t err;
ngx_http_referer_regex_t *rr;
u_char errstr[NGX_MAX_CONF_ERRSTR];
if (rlcf->regex == NULL) {
rlcf->regex = ngx_array_create(cf->pool, 2,
sizeof(ngx_http_referer_regex_t));
if (rlcf->regex == NULL) {
return NGX_CONF_ERROR;
}
}
rr = ngx_array_push(rlcf->regex);
if (rr == NULL) {
return NGX_CONF_ERROR;
}
if (regex) {
rr->regex = regex;
rr->name = *name;
return NGX_CONF_OK;
}
err.len = NGX_MAX_CONF_ERRSTR;
err.data = errstr;
name->len--;
name->data++;
rr->regex = ngx_regex_compile(name, NGX_REGEX_CASELESS, cf->pool, &err);
if (rr->regex == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
return NGX_CONF_ERROR;
}
rr->name = *name;
return NGX_CONF_OK;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"the using of the regex \"%V\" requires PCRE library",
name);
return NGX_CONF_ERROR;
#endif
}
static int ngx_libc_cdecl
ngx_http_cmp_referer_wildcards(const void *one, const void *two)
{

View File

@ -924,7 +924,7 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
value[1].len--;
value[1].data++;
v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGABLE);
v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE);
if (v == NULL) {
return NGX_CONF_ERROR;
}

View File

@ -212,6 +212,7 @@ static ngx_str_t ngx_http_ssi_null_string = ngx_null_string;
#define NGX_HTTP_SSI_ECHO_VAR 0
#define NGX_HTTP_SSI_ECHO_DEFAULT 1
#define NGX_HTTP_SSI_ECHO_ENCODING 2
#define NGX_HTTP_SSI_CONFIG_ERRMSG 0
#define NGX_HTTP_SSI_CONFIG_TIMEFMT 1
@ -237,6 +238,7 @@ static ngx_http_ssi_param_t ngx_http_ssi_include_params[] = {
static ngx_http_ssi_param_t ngx_http_ssi_echo_params[] = {
{ ngx_string("var"), NGX_HTTP_SSI_ECHO_VAR, 1, 0 },
{ ngx_string("default"), NGX_HTTP_SSI_ECHO_DEFAULT, 0, 0 },
{ ngx_string("encoding"), NGX_HTTP_SSI_ECHO_ENCODING, 0, 0 },
{ ngx_null_string, 0, 0, 0 }
};
@ -301,10 +303,10 @@ static ngx_http_ssi_command_t ngx_http_ssi_commands[] = {
static ngx_http_variable_t ngx_http_ssi_vars[] = {
{ ngx_string("date_local"), NULL, ngx_http_ssi_date_gmt_local_variable, 0,
NGX_HTTP_VAR_NOCACHABLE, 0 },
NGX_HTTP_VAR_NOCACHEABLE, 0 },
{ ngx_string("date_gmt"), NULL, ngx_http_ssi_date_gmt_local_variable, 1,
NGX_HTTP_VAR_NOCACHABLE, 0 },
NGX_HTTP_VAR_NOCACHEABLE, 0 },
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
};
@ -355,6 +357,7 @@ found:
ctx->value_len = slcf->value_len;
ctx->last_out = &ctx->out;
ctx->encoding = NGX_HTTP_SSI_ENTITY_ENCODING;
ctx->output = 1;
ctx->params.elts = ctx->params_array;
@ -439,6 +442,8 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
if (rc == NGX_ERROR || rc == NGX_AGAIN) {
return rc;
}
break;
}
}
@ -553,8 +558,9 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
if (b->in_file) {
if (slcf->min_file_chunk < (size_t) (b->last - b->pos))
{
b->file_last = b->file_pos + (b->last - b->start);
b->file_pos += b->pos - b->start;
b->file_last = b->file_pos
+ (b->last - ctx->buf->pos);
b->file_pos += b->pos - ctx->buf->pos;
} else {
b->in_file = 0;
@ -800,8 +806,14 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
}
if (cmd->flush && ctx->out) {
rc = ngx_http_ssi_output(r, ctx);
if (cmd->flush) {
if (ctx->out) {
rc = ngx_http_ssi_output(r, ctx);
} else {
rc = ngx_http_next_body_filter(r, NULL);
}
if (rc == NGX_ERROR) {
return NGX_ERROR;
@ -1020,6 +1032,7 @@ ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
ch = *p;
}
ctx->state = state;
ctx->pos = p;
ctx->looked = looked;
ctx->copy_end = p;
@ -1846,6 +1859,8 @@ static ngx_int_t
ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
ngx_str_t **params)
{
u_char *dst, *src;
size_t len;
ngx_int_t rc, key;
ngx_str_t *uri, *file, *wait, *set, *stub, args;
ngx_buf_t *b;
@ -1915,13 +1930,25 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
return rc;
}
args.len = 0;
args.data = NULL;
flags = 0;
dst = uri->data;
src = uri->data;
ngx_unescape_uri(&dst, &src, uri->len, NGX_UNESCAPE_URI);
len = (uri->data + uri->len) - src;
if (len) {
dst = ngx_copy(dst, src, len);
}
uri->len = dst - uri->data;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"ssi include: \"%V\"", uri);
args.len = 0;
args.data = NULL;
flags = 0;
if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
return NGX_HTTP_SSI_ERROR;
}
@ -1957,6 +1984,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
if (bl[i].count++) {
out = NULL;
ll = &out;
for (tl = bl[i].bufs; tl; tl = tl->next) {
@ -2110,10 +2138,12 @@ static ngx_int_t
ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
ngx_str_t **params)
{
u_char *p;
uintptr_t len;
ngx_int_t key;
ngx_uint_t i;
ngx_buf_t *b;
ngx_str_t *var, *value, text;
ngx_str_t *var, *value, *enc, text;
ngx_chain_t *cl;
ngx_http_variable_value_t *vv;
@ -2161,6 +2191,69 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
}
}
enc = params[NGX_HTTP_SSI_ECHO_ENCODING];
if (enc) {
if (enc->len == 4 && ngx_strncmp(enc->data, "none", 4) == 0) {
ctx->encoding = NGX_HTTP_SSI_NO_ENCODING;
} else if (enc->len == 3 && ngx_strncmp(enc->data, "url", 3) == 0) {
ctx->encoding = NGX_HTTP_SSI_URL_ENCODING;
} else if (enc->len == 6 && ngx_strncmp(enc->data, "entity", 6) == 0) {
ctx->encoding = NGX_HTTP_SSI_ENTITY_ENCODING;
} else {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"unknown encoding \"%V\" in the \"echo\" command",
enc);
}
}
switch (ctx->encoding) {
case NGX_HTTP_SSI_NO_ENCODING:
break;
case NGX_HTTP_SSI_URL_ENCODING:
len = 2 * ngx_escape_uri(NULL, value->data, value->len,
NGX_ESCAPE_HTML);
if (len) {
p = ngx_palloc(r->pool, value->len + len);
if (p == NULL) {
return NGX_HTTP_SSI_ERROR;
}
(void) ngx_escape_uri(p, value->data, value->len, NGX_ESCAPE_HTML);
value->len += len;
value->data = p;
}
break;
case NGX_HTTP_SSI_ENTITY_ENCODING:
len = ngx_escape_html(NULL, value->data, value->len);
if (len) {
p = ngx_palloc(r->pool, value->len + len);
if (p == NULL) {
return NGX_HTTP_SSI_ERROR;
}
(void) ngx_escape_html(p, value->data, value->len);
value->len += len;
value->data = p;
}
break;
}
b = ngx_calloc_buf(r->pool);
if (b == NULL) {
return NGX_HTTP_SSI_ERROR;
@ -2564,15 +2657,16 @@ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
char buf[NGX_HTTP_SSI_DATE_LEN];
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
tp = ngx_timeofday();
ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
if (ctx->timefmt.len == sizeof("%s") - 1
&& ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's')
if (ctx == NULL
|| (ctx->timefmt.len == sizeof("%s") - 1
&& ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's'))
{
v->data = ngx_palloc(r->pool, NGX_TIME_T_LEN);
if (v->data == NULL) {

View File

@ -13,15 +13,20 @@
#include <ngx_http.h>
#define NGX_HTTP_SSI_MAX_PARAMS 16
#define NGX_HTTP_SSI_MAX_PARAMS 16
#define NGX_HTTP_SSI_COMMAND_LEN 32
#define NGX_HTTP_SSI_PARAM_LEN 32
#define NGX_HTTP_SSI_PARAMS_N 4
#define NGX_HTTP_SSI_COMMAND_LEN 32
#define NGX_HTTP_SSI_PARAM_LEN 32
#define NGX_HTTP_SSI_PARAMS_N 4
#define NGX_HTTP_SSI_COND_IF 1
#define NGX_HTTP_SSI_COND_ELSE 2
#define NGX_HTTP_SSI_COND_IF 1
#define NGX_HTTP_SSI_COND_ELSE 2
#define NGX_HTTP_SSI_NO_ENCODING 0
#define NGX_HTTP_SSI_URL_ENCODING 1
#define NGX_HTTP_SSI_ENTITY_ENCODING 2
typedef struct {
@ -60,6 +65,7 @@ typedef struct {
ngx_array_t *blocks;
unsigned conditional:2;
unsigned encoding:2;
unsigned block:1;
unsigned output:1;
unsigned output_chosen:1;

View File

@ -170,19 +170,19 @@ ngx_module_t ngx_http_ssl_module = {
static ngx_http_variable_t ngx_http_ssl_vars[] = {
{ ngx_string("ssl_protocol"), NULL, ngx_http_ssl_static_variable,
(uintptr_t) ngx_ssl_get_protocol, NGX_HTTP_VAR_CHANGABLE, 0 },
(uintptr_t) ngx_ssl_get_protocol, NGX_HTTP_VAR_CHANGEABLE, 0 },
{ ngx_string("ssl_cipher"), NULL, ngx_http_ssl_static_variable,
(uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGABLE, 0 },
(uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGEABLE, 0 },
{ ngx_string("ssl_client_s_dn"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_subject_dn, NGX_HTTP_VAR_CHANGABLE, 0 },
(uintptr_t) ngx_ssl_get_subject_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
{ ngx_string("ssl_client_i_dn"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_issuer_dn, NGX_HTTP_VAR_CHANGABLE, 0 },
(uintptr_t) ngx_ssl_get_issuer_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
{ ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGABLE, 0 },
(uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 },
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
};
@ -197,17 +197,20 @@ ngx_http_ssl_static_variable(ngx_http_request_t *r,
{
ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
size_t len;
size_t len;
ngx_str_t s;
if (r->connection->ssl) {
(void) handler(r->connection, NULL, (ngx_str_t *) v);
(void) handler(r->connection, NULL, &s);
v->data = s.data;
for (len = 0; v->data[len]; len++) { /* void */ }
v->len = len;
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
return NGX_OK;
@ -225,14 +228,20 @@ ngx_http_ssl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
{
ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
ngx_str_t s;
if (r->connection->ssl) {
if (handler(r->connection, r->pool, (ngx_str_t *) v) != NGX_OK) {
if (handler(r->connection, r->pool, &s) != NGX_OK) {
return NGX_ERROR;
}
v->len = s.len;
v->data = s.data;
if (v->len) {
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
return NGX_OK;

View File

@ -129,7 +129,7 @@ static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
return rc;
}
return ngx_http_output_filter(r, &out);;
return ngx_http_output_filter(r, &out);
}

View File

@ -322,8 +322,8 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
b->recycled = 0;
if (b->in_file) {
b->file_last = b->file_pos + (b->last - b->start);
b->file_pos += b->pos - b->start;
b->file_last = b->file_pos + (b->last - ctx->buf->pos);
b->file_pos += b->pos - ctx->buf->pos;
}
cl->next = NULL;
@ -369,9 +369,14 @@ ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
}
b->memory = 1;
b->pos = ctx->sub.data;
b->last = ctx->sub.data + ctx->sub.len;
if (ctx->sub.len) {
b->memory = 1;
b->pos = ctx->sub.data;
b->last = ctx->sub.data + ctx->sub.len;
} else {
b->sync = 1;
}
cl->buf = b;
cl->next = NULL;
@ -557,6 +562,7 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
ch = ngx_tolower(ch);
}
ctx->state = state;
ctx->pos = p;
ctx->looked = looked;
ctx->copy_end = p;
@ -578,9 +584,13 @@ ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
looked++;
if (looked == ctx->match.len) {
if ((size_t) (p - ctx->pos) < looked) {
ctx->saved = 0;
}
ctx->state = sub_start_state;
ctx->pos = p + 1;
ctx->looked = looked;
ctx->looked = 0;
ctx->copy_end = copy_end;
if (ctx->copy_start == NULL && copy_end) {

View File

@ -198,9 +198,6 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
pc->sockaddr = peer->sockaddr;
pc->socklen = peer->socklen;
pc->name = &peer->name;
#if (NGX_SSL)
pc->ssl_session = peer->ssl_session;
#endif
/* ngx_unlock_mutex(iphp->rrp.peers->mutex); */

View File

@ -61,9 +61,11 @@ static char *ngx_http_userid_expires(ngx_conf_t *cf, ngx_command_t *cmd,
static char *ngx_http_userid_p3p(ngx_conf_t *cf, void *post, void *data);
static char *ngx_http_userid_mark(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static ngx_int_t ngx_http_userid_init_worker(ngx_cycle_t *cycle);
static uint32_t start_value;
static uint32_t sequencer_v1 = 1;
static uint32_t sequencer_v2 = 0x03030302;
@ -173,7 +175,7 @@ ngx_module_t ngx_http_userid_filter_module = {
NGX_HTTP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
ngx_http_userid_init_worker, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
@ -319,7 +321,7 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
ctx->uid_set[0] = conf->service;
}
ctx->uid_set[1] = ngx_time();
ctx->uid_set[2] = ngx_pid;
ctx->uid_set[2] = start_value;
ctx->uid_set[3] = sequencer_v1;
sequencer_v1 += 0x100;
@ -346,7 +348,7 @@ ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
}
ctx->uid_set[1] = htonl(ngx_time());
ctx->uid_set[2] = htonl(ngx_pid);
ctx->uid_set[2] = htonl(start_value);
ctx->uid_set[3] = htonl(sequencer_v2);
sequencer_v2 += 0x100;
if (sequencer_v2 < 0x03030302) {
@ -493,7 +495,7 @@ ngx_http_userid_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
}
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
ngx_sprintf(v->data, "%V=%08XD%08XD%08XD%08XD",
@ -706,3 +708,18 @@ ngx_http_userid_mark(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}
static ngx_int_t
ngx_http_userid_init_worker(ngx_cycle_t *cycle)
{
struct timeval tp;
ngx_gettimeofday(&tp);
/* use the most significant usec part that fits to 16 bits */
start_value = ((tp.tv_usec / 20) << 16) | ngx_pid;
return NGX_OK;
}

View File

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

View File

@ -131,6 +131,8 @@ send_http_header(r, ...)
XSRETURN_EMPTY;
}
r->headers_out.content_type_len = r->headers_out.content_type.len;
} else {
if (ngx_http_set_content_type(r) != NGX_OK) {
XSRETURN_EMPTY;
@ -910,7 +912,7 @@ variable(r, name, value = NULL)
if (value) {
vv->len = val.len;
vv->valid = 1;
vv->no_cachable = 0;
vv->no_cacheable = 0;
vv->not_found = 0;
vv->data = val.data;

View File

@ -67,6 +67,7 @@ static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static void ngx_http_perl_cleanup_perl(void *data);
#endif
static ngx_int_t ngx_http_perl_init_worker(ngx_cycle_t *cycle);
static void ngx_http_perl_exit(ngx_cycle_t *cycle);
@ -126,7 +127,7 @@ ngx_module_t ngx_http_perl_module = {
NGX_HTTP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
ngx_http_perl_init_worker, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
@ -335,7 +336,7 @@ ngx_http_perl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
if (value.data) {
v->len = value.len;
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
v->data = value.data;
@ -953,7 +954,7 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
value[1].len--;
value[1].data++;
v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGABLE);
v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE);
if (v == NULL) {
return NGX_CONF_ERROR;
}
@ -1004,6 +1005,27 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
static ngx_int_t
ngx_http_perl_init_worker(ngx_cycle_t *cycle)
{
ngx_http_perl_main_conf_t *pmcf;
pmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_perl_module);
{
dTHXa(pmcf->perl);
PERL_SET_CONTEXT(pmcf->perl);
/* set worker's $$ */
sv_setiv(GvSV(gv_fetchpv("$", TRUE, SVt_PV)), (I32) ngx_pid);
}
return NGX_OK;
}
static void
ngx_http_perl_exit(ngx_cycle_t *cycle)
{

View File

@ -73,7 +73,6 @@ static char *
ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *rv;
u_char ch;
ngx_int_t rc, j;
ngx_uint_t mi, m, s, l, p, a, i, n;
ngx_uint_t find_config_index, use_rewrite, use_access;
@ -99,6 +98,9 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_http_core_loc_conf_t *clcf;
ngx_http_phase_handler_pt checker;
ngx_http_core_main_conf_t *cmcf;
#if (NGX_PCRE)
ngx_uint_t regex;
#endif
#if (NGX_WIN32)
ngx_iocp_conf_t *iocpcf;
#endif
@ -402,6 +404,7 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
cmcf->phase_engine.server_rewrite_index = (ngx_uint_t) -1;
cmcf->phase_engine.location_rewrite_index = (ngx_uint_t) -1;
find_config_index = 0;
use_rewrite = cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers.nelts ? 1 : 0;
use_access = cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers.nelts ? 1 : 0;
@ -443,6 +446,14 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
case NGX_HTTP_REWRITE_PHASE:
if (cmcf->phase_engine.location_rewrite_index == (ngx_uint_t) -1) {
cmcf->phase_engine.location_rewrite_index = n;
}
checker = ngx_http_core_generic_phase;
break;
case NGX_HTTP_POST_REWRITE_PHASE:
if (use_rewrite) {
ph->checker = ngx_http_core_post_rewrite_phase;
@ -542,8 +553,8 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (in_addr[a].default_server) {
ngx_log_error(NGX_LOG_ERR, cf->log, 0,
"the duplicate default server in %V:%d",
&lscf[l].file_name, lscf[l].line);
"the duplicate default server in %s:%ui",
&lscf[l].file_name, lscf[l].line);
return NGX_CONF_ERROR;
}
@ -647,36 +658,20 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
#if (NGX_PCRE)
regex = 0;
#endif
name = in_addr[a].names.elts;
for (s = 0; s < in_addr[a].names.nelts; s++) {
ch = name[s].name.data[0];
if (ch == '*' || ch == '.') {
continue;
}
rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf,
0);
if (rc == NGX_ERROR) {
return NGX_CONF_ERROR;
}
if (rc == NGX_BUSY) {
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
"conflicting server name \"%V\" on %s, ignored",
&name[s].name, in_addr[a].listen_conf->addr);
}
}
for (s = 0; s < in_addr[a].names.nelts; s++) {
ch = name[s].name.data[0];
if (ch != '*' && ch != '.') {
#if (NGX_PCRE)
if (name[s].regex) {
regex++;
continue;
}
#endif
rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf,
NGX_HASH_WILDCARD_KEY);
@ -685,6 +680,13 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
if (rc == NGX_DECLINED) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"invalid server name or wildcard \"%V\" on %s",
&name[s].name, in_addr[a].listen_conf->addr);
return NGX_CONF_ERROR;
}
if (rc == NGX_BUSY) {
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
"conflicting server name \"%V\" on %s, ignored",
@ -709,28 +711,70 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
if (ha.dns_wildcards.nelts) {
if (ha.dns_wc_head.nelts) {
ngx_qsort(ha.dns_wildcards.elts,
(size_t) ha.dns_wildcards.nelts,
ngx_qsort(ha.dns_wc_head.elts,
(size_t) ha.dns_wc_head.nelts,
sizeof(ngx_hash_key_t),
ngx_http_cmp_dns_wildcards);
hash.hash = NULL;
hash.temp_pool = ha.temp_pool;
if (ngx_hash_wildcard_init(&hash, ha.dns_wildcards.elts,
ha.dns_wildcards.nelts)
if (ngx_hash_wildcard_init(&hash, ha.dns_wc_head.elts,
ha.dns_wc_head.nelts)
!= NGX_OK)
{
ngx_destroy_pool(ha.temp_pool);
return NGX_CONF_ERROR;
}
in_addr[a].dns_wildcards = (ngx_hash_wildcard_t *) hash.hash;
in_addr[a].wc_head = (ngx_hash_wildcard_t *) hash.hash;
}
if (ha.dns_wc_tail.nelts) {
ngx_qsort(ha.dns_wc_tail.elts,
(size_t) ha.dns_wc_tail.nelts,
sizeof(ngx_hash_key_t),
ngx_http_cmp_dns_wildcards);
hash.hash = NULL;
hash.temp_pool = ha.temp_pool;
if (ngx_hash_wildcard_init(&hash, ha.dns_wc_tail.elts,
ha.dns_wc_tail.nelts)
!= NGX_OK)
{
ngx_destroy_pool(ha.temp_pool);
return NGX_CONF_ERROR;
}
in_addr[a].wc_tail = (ngx_hash_wildcard_t *) hash.hash;
}
ngx_destroy_pool(ha.temp_pool);
#if (NGX_PCRE)
if (regex == 0) {
continue;
}
in_addr[a].nregex = regex;
in_addr[a].regex = ngx_palloc(cf->pool,
regex * sizeof(ngx_http_server_name_t));
if (in_addr[a].regex == NULL) {
return NGX_CONF_ERROR;
}
for (i = 0, s = 0; s < in_addr[a].names.nelts; s++) {
if (name[s].regex) {
in_addr[a].regex[i++] = name[s];
}
}
#endif
}
in_addr = in_port[p].addrs.elts;
@ -848,8 +892,10 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
hip->addrs[i].core_srv_conf = in_addr[i].core_srv_conf;
if (in_addr[i].hash.buckets == NULL
&& (in_addr[i].dns_wildcards == NULL
|| in_addr[i].dns_wildcards->hash.buckets == NULL))
&& (in_addr[i].wc_head == NULL
|| in_addr[i].wc_head->hash.buckets == NULL)
&& (in_addr[i].wc_head == NULL
|| in_addr[i].wc_head->hash.buckets == NULL))
{
continue;
}
@ -860,8 +906,13 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
hip->addrs[i].virtual_names = vn;
vn->hash = in_addr[i].hash;
vn->dns_wildcards = in_addr[i].dns_wildcards;
vn->names.hash = in_addr[i].hash;
vn->names.wc_head = in_addr[i].wc_head;
vn->names.wc_tail = in_addr[i].wc_tail;
#if (NGX_PCRE)
vn->nregex = in_addr[i].nregex;
vn->regex = in_addr[i].regex;
#endif
}
if (done) {
@ -920,7 +971,8 @@ ngx_http_add_address(ngx_conf_t *cf, ngx_http_conf_in_port_t *in_port,
if (in_port->addrs.elts == NULL) {
if (ngx_array_init(&in_port->addrs, cf->temp_pool, 4,
sizeof(ngx_http_conf_in_addr_t)) != NGX_OK)
sizeof(ngx_http_conf_in_addr_t))
!= NGX_OK)
{
return NGX_ERROR;
}
@ -934,8 +986,13 @@ ngx_http_add_address(ngx_conf_t *cf, ngx_http_conf_in_port_t *in_port,
in_addr->addr = lscf->addr;
in_addr->hash.buckets = NULL;
in_addr->hash.size = 0;
in_addr->dns_wildcards = NULL;
in_addr->wc_head = NULL;
in_addr->wc_tail = NULL;
in_addr->names.elts = NULL;
#if (NGX_PCRE)
in_addr->nregex = 0;
in_addr->regex = NULL;
#endif
in_addr->core_srv_conf = cscf;
in_addr->default_server = lscf->conf.default_server;
in_addr->bind = lscf->conf.bind;
@ -968,13 +1025,15 @@ ngx_http_add_names(ngx_conf_t *cf, ngx_http_conf_in_addr_t *in_addr,
if (in_addr->names.elts == NULL) {
if (ngx_array_init(&in_addr->names, cf->temp_pool, 4,
sizeof(ngx_http_server_name_t)) != NGX_OK)
sizeof(ngx_http_server_name_t))
!= NGX_OK)
{
return NGX_ERROR;
}
}
server_names = cscf->server_names.elts;
for (i = 0; i < cscf->server_names.nelts; i++) {
for (n = 0; n < server_names[i].name.len; n++) {
@ -985,7 +1044,6 @@ ngx_http_add_names(ngx_conf_t *cf, ngx_http_conf_in_addr_t *in_addr,
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
"name: %V", &server_names[i].name);
name = ngx_array_push(&in_addr->names);
if (name == NULL) {
return NGX_ERROR;

View File

@ -64,7 +64,8 @@ int ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg);
#endif
ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b);
ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r);
ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r,
ngx_uint_t merge_slashes);
ngx_int_t ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
ngx_str_t *args, ngx_uint_t *flags);
ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b);
@ -112,9 +113,4 @@ extern ngx_http_output_header_filter_pt ngx_http_top_header_filter;
extern ngx_http_output_body_filter_pt ngx_http_top_body_filter;
/* STUB */
ngx_int_t ngx_http_log_handler(ngx_http_request_t *r);
/**/
#endif /* _NGX_HTTP_H_INCLUDED_ */

View File

@ -10,9 +10,9 @@
static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
ngx_http_busy_lock_ctx_t *bc,
int lock);
static int ngx_http_busy_lock_look_cacheable(ngx_http_busy_lock_t *bl,
ngx_http_busy_lock_ctx_t *bc,
int lock);
int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc)
@ -60,12 +60,12 @@ int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc)
}
int ngx_http_busy_lock_cachable(ngx_http_busy_lock_t *bl,
ngx_http_busy_lock_ctx_t *bc, int lock)
int ngx_http_busy_lock_cacheable(ngx_http_busy_lock_t *bl,
ngx_http_busy_lock_ctx_t *bc, int lock)
{
int rc;
rc = ngx_http_busy_lock_look_cachable(bl, bc, lock);
rc = ngx_http_busy_lock_look_cacheable(bl, bc, lock);
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, bc->event->log, 0,
"http busylock: %d w:%d mw::%d",
@ -121,22 +121,22 @@ void ngx_http_busy_unlock(ngx_http_busy_lock_t *bl,
if (bl->md5) {
bl->md5_mask[bc->slot / 8] &= ~(1 << (bc->slot & 7));
bl->cachable--;
bl->cacheable--;
}
bl->busy--;
}
static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
ngx_http_busy_lock_ctx_t *bc,
int lock)
static int ngx_http_busy_lock_look_cacheable(ngx_http_busy_lock_t *bl,
ngx_http_busy_lock_ctx_t *bc,
int lock)
{
int i, b, cachable, free;
int i, b, cacheable, free;
u_int mask;
b = 0;
cachable = 0;
cacheable = 0;
free = -1;
#if (NGX_SUPPRESS_WARN)
@ -153,15 +153,15 @@ static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
if (ngx_memcmp(&bl->md5[i * 16], bc->md5, 16) == 0) {
return NGX_AGAIN;
}
cachable++;
cacheable++;
} else if (free == -1) {
free = i;
}
#if 1
if (cachable == bl->cachable) {
if (free == -1 && cachable < bl->max_busy) {
if (cacheable == bl->cacheable) {
if (free == -1 && cacheable < bl->max_busy) {
free = i + 1;
}
@ -186,7 +186,7 @@ static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
bl->md5_mask[free / 8] |= 1 << (free & 7);
bc->slot = free;
bl->cachable++;
bl->cacheable++;
bl->busy++;
}

View File

@ -17,7 +17,7 @@
typedef struct {
u_char *md5_mask;
char *md5;
int cachable;
int cacheable;
int busy;
int max_busy;
@ -41,8 +41,8 @@ typedef struct {
int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc);
int ngx_http_busy_lock_cachable(ngx_http_busy_lock_t *bl,
ngx_http_busy_lock_ctx_t *bc, int lock);
int ngx_http_busy_lock_cacheable(ngx_http_busy_lock_t *bl,
ngx_http_busy_lock_ctx_t *bc, int lock);
void ngx_http_busy_unlock(ngx_http_busy_lock_t *bl,
ngx_http_busy_lock_ctx_t *bc);

View File

@ -117,6 +117,10 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
r->buffered |= NGX_HTTP_COPY_BUFFERED;
}
if (r != r->main) {
r->out = ctx->in;
}
#if (NGX_DEBUG)
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args);

View File

@ -183,6 +183,13 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_srv_conf_t, ignore_invalid_headers),
NULL },
{ ngx_string("merge_slashes"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_core_srv_conf_t, merge_slashes),
NULL },
{ ngx_string("location"),
NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
ngx_http_core_location,
@ -425,6 +432,13 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_loc_conf_t, recursive_error_pages),
NULL },
{ ngx_string("server_tokens"),
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_core_loc_conf_t, server_tokens),
NULL },
{ ngx_string("error_page"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_2MORE,
@ -620,6 +634,8 @@ ngx_int_t
ngx_http_core_find_config_phase(ngx_http_request_t *r,
ngx_http_phase_handler_t *ph)
{
u_char *p;
size_t len;
ngx_int_t rc;
ngx_http_core_loc_conf_t *clcf;
ngx_http_core_srv_conf_t *cscf;
@ -660,7 +676,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
&& clcf->client_max_body_size < r->headers_in.content_length_n)
{
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"client intented to send too large body: %O bytes",
"client intended to send too large body: %O bytes",
r->headers_in.content_length_n);
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
@ -680,7 +696,25 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
* r->headers_out.location->key fields
*/
r->headers_out.location->value = clcf->name;
if (r->args.len == 0) {
r->headers_out.location->value = clcf->name;
} else {
len = clcf->name.len + 1 + r->args.len;
p = ngx_palloc(r->pool, len);
if (p == NULL) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return NGX_OK;
}
r->headers_out.location->value.len = len;
r->headers_out.location->value.data = p;
p = ngx_cpymem(p, clcf->name.data, clcf->name.len);
*p++ = '?';
ngx_memcpy(p, r->args.data, r->args.len);
}
ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
return NGX_OK;
@ -857,7 +891,7 @@ ngx_http_core_content_phase(ngx_http_request_t *r,
if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"directory index of \"%V\" is forbidden", &path);
"directory index of \"%s\" is forbidden", path.data);
}
ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
@ -933,25 +967,29 @@ ngx_http_core_find_location(ngx_http_request_t *r,
ngx_array_t *locations, ngx_uint_t regex_start, size_t len)
{
ngx_int_t n, rc;
ngx_uint_t i, found, noregex;
ngx_uint_t i, found;
ngx_http_core_loc_conf_t *clcf, **clcfp;
#if (NGX_PCRE)
ngx_uint_t noregex;
#endif
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"find location for \"%V\"", &r->uri);
found = 0;
#if (NGX_PCRE)
noregex = 0;
#endif
clcfp = locations->elts;
for (i = 0; i < locations->nelts; i++) {
if (clcfp[i]->noname
#if (NGX_PCRE)
if (clcfp[i]->regex) {
break;
}
|| clcfp[i]->regex
#endif
if (clcfp[i]->noname) {
|| clcfp[i]->named)
{
break;
}
@ -999,9 +1037,12 @@ ngx_http_core_find_location(ngx_http_request_t *r,
break;
}
r->loc_conf = clcfp[i]->loc_conf;
noregex = clcfp[i]->noregex;
found = 1;
r->loc_conf = clcfp[i]->loc_conf;
#if (NGX_PCRE)
noregex = clcfp[i]->noregex;
#endif
}
}
@ -1028,7 +1069,7 @@ ngx_http_core_find_location(ngx_http_request_t *r,
for (i = regex_start; i < locations->nelts; i++) {
if (clcfp[i]->noname) {
if (!clcfp[i]->regex) {
break;
}
@ -1513,6 +1554,51 @@ ngx_http_internal_redirect(ngx_http_request_t *r,
}
ngx_int_t
ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
{
ngx_uint_t i;
ngx_http_core_srv_conf_t *cscf;
ngx_http_core_loc_conf_t **clcfp;
ngx_http_core_main_conf_t *cmcf;
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
clcfp = cscf->locations.elts;
for (i = cscf->named_start; i < cscf->locations.nelts; i++) {
if (name->len != clcfp[i]->name.len
|| ngx_strncmp(name->data, clcfp[i]->name.data, name->len) != 0)
{
continue;
}
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"named location: %V \"%V?%V\"", name, &r->uri, &r->args);
r->internal = 1;
r->loc_conf = clcfp[i]->loc_conf;
ngx_http_update_location_config(r);
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
r->phase_handler = cmcf->phase_engine.location_rewrite_index;
ngx_http_core_run_phases(r);
return NGX_DONE;
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"could not find named location \"%V\"", name);
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return NGX_DONE;
}
ngx_http_cleanup_t *
ngx_http_cleanup_add(ngx_http_request_t *r, size_t size)
{
@ -1557,10 +1643,8 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
ngx_http_module_t *module;
ngx_http_conf_ctx_t *ctx, *http_ctx;
ngx_http_core_srv_conf_t *cscf, **cscfp;
ngx_http_core_main_conf_t *cmcf;
#if (NGX_PCRE)
ngx_http_core_loc_conf_t **clcfp;
#endif
ngx_http_core_main_conf_t *cmcf;
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
if (ctx == NULL) {
@ -1644,10 +1728,11 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
ngx_sort(cscf->locations.elts, (size_t) cscf->locations.nelts,
sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
clcfp = cscf->locations.elts;
#if (NGX_PCRE)
cscf->regex_start = cscf->locations.nelts;
clcfp = cscf->locations.elts;
for (i = 0; i < cscf->locations.nelts; i++) {
if (clcfp[i]->regex) {
@ -1658,6 +1743,15 @@ ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
#endif
cscf->named_start = cscf->locations.nelts;
for (i = 0; i < cscf->locations.nelts; i++) {
if (clcfp[i]->named) {
cscf->named_start = i;
break;
}
}
return rv;
}
@ -1758,7 +1852,12 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
}
} else {
clcf->name = value[1];
if (value[1].data[0] == '@') {
clcf->named = 1;
}
}
pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
@ -1784,6 +1883,14 @@ ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
return NGX_CONF_ERROR;
}
if (pclcf->named) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"location \"%V\" could not be inside "
"the named location \"%V\"",
&clcf->name, &pclcf->name);
return NGX_CONF_ERROR;
}
#if (NGX_PCRE)
if (clcf->regex == NULL
&& ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len)
@ -1861,6 +1968,20 @@ ngx_http_core_cmp_locations(const void *one, const void *two)
first = *(ngx_http_core_loc_conf_t **) one;
second = *(ngx_http_core_loc_conf_t **) two;
if (first->named && !second->named) {
/* shift named locations to the end */
return 1;
}
if (!first->named && second->named) {
/* shift named locations to the end */
return -1;
}
if (first->named && second->named) {
return ngx_strcmp(first->name.data, second->name.data);
}
if (first->noname && !second->noname) {
/* shift no named locations to the end */
return 1;
@ -2106,6 +2227,7 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
cscf->optimize_server_names = NGX_CONF_UNSET;
cscf->ignore_invalid_headers = NGX_CONF_UNSET;
cscf->merge_slashes = NGX_CONF_UNSET;
return cscf;
}
@ -2139,7 +2261,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
#endif
ls->family = AF_INET;
ls->conf.backlog = -1;
ls->conf.backlog = NGX_LISTEN_BACKLOG;
ls->conf.rcvbuf = -1;
ls->conf.sndbuf = -1;
}
@ -2165,9 +2287,12 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR;
}
#if (NGX_PCRE)
sn->regex = NULL;
#endif
sn->core_srv_conf = conf;
sn->name.len = conf->server_name.len;
sn->name.data = conf->server_name.data;
sn->core_srv_conf = conf;
}
ngx_conf_merge_size_value(conf->connection_pool_size,
@ -2195,6 +2320,8 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->ignore_invalid_headers,
prev->ignore_invalid_headers, 1);
ngx_conf_merge_value(conf->merge_slashes, prev->merge_slashes, 1);
return NGX_CONF_OK;
}
@ -2250,6 +2377,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
lcf->msie_refresh = NGX_CONF_UNSET;
lcf->log_not_found = NGX_CONF_UNSET;
lcf->recursive_error_pages = NGX_CONF_UNSET;
lcf->server_tokens = NGX_CONF_UNSET;
lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
@ -2434,6 +2562,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
ngx_conf_merge_value(conf->recursive_error_pages,
prev->recursive_error_pages, 0);
ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
if (conf->open_files == NULL) {
conf->open_files = prev->open_files;
@ -2468,7 +2597,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
u.listen = 1;
u.default_port = 80;
if (ngx_parse_url(cf, &u) != NGX_OK) {
if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
if (u.err) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"%s in \"%V\" of the \"listen\" directive",
@ -2488,9 +2617,9 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ls->family = AF_INET;
ls->addr = u.addr.in_addr;
ls->port = u.port;
ls->file_name = cf->conf_file->file.name;
ls->file_name = cf->conf_file->file.name.data;
ls->line = cf->conf_file->line;
ls->conf.backlog = -1;
ls->conf.backlog = NGX_LISTEN_BACKLOG;
ls->conf.rcvbuf = -1;
ls->conf.sndbuf = -1;
@ -2612,19 +2741,30 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_str_t *value, name;
ngx_uint_t i;
ngx_http_server_name_t *sn;
#if (NGX_PCRE)
ngx_str_t err;
u_char errstr[NGX_MAX_CONF_ERRSTR];
#endif
value = cf->args->elts;
ch = value[1].data[0];
if (cscf->server_name.data == NULL && value[1].len) {
if (ch == '*') {
if (ngx_strchr(value[1].data, '*')) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"first server name \"%V\" must not be wildcard",
&value[1]);
return NGX_CONF_ERROR;
}
if (value[1].data[0] == '~') {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"first server name \"%V\" "
"must not be regular expression", &value[1]);
return NGX_CONF_ERROR;
}
name = value[1];
if (ch == '.') {
@ -2668,9 +2808,42 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
#if (NGX_PCRE)
sn->regex = NULL;
#endif
sn->core_srv_conf = cscf;
sn->name.len = value[i].len;
sn->name.data = value[i].data;
sn->core_srv_conf = cscf;
if (value[i].data[0] != '~') {
continue;
}
#if (NGX_PCRE)
err.len = NGX_MAX_CONF_ERRSTR;
err.data = errstr;
value[i].len--;
value[i].data++;
sn->regex = ngx_regex_compile(&value[i], NGX_REGEX_CASELESS, cf->pool,
&err);
if (sn->regex == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
return NGX_CONF_ERROR;
}
sn->name.len = value[i].len;
sn->name.data = value[i].data;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"the using of the regex \"%V\" "
"requires PCRE library", &value[i]);
return NGX_CONF_ERROR;
#endif
}
return NGX_CONF_OK;
@ -2706,6 +2879,14 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
if (lcf->named && alias) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"the \"alias\" directive may not be used "
"inside named location");
return NGX_CONF_ERROR;
}
#if (NGX_PCRE)
if (lcf->regex && alias) {

View File

@ -38,8 +38,8 @@ typedef struct {
in_port_t port;
int family;
ngx_str_t file_name;
ngx_int_t line;
u_char *file_name;
ngx_uint_t line;
ngx_http_listen_conf_t conf;
} ngx_http_listen_t;
@ -79,6 +79,7 @@ struct ngx_http_phase_handler_s {
typedef struct {
ngx_http_phase_handler_t *handlers;
ngx_uint_t server_rewrite_index;
ngx_uint_t location_rewrite_index;
} ngx_http_phase_engine_t;
@ -117,7 +118,8 @@ typedef struct {
*/
ngx_array_t locations;
unsigned regex_start:16;
unsigned regex_start:15;
unsigned named_start:15;
unsigned wildcard:1;
/* array of the ngx_http_listen_t, "listen" directive */
@ -141,6 +143,7 @@ typedef struct {
ngx_flag_t optimize_server_names;
ngx_flag_t ignore_invalid_headers;
ngx_flag_t merge_slashes;
} ngx_http_core_srv_conf_t;
@ -149,8 +152,10 @@ typedef struct {
typedef struct {
in_addr_t addr;
/* the default server configuration for this address:port */
ngx_http_core_srv_conf_t *core_srv_conf;
ngx_http_virtual_names_t *virtual_names;
} ngx_http_in_addr_t;
@ -173,10 +178,16 @@ typedef struct {
in_addr_t addr;
ngx_hash_t hash;
ngx_hash_wildcard_t *dns_wildcards;
ngx_hash_wildcard_t *wc_head;
ngx_hash_wildcard_t *wc_tail;
ngx_array_t names; /* array of ngx_http_server_name_t */
#if (NGX_PCRE)
ngx_uint_t nregex;
ngx_http_server_name_t *regex;
#endif
/* the default server configuration for this address:port */
ngx_http_core_srv_conf_t *core_srv_conf;
@ -187,10 +198,13 @@ typedef struct {
} ngx_http_conf_in_addr_t;
typedef struct {
ngx_str_t name;
struct ngx_http_server_name_s {
#if (NGX_PCRE)
ngx_regex_t *regex;
#endif
ngx_http_core_srv_conf_t *core_srv_conf; /* virtual name server conf */
} ngx_http_server_name_t;
ngx_str_t name;
};
typedef struct {
@ -211,9 +225,10 @@ struct ngx_http_core_loc_conf_s {
ngx_regex_t *regex;
#endif
unsigned regex_start:16;
unsigned regex_start:15;
unsigned noname:1; /* "if () {}" block */
unsigned noname:1; /* "if () {}" block or limit_except */
unsigned named:1;
unsigned exact_match:1;
unsigned noregex:1;
@ -270,6 +285,7 @@ struct ngx_http_core_loc_conf_s {
ngx_flag_t msie_refresh; /* msie_refresh */
ngx_flag_t log_not_found; /* log_not_found */
ngx_flag_t recursive_error_pages; /* recursive_error_pages */
ngx_flag_t server_tokens; /* server_tokens */
ngx_array_t *error_pages; /* error_page */
@ -313,6 +329,8 @@ ngx_int_t ngx_http_subrequest(ngx_http_request_t *r,
ngx_http_post_subrequest_t *psr, ngx_uint_t flags);
ngx_int_t ngx_http_internal_redirect(ngx_http_request_t *r,
ngx_str_t *uri, ngx_str_t *args);
ngx_int_t ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name);
ngx_http_cleanup_t *ngx_http_cleanup_add(ngx_http_request_t *r, size_t size);

View File

@ -45,7 +45,8 @@ ngx_module_t ngx_http_header_filter_module = {
};
static char ngx_http_server_string[] = "Server: " NGINX_VER CRLF;
static char ngx_http_server_string[] = "Server: nginx" CRLF;
static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
static ngx_str_t ngx_http_status_lines[] = {
@ -237,8 +238,11 @@ ngx_http_header_filter(ngx_http_request_t *r)
len += ngx_http_status_lines[status].len;
}
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (r->headers_out.server == NULL) {
len += sizeof(ngx_http_server_string) - 1;
len += clcf->server_tokens ? sizeof(ngx_http_server_full_string) - 1:
sizeof(ngx_http_server_string) - 1;
}
if (r->headers_out.date == NULL) {
@ -268,8 +272,6 @@ ngx_http_header_filter(ngx_http_request_t *r)
len += sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1;
}
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (r->headers_out.location
&& r->headers_out.location->value.len
&& r->headers_out.location->value.data[0] == '/')
@ -365,8 +367,16 @@ ngx_http_header_filter(ngx_http_request_t *r)
*b->last++ = CR; *b->last++ = LF;
if (r->headers_out.server == NULL) {
b->last = ngx_cpymem(b->last, ngx_http_server_string,
sizeof(ngx_http_server_string) - 1);
if (clcf->server_tokens) {
p = (u_char *) ngx_http_server_full_string;
len = sizeof(ngx_http_server_full_string) - 1;
} else {
p = (u_char *) ngx_http_server_string;
len = sizeof(ngx_http_server_string) - 1;
}
b->last = ngx_cpymem(b->last, p, len);
}
if (r->headers_out.date == NULL) {

View File

@ -124,6 +124,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
sw_major_digit,
sw_first_minor_digit,
sw_minor_digit,
sw_spaces_after_digit,
sw_almost_done
} state;
@ -335,18 +336,26 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
break;
}
r->host_end = p;
switch (ch) {
case ':':
r->host_end = p;
state = sw_port;
break;
case '/':
r->host_end = p;
r->uri_start = p;
state = sw_after_slash_in_uri;
break;
case ' ':
/*
* use single "/" from request line to preserve pointers,
* if request line will be copied to large client buffer
*/
r->uri_start = r->schema_end + 1;
r->uri_end = r->schema_end + 2;
state = sw_http_09;
break;
default:
r->host_end = p;
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
@ -362,6 +371,16 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
r->uri_start = p;
state = sw_after_slash_in_uri;
break;
case ' ':
r->port_end = p;
/*
* use single "/" from request line to preserve pointers,
* if request line will be copied to large client buffer
*/
r->uri_start = r->schema_end + 1;
r->uri_end = r->schema_end + 2;
state = sw_http_09;
break;
default:
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
@ -618,6 +637,11 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
goto done;
}
if (ch == ' ') {
state = sw_spaces_after_digit;
break;
}
if (ch < '0' || ch > '9') {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
@ -625,6 +649,20 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
r->http_minor = r->http_minor * 10 + ch - '0';
break;
case sw_spaces_after_digit:
switch (ch) {
case ' ':
break;
case CR:
state = sw_almost_done;
break;
case LF:
goto done;
default:
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
/* end of request line */
case sw_almost_done:
r->request_end = p - 1;
@ -700,6 +738,7 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
/* first char */
case sw_start:
r->header_name_start = p;
r->invalid_header = 0;
switch (ch) {
@ -712,7 +751,6 @@ ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b)
goto header_done;
default:
state = sw_name;
r->header_name_start = p;
c = lowcase[ch];
@ -890,7 +928,7 @@ header_done:
ngx_int_t
ngx_http_parse_complex_uri(ngx_http_request_t *r)
ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
{
u_char c, ch, decoded, *p, *u;
enum {
@ -998,8 +1036,12 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
switch(ch) {
#if (NGX_WIN32)
case '\\':
break;
#endif
case '/':
if (!merge_slashes) {
*u++ = ch;
}
break;
case '.':
state = sw_dot;
@ -1081,11 +1123,15 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
#endif
case '/':
state = sw_slash;
u -= 4;
if (u < r->uri.data) {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
while (*(u - 1) != '/') {
u -= 5;
for ( ;; ) {
if (u < r->uri.data) {
return NGX_HTTP_PARSE_INVALID_REQUEST;
}
if (*u == '/') {
u++;
break;
}
u--;
}
break;

View File

@ -11,7 +11,8 @@
static int mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
time_t ngx_http_parse_time(u_char *value, size_t len)
time_t
ngx_http_parse_time(u_char *value, size_t len)
{
u_char *p, *end;
int day, month, year, hour, min, sec;
@ -247,7 +248,7 @@ time_t ngx_http_parse_time(u_char *value, size_t len)
year -= 1;
}
/* Gauss's formula for Grigorian days from 1 March 1 BC */
/* Gauss's formula for Grigorian days from March 1, 1 BC */
return (365 * year + year / 4 - year / 100 + year / 400
+ 367 * month / 12 - 31

View File

@ -168,7 +168,7 @@ ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r)
pr = r->postponed;
if (pr == NULL) {
return NGX_OK;
break;
}
if (pr->request) {
@ -196,7 +196,7 @@ ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r)
}
if (pr == NULL) {
return NGX_OK;
break;
}
out = pr->out;
@ -215,6 +215,17 @@ ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r)
r->postponed = r->postponed->next;
}
if (r->out) {
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http postpone filter out again \"%V?%V\"",
&r->uri, &r->args);
r->connection->data = r;
return NGX_AGAIN;
}
return NGX_OK;
}

View File

@ -21,6 +21,8 @@ static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
@ -34,6 +36,7 @@ static ngx_int_t ngx_http_set_write_handler(ngx_http_request_t *r);
static void ngx_http_writer(ngx_http_request_t *r);
static void ngx_http_block_read(ngx_http_request_t *r);
static void ngx_http_test_read(ngx_http_request_t *r);
static void ngx_http_set_keepalive(ngx_http_request_t *r);
static void ngx_http_keepalive_handler(ngx_event_t *ev);
static void ngx_http_set_lingering_close(ngx_http_request_t *r);
@ -71,11 +74,11 @@ ngx_http_header_t ngx_http_headers_in[] = {
ngx_http_process_unique_header_line },
{ ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection),
ngx_http_process_unique_header_line },
ngx_http_process_connection },
{ ngx_string("If-Modified-Since"),
offsetof(ngx_http_headers_in_t, if_modified_since),
ngx_http_process_header_line },
ngx_http_process_unique_header_line },
{ ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
ngx_http_process_header_line },
@ -94,6 +97,10 @@ ngx_http_header_t ngx_http_headers_in[] = {
{ ngx_string("Range"), offsetof(ngx_http_headers_in_t, range),
ngx_http_process_header_line },
{ ngx_string("If-Range"),
offsetof(ngx_http_headers_in_t, if_range),
ngx_http_process_unique_header_line },
{ ngx_string("Transfer-Encoding"),
offsetof(ngx_http_headers_in_t, transfer_encoding),
ngx_http_process_header_line },
@ -600,10 +607,11 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
static void
ngx_http_process_request_line(ngx_event_t *rev)
{
ssize_t n;
ngx_int_t rc, rv;
ngx_connection_t *c;
ngx_http_request_t *r;
ssize_t n;
ngx_int_t rc, rv;
ngx_connection_t *c;
ngx_http_request_t *r;
ngx_http_core_srv_conf_t *cscf;
c = rev->data;
r = c->data;
@ -655,7 +663,9 @@ ngx_http_process_request_line(ngx_event_t *rev)
return;
}
rc = ngx_http_parse_complex_uri(r);
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
rc = ngx_http_parse_complex_uri(r, cscf->merge_slashes);
if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
@ -836,7 +846,7 @@ ngx_http_process_request_headers(ngx_event_t *rev)
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent too long header line: \"%V\"",
&header);
ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
return;
}
}
@ -948,7 +958,7 @@ ngx_http_process_request_headers(ngx_event_t *rev)
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent invalid header line: \"%V\\r...\"",
&header);
ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
return;
}
}
@ -1145,6 +1155,10 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
r->args_start = new + (r->args_start - old);
}
if (r->http_protocol.data) {
r->http_protocol.data = new + (r->http_protocol.data - old);
}
} else {
r->header_name_start = new;
r->header_name_end = new + (r->header_name_end - old);
@ -1198,6 +1212,21 @@ ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
}
static ngx_int_t
ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{
if (ngx_strcasestrn(h->value.data, "close", 5 - 1)) {
r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
} else if (ngx_strcasestrn(h->value.data, "keep-alive", 10 - 1)) {
r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
}
return NGX_OK;
}
static ngx_int_t
ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
@ -1294,7 +1323,7 @@ ngx_http_process_request_header(ngx_http_request_t *r)
return NGX_ERROR;
}
if (r->method & (NGX_HTTP_TRACE)) {
if (r->method & NGX_HTTP_TRACE) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent TRACE method");
ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
@ -1302,7 +1331,8 @@ ngx_http_process_request_header(ngx_http_request_t *r)
}
if (r->headers_in.transfer_encoding
&& ngx_strstr(r->headers_in.transfer_encoding->value.data, "chunked"))
&& ngx_strcasestrn(r->headers_in.transfer_encoding->value.data,
"chunked", 7 - 1))
{
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent \"Transfer-Encoding: chunked\" header");
@ -1310,33 +1340,11 @@ ngx_http_process_request_header(ngx_http_request_t *r)
return NGX_ERROR;
}
if (r->plain_http) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent plain HTTP request to HTTPS port");
ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
return NGX_ERROR;
}
if (r->headers_in.connection) {
if (r->headers_in.connection->value.len == 5
&& ngx_strcasecmp(r->headers_in.connection->value.data,
(u_char *) "close")
== 0)
{
r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
} else if (r->headers_in.connection->value.len == 10
&& ngx_strcasecmp(r->headers_in.connection->value.data,
(u_char *) "keep-alive")
== 0)
{
r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
if (r->headers_in.keep_alive) {
r->headers_in.keep_alive_n =
ngx_atotm(r->headers_in.keep_alive->value.data,
r->headers_in.keep_alive->value.len);
}
if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
if (r->headers_in.keep_alive) {
r->headers_in.keep_alive_n =
ngx_atotm(r->headers_in.keep_alive->value.data,
r->headers_in.keep_alive->value.len);
}
}
@ -1349,7 +1357,7 @@ ngx_http_process_request_header(ngx_http_request_t *r)
user_agent = r->headers_in.user_agent->value.data;
ua = (u_char *) ngx_strstr(user_agent, "MSIE");
ua = ngx_strstrn(user_agent, "MSIE", 4 - 1);
if (ua && ua + 8 < user_agent + r->headers_in.user_agent->value.len) {
@ -1367,7 +1375,7 @@ ngx_http_process_request_header(ngx_http_request_t *r)
#endif
}
if (ngx_strstr(user_agent, "Opera")) {
if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
r->headers_in.opera = 1;
r->headers_in.msie = 0;
r->headers_in.msie4 = 0;
@ -1375,10 +1383,10 @@ ngx_http_process_request_header(ngx_http_request_t *r)
if (!r->headers_in.msie && !r->headers_in.opera) {
if (ngx_strstr(user_agent, "Gecko/")) {
if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
r->headers_in.gecko = 1;
} else if (ngx_strstr(user_agent, "Konqueror")) {
} else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
r->headers_in.konqueror = 1;
}
}
@ -1399,6 +1407,13 @@ ngx_http_process_request(ngx_http_request_t *r)
c = r->connection;
if (r->plain_http) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent plain HTTP request to HTTPS port");
ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
return;
}
#if (NGX_HTTP_SSL)
if (c->ssl) {
@ -1453,26 +1468,55 @@ static void
ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len,
ngx_uint_t hash)
{
ngx_http_virtual_names_t *vn;
ngx_http_core_loc_conf_t *clcf;
ngx_http_core_srv_conf_t *cscf;
#if (NGX_PCRE)
ngx_int_t n;
ngx_uint_t i;
ngx_str_t name;
ngx_http_server_name_t *sn;
#endif
vn = r->virtual_names;
cscf = ngx_hash_find_combined(&r->virtual_names->names, hash, host, len);
if (cscf) {
goto found;
}
#if (NGX_PCRE)
if (r->virtual_names->nregex) {
name.len = len;
name.data = host;
sn = r->virtual_names->regex;
for (i = 0; i < r->virtual_names->nregex; i++) {
n = ngx_regex_exec(sn[i].regex, &name, NULL, 0);
if (n == NGX_REGEX_NO_MATCHED) {
continue;
}
if (n < 0) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
ngx_regex_exec_n
" failed: %d on \"%V\" using \"%V\"",
n, &name, &sn[i].name);
return;
}
/* match */
cscf = sn[i].core_srv_conf;
if (vn->hash.buckets) {
cscf = ngx_hash_find(&vn->hash, hash, host, len);
if (cscf) {
goto found;
}
}
if (vn->dns_wildcards && vn->dns_wildcards->hash.buckets) {
cscf = ngx_hash_find_wildcard(vn->dns_wildcards, host, len);
if (cscf) {
goto found;
}
}
#endif
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
@ -1710,7 +1754,7 @@ ngx_http_set_write_handler(ngx_http_request_t *r)
r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;
r->read_event_handler = ngx_http_block_read;
r->read_event_handler = ngx_http_test_read;
r->write_event_handler = ngx_http_writer;
wev = r->connection->write;
@ -1822,6 +1866,26 @@ ngx_http_writer(ngx_http_request_t *r)
static void
ngx_http_block_read(ngx_http_request_t *r)
{
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http read blocked");
/* aio does not call this handler */
if ((ngx_event_flags & NGX_USE_LEVEL_EVENT)
&& r->connection->read->active)
{
if (ngx_del_event(r->connection->read, NGX_READ_EVENT, 0)
== NGX_ERROR)
{
ngx_http_close_request(r, 0);
}
}
}
static void
ngx_http_test_read(ngx_http_request_t *r)
{
int n;
char buf[1];
@ -1832,7 +1896,7 @@ ngx_http_block_read(ngx_http_request_t *r)
c = r->connection;
rev = c->read;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http read blocked");
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http test read");
#if (NGX_HAVE_KQUEUE)
@ -1982,7 +2046,8 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
hc->pipeline = 1;
c->log->action = "reading client pipelined request line";
ngx_http_init_request(rev);
rev->handler = ngx_http_init_request;
ngx_post_event(rev, &ngx_posted_events);
return;
}
@ -2021,7 +2086,7 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
if (hc->free) {
for (i = 0; i < hc->nfree; i++) {
ngx_pfree(c->pool, hc->free[i]);
ngx_pfree(c->pool, hc->free[i]->start);
hc->free[i] = NULL;
}
@ -2033,7 +2098,7 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
if (hc->busy) {
for (i = 0; i < hc->nbusy; i++) {
ngx_pfree(c->pool, hc->busy[i]);
ngx_pfree(c->pool, hc->busy[i]->start);
hc->busy[i] = NULL;
}
@ -2092,7 +2157,7 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
c->idle = 1;
if (rev->ready) {
ngx_http_keepalive_handler(rev);
ngx_post_event(rev, &ngx_posted_events);
}
}
@ -2543,28 +2608,21 @@ ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
buf = p;
}
if (r->unparsed_uri.data) {
p = ngx_snprintf(buf, len, ", URL: \"%V\"", &r->unparsed_uri);
if (r->request_line.data == NULL && r->request_start) {
for (p = r->request_start; p < r->header_in->last; p++) {
if (*p == CR || *p == LF) {
break;
}
}
r->request_line.len = p - r->request_start;
r->request_line.data = r->request_start;
}
if (r->request_line.len) {
p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line);
len -= p - buf;
buf = p;
} else {
if (r->request_line.data == NULL && r->request_start) {
for (p = r->request_start; p < r->header_in->last; p++) {
if (*p == CR || *p == LF) {
break;
}
}
r->request_line.len = p - r->request_start;
r->request_line.data = r->request_start;
}
if (r->request_line.len) {
p = ngx_snprintf(buf, len, ", request: \"%V\"", &r->request_line);
len -= p - buf;
buf = p;
}
}
if (r != sr) {

View File

@ -168,6 +168,7 @@ typedef struct {
ngx_table_elt_t *content_type;
ngx_table_elt_t *range;
ngx_table_elt_t *if_range;
ngx_table_elt_t *transfer_encoding;
@ -275,9 +276,14 @@ typedef struct {
} ngx_http_connection_t;
typedef struct ngx_http_server_name_s ngx_http_server_name_t;
typedef struct {
ngx_hash_t hash;
ngx_hash_wildcard_t *dns_wildcards;
ngx_hash_combined_t names;
ngx_uint_t nregex;
ngx_http_server_name_t *regex;
} ngx_http_virtual_names_t;
@ -444,7 +450,7 @@ struct ngx_http_request_s {
unsigned limit_zone_set:1;
#if 0
unsigned cachable:1;
unsigned cacheable:1;
#endif
unsigned pipeline:1;

View File

@ -88,6 +88,7 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
}
post_handler(r);
return NGX_OK;
}

View File

@ -314,7 +314,7 @@ ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
for (i = 0; i < cmcf->variables.nelts; i++) {
if (r->variables[i].no_cachable) {
if (r->variables[i].no_cacheable) {
r->variables[i].valid = 0;
r->variables[i].not_found = 0;
}
@ -351,7 +351,7 @@ ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
void
ngx_http_script_flush_no_cachable_variables(ngx_http_request_t *r,
ngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r,
ngx_array_t *indices)
{
ngx_uint_t n, *index;
@ -359,7 +359,7 @@ ngx_http_script_flush_no_cachable_variables(ngx_http_request_t *r,
if (indices) {
index = indices->elts;
for (n = 0; n < indices->nelts; n++) {
if (r->variables[index[n]].no_cachable) {
if (r->variables[index[n]].no_cacheable) {
r->variables[index[n]].valid = 0;
r->variables[index[n]].not_found = 0;
}
@ -750,7 +750,8 @@ ngx_http_script_regex_end_code(ngx_http_script_engine_t *e)
dst = e->buf.data;
src = e->buf.data;
ngx_unescape_uri(&dst, &src, e->pos - e->buf.data, NGX_UNESCAPE_URI);
ngx_unescape_uri(&dst, &src, e->pos - e->buf.data,
NGX_UNESCAPE_REDIRECT);
if (src < e->pos) {
dst = ngx_copy(dst, src, e->pos - src);
@ -1125,7 +1126,7 @@ ngx_http_script_value_code(ngx_http_script_engine_t *e)
e->sp->data = (u_char *) code->text_data;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
"http script value: \"%V\"", e->sp);
"http script value: \"%v\"", e->sp);
e->sp++;
}
@ -1150,7 +1151,7 @@ ngx_http_script_set_var_code(ngx_http_script_engine_t *e)
r->variables[code->index].len = e->sp->len;
r->variables[code->index].valid = 1;
r->variables[code->index].no_cachable = 0;
r->variables[code->index].no_cacheable = 0;
r->variables[code->index].not_found = 0;
r->variables[code->index].data = e->sp->data;
}
@ -1191,7 +1192,7 @@ ngx_http_script_var_code(ngx_http_script_engine_t *e)
if (value && !value->not_found) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
"http script var: \"%V\"", value);
"http script var: \"%v\"", value);
*e->sp = *value;
e->sp++;

View File

@ -181,7 +181,7 @@ ngx_uint_t ngx_http_script_variables_count(ngx_str_t *value);
ngx_int_t ngx_http_script_compile(ngx_http_script_compile_t *sc);
u_char *ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
void *code_lengths, size_t reserved, void *code_values);
void ngx_http_script_flush_no_cachable_variables(ngx_http_request_t *r,
void ngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r,
ngx_array_t *indices);
void *ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes,

View File

@ -10,13 +10,27 @@
#include <nginx.h>
static u_char error_tail[] =
static ngx_int_t ngx_http_send_error_page(ngx_http_request_t *r,
ngx_http_err_page_t *err_page);
static ngx_int_t ngx_http_send_special_response(ngx_http_request_t *r,
ngx_http_core_loc_conf_t *clcf, ngx_uint_t err);
static ngx_int_t ngx_http_send_refresh(ngx_http_request_t *r);
static u_char ngx_http_error_full_tail[] =
"<hr><center>" NGINX_VER "</center>" CRLF
"</body>" CRLF
"</html>" CRLF
;
static u_char ngx_http_error_tail[] =
"<hr><center>nginx</center>" CRLF
"</body>" CRLF
"</html>" CRLF
;
static u_char ngx_http_msie_stub[] =
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
"<!-- The padding to disable MSIE's friendly error page -->" CRLF
@ -35,7 +49,7 @@ static u_char ngx_http_msie_refresh_tail[] =
"\"></head><body></body></html>" CRLF;
static char error_301_page[] =
static char ngx_http_error_301_page[] =
"<html>" CRLF
"<head><title>301 Moved Permanently</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -43,7 +57,7 @@ static char error_301_page[] =
;
static char error_302_page[] =
static char ngx_http_error_302_page[] =
"<html>" CRLF
"<head><title>302 Found</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -51,7 +65,7 @@ static char error_302_page[] =
;
static char error_400_page[] =
static char ngx_http_error_400_page[] =
"<html>" CRLF
"<head><title>400 Bad Request</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -59,7 +73,7 @@ static char error_400_page[] =
;
static char error_401_page[] =
static char ngx_http_error_401_page[] =
"<html>" CRLF
"<head><title>401 Authorization Required</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -67,7 +81,7 @@ static char error_401_page[] =
;
static char error_402_page[] =
static char ngx_http_error_402_page[] =
"<html>" CRLF
"<head><title>402 Payment Required</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -75,7 +89,7 @@ static char error_402_page[] =
;
static char error_403_page[] =
static char ngx_http_error_403_page[] =
"<html>" CRLF
"<head><title>403 Forbidden</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -83,7 +97,7 @@ static char error_403_page[] =
;
static char error_404_page[] =
static char ngx_http_error_404_page[] =
"<html>" CRLF
"<head><title>404 Not Found</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -91,7 +105,7 @@ static char error_404_page[] =
;
static char error_405_page[] =
static char ngx_http_error_405_page[] =
"<html>" CRLF
"<head><title>405 Not Allowed</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -99,7 +113,7 @@ static char error_405_page[] =
;
static char error_406_page[] =
static char ngx_http_error_406_page[] =
"<html>" CRLF
"<head><title>406 Not Acceptable</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -107,7 +121,7 @@ static char error_406_page[] =
;
static char error_408_page[] =
static char ngx_http_error_408_page[] =
"<html>" CRLF
"<head><title>408 Request Time-out</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -115,7 +129,7 @@ static char error_408_page[] =
;
static char error_409_page[] =
static char ngx_http_error_409_page[] =
"<html>" CRLF
"<head><title>409 Conflict</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -123,7 +137,7 @@ static char error_409_page[] =
;
static char error_410_page[] =
static char ngx_http_error_410_page[] =
"<html>" CRLF
"<head><title>410 Gone</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -131,7 +145,7 @@ static char error_410_page[] =
;
static char error_411_page[] =
static char ngx_http_error_411_page[] =
"<html>" CRLF
"<head><title>411 Length Required</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -139,7 +153,7 @@ static char error_411_page[] =
;
static char error_412_page[] =
static char ngx_http_error_412_page[] =
"<html>" CRLF
"<head><title>412 Precondition Failed</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -147,7 +161,7 @@ static char error_412_page[] =
;
static char error_413_page[] =
static char ngx_http_error_413_page[] =
"<html>" CRLF
"<head><title>413 Request Entity Too Large</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -155,7 +169,7 @@ static char error_413_page[] =
;
static char error_414_page[] =
static char ngx_http_error_414_page[] =
"<html>" CRLF
"<head><title>414 Request-URI Too Large</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -163,7 +177,7 @@ static char error_414_page[] =
;
static char error_415_page[] =
static char ngx_http_error_415_page[] =
"<html>" CRLF
"<head><title>415 Unsupported Media Type</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -171,7 +185,7 @@ static char error_415_page[] =
;
static char error_416_page[] =
static char ngx_http_error_416_page[] =
"<html>" CRLF
"<head><title>416 Requested Range Not Satisfiable</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -179,7 +193,7 @@ static char error_416_page[] =
;
static char error_495_page[] =
static char ngx_http_error_495_page[] =
"<html>" CRLF
"<head><title>400 The SSL certificate error</title></head>"
CRLF
@ -189,7 +203,7 @@ CRLF
;
static char error_496_page[] =
static char ngx_http_error_496_page[] =
"<html>" CRLF
"<head><title>400 No required SSL certificate was sent</title></head>"
CRLF
@ -199,7 +213,7 @@ CRLF
;
static char error_497_page[] =
static char ngx_http_error_497_page[] =
"<html>" CRLF
"<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>"
CRLF
@ -209,7 +223,7 @@ CRLF
;
static char error_500_page[] =
static char ngx_http_error_500_page[] =
"<html>" CRLF
"<head><title>500 Internal Server Error</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -217,7 +231,7 @@ static char error_500_page[] =
;
static char error_501_page[] =
static char ngx_http_error_501_page[] =
"<html>" CRLF
"<head><title>501 Method Not Implemented</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -225,7 +239,7 @@ static char error_501_page[] =
;
static char error_502_page[] =
static char ngx_http_error_502_page[] =
"<html>" CRLF
"<head><title>502 Bad Gateway</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -233,7 +247,7 @@ static char error_502_page[] =
;
static char error_503_page[] =
static char ngx_http_error_503_page[] =
"<html>" CRLF
"<head><title>503 Service Temporarily Unavailable</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -241,7 +255,7 @@ static char error_503_page[] =
;
static char error_504_page[] =
static char ngx_http_error_504_page[] =
"<html>" CRLF
"<head><title>504 Gateway Time-out</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -249,7 +263,7 @@ static char error_504_page[] =
;
static char error_507_page[] =
static char ngx_http_error_507_page[] =
"<html>" CRLF
"<head><title>507 Insufficient Storage</title></head>" CRLF
"<body bgcolor=\"white\">" CRLF
@ -257,53 +271,53 @@ static char error_507_page[] =
;
static ngx_str_t error_pages[] = {
static ngx_str_t ngx_http_error_pages[] = {
ngx_null_string, /* 201, 204 */
ngx_null_string, /* 201, 204 */
#define NGX_HTTP_LEVEL_200 1
/* ngx_null_string, */ /* 300 */
ngx_string(error_301_page),
ngx_string(error_302_page),
ngx_null_string, /* 303 */
/* ngx_null_string, */ /* 300 */
ngx_string(ngx_http_error_301_page),
ngx_string(ngx_http_error_302_page),
ngx_null_string, /* 303 */
#define NGX_HTTP_LEVEL_300 3
ngx_string(error_400_page),
ngx_string(error_401_page),
ngx_string(error_402_page),
ngx_string(error_403_page),
ngx_string(error_404_page),
ngx_string(error_405_page),
ngx_string(error_406_page),
ngx_null_string, /* 407 */
ngx_string(error_408_page),
ngx_string(error_409_page),
ngx_string(error_410_page),
ngx_string(error_411_page),
ngx_string(error_412_page),
ngx_string(error_413_page),
ngx_string(error_414_page),
ngx_string(error_415_page),
ngx_string(error_416_page),
ngx_string(ngx_http_error_400_page),
ngx_string(ngx_http_error_401_page),
ngx_string(ngx_http_error_402_page),
ngx_string(ngx_http_error_403_page),
ngx_string(ngx_http_error_404_page),
ngx_string(ngx_http_error_405_page),
ngx_string(ngx_http_error_406_page),
ngx_null_string, /* 407 */
ngx_string(ngx_http_error_408_page),
ngx_string(ngx_http_error_409_page),
ngx_string(ngx_http_error_410_page),
ngx_string(ngx_http_error_411_page),
ngx_string(ngx_http_error_412_page),
ngx_string(ngx_http_error_413_page),
ngx_string(ngx_http_error_414_page),
ngx_string(ngx_http_error_415_page),
ngx_string(ngx_http_error_416_page),
#define NGX_HTTP_LEVEL_400 17
ngx_string(error_495_page), /* 495, https certificate error */
ngx_string(error_496_page), /* 496, https no certificate */
ngx_string(error_497_page), /* 497, http to https */
ngx_string(error_404_page), /* 498, invalid host name */
ngx_null_string, /* 499, client had closed connection */
ngx_string(ngx_http_error_495_page), /* 495, https certificate error */
ngx_string(ngx_http_error_496_page), /* 496, https no certificate */
ngx_string(ngx_http_error_497_page), /* 497, http to https */
ngx_string(ngx_http_error_404_page), /* 498, canceled */
ngx_null_string, /* 499, client has closed connection */
ngx_string(error_500_page),
ngx_string(error_501_page),
ngx_string(error_502_page),
ngx_string(error_503_page),
ngx_string(error_504_page),
ngx_null_string, /* 505 */
ngx_null_string, /* 506 */
ngx_string(error_507_page)
ngx_string(ngx_http_error_500_page),
ngx_string(ngx_http_error_501_page),
ngx_string(ngx_http_error_502_page),
ngx_string(ngx_http_error_503_page),
ngx_string(ngx_http_error_504_page),
ngx_null_string, /* 505 */
ngx_null_string, /* 506 */
ngx_string(ngx_http_error_507_page)
};
@ -313,13 +327,8 @@ static ngx_str_t ngx_http_get_name = { 3, (u_char *) "GET " };
ngx_int_t
ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
{
u_char *p;
size_t msie_refresh;
ngx_int_t rc;
ngx_buf_t *b;
ngx_str_t *uri, *location;
ngx_uint_t i, n, err, msie_padding;
ngx_chain_t *out, *cl;
ngx_uint_t i, err;
ngx_http_err_page_t *err_page;
ngx_http_core_loc_conf_t *clcf;
@ -370,64 +379,20 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
err_page = clcf->error_pages->elts;
for (i = 0; i < clcf->error_pages->nelts; i++) {
if (err_page[i].status == error) {
r->err_status = err_page[i].overwrite;
r->method = NGX_HTTP_GET;
r->method_name = ngx_http_get_name;
uri = &err_page[i].uri;
if (err_page[i].uri_lengths) {
if (ngx_http_script_run(r, uri,
err_page[i].uri_lengths->elts, 0,
err_page[i].uri_values->elts)
== NULL)
{
return NGX_ERROR;
}
if (r->zero_in_uri) {
for (n = 0; n < uri->len; n++) {
if (uri->data[n] == '\0') {
goto zero;
}
}
r->zero_in_uri = 0;
}
} else {
r->zero_in_uri = 0;
}
zero:
if (uri->data[0] == '/') {
return ngx_http_internal_redirect(r, uri, NULL);
}
r->headers_out.location =
ngx_list_push(&r->headers_out.headers);
if (r->headers_out.location) {
error = NGX_HTTP_MOVED_TEMPORARILY;
r->err_status = NGX_HTTP_MOVED_TEMPORARILY;
r->headers_out.location->hash = 1;
r->headers_out.location->key.len = sizeof("Location") - 1;
r->headers_out.location->key.data = (u_char *) "Location";
r->headers_out.location->value = *uri;
} else {
return NGX_ERROR;
}
return ngx_http_send_error_page(r, &err_page[i]);
}
}
}
if (clcf->msie_refresh
&& r->headers_in.msie
&& (error == NGX_HTTP_MOVED_PERMANENTLY
|| error == NGX_HTTP_MOVED_TEMPORARILY))
{
return ngx_http_send_refresh(r);
}
if (error == NGX_HTTP_CREATED) {
/* 201 */
err = 0;
@ -456,29 +421,150 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
case NGX_HTTPS_CERT_ERROR:
case NGX_HTTPS_NO_CERT:
r->err_status = NGX_HTTP_BAD_REQUEST;
error = NGX_HTTP_BAD_REQUEST;
break;
}
}
return ngx_http_send_special_response(r, clcf, err);
}
static ngx_int_t
ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
{
u_char ch, *p, *last;
ngx_str_t *uri, *args, u, a;
ngx_table_elt_t *location;
ngx_http_core_loc_conf_t *clcf;
r->err_status = err_page->overwrite;
r->method = NGX_HTTP_GET;
r->method_name = ngx_http_get_name;
r->zero_in_uri = 0;
args = NULL;
if (err_page->uri_lengths) {
if (ngx_http_script_run(r, &u, err_page->uri_lengths->elts, 0,
err_page->uri_values->elts)
== NULL)
{
return NGX_ERROR;
}
p = u.data;
uri = &u;
if (*p == '/') {
last = p + uri->len;
while (p < last) {
ch = *p++;
if (ch == '?') {
a.len = last - p;
a.data = p;
args = &a;
u.len = p - 1 - u.data;
while (p < last) {
if (*p++ == '\0') {
r->zero_in_uri = 1;
break;
}
}
break;
}
if (ch == '\0') {
r->zero_in_uri = 1;
continue;
}
}
}
} else {
uri = &err_page->uri;
}
if (uri->data[0] == '/') {
return ngx_http_internal_redirect(r, uri, args);
}
if (uri->data[0] == '@') {
return ngx_http_named_location(r, uri);
}
location = ngx_list_push(&r->headers_out.headers);
if (location == NULL) {
return NGX_ERROR;
}
r->err_status = NGX_HTTP_MOVED_TEMPORARILY;
location->hash = 1;
location->key.len = sizeof("Location") - 1;
location->key.data = (u_char *) "Location";
location->value = *uri;
r->headers_out.location = location;
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (clcf->msie_refresh && r->headers_in.msie) {
return ngx_http_send_refresh(r);
}
return ngx_http_send_special_response(r, clcf, NGX_HTTP_MOVED_TEMPORARILY
- NGX_HTTP_MOVED_PERMANENTLY
+ NGX_HTTP_LEVEL_200);
}
static ngx_int_t
ngx_http_send_special_response(ngx_http_request_t *r,
ngx_http_core_loc_conf_t *clcf, ngx_uint_t err)
{
u_char *tail;
size_t len;
ngx_int_t rc;
ngx_buf_t *b;
ngx_uint_t msie_padding;
ngx_chain_t out[3];
if (clcf->server_tokens) {
len = sizeof(ngx_http_error_full_tail) - 1;
tail = ngx_http_error_full_tail;
} else {
len = sizeof(ngx_http_error_tail) - 1;
tail = ngx_http_error_tail;
}
msie_padding = 0;
if (!r->zero_body) {
if (error_pages[err].len) {
r->headers_out.content_length_n = error_pages[err].len
+ sizeof(error_tail) - 1;
if (ngx_http_error_pages[err].len) {
r->headers_out.content_length_n = ngx_http_error_pages[err].len
+ len;
if (clcf->msie_padding
&& r->headers_in.msie
&& r->http_version >= NGX_HTTP_VERSION_10
&& error >= NGX_HTTP_BAD_REQUEST
&& error != NGX_HTTP_REQUEST_URI_TOO_LARGE)
&& err >= NGX_HTTP_LEVEL_300)
{
r->headers_out.content_length_n +=
sizeof(ngx_http_msie_stub) - 1;
msie_padding = 1;
}
r->headers_out.content_type_len = sizeof("text/html") - 1;
r->headers_out.content_type.len = sizeof("text/html") - 1;
r->headers_out.content_type.data = (u_char *) "text/html";
@ -496,24 +582,102 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
r->headers_out.content_length = NULL;
}
msie_refresh = 0;
location = NULL;
ngx_http_clear_accept_ranges(r);
ngx_http_clear_last_modified(r);
if (clcf->msie_refresh
&& r->headers_in.msie
&& (error == NGX_HTTP_MOVED_PERMANENTLY
|| error == NGX_HTTP_MOVED_TEMPORARILY))
{
location = &r->headers_out.location->value;
msie_refresh = sizeof(ngx_http_msie_refresh_head) - 1
+ location->len
+ sizeof(ngx_http_msie_refresh_tail) - 1;
rc = ngx_http_send_header(r);
r->err_status = NGX_HTTP_OK;
r->headers_out.content_type_len = sizeof("text/html") - 1;
r->headers_out.content_length_n = msie_refresh;
r->headers_out.location->hash = 0;
r->headers_out.location = NULL;
if (rc == NGX_ERROR || r->header_only) {
return rc;
}
if (ngx_http_error_pages[err].len == 0) {
return NGX_OK;
}
b = ngx_calloc_buf(r->pool);
if (b == NULL) {
return NGX_ERROR;
}
b->memory = 1;
b->pos = ngx_http_error_pages[err].data;
b->last = ngx_http_error_pages[err].data + ngx_http_error_pages[err].len;
out[0].buf = b;
out[0].next = &out[1];
b = ngx_calloc_buf(r->pool);
if (b == NULL) {
return NGX_ERROR;
}
b->memory = 1;
b->pos = tail;
b->last = tail + len;
out[1].buf = b;
out[1].next = NULL;;
if (msie_padding) {
b = ngx_calloc_buf(r->pool);
if (b == NULL) {
return NGX_ERROR;
}
b->memory = 1;
b->pos = ngx_http_msie_stub;
b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1;
out[1].next = &out[2];
out[2].buf = b;
out[2].next = NULL;;
}
if (r == r->main) {
b->last_buf = 1;
}
b->last_in_chain = 1;
return ngx_http_output_filter(r, &out[0]);
}
static ngx_int_t
ngx_http_send_refresh(ngx_http_request_t *r)
{
u_char *p, *location;
size_t len, size;
uintptr_t escape;
ngx_int_t rc;
ngx_buf_t *b;
ngx_chain_t out;
len = r->headers_out.location->value.len;
location = r->headers_out.location->value.data;
escape = 2 * ngx_escape_uri(NULL, location, len, NGX_ESCAPE_REFRESH);
size = sizeof(ngx_http_msie_refresh_head) - 1
+ escape + len
+ sizeof(ngx_http_msie_refresh_tail) - 1;
r->err_status = NGX_HTTP_OK;
r->headers_out.content_type_len = sizeof("text/html") - 1;
r->headers_out.content_type.len = sizeof("text/html") - 1;
r->headers_out.content_type.data = (u_char *) "text/html";
r->headers_out.location->hash = 0;
r->headers_out.location = NULL;
r->headers_out.content_length_n = size;
if (r->headers_out.content_length) {
r->headers_out.content_length->hash = 0;
r->headers_out.content_length = NULL;
}
ngx_http_clear_accept_ranges(r);
@ -525,97 +689,29 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
return rc;
}
b = ngx_create_temp_buf(r->pool, size);
if (b == NULL) {
return NGX_ERROR;
}
if (msie_refresh == 0) {
p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head,
sizeof(ngx_http_msie_refresh_head) - 1);
if (error_pages[err].len == 0) {
return NGX_OK;
}
b = ngx_calloc_buf(r->pool);
if (b == NULL) {
return NGX_ERROR;
}
b->memory = 1;
b->pos = error_pages[err].data;
b->last = error_pages[err].data + error_pages[err].len;
cl = ngx_alloc_chain_link(r->pool);
if (cl == NULL) {
return NGX_ERROR;
}
cl->buf = b;
out = cl;
b = ngx_calloc_buf(r->pool);
if (b == NULL) {
return NGX_ERROR;
}
b->memory = 1;
b->pos = error_tail;
b->last = error_tail + sizeof(error_tail) - 1;
cl->next = ngx_alloc_chain_link(r->pool);
if (cl->next == NULL) {
return NGX_ERROR;
}
cl = cl->next;
cl->buf = b;
if (msie_padding) {
b = ngx_calloc_buf(r->pool);
if (b == NULL) {
return NGX_ERROR;
}
b->memory = 1;
b->pos = ngx_http_msie_stub;
b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1;
cl->next = ngx_alloc_chain_link(r->pool);
if (cl->next == NULL) {
return NGX_ERROR;
}
cl = cl->next;
cl->buf = b;
}
if (escape == 0) {
p = ngx_cpymem(p, location, len);
} else {
b = ngx_create_temp_buf(r->pool, msie_refresh);
if (b == NULL) {
return NGX_ERROR;
}
p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head,
sizeof(ngx_http_msie_refresh_head) - 1);
p = ngx_cpymem(p, location->data, location->len);
b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail,
sizeof(ngx_http_msie_refresh_tail) - 1);
cl = ngx_alloc_chain_link(r->pool);
if (cl == NULL) {
return NGX_ERROR;
}
cl->buf = b;
out = cl;
p = (u_char *) ngx_escape_uri(p, location, len, NGX_ESCAPE_REFRESH);
}
if (r == r->main) {
b->last_buf = 1;
}
b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail,
sizeof(ngx_http_msie_refresh_tail) - 1);
b->last_buf = 1;
b->last_in_chain = 1;
cl->next = NULL;
out.buf = b;
out.next = NULL;
return ngx_http_output_filter(r, out);
return ngx_http_output_filter(r, &out);
}

View File

@ -33,6 +33,8 @@ static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data,
ssize_t bytes);
static void ngx_http_upstream_process_downstream(ngx_http_request_t *r);
static void ngx_http_upstream_process_body(ngx_event_t *ev);
static void ngx_http_upstream_store(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void ngx_http_upstream_dummy_handler(ngx_event_t *wev);
static void ngx_http_upstream_next(ngx_http_request_t *r,
ngx_http_upstream_t *u, ngx_uint_t ft_type);
@ -116,6 +118,12 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
ngx_http_upstream_copy_header_line,
offsetof(ngx_http_headers_out_t, date), 0 },
{ ngx_string("Last-Modified"),
ngx_http_upstream_process_header_line,
offsetof(ngx_http_upstream_headers_in_t, last_modified),
ngx_http_upstream_copy_header_line,
offsetof(ngx_http_headers_out_t, last_modified), 0 },
{ ngx_string("Server"),
ngx_http_upstream_process_header_line,
offsetof(ngx_http_upstream_headers_in_t, server),
@ -364,6 +372,8 @@ ngx_http_upstream_init(ngx_http_request_t *r)
cln->data = r;
u->cleanup = &cln->handler;
u->store = (u->conf->store || u->conf->store_lengths);
ngx_http_upstream_connect(r, u);
}
@ -424,7 +434,7 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
ev->error = 1;
}
if (!u->cachable && u->peer.connection) {
if (!u->cacheable && !u->store && u->peer.connection) {
ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
"kevent() reported that client closed prematurely "
"connection, so upstream connection is closed too");
@ -490,7 +500,7 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
ev->eof = 1;
c->error = 1;
if (!u->cachable && u->peer.connection) {
if (!u->cacheable && !u->store && u->peer.connection) {
ngx_log_error(NGX_LOG_INFO, ev->log, err,
"client closed prematurely connection, "
"so upstream connection is closed too");
@ -571,7 +581,7 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
c->write->handler = ngx_http_upstream_send_request_handler;
c->read->handler = ngx_http_upstream_process_header;
c->sendfile = r->connection->sendfile;
c->sendfile &= r->connection->sendfile;
c->pool = r->pool;
c->read->log = c->write->log = c->log = r->connection->log;
@ -657,7 +667,7 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
c->sendfile = 0;
u->output.sendfile = 0;
if (ngx_ssl_set_session(c, u->peer.ssl_session) != NGX_OK) {
if (u->peer.set_session(&u->peer, u->peer.data) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
@ -968,8 +978,7 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
#endif
}
n = u->peer.connection->recv(u->peer.connection, u->buffer.last,
u->buffer.end - u->buffer.last);
n = c->recv(c, u->buffer.last, u->buffer.end - u->buffer.last);
if (n == NGX_AGAIN) {
#if 0
@ -1032,7 +1041,7 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
return;
}
if (rc == NGX_ERROR || rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
if (rc == NGX_ERROR) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
@ -1226,6 +1235,8 @@ ngx_http_upstream_process_header(ngx_event_t *rev)
r->headers_out.status = u->headers_in.status_n;
r->headers_out.status_line = u->headers_in.status_line;
u->headers_in.content_length_n = r->headers_out.content_length_n;
if (r->headers_out.content_length_n != -1) {
u->length = (size_t) r->headers_out.content_length_n;
@ -1278,6 +1289,7 @@ ngx_http_upstream_test_connect(ngx_connection_t *c)
if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
if (c->write->pending_eof) {
c->log->action = "connecting to upstream";
(void) ngx_connection_error(c, c->write->kq_errno,
"kevent() reported that connect() failed");
return NGX_ERROR;
@ -1301,6 +1313,7 @@ ngx_http_upstream_test_connect(ngx_connection_t *c)
}
if (err) {
c->log->action = "connecting to upstream";
(void) ngx_connection_error(c, err, "connect() failed");
return NGX_ERROR;
}
@ -1478,6 +1491,11 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
ngx_http_upstream_finalize_request(r, u, 0);
return;
}
if (u->peer.connection->read->ready) {
ngx_http_upstream_process_non_buffered_body(
u->peer.connection->read);
}
}
return;
@ -1495,7 +1513,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
}
}
if (u->cachable) {
if (u->cacheable) {
header = (ngx_http_cache_header_t *) u->buffer->start;
header->expires = u->cache->ctx.expires;
@ -1523,7 +1541,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
p->pool = r->pool;
p->log = c->log;
p->cachable = u->cachable;
p->cacheable = u->cacheable || u->store;
p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
if (p->temp_file == NULL) {
@ -1536,8 +1554,9 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
p->temp_file->path = u->conf->temp_path;
p->temp_file->pool = r->pool;
if (u->cachable) {
if (u->cacheable || u->store) {
p->temp_file->persistent = 1;
} else {
p->temp_file->log_level = NGX_LOG_WARN;
p->temp_file->warn = "an upstream response is buffered "
@ -1552,18 +1571,21 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
ngx_http_upstream_finalize_request(r, u, 0);
return;
}
p->preread_bufs->buf = &u->buffer;
p->preread_bufs->next = NULL;
u->buffer.recycled = 1;
p->preread_size = u->buffer.last - u->buffer.pos;
if (u->cachable) {
if (u->cacheable) {
p->buf_to_file = ngx_calloc_buf(r->pool);
if (p->buf_to_file == NULL) {
ngx_http_upstream_finalize_request(r, u, 0);
return;
}
p->buf_to_file->pos = u->buffer.start;
p->buf_to_file->last = u->buffer.pos;
p->buf_to_file->temporary = 1;
@ -1818,6 +1840,7 @@ ngx_http_upstream_process_downstream(ngx_http_request_t *r)
static void
ngx_http_upstream_process_body(ngx_event_t *ev)
{
ngx_temp_file_t *tf;
ngx_event_pipe_t *p;
ngx_connection_t *c, *downstream;
ngx_http_log_ctx_t *ctx;
@ -1910,16 +1933,41 @@ ngx_http_upstream_process_body(ngx_event_t *ev)
if (u->peer.connection) {
if (u->store) {
tf = u->pipe->temp_file;
if (p->upstream_eof
&& u->headers_in.status_n == NGX_HTTP_OK
&& (u->headers_in.content_length_n == -1
|| (u->headers_in.content_length_n == tf->offset)))
{
ngx_http_upstream_store(r, u);
} else if ((p->upstream_error
|| (p->upstream_eof
&& u->headers_in.status_n != NGX_HTTP_OK))
&& tf->file.fd != NGX_INVALID_FILE)
{
if (ngx_delete_file(tf->file.name.data) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
ngx_delete_file_n " \"%s\" failed",
u->pipe->temp_file->file.name.data);
}
}
}
#if (NGX_HTTP_FILE_CACHE)
if (p->upstream_done && u->cachable) {
if (p->upstream_done && u->cacheable) {
if (ngx_http_cache_update(r) == NGX_ERROR) {
ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
ngx_http_upstream_finalize_request(r, u, 0);
return;
}
} else if (p->upstream_eof && u->cachable) {
} else if (p->upstream_eof && u->cacheable) {
/* TODO: check length & update cache */
@ -1947,13 +1995,150 @@ ngx_http_upstream_process_body(ngx_event_t *ev)
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http upstream downstream error");
if (!u->cachable && u->peer.connection) {
if (!u->cacheable && u->peer.connection) {
ngx_http_upstream_finalize_request(r, u, 0);
}
}
}
static void
ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
{
char *failed;
u_char *name;
size_t root;
time_t lm;
ngx_err_t err;
ngx_str_t *temp, path, *last_modified;
ngx_temp_file_t *tf;
if (u->pipe->temp_file->file.fd == NGX_INVALID_FILE) {
/* create file for empty 200 response */
tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
if (tf == NULL) {
return;
}
tf->file.fd = NGX_INVALID_FILE;
tf->file.log = r->connection->log;
tf->path = u->conf->temp_path;
tf->pool = r->pool;
tf->persistent = 1;
if (ngx_create_temp_file(&tf->file, tf->path, tf->pool,
tf->persistent, tf->clean, tf->access)
!= NGX_OK)
{
return;
}
u->pipe->temp_file = tf;
}
temp = &u->pipe->temp_file->file.name;
#if !(NGX_WIN32)
if (ngx_change_file_access(temp->data, u->conf->store_access)
== NGX_FILE_ERROR)
{
err = ngx_errno;
failed = ngx_change_file_access_n;
name = temp->data;
goto failed;
}
#endif
if (r->upstream->headers_in.last_modified) {
last_modified = &r->upstream->headers_in.last_modified->value;
lm = ngx_http_parse_time(last_modified->data, last_modified->len);
if (lm != NGX_ERROR) {
if (ngx_set_file_time(temp->data, u->pipe->temp_file->file.fd, lm)
!= NGX_OK)
{
err = ngx_errno;
failed = ngx_set_file_time_n;
name = temp->data;
goto failed;
}
}
}
if (u->conf->store_lengths == NULL) {
ngx_http_map_uri_to_path(r, &path, &root, 0);
} else {
if (ngx_http_script_run(r, &path, u->conf->store_lengths->elts, 0,
u->conf->store_values->elts)
== NULL)
{
return;
}
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"upstream stores \"%s\" to \"%s\"", temp->data, path.data);
failed = ngx_rename_file_n;
name = path.data;
if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) {
return;
}
err = ngx_errno;
if (err == NGX_ENOENT) {
err = ngx_create_full_path(path.data,
ngx_dir_access(u->conf->store_access));
if (err == 0) {
if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) {
return;
}
err = ngx_errno;
}
}
#if (NGX_WIN32)
if (err == NGX_EEXIST) {
if (ngx_win32_rename_file(temp, &path, r->pool) != NGX_ERROR) {
if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) {
return;
}
}
err = ngx_errno;
}
#endif
failed:
if (ngx_delete_file(temp->data) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
ngx_delete_file_n " \"%s\" failed",
temp->data);
}
ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
"%s \"%s\" failed", failed, name);
}
static void
ngx_http_upstream_dummy_handler(ngx_event_t *wev)
{
@ -2157,8 +2342,17 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
r->connection->log->action = "sending to client";
if (rc == 0 && r == r->main && !r->post_action) {
rc = ngx_http_send_special(r, NGX_HTTP_LAST);
if (rc == 0) {
if (r == r->main) {
if (!r->post_action) {
rc = ngx_http_send_special(r, NGX_HTTP_LAST);
}
} else {
if (r->out) {
rc = NGX_AGAIN;
}
}
}
ngx_http_finalize_request(r, rc);
@ -2349,6 +2543,10 @@ ngx_http_upstream_copy_content_type(ngx_http_request_t *r, ngx_table_elt_t *h,
while (*++p == ' ') { /* void */ }
if (*p == '\0') {
return NGX_OK;
}
if (ngx_strncasecmp(p, (u_char *) "charset=", 8) != 0) {
continue;
}
@ -2444,7 +2642,7 @@ ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r, ngx_table_elt_t *h,
if (r->upstream->rewrite_redirect) {
p = (u_char *) ngx_strstr(ho->value.data, "url=");
p = ngx_strcasestrn(ho->value.data, "url=", 4 - 1);
if (p) {
rc = r->upstream->rewrite_redirect(r, ho, p + 4 - ho->value.data);
@ -2523,7 +2721,7 @@ ngx_http_upstream_addr_variable(ngx_http_request_t *r,
ngx_http_upstream_state_t *state;
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
@ -2594,7 +2792,7 @@ ngx_http_upstream_status_variable(ngx_http_request_t *r,
ngx_http_upstream_state_t *state;
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
@ -2660,7 +2858,7 @@ ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
ngx_http_upstream_state_t *state;
v->valid = 1;
v->no_cachable = 0;
v->no_cacheable = 0;
v->not_found = 0;
if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
@ -2874,7 +3072,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
u.url = value[1];
u.default_port = 80;
if (ngx_parse_url(cf, &u) != NGX_OK) {
if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
if (u.err) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"%s in upstream \"%V\"", u.err, &u.url);
@ -2978,7 +3176,7 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
if (!(flags & NGX_HTTP_UPSTREAM_CREATE)) {
if (ngx_parse_url(cf, u) != NGX_OK) {
if (ngx_parse_url(cf->pool, u) != NGX_OK) {
if (u->err) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"%s in upstream \"%V\"", u->err, &u->url);
@ -3020,7 +3218,7 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
ngx_log_error(NGX_LOG_WARN, cf->log, 0,
"upstream \"%V\" may not have port %d in %s:%ui",
&u->host, uscfp[i]->port,
uscfp[i]->file_name.data, uscfp[i]->line);
uscfp[i]->file_name, uscfp[i]->line);
return NULL;
}
@ -3028,6 +3226,12 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
continue;
}
if (uscfp[i]->default_port && u->default_port
&& uscfp[i]->default_port != u->default_port)
{
continue;
}
return uscfp[i];
}
@ -3038,7 +3242,7 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
uscf->flags = flags;
uscf->host = u->host;
uscf->file_name = cf->conf_file->file.name;
uscf->file_name = cf->conf_file->file.name.data;
uscf->line = cf->conf_file->line;
uscf->port = u->port;
uscf->default_port = u->default_port;
@ -3072,6 +3276,113 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
}
ngx_int_t
ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
ngx_str_t *default_hide_headers, ngx_hash_init_t *hash)
{
ngx_str_t *h;
ngx_uint_t i, j;
ngx_array_t hide_headers;
ngx_hash_key_t *hk;
if (conf->hide_headers == NGX_CONF_UNSET_PTR
&& conf->pass_headers == NGX_CONF_UNSET_PTR)
{
conf->hide_headers_hash = prev->hide_headers_hash;
if (conf->hide_headers_hash.buckets) {
return NGX_OK;
}
conf->hide_headers = prev->hide_headers;
conf->pass_headers = prev->pass_headers;
} else {
if (conf->hide_headers == NGX_CONF_UNSET_PTR) {
conf->hide_headers = prev->hide_headers;
}
if (conf->pass_headers == NGX_CONF_UNSET_PTR) {
conf->pass_headers = prev->pass_headers;
}
}
if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
!= NGX_OK)
{
return NGX_ERROR;
}
for (h = default_hide_headers; h->len; h++) {
hk = ngx_array_push(&hide_headers);
if (hk == NULL) {
return NGX_ERROR;
}
hk->key = *h;
hk->key_hash = ngx_hash_key_lc(h->data, h->len);
hk->value = (void *) 1;
}
if (conf->hide_headers != NGX_CONF_UNSET_PTR) {
h = conf->hide_headers->elts;
for (i = 0; i < conf->hide_headers->nelts; i++) {
hk = hide_headers.elts;
for (j = 0; j < hide_headers.nelts; j++) {
if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {
goto exist;
}
}
hk = ngx_array_push(&hide_headers);
if (hk == NULL) {
return NGX_ERROR;
}
hk->key = h[i];
hk->key_hash = ngx_hash_key_lc(h[i].data, h[i].len);
hk->value = (void *) 1;
exist:
continue;
}
}
if (conf->pass_headers != NGX_CONF_UNSET_PTR) {
h = conf->pass_headers->elts;
hk = hide_headers.elts;
for (i = 0; i < conf->pass_headers->nelts; i++) {
for (j = 0; j < hide_headers.nelts; j++) {
if (hk[j].key.data == NULL) {
continue;
}
if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {
hk[j].key.data = NULL;
break;
}
}
}
}
hash->hash = &conf->hide_headers_hash;
hash->key = ngx_hash_key_lc;
hash->pool = cf->pool;
hash->temp_pool = NULL;
return ngx_hash_init(hash, hide_headers.elts, hide_headers.nelts);
}
static void *
ngx_http_upstream_create_main_conf(ngx_conf_t *cf)
{

View File

@ -91,7 +91,7 @@ struct ngx_http_upstream_srv_conf_s {
ngx_uint_t flags;
ngx_str_t host;
ngx_str_t file_name;
u_char *file_name;
ngx_uint_t line;
in_port_t port;
in_port_t default_port;
@ -118,6 +118,7 @@ typedef struct {
size_t temp_file_write_size_conf;
ngx_uint_t next_upstream;
ngx_uint_t store_access;
ngx_bufs_t bufs;
@ -140,6 +141,10 @@ typedef struct {
ngx_str_t location;
ngx_str_t url; /* used in proxy_rewrite_location */
ngx_array_t *store_lengths;
ngx_array_t *store_values;
signed store:2;
unsigned intercept_404:1;
unsigned change_buffering:1;
@ -189,6 +194,8 @@ typedef struct {
ngx_table_elt_t *content_encoding;
#endif
off_t content_length_n;
ngx_array_t cache_control;
} ngx_http_upstream_headers_in_t;
@ -237,7 +244,8 @@ struct ngx_http_upstream_s {
ngx_http_cleanup_pt *cleanup;
unsigned cachable:1;
unsigned store:1;
unsigned cacheable:1;
unsigned accel:1;
unsigned buffering:1;
@ -253,6 +261,9 @@ ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
void ngx_http_upstream_init(ngx_http_request_t *r);
ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
ngx_url_t *u, ngx_uint_t flags);
ngx_int_t ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
ngx_str_t *default_hide_headers, ngx_hash_init_t *hash);
#define ngx_http_conf_upstream_srv_conf(uscf, module) \

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