summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorrobert <robert@openbsd.org>2014-08-26 19:35:31 +0000
committerrobert <robert@openbsd.org>2014-08-26 19:35:31 +0000
commitc11519ffeda73deab560cc100658d89d70c26934 (patch)
tree5d718501b01d61c85227fde68121a14d950853c8 /usr.sbin
parentusr.sbin (diff)
downloadwireguard-openbsd-c11519ffeda73deab560cc100658d89d70c26934.tar.xz
wireguard-openbsd-c11519ffeda73deab560cc100658d89d70c26934.zip
remove nginx from the base system in favor of OpenBSD's own httpd(8)
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/Makefile4
-rw-r--r--usr.sbin/nginx/CHANGES6644
-rw-r--r--usr.sbin/nginx/CHANGES.ru6749
-rw-r--r--usr.sbin/nginx/LICENSE26
-rw-r--r--usr.sbin/nginx/Makefile.bsd-wrapper104
-rw-r--r--usr.sbin/nginx/README3
-rw-r--r--usr.sbin/nginx/README.OpenBSD33
-rw-r--r--usr.sbin/nginx/auto/cc/acc15
-rw-r--r--usr.sbin/nginx/auto/cc/bcc72
-rw-r--r--usr.sbin/nginx/auto/cc/ccc46
-rw-r--r--usr.sbin/nginx/auto/cc/clang99
-rw-r--r--usr.sbin/nginx/auto/cc/conf218
-rw-r--r--usr.sbin/nginx/auto/cc/gcc181
-rw-r--r--usr.sbin/nginx/auto/cc/icc121
-rw-r--r--usr.sbin/nginx/auto/cc/msvc136
-rw-r--r--usr.sbin/nginx/auto/cc/name89
-rw-r--r--usr.sbin/nginx/auto/cc/owc104
-rw-r--r--usr.sbin/nginx/auto/cc/sunc158
-rw-r--r--usr.sbin/nginx/auto/define12
-rw-r--r--usr.sbin/nginx/auto/endianness45
-rw-r--r--usr.sbin/nginx/auto/feature123
-rw-r--r--usr.sbin/nginx/auto/have12
-rw-r--r--usr.sbin/nginx/auto/have_headers12
-rw-r--r--usr.sbin/nginx/auto/headers13
-rw-r--r--usr.sbin/nginx/auto/include61
-rw-r--r--usr.sbin/nginx/auto/init51
-rw-r--r--usr.sbin/nginx/auto/install121
-rw-r--r--usr.sbin/nginx/auto/lib/conf83
-rw-r--r--usr.sbin/nginx/auto/lib/geoip/conf94
-rw-r--r--usr.sbin/nginx/auto/lib/google-perftools/conf61
-rw-r--r--usr.sbin/nginx/auto/lib/libatomic/conf43
-rw-r--r--usr.sbin/nginx/auto/lib/libatomic/make16
-rw-r--r--usr.sbin/nginx/auto/lib/libgd/conf83
-rw-r--r--usr.sbin/nginx/auto/lib/libxslt/conf156
-rw-r--r--usr.sbin/nginx/auto/lib/make32
-rw-r--r--usr.sbin/nginx/auto/lib/md5/conf103
-rw-r--r--usr.sbin/nginx/auto/lib/md5/make96
-rw-r--r--usr.sbin/nginx/auto/lib/md5/makefile.bcc22
-rw-r--r--usr.sbin/nginx/auto/lib/md5/makefile.msvc22
-rw-r--r--usr.sbin/nginx/auto/lib/md5/makefile.owc11
-rw-r--r--usr.sbin/nginx/auto/lib/openssl/conf78
-rw-r--r--usr.sbin/nginx/auto/lib/openssl/make67
-rw-r--r--usr.sbin/nginx/auto/lib/openssl/makefile.bcc18
-rw-r--r--usr.sbin/nginx/auto/lib/openssl/makefile.msvc14
-rw-r--r--usr.sbin/nginx/auto/lib/pcre/conf209
-rw-r--r--usr.sbin/nginx/auto/lib/pcre/make64
-rw-r--r--usr.sbin/nginx/auto/lib/pcre/makefile.bcc27
-rw-r--r--usr.sbin/nginx/auto/lib/pcre/makefile.msvc23
-rw-r--r--usr.sbin/nginx/auto/lib/pcre/makefile.owc25
-rw-r--r--usr.sbin/nginx/auto/lib/perl/conf70
-rw-r--r--usr.sbin/nginx/auto/lib/perl/make41
-rw-r--r--usr.sbin/nginx/auto/lib/sha1/conf79
-rw-r--r--usr.sbin/nginx/auto/lib/sha1/make96
-rw-r--r--usr.sbin/nginx/auto/lib/sha1/makefile.bcc22
-rw-r--r--usr.sbin/nginx/auto/lib/sha1/makefile.msvc22
-rw-r--r--usr.sbin/nginx/auto/lib/sha1/makefile.owc11
-rw-r--r--usr.sbin/nginx/auto/lib/test40
-rw-r--r--usr.sbin/nginx/auto/lib/zlib/conf79
-rw-r--r--usr.sbin/nginx/auto/lib/zlib/make135
-rw-r--r--usr.sbin/nginx/auto/lib/zlib/makefile.bcc17
-rw-r--r--usr.sbin/nginx/auto/lib/zlib/makefile.msvc17
-rw-r--r--usr.sbin/nginx/auto/lib/zlib/makefile.owc14
-rw-r--r--usr.sbin/nginx/auto/lib/zlib/patch.zlib.h10
-rw-r--r--usr.sbin/nginx/auto/make418
-rw-r--r--usr.sbin/nginx/auto/modules529
-rw-r--r--usr.sbin/nginx/auto/nohave12
-rw-r--r--usr.sbin/nginx/auto/options520
-rw-r--r--usr.sbin/nginx/auto/os/conf107
-rw-r--r--usr.sbin/nginx/auto/os/darwin116
-rw-r--r--usr.sbin/nginx/auto/os/freebsd144
-rw-r--r--usr.sbin/nginx/auto/os/linux185
-rw-r--r--usr.sbin/nginx/auto/os/solaris61
-rw-r--r--usr.sbin/nginx/auto/os/win3240
-rw-r--r--usr.sbin/nginx/auto/sources565
-rw-r--r--usr.sbin/nginx/auto/stubs8
-rw-r--r--usr.sbin/nginx/auto/summary116
-rw-r--r--usr.sbin/nginx/auto/types/sizeof84
-rw-r--r--usr.sbin/nginx/auto/types/typedef77
-rw-r--r--usr.sbin/nginx/auto/types/uintptr_t45
-rw-r--r--usr.sbin/nginx/auto/types/value12
-rwxr-xr-xusr.sbin/nginx/auto/unix806
-rw-r--r--usr.sbin/nginx/conf/fastcgi.conf25
-rw-r--r--usr.sbin/nginx/conf/fastcgi_params25
-rw-r--r--usr.sbin/nginx/conf/koi-utf110
-rw-r--r--usr.sbin/nginx/conf/koi-win104
-rw-r--r--usr.sbin/nginx/conf/mime.types105
-rw-r--r--usr.sbin/nginx/conf/nginx.conf123
-rw-r--r--usr.sbin/nginx/conf/scgi_params17
-rw-r--r--usr.sbin/nginx/conf/uwsgi_params17
-rw-r--r--usr.sbin/nginx/conf/win-utf127
-rw-r--r--usr.sbin/nginx/configure111
-rw-r--r--usr.sbin/nginx/contrib/README21
-rw-r--r--usr.sbin/nginx/contrib/geo2nginx.pl58
-rw-r--r--usr.sbin/nginx/contrib/unicode2nginx/koi-utf131
-rwxr-xr-xusr.sbin/nginx/contrib/unicode2nginx/unicode-to-nginx.pl45
-rw-r--r--usr.sbin/nginx/contrib/unicode2nginx/win-utf130
-rw-r--r--usr.sbin/nginx/html/50x.html21
-rw-r--r--usr.sbin/nginx/html/index.html25
-rw-r--r--usr.sbin/nginx/man/nginx.8213
-rw-r--r--usr.sbin/nginx/man/nginx.conf.58753
-rw-r--r--usr.sbin/nginx/src/core/nginx.c1369
-rw-r--r--usr.sbin/nginx/src/core/nginx.h20
-rw-r--r--usr.sbin/nginx/src/core/ngx_array.c141
-rw-r--r--usr.sbin/nginx/src/core/ngx_array.h53
-rw-r--r--usr.sbin/nginx/src/core/ngx_buf.c220
-rw-r--r--usr.sbin/nginx/src/core/ngx_buf.h162
-rw-r--r--usr.sbin/nginx/src/core/ngx_conf_file.c1400
-rw-r--r--usr.sbin/nginx/src/core/ngx_conf_file.h340
-rw-r--r--usr.sbin/nginx/src/core/ngx_config.h134
-rw-r--r--usr.sbin/nginx/src/core/ngx_connection.c1210
-rw-r--r--usr.sbin/nginx/src/core/ngx_connection.h211
-rw-r--r--usr.sbin/nginx/src/core/ngx_core.h101
-rw-r--r--usr.sbin/nginx/src/core/ngx_cpuinfo.c139
-rw-r--r--usr.sbin/nginx/src/core/ngx_crc.h39
-rw-r--r--usr.sbin/nginx/src/core/ngx_crc32.c129
-rw-r--r--usr.sbin/nginx/src/core/ngx_crc32.h79
-rw-r--r--usr.sbin/nginx/src/core/ngx_crypt.c283
-rw-r--r--usr.sbin/nginx/src/core/ngx_crypt.h20
-rw-r--r--usr.sbin/nginx/src/core/ngx_cycle.c1294
-rw-r--r--usr.sbin/nginx/src/core/ngx_cycle.h144
-rw-r--r--usr.sbin/nginx/src/core/ngx_file.c1101
-rw-r--r--usr.sbin/nginx/src/core/ngx_file.h154
-rw-r--r--usr.sbin/nginx/src/core/ngx_hash.c975
-rw-r--r--usr.sbin/nginx/src/core/ngx_hash.h122
-rw-r--r--usr.sbin/nginx/src/core/ngx_inet.c1271
-rw-r--r--usr.sbin/nginx/src/core/ngx_inet.h122
-rw-r--r--usr.sbin/nginx/src/core/ngx_list.c63
-rw-r--r--usr.sbin/nginx/src/core/ngx_list.h83
-rw-r--r--usr.sbin/nginx/src/core/ngx_log.c619
-rw-r--r--usr.sbin/nginx/src/core/ngx_log.h259
-rw-r--r--usr.sbin/nginx/src/core/ngx_md5.c289
-rw-r--r--usr.sbin/nginx/src/core/ngx_md5.h60
-rw-r--r--usr.sbin/nginx/src/core/ngx_murmurhash.c50
-rw-r--r--usr.sbin/nginx/src/core/ngx_murmurhash.h19
-rw-r--r--usr.sbin/nginx/src/core/ngx_open_file_cache.c1253
-rw-r--r--usr.sbin/nginx/src/core/ngx_open_file_cache.h129
-rw-r--r--usr.sbin/nginx/src/core/ngx_output_chain.c674
-rw-r--r--usr.sbin/nginx/src/core/ngx_palloc.c436
-rw-r--r--usr.sbin/nginx/src/core/ngx_palloc.h95
-rw-r--r--usr.sbin/nginx/src/core/ngx_parse.c249
-rw-r--r--usr.sbin/nginx/src/core/ngx_parse.h21
-rw-r--r--usr.sbin/nginx/src/core/ngx_proxy_protocol.c91
-rw-r--r--usr.sbin/nginx/src/core/ngx_proxy_protocol.h23
-rw-r--r--usr.sbin/nginx/src/core/ngx_queue.c80
-rw-r--r--usr.sbin/nginx/src/core/ngx_queue.h112
-rw-r--r--usr.sbin/nginx/src/core/ngx_radix_tree.c488
-rw-r--r--usr.sbin/nginx/src/core/ngx_radix_tree.h55
-rw-r--r--usr.sbin/nginx/src/core/ngx_rbtree.c382
-rw-r--r--usr.sbin/nginx/src/core/ngx_rbtree.h84
-rw-r--r--usr.sbin/nginx/src/core/ngx_regex.c464
-rw-r--r--usr.sbin/nginx/src/core/ngx_regex.h60
-rw-r--r--usr.sbin/nginx/src/core/ngx_resolver.c3108
-rw-r--r--usr.sbin/nginx/src/core/ngx_resolver.h178
-rw-r--r--usr.sbin/nginx/src/core/ngx_sha1.h31
-rw-r--r--usr.sbin/nginx/src/core/ngx_shmtx.c309
-rw-r--r--usr.sbin/nginx/src/core/ngx_shmtx.h49
-rw-r--r--usr.sbin/nginx/src/core/ngx_slab.c702
-rw-r--r--usr.sbin/nginx/src/core/ngx_slab.h56
-rw-r--r--usr.sbin/nginx/src/core/ngx_spinlock.c53
-rw-r--r--usr.sbin/nginx/src/core/ngx_string.c1929
-rw-r--r--usr.sbin/nginx/src/core/ngx_string.h234
-rw-r--r--usr.sbin/nginx/src/core/ngx_syslog.c342
-rw-r--r--usr.sbin/nginx/src/core/ngx_syslog.h30
-rw-r--r--usr.sbin/nginx/src/core/ngx_times.c428
-rw-r--r--usr.sbin/nginx/src/core/ngx_times.h52
-rw-r--r--usr.sbin/nginx/src/event/modules/ngx_aio_module.c171
-rw-r--r--usr.sbin/nginx/src/event/modules/ngx_devpoll_module.c575
-rw-r--r--usr.sbin/nginx/src/event/modules/ngx_epoll_module.c845
-rw-r--r--usr.sbin/nginx/src/event/modules/ngx_eventport_module.c633
-rw-r--r--usr.sbin/nginx/src/event/modules/ngx_kqueue_module.c785
-rw-r--r--usr.sbin/nginx/src/event/modules/ngx_poll_module.c443
-rw-r--r--usr.sbin/nginx/src/event/modules/ngx_rtsig_module.c747
-rw-r--r--usr.sbin/nginx/src/event/modules/ngx_select_module.c435
-rw-r--r--usr.sbin/nginx/src/event/modules/ngx_win32_select_module.c400
-rw-r--r--usr.sbin/nginx/src/event/ngx_event.c1339
-rw-r--r--usr.sbin/nginx/src/event/ngx_event.h569
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_accept.c507
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_busy_lock.c286
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_busy_lock.h65
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_connect.c258
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_connect.h76
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_mutex.c70
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_openssl.c2852
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_openssl.h197
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_openssl_stapling.c1760
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_pipe.c1011
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_pipe.h94
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_posted.c173
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_posted.h75
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_timer.c158
-rw-r--r--usr.sbin/nginx/src/event/ngx_event_timer.h102
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_access_module.c469
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_addition_filter_module.c251
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_auth_basic_module.c471
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_auth_request_module.c444
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_autoindex_module.c705
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_browser_module.c715
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_charset_filter_module.c1681
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_chunked_filter_module.c243
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_dav_module.c1144
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_degradation_module.c243
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_empty_gif_module.c140
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_fastcgi_module.c3279
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_flv_module.c266
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_geo_module.c1644
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_geoip_module.c919
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_gunzip_filter_module.c681
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_gzip_filter_module.c1229
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_gzip_static_module.c333
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_headers_filter_module.c635
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_image_filter_module.c1520
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_index_module.c540
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_limit_conn_module.c767
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_limit_req_module.c989
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_log_module.c1758
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_map_module.c567
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_memcached_module.c703
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_mp4_module.c3500
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_not_modified_filter_module.c240
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_proxy_module.c3832
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_random_index_module.c317
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_range_filter_module.c890
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_realip_module.c442
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_referer_module.c671
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_rewrite_module.c1025
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_scgi_module.c1810
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_secure_link_module.c368
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_split_clients_module.c246
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_ssi_filter_module.c2927
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_ssi_filter_module.h114
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_ssl_module.c921
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_ssl_module.h63
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_static_module.c290
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_stub_status_module.c234
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_sub_filter_module.c749
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c279
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c536
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c408
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_userid_filter_module.c842
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_uwsgi_module.c2036
-rw-r--r--usr.sbin/nginx/src/http/modules/ngx_http_xslt_filter_module.c1145
-rw-r--r--usr.sbin/nginx/src/http/modules/perl/Makefile.PL33
-rw-r--r--usr.sbin/nginx/src/http/modules/perl/nginx.pm138
-rw-r--r--usr.sbin/nginx/src/http/modules/perl/nginx.xs1038
-rw-r--r--usr.sbin/nginx/src/http/modules/perl/ngx_http_perl_module.c1076
-rw-r--r--usr.sbin/nginx/src/http/modules/perl/ngx_http_perl_module.h67
-rw-r--r--usr.sbin/nginx/src/http/modules/perl/typemap3
-rw-r--r--usr.sbin/nginx/src/http/ngx_http.c2118
-rw-r--r--usr.sbin/nginx/src/http/ngx_http.h184
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_busy_lock.c307
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_busy_lock.h54
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_cache.h161
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_config.h75
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_copy_filter_module.c303
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_core_module.c5254
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_core_module.h588
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_file_cache.c1999
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_header_filter_module.c633
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_parse.c2308
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_parse_time.c277
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_postpone_filter_module.c176
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_request.c3648
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_request.h598
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_request_body.c1099
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_script.c1754
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_script.h257
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_spdy.c3497
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_spdy.h258
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_spdy_filter_module.c1214
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_spdy_module.c408
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_spdy_module.h41
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_special_response.c792
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_upstream.c5311
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_upstream.h383
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.c689
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.h89
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_variables.c2576
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_variables.h112
-rw-r--r--usr.sbin/nginx/src/http/ngx_http_write_filter_module.c318
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail.c568
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail.h421
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_auth_http_module.c1461
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_core_module.c653
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_handler.c784
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_imap_handler.c457
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_imap_module.c253
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_imap_module.h39
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_parse.c918
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_pop3_handler.c500
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_pop3_module.c264
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_pop3_module.h38
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_proxy_module.c1136
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_smtp_handler.c844
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_smtp_module.c307
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_smtp_module.h45
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_ssl_module.c533
-rw-r--r--usr.sbin/nginx/src/mail/ngx_mail_ssl_module.h55
-rw-r--r--usr.sbin/nginx/src/misc/ngx_cpp_test_module.cpp29
-rw-r--r--usr.sbin/nginx/src/misc/ngx_google_perftools_module.c126
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_aio_read.c109
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_aio_read_chain.c78
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_aio_write.c109
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_aio_write_chain.c100
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_alloc.c90
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_alloc.h45
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_atomic.h313
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_channel.c260
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_channel.h34
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_daemon.c70
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_darwin.h23
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_darwin_config.h98
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_darwin_init.c196
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_darwin_sendfile_chain.c370
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_errno.c87
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_errno.h78
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_file_aio_read.c208
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_files.c564
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_files.h386
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_freebsd.h25
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_freebsd_config.h127
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_freebsd_init.c260
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_freebsd_rfork_thread.c756
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_freebsd_rfork_thread.h122
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c440
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_amd64.h82
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_ppc.h155
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_sparc64.h82
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_x86.h127
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_linux.h18
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_linux_aio_read.c137
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_linux_config.h124
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_linux_init.c91
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_linux_sendfile_chain.c378
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_os.h83
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_posix_config.h158
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_posix_init.c128
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_process.c630
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_process.h89
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_process_cycle.c1459
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_process_cycle.h62
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_pthread_thread.c278
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_readv_chain.c267
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_recv.c183
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_send.c73
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_setaffinity.c69
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_setaffinity.h23
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_setproctitle.c135
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_setproctitle.h52
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_shmem.c126
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_shmem.h29
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_socket.c116
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_socket.h64
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_solaris.h16
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_solaris_config.h110
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_solaris_init.c75
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c260
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_sunpro_amd64.il43
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_sunpro_atomic_sparc64.h61
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_sunpro_sparc64.il36
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_sunpro_x86.il44
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_thread.h128
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_time.c104
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_time.h66
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_udp_recv.c115
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_user.c108
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_user.h24
-rw-r--r--usr.sbin/nginx/src/os/unix/ngx_writev_chain.c185
-rw-r--r--usr.sbin/nginx/src/os/unix/rfork_thread.S73
-rw-r--r--usr.sbin/nginx/src/pcre/LICENCE92
-rw-r--r--usr.sbin/nginx/src/pcre/config.h350
-rw-r--r--usr.sbin/nginx/src/pcre/pcre.h663
-rw-r--r--usr.sbin/nginx/src/pcre/pcre_chartables.c198
-rw-r--r--usr.sbin/nginx/src/pcre/pcre_compile.c8436
-rw-r--r--usr.sbin/nginx/src/pcre/pcre_exec.c7213
-rw-r--r--usr.sbin/nginx/src/pcre/pcre_fullinfo.c241
-rw-r--r--usr.sbin/nginx/src/pcre/pcre_globals.c84
-rw-r--r--usr.sbin/nginx/src/pcre/pcre_internal.h2771
-rw-r--r--usr.sbin/nginx/src/pcre/pcre_newline.c210
-rw-r--r--usr.sbin/nginx/src/pcre/pcre_ord2utf8.c94
-rw-r--r--usr.sbin/nginx/src/pcre/pcre_study.c1562
-rw-r--r--usr.sbin/nginx/src/pcre/pcre_tables.c658
-rw-r--r--usr.sbin/nginx/src/pcre/pcre_ucd.c3298
-rw-r--r--usr.sbin/nginx/src/pcre/pcre_valid_utf8.c312
-rw-r--r--usr.sbin/nginx/src/pcre/pcre_xclass.c212
-rw-r--r--usr.sbin/nginx/src/pcre/ucp.h197
385 files changed, 2 insertions, 204447 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index 7498c26426f..e839445f398 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.181 2014/08/26 17:47:24 jsing Exp $
+# $OpenBSD: Makefile,v 1.182 2014/08/26 19:35:31 robert Exp $
.include <bsd.own.mk>
@@ -10,7 +10,7 @@ SUBDIR= ac accton acpidump adduser amd apm apmd arp \
ldapd ldapctl ldomctl ldomd ldpd ldpctl lpr mailwrapper map-mbone \
memconfig mksuncd mkuboot mopd mrinfo mrouted \
mtrace mtree ndp netgroup_mkdb \
- nginx npppctl npppd nsd ntpd ospfctl ospfd ospf6d ospf6ctl \
+ npppctl npppd nsd ntpd ospfctl ospfd ospf6d ospf6ctl \
pcidump pkg_add portmap pppd procmap pstat pwd_mkdb \
quot quotaon rarpd rbootd rcctl rdate relayctl relayd repquota rip6query \
ripctl ripd rmt route6d rpc.bootparamd rpc.lockd rpc.statd rtadvd \
diff --git a/usr.sbin/nginx/CHANGES b/usr.sbin/nginx/CHANGES
deleted file mode 100644
index 1b502bf91c4..00000000000
--- a/usr.sbin/nginx/CHANGES
+++ /dev/null
@@ -1,6644 +0,0 @@
-
-Changes with nginx 1.6.0 24 Apr 2014
-
- *) 1.6.x stable branch.
-
-
-Changes with nginx 1.5.13 08 Apr 2014
-
- *) Change: improved hash table handling; the default values of the
- "variables_hash_max_size" and "types_hash_bucket_size" were changed
- to 1024 and 64 respectively.
-
- *) Feature: the ngx_http_mp4_module now supports the "end" argument.
-
- *) Feature: byte ranges support in the ngx_http_mp4_module and while
- saving responses to cache.
-
- *) Bugfix: alerts "ngx_slab_alloc() failed: no memory" no longer logged
- when using shared memory in the "ssl_session_cache" directive and in
- the ngx_http_limit_req_module.
-
- *) Bugfix: the "underscores_in_headers" directive did not allow
- underscore as a first character of a header.
- Thanks to Piotr Sikora.
-
- *) Bugfix: cache manager might hog CPU on exit in nginx/Windows.
-
- *) Bugfix: nginx/Windows terminated abnormally if the
- "ssl_session_cache" directive was used with the "shared" parameter.
-
- *) Bugfix: in the ngx_http_spdy_module.
-
-
-Changes with nginx 1.5.12 18 Mar 2014
-
- *) Security: a heap memory buffer overflow might occur in a worker
- process while handling a specially crafted request by
- ngx_http_spdy_module, potentially resulting in arbitrary code
- execution (CVE-2014-0133).
- Thanks to Lucas Molas, researcher at Programa STIC, Fundación Dr.
- Manuel Sadosky, Buenos Aires, Argentina.
-
- *) Feature: the "proxy_protocol" parameters of the "listen" and
- "real_ip_header" directives, the $proxy_protocol_addr variable.
-
- *) Bugfix: in the "fastcgi_next_upstream" directive.
- Thanks to Lucas Molas.
-
-
-Changes with nginx 1.5.11 04 Mar 2014
-
- *) Security: memory corruption might occur in a worker process on 32-bit
- platforms while handling a specially crafted request by
- ngx_http_spdy_module, potentially resulting in arbitrary code
- execution (CVE-2014-0088); the bug had appeared in 1.5.10.
- Thanks to Lucas Molas, researcher at Programa STIC, Fundación Dr.
- Manuel Sadosky, Buenos Aires, Argentina.
-
- *) Feature: the $ssl_session_reused variable.
-
- *) Bugfix: the "client_max_body_size" directive might not work when
- reading a request body using chunked transfer encoding; the bug had
- appeared in 1.3.9.
- Thanks to Lucas Molas.
-
- *) Bugfix: a segmentation fault might occur in a worker process when
- proxying WebSocket connections.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- ngx_http_spdy_module was used on 32-bit platforms; the bug had
- appeared in 1.5.10.
-
- *) Bugfix: the $upstream_status variable might contain wrong data if the
- "proxy_cache_use_stale" or "proxy_cache_revalidate" directives were
- used.
- Thanks to Piotr Sikora.
-
- *) Bugfix: a segmentation fault might occur in a worker process if
- errors with code 400 were redirected to a named location using the
- "error_page" directive.
-
- *) Bugfix: nginx/Windows could not be built with Visual Studio 2013.
-
-
-Changes with nginx 1.5.10 04 Feb 2014
-
- *) Feature: the ngx_http_spdy_module now uses SPDY 3.1 protocol.
- Thanks to Automattic and MaxCDN for sponsoring this work.
-
- *) Feature: the ngx_http_mp4_module now skips tracks too short for a
- seek requested.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- $ssl_session_id variable was used in logs; the bug had appeared in
- 1.5.9.
-
- *) Bugfix: the $date_local and $date_gmt variables used wrong format
- outside of the ngx_http_ssi_filter_module.
-
- *) Bugfix: client connections might be immediately closed if deferred
- accept was used; the bug had appeared in 1.3.15.
-
- *) Bugfix: alerts "getsockopt(TCP_FASTOPEN) ... failed" appeared in logs
- during binary upgrade on Linux; the bug had appeared in 1.5.8.
- Thanks to Piotr Sikora.
-
-
-Changes with nginx 1.5.9 22 Jan 2014
-
- *) Change: now nginx expects escaped URIs in "X-Accel-Redirect" headers.
-
- *) Feature: the "ssl_buffer_size" directive.
-
- *) Feature: the "limit_rate" directive can now be used to rate limit
- responses sent in SPDY connections.
-
- *) Feature: the "spdy_chunk_size" directive.
-
- *) Feature: the "ssl_session_tickets" directive.
- Thanks to Dirkjan Bussink.
-
- *) Bugfix: the $ssl_session_id variable contained full session
- serialized instead of just a session id.
- Thanks to Ivan Ristić.
-
- *) Bugfix: nginx incorrectly handled escaped "?" character in the
- "include" SSI command.
-
- *) Bugfix: the ngx_http_dav_module did not unescape destination URI of
- the COPY and MOVE methods.
-
- *) Bugfix: resolver did not understand domain names with a trailing dot.
- Thanks to Yichun Zhang.
-
- *) Bugfix: alerts "zero size buf in output" might appear in logs while
- proxying; the bug had appeared in 1.3.9.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- ngx_http_spdy_module was used.
-
- *) Bugfix: proxied WebSocket connections might hang right after
- handshake if the select, poll, or /dev/poll methods were used.
-
- *) Bugfix: the "xclient" directive of the mail proxy module incorrectly
- handled IPv6 client addresses.
-
-
-Changes with nginx 1.5.8 17 Dec 2013
-
- *) Feature: IPv6 support in resolver.
-
- *) Feature: the "listen" directive supports the "fastopen" parameter.
- Thanks to Mathew Rodley.
-
- *) Feature: SSL support in the ngx_http_uwsgi_module.
- Thanks to Roberto De Ioris.
-
- *) Feature: vim syntax highlighting scripts were added to contrib.
- Thanks to Evan Miller.
-
- *) Bugfix: a timeout might occur while reading client request body in an
- SSL connection using chunked transfer encoding.
-
- *) Bugfix: the "master_process" directive did not work correctly in
- nginx/Windows.
-
- *) Bugfix: the "setfib" parameter of the "listen" directive might not
- work.
-
- *) Bugfix: in the ngx_http_spdy_module.
-
-
-Changes with nginx 1.5.7 19 Nov 2013
-
- *) Security: a character following an unescaped space in a request line
- was handled incorrectly (CVE-2013-4547); the bug had appeared in
- 0.8.41.
- Thanks to Ivan Fratric of the Google Security Team.
-
- *) Change: a logging level of auth_basic errors about no user/password
- provided has been lowered from "error" to "info".
-
- *) Feature: the "proxy_cache_revalidate", "fastcgi_cache_revalidate",
- "scgi_cache_revalidate", and "uwsgi_cache_revalidate" directives.
-
- *) Feature: the "ssl_session_ticket_key" directive.
- Thanks to Piotr Sikora.
-
- *) Bugfix: the directive "add_header Cache-Control ''" added a
- "Cache-Control" response header line with an empty value.
-
- *) Bugfix: the "satisfy any" directive might return 403 error instead of
- 401 if auth_request and auth_basic directives were used.
- Thanks to Jan Marc Hoffmann.
-
- *) Bugfix: the "accept_filter" and "deferred" parameters of the "listen"
- directive were ignored for listen sockets created during binary
- upgrade.
- Thanks to Piotr Sikora.
-
- *) Bugfix: some data received from a backend with unbufferred proxy
- might not be sent to a client immediately if "gzip" or "gunzip"
- directives were used.
- Thanks to Yichun Zhang.
-
- *) Bugfix: in error handling in ngx_http_gunzip_filter_module.
-
- *) Bugfix: responses might hang if the ngx_http_spdy_module was used
- with the "auth_request" directive.
-
- *) Bugfix: memory leak in nginx/Windows.
-
-
-Changes with nginx 1.5.6 01 Oct 2013
-
- *) Feature: the "fastcgi_buffering" directive.
-
- *) Feature: the "proxy_ssl_protocols" and "proxy_ssl_ciphers"
- directives.
- Thanks to Piotr Sikora.
-
- *) Feature: optimization of SSL handshakes when using long certificate
- chains.
-
- *) Feature: the mail proxy supports SMTP pipelining.
-
- *) Bugfix: in the ngx_http_auth_basic_module when using "$apr1$"
- password encryption method.
- Thanks to Markus Linnala.
-
- *) Bugfix: in MacOSX, Cygwin, and nginx/Windows incorrect location might
- be used to process a request if locations were given using characters
- in different cases.
-
- *) Bugfix: automatic redirect with appended trailing slash for proxied
- locations might not work.
-
- *) Bugfix: in the mail proxy server.
-
- *) Bugfix: in the ngx_http_spdy_module.
-
-
-Changes with nginx 1.5.5 17 Sep 2013
-
- *) Change: now nginx assumes HTTP/1.0 by default if it is not able to
- detect protocol reliably.
-
- *) Feature: the "disable_symlinks" directive now uses O_PATH on Linux.
-
- *) Feature: now nginx uses EPOLLRDHUP events to detect premature
- connection close by clients if the "epoll" method is used.
-
- *) Bugfix: in the "valid_referers" directive if the "server_names"
- parameter was used.
-
- *) Bugfix: the $request_time variable did not work in nginx/Windows.
-
- *) Bugfix: in the "image_filter" directive.
- Thanks to Lanshun Zhou.
-
- *) Bugfix: OpenSSL 1.0.1f compatibility.
- Thanks to Piotr Sikora.
-
-
-Changes with nginx 1.5.4 27 Aug 2013
-
- *) Change: the "js" extension MIME type has been changed to
- "application/javascript"; default value of the "charset_types"
- directive was changed accordingly.
-
- *) Change: now the "image_filter" directive with the "size" parameter
- returns responses with the "application/json" MIME type.
-
- *) Feature: the ngx_http_auth_request_module.
-
- *) Bugfix: a segmentation fault might occur on start or during
- reconfiguration if the "try_files" directive was used with an empty
- parameter.
-
- *) Bugfix: memory leak if relative paths were specified using variables
- in the "root" or "auth_basic_user_file" directives.
-
- *) Bugfix: the "valid_referers" directive incorrectly executed regular
- expressions if a "Referer" header started with "https://".
- Thanks to Liangbin Li.
-
- *) Bugfix: responses might hang if subrequests were used and an SSL
- handshake error happened during subrequest processing.
- Thanks to Aviram Cohen.
-
- *) Bugfix: in the ngx_http_autoindex_module.
-
- *) Bugfix: in the ngx_http_spdy_module.
-
-
-Changes with nginx 1.5.3 30 Jul 2013
-
- *) Change in internal API: now u->length defaults to -1 if working with
- backends in unbuffered mode.
-
- *) Change: now after receiving an incomplete response from a backend
- server nginx tries to send an available part of the response to a
- client, and then closes client connection.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- ngx_http_spdy_module was used with the "client_body_in_file_only"
- directive.
-
- *) Bugfix: the "so_keepalive" parameter of the "listen" directive might
- be handled incorrectly on DragonFlyBSD.
- Thanks to Sepherosa Ziehau.
-
- *) Bugfix: in the ngx_http_xslt_filter_module.
-
- *) Bugfix: in the ngx_http_sub_filter_module.
-
-
-Changes with nginx 1.5.2 02 Jul 2013
-
- *) Feature: now several "error_log" directives can be used.
-
- *) Bugfix: the $r->header_in() embedded perl method did not return value
- of the "Cookie" and "X-Forwarded-For" request header lines; the bug
- had appeared in 1.3.14.
-
- *) Bugfix: in the ngx_http_spdy_module.
- Thanks to Jim Radford.
-
- *) Bugfix: nginx could not be built on Linux with x32 ABI.
- Thanks to Serguei Ivantsov.
-
-
-Changes with nginx 1.5.1 04 Jun 2013
-
- *) Feature: the "ssi_last_modified", "sub_filter_last_modified", and
- "xslt_last_modified" directives.
- Thanks to Alexey Kolpakov.
-
- *) Feature: the "http_403" parameter of the "proxy_next_upstream",
- "fastcgi_next_upstream", "scgi_next_upstream", and
- "uwsgi_next_upstream" directives.
-
- *) Feature: the "allow" and "deny" directives now support unix domain
- sockets.
-
- *) Bugfix: nginx could not be built with the ngx_mail_ssl_module, but
- without ngx_http_ssl_module; the bug had appeared in 1.3.14.
-
- *) Bugfix: in the "proxy_set_body" directive.
- Thanks to Lanshun Zhou.
-
- *) Bugfix: in the "lingering_time" directive.
- Thanks to Lanshun Zhou.
-
- *) Bugfix: the "fail_timeout" parameter of the "server" directive in the
- "upstream" context might not work if "max_fails" parameter was used;
- the bug had appeared in 1.3.0.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- "ssl_stapling" directive was used.
- Thanks to Piotr Sikora.
-
- *) Bugfix: in the mail proxy server.
- Thanks to Filipe Da Silva.
-
- *) Bugfix: nginx/Windows might stop accepting connections if several
- worker processes were used.
-
-
-Changes with nginx 1.5.0 07 May 2013
-
- *) Security: a stack-based buffer overflow might occur in a worker
- process while handling a specially crafted request, potentially
- resulting in arbitrary code execution (CVE-2013-2028); the bug had
- appeared in 1.3.9.
- Thanks to Greg MacManus, iSIGHT Partners Labs.
-
-
-Changes with nginx 1.4.0 24 Apr 2013
-
- *) Bugfix: nginx could not be built with the ngx_http_perl_module if the
- --with-openssl option was used; the bug had appeared in 1.3.16.
-
- *) Bugfix: in a request body handling in the ngx_http_perl_module; the
- bug had appeared in 1.3.9.
-
-
-Changes with nginx 1.3.16 16 Apr 2013
-
- *) Bugfix: a segmentation fault might occur in a worker process if
- subrequests were used; the bug had appeared in 1.3.9.
-
- *) Bugfix: the "tcp_nodelay" directive caused an error if a WebSocket
- connection was proxied into a unix domain socket.
-
- *) Bugfix: the $upstream_response_length variable has an incorrect value
- "0" if buffering was not used.
- Thanks to Piotr Sikora.
-
- *) Bugfix: in the eventport and /dev/poll methods.
-
-
-Changes with nginx 1.3.15 26 Mar 2013
-
- *) Change: opening and closing a connection without sending any data in
- it is no longer logged to access_log with error code 400.
-
- *) Feature: the ngx_http_spdy_module.
- Thanks to Automattic for sponsoring this work.
-
- *) Feature: the "limit_req_status" and "limit_conn_status" directives.
- Thanks to Nick Marden.
-
- *) Feature: the "image_filter_interlace" directive.
- Thanks to Ian Babrou.
-
- *) Feature: $connections_waiting variable in the
- ngx_http_stub_status_module.
-
- *) Feature: the mail proxy module now supports IPv6 backends.
-
- *) Bugfix: request body might be transmitted incorrectly when retrying a
- request to the next upstream server; the bug had appeared in 1.3.9.
- Thanks to Piotr Sikora.
-
- *) Bugfix: in the "client_body_in_file_only" directive; the bug had
- appeared in 1.3.9.
-
- *) Bugfix: responses might hang if subrequests were used and a DNS error
- happened during subrequest processing.
- Thanks to Lanshun Zhou.
-
- *) Bugfix: in backend usage accounting.
-
-
-Changes with nginx 1.3.14 05 Mar 2013
-
- *) Feature: $connections_active, $connections_reading, and
- $connections_writing variables in the ngx_http_stub_status_module.
-
- *) Feature: support of WebSocket connections in the
- ngx_http_uwsgi_module and ngx_http_scgi_module.
-
- *) Bugfix: in virtual servers handling with SNI.
-
- *) Bugfix: new sessions were not always stored if the "ssl_session_cache
- shared" directive was used and there was no free space in shared
- memory.
- Thanks to Piotr Sikora.
-
- *) Bugfix: multiple X-Forwarded-For headers were handled incorrectly.
- Thanks to Neal Poole for sponsoring this work.
-
- *) Bugfix: in the ngx_http_mp4_module.
- Thanks to Gernot Vormayr.
-
-
-Changes with nginx 1.3.13 19 Feb 2013
-
- *) Change: a compiler with name "cc" is now used by default.
-
- *) Feature: support for proxying of WebSocket connections.
- Thanks to Apcera and CloudBees for sponsoring this work.
-
- *) Feature: the "auth_basic_user_file" directive supports "{SHA}"
- password encryption method.
- Thanks to Louis Opter.
-
-
-Changes with nginx 1.3.12 05 Feb 2013
-
- *) Feature: variables support in the "proxy_bind", "fastcgi_bind",
- "memcached_bind", "scgi_bind", and "uwsgi_bind" directives.
-
- *) Feature: the $pipe, $request_length, $time_iso8601, and $time_local
- variables can now be used not only in the "log_format" directive.
- Thanks to Kiril Kalchev.
-
- *) Feature: IPv6 support in the ngx_http_geoip_module.
- Thanks to Gregor Kališnik.
-
- *) Bugfix: in the "proxy_method" directive.
-
- *) Bugfix: a segmentation fault might occur in a worker process if
- resolver was used with the poll method.
-
- *) Bugfix: nginx might hog CPU during SSL handshake with a backend if
- the select, poll, or /dev/poll methods were used.
-
- *) Bugfix: the "[crit] SSL_write() failed (SSL:)" error.
-
- *) Bugfix: in the "client_body_in_file_only" directive; the bug had
- appeared in 1.3.9.
-
- *) Bugfix: in the "fastcgi_keep_conn" directive.
-
-
-Changes with nginx 1.3.11 10 Jan 2013
-
- *) Bugfix: a segmentation fault might occur if logging was used; the bug
- had appeared in 1.3.10.
-
- *) Bugfix: the "proxy_pass" directive did not work with IP addresses
- without port specified; the bug had appeared in 1.3.10.
-
- *) Bugfix: a segmentation fault occurred on start or during
- reconfiguration if the "keepalive" directive was specified more than
- once in a single upstream block.
-
- *) Bugfix: parameter "default" of the "geo" directive did not set
- default value for IPv6 addresses.
-
-
-Changes with nginx 1.3.10 25 Dec 2012
-
- *) Change: domain names specified in configuration file are now resolved
- to IPv6 addresses as well as IPv4 ones.
-
- *) Change: now if the "include" directive with mask is used on Unix
- systems, included files are sorted in alphabetical order.
-
- *) Change: the "add_header" directive adds headers to 201 responses.
-
- *) Feature: the "geo" directive now supports IPv6 addresses in CIDR
- notation.
-
- *) Feature: the "flush" and "gzip" parameters of the "access_log"
- directive.
-
- *) Feature: variables support in the "auth_basic" directive.
-
- *) Bugfix: nginx could not be built with the ngx_http_perl_module in
- some cases.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- ngx_http_xslt_module was used.
-
- *) Bugfix: nginx could not be built on MacOSX in some cases.
- Thanks to Piotr Sikora.
-
- *) Bugfix: the "limit_rate" directive with high rates might result in
- truncated responses on 32-bit platforms.
- Thanks to Alexey Antropov.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- "if" directive was used.
- Thanks to Piotr Sikora.
-
- *) Bugfix: a "100 Continue" response was issued with "413 Request Entity
- Too Large" responses.
-
- *) Bugfix: the "image_filter", "image_filter_jpeg_quality" and
- "image_filter_sharpen" directives might be inherited incorrectly.
- Thanks to Ian Babrou.
-
- *) Bugfix: "crypt_r() failed" errors might appear if the "auth_basic"
- directive was used on Linux.
-
- *) Bugfix: in backup servers handling.
- Thanks to Thomas Chen.
-
- *) Bugfix: proxied HEAD requests might return incorrect response if the
- "gzip" directive was used.
-
-
-Changes with nginx 1.3.9 27 Nov 2012
-
- *) Feature: support for chunked transfer encoding while reading client
- request body.
-
- *) Feature: the $request_time and $msec variables can now be used not
- only in the "log_format" directive.
-
- *) Bugfix: cache manager and cache loader processes might not be able to
- start if more than 512 listen sockets were used.
-
- *) Bugfix: in the ngx_http_dav_module.
-
-
-Changes with nginx 1.3.8 30 Oct 2012
-
- *) Feature: the "optional_no_ca" parameter of the "ssl_verify_client"
- directive.
- Thanks to Mike Kazantsev and Eric O'Connor.
-
- *) Feature: the $bytes_sent, $connection, and $connection_requests
- variables can now be used not only in the "log_format" directive.
- Thanks to Benjamin Grössing.
-
- *) Feature: the "auto" parameter of the "worker_processes" directive.
-
- *) Bugfix: "cache file ... has md5 collision" alert.
-
- *) Bugfix: in the ngx_http_gunzip_filter_module.
-
- *) Bugfix: in the "ssl_stapling" directive.
-
-
-Changes with nginx 1.3.7 02 Oct 2012
-
- *) Feature: OCSP stapling support.
- Thanks to Comodo, DigiCert and GlobalSign for sponsoring this work.
-
- *) Feature: the "ssl_trusted_certificate" directive.
-
- *) Feature: resolver now randomly rotates addresses returned from cache.
- Thanks to Anton Jouline.
-
- *) Bugfix: OpenSSL 0.9.7 compatibility.
-
-
-Changes with nginx 1.3.6 12 Sep 2012
-
- *) Feature: the ngx_http_gunzip_filter_module.
-
- *) Feature: the "memcached_gzip_flag" directive.
-
- *) Feature: the "always" parameter of the "gzip_static" directive.
-
- *) Bugfix: in the "limit_req" directive; the bug had appeared in 1.1.14.
- Thanks to Charles Chen.
-
- *) Bugfix: nginx could not be built by gcc 4.7 with -O2 optimization if
- the --with-ipv6 option was used.
-
-
-Changes with nginx 1.3.5 21 Aug 2012
-
- *) Change: the ngx_http_mp4_module module no longer skips tracks in
- formats other than H.264 and AAC.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- "map" directive was used with variables as values.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- "geo" directive was used with the "ranges" parameter but without the
- "default" parameter; the bug had appeared in 0.8.43.
- Thanks to Zhen Chen and Weibin Yao.
-
- *) Bugfix: in the -p command-line parameter handling.
-
- *) Bugfix: in the mail proxy server.
-
- *) Bugfix: of minor potential bugs.
- Thanks to Coverity.
-
- *) Bugfix: nginx/Windows could not be built with Visual Studio 2005
- Express.
- Thanks to HAYASHI Kentaro.
-
-
-Changes with nginx 1.3.4 31 Jul 2012
-
- *) Change: the "ipv6only" parameter is now turned on by default for
- listening IPv6 sockets.
-
- *) Feature: the Clang compiler support.
-
- *) Bugfix: extra listening sockets might be created.
- Thanks to Roman Odaisky.
-
- *) Bugfix: nginx/Windows might hog CPU if a worker process failed to
- start.
- Thanks to Ricardo Villalobos Guevara.
-
- *) Bugfix: the "proxy_pass_header", "fastcgi_pass_header",
- "scgi_pass_header", "uwsgi_pass_header", "proxy_hide_header",
- "fastcgi_hide_header", "scgi_hide_header", and "uwsgi_hide_header"
- directives might be inherited incorrectly.
-
-
-Changes with nginx 1.3.3 10 Jul 2012
-
- *) Feature: entity tags support and the "etag" directive.
-
- *) Bugfix: trailing dot in a source value was not ignored if the "map"
- directive was used with the "hostnames" parameter.
-
- *) Bugfix: incorrect location might be used to process a request if a
- URI was changed via a "rewrite" directive before an internal redirect
- to a named location.
-
-
-Changes with nginx 1.3.2 26 Jun 2012
-
- *) Change: the "single" parameter of the "keepalive" directive is now
- ignored.
-
- *) Change: SSL compression is now disabled when using all versions of
- OpenSSL, including ones prior to 1.0.0.
-
- *) Feature: it is now possible to use the "ip_hash" directive to balance
- IPv6 clients.
-
- *) Feature: the $status variable can now be used not only in the
- "log_format" directive.
-
- *) Bugfix: a segmentation fault might occur in a worker process on
- shutdown if the "resolver" directive was used.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- ngx_http_mp4_module was used.
-
- *) Bugfix: in the ngx_http_mp4_module.
-
- *) Bugfix: a segmentation fault might occur in a worker process if
- conflicting wildcard server names were used.
-
- *) Bugfix: nginx might be terminated abnormally on a SIGBUS signal on
- ARM platform.
-
- *) Bugfix: an alert "sendmsg() failed (9: Bad file number)" on HP-UX
- while reconfiguration.
-
-
-Changes with nginx 1.3.1 05 Jun 2012
-
- *) Security: now nginx/Windows ignores trailing dot in URI path
- component, and does not allow URIs with ":$" in it.
- Thanks to Vladimir Kochetkov, Positive Research Center.
-
- *) Feature: the "proxy_pass", "fastcgi_pass", "scgi_pass", "uwsgi_pass"
- directives, and the "server" directive inside the "upstream" block,
- now support IPv6 addresses.
-
- *) Feature: the "resolver" directive now supports IPv6 addresses and an
- optional port specification.
-
- *) Feature: the "least_conn" directive inside the "upstream" block.
-
- *) Feature: it is now possible to specify a weight for servers while
- using the "ip_hash" directive.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- "image_filter" directive was used; the bug had appeared in 1.3.0.
-
- *) Bugfix: nginx could not be built with ngx_cpp_test_module; the bug
- had appeared in 1.1.12.
-
- *) Bugfix: access to variables from SSI and embedded perl module might
- not work after reconfiguration.
- Thanks to Yichun Zhang.
-
- *) Bugfix: in the ngx_http_xslt_filter_module.
- Thanks to Kuramoto Eiji.
-
- *) Bugfix: memory leak if $geoip_org variable was used.
- Thanks to Denis F. Latypoff.
-
- *) Bugfix: in the "proxy_cookie_domain" and "proxy_cookie_path"
- directives.
-
-
-Changes with nginx 1.3.0 15 May 2012
-
- *) Feature: the "debug_connection" directive now supports IPv6 addresses
- and the "unix:" parameter.
-
- *) Feature: the "set_real_ip_from" directive and the "proxy" parameter
- of the "geo" directive now support IPv6 addresses.
-
- *) Feature: the "real_ip_recursive", "geoip_proxy", and
- "geoip_proxy_recursive" directives.
-
- *) Feature: the "proxy_recursive" parameter of the "geo" directive.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- "resolver" directive was used.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- "fastcgi_pass", "scgi_pass", or "uwsgi_pass" directives were used and
- backend returned incorrect response.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- "rewrite" directive was used and new request arguments in a
- replacement used variables.
-
- *) Bugfix: nginx might hog CPU if the open file resource limit was
- reached.
-
- *) Bugfix: nginx might loop infinitely over backends if the
- "proxy_next_upstream" directive with the "http_404" parameter was
- used and there were backup servers specified in an upstream block.
-
- *) Bugfix: adding the "down" parameter of the "server" directive might
- cause unneeded client redistribution among backend servers if the
- "ip_hash" directive was used.
-
- *) Bugfix: socket leak.
- Thanks to Yichun Zhang.
-
- *) Bugfix: in the ngx_http_fastcgi_module.
-
-
-Changes with nginx 1.2.0 23 Apr 2012
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- "try_files" directive was used; the bug had appeared in 1.1.19.
-
- *) Bugfix: response might be truncated if there were more than IOV_MAX
- buffers used.
-
- *) Bugfix: in the "crop" parameter of the "image_filter" directive.
- Thanks to Maxim Bublis.
-
-
-Changes with nginx 1.1.19 12 Apr 2012
-
- *) Security: specially crafted mp4 file might allow to overwrite memory
- locations in a worker process if the ngx_http_mp4_module was used,
- potentially resulting in arbitrary code execution (CVE-2012-2089).
- Thanks to Matthew Daley.
-
- *) Bugfix: nginx/Windows might be terminated abnormally.
- Thanks to Vincent Lee.
-
- *) Bugfix: nginx hogged CPU if all servers in an upstream were marked as
- "backup".
-
- *) Bugfix: the "allow" and "deny" directives might be inherited
- incorrectly if they were used with IPv6 addresses.
-
- *) Bugfix: the "modern_browser" and "ancient_browser" directives might
- be inherited incorrectly.
-
- *) Bugfix: timeouts might be handled incorrectly on Solaris/SPARC.
-
- *) Bugfix: in the ngx_http_mp4_module.
-
-
-Changes with nginx 1.1.18 28 Mar 2012
-
- *) Change: keepalive connections are no longer disabled for Safari by
- default.
-
- *) Feature: the $connection_requests variable.
-
- *) Feature: $tcpinfo_rtt, $tcpinfo_rttvar, $tcpinfo_snd_cwnd and
- $tcpinfo_rcv_space variables.
-
- *) Feature: the "worker_cpu_affinity" directive now works on FreeBSD.
-
- *) Feature: the "xslt_param" and "xslt_string_param" directives.
- Thanks to Samuel Behan.
-
- *) Bugfix: in configure tests.
- Thanks to Piotr Sikora.
-
- *) Bugfix: in the ngx_http_xslt_filter_module.
-
- *) Bugfix: nginx could not be built on Debian GNU/Hurd.
-
-
-Changes with nginx 1.1.17 15 Mar 2012
-
- *) Security: content of previously freed memory might be sent to a
- client if backend returned specially crafted response.
- Thanks to Matthew Daley.
-
- *) Bugfix: in the embedded perl module if used from SSI.
- Thanks to Matthew Daley.
-
- *) Bugfix: in the ngx_http_uwsgi_module.
-
-
-Changes with nginx 1.1.16 29 Feb 2012
-
- *) Change: the simultaneous subrequest limit has been raised to 200.
-
- *) Feature: the "from" parameter of the "disable_symlinks" directive.
-
- *) Feature: the "return" and "error_page" directives can now be used to
- return 307 redirections.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- "resolver" directive was used and there was no "error_log" directive
- specified at global level.
- Thanks to Roman Arutyunyan.
-
- *) Bugfix: a segmentation fault might occur in a worker process if the
- "proxy_http_version 1.1" or "fastcgi_keep_conn on" directives were
- used.
-
- *) Bugfix: memory leaks.
- Thanks to Lanshun Zhou.
-
- *) Bugfix: in the "disable_symlinks" directive.
-
- *) Bugfix: on ZFS filesystem disk cache size might be calculated
- incorrectly; the bug had appeared in 1.0.1.
-
- *) Bugfix: nginx could not be built by the icc 12.1 compiler.
-
- *) Bugfix: nginx could not be built by gcc on Solaris; the bug had
- appeared in 1.1.15.
-
-
-Changes with nginx 1.1.15 15 Feb 2012
-
- *) Feature: the "disable_symlinks" directive.
-
- *) Feature: the "proxy_cookie_domain" and "proxy_cookie_path"
- directives.
-
- *) Bugfix: nginx might log incorrect error "upstream prematurely closed
- connection" instead of correct "upstream sent too big header" one.
- Thanks to Feibo Li.
-
- *) Bugfix: nginx could not be built with the ngx_http_perl_module if the
- --with-openssl option was used.
-
- *) Bugfix: the number of internal redirects to named locations was not
- limited.
-
- *) Bugfix: calling $r->flush() multiple times might cause errors in the
- ngx_http_gzip_filter_module.
-
- *) Bugfix: temporary files might be not removed if the "proxy_store"
- directive was used with SSI includes.
-
- *) Bugfix: in some cases non-cacheable variables (such as the $args
- variable) returned old empty cached value.
-
- *) Bugfix: a segmentation fault might occur in a worker process if too
- many SSI subrequests were issued simultaneously; the bug had appeared
- in 0.7.25.
-
-
-Changes with nginx 1.1.14 30 Jan 2012
-
- *) Feature: multiple "limit_req" limits may be used simultaneously.
-
- *) Bugfix: in error handling while connecting to a backend.
- Thanks to Piotr Sikora.
-
- *) Bugfix: in AIO error handling on FreeBSD.
-
- *) Bugfix: in the OpenSSL library initialization.
-
- *) Bugfix: the "proxy_redirect" directives might be inherited
- incorrectly.
-
- *) Bugfix: memory leak during reconfiguration if the "pcre_jit"
- directive was used.
-
-
-Changes with nginx 1.1.13 16 Jan 2012
-
- *) Feature: the "TLSv1.1" and "TLSv1.2" parameters of the
- "ssl_protocols" directive.
-
- *) Bugfix: the "limit_req" directive parameters were not inherited
- correctly; the bug had appeared in 1.1.12.
-
- *) Bugfix: the "proxy_redirect" directive incorrectly processed
- "Refresh" header if regular expression were used.
-
- *) Bugfix: the "proxy_cache_use_stale" directive with "error" parameter
- did not return answer from cache if there were no live upstreams.
-
- *) Bugfix: the "worker_cpu_affinity" directive might not work.
-
- *) Bugfix: nginx could not be built on Solaris; the bug had appeared in
- 1.1.12.
-
- *) Bugfix: in the ngx_http_mp4_module.
-
-
-Changes with nginx 1.1.12 26 Dec 2011
-
- *) Change: a "proxy_pass" directive without URI part now uses changed
- URI after redirection with the "error_page" directive.
- Thanks to Lanshun Zhou.
-
- *) Feature: the "proxy/fastcgi/scgi/uwsgi_cache_lock",
- "proxy/fastcgi/scgi/uwsgi_cache_lock_timeout" directives.
-
- *) Feature: the "pcre_jit" directive.
-
- *) Feature: the "if" SSI command supports captures in regular
- expressions.
-
- *) Bugfix: the "if" SSI command did not work inside the "block" command.
-
- *) Bugfix: the "limit_conn_log_level" and "limit_req_log_level"
- directives might not work.
-
- *) Bugfix: the "limit_rate" directive did not allow to use full
- throughput, even if limit value was very high.
-
- *) Bugfix: the "sendfile_max_chunk" directive did not work, if the
- "limit_rate" directive was used.
-
- *) Bugfix: a "proxy_pass" directive without URI part always used
- original request URI if variables were used.
-
- *) Bugfix: a "proxy_pass" directive without URI part might use original
- request after redirection with the "try_files" directive.
- Thanks to Lanshun Zhou.
-
- *) Bugfix: in the ngx_http_scgi_module.
-
- *) Bugfix: in the ngx_http_mp4_module.
-
- *) Bugfix: nginx could not be built on Solaris; the bug had appeared in
- 1.1.9.
-
-
-Changes with nginx 1.1.11 12 Dec 2011
-
- *) Feature: the "so_keepalive" parameter of the "listen" directive.
- Thanks to Vsevolod Stakhov.
-
- *) Feature: the "if_not_empty" parameter of the
- "fastcgi/scgi/uwsgi_param" directives.
-
- *) Feature: the $https variable.
-
- *) Feature: the "proxy_redirect" directive supports variables in the
- first parameter.
-
- *) Feature: the "proxy_redirect" directive supports regular expressions.
-
- *) Bugfix: the $sent_http_cache_control variable might contain a wrong
- value if the "expires" directive was used.
- Thanks to Yichun Zhang.
-
- *) Bugfix: the "read_ahead" directive might not work combined with
- "try_files" and "open_file_cache".
-
- *) Bugfix: a segmentation fault might occur in a worker process if small
- time was used in the "inactive" parameter of the "proxy_cache_path"
- directive.
-
- *) Bugfix: responses from cache might hang.
-
-
-Changes with nginx 1.1.10 30 Nov 2011
-
- *) Bugfix: a segmentation fault occured in a worker process if AIO was
- used on Linux; the bug had appeared in 1.1.9.
-
-
-Changes with nginx 1.1.9 28 Nov 2011
-
- *) Change: now double quotes are encoded in an "echo" SSI-command
- output.
- Thanks to Zaur Abasmirzoev.
-
- *) Feature: the "valid" parameter of the "resolver" directive. By
- default TTL returned by a DNS server is used.
- Thanks to Kirill A. Korinskiy.
-
- *) Bugfix: nginx might hang after a worker process abnormal termination.
-
- *) Bugfix: a segmentation fault might occur in a worker process if SNI
- was used; the bug had appeared in 1.1.2.
-
- *) Bugfix: in the "keepalive_disable" directive; the bug had appeared in
- 1.1.8.
- Thanks to Alexander Usov.
-
- *) Bugfix: SIGWINCH signal did not work after first binary upgrade; the
- bug had appeared in 1.1.1.
-
- *) Bugfix: backend responses with length not matching "Content-Length"
- header line are no longer cached.
-
- *) Bugfix: in the "scgi_param" directive, if complex parameters were
- used.
-
- *) Bugfix: in the "epoll" event method.
- Thanks to Yichun Zhang.
-
- *) Bugfix: in the ngx_http_flv_module.
- Thanks to Piotr Sikora.
-
- *) Bugfix: in the ngx_http_mp4_module.
-
- *) Bugfix: IPv6 addresses are now handled properly in a request line and
- in a "Host" request header line.
-
- *) Bugfix: "add_header" and "expires" directives did not work if a
- request was proxied and response status code was 206.
-
- *) Bugfix: nginx could not be built on FreeBSD 10.
-
- *) Bugfix: nginx could not be built on AIX.
-
-
-Changes with nginx 1.1.8 14 Nov 2011
-
- *) Change: the ngx_http_limit_zone_module was renamed to the
- ngx_http_limit_conn_module.
-
- *) Change: the "limit_zone" directive was superseded by the
- "limit_conn_zone" directive with a new syntax.
-
- *) Feature: support for multiple "limit_conn" limits on the same level.
-
- *) Feature: the "image_filter_sharpen" directive.
-
- *) Bugfix: a segmentation fault might occur in a worker process if
- resolver got a big DNS response.
- Thanks to Ben Hawkes.
-
- *) Bugfix: in cache key calculation if internal MD5 implementation was
- used; the bug had appeared in 1.0.4.
-
- *) Bugfix: the "If-Modified-Since", "If-Range", etc. client request
- header lines might be passed to backend while caching; or not passed
- without caching if caching was enabled in another part of the
- configuration.
-
- *) Bugfix: the module ngx_http_mp4_module sent incorrect
- "Content-Length" response header line if the "start" argument was
- used.
- Thanks to Piotr Sikora.
-
-
-Changes with nginx 1.1.7 31 Oct 2011
-
- *) Feature: support of several DNS servers in the "resolver" directive.
- Thanks to Kirill A. Korinskiy.
-
- *) Bugfix: a segmentation fault occurred on start or during
- reconfiguration if the "ssl" directive was used at http level and
- there was no "ssl_certificate" defined.
-
- *) Bugfix: reduced memory consumption while proxying big files if they
- were buffered to disk.
-
- *) Bugfix: a segmentation fault might occur in a worker process if
- "proxy_http_version 1.1" directive was used.
-
- *) Bugfix: in the "expires @time" directive.
-
-
-Changes with nginx 1.1.6 17 Oct 2011
-
- *) Change in internal API: now module context data are cleared while
- internal redirect to named location.
- Requested by Yichun Zhang.
-
- *) Change: if a server in an upstream failed, only one request will be
- sent to it after fail_timeout; the server will be considered alive if
- it will successfully respond to the request.
-
- *) Change: now the 0x7F-0x1F characters are escaped as \xXX in an
- access_log.
-
- *) Feature: "proxy/fastcgi/scgi/uwsgi_ignore_headers" directives support
- the following additional values: X-Accel-Limit-Rate,
- X-Accel-Buffering, X-Accel-Charset.
-
- *) Feature: decrease of memory consumption if SSL is used.
-
- *) Bugfix: some UTF-8 characters were processed incorrectly.
- Thanks to Alexey Kuts.
-
- *) Bugfix: the ngx_http_rewrite_module directives specified at "server"
- level were executed twice if no matching locations were defined.
-
- *) Bugfix: a socket leak might occurred if "aio sendfile" was used.
-
- *) Bugfix: connections with fast clients might be closed after
- send_timeout if file AIO was used.
-
- *) Bugfix: in the ngx_http_autoindex_module.
-
- *) Bugfix: the module ngx_http_mp4_module did not support seeking on
- 32-bit platforms.
-
-
-Changes with nginx 1.1.5 05 Oct 2011
-
- *) Feature: the "uwsgi_buffering" and "scgi_buffering" directives.
- Thanks to Peter Smit.
-
- *) Bugfix: non-cacheable responses might be cached if
- "proxy_cache_bypass" directive was used.
- Thanks to John Ferlito.
-
- *) Bugfix: in HTTP/1.1 support in the ngx_http_proxy_module.
-
- *) Bugfix: cached responses with an empty body were returned
- incorrectly; the bug had appeared in 0.8.31.
-
- *) Bugfix: 201 responses of the ngx_http_dav_module were incorrect; the
- bug had appeared in 0.8.32.
-
- *) Bugfix: in the "return" directive.
-
- *) Bugfix: the "ssl_session_cache builtin" directive caused segmentation
- fault; the bug had appeared in 1.1.1.
-
-
-Changes with nginx 1.1.4 20 Sep 2011
-
- *) Feature: the ngx_http_upstream_keepalive module.
-
- *) Feature: the "proxy_http_version" directive.
-
- *) Feature: the "fastcgi_keep_conn" directive.
-
- *) Feature: the "worker_aio_requests" directive.
-
- *) Bugfix: if nginx was built --with-file-aio it could not be run on
- Linux kernel which did not support AIO.
-
- *) Bugfix: in Linux AIO error processing.
- Thanks to Hagai Avrahami.
-
- *) Bugfix: reduced memory consumption for long-lived requests.
-
- *) Bugfix: the module ngx_http_mp4_module did not support 64-bit MP4
- "co64" atom.
-
-
-Changes with nginx 1.1.3 14 Sep 2011
-
- *) Feature: the module ngx_http_mp4_module.
-
- *) Bugfix: in Linux AIO combined with open_file_cache.
-
- *) Bugfix: open_file_cache did not update file info on retest if file
- was not atomically changed.
-
- *) Bugfix: nginx could not be built on MacOSX 10.7.
-
-
-Changes with nginx 1.1.2 05 Sep 2011
-
- *) Change: now if total size of all ranges is greater than source
- response size, then nginx disables ranges and returns just the source
- response.
-
- *) Feature: the "max_ranges" directive.
-
- *) Bugfix: the "ssl_verify_client", "ssl_verify_depth", and
- "ssl_prefer_server_ciphers" directives might work incorrectly if SNI
- was used.
-
- *) Bugfix: in the "proxy/fastcgi/scgi/uwsgi_ignore_client_abort"
- directives.
-
-
-Changes with nginx 1.1.1 22 Aug 2011
-
- *) Change: now cache loader processes either as many files as specified
- by "loader_files" parameter or works no longer than time specified by
- the "loader_threshold" parameter during each iteration.
-
- *) Change: now SIGWINCH signal works only in daemon mode.
-
- *) Feature: now shared zones and caches use POSIX semaphores on Solaris.
- Thanks to Den Ivanov.
-
- *) Feature: accept filters are now supported on NetBSD.
-
- *) Bugfix: nginx could not be built on Linux 3.0.
-
- *) Bugfix: nginx did not use gzipping in some cases; the bug had
- appeared in 1.1.0.
-
- *) Bugfix: request body might be processed incorrectly if client used
- pipelining.
-
- *) Bugfix: in the "request_body_in_single_buf" directive.
-
- *) Bugfix: in "proxy_set_body" and "proxy_pass_request_body" directives
- if SSL connection to backend was used.
-
- *) Bugfix: nginx hogged CPU if all servers in an upstream were marked as
- "down".
-
- *) Bugfix: a segmentation fault might occur during reconfiguration if
- ssl_session_cache was defined but not used in previous configuration.
-
- *) Bugfix: a segmentation fault might occur in a worker process if many
- backup servers were used in an upstream.
-
- *) Bugfix: a segmentation fault might occur in a worker process if
- "fastcgi/scgi/uwsgi_param" directives were used with values starting
- with "HTTP_"; the bug had appeared in 0.8.40.
-
-
-Changes with nginx 1.1.0 01 Aug 2011
-
- *) Feature: cache loader run time decrease.
-
- *) Feature: "loader_files", "loader_sleep", and "loader_threshold"
- options of the "proxy/fastcgi/scgi/uwsgi_cache_path" directives.
-
- *) Feature: loading time decrease of configuration with large number of
- HTTPS sites.
-
- *) Feature: now nginx supports ECDHE key exchange ciphers.
- Thanks to Adrian Kotelba.
-
- *) Feature: the "lingering_close" directive.
- Thanks to Maxim Dounin.
-
- *) Bugfix: in closing connection for pipelined requests.
- Thanks to Maxim Dounin.
-
- *) Bugfix: nginx did not disable gzipping if client sent "gzip;q=0" in
- "Accept-Encoding" request header line.
-
- *) Bugfix: in timeout in unbuffered proxied mode.
- Thanks to Maxim Dounin.
-
- *) Bugfix: memory leaks when a "proxy_pass" directive contains variables
- and proxies to an HTTPS backend.
- Thanks to Maxim Dounin.
-
- *) Bugfix: in parameter validaiton of a "proxy_pass" directive with
- variables.
- Thanks to Lanshun Zhou.
-
- *) Bugfix: SSL did not work on QNX.
- Thanks to Maxim Dounin.
-
- *) Bugfix: SSL modules could not be built by gcc 4.6 without
- --with-debug option.
-
-
-Changes with nginx 1.0.5 19 Jul 2011
-
- *) Change: now default SSL ciphers are "HIGH:!aNULL:!MD5".
- Thanks to Rob Stradling.
-
- *) Feature: the "referer_hash_max_size" and "referer_hash_bucket_size"
- directives.
- Thanks to Witold Filipczyk.
-
- *) Feature: $uid_reset variable.
-
- *) Bugfix: a segmentation fault might occur in a worker process, if a
- caching was used.
- Thanks to Lanshun Zhou.
-
- *) Bugfix: worker processes may got caught in an endless loop during
- reconfiguration, if a caching was used; the bug had appeared in
- 0.8.48.
- Thanks to Maxim Dounin.
-
- *) Bugfix: "stalled cache updating" alert.
- Thanks to Maxim Dounin.
-
-
-Changes with nginx 1.0.4 01 Jun 2011
-
- *) Change: now regular expressions case sensitivity in the "map"
- directive is given by prefixes "~" or "~*".
-
- *) Feature: now shared zones and caches use POSIX semaphores on Linux.
- Thanks to Denis F. Latypoff.
-
- *) Bugfix: "stalled cache updating" alert.
-
- *) Bugfix: nginx could not be built --without-http_auth_basic_module;
- the bug had appeared in 1.0.3.
-
-
-Changes with nginx 1.0.3 25 May 2011
-
- *) Feature: the "auth_basic_user_file" directive supports "$apr1",
- "{PLAIN}", and "{SSHA}" password encryption methods.
- Thanks to Maxim Dounin.
-
- *) Feature: the "geoip_org" directive and $geoip_org variable.
- Thanks to Alexander Uskov, Arnaud Granal, and Denis F. Latypoff.
-
- *) Feature: ngx_http_geo_module and ngx_http_geoip_module support IPv4
- addresses mapped to IPv6 addresses.
-
- *) Bugfix: a segmentation fault occurred in a worker process during
- testing IPv4 address mapped to IPv6 address, if access or deny rules
- were defined only for IPv6; the bug had appeared in 0.8.22.
-
- *) Bugfix: a cached response may be broken if "proxy/fastcgi/scgi/
- uwsgi_cache_bypass" and "proxy/fastcgi/scgi/uwsgi_no_cache" directive
- values were different; the bug had appeared in 0.8.46.
-
-
-Changes with nginx 1.0.2 10 May 2011
-
- *) Feature: now shared zones and caches use POSIX semaphores.
-
- *) Bugfix: in the "rotate" parameter of the "image_filter" directive.
- Thanks to Adam Bocim.
-
- *) Bugfix: nginx could not be built on Solaris; the bug had appeared in
- 1.0.1.
-
-
-Changes with nginx 1.0.1 03 May 2011
-
- *) Change: now the "split_clients" directive uses MurmurHash2 algorithm
- because of better distribution.
- Thanks to Oleg Mamontov.
-
- *) Change: now long strings starting with zero are not considered as
- false values.
- Thanks to Maxim Dounin.
-
- *) Change: now nginx uses a default listen backlog value 511 on Linux.
-
- *) Feature: the $upstream_... variables may be used in the SSI and perl
- modules.
-
- *) Bugfix: now nginx limits better disk cache size.
- Thanks to Oleg Mamontov.
-
- *) Bugfix: a segmentation fault might occur while parsing incorrect IPv4
- address; the bug had appeared in 0.9.3.
- Thanks to Maxim Dounin.
-
- *) Bugfix: nginx could not be built by gcc 4.6 without --with-debug
- option.
-
- *) Bugfix: nginx could not be built on Solaris 9 and earlier; the bug
- had appeared in 0.9.3.
- Thanks to Dagobert Michelsen.
-
- *) Bugfix: $request_time variable had invalid values if subrequests were
- used; the bug had appeared in 0.8.47.
- Thanks to Igor A. Valcov.
-
-
-Changes with nginx 1.0.0 12 Apr 2011
-
- *) Bugfix: a cache manager might hog CPU after reload.
- Thanks to Maxim Dounin.
-
- *) Bugfix: an "image_filter crop" directive worked incorrectly coupled
- with an "image_filter rotate 180" directive.
-
- *) Bugfix: a "satisfy any" directive disabled custom 401 error page.
-
-
-Changes with nginx 0.9.7 04 Apr 2011
-
- *) Feature: now keepalive connections may be closed premature, if there
- are no free worker connections.
- Thanks to Maxim Dounin.
-
- *) Feature: the "rotate" parameter of the "image_filter" directive.
- Thanks to Adam Bocim.
-
- *) Bugfix: a case when a backend in "fastcgi_pass", "scgi_pass", or
- "uwsgi_pass" directives is given by expression and refers to a
- defined upstream.
-
-
-Changes with nginx 0.9.6 21 Mar 2011
-
- *) Feature: the "map" directive supports regular expressions as value of
- the first parameter.
-
- *) Feature: $time_iso8601 access_log variable.
- Thanks to Michael Lustfield.
-
-
-Changes with nginx 0.9.5 21 Feb 2011
-
- *) Change: now nginx uses a default listen backlog value -1 on Linux.
- Thanks to Andrei Nigmatulin.
-
- *) Feature: the "utf8" parameter of "geoip_country" and "geoip_city"
- directives.
- Thanks to Denis F. Latypoff.
-
- *) Bugfix: in a default "proxy_redirect" directive if "proxy_pass"
- directive has no URI part.
- Thanks to Maxim Dounin.
-
- *) Bugfix: an "error_page" directive did not work with nonstandard error
- codes; the bug had appeared in 0.8.53.
- Thanks to Maxim Dounin.
-
-
-Changes with nginx 0.9.4 21 Jan 2011
-
- *) Feature: the "server_name" directive supports the $hostname variable.
-
- *) Feature: 494 code for "Request Header Too Large" error.
-
-
-Changes with nginx 0.9.3 13 Dec 2010
-
- *) Bugfix: if there was a single server for given IPv6 address:port
- pair, then captures in regular expressions in a "server_name"
- directive did not work.
-
- *) Bugfix: nginx could not be built on Solaris; the bug had appeared in
- 0.9.0.
-
-
-Changes with nginx 0.9.2 06 Dec 2010
-
- *) Feature: the "If-Unmodified-Since" client request header line
- support.
-
- *) Workaround: fallback to accept() syscall if accept4() was not
- implemented; the issue had appeared in 0.9.0.
-
- *) Bugfix: nginx could not be built on Cygwin; the bug had appeared in
- 0.9.0.
-
- *) Bugfix: for OpenSSL vulnerability CVE-2010-4180.
- Thanks to Maxim Dounin.
-
-
-Changes with nginx 0.9.1 30 Nov 2010
-
- *) Bugfix: "return CODE message" directives did not work; the bug had
- appeared in 0.9.0.
-
-
-Changes with nginx 0.9.0 29 Nov 2010
-
- *) Feature: the "keepalive_disable" directive.
-
- *) Feature: the "map" directive supports variables as value of a defined
- variable.
-
- *) Feature: the "map" directive supports empty strings as value of the
- first parameter.
-
- *) Feature: the "map" directive supports expressions as the first
- parameter.
-
- *) Feature: nginx(8) manual page.
- Thanks to Sergey Osokin.
-
- *) Feature: Linux accept4() support.
- Thanks to Simon Liu.
-
- *) Workaround: elimination of Linux linker warning about "sys_errlist"
- and "sys_nerr"; the warning had appeared in 0.8.35.
-
- *) Bugfix: a segmentation fault might occur in a worker process, if the
- "auth_basic" directive was used.
- Thanks to Michail Laletin.
-
- *) Bugfix: compatibility with ngx_http_eval_module; the bug had appeared
- in 0.8.42.
-
-
-Changes with nginx 0.8.53 18 Oct 2010
-
- *) Feature: now the "error_page" directive allows to change a status
- code in a redirect.
-
- *) Feature: the "gzip_disable" directive supports special "degradation"
- mask.
-
- *) Bugfix: a socket leak might occurred if file AIO was used.
- Thanks to Maxim Dounin.
-
- *) Bugfix: if the first server had no "listen" directive and there was
- no explicit default server, then a next server with a "listen"
- directive became the default server; the bug had appeared in 0.8.21.
-
-
-Changes with nginx 0.8.52 28 Sep 2010
-
- *) Bugfix: nginx used SSL mode for a listen socket if any listen option
- was set; the bug had appeared in 0.8.51.
-
-
-Changes with nginx 0.8.51 27 Sep 2010
-
- *) Change: the "secure_link_expires" directive has been canceled.
-
- *) Change: a logging level of resolver errors has been lowered from
- "alert" to "error".
-
- *) Feature: now a listen socket "ssl" parameter may be set several
- times.
-
-
-Changes with nginx 0.8.50 02 Sep 2010
-
- *) Feature: the "secure_link", "secure_link_md5", and
- "secure_link_expires" directives of the ngx_http_secure_link_module.
-
- *) Feature: the -q switch.
- Thanks to Gena Makhomed.
-
- *) Bugfix: worker processes may got caught in an endless loop during
- reconfiguration, if a caching was used; the bug had appeared in
- 0.8.48.
-
- *) Bugfix: in the "gzip_disable" directive.
- Thanks to Derrick Petzold.
-
- *) Bugfix: nginx/Windows could not send stop, quit, reopen, and reload
- signals to a process run in other session.
-
-
-Changes with nginx 0.8.49 09 Aug 2010
-
- *) Feature: the "image_filter_jpeg_quality" directive supports
- variables.
-
- *) Bugfix: a segmentation fault might occur in a worker process, if the
- $geoip_region_name variables was used; the bug had appeared in
- 0.8.48.
-
- *) Bugfix: errors intercepted by error_page were cached only for next
- request; the bug had appeared in 0.8.48.
-
-
-Changes with nginx 0.8.48 03 Aug 2010
-
- *) Change: now the "server_name" directive default value is an empty
- name "".
- Thanks to Gena Makhomed.
-
- *) Change: now the "server_name_in_redirect" directive default value is
- "off".
-
- *) Feature: the $geoip_dma_code, $geoip_area_code, and
- $geoip_region_name variables.
- Thanks to Christine McGonagle.
-
- *) Bugfix: the "proxy_pass", "fastcgi_pass", "uwsgi_pass", and
- "scgi_pass" directives were not inherited inside "limit_except"
- blocks.
-
- *) Bugfix: the "proxy_cache_min_uses", "fastcgi_cache_min_uses"
- "uwsgi_cache_min_uses", and "scgi_cache_min_uses" directives did not
- work; the bug had appeared in 0.8.46.
-
- *) Bugfix: the "fastcgi_split_path_info" directive used incorrectly
- captures, if only parts of an URI were captured.
- Thanks to Yuriy Taraday and Frank Enderle.
-
- *) Bugfix: the "rewrite" directive did not escape a ";" character during
- copying from URI to query string.
- Thanks to Daisuke Murase.
-
- *) Bugfix: the ngx_http_image_filter_module closed a connection, if an
- image was larger than "image_filter_buffer" size.
-
-
-Changes with nginx 0.8.47 28 Jul 2010
-
- *) Bugfix: $request_time variable had invalid values for subrequests.
-
- *) Bugfix: errors intercepted by error_page could not be cached.
-
- *) Bugfix: a cache manager process may got caught in an endless loop, if
- max_size parameter was used; the bug had appeared in 0.8.46.
-
-
-Changes with nginx 0.8.46 19 Jul 2010
-
- *) Change: now the "proxy_no_cache", "fastcgi_no_cache",
- "uwsgi_no_cache", and "scgi_no_cache" directives affect on a cached
- response saving only.
-
- *) Feature: the "proxy_cache_bypass", "fastcgi_cache_bypass",
- "uwsgi_cache_bypass", and "scgi_cache_bypass" directives.
-
- *) Bugfix: nginx did not free memory in cache keys zones if there was an
- error during working with backend: the memory was freed only after
- inactivity time or on memory low condition.
-
-
-Changes with nginx 0.8.45 13 Jul 2010
-
- *) Feature: ngx_http_xslt_filter improvements.
- Thanks to Laurence Rowe.
-
- *) Bugfix: SSI response might be truncated after include with
- wait="yes"; the bug had appeared in 0.7.25.
- Thanks to Maxim Dounin.
-
- *) Bugfix: the "listen" directive did not support the "setfib=0"
- parameter.
-
-
-Changes with nginx 0.8.44 05 Jul 2010
-
- *) Change: now nginx does not cache by default backend responses, if
- they have a "Set-Cookie" header line.
-
- *) Feature: the "listen" directive supports the "setfib" parameter.
- Thanks to Andrew Filonov.
-
- *) Bugfix: the "sub_filter" directive might change character case on
- partial match.
-
- *) Bugfix: compatibility with HP/UX.
-
- *) Bugfix: compatibility with AIX xlC_r compiler.
-
- *) Bugfix: nginx treated large SSLv2 packets as plain requests.
- Thanks to Miroslaw Jaworski.
-
-
-Changes with nginx 0.8.43 30 Jun 2010
-
- *) Feature: large geo ranges base loading speed-up.
-
- *) Bugfix: an error_page redirection to "location /zero {return 204;}"
- without changing status code kept the error body; the bug had
- appeared in 0.8.42.
-
- *) Bugfix: nginx might close IPv6 listen socket during reconfiguration.
- Thanks to Maxim Dounin.
-
- *) Bugfix: the $uid_set variable may be used at any request processing
- stage.
-
-
-Changes with nginx 0.8.42 21 Jun 2010
-
- *) Change: now nginx tests locations given by regular expressions, if
- request was matched exactly by a location given by a prefix string.
- The previous behavior has been introduced in 0.7.1.
-
- *) Feature: the ngx_http_scgi_module.
- Thanks to Manlio Perillo.
-
- *) Feature: a text answer may be added to a "return" directive.
-
-
-Changes with nginx 0.8.41 15 Jun 2010
-
- *) Security: nginx/Windows worker might be terminated abnormally if a
- requested file name has invalid UTF-8 encoding.
-
- *) Change: now nginx allows to use spaces in a request line.
-
- *) Bugfix: the "proxy_redirect" directive changed incorrectly a backend
- "Refresh" response header line.
- Thanks to Andrey Andreew and Max Sogin.
-
- *) Bugfix: nginx did not support path without host name in "Destination"
- request header line.
-
-
-Changes with nginx 0.8.40 07 Jun 2010
-
- *) Security: now nginx/Windows ignores default file stream name.
- Thanks to Jose Antonio Vazquez Gonzalez.
-
- *) Feature: the ngx_http_uwsgi_module.
- Thanks to Roberto De Ioris.
-
- *) Feature: a "fastcgi_param" directive with value starting with "HTTP_"
- overrides a client request header line.
-
- *) Bugfix: the "If-Modified-Since", "If-Range", etc. client request
- header lines were passed to FastCGI-server while caching.
-
- *) Bugfix: listen unix domain socket could not be changed during
- reconfiguration.
- Thanks to Maxim Dounin.
-
-
-Changes with nginx 0.8.39 31 May 2010
-
- *) Bugfix: an inherited "alias" directive worked incorrectly in
- inclusive location.
-
- *) Bugfix: in "alias" with variables and "try_files" directives
- combination.
-
- *) Bugfix: listen unix domain and IPv6 sockets did not inherit while
- online upgrade.
- Thanks to Maxim Dounin.
-
-
-Changes with nginx 0.8.38 24 May 2010
-
- *) Feature: the "proxy_no_cache" and "fastcgi_no_cache" directives.
-
- *) Feature: now the "rewrite" directive does a redirect automatically if
- the $scheme variable is used.
- Thanks to Piotr Sikora.
-
- *) Bugfix: now "limit_req" delay directive conforms to the described
- algorithm.
- Thanks to Maxim Dounin.
-
- *) Bugfix: the $uid_got variable might not be used in the SSI and perl
- modules.
-
-
-Changes with nginx 0.8.37 17 May 2010
-
- *) Feature: the ngx_http_split_clients_module.
-
- *) Feature: the "map" directive supports keys more than 255 characters.
-
- *) Bugfix: nginx ignored the "private" and "no-store" values in the
- "Cache-Control" backend response header line.
-
- *) Bugfix: a "stub" parameter of an "include" SSI directive was not
- used, if empty response has 200 status code.
-
- *) Bugfix: if a proxied or FastCGI request was internally redirected to
- another proxied or FastCGI location, then a segmentation fault might
- occur in a worker process; the bug had appeared in 0.8.33.
- Thanks to Yichun Zhang.
-
- *) Bugfix: IMAP connections may hang until they timed out while talking
- to Zimbra server.
- Thanks to Alan Batie.
-
-
-Changes with nginx 0.8.36 22 Apr 2010
-
- *) Bugfix: the ngx_http_dav_module handled incorrectly the DELETE, COPY,
- and MOVE methods for symlinks.
-
- *) Bugfix: values of the $query_string, $arg_..., etc. variables cached
- in main request were used by the SSI module in subrequests.
-
- *) Bugfix: a variable value was repeatedly encoded after each an "echo"
- SSI-command output; the bug had appeared in 0.6.14.
-
- *) Bugfix: a worker process hung if a FIFO file was requested.
- Thanks to Vicente Aguilar and Maxim Dounin.
-
- *) Bugfix: OpenSSL-1.0.0 compatibility on 64-bit Linux.
- Thanks to Maxim Dounin.
-
- *) Bugfix: nginx could not be built --without-http-cache; the bug had
- appeared in 0.8.35.
-
-
-Changes with nginx 0.8.35 01 Apr 2010
-
- *) Change: now the charset filter runs before the SSI filter.
-
- *) Feature: the "chunked_transfer_encoding" directive.
-
- *) Bugfix: an "&" character was not escaped when it was copied in
- arguments part in a rewrite rule.
-
- *) Bugfix: nginx might be terminated abnormally while a signal
- processing or if the directive "timer_resolution" was used on
- platforms which do not support kqueue or eventport notification
- methods.
- Thanks to George Xie and Maxim Dounin.
-
- *) Bugfix: if temporary files and permanent storage area resided at
- different file systems, then permanent file modification times were
- incorrect.
- Thanks to Maxim Dounin.
-
- *) Bugfix: ngx_http_memcached_module might issue the error message
- "memcached sent invalid trailer".
- Thanks to Maxim Dounin.
-
- *) Bugfix: nginx could not built zlib-1.2.4 library using the library
- sources.
- Thanks to Maxim Dounin.
-
- *) Bugfix: a segmentation fault occurred in a worker process, if there
- was large stderr output before FastCGI response; the bug had appeared
- in 0.8.34.
- Thanks to Maxim Dounin.
-
-
-Changes with nginx 0.8.34 03 Mar 2010
-
- *) Bugfix: nginx did not support all ciphers and digests used in client
- certificates.
- Thanks to Innocenty Enikeew.
-
- *) Bugfix: nginx cached incorrectly FastCGI responses if there was large
- stderr output before response.
-
- *) Bugfix: nginx did not support HTTPS referrers.
-
- *) Bugfix: nginx/Windows might not find file if path in configuration
- was given in other character case; the bug had appeared in 0.8.33.
-
- *) Bugfix: the $date_local variable has an incorrect value, if the "%s"
- format was used.
- Thanks to Maxim Dounin.
-
- *) Bugfix: if ssl_session_cache was not set or was set to "none", then
- during client certificate verify the error "session id context
- uninitialized" might occur; the bug had appeared in 0.7.1.
-
- *) Bugfix: a geo range returned default value if the range included two
- or more /16 networks and did not begin at /16 network boundary.
-
- *) Bugfix: a block used in a "stub" parameter of an "include" SSI
- directive was output with "text/plain" MIME type.
-
- *) Bugfix: $r->sleep() did not work; the bug had appeared in 0.8.11.
-
-
-Changes with nginx 0.8.33 01 Feb 2010
-
- *) Security: now nginx/Windows ignores trailing spaces in URI.
- Thanks to Dan Crowley, Core Security Technologies.
-
- *) Security: now nginx/Windows ignores short files names.
- Thanks to Dan Crowley, Core Security Technologies.
-
- *) Change: now keepalive connections after POST requests are not
- disabled for MSIE 7.0+.
- Thanks to Adam Lounds.
-
- *) Workaround: now keepalive connections are disabled for Safari.
- Thanks to Joshua Sierles.
-
- *) Bugfix: if a proxied or FastCGI request was internally redirected to
- another proxied or FastCGI location, then $upstream_response_time
- variable may have abnormally large value; the bug had appeared in
- 0.8.7.
-
- *) Bugfix: a segmentation fault might occur in a worker process, while
- discarding a request body; the bug had appeared in 0.8.11.
-
-
-Changes with nginx 0.8.32 11 Jan 2010
-
- *) Bugfix: UTF-8 encoding usage in the ngx_http_autoindex_module.
- Thanks to Maxim Dounin.
-
- *) Bugfix: regular expression named captures worked for two names only.
- Thanks to Maxim Dounin.
-
- *) Bugfix: now the "localhost" name is used in the "Host" request header
- line, if an unix domain socket is defined in the "auth_http"
- directive.
- Thanks to Maxim Dounin.
-
- *) Bugfix: nginx did not support chunked transfer encoding for 201
- responses.
- Thanks to Julian Reich.
-
- *) Bugfix: if the "expires modified" set date in the past, then a
- negative number was set in the "Cache-Control" response header line.
- Thanks to Alex Kapranoff.
-
-
-Changes with nginx 0.8.31 23 Dec 2009
-
- *) Feature: now the "error_page" directive may redirect the 301 and 302
- responses.
-
- *) Feature: the $geoip_city_continent_code, $geoip_latitude, and
- $geoip_longitude variables.
- Thanks to Arvind Sundararajan.
-
- *) Feature: now the ngx_http_image_filter_module deletes always EXIF and
- other application specific data if the data consume more than 5% of a
- JPEG file.
-
- *) Bugfix: nginx closed a connection if a cached response had an empty
- body.
- Thanks to Piotr Sikora.
-
- *) Bugfix: nginx might not be built by gcc 4.x if the -O2 or higher
- optimization option was used.
- Thanks to Maxim Dounin and Denis F. Latypoff.
-
- *) Bugfix: regular expressions in location were always tested in
- case-sensitive mode; the bug had appeared in 0.8.25.
-
- *) Bugfix: nginx cached a 304 response if there was the "If-None-Match"
- header line in a proxied request.
- Thanks to Tim Dettrick and David Kostal.
-
- *) Bugfix: nginx/Windows tried to delete a temporary file twice if the
- file should replace an already existent file.
-
-
-Changes with nginx 0.8.30 15 Dec 2009
-
- *) Change: now the default buffer size of the
- "large_client_header_buffers" directive is 8K.
- Thanks to Andrew Cholakian.
-
- *) Feature: the conf/fastcgi.conf for simple FastCGI configurations.
-
- *) Bugfix: nginx/Windows tried to rename a temporary file twice if the
- file should replace an already existent file.
-
- *) Bugfix: of "double free or corruption" error issued if host could not
- be resolved; the bug had appeared in 0.8.22.
- Thanks to Konstantin Svist.
-
- *) Bugfix: in libatomic usage on some platforms.
- Thanks to W-Mark Kubacki.
-
-
-Changes with nginx 0.8.29 30 Nov 2009
-
- *) Change: now the "009" status code is written to an access log for
- proxied HTTP/0.9 responses.
-
- *) Feature: the "addition_types", "charset_types", "gzip_types",
- "ssi_types", "sub_filter_types", and "xslt_types" directives support
- an "*" parameter.
-
- *) Feature: GCC 4.1+ built-in atomic operations usage.
- Thanks to W-Mark Kubacki.
-
- *) Feature: the --with-libatomic[=DIR] option in the configure.
- Thanks to W-Mark Kubacki.
-
- *) Bugfix: listen unix domain socket had limited access rights.
-
- *) Bugfix: cached HTTP/0.9 responses were handled incorrectly.
-
- *) Bugfix: regular expression named captures given by "?P<...>" did not
- work in a "server_name" directive.
- Thanks to Maxim Dounin.
-
-
-Changes with nginx 0.8.28 23 Nov 2009
-
- *) Bugfix: nginx could not be built with the --without-pcre parameter;
- the bug had appeared in 0.8.25.
-
-
-Changes with nginx 0.8.27 17 Nov 2009
-
- *) Bugfix: regular expressions did not work in nginx/Windows; the bug
- had appeared in 0.8.25.
-
-
-Changes with nginx 0.8.26 16 Nov 2009
-
- *) Bugfix: in captures usage in "rewrite" directive; the bug had
- appeared in 0.8.25.
-
- *) Bugfix: nginx could not be built without the --with-debug option; the
- bug had appeared in 0.8.25.
-
-
-Changes with nginx 0.8.25 16 Nov 2009
-
- *) Change: now no message is written in an error log if a variable is
- not found by $r->variable() method.
-
- *) Feature: the ngx_http_degradation_module.
-
- *) Feature: regular expression named captures.
-
- *) Feature: now URI part is not required a "proxy_pass" directive if
- variables are used.
-
- *) Feature: now the "msie_padding" directive works for Chrome too.
-
- *) Bugfix: a segmentation fault occurred in a worker process on low
- memory condition; the bug had appeared in 0.8.18.
-
- *) Bugfix: nginx sent gzipped responses to clients those do not support
- gzip, if "gzip_static on" and "gzip_vary off"; the bug had appeared
- in 0.8.16.
-
-
-Changes with nginx 0.8.24 11 Nov 2009
-
- *) Bugfix: nginx always added "Content-Encoding: gzip" response header
- line in 304 responses sent by ngx_http_gzip_static_module.
-
- *) Bugfix: nginx could not be built without the --with-debug option; the
- bug had appeared in 0.8.23.
-
- *) Bugfix: the "unix:" parameter of the "set_real_ip_from" directive
- inherited incorrectly from previous level.
-
- *) Bugfix: in resolving empty name.
-
-
-Changes with nginx 0.8.23 11 Nov 2009
-
- *) Security: now SSL/TLS renegotiation is disabled.
- Thanks to Maxim Dounin.
-
- *) Bugfix: listen unix domain socket did not inherit while online
- upgrade.
-
- *) Bugfix: the "unix:" parameter of the "set_real_ip_from" directive did
- not without yet another directive with any IP address.
-
- *) Bugfix: segmentation fault and infinite looping in resolver.
-
- *) Bugfix: in resolver.
- Thanks to Artem Bokhan.
-
-
-Changes with nginx 0.8.22 03 Nov 2009
-
- *) Feature: the "proxy_bind", "fastcgi_bind", and "memcached_bind"
- directives.
-
- *) Feature: the "access" and the "deny" directives support IPv6.
-
- *) Feature: the "set_real_ip_from" directive supports IPv6 addresses in
- request headers.
-
- *) Feature: the "unix:" parameter of the "set_real_ip_from" directive.
-
- *) Bugfix: nginx did not delete unix domain socket after configuration
- testing.
-
- *) Bugfix: nginx deleted unix domain socket while online upgrade.
-
- *) Bugfix: the "!-x" operator did not work.
- Thanks to Maxim Dounin.
-
- *) Bugfix: a segmentation fault might occur in a worker process, if
- limit_rate was used in HTTPS server.
- Thanks to Maxim Dounin.
-
- *) Bugfix: a segmentation fault might occur in a worker process while
- $limit_rate logging.
- Thanks to Maxim Dounin.
-
- *) Bugfix: a segmentation fault might occur in a worker process, if
- there was no "listen" directive in "server" block; the bug had
- appeared in 0.8.21.
-
-
-Changes with nginx 0.8.21 26 Oct 2009
-
- *) Feature: now the "-V" switch shows TLS SNI support.
-
- *) Feature: the "listen" directive of the HTTP module supports unix
- domain sockets.
- Thanks to Hongli Lai.
-
- *) Feature: the "default_server" parameter of the "listen" directive.
-
- *) Feature: now a "default" parameter is not required to set listen
- socket options.
-
- *) Bugfix: nginx did not support dates in 2038 year on 32-bit platforms;
-
- *) Bugfix: socket leak; the bug had appeared in 0.8.11.
-
-
-Changes with nginx 0.8.20 14 Oct 2009
-
- *) Change: now default SSL ciphers are "HIGH:!ADH:!MD5".
-
- *) Bugfix: the ngx_http_autoindex_module did not show the trailing slash
- in links to a directory; the bug had appeared in 0.7.15.
-
- *) Bugfix: nginx did not close a log file set by the --error-log-path
- configuration option; the bug had appeared in 0.7.53.
-
- *) Bugfix: nginx did not treat a comma as separator in the
- "Cache-Control" backend response header line.
-
- *) Bugfix: nginx/Windows might not create temporary file, a cache file,
- or "proxy/fastcgi_store"d file if a worker had no enough access
- rights for top level directories.
-
- *) Bugfix: the "Set-Cookie" and "P3P" FastCGI response header lines were
- not hidden while caching if no "fastcgi_hide_header" directives were
- used with any parameters.
-
- *) Bugfix: nginx counted incorrectly disk cache size.
-
-
-Changes with nginx 0.8.19 06 Oct 2009
-
- *) Change: now SSLv2 protocol is disabled by default.
-
- *) Change: now default SSL ciphers are "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM".
-
- *) Bugfix: a "limit_req" directive did not work; the bug had appeared in
- 0.8.18.
-
-
-Changes with nginx 0.8.18 06 Oct 2009
-
- *) Feature: the "read_ahead" directive.
-
- *) Feature: now several "perl_modules" directives may be used.
-
- *) Feature: the "limit_req_log_level" and "limit_conn_log_level"
- directives.
-
- *) Bugfix: now "limit_req" directive conforms to the leaky bucket
- algorithm.
- Thanks to Maxim Dounin.
-
- *) Bugfix: nginx did not work on Linux/sparc.
- Thanks to Marcus Ramberg.
-
- *) Bugfix: nginx sent '\0' in a "Location" response header line on MKCOL
- request.
- Thanks to Xie Zhenye.
-
- *) Bugfix: zero status code was logged instead of 499 status code; the
- bug had appeared in 0.8.11.
-
- *) Bugfix: socket leak; the bug had appeared in 0.8.11.
-
-
-Changes with nginx 0.8.17 28 Sep 2009
-
- *) Security: now "/../" are disabled in "Destination" request header
- line.
-
- *) Change: now $host variable value is always low case.
-
- *) Feature: the $ssl_session_id variable.
-
- *) Bugfix: socket leak; the bug had appeared in 0.8.11.
-
-
-Changes with nginx 0.8.16 22 Sep 2009
-
- *) Feature: the "image_filter_transparency" directive.
-
- *) Bugfix: "addition_types" directive was incorrectly named
- "addtion_types".
-
- *) Bugfix: resolver cache poisoning.
- Thanks to Matthew Dempsky.
-
- *) Bugfix: memory leak in resolver.
- Thanks to Matthew Dempsky.
-
- *) Bugfix: invalid request line in $request variable was written in
- access_log only if error_log was set to "info" or "debug" level.
-
- *) Bugfix: in PNG alpha-channel support in the
- ngx_http_image_filter_module.
-
- *) Bugfix: nginx always added "Vary: Accept-Encoding" response header
- line, if both "gzip_static" and "gzip_vary" were on.
-
- *) Bugfix: in UTF-8 encoding support by "try_files" directive in
- nginx/Windows.
-
- *) Bugfix: in "post_action" directive usage; the bug had appeared in
- 0.8.11.
- Thanks to Igor Artemiev.
-
-
-Changes with nginx 0.8.15 14 Sep 2009
-
- *) Security: a segmentation fault might occur in worker process while
- specially crafted request handling.
- Thanks to Chris Ries.
-
- *) Bugfix: if names .domain.tld, .sub.domain.tld, and .domain-some.tld
- were defined, then the name .sub.domain.tld was matched by
- .domain.tld.
-
- *) Bugfix: in transparency support in the ngx_http_image_filter_module.
-
- *) Bugfix: in file AIO.
-
- *) Bugfix: in X-Accel-Redirect usage; the bug had appeared in 0.8.11.
-
- *) Bugfix: in embedded perl module; the bug had appeared in 0.8.11.
-
-
-Changes with nginx 0.8.14 07 Sep 2009
-
- *) Bugfix: an expired cached response might stick in the "UPDATING"
- state.
-
- *) Bugfix: a segmentation fault might occur in worker process, if
- error_log was set to info or debug level.
- Thanks to Sergey Bochenkov.
-
- *) Bugfix: in embedded perl module; the bug had appeared in 0.8.11.
-
- *) Bugfix: an "error_page" directive did not redirect a 413 error; the
- bug had appeared in 0.6.10.
-
-
-Changes with nginx 0.8.13 31 Aug 2009
-
- *) Bugfix: in the "aio sendfile" directive; the bug had appeared in
- 0.8.12.
-
- *) Bugfix: nginx could not be built without the --with-file-aio option
- on FreeBSD; the bug had appeared in 0.8.12.
-
-
-Changes with nginx 0.8.12 31 Aug 2009
-
- *) Feature: the "sendfile" parameter in the "aio" directive on FreeBSD.
-
- *) Bugfix: in try_files; the bug had appeared in 0.8.11.
-
- *) Bugfix: in memcached; the bug had appeared in 0.8.11.
-
-
-Changes with nginx 0.8.11 28 Aug 2009
-
- *) Change: now directive "gzip_disable msie6" does not disable gzipping
- for MSIE 6.0 SV1.
-
- *) Feature: file AIO support on FreeBSD and Linux.
-
- *) Feature: the "directio_alignment" directive.
-
-
-Changes with nginx 0.8.10 24 Aug 2009
-
- *) Bugfix: memory leaks if GeoIP City database was used.
-
- *) Bugfix: in copying temporary files to permanent storage area; the bug
- had appeared in 0.8.9.
-
-
-Changes with nginx 0.8.9 17 Aug 2009
-
- *) Feature: now the start cache loader runs in a separate process; this
- should improve large caches handling.
-
- *) Feature: now temporary files and permanent storage area may reside at
- different file systems.
-
-
-Changes with nginx 0.8.8 10 Aug 2009
-
- *) Bugfix: in handling FastCGI headers split in records.
-
- *) Bugfix: a segmentation fault occurred in worker process, if a request
- was handled in two proxied or FastCGIed locations and a caching was
- enabled in the first location; the bug had appeared in 0.8.7.
-
-
-Changes with nginx 0.8.7 27 Jul 2009
-
- *) Change: minimum supported OpenSSL version is 0.9.7.
-
- *) Change: the "ask" parameter of the "ssl_verify_client" directive was
- changed to the "optional" parameter and now it checks a client
- certificate if it was offered.
- Thanks to Brice Figureau.
-
- *) Feature: the $ssl_client_verify variable.
- Thanks to Brice Figureau.
-
- *) Feature: the "ssl_crl" directive.
- Thanks to Brice Figureau.
-
- *) Feature: the "proxy" parameter of the "geo" directive.
-
- *) Feature: the "image_filter" directive supports variables for setting
- size.
-
- *) Bugfix: the $ssl_client_cert variable usage corrupted memory; the bug
- had appeared in 0.7.7.
- Thanks to Sergey Zhuravlev.
-
- *) Bugfix: "proxy_pass_header" and "fastcgi_pass_header" directives did
- not pass to a client the "X-Accel-Redirect", "X-Accel-Limit-Rate",
- "X-Accel-Buffering", and "X-Accel-Charset" lines from backend
- response header.
- Thanks to Maxim Dounin.
-
- *) Bugfix: in handling "Last-Modified" and "Accept-Ranges" backend
- response header lines; the bug had appeared in 0.7.44.
- Thanks to Maxim Dounin.
-
- *) Bugfix: the "[alert] zero size buf" error if subrequest returns an
- empty response; the bug had appeared in 0.8.5.
-
-
-Changes with nginx 0.8.6 20 Jul 2009
-
- *) Feature: the ngx_http_geoip_module.
-
- *) Bugfix: XSLT filter may fail with message "not well formed XML
- document" for valid XML document.
- Thanks to Kuramoto Eiji.
-
- *) Bugfix: now in MacOSX, Cygwin, and nginx/Windows locations given by a
- regular expression are always tested in case insensitive mode.
-
- *) Bugfix: now nginx/Windows ignores trailing dots in URI.
- Thanks to Hugo Leisink.
-
- *) Bugfix: name of file specified in --conf-path was not honored during
- installation; the bug had appeared in 0.6.6.
- Thanks to Maxim Dounin.
-
-
-Changes with nginx 0.8.5 13 Jul 2009
-
- *) Bugfix: now nginx allows underscores in a request method.
-
- *) Bugfix: a 500 error code was returned for invalid login/password
- while HTTP Basic authentication on Windows.
-
- *) Bugfix: ngx_http_perl_module responses did not work in subrequests.
-
- *) Bugfix: in ngx_http_limit_req_module.
- Thanks to Maxim Dounin.
-
-
-Changes with nginx 0.8.4 22 Jun 2009
-
- *) Bugfix: nginx could not be built --without-http-cache; the bug had
- appeared in 0.8.3.
-
-
-Changes with nginx 0.8.3 19 Jun 2009
-
- *) Feature: the $upstream_cache_status variable.
-
- *) Bugfix: nginx could not be built on MacOSX 10.6.
-
- *) Bugfix: nginx could not be built --without-http-cache; the bug had
- appeared in 0.8.2.
-
- *) Bugfix: a segmentation fault occurred in worker process, if a backend
- 401 error was intercepted and the backend did not set the
- "WWW-Authenticate" response header line.
- Thanks to Eugene Mychlo.
-
-
-Changes with nginx 0.8.2 15 Jun 2009
-
- *) Bugfix: in open_file_cache and proxy/fastcgi cache interaction on
- start up.
-
- *) Bugfix: open_file_cache might cache open file descriptors too long;
- the bug had appeared in 0.7.4.
-
-
-Changes with nginx 0.8.1 08 Jun 2009
-
- *) Feature: the "updating" parameter in "proxy_cache_use_stale" and
- "fastcgi_cache_use_stale" directives.
-
- *) Bugfix: the "If-Modified-Since", "If-Range", etc. client request
- header lines were passed to backend while caching if no
- "proxy_set_header" directive was used with any parameters.
-
- *) Bugfix: the "Set-Cookie" and "P3P" response header lines were not
- hidden while caching if no "proxy_hide_header/fastcgi_hide_header"
- directives were used with any parameters.
-
- *) Bugfix: the ngx_http_image_filter_module did not support GIF87a
- format.
- Thanks to Denis Ilyinyh.
-
- *) Bugfix: nginx could not be built modules on Solaris 10 and early; the
- bug had appeared in 0.7.56.
-
-
-Changes with nginx 0.8.0 02 Jun 2009
-
- *) Feature: the "keepalive_requests" directive.
-
- *) Feature: the "limit_rate_after" directive.
- Thanks to Ivan Debnar.
-
- *) Bugfix: XLST filter did not work in subrequests.
-
- *) Bugfix: in relative paths handling in nginx/Windows.
-
- *) Bugfix: in proxy_store, fastcgi_store, proxy_cache, and fastcgi_cache
- in nginx/Windows.
-
- *) Bugfix: in memory allocation error handling.
- Thanks to Maxim Dounin and Kirill A. Korinskiy.
-
-
-Changes with nginx 0.7.59 25 May 2009
-
- *) Feature: the "proxy_cache_methods" and "fastcgi_cache_methods"
- directives.
-
- *) Bugfix: socket leak; the bug had appeared in 0.7.25.
- Thanks to Maxim Dounin.
-
- *) Bugfix: a segmentation fault occurred in worker process, if a request
- had no body and the $request_body variable was used;
- the bug had appeared in 0.7.58.
-
- *) Bugfix: the SSL modules might not built on Solaris and Linux;
- the bug had appeared in 0.7.56.
-
- *) Bugfix: ngx_http_xslt_filter_module responses were not handled by
- SSI, charset, and gzip filters.
-
- *) Bugfix: a "charset" directive did not set a charset to
- ngx_http_gzip_static_module responses.
-
-
-Changes with nginx 0.7.58 18 May 2009
-
- *) Feature: a "listen" directive of the mail proxy module supports IPv6.
-
- *) Feature: the "image_filter_jpeg_quality" directive.
-
- *) Feature: the "client_body_in_single_buffer" directive.
-
- *) Feature: the $request_body variable.
-
- *) Bugfix: in ngx_http_autoindex_module in file name links having a ":"
- symbol in the name.
-
- *) Bugfix: "make upgrade" procedure did not work; the bug had appeared
- in 0.7.53.
- Thanks to Denis F. Latypoff.
-
-
-Changes with nginx 0.7.57 12 May 2009
-
- *) Bugfix: a floating-point fault occurred in worker process, if the
- ngx_http_image_filter_module errors were redirected to named
- location; the bug had appeared in 0.7.56.
-
-
-Changes with nginx 0.7.56 11 May 2009
-
- *) Feature: nginx/Windows supports IPv6 in a "listen" directive of the
- HTTP module.
-
- *) Bugfix: in ngx_http_image_filter_module.
-
-
-Changes with nginx 0.7.55 06 May 2009
-
- *) Bugfix: the http_XXX parameters in "proxy_cache_use_stale" and
- "fastcgi_cache_use_stale" directives did not work.
-
- *) Bugfix: fastcgi cache did not cache header only responses.
-
- *) Bugfix: of "select() failed (9: Bad file descriptor)" error in
- nginx/Unix and "select() failed (10038: ...)" error in nginx/Windows.
-
- *) Bugfix: a segmentation fault might occur in worker process, if an
- "debug_connection" directive was used; the bug had appeared in
- 0.7.54.
-
- *) Bugfix: fix ngx_http_image_filter_module building errors.
-
- *) Bugfix: the files bigger than 2G could not be transferred using
- $r->sendfile.
- Thanks to Maxim Dounin.
-
-
-Changes with nginx 0.7.54 01 May 2009
-
- *) Feature: the ngx_http_image_filter_module.
-
- *) Feature: the "proxy_ignore_headers" and "fastcgi_ignore_headers"
- directives.
-
- *) Bugfix: a segmentation fault might occur in worker process, if an
- "open_file_cache_errors off" directive was used; the bug had appeared
- in 0.7.53.
-
- *) Bugfix: the "port_in_redirect off" directive did not work; the bug
- had appeared in 0.7.39.
-
- *) Bugfix: improve handling of "select" method errors.
-
- *) Bugfix: of "select() failed (10022: ...)" error in nginx/Windows.
-
- *) Bugfix: in error text descriptions in nginx/Windows; the bug had
- appeared in 0.7.53.
-
-
-Changes with nginx 0.7.53 27 Apr 2009
-
- *) Change: now a log set by --error-log-path is created from the very
- start-up.
-
- *) Feature: now the start up errors and warnings are outputted to an
- error_log and stderr.
-
- *) Feature: the empty --prefix= configure parameter forces nginx to use
- a directory where it was run as prefix.
-
- *) Feature: the -p switch.
-
- *) Feature: the -s switch on Unix platforms.
-
- *) Feature: the -? and -h switches.
- Thanks to Jerome Loyet.
-
- *) Feature: now switches may be set in condensed form.
-
- *) Bugfix: nginx/Windows did not work if configuration file was given by
- the -c switch.
-
- *) Bugfix: temporary files might be not removed if the "proxy_store",
- "fastcgi_store", "proxy_cache", or "fastcgi_cache" were used.
- Thanks to Maxim Dounin.
-
- *) Bugfix: an incorrect value was passed to mail proxy authentication
- server in "Auth-Method" header line; the bug had appeared
- in 0.7.34.
- Thanks to Simon Lecaille.
-
- *) Bugfix: system error text descriptions were not logged on Linux;
- the bug had appeared in 0.7.45.
-
- *) Bugfix: the "fastcgi_cache_min_uses" directive did not work.
- Thanks to Andrew Vorobyoff.
-
-
-Changes with nginx 0.7.52 20 Apr 2009
-
- *) Feature: the first native Windows binary release.
-
- *) Bugfix: in processing HEAD method while caching.
-
- *) Bugfix: in processing the "If-Modified-Since", "If-Range", etc.
- client request header lines while caching.
-
- *) Bugfix: now the "Set-Cookie" and "P3P" header lines are hidden in
- cacheable responses.
-
- *) Bugfix: if nginx was built with the ngx_http_perl_module and with a
- perl which supports threads, then during a master process exit the
- message "panic: MUTEX_LOCK" might be issued.
-
- *) Bugfix: nginx could not be built --without-http-cache; the bug had
- appeared in 0.7.48.
-
- *) Bugfix: nginx could not be built on platforms different from i386,
- amd64, sparc, and ppc; the bug had appeared in 0.7.42.
-
-
-Changes with nginx 0.7.51 12 Apr 2009
-
- *) Feature: the "try_files" directive supports a response code in the
- fallback parameter.
-
- *) Feature: now any response code can be used in the "return" directive.
-
- *) Bugfix: the "error_page" directive made an external redirect without
- query string; the bug had appeared in 0.7.44.
-
- *) Bugfix: if servers listened on several defined explicitly addresses,
- then virtual servers might not work; the bug had appeared in 0.7.39.
-
-
-Changes with nginx 0.7.50 06 Apr 2009
-
- *) Bugfix: the $arg_... variables did not work; the bug had appeared in
- 0.7.49.
-
-
-Changes with nginx 0.7.49 06 Apr 2009
-
- *) Bugfix: a segmentation fault might occur in worker process, if the
- $arg_... variables were used; the bug had appeared in 0.7.48.
-
-
-Changes with nginx 0.7.48 06 Apr 2009
-
- *) Feature: the "proxy_cache_key" directive.
-
- *) Bugfix: now nginx takes into account the "X-Accel-Expires",
- "Expires", and "Cache-Control" header lines in a backend response.
-
- *) Bugfix: now nginx caches responses for the GET requests only.
-
- *) Bugfix: the "fastcgi_cache_key" directive was not inherited.
-
- *) Bugfix: the $arg_... variables did not work with SSI subrequests.
- Thanks to Maxim Dounin.
-
- *) Bugfix: nginx could not be built with uclibc library.
- Thanks to Timothy Redaelli.
-
- *) Bugfix: nginx could not be built on OpenBSD; the bug had
- appeared in 0.7.46.
-
-
-Changes with nginx 0.7.47 01 Apr 2009
-
- *) Bugfix: nginx could not be built on FreeBSD 6 and early versions; the
- bug had appeared in 0.7.46.
-
- *) Bugfix: nginx could not be built on MacOSX; the bug had
- appeared in 0.7.46.
-
- *) Bugfix: if the "max_size" parameter was set, then the cache manager
- might purge a whole cache; the bug had appeared in 0.7.46.
-
- *) Change: a segmentation fault might occur in worker process, if the
- "proxy_cache"/"fastcgi_cache" and the "proxy_cache_valid"/
- "fastcgi_cache_valid" were set on different levels; the bug had
- appeared in 0.7.46.
-
- *) Bugfix: a segmentation fault might occur in worker process, if a
- request was redirected to a proxied or FastCGI server via error_page
- or try_files; the bug had appeared in 0.7.44.
-
-
-Changes with nginx 0.7.46 30 Mar 2009
-
- *) Bugfix: the previous release tarball was incorrect.
-
-
-Changes with nginx 0.7.45 30 Mar 2009
-
- *) Change: now the "proxy_cache" and the "proxy_cache_valid" directives
- can be set on different levels.
-
- *) Change: the "clean_time" parameter of the "proxy_cache_path"
- directive is canceled.
-
- *) Feature: the "max_size" parameter of the "proxy_cache_path"
- directive.
-
- *) Feature: the ngx_http_fastcgi_module preliminary cache support.
-
- *) Feature: now on shared memory allocation errors directive and zone
- names are logged.
-
- *) Bugfix: the directive "add_header last-modified ''" did not delete a
- "Last-Modified" response header line; the bug had appeared in 0.7.44.
-
- *) Bugfix: a relative path in the "auth_basic_user_file" directive given
- without variables did not work; the bug had appeared in 0.7.44.
- Thanks to Jerome Loyet.
-
- *) Bugfix: in an "alias" directive given using variables without
- references to captures of regular expressions; the bug had appeared
- in 0.7.42.
-
-
-Changes with nginx 0.7.44 23 Mar 2009
-
- *) Feature: the ngx_http_proxy_module preliminary cache support.
-
- *) Feature: the --with-pcre option in the configure.
-
- *) Feature: the "try_files" directive is now allowed on the server block
- level.
-
- *) Bugfix: the "try_files" directive handled incorrectly a query string
- in a fallback parameter.
-
- *) Bugfix: the "try_files" directive might test incorrectly directories.
-
- *) Bugfix: if there was a single server for given address:port pair,
- then captures in regular expressions in a "server_name" directive did
- not work.
-
-
-Changes with nginx 0.7.43 18 Mar 2009
-
- *) Bugfix: a request was handled incorrectly, if a "root" directive used
- variables; the bug had appeared in 0.7.42.
-
- *) Bugfix: if a server listened on wildcard address, then the
- $server_addr variable value was "0.0.0.0"; the bug had appeared in
- 0.7.36.
-
-
-Changes with nginx 0.7.42 16 Mar 2009
-
- *) Change: now the "Invalid argument" error returned by
- setsockopt(TCP_NODELAY) on Solaris, is ignored.
-
- *) Change: now if a file specified in a "auth_basic_user_file" directive
- is absent, then the 403 error is returned instead of the 500 one.
-
- *) Feature: the "auth_basic_user_file" directive supports variables.
- Thanks to Kirill A. Korinskiy.
-
- *) Feature: the "listen" directive supports the "ipv6only" parameter.
- Thanks to Zhang Hua.
-
- *) Bugfix: in an "alias" directive with references to captures of
- regular expressions; the bug had appeared in 0.7.40.
-
- *) Bugfix: compatibility with Tru64 UNIX.
- Thanks to Dustin Marquess.
-
- *) Bugfix: nginx could not be built without PCRE library; the bug had
- appeared in 0.7.41.
-
-
-Changes with nginx 0.7.41 11 Mar 2009
-
- *) Bugfix: a segmentation fault might occur in worker process, if a
- "server_name" or a "location" directives had captures in regular
- expressions; the issue had appeared in 0.7.40.
- Thanks to Vladimir Sopot.
-
-
-Changes with nginx 0.7.40 09 Mar 2009
-
- *) Feature: the "location" directive supports captures in regular
- expressions.
-
- *) Feature: an "alias" directive with capture references may be used
- inside a location given by a regular expression with captures.
-
- *) Feature: the "server_name" directive supports captures in regular
- expressions.
-
- *) Workaround: the ngx_http_autoindex_module did not show the trailing
- slash in directories on XFS filesystem; the issue had appeared in
- 0.7.15.
- Thanks to Dmitry Kuzmenko.
-
-
-Changes with nginx 0.7.39 02 Mar 2009
-
- *) Bugfix: large response with SSI might hang, if gzipping was enabled;
- the bug had appeared in 0.7.28.
- Thanks to Artem Bokhan.
-
- *) Bugfix: a segmentation fault might occur in worker process, if short
- static variants are used in a "try_files" directive.
-
-
-Changes with nginx 0.7.38 23 Feb 2009
-
- *) Feature: authentication failures logging.
-
- *) Bugfix: name/password in auth_basic_user_file were ignored after odd
- number of empty lines.
- Thanks to Alexander Zagrebin.
-
- *) Bugfix: a segmentation fault occurred in a master process, if long
- path was used in unix domain socket; the bug had appeared in 0.7.36.
-
-
-Changes with nginx 0.7.37 21 Feb 2009
-
- *) Bugfix: directives using upstreams did not work; the bug had appeared
- in 0.7.36.
-
-
-Changes with nginx 0.7.36 21 Feb 2009
-
- *) Feature: a preliminary IPv6 support; the "listen" directive of the
- HTTP module supports IPv6.
-
- *) Bugfix: the $ancient_browser variable did not work for browsers
- preset by a "modern_browser" directives.
-
-
-Changes with nginx 0.7.35 16 Feb 2009
-
- *) Bugfix: a "ssl_engine" directive did not use a SSL-accelerator for
- asymmetric ciphers.
- Thanks to Marcin Gozdalik.
-
- *) Bugfix: a "try_files" directive set MIME type depending on an
- original request extension.
-
- *) Bugfix: "*domain.tld" names were handled incorrectly in
- "server_name", "valid_referers", and "map" directives, if
- ".domain.tld" and ".subdomain.domain.tld" wildcards were used;
- the bug had appeared in 0.7.9.
-
-
-Changes with nginx 0.7.34 10 Feb 2009
-
- *) Feature: the "off" parameter of the "if_modified_since" directive.
-
- *) Feature: now nginx sends an HELO/EHLO command after a XCLIENT
- command.
- Thanks to Maxim Dounin.
-
- *) Feature: Microsoft specific "AUTH LOGIN with User Name" mode support
- in mail proxy server.
- Thanks to Maxim Dounin.
-
- *) Bugfix: in a redirect rewrite directive original arguments were
- concatenated with new arguments by a "?" rather than an "&";
- the bug had appeared in 0.1.18.
- Thanks to Maxim Dounin.
-
- *) Bugfix: nginx could not be built on AIX.
-
-
-Changes with nginx 0.7.33 02 Feb 2009
-
- *) Bugfix: a double response might be returned if the epoll or rtsig
- methods are used and a redirect was returned to a request with body.
- Thanks to Eden Li.
-
- *) Bugfix: the $sent_http_location variable was empty for some redirects
- types.
-
- *) Bugfix: a segmentation fault might occur in worker process if
- "resolver" directive was used in SMTP proxy.
-
-
-Changes with nginx 0.7.32 26 Jan 2009
-
- *) Feature: now a directory existence testing can be set explicitly in
- the "try_files" directive.
-
- *) Bugfix: fastcgi_store stored files not always.
-
- *) Bugfix: in geo ranges.
-
- *) Bugfix: in shared memory allocations if nginx was built without
- debugging.
- Thanks to Andrey Kvasov.
-
-
-Changes with nginx 0.7.31 19 Jan 2009
-
- *) Change: now the "try_files" directive tests files only and ignores
- directories.
-
- *) Feature: the "fastcgi_split_path_info" directive.
-
- *) Bugfixes in an "Expect" request header line support.
-
- *) Bugfixes in geo ranges.
-
- *) Bugfix: in a miss case ngx_http_memcached_module returned the "END"
- line as response body instead of default 404 page body; the bug had
- appeared in 0.7.18.
- Thanks to Maxim Dounin.
-
- *) Bugfix: while SMTP proxying nginx issued message "250 2.0.0 OK"
- instead of "235 2.0.0 OK"; the bug had appeared in 0.7.22.
- Thanks to Maxim Dounin.
-
-
-Changes with nginx 0.7.30 24 Dec 2008
-
- *) Bugfix: a segmentation fault occurred in worker process, if variables
- were used in the "fastcgi_pass" or "proxy_pass" directives and host
- name must be resolved; the bug had appeared in 0.7.29.
-
-
-Changes with nginx 0.7.29 24 Dec 2008
-
- *) Bugfix: the "fastcgi_pass" and "proxy_pass" directives did not
- support variables if unix domain sockets were used.
-
- *) Bugfixes in subrequest processing; the bugs had appeared in 0.7.25.
-
- *) Bugfix: a "100 Continue" response was issued for HTTP/1.0 requests;
- Thanks to Maxim Dounin.
-
- *) Bugfix: in memory allocation in the ngx_http_gzip_filter_module on
- Cygwin.
-
-
-Changes with nginx 0.7.28 22 Dec 2008
-
- *) Change: in memory allocation in the ngx_http_gzip_filter_module.
-
- *) Change: the default "gzip_buffers" directive values have been changed
- to 32 4k or 16 8k from 4 4k/8k.
-
-
-Changes with nginx 0.7.27 15 Dec 2008
-
- *) Feature: the "try_files" directive.
-
- *) Feature: variables support in the "fastcgi_pass" directive.
-
- *) Feature: now the $geo variable may get an address from a variable.
- Thanks to Andrei Nigmatulin.
-
- *) Feature: now a location's modifier may be used without space before
- name.
-
- *) Feature: the $upstream_response_length variable.
-
- *) Bugfix: now a "add_header" directive does not add an empty value.
-
- *) Bugfix: if zero length static file was requested, then nginx just
- closed connection; the bug had appeared in 0.7.25.
-
- *) Bugfix: a MOVE method could not move file in non-existent directory.
-
- *) Bugfix: a segmentation fault occurred in worker process, if no one
- named location was defined in server, but some one was used in an
- error_page directive.
- Thanks to Sergey Bochenkov.
-
-
-Changes with nginx 0.7.26 08 Dec 2008
-
- *) Bugfix: in subrequest processing; the bug had appeared in 0.7.25.
-
-
-Changes with nginx 0.7.25 08 Dec 2008
-
- *) Change: in subrequest processing.
-
- *) Change: now POSTs without "Content-Length" header line are allowed.
-
- *) Bugfix: now the "limit_req" and "limit_conn" directives log a
- prohibition reason.
-
- *) Bugfix: in the "delete" parameter of the "geo" directive.
-
-
-Changes with nginx 0.7.24 01 Dec 2008
-
- *) Feature: the "if_modified_since" directive.
-
- *) Bugfix: nginx did not process a FastCGI server response, if the
- server send too many messages to stderr before response.
-
- *) Bugfix: the "$cookie_..." variables did not work in the SSI and the
- perl module.
-
-
-Changes with nginx 0.7.23 27 Nov 2008
-
- *) Feature: the "delete" and "ranges" parameters in the "geo" directive.
-
- *) Feature: speeding up loading of geo base with large number of values.
-
- *) Feature: decrease of memory required for geo base load.
-
-
-Changes with nginx 0.7.22 20 Nov 2008
-
- *) Feature: the "none" parameter in the "smtp_auth" directive.
- Thanks to Maxim Dounin.
-
- *) Feature: the "$cookie_..." variables.
-
- *) Bugfix: the "directio" directive did not work in XFS filesystem.
-
- *) Bugfix: the resolver did not understand big DNS responses.
- Thanks to Zyb.
-
-
-Changes with nginx 0.7.21 11 Nov 2008
-
- *) Changes in the ngx_http_limit_req_module.
-
- *) Feature: the EXSLT support in the ngx_http_xslt_module.
- Thanks to Denis F. Latypoff.
-
- *) Workaround: compatibility with glibc 2.3.
- Thanks to Eric Benson and Maxim Dounin.
-
- *) Bugfix: nginx could not run on MacOSX 10.4 and earlier; the bug had
- appeared in 0.7.6.
-
-
-Changes with nginx 0.7.20 10 Nov 2008
-
- *) Changes in the ngx_http_gzip_filter_module.
-
- *) Feature: the ngx_http_limit_req_module.
-
- *) Bugfix: worker processes might exit on a SIGBUS signal on sparc and
- ppc platforms; the bug had appeared in 0.7.3.
- Thanks to Maxim Dounin.
-
- *) Bugfix: the "proxy_pass http://host/some:uri" directives did not
- work; the bug had appeared in 0.7.12.
-
- *) Bugfix: in HTTPS mode requests might fail with the "bad write retry"
- error.
-
- *) Bugfix: the ngx_http_secure_link_module did not work inside
- locations, whose names are less than 3 characters.
-
- *) Bugfix: $server_addr variable might have no value.
-
-
-Changes with nginx 0.7.19 13 Oct 2008
-
- *) Bugfix: version number update.
-
-
-Changes with nginx 0.7.18 13 Oct 2008
-
- *) Change: the "underscores_in_headers" directive; now nginx does not
- allows underscores in a client request header line names.
-
- *) Feature: the ngx_http_secure_link_module.
-
- *) Feature: the "real_ip_header" directive supports any header.
-
- *) Feature: the "log_subrequest" directive.
-
- *) Feature: the $realpath_root variable.
-
- *) Feature: the "http_502" and "http_504" parameters of the
- "proxy_next_upstream" directive.
-
- *) Bugfix: the "http_503" parameter of the "proxy_next_upstream" or
- "fastcgi_next_upstream" directives did not work.
-
- *) Bugfix: nginx might send a "Transfer-Encoding: chunked" header line
- for HEAD requests.
-
- *) Bugfix: now accept threshold depends on worker_connections.
-
-
-Changes with nginx 0.7.17 15 Sep 2008
-
- *) Feature: now the "directio" directive works on Linux.
-
- *) Feature: the $pid variable.
-
- *) Bugfix: the "directio" optimization that had appeared in 0.7.15 did
- not work with open_file_cache.
-
- *) Bugfix: the "access_log" with variables did not work on Linux; the
- bug had appeared in 0.7.7.
-
- *) Bugfix: the ngx_http_charset_module did not understand quoted charset
- name received from backend.
-
-
-Changes with nginx 0.7.16 08 Sep 2008
-
- *) Bugfix: nginx could not be built on 64-bit platforms; the bug had
- appeared in 0.7.15.
-
-
-Changes with nginx 0.7.15 08 Sep 2008
-
- *) Feature: the ngx_http_random_index_module.
-
- *) Feature: the "directio" directive has been optimized for file
- requests starting from arbitrary position.
-
- *) Feature: the "directio" directive turns off sendfile if it is
- necessary.
-
- *) Feature: now nginx allows underscores in a client request header line
- names.
-
-
-Changes with nginx 0.7.14 01 Sep 2008
-
- *) Change: now the ssl_certificate and ssl_certificate_key directives
- have no default values.
-
- *) Feature: the "listen" directive supports the "ssl" parameter.
-
- *) Feature: now nginx takes into account a time zone change while
- reconfiguration on FreeBSD and Linux.
-
- *) Bugfix: the "listen" directive parameters such as "backlog",
- "rcvbuf", etc. were not set, if a default server was not the first
- one.
-
- *) Bugfix: if URI part captured by a "rewrite" directive was used as a
- query string, then the query string was not escaped.
-
- *) Bugfix: configuration file validity test improvements.
-
-
-Changes with nginx 0.7.13 26 Aug 2008
-
- *) Bugfix: nginx could not be built on Linux and Solaris; the bug had
- appeared in 0.7.12.
-
-
-Changes with nginx 0.7.12 26 Aug 2008
-
- *) Feature: the "server_name" directive supports empty name "".
-
- *) Feature: the "gzip_disable" directive supports special "msie6" mask.
-
- *) Bugfix: if the "max_fails=0" parameter was used in upstream with
- several servers, then a worker process exited on a SIGFPE signal.
- Thanks to Maxim Dounin.
-
- *) Bugfix: a request body was dropped while redirection via an
- "error_page" directive.
-
- *) Bugfix: a full response was returned for request method HEAD while
- redirection via an "error_page" directive.
-
- *) Bugfix: the $r->header_in() method did not return value of the
- "Host", "User-Agent", and "Connection" request header lines; the bug
- had appeared in 0.7.0.
-
-
-Changes with nginx 0.7.11 18 Aug 2008
-
- *) Change: now ngx_http_charset_module does not work by default with
- text/css MIME type.
-
- *) Feature: now nginx returns the 405 status code for POST method
- requesting a static file only if the file exists.
-
- *) Feature: the "proxy_ssl_session_reuse" directive.
-
- *) Bugfix: a "proxy_pass" directive without URI part might use original
- request after the "X-Accel-Redirect" redirection was used;
-
- *) Bugfix: if a directory has search only rights and the first index
- file was absent, then nginx returned the 500 status code.
-
- *) Bugfix: in inclusive locations; the bugs had appeared in 0.7.1.
-
-
-Changes with nginx 0.7.10 13 Aug 2008
-
- *) Bugfix: in the "addition_types", "charset_types", "gzip_types",
- "ssi_types", "sub_filter_types", and "xslt_types" directives; the
- bugs had appeared in 0.7.9.
-
- *) Bugfix: of recursive error_page for 500 status code.
-
- *) Bugfix: now the ngx_http_realip_module sets address not for whole
- keepalive connection, but for each request passed via the connection.
-
-
-Changes with nginx 0.7.9 12 Aug 2008
-
- *) Change: now ngx_http_charset_module works by default with following
- MIME types: text/html, text/css, text/xml, text/plain,
- text/vnd.wap.wml, application/x-javascript, and application/rss+xml.
-
- *) Feature: the "charset_types" and "addition_types" directives.
-
- *) Feature: now the "gzip_types", "ssi_types", and "sub_filter_types"
- directives use hash.
-
- *) Feature: the ngx_cpp_test_module.
-
- *) Feature: the "expires" directive supports daily time.
-
- *) Feature: the ngx_http_xslt_module improvements and bug fixing.
- Thanks to Denis F. Latypoff and Maxim Dounin.
-
- *) Bugfix: the "log_not_found" directive did not work for index files
- tests.
-
- *) Bugfix: HTTPS connections might hang, if kqueue, epoll, rtsig, or
- eventport methods were used; the bug had appeared in 0.7.7.
-
- *) Bugfix: if the "server_name", "valid_referers", and "map" directives
- used an "*.domain.tld" wildcard and exact name "domain.tld" was not
- set, then the exact name was matched by the wildcard; the bug had
- appeared in 0.3.18.
-
-
-Changes with nginx 0.7.8 04 Aug 2008
-
- *) Feature: the ngx_http_xslt_module.
-
- *) Feature: the "$arg_..." variables.
-
- *) Feature: Solaris directio support.
- Thanks to Ivan Debnar.
-
- *) Bugfix: now if FastCGI server sends a "Location" header line without
- status line, then nginx uses 302 status code.
- Thanks to Maxim Dounin.
-
-
-Changes with nginx 0.7.7 30 Jul 2008
-
- *) Change: now the EAGAIN error returned by connect() is not considered
- as temporary error.
-
- *) Change: now the $ssl_client_cert variable value is a certificate with
- TAB character intended before each line except first one; an
- unchanged certificate is available in the $ssl_client_raw_cert
- variable.
-
- *) Feature: the "ask" parameter in the "ssl_verify_client" directive.
-
- *) Feature: byte-range processing improvements.
- Thanks to Maxim Dounin.
-
- *) Feature: the "directio" directive.
- Thanks to Jiang Hong.
-
- *) Feature: MacOSX 10.5 sendfile() support.
-
- *) Bugfix: now in MacOSX and Cygwin locations are tested in case
- insensitive mode; however, the compare is provided by single-byte
- locales only.
-
- *) Bugfix: mail proxy SSL connections hanged, if select, poll, or
- /dev/poll methods were used.
-
- *) Bugfix: UTF-8 encoding usage in the ngx_http_autoindex_module.
-
-
-Changes with nginx 0.7.6 07 Jul 2008
-
- *) Bugfix: now if variables are used in the "access_log" directive a
- request root existence is always tested.
-
- *) Bugfix: the ngx_http_flv_module did not support several values in a
- query string.
-
-
-Changes with nginx 0.7.5 01 Jul 2008
-
- *) Bugfixes in variables support in the "access_log" directive; the bugs
- had appeared in 0.7.4.
-
- *) Bugfix: nginx could not be built --without-http_gzip_module; the bug
- had appeared in 0.7.3.
- Thanks to Kirill A. Korinskiy.
-
- *) Bugfix: if sub_filter and SSI were used together, then responses
- might were transferred incorrectly.
-
-
-Changes with nginx 0.7.4 30 Jun 2008
-
- *) Feature: variables support in the "access_log" directive.
-
- *) Feature: the "open_log_file_cache" directive.
-
- *) Feature: the -g switch.
-
- *) Feature: the "Expect" request header line support.
-
- *) Bugfix: large SSI inclusions might be truncated.
-
-
-Changes with nginx 0.7.3 23 Jun 2008
-
- *) Change: the "rss" extension MIME type has been changed to
- "application/rss+xml".
-
- *) Change: now the "gzip_vary" directive turned on issues a
- "Vary: Accept-Encoding" header line for uncompressed responses too.
-
- *) Feature: now the "rewrite" directive does a redirect automatically if
- the "https://" protocol is used.
-
- *) Bugfix: the "proxy_pass" directive did not work with the HTTPS
- protocol; the bug had appeared in 0.6.9.
-
-
-Changes with nginx 0.7.2 16 Jun 2008
-
- *) Feature: now nginx supports EDH key exchange ciphers.
-
- *) Feature: the "ssl_dhparam" directive.
-
- *) Feature: the $ssl_client_cert variable.
- Thanks to Manlio Perillo.
-
- *) Bugfix: after changing URI via a "rewrite" directive nginx did not
- search a new location; the bug had appeared in 0.7.1.
- Thanks to Maxim Dounin.
-
- *) Bugfix: nginx could not be built without PCRE library; the bug had
- appeared in 0.7.1.
-
- *) Bugfix: when a request to a directory was redirected with the slash
- added, nginx dropped a query string from the original request.
-
-
-Changes with nginx 0.7.1 26 May 2008
-
- *) Change: now locations are searched in a tree.
-
- *) Change: the "optimize_server_names" directive was canceled due to the
- "server_name_in_redirect" directive introduction.
-
- *) Change: some long deprecated directives are not supported anymore.
-
- *) Change: the "none" parameter in the "ssl_session_cache" directive;
- now this is default parameter.
- Thanks to Rob Mueller.
-
- *) Bugfix: worker processes might not catch reconfiguration and log
- rotation signals.
-
- *) Bugfix: nginx could not be built on latest Fedora 9 Linux.
- Thanks to Roxis.
-
-
-Changes with nginx 0.7.0 19 May 2008
-
- *) Change: now the 0x00-0x1F, '"' and '\' characters are escaped as \xXX
- in an access_log.
- Thanks to Maxim Dounin.
-
- *) Change: now nginx allows several "Host" request header line.
-
- *) Feature: the "modified" flag in the "expires" directive.
-
- *) Feature: the $uid_got and $uid_set variables may be used at any
- request processing stage.
-
- *) Feature: the $hostname variable.
- Thanks to Andrei Nigmatulin.
-
- *) Feature: DESTDIR support.
- Thanks to Todd A. Fisher and Andras Voroskoi.
-
- *) Bugfix: a segmentation fault might occur in worker process on Linux,
- if keepalive was enabled.
-
-
-Changes with nginx 0.6.31 12 May 2008
-
- *) Bugfix: nginx did not process FastCGI response if header was at the
- end of FastCGI record; the bug had appeared in 0.6.2.
- Thanks to Sergey Serov.
-
- *) Bugfix: a segmentation fault might occur in worker process if a file
- was deleted and the "open_file_cache_errors" directive was off.
-
-
-Changes with nginx 0.6.30 29 Apr 2008
-
- *) Change: now if an "include" directive pattern does not match any
- file, then nginx does not issue an error.
-
- *) Feature: now the time in directives may be specified without spaces,
- for example, "1h50m".
-
- *) Bugfix: memory leaks if the "ssl_verify_client" directive was on.
- Thanks to Chavelle Vincent.
-
- *) Bugfix: the "sub_filter" directive might set text to change into
- output.
-
- *) Bugfix: the "error_page" directive did not take into account
- arguments in redirected URI.
-
- *) Bugfix: now nginx always opens files in binary mode under Cygwin.
-
- *) Bugfix: nginx could not be built on OpenBSD; the bug had appeared in
- 0.6.15.
-
-
-Changes with nginx 0.6.29 18 Mar 2008
-
- *) Feature: the ngx_google_perftools_module.
-
- *) Bugfix: the ngx_http_perl_module could not be built on 64-bit
- platforms; the bug had appeared in 0.6.27.
-
-
-Changes with nginx 0.6.28 13 Mar 2008
-
- *) Bugfix: the rtsig method could not be built; the bug had appeared in
- 0.6.27.
-
-
-Changes with nginx 0.6.27 12 Mar 2008
-
- *) Change: now by default the rtsig method is not built on
- Linux 2.6.18+.
-
- *) Change: now a request method is not changed while redirection to a
- named location via an "error_page" directive.
-
- *) Feature: the "resolver" and "resolver_timeout" directives in SMTP
- proxy.
-
- *) Feature: the "post_action" directive supports named locations.
-
- *) Bugfix: a segmentation fault occurred in worker process, if a request
- was redirected from proxy, FastCGI, or memcached location to static
- named locations.
-
- *) Bugfix: browsers did not repeat SSL handshake if there is no valid
- client certificate in first handshake.
- Thanks to Alexander V. Inyukhin.
-
- *) Bugfix: if response code 495-497 was redirected via an "error_page"
- directive without code change, then nginx tried to allocate too many
- memory.
-
- *) Bugfix: memory leak in long-lived non buffered connections.
-
- *) Bugfix: memory leak in resolver.
-
- *) Bugfix: a segmentation fault occurred in worker process, if a request
- was redirected from proxy, FastCGI, or memcached location to static
- named locations.
-
- *) Bugfix: in the $proxy_host and $proxy_port variables caching.
- Thanks to Sergey Bochenkov.
-
- *) Bugfix: a "proxy_pass" directive with variables used incorrectly the
- same port as in another "proxy_pass" directive with the same host
- name and without variables.
- Thanks to Sergey Bochenkov.
-
- *) Bugfix: an alert "sendmsg() failed (9: Bad file descriptor)" on some
- 64-bit platforms while reconfiguration.
-
- *) Bugfix: a segmentation fault occurred in worker process, if empty
- stub block was used second time in SSI.
-
- *) Bugfix: in copying URI part contained escaped symbols into arguments.
-
-
-Changes with nginx 0.6.26 11 Feb 2008
-
- *) Bugfix: the "proxy_store" and "fastcgi_store" directives did not
- check a response length.
-
- *) Bugfix: a segmentation fault occurred in worker process, if big value
- was used in a "expires" directive.
- Thanks to Joaquin Cuenca Abela.
-
- *) Bugfix: nginx incorrectly detected cache line size on Pentium 4.
- Thanks to Gena Makhomed.
-
- *) Bugfix: in proxied or FastCGI subrequests a client original method
- was used instead of the GET method.
-
- *) Bugfix: socket leak in HTTPS mode if deferred accept was used.
- Thanks to Ben Maurer.
-
- *) Bugfix: nginx issued the bogus error message "SSL_shutdown() failed
- (SSL: )"; the bug had appeared in 0.6.23.
-
- *) Bugfix: in HTTPS mode requests might fail with the "bad write retry"
- error; the bug had appeared in 0.6.23.
-
-
-Changes with nginx 0.6.25 08 Jan 2008
-
- *) Change: now the "server_name_in_redirect" directive is used instead
- of the "server_name" directive's special "*" parameter.
-
- *) Change: now wildcard and regex names can be used as main name in a
- "server_name" directive.
-
- *) Change: the "satisfy_any" directive was replaced by the "satisfy"
- directive.
-
- *) Workaround: old worker processes might hog CPU after reconfiguration
- if they was run under Linux OpenVZ.
-
- *) Feature: the "min_delete_depth" directive.
-
- *) Bugfix: the COPY and MOVE methods did not work with single files.
-
- *) Bugfix: the ngx_http_gzip_static_module did not allow the
- ngx_http_dav_module to work; the bug had appeared in 0.6.23.
-
- *) Bugfix: socket leak in HTTPS mode if deferred accept was used.
- Thanks to Ben Maurer.
-
- *) Bugfix: nginx could not be built without PCRE library; the bug had
- appeared in 0.6.23.
-
-
-Changes with nginx 0.6.24 27 Dec 2007
-
- *) Bugfix: a segmentation fault might occur in worker process if HTTPS
- was used; the bug had appeared in 0.6.23.
-
-
-Changes with nginx 0.6.23 27 Dec 2007
-
- *) Change: the "off" parameter in the "ssl_session_cache" directive; now
- this is default parameter.
-
- *) Change: the "open_file_cache_retest" directive was renamed to the
- "open_file_cache_valid".
-
- *) Feature: the "open_file_cache_min_uses" directive.
-
- *) Feature: the ngx_http_gzip_static_module.
-
- *) Feature: the "gzip_disable" directive.
-
- *) Feature: the "memcached_pass" directive may be used inside the "if"
- block.
-
- *) Bugfix: a segmentation fault occurred in worker process, if the
- "memcached_pass" and "if" directives were used in the same location.
-
- *) Bugfix: if a "satisfy_any on" directive was used and not all access
- and auth modules directives were set, then other given access and
- auth directives were not tested;
-
- *) Bugfix: regex parameters in a "valid_referers" directive were not
- inherited from previous level.
-
- *) Bugfix: a "post_action" directive did run if a request was completed
- with 499 status code.
-
- *) Bugfix: optimization of 16K buffer usage in a SSL connection.
- Thanks to Ben Maurer.
-
- *) Bugfix: the STARTTLS in SMTP mode did not work.
- Thanks to Oleg Motienko.
-
- *) Bugfix: in HTTPS mode requests might fail with the "bad write retry"
- error; the bug had appeared in 0.5.13.
-
-
-Changes with nginx 0.6.22 19 Dec 2007
-
- *) Change: now all ngx_http_perl_module methods return values copied to
- perl's allocated memory.
-
- *) Bugfix: if nginx was built with ngx_http_perl_module, the perl before
- 5.8.6 was used, and perl supported threads, then during
- reconfiguration the master process aborted; the bug had appeared in
- 0.5.9.
- Thanks to Boris Zhmurov.
-
- *) Bugfix: the ngx_http_perl_module methods may get invalid values of
- the regex captures.
-
- *) Bugfix: a segmentation fault occurred in worker process, if the
- $r->has_request_body() method was called for a request whose small
- request body was already received.
-
- *) Bugfix: large_client_header_buffers did not freed before going to
- keep-alive state.
- Thanks to Olexander Shtepa.
-
- *) Bugfix: the last address was missed in the $upstream_addr variable;
- the bug had appeared in 0.6.18.
-
- *) Bugfix: the "fastcgi_catch_stderr" directive did return error code;
- now it returns 502 code, that can be rerouted to a next server using
- the "fastcgi_next_upstream invalid_header" directive.
-
- *) Bugfix: a segmentation fault occurred in master process if the
- "fastcgi_catch_stderr" directive was used; the bug had appeared in
- 0.6.10.
- Thanks to Manlio Perillo.
-
-
-Changes with nginx 0.6.21 03 Dec 2007
-
- *) Change: if variable values used in a "proxy_pass" directive contain
- IP-addresses only, then a "resolver" directive is not mandatory.
-
- *) Bugfix: a segmentation fault might occur in worker process if a
- "proxy_pass" directive with URI-part was used; the bug had appeared
- in 0.6.19.
-
- *) Bugfix: if resolver was used on platform that does not support
- kqueue, then nginx issued an alert "name is out of response".
- Thanks to Andrei Nigmatulin.
-
- *) Bugfix: if the $server_protocol was used in FastCGI parameters and a
- request line length was near to the "client_header_buffer_size"
- directive value, then nginx issued an alert "fastcgi: the request
- record is too big".
-
- *) Bugfix: if a plain text HTTP/0.9 version request was made to HTTPS
- server, then nginx returned usual response.
-
-
-Changes with nginx 0.6.20 28 Nov 2007
-
- *) Bugfix: a segmentation fault might occur in worker process if a
- "proxy_pass" directive with URI-part was used; the bug had appeared
- in 0.6.19.
-
-
-Changes with nginx 0.6.19 27 Nov 2007
-
- *) Bugfix: the 0.6.18 version could not be built.
-
-
-Changes with nginx 0.6.18 27 Nov 2007
-
- *) Change: now the ngx_http_userid_module adds start time microseconds
- to the cookie field contains a pid value.
-
- *) Change: now the full request line instead of URI only is written to
- error_log.
-
- *) Feature: variables support in the "proxy_pass" directive.
-
- *) Feature: the "resolver" and "resolver_timeout" directives.
-
- *) Feature: now the directive "add_header last-modified ''" deletes a
- "Last-Modified" response header line.
-
- *) Bugfix: the "limit_rate" directive did not allow to use full
- throughput, even if limit value was very high.
-
-
-Changes with nginx 0.6.17 15 Nov 2007
-
- *) Feature: the "If-Range" request header line support.
- Thanks to Alexander V. Inyukhin.
-
- *) Bugfix: URL double escaping in a redirect of the "msie_refresh"
- directive; the bug had appeared in 0.6.4.
-
- *) Bugfix: the "autoindex" directive did not work with the "alias /"
- directive.
-
- *) Bugfix: a segmentation fault might occur in worker process if
- subrequests were used.
-
- *) Bugfix: the big responses may be transferred truncated if SSL and
- gzip were used.
-
- *) Bugfix: the $status variable was equal to 0 if a proxied server
- returned response in HTTP/0.9 version.
-
-
-Changes with nginx 0.6.16 29 Oct 2007
-
- *) Change: now the uname(2) is used on Linux instead of procfs.
- Thanks to Ilya Novikov.
-
- *) Bugfix: if the "?" character was in a "error_page" directive, then it
- was escaped in a proxied request; the bug had appeared in 0.6.11.
-
- *) Bugfix: compatibility with mget.
-
-
-Changes with nginx 0.6.15 22 Oct 2007
-
- *) Feature: Cygwin compatibility.
- Thanks to Vladimir Kutakov.
-
- *) Feature: the "merge_slashes" directive.
-
- *) Feature: the "gzip_vary" directive.
-
- *) Feature: the "server_tokens" directive.
-
- *) Bugfix: nginx did not unescape URI in the "include" SSI command.
-
- *) Bugfix: the segmentation fault was occurred on start or while
- reconfiguration if variable was used in the "charset" or
- "source_charset" directives.
-
- *) Bugfix: nginx returned the 400 response on requests like
- "GET http://www.domain.com HTTP/1.0".
- Thanks to James Oakley.
-
- *) Bugfix: if request with request body was redirected using the
- "error_page" directive, then nginx tried to read the request body
- again; the bug had appeared in 0.6.7.
-
- *) Bugfix: a segmentation fault occurred in worker process if no
- server_name was explicitly defined for server processing request; the
- bug had appeared in 0.6.7.
-
-
-Changes with nginx 0.6.14 15 Oct 2007
-
- *) Change: now by default the "echo" SSI command uses entity encoding.
-
- *) Feature: the "encoding" parameter in the "echo" SSI command.
-
- *) Feature: the "access_log" directive may be used inside the
- "limit_except" block.
-
- *) Bugfix: if all upstream servers were failed, then all servers had got
- weight the was equal one until servers became alive; the bug had
- appeared in 0.6.6.
-
- *) Bugfix: a segmentation fault occurred in worker process if
- $date_local and $date_gmt were used outside the
- ngx_http_ssi_filter_module.
-
- *) Bugfix: a segmentation fault might occur in worker process if debug
- log was enabled.
- Thanks to Andrei Nigmatulin.
-
- *) Bugfix: ngx_http_memcached_module did not set
- $upstream_response_time.
- Thanks to Maxim Dounin.
-
- *) Bugfix: a worker process may got caught in an endless loop, if the
- memcached was used.
-
- *) Bugfix: nginx supported low case only "close" and "keep-alive" values
- in the "Connection" request header line; the bug had appeared in
- 0.6.11.
-
- *) Bugfix: sub_filter did not work with empty substitution.
-
- *) Bugfix: in sub_filter parsing.
-
-
-Changes with nginx 0.6.13 24 Sep 2007
-
- *) Bugfix: nginx did not close directory file on HEAD request if
- autoindex was used.
- Thanks to Arkadiusz Patyk.
-
-
-Changes with nginx 0.6.12 21 Sep 2007
-
- *) Change: mail proxy was split on three modules: pop3, imap and smtp.
-
- *) Feature: the --without-mail_pop3_module, --without-mail_imap_module,
- and --without-mail_smtp_module configuration parameters.
-
- *) Feature: the "smtp_greeting_delay" and "smtp_client_buffer"
- directives of the ngx_mail_smtp_module.
-
- *) Bugfix: the trailing wildcards did not work; the bug had appeared in
- 0.6.9.
-
- *) Bugfix: nginx could not start on Solaris if the shared PCRE library
- located in non-standard place was used.
-
- *) Bugfix: the "proxy_hide_header" and "fastcgi_hide_header" directives
- did not hide response header lines whose name was longer than 32
- characters.
- Thanks to Manlio Perillo.
-
-
-Changes with nginx 0.6.11 11 Sep 2007
-
- *) Bugfix: active connection counter always increased if mail proxy was
- used.
-
- *) Bugfix: if backend returned response header only using non-buffered
- proxy, then nginx closed backend connection on timeout.
-
- *) Bugfix: nginx did not support several "Connection" request header
- lines.
-
- *) Bugfix: if the "max_fails" was set for upstream server, then after
- first failure server weight was always one; the bug had appeared in
- 0.6.6.
-
-
-Changes with nginx 0.6.10 03 Sep 2007
-
- *) Feature: the "open_file_cache", "open_file_cache_retest", and
- "open_file_cache_errors" directives.
-
- *) Bugfix: socket leak; the bug had appeared in 0.6.7.
-
- *) Bugfix: a charset set by the "charset" directive was not appended to
- the "Content-Type" header set by $r->send_http_header().
-
- *) Bugfix: a segmentation fault might occur in worker process if
- /dev/poll method was used.
-
-
-Changes with nginx 0.6.9 28 Aug 2007
-
- *) Bugfix: a worker process may got caught in an endless loop, if the
- HTTPS protocol was used; the bug had appeared in 0.6.7.
-
- *) Bugfix: if server listened on two addresses or ports and trailing
- wildcard was used, then nginx did not run.
-
- *) Bugfix: the "ip_hash" directive might incorrectly mark servers as
- down.
-
- *) Bugfix: nginx could not be built on amd64; the bug had appeared in
- 0.6.8.
-
-
-Changes with nginx 0.6.8 20 Aug 2007
-
- *) Change: now nginx tries to set the "worker_priority",
- "worker_rlimit_nofile", "worker_rlimit_core", and
- "worker_rlimit_sigpending" without super-user privileges.
-
- *) Change: now nginx escapes space and "%" in request to a mail proxy
- authentication server.
-
- *) Change: now nginx escapes "%" in $memcached_key variable.
-
- *) Bugfix: nginx used path relative to configuration prefix for
- non-absolute configuration file path specified in the "-c" key; the
- bug had appeared in 0.6.6.
-
- *) Bugfix: nginx did not work on FreeBSD/sparc64.
-
-
-Changes with nginx 0.6.7 15 Aug 2007
-
- *) Change: now the paths specified in the "include",
- "auth_basic_user_file", "perl_modules", "ssl_certificate",
- "ssl_certificate_key", and "ssl_client_certificate" directives are
- relative to directory of nginx configuration file nginx.conf, but not
- to nginx prefix directory.
-
- *) Change: the --sysconfdir=PATH option in configure was canceled.
-
- *) Change: the special make target "upgrade1" was defined for online
- upgrade of 0.1.x versions.
-
- *) Feature: the "server_name" and "valid_referers" directives support
- regular expressions.
-
- *) Feature: the "server" directive in the "upstream" context supports
- the "backup" parameter.
-
- *) Feature: the ngx_http_perl_module supports the
- $r->discard_request_body.
-
- *) Feature: the "add_header Last-Modified ..." directive changes the
- "Last-Modified" response header line.
-
- *) Bugfix: if a response different than 200 was returned to a request
- with body and connection went to the keep-alive state after the
- request, then nginx returned 400 for the next request.
-
- *) Bugfix: a segmentation fault occurred in worker process if invalid
- address was set in the "auth_http" directive.
-
- *) Bugfix: now nginx uses default listen backlog value 511 on all
- platforms except FreeBSD.
- Thanks to Jiang Hong.
-
- *) Bugfix: a worker process may got caught in an endless loop, if a
- "server" inside "upstream" block was marked as "down"; the bug had
- appeared in 0.6.6.
-
- *) Bugfix: now Solaris sendfilev() is not used to transfer the client
- request body to FastCGI-server via the unix domain socket.
-
-
-Changes with nginx 0.6.6 30 Jul 2007
-
- *) Feature: the --sysconfdir=PATH option in configure.
-
- *) Feature: named locations.
-
- *) Feature: the $args variable can be set with the "set" directive.
-
- *) Feature: the $is_args variable.
-
- *) Bugfix: fair big weight upstream balancer.
-
- *) Bugfix: if a client has closed connection to mail proxy then nginx
- might not close connection to backend.
-
- *) Bugfix: if the same host without specified port was used as backend
- for HTTP and HTTPS, then nginx used only one port - 80 or 443.
-
- *) Bugfix: fix building on Solaris/amd64 by Sun Studio 11 and early
- versions; the bug had appeared in 0.6.4.
-
-
-Changes with nginx 0.6.5 23 Jul 2007
-
- *) Feature: $nginx_version variable.
- Thanks to Nick S. Grechukh.
-
- *) Feature: the mail proxy supports AUTHENTICATE in IMAP mode.
- Thanks to Maxim Dounin.
-
- *) Feature: the mail proxy supports STARTTLS in SMTP mode.
- Thanks to Maxim Dounin.
-
- *) Bugfix: now nginx escapes space in $memcached_key variable.
-
- *) Bugfix: nginx was incorrectly built by Sun Studio on Solaris/amd64.
- Thanks to Jiang Hong.
-
- *) Bugfix: of minor potential bugs.
- Thanks to Coverity's Scan.
-
-
-Changes with nginx 0.6.4 17 Jul 2007
-
- *) Security: the "msie_refresh" directive allowed XSS.
- Thanks to Maxim Boguk.
-
- *) Change: the "proxy_store" and "fastcgi_store" directives were
- changed.
-
- *) Feature: the "proxy_store_access" and "fastcgi_store_access"
- directives.
-
- *) Bugfix: nginx did not work on Solaris/sparc64 if it was built by Sun
- Studio.
- Thanks to Andrei Nigmatulin.
-
- *) Workaround: for Sun Studio 12.
- Thanks to Jiang Hong.
-
-
-Changes with nginx 0.6.3 12 Jul 2007
-
- *) Feature: the "proxy_store" and "fastcgi_store" directives.
-
- *) Bugfix: a segmentation fault might occur in worker process if the
- "auth_http_header" directive was used.
- Thanks to Maxim Dounin.
-
- *) Bugfix: a segmentation fault occurred in worker process if the
- CRAM-MD5 authentication method was used, but it was not enabled.
-
- *) Bugfix: a segmentation fault might occur in worker process when the
- HTTPS protocol was used in the "proxy_pass" directive.
-
- *) Bugfix: a segmentation fault might occur in worker process if the
- eventport method was used.
-
- *) Bugfix: the "proxy_ignore_client_abort" and
- "fastcgi_ignore_client_abort" directives did not work; the bug had
- appeared in 0.5.13.
-
-
-Changes with nginx 0.6.2 09 Jul 2007
-
- *) Bugfix: if the FastCGI header was split in records, then nginx passed
- garbage in the header to a client.
-
-
-Changes with nginx 0.6.1 17 Jun 2007
-
- *) Bugfix: in SSI parsing.
-
- *) Bugfix: if remote SSI subrequest was used, then posterior local file
- subrequest might transferred to client in wrong order.
-
- *) Bugfix: large SSI inclusions buffered in temporary files were
- truncated.
-
- *) Bugfix: the perl $$ variable value in ngx_http_perl_module was equal
- to the master process identification number.
-
-
-Changes with nginx 0.6.0 14 Jun 2007
-
- *) Feature: the "server_name", "map", and "valid_referers" directives
- support the "www.example.*" wildcards.
-
-
-Changes with nginx 0.5.25 11 Jun 2007
-
- *) Bugfix: nginx could not be built with the
- --without-http_rewrite_module parameter; the bug had appeared in
- 0.5.24.
-
-
-Changes with nginx 0.5.24 06 Jun 2007
-
- *) Security: the "ssl_verify_client" directive did not work if request
- was made using HTTP/0.9.
-
- *) Bugfix: a part of response body might be passed uncompressed if gzip
- was used; the bug had appeared in 0.5.23.
-
-
-Changes with nginx 0.5.23 04 Jun 2007
-
- *) Feature: the ngx_http_ssl_module supports Server Name Indication TLS
- extension.
-
- *) Feature: the "fastcgi_catch_stderr" directive.
- Thanks to Nick S. Grechukh, OWOX project.
-
- *) Bugfix: a segmentation fault occurred in master process if two
- virtual servers should bind() to the overlapping ports.
-
- *) Bugfix: if nginx was built with ngx_http_perl_module and perl
- supported threads, then during second reconfiguration the error
- messages "panic: MUTEX_LOCK" and "perl_parse() failed" were issued.
-
- *) Bugfix: in the HTTPS protocol in the "proxy_pass" directive.
-
-
-Changes with nginx 0.5.22 29 May 2007
-
- *) Bugfix: a big request body might not be passed to backend; the bug
- had appeared in 0.5.21.
-
-
-Changes with nginx 0.5.21 28 May 2007
-
- *) Bugfix: if server has more than about ten locations, then regex
- locations might be choosen not in that order as they were specified.
-
- *) Bugfix: a worker process may got caught in an endless loop on 64-bit
- platform, if the 33-rd or next in succession backend has failed.
- Thanks to Anton Povarov.
-
- *) Bugfix: a bus error might occur on Solaris/sparc64 if the PCRE
- library was used.
- Thanks to Andrei Nigmatulin.
-
- *) Bugfix: in the HTTPS protocol in the "proxy_pass" directive.
-
-
-Changes with nginx 0.5.20 07 May 2007
-
- *) Feature: the "sendfile_max_chunk" directive.
-
- *) Feature: the "$http_...", "$sent_http_...", and "$upstream_http_..."
- variables may be changed using the "set" directive.
-
- *) Bugfix: a segmentation fault might occur in worker process if the SSI
- command 'if expr="$var = /"' was used.
-
- *) Bugfix: trailing boundary of multipart range response was transferred
- incorrectly.
- Thanks to Evan Miller.
-
- *) Bugfix: nginx did not work on Solaris/sparc64 if it was built by Sun
- Studio.
- Thanks to Andrei Nigmatulin.
-
- *) Bugfix: the ngx_http_perl_module could not be built by Solaris make.
- Thanks to Andrei Nigmatulin.
-
-
-Changes with nginx 0.5.19 24 Apr 2007
-
- *) Change: now the $request_time variable has millisecond precision.
-
- *) Change: the method $r->rflush of ngx_http_perl_module was renamed to
- the $r->flush.
-
- *) Feature: the $upstream_addr variable.
-
- *) Feature: the "proxy_headers_hash_max_size" and
- "proxy_headers_hash_bucket_size" directives.
- Thanks to Volodymyr Kostyrko.
-
- *) Bugfix: the files more than 2G could not be transferred using
- sendfile and limit_rate on 64-bit platforms.
-
- *) Bugfix: the files more than 2G could not be transferred using
- sendfile on 64-bit Linux.
-
-
-Changes with nginx 0.5.18 19 Apr 2007
-
- *) Feature: the ngx_http_sub_filter_module.
-
- *) Feature: the "$upstream_http_..." variables.
-
- *) Feature: now the $upstream_status and $upstream_response_time
- variables keep data about all upstreams before X-Accel-Redirect.
-
- *) Bugfix: a segmentation fault occurred in master process after first
- reconfiguration and receiving any signal if nginx was built with
- ngx_http_perl_module and perl did not support multiplicity; the bug
- had appeared in 0.5.9.
-
- *) Bugfix: if perl did not support multiplicity, then after
- reconfiguration perl code did not work; the bug had appeared in
- 0.3.38.
-
-
-Changes with nginx 0.5.17 02 Apr 2007
-
- *) Change: now nginx always returns the 405 status for the TRACE method.
-
- *) Feature: now nginx supports the "include" directive inside the
- "types" block.
-
- *) Bugfix: the $document_root variable usage in the "root" and "alias"
- directives is disabled: this caused recursive stack overflow.
-
- *) Bugfix: in the HTTPS protocol in the "proxy_pass" directive.
-
- *) Bugfix: in some cases non-cachable variables (such as $uri variable)
- returned old cached value.
-
-
-Changes with nginx 0.5.16 26 Mar 2007
-
- *) Bugfix: the C-class network was not used as hash key in the "ip_hash"
- directive.
- Thanks to Pavel Yarkovoy.
-
- *) Bugfix: a segmentation fault might occur in worker process if a
- charset was set in the "Content-Type" header line and the line has
- trailing ";"; the bug had appeared in 0.3.50.
-
- *) Bugfix: the "[alert] zero size buf" error when FastCGI server was
- used and a request body written in a temporary file was multiple of
- 32K.
-
- *) Bugfix: nginx could not be built on Solaris without the --with-debug
- option; the bug had appeared in 0.5.15.
-
-
-Changes with nginx 0.5.15 19 Mar 2007
-
- *) Feature: the mail proxy supports authenticated SMTP proxying and the
- "smtp_auth", "smtp_capablities", and "xclient" directives.
- Thanks to Anton Yuzhaninov and Maxim Dounin.
-
- *) Feature: now the keep-alive connections are closed just after
- receiving the reconfiguration signal.
-
- *) Change: the "imap" and "auth" directives were renamed to the "mail"
- and "pop3_auth" directives.
-
- *) Bugfix: a segmentation fault occurred in worker process if the
- CRAM-MD5 authentication method was used and the APOP method was
- disabled.
-
- *) Bugfix: if the "starttls only" directive was used in POP3 protocol,
- then nginx allowed authentication without switching to the SSL mode.
-
- *) Bugfix: worker processes did not exit after reconfiguration and did
- not rotate logs if the eventport method was used.
-
- *) Bugfix: a worker process may got caught in an endless loop, if the
- "ip_hash" directive was used.
-
- *) Bugfix: now nginx does not log some alerts if eventport or /dev/poll
- methods are used.
-
-
-Changes with nginx 0.5.14 23 Feb 2007
-
- *) Bugfix: nginx ignored superfluous closing "}" in the end of
- configuration file.
-
-
-Changes with nginx 0.5.13 19 Feb 2007
-
- *) Feature: the COPY and MOVE methods.
-
- *) Bugfix: the ngx_http_realip_module set garbage for requests passed
- via keep-alive connection.
-
- *) Bugfix: nginx did not work on big-endian 64-bit Linux.
- Thanks to Andrei Nigmatulin.
-
- *) Bugfix: now when IMAP/POP3 proxy receives too long command it closes
- the connection right away, but not after timeout.
-
- *) Bugfix: if the "epoll" method was used and a client closed a
- connection prematurely, then nginx closed the connection after a send
- timeout only.
-
- *) Bugfix: nginx could not be built on platforms different from i386,
- amd64, sparc, and ppc; the bug had appeared in 0.5.8.
-
-
-Changes with nginx 0.5.12 12 Feb 2007
-
- *) Bugfix: nginx could not be built on platforms different from i386,
- amd64, sparc, and ppc; the bug had appeared in 0.5.8.
-
- *) Bugfix: a segmentation fault might occur in worker process if the
- temporary files were used while working with FastCGI server; the bug
- had appeared in 0.5.8.
-
- *) Bugfix: a segmentation fault might occur in worker process if the
- $fastcgi_script_name variable was logged.
-
- *) Bugfix: ngx_http_perl_module could not be built on Solaris.
-
-
-Changes with nginx 0.5.11 05 Feb 2007
-
- *) Feature: now configure detects system PCRE library in MacPorts.
- Thanks to Chris McGrath.
-
- *) Bugfix: the response was incorrect if several ranges were requested;
- the bug had appeared in 0.5.6.
-
- *) Bugfix: the "create_full_put_path" directive could not create the
- intermediate directories if no "dav_access" directive was set.
- Thanks to Evan Miller.
-
- *) Bugfix: the "0" response code might be logged in the access_log
- instead of the "400" and "408" error codes.
-
- *) Bugfix: a segmentation fault might occur in worker process if nginx
- was built with -O2 optimization.
-
-
-Changes with nginx 0.5.10 26 Jan 2007
-
- *) Bugfix: while online executable file upgrade the new master process
- did not inherit the listening sockets; the bug had appeared in 0.5.9.
-
- *) Bugfix: a segmentation fault might occur in worker process if nginx
- was built with -O2 optimization; the bug had appeared in 0.5.1.
-
-
-Changes with nginx 0.5.9 25 Jan 2007
-
- *) Change: now the ngx_http_memcached_module uses the $memcached_key
- variable value as a key.
-
- *) Feature: the $memcached_key variable.
-
- *) Feature: the "clean" parameter in the "client_body_in_file_only"
- directive.
-
- *) Feature: the "env" directive.
-
- *) Feature: the "sendfile" directive is available inside the "if" block.
-
- *) Feature: now on failure of the writing to access nginx logs a message
- to error_log, but not more often than once a minute.
-
- *) Bugfix: the "access_log off" directive did not always turn off the
- logging.
-
-
-Changes with nginx 0.5.8 19 Jan 2007
-
- *) Bugfix: a segmentation fault might occur if
- "client_body_in_file_only on" was used and a request body was small.
-
- *) Bugfix: a segmentation fault occurred if
- "client_body_in_file_only on" and "proxy_pass_request_body off" or
- "fastcgi_pass_request_body off" directives were used, and nginx
- switched to a next upstream.
-
- *) Bugfix: if the "proxy_buffering off" directive was used and a client
- connection was non-active, then the connection was closed after send
- timeout; the bug had appeared in 0.4.7.
-
- *) Bugfix: if the "epoll" method was used and a client closed a
- connection prematurely, then nginx closed the connection after a send
- timeout only.
-
- *) Bugfix: the "[alert] zero size buf" error when FastCGI server was
- used.
-
- *) Bugfixes in the "limit_zone" directive.
-
-
-Changes with nginx 0.5.7 15 Jan 2007
-
- *) Feature: the ssl_session_cache storage optimization.
-
- *) Bugfixes in the "ssl_session_cache" and "limit_zone" directives.
-
- *) Bugfix: the segmentation fault was occurred on start or while
- reconfiguration if the "ssl_session_cache" or "limit_zone" directives
- were used on 64-bit platforms.
-
- *) Bugfix: a segmentation fault occurred if the "add_before_body" or
- "add_after_body" directives were used and there was no "Content-Type"
- header line in response.
-
- *) Bugfix: the OpenSSL library was always built with the threads
- support.
- Thanks to Den Ivanov.
-
- *) Bugfix: the PCRE-6.5+ library and the icc compiler compatibility.
-
-
-Changes with nginx 0.5.6 09 Jan 2007
-
- *) Change: now the ngx_http_index_module ignores all methods except the
- GET, HEAD, and POST methods.
-
- *) Feature: the ngx_http_limit_zone_module.
-
- *) Feature: the $binary_remote_addr variable.
-
- *) Feature: the "ssl_session_cache" directives of the
- ngx_http_ssl_module and ngx_imap_ssl_module.
-
- *) Feature: the DELETE method supports recursive removal.
-
- *) Bugfix: the byte-ranges were transferred incorrectly if the
- $r->sendfile() was used.
-
-
-Changes with nginx 0.5.5 24 Dec 2006
-
- *) Change: the -v switch does not show compiler information any more.
-
- *) Feature: the -V switch.
-
- *) Feature: the "worker_rlimit_core" directive supports size in K, M,
- and G.
-
- *) Bugfix: the nginx.pm module now could be installed by an unprivileged
- user.
-
- *) Bugfix: a segmentation fault might occur if the $r->request_body or
- $r->request_body_file methods were used.
-
- *) Bugfix: the ppc platform specific bugs.
-
-
-Changes with nginx 0.5.4 15 Dec 2006
-
- *) Feature: the "perl" directive may be used inside the "limit_except"
- block.
-
- *) Bugfix: the ngx_http_dav_module required the "Date" request header
- line for the DELETE method.
-
- *) Bugfix: if one only parameter was used in the "dav_access" directive,
- then nginx might report about configuration error.
-
- *) Bugfix: a segmentation fault might occur if the $host variable was
- used; the bug had appeared in 0.4.14.
-
-
-Changes with nginx 0.5.3 13 Dec 2006
-
- *) Feature: the ngx_http_perl_module supports the $r->status,
- $r->log_error, and $r->sleep methods.
-
- *) Feature: the $r->variable method supports variables that do not exist
- in nginx configuration.
-
- *) Bugfix: the $r->has_request_body method did not work.
-
-
-Changes with nginx 0.5.2 11 Dec 2006
-
- *) Bugfix: if the "proxy_pass" directive used the name of the "upstream"
- block, then nginx tried to resolve the name; the bug had appeared in
- 0.5.1.
-
-
-Changes with nginx 0.5.1 11 Dec 2006
-
- *) Bugfix: the "post_action" directive might not run after a
- unsuccessful completion of a request.
-
- *) Workaround: for Eudora for Mac; the bug had appeared in 0.4.11.
- Thanks to Bron Gondwana.
-
- *) Bugfix: if the "upstream" name was used in the "fastcgi_pass", then
- the message "no port in upstream" was issued; the bug had appeared in
- 0.5.0.
-
- *) Bugfix: if the "proxy_pass" and "fastcgi_pass" directives used the
- same servers but different ports, then these directives uses the
- first described port; the bug had appeared in 0.5.0.
-
- *) Bugfix: if the "proxy_pass" and "fastcgi_pass" directives used the
- unix domain sockets, then these directives used first described
- socket; the bug had appeared in 0.5.0.
-
- *) Bugfix: ngx_http_auth_basic_module ignored the user if it was in the
- last line in the password file and there was no the carriage return,
- the line feed, or the ":" symbol after the password.
-
- *) Bugfix: the $upstream_response_time variable might be equal to
- "0.000", although response time was more than 1 millisecond.
-
-
-Changes with nginx 0.5.0 04 Dec 2006
-
- *) Change: the parameters in the "%name" form in the "log_format"
- directive are not supported anymore.
-
- *) Change: the "proxy_upstream_max_fails",
- "proxy_upstream_fail_timeout", "fastcgi_upstream_max_fails",
- "fastcgi_upstream_fail_timeout", "memcached_upstream_max_fails", and
- "memcached_upstream_fail_timeout" directives are not supported
- anymore.
-
- *) Feature: the "server" directive in the "upstream" context supports
- the "max_fails", "fail_timeout", and "down" parameters.
-
- *) Feature: the "ip_hash" directive inside the "upstream" block.
-
- *) Feature: the WAIT status in the "Auth-Status" header line of the
- IMAP/POP3 proxy authentication server response.
-
- *) Bugfix: nginx could not be built on 64-bit platforms; the bug had
- appeared in 0.4.14.
-
-
-Changes with nginx 0.4.14 27 Nov 2006
-
- *) Feature: the "proxy_pass_error_message" directive in IMAP/POP3 proxy.
-
- *) Feature: now configure detects system PCRE library on FreeBSD, Linux,
- and NetBSD.
-
- *) Bugfix: ngx_http_perl_module did not work with perl built with the
- threads support; the bug had appeared in 0.3.38.
-
- *) Bugfix: ngx_http_perl_module did not work if perl was called
- recursively.
-
- *) Bugfix: nginx ignored a host name in a request line.
-
- *) Bugfix: a worker process may got caught in an endless loop, if a
- FastCGI server sent too many data to the stderr.
-
- *) Bugfix: the $upstream_response_time variable may be negative if the
- system time was changed backward.
-
- *) Bugfix: the "Auth-Login-Attempt" parameter was not sent to IMAP/POP3
- proxy authentication server when POP3 was used.
-
- *) Bugfix: a segmentation fault might occur if connect to IMAP/POP3
- proxy authentication server failed.
-
-
-Changes with nginx 0.4.13 15 Nov 2006
-
- *) Feature: the "proxy_pass" directive may be used inside the
- "limit_except" block.
-
- *) Feature: the "limit_except" directive supports all WebDAV methods.
-
- *) Bugfix: if the "add_before_body" directive was used without the
- "add_after_body" directive, then a response did not transferred
- complete.
-
- *) Bugfix: a large request body did not receive if the epoll method and
- the deferred accept() were used.
-
- *) Bugfix: a charset could not be set for ngx_http_autoindex_module
- responses; the bug had appeared in 0.3.50.
-
- *) Bugfix: the "[alert] zero size buf" error when FastCGI server was
- used;
-
- *) Bugfix: the --group= configuration parameter was ignored.
- Thanks to Thomas Moschny.
-
- *) Bugfix: the 50th subrequest in SSI response did not work; the bug had
- appeared in 0.3.50.
-
-
-Changes with nginx 0.4.12 31 Oct 2006
-
- *) Feature: the ngx_http_perl_module supports the $r->variable method.
-
- *) Bugfix: if a big static file was included using SSI in a response,
- then the response may be transferred incomplete.
-
- *) Bugfix: nginx did not omit the "#fragment" part in URI.
-
-
-Changes with nginx 0.4.11 25 Oct 2006
-
- *) Feature: the POP3 proxy supports the AUTH LOGIN PLAIN and CRAM-MD5.
-
- *) Feature: the ngx_http_perl_module supports the $r->allow_ranges
- method.
-
- *) Bugfix: if the APOP was enabled in the POP3 proxy, then the USER/PASS
- commands might not work; the bug had appeared in 0.4.10.
-
-
-Changes with nginx 0.4.10 23 Oct 2006
-
- *) Feature: the POP3 proxy supports the APOP command.
-
- *) Bugfix: if the select, poll or /dev/poll methods were used, then
- while waiting authentication server response the IMAP/POP3 proxy
- hogged CPU.
-
- *) Bugfix: a segmentation fault might occur if the $server_addr variable
- was used in the "map" directive.
-
- *) Bugfix: the ngx_http_flv_module did not support the byte ranges for
- full responses; the bug had appeared in 0.4.7.
-
- *) Bugfix: nginx could not be built on Debian amd64; the bug had
- appeared in 0.4.9.
-
-
-Changes with nginx 0.4.9 13 Oct 2006
-
- *) Feature: the "set" parameter in the "include" SSI command.
-
- *) Feature: the ngx_http_perl_module now tests the nginx.pm module
- version.
-
-
-Changes with nginx 0.4.8 11 Oct 2006
-
- *) Bugfix: if an "include" SSI command were before another "include" SSI
- command with a "wait" parameter, then the "wait" parameter might not
- work.
-
- *) Bugfix: the ngx_http_flv_module added the FLV header to the full
- responses.
- Thanks to Alexey Kovyrin.
-
-
-Changes with nginx 0.4.7 10 Oct 2006
-
- *) Feature: the ngx_http_flv_module.
-
- *) Feature: the $request_body_file variable.
-
- *) Feature: the "charset" and "source_charset" directives support the
- variables.
-
- *) Bugfix: if an "include" SSI command were before another "include" SSI
- command with a "wait" parameter, then the "wait" parameter might not
- work.
-
- *) Bugfix: if the "proxy_buffering off" directive was used or while
- working with memcached the connections might not be closed on
- timeout.
-
- *) Bugfix: nginx did not run on 64-bit platforms except amd64, sparc64,
- and ppc64.
-
-
-Changes with nginx 0.4.6 06 Oct 2006
-
- *) Bugfix: nginx did not run on 64-bit platforms except amd64, sparc64,
- and ppc64.
-
- *) Bugfix: nginx sent the chunked response for HTTP/1.1 request,
- if its length was set by text string in the
- $r->headers_out("Content-Length", ...) method.
-
- *) Bugfix: after redirecting error by an "error_page" directive any
- ngx_http_rewrite_module directive returned this error code; the bug
- had appeared in 0.4.4.
-
-
-Changes with nginx 0.4.5 02 Oct 2006
-
- *) Bugfix: nginx could not be built on Linux and Solaris; the bug had
- appeared in 0.4.4.
-
-
-Changes with nginx 0.4.4 02 Oct 2006
-
- *) Feature: the $scheme variable.
-
- *) Feature: the "expires" directive supports the "max" parameter.
-
- *) Feature: the "include" directive supports the "*" mask.
- Thanks to Jonathan Dance.
-
- *) Bugfix: the "return" directive always overrode the "error_page"
- response code redirected by the "error_page" directive.
-
- *) Bugfix: a segmentation fault occurred if zero-length body was in PUT
- method.
-
- *) Bugfix: the redirect was changed incorrectly if the variables were
- used in the "proxy_redirect" directive.
-
-
-Changes with nginx 0.4.3 26 Sep 2006
-
- *) Change: now the 499 error could not be redirected using an
- "error_page" directive.
-
- *) Feature: the Solaris 10 event ports support.
-
- *) Feature: the ngx_http_browser_module.
-
- *) Bugfix: a segmentation fault may occur while redirecting the 400
- error to the proxied server using a "proxy_pass" directive.
-
- *) Bugfix: a segmentation fault occurred if an unix domain socket was
- used in a "proxy_pass" directive; the bug had appeared in 0.3.47.
-
- *) Bugfix: SSI did work with memcached and nonbuffered responses.
-
- *) Workaround: of the Sun Studio PAUSE hardware capability bug.
-
-
-Changes with nginx 0.4.2 14 Sep 2006
-
- *) Bugfix: the O_NOATIME flag support on Linux was canceled; the bug had
- appeared in 0.4.1.
-
-
-Changes with nginx 0.4.1 14 Sep 2006
-
- *) Bugfix: the DragonFlyBSD compatibility.
- Thanks to Pavel Nazarov.
-
- *) Workaround: of bug in 64-bit Linux sendfile(), when file is more than
- 2G.
-
- *) Feature: now on Linux nginx uses O_NOATIME flag for static requests.
- Thanks to Yusuf Goolamabbas.
-
-
-Changes with nginx 0.4.0 30 Aug 2006
-
- *) Change in internal API: the HTTP modules initialization was moved
- from the init module phase to the HTTP postconfiguration phase.
-
- *) Change: now the request body is not read beforehand for the
- ngx_http_perl_module: it's required to start the reading using the
- $r->has_request_body method.
-
- *) Feature: the ngx_http_perl_module supports the DECLINED return code.
-
- *) Feature: the ngx_http_dav_module supports the incoming "Date" header
- line for the PUT method.
-
- *) Feature: the "ssi" directive is available inside the "if" block.
-
- *) Bugfix: a segmentation fault occurred if there was an "index"
- directive with variables and the first index name was without
- variables; the bug had appeared in 0.1.29.
-
-
-Changes with nginx 0.3.61 28 Aug 2006
-
- *) Change: now the "tcp_nodelay" directive is turned on by default.
-
- *) Feature: the "msie_refresh" directive.
-
- *) Feature: the "recursive_error_pages" directive.
-
- *) Bugfix: the "rewrite" directive returned incorrect redirect, if the
- redirect had the captured escaped symbols from original URI.
-
-
-Changes with nginx 0.3.60 18 Aug 2006
-
- *) Bugfix: a worker process may got caught in an endless loop while an
- error redirection; the bug had appeared in 0.3.59.
-
-
-Changes with nginx 0.3.59 16 Aug 2006
-
- *) Feature: now is possible to do several redirection using the
- "error_page" directive.
-
- *) Bugfix: the "dav_access" directive did not support three parameters.
-
- *) Bugfix: the "error_page" directive did not changes the "Content-Type"
- header line after the "X-Accel-Redirect" was used; the bug had
- appeared in 0.3.58.
-
-
-Changes with nginx 0.3.58 14 Aug 2006
-
- *) Feature: the "error_page" directive supports the variables.
-
- *) Change: now the procfs interface instead of sysctl is used on Linux.
-
- *) Change: now the "Content-Type" header line is inherited from first
- response when the "X-Accel-Redirect" was used.
-
- *) Bugfix: the "error_page" directive did not redirect the 413 error.
-
- *) Bugfix: the trailing "?" did not remove old arguments if no new
- arguments were added to a rewritten URI.
-
- *) Bugfix: nginx could not run on 64-bit FreeBSD 7.0-CURRENT.
-
-
-Changes with nginx 0.3.57 09 Aug 2006
-
- *) Feature: the $ssl_client_serial variable.
-
- *) Bugfix: in the "!-e" operator of the "if" directive.
- Thanks to Andrian Budanstov.
-
- *) Bugfix: while a client certificate verification nginx did not send to
- a client the required certificates information.
-
- *) Bugfix: the $document_root variable did not support the variables in
- the "root" directive.
-
-
-Changes with nginx 0.3.56 04 Aug 2006
-
- *) Feature: the "dav_access" directive.
-
- *) Feature: the "if" directive supports the "-d", "!-d", "-e", "!-e",
- "-x", and "!-x" operators.
-
- *) Bugfix: a segmentation fault occurred if a request returned a
- redirect and some sent to client header lines were logged in the
- access log.
-
-
-Changes with nginx 0.3.55 28 Jul 2006
-
- *) Feature: the "stub" parameter in the "include" SSI command.
-
- *) Feature: the "block" SSI command.
-
- *) Feature: the unicode2nginx script was added to contrib.
-
- *) Bugfix: if a "root" was specified by variable only, then the root was
- relative to a server prefix.
-
- *) Bugfix: if the request contained "//" or "/./" and escaped symbols
- after them, then the proxied request was sent unescaped.
-
- *) Bugfix: the $r->header_in("Cookie") of the ngx_http_perl_module now
- returns all "Cookie" header lines.
-
- *) Bugfix: a segmentation fault occurred if
- "client_body_in_file_only on" was used and nginx switched to a next
- upstream.
-
- *) Bugfix: on some condition while reconfiguration character codes
- inside the "charset_map" may be treated invalid; the bug had appeared
- in 0.3.50.
-
-
-Changes with nginx 0.3.54 11 Jul 2006
-
- *) Feature: nginx now logs the subrequest information to the error log.
-
- *) Feature: the "proxy_next_upstream", "fastcgi_next_upstream", and
- "memcached_next_upstream" directives support the "off" parameter.
-
- *) Feature: the "debug_connection" directive supports the CIDR address
- form.
-
- *) Bugfix: if a response of proxied server or FastCGI server was
- converted from UTF-8 or back, then it may be transferred incomplete.
-
- *) Bugfix: the $upstream_response_time variable had the time of the
- first request to a backend only.
-
- *) Bugfix: nginx could not be built on amd64 platform; the bug had
- appeared in 0.3.53.
-
-
-Changes with nginx 0.3.53 07 Jul 2006
-
- *) Change: the "add_header" directive adds the string to 204, 301, and
- 302 responses.
-
- *) Feature: the "server" directive in the "upstream" context supports
- the "weight" parameter.
-
- *) Feature: the "server_name" directive supports the "*" wildcard.
-
- *) Feature: nginx supports the request body size more than 2G.
-
- *) Bugfix: if a client was successfully authorized using "satisfy_any
- on", then anyway the message "access forbidden by rule" was written
- in the log.
-
- *) Bugfix: the "PUT" method may erroneously not create a file and return
- the 409 code.
-
- *) Bugfix: if the IMAP/POP3 backend returned an error, then nginx
- continued proxying anyway.
-
-
-Changes with nginx 0.3.52 03 Jul 2006
-
- *) Change: the ngx_http_index_module behavior for the "POST /" requests
- is reverted to the 0.3.40 version state: the module now does not
- return the 405 error.
-
- *) Bugfix: the worker process may got caught in an endless loop if the
- limit rate was used; the bug had appeared in 0.3.37.
-
- *) Bugfix: ngx_http_charset_module logged "unknown charset" alert, even
- if the recoding was not needed; the bug had appeared in 0.3.50.
-
- *) Bugfix: if a code response of the PUT request was 409, then a
- temporary file was not removed.
-
-
-Changes with nginx 0.3.51 30 Jun 2006
-
- *) Bugfix: the "<" symbols might disappeared some conditions in the SSI;
- the bug had appeared in 0.3.50.
-
-
-Changes with nginx 0.3.50 28 Jun 2006
-
- *) Change: the "proxy_redirect_errors" and "fastcgi_redirect_errors"
- directives was renamed to the "proxy_intercept_errors" and
- "fastcgi_intercept_errors" directives.
-
- *) Feature: the ngx_http_charset_module supports the recoding from the
- single byte encodings to the UTF-8 encoding and back.
-
- *) Feature: the "X-Accel-Charset" response header line is supported in
- proxy and FastCGI mode.
-
- *) Bugfix: the "\" escape symbol in the "\"" and "\'" pairs in the SSI
- command was removed only if the command also has the "$" symbol.
-
- *) Bugfix: the "<!--" string might be added on some conditions in the
- SSI after inclusion.
-
- *) Bugfix: if the "Content-Length: 0" header line was in response, then
- in nonbuffered proxying mode the client connection was not closed.
-
-
-Changes with nginx 0.3.49 31 May 2006
-
- *) Bugfix: in the "set" directive.
-
- *) Bugfix: if two or more FastCGI subrequests was in SSI, then first
- subrequest output was included instead of second and following
- subrequests.
-
-
-Changes with nginx 0.3.48 29 May 2006
-
- *) Change: now the ngx_http_charset_module works for subrequests, if the
- response has no "Content-Type" header line.
-
- *) Bugfix: if the "proxy_pass" directive has no URI part, then the
- "proxy_redirect default" directive add the unnecessary slash in start
- of the rewritten redirect.
-
- *) Bugfix: the internal redirect always transform client's HTTP method
- to GET, now the transformation is made for the "X-Accel-Redirect"
- redirects only and if the method is not HEAD; the bug had appeared in
- 0.3.42.
-
- *) Bugfix: the ngx_http_perl_module could not be built, if the perl was
- built with the threads support; the bug had appeared in 0.3.46.
-
-
-Changes with nginx 0.3.47 23 May 2006
-
- *) Feature: the "upstream" directive.
-
- *) Change: now the "\" escape symbol in the "\"" and "\'" pairs in the
- SSI command is always removed.
-
-
-Changes with nginx 0.3.46 11 May 2006
-
- *) Feature: the "proxy_hide_header", "proxy_pass_header",
- "fastcgi_hide_header", and "fastcgi_pass_header" directives.
-
- *) Change: the "proxy_pass_x_powered_by", "fastcgi_x_powered_by", and
- "proxy_pass_server" directives were canceled.
-
- *) Feature: the "X-Accel-Buffering" response header line is supported in
- proxy mode.
-
- *) Bugfix: the reconfiguration bug and memory leaks in the
- ngx_http_perl_module.
-
-
-Changes with nginx 0.3.45 06 May 2006
-
- *) Feature: the "ssl_verify_client", "ssl_verify_depth", and
- "ssl_client_certificate" directives.
-
- *) Change: the $request_method variable now returns the main request
- method.
-
- *) Change: the &deg; symbol codes were changed in koi-win conversion
- table.
-
- *) Feature: the euro and N symbols were added to koi-win conversion
- table.
-
- *) Bugfix: if nginx distributed the requests among several backends and
- some backend failed, then requests intended for this backend was
- directed to one live backend only instead of being distributed among
- the rest.
-
-
-Changes with nginx 0.3.44 04 May 2006
-
- *) Feature: the "wait" parameter in the "include" SSI command.
-
- *) Feature: the Ukrainian and Byelorussian characters were added to
- koi-win conversion table.
-
- *) Bugfix: in the SSI.
-
-
-Changes with nginx 0.3.43 26 Apr 2006
-
- *) Bugfix: in the SSI.
-
-
-Changes with nginx 0.3.42 26 Apr 2006
-
- *) Feature: the "bind" option of the "listen" directive in IMAP/POP3
- proxy.
-
- *) Bugfix: if the same capture in the "rewrite" directive was used more
- then once.
-
- *) Bugfix: the $sent_http_content_type, $sent_http_content_length,
- $sent_http_last_modified, $sent_http_connection,
- $sent_http_keep_alive, and $sent_http_transfer_encoding variables
- were not written to access log.
-
- *) Bugfix: the $sent_http_cache_control returned value of the single
- "Cache-Control" response header line.
-
-
-Changes with nginx 0.3.41 21 Apr 2006
-
- *) Feature: the -v switch.
-
- *) Bugfix: the segmentation fault may occurred if the SSI page has
- remote subrequests.
-
- *) Bugfix: in FastCGI handling.
-
- *) Bugfix: if the perl modules path was not set using
- --with-perl_modules_path=PATH or the "perl_modules", then the
- segmentation fault was occurred.
-
-
-Changes with nginx 0.3.40 19 Apr 2006
-
- *) Feature: the ngx_http_dav_module supports the MKCOL method.
-
- *) Feature: the "create_full_put_path" directive.
-
- *) Feature: the "$limit_rate" variable.
-
-
-Changes with nginx 0.3.39 17 Apr 2006
-
- *) Feature: the "uninitialized_variable_warn" directive; the logging
- level of the "uninitialized variable" message was lowered from
- "alert" to "warn".
-
- *) Feature: the "override_charset" directive.
-
- *) Change: now if the unknown variable is used in the "echo" and "if
- expr='$name'" SSI-commands, then the "unknown variable" message is
- not logged.
-
- *) Bugfix: the active connection counter increased on the exceeding of
- the connection limit specified by the "worker_connections" directive;
- the bug had appeared in 0.2.0.
-
- *) Bugfix: the limit rate might not work on some condition; the bug had
- appeared in 0.3.38.
-
-
-Changes with nginx 0.3.38 14 Apr 2006
-
- *) Feature: the ngx_http_dav_module.
-
- *) Change: the ngx_http_perl_module optimizations.
- Thanks to Sergey Skvortsov.
-
- *) Feature: the ngx_http_perl_module supports the $r->request_body_file
- method.
-
- *) Feature: the "client_body_in_file_only" directive.
-
- *) Workaround: now on disk overflow nginx tries to write access logs
- once a second only.
- Thanks to Anton Yuzhaninov and Maxim Dounin.
-
- *) Bugfix: now the "limit_rate" directive more precisely limits rate if
- rate is more than 100 Kbyte/s.
- Thanks to ForJest.
-
- *) Bugfix: now the IMAP/POP3 proxy escapes the "\r" and "\n" symbols in
- login and password to pass authorization server.
- Thanks to Maxim Dounin.
-
-
-Changes with nginx 0.3.37 07 Apr 2006
-
- *) Feature: the "limit_except" directive.
-
- *) Feature: the "if" directive supports the "!~", "!~*", "-f", and "!-f"
- operators.
-
- *) Feature: the ngx_http_perl_module supports the $r->request_body
- method.
-
- *) Bugfix: in the ngx_http_addition_filter_module.
-
-
-Changes with nginx 0.3.36 05 Apr 2006
-
- *) Feature: the ngx_http_addition_filter_module.
-
- *) Feature: the "proxy_pass" and "fastcgi_pass" directives may be used
- inside the "if" block.
-
- *) Feature: the "proxy_ignore_client_abort" and
- "fastcgi_ignore_client_abort" directives.
-
- *) Feature: the "$request_completion" variable.
-
- *) Feature: the ngx_http_perl_module supports the $r->request_method and
- $r->remote_addr.
-
- *) Feature: the ngx_http_ssi_module supports the "elif" command.
-
- *) Bugfix: the "\/" string in the expression of the "if" command of the
- ngx_http_ssi_module was treated incorrectly.
-
- *) Bugfix: in the regular expressions in the "if" command of the
- ngx_http_ssi_module.
-
- *) Bugfix: if the relative path was specified in the
- "client_body_temp_path", "proxy_temp_path", "fastcgi_temp_path", and
- "perl_modules" directives, then the directory was used relatively to
- a current path but not to a server prefix.
-
-
-Changes with nginx 0.3.35 22 Mar 2006
-
- *) Bugfix: the accept-filter and the TCP_DEFER_ACCEPT option were set
- for first "listen" directive only; the bug had appeared in 0.3.31.
-
- *) Bugfix: in the "proxy_pass" directive without the URI part in a
- subrequest.
-
-
-Changes with nginx 0.3.34 21 Mar 2006
-
- *) Feature: the "add_header" directive supports the variables.
-
-
-Changes with nginx 0.3.33 15 Mar 2006
-
- *) Feature: the "http_503" parameter of the "proxy_next_upstream" or
- "fastcgi_next_upstream" directives.
-
- *) Bugfix: ngx_http_perl_module did not work with inlined in the
- configuration code, if it was not started with the "sub" word.
-
- *) Bugfix: in the "post_action" directive.
-
-
-Changes with nginx 0.3.32 11 Mar 2006
-
- *) Bugfix: the debug logging on startup and reconfiguration time was
- removed; the bug had appeared in 0.3.31.
-
-
-Changes with nginx 0.3.31 10 Mar 2006
-
- *) Change: now nginx passes the malformed proxied backend responses.
-
- *) Feature: the "listen" directives support the address in the "*:port"
- form.
-
- *) Feature: the EVFILER_TIMER support in MacOSX 10.4.
-
- *) Workaround: for MacOSX 64-bit kernel kqueue millisecond timeout bug.
- Thanks to Andrei Nigmatulin.
-
- *) Bugfix: if there were several "listen" directives listening one
- various addresses inside one server, then server names like
- "*.domain.tld" worked for first address only; the bug had appeared in
- 0.3.18.
-
- *) Bugfix: if the HTTPS protocol was used in the "proxy_pass" directive
- and the request body was in temporary file then the request was not
- transferred.
-
- *) Bugfix: perl 5.8.8 compatibility.
-
-
-Changes with nginx 0.3.30 22 Feb 2006
-
- *) Change: the ECONNABORTED error log level was changed to "error" from
- "crit".
-
- *) Bugfix: the ngx_http_perl_module could not be build without the
- ngx_http_ssi_filter_module.
-
- *) Bugfix: nginx could not be built on i386 platform, if the PIC was
- used; the bug had appeared in 0.3.27.
-
-
-Changes with nginx 0.3.29 20 Feb 2006
-
- *) Feature: now nginx uses less memory, if PHP in FastCGI mode sends
- many warnings before the response.
-
- *) Bugfix: the "Transfer-Encoding: chunked" header line was issued in
- the 204 responses for the HTTP/1.1 requests.
-
- *) Bugfix: nginx returned the 502 response, if the complete response
- header lines were transferred in a separate FastCGI records.
-
- *) Bugfix: if the proxied URI was specified in the "post_action"
- directive, then it ran only after a successful completion of a
- request.
-
-
-Changes with nginx 0.3.28 16 Feb 2006
-
- *) Feature: the "restrict_host_names" directive was canceled.
-
- *) Feature: the --with-cpu-opt=ppc64 configuration parameter.
-
- *) Bugfix: on some condition the proxied connection with a client was
- terminated prematurely.
- Thanks to Vladimir Shutoff.
-
- *) Bugfix: the "X-Accel-Limit-Rate" header line was not taken into
- account if the request was redirected using the "X-Accel-Redirect"
- header line.
-
- *) Bugfix: the "post_action" directive ran only after a successful
- completion of a request.
-
- *) Bugfix: the proxied response body generated by the "post_action"
- directive was transferred to a client.
-
-
-Changes with nginx 0.3.27 08 Feb 2006
-
- *) Change: the "variables_hash_max_size" and
- "variables_hash_bucket_size" directives.
-
- *) Feature: the $body_bytes_sent variable can be used not only in the
- "log_format" directive.
-
- *) Feature: the $ssl_protocol and $ssl_cipher variables.
-
- *) Feature: the cache line size detection for widespread CPUs at start
- time.
-
- *) Feature: now the "accept_mutex" directive is supported using fcntl(2)
- on platforms different from i386, amd64, sparc64, and ppc.
-
- *) Feature: the "lock_file" directive and the --with-lock-path=PATH
- autoconfiguration directive.
-
- *) Bugfix: if the HTTPS protocol was used in the "proxy_pass" directive
- then the requests with the body was not transferred.
-
-
-Changes with nginx 0.3.26 03 Feb 2006
-
- *) Change: the "optimize_host_names" directive was renamed to the
- "optimize_server_names".
-
- *) Bugfix: if in the "proxy_pass" directive was no the URI part, then
- the main request URI was transferred to a backend while proxying the
- SSI subrequest.
-
-
-Changes with nginx 0.3.25 01 Feb 2006
-
- *) Bugfix: the segmentation fault was occurred on start or while
- reconfiguration if there was invalid configuration; the bug had
- appeared in 0.3.24.
-
-
-Changes with nginx 0.3.24 01 Feb 2006
-
- *) Workaround: for bug in FreeBSD kqueue.
-
- *) Bugfix: now a response generated by the "post_action" directive is
- not transferred to a client.
-
- *) Bugfix: the memory leaks were occurring if many log files were used.
-
- *) Bugfix: the first "proxy_redirect" directive was working inside one
- location.
-
- *) Bugfix: on 64-bit platforms segmentation fault may occurred on start
- if the many names were used in the "server_name" directives; the bug
- had appeared in 0.3.18.
-
-
-Changes with nginx 0.3.23 24 Jan 2006
-
- *) Feature: the "optimize_host_names" directive.
-
- *) Bugfix: in using of the variables in the "path" and "alias"
- directives.
-
- *) Bugfix: the ngx_http_perl_module was incorrectly built on Linux and
- Solaris.
-
-
-Changes with nginx 0.3.22 17 Jan 2006
-
- *) Feature: the ngx_http_perl_module supports the $r->args and
- $r->unescape methods.
-
- *) Feature: the method $r->query_string of ngx_http_perl_module was
- canceled.
-
- *) Bugfix: segmentation fault was occurred if the "none" or "blocked"
- values was specified in the "valid_referers" directive; the bug had
- appeared in 0.3.18.
-
-
-Changes with nginx 0.3.21 16 Jan 2006
-
- *) Feature: the ngx_http_perl_module.
-
- *) Change: the "valid_referers" directive allows the referreres without
- URI part.
-
-
-Changes with nginx 0.3.20 11 Jan 2006
-
- *) Bugfix: in SSI handling.
-
- *) Bugfix: the ngx_http_memcached_module did not support the keys in the
- "/usr?args" form.
-
-
-Changes with nginx 0.3.19 28 Dec 2005
-
- *) Feature: the "path" and "alias" directives support the variables.
-
- *) Change: now the "valid_referers" directive again checks the URI part.
-
- *) Bugfix: in SSI handling.
-
-
-Changes with nginx 0.3.18 26 Dec 2005
-
- *) Feature: the "server_names" directive supports the ".domain.tld"
- names.
-
- *) Feature: the "server_names" directive uses the hash for the
- "*.domain.tld" names and more effective hash for usual names.
-
- *) Change: the "server_names_hash_max_size" and
- "server_names_hash_bucket_size" directives.
-
- *) Change: the "server_names_hash" and "server_names_hash_threshold"
- directives were canceled.
-
- *) Feature: the "valid_referers" directive uses the hash site names.
-
- *) Change: now the "valid_referers" directive checks the site names only
- without the URI part.
-
- *) Bugfix: some ".domain.tld" names incorrectly processed by the
- ngx_http_map_module.
-
- *) Bugfix: segmentation fault was occurred if configuration file did not
- exist; the bug had appeared in 0.3.12.
-
- *) Bugfix: on 64-bit platforms segmentation fault may occurred on start;
- the bug had appeared in 0.3.16.
-
-
-Changes with nginx 0.3.17 18 Dec 2005
-
- *) Change: now on Linux configure checks the presence of epoll and
- sendfile64() in kernel.
-
- *) Feature: the "map" directive supports domain names in the
- ".domain.tld" form.
-
- *) Bugfix: the timeouts were not used in SSL handshake; the bug had
- appeared in 0.2.4.
-
- *) Bugfix: in the HTTPS protocol in the "proxy_pass" directive.
-
- *) Bugfix: when the HTTPS protocol was used in the "proxy_pass"
- directive the port 80 was used by default.
-
-
-Changes with nginx 0.3.16 16 Dec 2005
-
- *) Feature: the ngx_http_map_module.
-
- *) Feature: the "types_hash_max_size" and "types_hash_bucket_size"
- directives.
-
- *) Feature: the "ssi_value_length" directive.
-
- *) Feature: the "worker_rlimit_core" directive.
-
- *) Workaround: the connection number in logs was always 1 if nginx was
- built by the icc 8.1 or 9.0 compilers with optimization for
- Pentium 4.
-
- *) Bugfix: the "config timefmt" SSI command set incorrect time format.
-
- *) Bugfix: nginx did not close connection to IMAP/POP3 backend for the
- SSL connections; the bug had appeared in 0.3.13.
- Thanks to Rob Mueller.
-
- *) Bugfix: segmentation fault may occurred in at SSL shutdown; the bug
- had appeared in 0.3.13.
-
-
-Changes with nginx 0.3.15 07 Dec 2005
-
- *) Feature: the new 444 code of the "return" directive to close
- connection.
-
- *) Feature: the "so_keepalive" directive in IMAP/POP3 proxy.
-
- *) Bugfix: if there are unclosed connection nginx now calls abort() only
- on gracefull quit and active "debug_points" directive.
-
-
-Changes with nginx 0.3.14 05 Dec 2005
-
- *) Bugfix: in the 304 response the body was transferred; the bug had
- appeared in 0.3.13.
-
-
-Changes with nginx 0.3.13 05 Dec 2005
-
- *) Feature: the IMAP/POP3 proxy supports STARTTLS and STLS.
-
- *) Bugfix: the IMAP/POP3 proxy did not work with the select, poll, and
- /dev/poll methods.
-
- *) Bugfix: in SSI handling.
-
- *) Bugfix: now Solaris sendfilev() is not used to transfer the client
- request body to FastCGI-server via the unix domain socket.
-
- *) Bugfix: the "auth_basic" directive did not disable the authorization;
- the bug had appeared in 0.3.11.
-
-
-Changes with nginx 0.3.12 26 Nov 2005
-
- *) Security: if nginx was built with the ngx_http_realip_module and the
- "satisfy_any on" directive was used, then access and authorization
- directives did not work. The ngx_http_realip_module was not built and
- is not built by default.
-
- *) Change: the "$time_gmt" variable name was changed to "$time_local".
-
- *) Change: the "proxy_header_buffer_size" and
- "fastcgi_header_buffer_size" directives was renamed to the
- "proxy_buffer_size" and "fastcgi_buffer_size" directives.
-
- *) Feature: the ngx_http_memcached_module.
-
- *) Feature: the "proxy_buffering" directive.
-
- *) Bugfix: the changes in accept mutex handling when the "rtsig" method
- was used; the bug had appeared in 0.3.0.
-
- *) Bugfix: if the client sent the "Transfer-Encoding: chunked" header
- line, then nginx returns the 411 error.
-
- *) Bugfix: if the "auth_basic" directive was inherited from the http
- level, then the realm in the "WWW-Authenticate" header line was
- without the "Basic realm" text.
-
- *) Bugfix: if the "combined" format was explicitly specified in the
- "access_log" directive, then the empty lines was written to the log;
- the bug had appeared in 0.3.8.
-
- *) Bugfix: nginx did not run on the sparc platform under any OS except
- Solaris.
-
- *) Bugfix: now it is not necessary to place space between the quoted
- string and closing bracket in the "if" directive.
-
-
-Changes with nginx 0.3.11 15 Nov 2005
-
- *) Bugfix: nginx did not pass the client request headers and body while
- proxying; the bug had appeared in 0.3.10.
-
-
-Changes with nginx 0.3.10 15 Nov 2005
-
- *) Change: the "valid_referers" directive and the "$invalid_referer"
- variable were moved to the new ngx_http_referer_module from the
- ngx_http_rewrite_module.
-
- *) Change: the "$apache_bytes_sent" variable name was changed to
- "$body_bytes_sent".
-
- *) Feature: the "$sent_http_..." variables.
-
- *) Feature: the "if" directive supports the "=" and "!=" operations.
-
- *) Feature: the "proxy_pass" directive supports the HTTPS protocol.
-
- *) Feature: the "proxy_set_body" directive.
-
- *) Feature: the "post_action" directive.
-
- *) Feature: the ngx_http_empty_gif_module.
-
- *) Feature: the "worker_cpu_affinity" directive for Linux.
-
- *) Bugfix: the "rewrite" directive did not unescape URI part in
- redirect, now it is unescaped except the %00-%25 and %7F-%FF
- characters.
-
- *) Bugfix: nginx could not be built by the icc 9.0 compiler.
-
- *) Bugfix: if the SSI was enabled for zero size static file, then the
- chunked response was encoded incorrectly.
-
-
-Changes with nginx 0.3.9 10 Nov 2005
-
- *) Bugfix: nginx considered URI as unsafe if two any symbols was between
- two slashes; the bug had appeared in 0.3.8.
-
-
-Changes with nginx 0.3.8 09 Nov 2005
-
- *) Security: nginx now checks URI got from a backend in
- "X-Accel-Redirect" header line or in SSI file for the "/../" paths
- and zeroes.
-
- *) Change: nginx now does not treat the empty user name in the
- "Authorization" header line as valid one.
-
- *) Feature: the "ssl_session_timeout" directives of the
- ngx_http_ssl_module and ngx_imap_ssl_module.
-
- *) Feature: the "auth_http_header" directive of the
- ngx_imap_auth_http_module.
-
- *) Feature: the "add_header" directive.
-
- *) Feature: the ngx_http_realip_module.
-
- *) Feature: the new variables to use in the "log_format" directive:
- $bytes_sent, $apache_bytes_sent, $status, $time_gmt, $uri,
- $request_time, $request_length, $upstream_status,
- $upstream_response_time, $gzip_ratio, $uid_got, $uid_set,
- $connection, $pipe, and $msec. The parameters in the "%name" form
- will be canceled soon.
-
- *) Change: now the false variable values in the "if" directive are the
- empty string "" and string starting with "0".
-
- *) Bugfix: while using proxied or FastCGI-server nginx may leave
- connections and temporary files with client requests in open state.
-
- *) Bugfix: the worker processes did not flush the buffered logs on
- graceful exit.
-
- *) Bugfix: if the request URI was changes by the "rewrite" directive and
- the request was proxied in location given by regular expression, then
- the incorrect request was transferred to backend; the bug had
- appeared in 0.2.6.
-
- *) Bugfix: the "expires" directive did not remove the previous "Expires"
- header.
-
- *) Bugfix: nginx may stop to accept requests if the "rtsig" method and
- several worker processes were used.
-
- *) Bugfix: the "\"" and "\'" escape symbols were incorrectly handled in
- SSI commands.
-
- *) Bugfix: if the response was ended just after the SSI command and
- gzipping was used, then the response did not transferred complete or
- did not transferred at all.
-
-
-Changes with nginx 0.3.7 27 Oct 2005
-
- *) Feature: the "access_log" supports the "buffer=" parameter.
-
- *) Bugfix: nginx could not be built on platforms different from i386,
- amd64, sparc, and ppc; the bug had appeared in 0.3.2.
-
-
-Changes with nginx 0.3.6 24 Oct 2005
-
- *) Change: now the IMAP/POP3 proxy do not send the empty login to
- authorization server.
-
- *) Feature: the "log_format" supports the variables in the $name form.
-
- *) Bugfix: if at least in one server was no the "listen" directive, then
- nginx did not listen on the 80 port; the bug had appeared in 0.3.3.
-
- *) Bugfix: if the URI part is omitted in "proxy_pass" directive, the 80
- port was always used.
-
-
-Changes with nginx 0.3.5 21 Oct 2005
-
- *) Bugfix: the segmentation fault may occurred if the IMAP/POP3 login
- was changed by authorization server; the bug had appeared in 0.2.2.
-
- *) Bugfix: the accept mutex did not work and all connections were
- handled by one process; the bug had appeared in 0.3.3.
-
- *) Bugfix: the timeout did not work if the "rtsig" method and the
- "timer_resolution" directive were used.
-
-
-Changes with nginx 0.3.4 19 Oct 2005
-
- *) Bugfix: nginx could not be built on Linux 2.4+ and MacOS X; the bug
- had appeared in 0.3.3.
-
-
-Changes with nginx 0.3.3 19 Oct 2005
-
- *) Change: the "bl" and "af" parameters of the "listen" directive was
- renamed to the "backlog" and "accept_filter".
-
- *) Feature: the "rcvbuf" and "sndbuf" parameters of the "listen"
- directive.
-
- *) Change: the "$msec" log parameter does not require now the additional
- the gettimeofday() system call.
-
- *) Feature: the -t switch now tests the "listen" directives.
-
- *) Bugfix: if the invalid address was specified in the "listen"
- directive, then after the -HUP signal nginx left an open socket in
- the CLOSED state.
-
- *) Bugfix: the mime type may be incorrectly set to default value for
- index file with variable in the name; the bug had appeared in 0.3.0.
-
- *) Feature: the "timer_resolution" directive.
-
- *) Feature: the millisecond "$upstream_response_time" log parameter.
-
- *) Bugfix: a temporary file with client request body now is removed just
- after the response header was transferred to a client.
-
- *) Bugfix: OpenSSL 0.9.6 compatibility.
-
- *) Bugfix: the SSL certificate and key file paths could not be relative.
-
- *) Bugfix: the "ssl_prefer_server_ciphers" directive did not work in the
- ngx_imap_ssl_module.
-
- *) Bugfix: the "ssl_protocols" directive allowed to specify the single
- protocol only.
-
-
-Changes with nginx 0.3.2 12 Oct 2005
-
- *) Feature: the Sun Studio 10 C compiler support.
-
- *) Feature: the "proxy_upstream_max_fails",
- "proxy_upstream_fail_timeout", "fastcgi_upstream_max_fails", and
- "fastcgi_upstream_fail_timeout" directives.
-
-
-Changes with nginx 0.3.1 10 Oct 2005
-
- *) Bugfix: the segmentation fault occurred when the signal queue
- overflowed if the "rtsig" method was used; the bug had appeared in
- 0.2.0.
-
- *) Change: correct handling of the "\\", "\"", "\'", and "\$" pairs in
- SSI.
-
-
-Changes with nginx 0.3.0 07 Oct 2005
-
- *) Change: the 10-days live time limit of worker process was eliminated.
- The limit was introduced because of millisecond timers overflow.
-
-
-Changes with nginx 0.2.6 05 Oct 2005
-
- *) Change: while using load-balancing the time before the failed backend
- retry was decreased from 60 to 10 seconds.
-
- *) Change: the "proxy_pass_unparsed_uri" was canceled, the original URI
- now passed, if the URI part is omitted in "proxy_pass" directive.
-
- *) Feature: the "error_page" directive supports redirects and allows
- more flexible to change an error code.
-
- *) Change: the charset in the "Content-Type" header line now is ignored
- in proxied subrequests.
-
- *) Bugfix: if the URI was changed in the "if" block and request did not
- found new configuration, then the ngx_http_rewrite_module rules ran
- again.
-
- *) Bugfix: if the "set" directive set the ngx_http_geo_module variable
- in some configuration part, the this variable was not available in
- other configuration parts and the "using uninitialized variable"
- error was occurred; the bug had appeared in 0.2.2.
-
-
-Changes with nginx 0.2.5 04 Oct 2005
-
- *) Change: the duplicate value of the ngx_http_geo_module variable now
- causes the warning and changes old value.
-
- *) Feature: the ngx_http_ssi_module supports the "set" command.
-
- *) Feature: the ngx_http_ssi_module supports the "file" parameter in the
- "include" command.
-
- *) Feature: the ngx_http_ssi_module supports the variable value
- substitutions in expressions of the "if" command.
-
-
-Changes with nginx 0.2.4 03 Oct 2005
-
- *) Feature: the ngx_http_ssi_module supports "$var=text", "$var!=text",
- "$var=/text/", and "$var!=/text/" expressions in the "if" command.
-
- *) Bugfix: in proxying location without trailing slash; the bug had
- appeared in 0.1.44.
-
- *) Bugfix: the segmentation fault may occurred if the "rtsig" method was
- used; the bug had appeared in 0.2.0.
-
-
-Changes with nginx 0.2.3 30 Sep 2005
-
- *) Bugfix: nginx could not be built without the --with-debug option; the
- bug had appeared in 0.2.2.
-
-
-Changes with nginx 0.2.2 30 Sep 2005
-
- *) Feature: the "config errmsg" command of the ngx_http_ssi_module.
-
- *) Change: the ngx_http_geo_module variables can be overridden by the
- "set" directive.
-
- *) Feature: the "ssl_protocols" and "ssl_prefer_server_ciphers"
- directives of the ngx_http_ssl_module and ngx_imap_ssl_module.
-
- *) Bugfix: the ngx_http_autoindex_module did not show correctly the long
- file names;
-
- *) Bugfix: the ngx_http_autoindex_module now do not show the files
- starting by dot.
-
- *) Bugfix: if the SSL handshake failed then another connection may be
- closed too.
- Thanks to Rob Mueller.
-
- *) Bugfix: the export versions of MSIE 5.x could not connect via HTTPS.
-
-
-Changes with nginx 0.2.1 23 Sep 2005
-
- *) Bugfix: if all backend using in load-balancing failed after one
- error, then nginx may got caught in an endless loop; the bug had
- appeared in 0.2.0.
-
-
-Changes with nginx 0.2.0 23 Sep 2005
-
- *) The pid-file names used during online upgrade was changed and now is
- not required a manual rename operation. The old master process adds
- the ".oldbin" suffix to its pid-file and executes a new binary file.
- The new master process creates usual pid-file without the ".newbin"
- suffix. If the master process exits, then old master process renames
- back its pid-file with the ".oldbin" suffix to the pid-file without
- suffix.
-
- *) Change: the "worker_connections" directive, new name of the
- "connections" directive; now the directive specifies maximum number
- of connections, but not maximum socket descriptor number.
-
- *) Feature: SSL supports the session cache inside one worker process.
-
- *) Feature: the "satisfy_any" directive.
-
- *) Change: the ngx_http_access_module and ngx_http_auth_basic_module do
- not run for subrequests.
-
- *) Feature: the "worker_rlimit_nofile" and "worker_rlimit_sigpending"
- directives.
-
- *) Bugfix: if all backend using in load-balancing failed after one
- error, then nginx did not try do connect to them during 60 seconds.
-
- *) Bugfix: in IMAP/POP3 command argument parsing.
- Thanks to Rob Mueller.
-
- *) Bugfix: errors while using SSL in IMAP/POP3 proxy.
-
- *) Bugfix: errors while using SSI and gzipping.
-
- *) Bugfix: the "Expires" and "Cache-Control" header lines were omitted
- from the 304 responses.
- Thanks to Alexandr Kukushkin.
-
-
-Changes with nginx 0.1.45 08 Sep 2005
-
- *) Change: the "ssl_engine" directive was canceled in the
- ngx_http_ssl_module and now is introduced at global level.
-
- *) Bugfix: the responses with SSI subrequests did not transferred via
- SSL connection.
-
- *) Various bug fixes in the IMAP/POP3 proxy.
-
-
-Changes with nginx 0.1.44 06 Sep 2005
-
- *) Feature: the IMAP/POP3 proxy supports SSL.
-
- *) Feature: the "proxy_timeout" directive of the ngx_imap_proxy_module.
-
- *) Feature: the "userid_mark" directive.
-
- *) Feature: the $remote_user variable value is determined independently
- of authorization use.
-
-
-Changes with nginx 0.1.43 30 Aug 2005
-
- *) Feature: the listen(2) backlog in the "listen" directive can be
- changed using the -HUP signal.
-
- *) Feature: the geo2nginx.pl script was added to contrib.
-
- *) Change: the FastCGI parameters with the empty values now are passed
- to a server.
-
- *) Bugfix: the segmentation fault occurred or the worker process may got
- caught in an endless loop if the proxied or FastCGI server sent the
- "Cache-Control" header line and the "expires" directive was used; in
- the proxied mode the bug had appeared in 0.1.29.
-
-
-Changes with nginx 0.1.42 23 Aug 2005
-
- *) Bugfix: if the request URI had a zero length after the processing in
- the ngx_http_proxy_module, then the segmentation fault or bus error
- occurred in the ngx_http_proxy_module.
-
- *) Bugfix: the "limit_rate" directive did not work inside the "if"
- block; the bug had appeared in 0.1.38.
-
-
-Changes with nginx 0.1.41 25 Jul 2005
-
- *) Bugfix: if the variable was used in the configuration file, then it
- can not be used in SSI.
-
-
-Changes with nginx 0.1.40 22 Jul 2005
-
- *) Bugfix: if a client sent too long header line, then the request
- information did not logged in the error log.
-
- *) Bugfix: the "Set-Cookie" header line was not transferred when the
- "X-Accel-Redirect" was used; the bug had appeared in 0.1.39.
-
- *) Bugfix: the "Content-Disposition" header line was not transferred
- when the "X-Accel-Redirect" was used.
-
- *) Bugfix: the master process did not close the listen socket on the
- SIGQUIT signal.
-
- *) Bugfix: after on-line upgrade on Linux and Solaris the process name
- became shorter in the "ps" command.
-
-
-Changes with nginx 0.1.39 14 Jul 2005
-
- *) The changes in the ngx_http_charset_module: the "default_charset"
- directive was canceled; the "charset" directive sets the response
- charset; the "source_charset" directive sets the source charset only.
-
- *) Bugfix: the backend "WWW-Authenticate" header line did not
- transferred while the 401 response code redirecting.
-
- *) Bugfix: the ngx_http_proxy_module and ngx_http_fastcgi_module may
- close a connection before anything was transferred to a client; the
- bug had appeared in 0.1.38.
-
- *) Workaround: the Linux glibc crypt_r() initialization bug.
-
- *) Bugfix: the ngx_http_ssi_module did not support the relative URI in
- the "include virtual" command.
-
- *) Bugfix: if the backend response had the "Location" header line and
- nginx should not rewrite this line, then the 500 code response body
- was transferred; the bug had appeared in 0.1.29.
-
- *) Bugfix: some directives of the ngx_http_proxy_module and
- ngx_http_fastcgi_module were not inherited from the server to the
- location level; the bug had appeared in 0.1.29.
-
- *) Bugfix: the ngx_http_ssl_module did not support the certificate
- chain.
-
- *) Bugfix: the ngx_http_autoindex_module did not show correctly the long
- file names; the bug had appeared in 0.1.38.
-
- *) Bugfixes in IMAP/POP3 proxy in interaction with a backend at the
- login state.
-
-
-Changes with nginx 0.1.38 08 Jul 2005
-
- *) Feature: the "limit_rate" directive is supported in proxy and FastCGI
- mode.
-
- *) Feature: the "X-Accel-Limit-Rate" response header line is supported
- in proxy and FastCGI mode.
-
- *) Feature: the "break" directive.
-
- *) Feature: the "log_not_found" directive.
-
- *) Bugfix: the response status code was not changed when request was
- redirected by the ""X-Accel-Redirect" header line.
-
- *) Bugfix: the variables set by the "set" directive could not be used in
- SSI.
-
- *) Bugfix: the segmentation fault may occurred if the SSI page has more
- than one remote subrequest.
-
- *) Bugfix: nginx treated the backend response as invalid if the status
- line in the header was transferred in two packets; the bug had
- appeared in 0.1.29.
-
- *) Feature: the "ssi_types" directive.
-
- *) Feature: the "autoindex_exact_size" directive.
-
- *) Bugfix: the ngx_http_autoindex_module did not support the long file
- names in UTF-8.
-
- *) Feature: the IMAP/POP3 proxy.
-
-
-Changes with nginx 0.1.37 23 Jun 2005
-
- *) Change: now the "\n" is added to the end of the "nginx.pid" file.
-
- *) Bugfix: the responses may be transferred not completely, if many
- parts or the big parts were included by SSI.
-
- *) Bugfix: if all backends had returned the 404 reponse and the
- "http_404" parameter of the "proxy_next_upstream" or
- "fastcgi_next_upstream" directives was used, then nginx started to
- request all backends again.
-
-
-Changes with nginx 0.1.36 15 Jun 2005
-
- *) Change: if the request header has duplicate the "Host", "Connection",
- "Content-Length", or "Authorization" lines, then nginx now returns
- the 400 error.
-
- *) Change: the "post_accept_timeout" directive was canceled.
-
- *) Feature: the "default", "af=", "bl=", "deferred", and "bind"
- parameters of the "listen" directive.
-
- *) Feature: the FreeBSD accept filters support.
-
- *) Feature: the Linux TCP_DEFER_ACCEPT support.
-
- *) Bugfix: the ngx_http_autoindex_module did not support the file names
- in UTF-8.
-
- *) Bugfix: the new log file can be rotated by the -USR1 signal only if
- the reconfiguration by the -HUP signal was made twice.
-
-
-Changes with nginx 0.1.35 07 Jun 2005
-
- *) Feature: the "working_directory" directive.
-
- *) Feature: the "port_in_redirect" directive.
-
- *) Bugfix: the segmentation fault was occurred if the backend response
- header was in several packets; the bug had appeared in 0.1.29.
-
- *) Bugfix: if more than 10 servers were configured or some server did
- not use the "listen" directive, then the segmentation fault was
- occurred on the start.
-
- *) Bugfix: the segmentation fault might occur if the response was bigger
- than the temporary file.
-
- *) Bugfix: nginx returned the 400 response on requests like
- "GET http://www.domain.com/uri HTTP/1.0"; the bug had appeared in
- 0.1.28.
-
-
-Changes with nginx 0.1.34 26 May 2005
-
- *) Bugfix: the worker process may got caught in an endless loop if the
- big response part were include by SSI.
-
- *) Bugfix: the variables set by the "set" directive were not available
- in SSI.
-
- *) Feature: the "autoindex_localtime" directive.
-
- *) Bugfix: the empty value of the "proxy_set_header" directive forbids
- the client request header line passing.
-
-
-Changes with nginx 0.1.33 23 May 2005
-
- *) Bugfix: nginx could not be built with the --without-pcre parameter;
- the bug had appeared in 0.1.29.
-
- *) Bugfix: 3, 4, 7, and 8 the "proxy_set_header" directives in one level
- cause the bus fault on start up.
-
- *) Bugfix: the HTTP protocol was specified in the HTTPS redirects.
-
- *) Bugfix: if the "rewrite" directive used the captures inside the "if"
- directive, then the 500 error code was returned.
-
-
-Changes with nginx 0.1.32 19 May 2005
-
- *) Bugfix: the arguments were omitted in the redirects, issued by the
- "rewrite" directive; the bug had appeared in 0.1.29.
-
- *) Feature: the "if" directive supports the captures in regular
- expressions.
-
- *) Feature: the "set" directive supports the variables and the captures
- of regular expressions.
-
- *) Feature: the "X-Accel-Redirect" response header line is supported in
- proxy and FastCGI mode.
-
-
-Changes with nginx 0.1.31 16 May 2005
-
- *) Bugfix: the response encrypted by SSL may not transferred complete.
-
- *) Bugfix: errors while processing FastCGI response by SSI.
-
- *) Bugfix: errors while using SSI and gzipping.
-
- *) Bugfix: the redirect with the 301 code was transferred without
- response body; the bug had appeared in 0.1.30.
-
-
-Changes with nginx 0.1.30 14 May 2005
-
- *) Bugfix: the worker process may got caught in an endless loop if the
- SSI was used.
-
- *) Bugfix: the response encrypted by SSL may not transferred complete.
-
- *) Bugfix: if the length of the response part received at once from
- proxied or FastCGI server was equal to 500, then nginx returns the
- 500 response code; in proxy mode the bug had appeared in 0.1.29 only.
-
- *) Bugfix: nginx did not consider the directives with 8 or 9 parameters
- as invalid.
-
- *) Feature: the "return" directive can return the 204 response code.
-
- *) Feature: the "ignore_invalid_headers" directive.
-
-
-Changes with nginx 0.1.29 12 May 2005
-
- *) Feature: the ngx_http_ssi_module supports "include virtual" command.
-
- *) Feature: the ngx_http_ssi_module supports the condition command like
- 'if expr="$NAME"' and "else" and "endif" commands. Only one nested
- level is supported.
-
- *) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and DATE_GMT
- variables and "config timefmt" command.
-
- *) Feature: the "ssi_ignore_recycled_buffers" directive.
-
- *) Bugfix: the "echo" command did not show the default value for the
- empty QUERY_STRING variable.
-
- *) Change: the ngx_http_proxy_module was rewritten.
-
- *) Feature: the "proxy_redirect", "proxy_pass_request_headers",
- "proxy_pass_request_body", and "proxy_method" directives.
-
- *) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
- canceled and must be replaced with the proxy_set_header directive.
-
- *) Change: the "proxy_preserve_host" is canceled and must be replaced
- with the "proxy_set_header Host $host" and the "proxy_redirect off"
- directives, the "proxy_set_header Host $host:$proxy_port" directive
- and the appropriate proxy_redirect directives.
-
- *) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
- with the "proxy_set_header X-Real-IP $remote_addr" directive.
-
- *) Change: the "proxy_add_x_forwarded_for" is canceled and must be
- replaced with
- the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
- directive.
-
- *) Change: the "proxy_set_x_url" is canceled and must be replaced with
- the "proxy_set_header X-URL http://$host:$server_port$request_uri"
- directive.
-
- *) Feature: the "fastcgi_param" directive.
-
- *) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
- directive are canceled and must be replaced with the fastcgi_param
- directives.
-
- *) Feature: the "index" directive can use the variables.
-
- *) Feature: the "index" directive can be used at http and server levels.
-
- *) Change: the last index only in the "index" directive can be absolute.
-
- *) Feature: the "rewrite" directive can use the variables.
-
- *) Feature: the "internal" directive.
-
- *) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
- SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
- REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
-
- *) Change: nginx now passes the invalid lines in a client request
- headers or a backend response header.
-
- *) Bugfix: if the backend did not transfer response for a long time and
- the "send_timeout" was less than "proxy_read_timeout", then nginx
- returned the 408 response.
-
- *) Bugfix: the segmentation fault was occurred if the backend sent an
- invalid line in response header; the bug had appeared in 0.1.26.
-
- *) Bugfix: the segmentation fault may occurred in FastCGI fault
- tolerance configuration.
-
- *) Bugfix: the "expires" directive did not remove the previous "Expires"
- and "Cache-Control" headers.
-
- *) Bugfix: nginx did not take into account trailing dot in "Host" header
- line.
-
- *) Bugfix: the ngx_http_auth_module did not work under Linux.
-
- *) Bugfix: the rewrite directive worked incorrectly, if the arguments
- were in a request.
-
- *) Bugfix: nginx could not be built on MacOS X.
-
-
-Changes with nginx 0.1.28 08 Apr 2005
-
- *) Bugfix: nginx hogs CPU while proxying the huge files.
-
- *) Bugfix: nginx could not be built by gcc 4.0 on Linux.
-
-
-Changes with nginx 0.1.27 28 Mar 2005
-
- *) Feature: the "blocked" parameter of the "valid_referers" directive.
-
- *) Change: the errors while handling the request header now logged at
- "info" level. The server name and the "Host" and "Referer" header
- lines also logged.
-
- *) Change: the "Host" header line is also logged in error log.
-
- *) Feature: the proxy_pass_unparsed_uri directive. The special handling
- of the "://" symbols in URI, appeared in 0.1.11 version, now is
- canceled.
-
- *) Bugfix: nginx could not be built on FreeBSD and Linux, if the
- --without-ngx_http_auth_basic_module configuration parameter was
- used.
-
-
-Changes with nginx 0.1.26 22 Mar 2005
-
- *) Change: the invalid client header lines are now ignored and logged at
- the info level.
-
- *) Change: the server name is also logged in error log.
-
- *) Feature: the ngx_http_auth_basic_module module and the auth_basic and
- auth_basic_user_file directives.
-
-
-Changes with nginx 0.1.25 19 Mar 2005
-
- *) Bugfix: nginx did run on Linux parisc.
-
- *) Feature: nginx now does not start under FreeBSD if the sysctl
- kern.ipc.somaxconn value is too big.
-
- *) Bugfix: if a request was internally redirected by the
- ngx_http_index_module module to the ngx_http_proxy_module or
- ngx_http_fastcgi_module modules, then the index file was not closed
- after request completion.
-
- *) Feature: the "proxy_pass" can be used in location with regular
- expression.
-
- *) Feature: the ngx_http_rewrite_filter_module module supports the
- condition like "if ($HTTP_USER_AGENT ~ MSIE)".
-
- *) Bugfix: nginx started too slow if the large number of addresses and
- text values were used in the "geo" directive.
-
- *) Change: a variable name must be declared as "$name" in the "geo"
- directive. The previous variant without "$" is still supported, but
- will be removed soon.
-
- *) Feature: the "%{VARIABLE}v" logging parameter.
-
- *) Feature: the "set $name value" directive.
-
- *) Bugfix: gcc 4.0 compatibility.
-
- *) Feature: the --with-openssl-opt=OPTIONS autoconfiguration directive.
-
-
-Changes with nginx 0.1.24 04 Mar 2005
-
- *) Feature: the ngx_http_ssi_filter_module supports the QUERY_STRING and
- DOCUMENT_URI variables.
-
- *) Bugfix: the ngx_http_autoindex_module may some times return the 404
- response for existent directory, if this directory was used in
- "alias" directive.
-
- *) Bugfix: the ngx_http_ssi_filter_module ran incorrectly for large
- responses.
-
- *) Bugfix: the lack of the "Referer" header line was always accounted as
- valid referrer.
-
-
-Changes with nginx 0.1.23 01 Mar 2005
-
- *) Feature: the ngx_http_ssi_filter_module and the ssi,
- ssi_silent_errors, and ssi_min_file_chunk directives. The 'echo
- var="HTTP_..." default=""' and 'echo var="REMOTE_ADDR"' commands are
- supported.
-
- *) Feature: the %request_time log parameter.
-
- *) Feature: if the request has no the "Host" header line, then the
- "proxy_preserve_host" directive set this header line to the first
- server name of the "server_name" directive.
-
- *) Bugfix: nginx could not be built on platforms different from i386,
- amd64, sparc, and ppc; the bug had appeared in 0.1.22.
-
- *) Bugfix: the ngx_http_autoindex_module now shows the information not
- about the symlink, but about file or directory it points to.
-
- *) Bugfix: the %apache_length parameter logged the negative length of
- the response header if the no response was transferred to a client.
-
-
-Changes with nginx 0.1.22 22 Feb 2005
-
- *) Bugfix: the ngx_http_stub_status_module showed incorrect handled
- connections statistics if the proxying or FastCGI server were used.
-
- *) Bugfix: the installation paths were incorrectly quoted on Linux and
- Solaris; the bug had appeared in 0.1.21.
-
-
-Changes with nginx 0.1.21 22 Feb 2005
-
- *) Bugfix: the ngx_http_stub_status_module showed incorrect statistics
- if "rtsig" method was used or if several worker process ran on SMP.
-
- *) Bugfix: nginx could not be built by the icc compiler on Linux or if
- the zlib-1.2.x library was building from sources.
-
- *) Bugfix: nginx could not be built on NetBSD 2.0.
-
-
-Changes with nginx 0.1.20 17 Feb 2005
-
- *) Feature: the new "script_filename" and "remote_port" parameters of
- the fastcgi_params directive.
-
- *) Bugfix: the FastCGI stderr stream was handled incorrectly.
-
-
-Changes with nginx 0.1.19 16 Feb 2005
-
- *) Bugfix: now, if request contains the zero, then the 404 error is
- returned for the local requests.
-
- *) Bugfix: nginx could not be built on NetBSD 2.0.
-
- *) Bugfix: the timeout may occur while reading of the client request
- body via SSL connections.
-
-
-Changes with nginx 0.1.18 09 Feb 2005
-
- *) Workaround: the default values of the devpoll_events and the
- devpoll_changes directives changed from 512 to 32 to be compatible
- with Solaris 10.
-
- *) Bugfix: the proxy_set_x_var and fastcgi_set_var directives were not
- inherited.
-
- *) Bugfix: in a redirect rewrite directive arguments were concatenated
- with URI by an "&" rather than a "?".
-
- *) Bugfix: the lines without trailing ";" in the file being included by
- the ngx_http_geo_module were silently ignored.
-
- *) Feature: the ngx_http_stub_status_module.
-
- *) Bugfix: the unknown log format in the access_log directive caused the
- segmentation fault.
-
- *) Feature: the new "document_root" parameter of the fastcgi_params
- directive.
-
- *) Feature: the fastcgi_redirect_errors directive.
-
- *) Feature: the new "break" modifier of the "rewrite" directive allows
- to stop the rewrite/location cycle and sets the current configuration
- to the request.
-
-
-Changes with nginx 0.1.17 03 Feb 2005
-
- *) Change: the ngx_http_rewrite_module was rewritten from the scratch.
- Now it is possible to redirect, to return the error codes, to check
- the variables and referrers. The directives can be used inside
- locations. The redirect directive was canceled.
-
- *) Feature: the ngx_http_geo_module.
-
- *) Feature: the proxy_set_x_var and fastcgi_set_var directives.
-
- *) Bugfix: the location configuration with "=" modifier may be used in
- another location.
-
- *) Bugfix: the correct content type was set only for requests that use
- small caps letters in extension.
-
- *) Bugfix: if the proxy_pass or fastcgi_pass directives were set in the
- location, and access was denied, and the error was redirected to a
- static page, then the segmentation fault occurred.
-
- *) Bugfix: if in a proxied "Location" header was a relative URL, then a
- host name and a slash were added to them; the bug had appeared in
- 0.1.14.
-
- *) Bugfix: the system error message was not logged on Linux.
-
-
-Changes with nginx 0.1.16 25 Jan 2005
-
- *) Bugfix: if the response were transferred by chunks, then on the HEAD
- request the final chunk was issued.
-
- *) Bugfix: the "Connection: keep-alive" header were issued, even if the
- keepalive_timeout directive forbade the keep-alive use.
-
- *) Bugfix: the errors in the ngx_http_fastcgi_module caused the
- segmentation faults.
-
- *) Bugfix: the compressed response encrypted by SSL may not transferred
- complete.
-
- *) Bugfix: the TCP-specific TCP_NODELAY, TCP_NOPUSH, and TCP_CORK
- options, are not used for the unix domain sockets.
-
- *) Feature: the rewrite directive supports the arguments rewriting.
-
- *) Bugfix: the response code 400 was returned for the POST request with
- the "Content-Length: 0" header; the bug had appeared in 0.1.14.
-
-
-Changes with nginx 0.1.15 19 Jan 2005
-
- *) Bugfix: the error while the connecting to the FastCGI server caused
- segmentation fault.
-
- *) Bugfix: the correct handling of the regular expression, that has
- different number of the captures and substitutions.
-
- *) Feature: the location, that is passed to the FastCGI server, can be
- regular expression.
-
- *) Bugfix: the FastCGI's parameter REQUEST_URI is now passed with the
- arguments and in the original state.
-
- *) Bugfix: the ngx_http_rewrite_module module was required to be built
- to use the regular expressions in locations.
-
- *) Bugfix: the directive "proxy_preserve_host on" adds port 80 to the
- "Host" headers, if upstream listen on port 80; the bug had appeared
- in 0.1.14.
-
- *) Bugfix: the same paths in autoconfiguration parameters
- --http-client-body-temp-path=PATH and --http-proxy-temp-path=PATH, or
- --http-client-body-temp-path=PATH and --http-fastcgi-temp-path=PATH
- caused segmentation fault.
-
-
-Changes with nginx 0.1.14 18 Jan 2005
-
- *) Feature: the autoconfiguration directives:
- --http-client-body-temp-path=PATH, --http-proxy-temp-path=PATH, and
- --http-fastcgi-temp-path=PATH
-
- *) Change: the directory name for the temporary files with the client
- request body is specified by directive client_body_temp_path, by
- default it is <prefix>/client_body_temp.
-
- *) Feature: the ngx_http_fastcgi_module and the directives:
- fastcgi_pass, fastcgi_root, fastcgi_index, fastcgi_params,
- fastcgi_connect_timeout, fastcgi_send_timeout, fastcgi_read_timeout,
- fastcgi_send_lowat, fastcgi_header_buffer_size, fastcgi_buffers,
- fastcgi_busy_buffers_size, fastcgi_temp_path,
- fastcgi_max_temp_file_size, fastcgi_temp_file_write_size,
- fastcgi_next_upstream, and fastcgi_x_powered_by.
-
- *) Bugfix: the "[alert] zero size buf" error; the bug had appeared in
- 0.1.3.
-
- *) Change: the URI must be specified after the host name in the
- proxy_pass directive.
-
- *) Change: the %3F symbol in the URI was considered as the argument
- string start.
-
- *) Feature: the unix domain sockets support in the
- ngx_http_proxy_module.
-
- *) Feature: the ssl_engine and ssl_ciphers directives.
- Thanks to Sergey Skvortsov for SSL-accelerator.
-
-
-Changes with nginx 0.1.13 21 Dec 2004
-
- *) Feature: the server_names_hash and server_names_hash_threshold
- directives.
-
- *) Bugfix: the *.domain.tld names in the "server_name" directive did not
- work.
-
- *) Bugfix: the %request_length log parameter logged the incorrect
- length.
-
-
-Changes with nginx 0.1.12 06 Dec 2004
-
- *) Feature: the %request_length log parameter.
-
- *) Bugfix: when using the /dev/poll, select and poll on the platforms,
- where these methods may do the false reports, there may be the long
- delay when the request was passed via the keep-alive connection. It
- may be at least on Solaris when using the /dev/poll.
-
- *) Bugfix: the send_lowat directive is ignored on Linux because Linux
- does not support the SO_SNDLOWAT option.
-
-
-Changes with nginx 0.1.11 02 Dec 2004
-
- *) Feature: the worker_priority directive.
-
- *) Change: both tcp_nopush and tcp_nodelay directives affect the
- transferred response.
-
- *) Bugfix: nginx did not call initgroups().
- Thanks to Andrew Sitnikov and Andrei Nigmatulin.
-
- *) Change: now the ngx_http_autoindex_module shows the file size in the
- bytes.
-
- *) Bugfix: the ngx_http_autoindex_module returned the 500 error if the
- broken symlink was in a directory.
-
- *) Bugfix: the files bigger than 4G could not be transferred using
- sendfile.
-
- *) Bugfix: if the backend was resolved to several backends and there was
- an error while the response waiting then process may got caught in an
- endless loop.
-
- *) Bugfix: the worker process may exit with the "unknown cycle" message
- when the /dev/poll method was used.
-
- *) Bugfix: "close() channel failed" errors.
-
- *) Bugfix: the autodetection of the "nobody" and "nogroup" groups.
-
- *) Bugfix: the send_lowat directive did not work on Linux.
-
- *) Bugfix: the segmentation fault occurred if there was no events
- section in configuration.
-
- *) Bugfix: nginx could not be built on OpenBSD.
-
- *) Bugfix: the double slashes in "://" in the URI were converted to
- ":/".
-
-
-Changes with nginx 0.1.10 26 Nov 2004
-
- *) Bugfix: if the request without arguments contains "//", "/./", "/../"
- or "%XX" then the last character in the request line was lost; the
- bug had appeared in 0.1.9.
-
- *) Bugfix: the fix in 0.1.9 for the files bigger than 2G on Linux did
- not work.
-
-
-Changes with nginx 0.1.9 25 Nov 2004
-
- *) Bugfix: the proxied request was sent without arguments if the request
- contains "//", "/./", "/../" or "%XX".
-
- *) Bugfix: the large compressed responses may be transferred not
- completely.
-
- *) Bugfix: the files bigger than 2G was not transferred on Linux that
- does not support sendfile64().
-
- *) Bugfix: while the build configuration on Linux the --with-poll_module
- parameter was required; the bug had appeared in 0.1.8.
-
-
-Changes with nginx 0.1.8 20 Nov 2004
-
- *) Bugfix: in the ngx_http_autoindex_module if the long file names were
- in the listing.
-
- *) Feature: the "^~" modifier in the location directive.
-
- *) Feature: the proxy_max_temp_file_size directive.
-
-
-Changes with nginx 0.1.7 12 Nov 2004
-
- *) Bugfix: on FreeBSD the segmentation fault may occur if the size of
- the transferred file was changed; the bug had appeared in 0.1.5.
-
-
-Changes with nginx 0.1.6 11 Nov 2004
-
- *) Bugfix: some location directive combinations with the regular
- expressions caused the wrong configuration choose.
-
-
-Changes with nginx 0.1.5 11 Nov 2004
-
- *) Bugfix: on Solaris and Linux there may be too many "recvmsg()
- returned not enough data" alerts.
-
- *) Bugfix: there were the "writev() failed (22: Invalid argument)"
- errors on Solaris in proxy mode without sendfile. On other platforms
- that do not support sendfile at all the process got caught in an
- endless loop.
-
- *) Bugfix: segmentation fault on Solaris in proxy mode and using
- sendfile.
-
- *) Bugfix: segmentation fault on Solaris.
-
- *) Bugfix: on-line upgrade did not work on Linux.
-
- *) Bugfix: the ngx_http_autoindex_module module did not escape the
- spaces, the quotes, and the percent signs in the directory listing.
-
- *) Change: the decrease of the copy operations.
-
- *) Feature: the userid_p3p directive.
-
-
-Changes with nginx 0.1.4 26 Oct 2004
-
- *) Bugfix: in the ngx_http_autoindex_module.
-
-
-Changes with nginx 0.1.3 25 Oct 2004
-
- *) Feature: the ngx_http_autoindex_module and the autoindex directive.
-
- *) Feature: the proxy_set_x_url directive.
-
- *) Bugfix: proxy module may get caught in an endless loop when sendfile
- is not used.
-
-
-Changes with nginx 0.1.2 21 Oct 2004
-
- *) Feature: the --user=USER, --group=GROUP, and --with-ld-opt=OPTIONS
- options in configure.
-
- *) Feature: the server_name directive supports *.domain.tld.
-
- *) Bugfix: the portability improvements.
-
- *) Bugfix: if configuration file was set in command line, the
- reconfiguration was impossible; the bug had appeared in 0.1.1.
-
- *) Bugfix: proxy module may get caught in an endless loop when sendfile
- is not used.
-
- *) Bugfix: with sendfile the response was not recoded according to the
- charset module directives; the bug had appeared in 0.1.1.
-
- *) Bugfix: very seldom bug in the kqueue processing.
-
- *) Bugfix: the gzip module compressed the proxied responses that was
- already compressed.
-
-
-Changes with nginx 0.1.1 11 Oct 2004
-
- *) Feature: the gzip_types directive.
-
- *) Feature: the tcp_nodelay directive.
-
- *) Feature: the send_lowat directive is working not only on OSes that
- support kqueue NOTE_LOWAT, but also on OSes that support SO_SNDLOWAT.
-
- *) Feature: the setproctitle() emulation for Linux and Solaris.
-
- *) Bugfix: the "Location" header rewrite bug fixed while the proxying.
-
- *) Bugfix: the ngx_http_chunked_module module may get caught in an
- endless loop.
-
- *) Bugfix: the /dev/poll module bugs fixed.
-
- *) Bugfix: the responses were corrupted when the temporary files were
- used while the proxying.
-
- *) Bugfix: the unescaped requests were passed to the backend.
-
- *) Bugfix: while the build configuration on Linux 2.4 the
- --with-poll_module parameter was required.
-
-
-Changes with nginx 0.1.0 04 Oct 2004
-
- *) The first public version.
-
diff --git a/usr.sbin/nginx/CHANGES.ru b/usr.sbin/nginx/CHANGES.ru
deleted file mode 100644
index 5915dd854f2..00000000000
--- a/usr.sbin/nginx/CHANGES.ru
+++ /dev/null
@@ -1,6749 +0,0 @@
-
-Изменения в nginx 1.6.0 24.04.2014
-
- *) Стабильная ветка 1.6.x.
-
-
-Изменения в nginx 1.5.13 08.04.2014
-
- *) Изменение: улучшена обработка хэш-таблиц; в директивах
- variables_hash_max_size и types_hash_bucket_size значения по
- умолчанию изменены на 1024 и 64 соответственно.
-
- *) Добавление: модуль ngx_http_mp4_module теперь понимает аргумент end.
-
- *) Добавление: поддержка byte ranges модулем ngx_http_mp4_module и при
- сохранении ответов в кэш.
-
- *) Исправление: теперь nginx не пишет в лог сообщения "ngx_slab_alloc()
- failed: no memory" при использовании разделяемой памяти в
- ssl_session_cache и в модуле ngx_http_limit_req_module.
-
- *) Исправление: директива underscores_in_headers не разрешала
- подчёркивание в первом символе заголовка.
- Спасибо Piotr Sikora.
-
- *) Исправление: cache manager мог нагружать процессор при выходе в
- nginx/Windows.
-
- *) Исправление: при использовании ssl_session_cache с параметром shared
- рабочий процесс nginx/Windows завершался аварийно.
-
- *) Исправление: в модуле ngx_http_spdy_module.
-
-
-Изменения в nginx 1.5.12 18.03.2014
-
- *) Безопасность: при обработке специально созданного запроса модулем
- ngx_http_spdy_module могло происходить переполнение буфера в рабочем
- процессе, что потенциально могло приводить к выполнению произвольного
- кода (CVE-2014-0133).
- Спасибо Lucas Molas из Programa STIC, Fundación Dr. Manuel Sadosky,
- Buenos Aires, Argentina.
-
- *) Добавление: параметр proxy_protocol в директивах listen и
- real_ip_header, переменная $proxy_protocol_addr.
-
- *) Исправление: в директиве fastcgi_next_upstream.
- Спасибо Lucas Molas.
-
-
-Изменения в nginx 1.5.11 04.03.2014
-
- *) Безопасность: при обработке специально созданного запроса модулем
- ngx_http_spdy_module на 32-битных платформах могла повреждаться
- память рабочего процесса, что потенциально могло приводить к
- выполнению произвольного кода (CVE-2014-0088); ошибка появилась в
- 1.5.10.
- Спасибо Lucas Molas из Programa STIC, Fundación Dr. Manuel Sadosky,
- Buenos Aires, Argentina.
-
- *) Добавление: переменная $ssl_session_reused.
-
- *) Исправление: директива client_max_body_size могла не работать при
- чтении тела запроса с использованием chunked transfer encoding;
- ошибка появилась в 1.3.9.
- Спасибо Lucas Molas.
-
- *) Исправление: при проксировании WebSocket-соединений в рабочем
- процессе мог произойти segmentation fault.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовался модуль ngx_http_spdy_module на 32-битных
- платформах; ошибка появилась в 1.5.10.
-
- *) Исправление: значение переменной $upstream_status могло быть
- неверным, если использовались директивы proxy_cache_use_stale или
- proxy_cache_revalidate.
- Спасибо Piotr Sikora.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если ошибки с кодом 400 с помощью директивы error_page
- перенаправлялись в именованный location.
-
- *) Исправление: nginx/Windows не собирался с Visual Studio 2013.
-
-
-Изменения в nginx 1.5.10 04.02.2014
-
- *) Добавление: модуль ngx_http_spdy_module теперь использует протокол
- SPDY 3.1.
- Спасибо Automattic и MaxCDN за спонсирование разработки.
-
- *) Добавление: модуль ngx_http_mp4_module теперь пропускает дорожки,
- имеющие меньшую длину, чем запрошенная перемотка.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если переменная $ssl_session_id использовалась при логгировании;
- ошибка появилась в 1.5.9.
-
- *) Исправление: переменные $date_local и $date_gmt использовали неверный
- формат вне модуля ngx_http_ssi_filter_module.
-
- *) Исправление: клиентские соединения могли сразу закрываться, если
- использовался отложенный accept; ошибка появилась в 1.3.15.
-
- *) Исправление: сообщения "getsockopt(TCP_FASTOPEN) ... failed"
- записывались в лог в процессе обновления исполняемого файла на Linux;
- ошибка появилась в 1.5.8.
- Спасибо Piotr Sikora.
-
-
-Изменения в nginx 1.5.9 22.01.2014
-
- *) Изменение: теперь в заголовке X-Accel-Redirect nginx ожидает
- закодированный URI.
-
- *) Добавление: директива ssl_buffer_size.
-
- *) Добавление: директиву limit_rate теперь можно использовать для
- ограничения скорости передачи ответов клиенту в SPDY-соединениях.
-
- *) Добавление: директива spdy_chunk_size.
-
- *) Добавление: директива ssl_session_tickets.
- Спасибо Dirkjan Bussink.
-
- *) Исправление: переменная $ssl_session_id содержала всю сессию в
- сериализованном виде вместо её идентификатора.
- Спасибо Ivan Ristić.
-
- *) Исправление: nginx неправильно обрабатывал закодированный символ "?"
- в команде SSI include.
-
- *) Исправление: модуль ngx_http_dav_module не раскодировал целевой URI
- при обработке методов COPY и MOVE.
-
- *) Исправление: resolver не понимал доменные имена с точкой в конце.
- Спасибо Yichun Zhang.
-
- *) Исправление: при проксировании в логах могли появляться сообщения
- "zero size buf in output"; ошибка появилась в 1.3.9.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовался модуль ngx_http_spdy_module.
-
- *) Исправление: при использовании методов обработки соединений select,
- poll и /dev/poll проксируемые WebSocket-соединения могли зависать
- сразу после открытия.
-
- *) Исправление: директива xclient почтового прокси-сервера некорректно
- передавала IPv6-адреса.
-
-
-Изменения в nginx 1.5.8 17.12.2013
-
- *) Добавление: теперь resolver поддерживает IPv6.
-
- *) Добавление: директива listen поддерживает параметр fastopen.
- Спасибо Mathew Rodley.
-
- *) Добавление: поддержка SSL в модуле ngx_http_uwsgi_module.
- Спасибо Roberto De Ioris.
-
- *) Добавление: скрипты подсветки синтаксиса для vim добавлены в contrib.
- Спасибо Evan Miller.
-
- *) Исправление: при чтении тела запроса с использованием chunked
- transfer encoding по SSL-соединению мог произойти таймаут.
-
- *) Исправление: директива master_process работала неправильно в
- nginx/Windows.
-
- *) Исправление: параметр setfib директивы listen мог не работать.
-
- *) Исправление: в модуле ngx_http_spdy_module.
-
-
-Изменения в nginx 1.5.7 19.11.2013
-
- *) Безопасность: символ, следующий за незакодированным пробелом в строке
- запроса, обрабатывался неправильно (CVE-2013-4547); ошибка появилась
- в 0.8.41.
- Спасибо Ivan Fratric из Google Security Team.
-
- *) Изменение: уровень логгирования ошибок auth_basic об отсутствии
- пароля понижен с уровня error до info.
-
- *) Добавление: директивы proxy_cache_revalidate,
- fastcgi_cache_revalidate, scgi_cache_revalidate и
- uwsgi_cache_revalidate.
-
- *) Добавление: директива ssl_session_ticket_key.
- Спасибо Piotr Sikora.
-
- *) Исправление: директива "add_header Cache-Control ''" добавляла строку
- заголовка ответа "Cache-Control" с пустым значением.
-
- *) Исправление: директива "satisfy any" могла вернуть ошибку 403 вместо
- 401 при использовании директив auth_request и auth_basic.
- Спасибо Jan Marc Hoffmann.
-
- *) Исправление: параметры accept_filter и deferred директивы listen
- игнорировались для listen-сокетов, создаваемых в процессе обновления
- исполняемого файла.
- Спасибо Piotr Sikora.
-
- *) Исправление: часть данных, полученных от бэкенда при
- небуферизированном проксировании, могла не отправляться клиенту
- сразу, если использовались директивы gzip или gunzip.
- Спасибо Yichun Zhang.
-
- *) Исправление: в обработке ошибок в модуле
- ngx_http_gunzip_filter_module.
-
- *) Исправление: ответы могли зависать, если использовался модуль
- ngx_http_spdy_module и директива auth_request.
-
- *) Исправление: утечки памяти в nginx/Windows.
-
-
-Изменения в nginx 1.5.6 01.10.2013
-
- *) Добавление: директива fastcgi_buffering.
-
- *) Добавление: директивы proxy_ssl_protocols и proxy_ssl_ciphers.
- Спасибо Piotr Sikora.
-
- *) Добавление: оптимизация SSL handshake при использовании длинных
- цепочек сертификатов.
-
- *) Добавление: почтовый прокси-сервер поддерживает SMTP pipelining.
-
- *) Исправление: в модуле ngx_http_auth_basic_module при использовании
- метода шифрования паролей "$apr1$".
- Спасибо Markus Linnala.
-
- *) Исправление: на MacOSX, Cygwin и nginx/Windows для обработки запроса
- мог использоваться неверный location, если для задания location'ов
- использовались символы разных регистров.
-
- *) Исправление: автоматическое перенаправление с добавлением
- завершающего слэша для проксированных location'ов могло не работать.
-
- *) Исправление: в почтовом прокси-сервере.
-
- *) Исправление: в модуле ngx_http_spdy_module.
-
-
-Изменения в nginx 1.5.5 17.09.2013
-
- *) Изменение: теперь nginx по умолчанию использует HTTP/1.0, если точно
- определить протокол не удалось.
-
- *) Добавление: директива disable_symlinks теперь использует O_PATH на
- Linux.
-
- *) Добавление: для определения того, что клиент закрыл соединение, при
- использовании метода epoll теперь используются события EPOLLRDHUP.
-
- *) Исправление: в директиве valid_referers при использовании параметра
- server_names.
-
- *) Исправление: переменная $request_time не работала в nginx/Windows.
-
- *) Исправление: в директиве image_filter.
- Спасибо Lanshun Zhou.
-
- *) Исправление: совместимость с OpenSSL 1.0.1f.
- Спасибо Piotr Sikora.
-
-
-Изменения в nginx 1.5.4 27.08.2013
-
- *) Изменение: MIME-тип для расширения js изменён на
- "application/javascript"; значение по умолчанию директивы
- charset_types изменено соответственно.
-
- *) Изменение: теперь директива image_filter с параметром size возвращает
- ответ с MIME-типом "application/json".
-
- *) Добавление: модуль ngx_http_auth_request_module.
-
- *) Исправление: на старте или во время переконфигурации мог произойти
- segmentation fault, если использовалась директива try_files с пустым
- параметром.
-
- *) Исправление: утечки памяти при использовании в директивах root и
- auth_basic_user_file относительных путей, заданных с помощью
- переменных.
-
- *) Исправление: директива valid_referers неправильно выполняла
- регулярные выражения, если заголовок Referer начинался с "https://".
- Спасибо Liangbin Li.
-
- *) Исправление: ответы могли зависать, если использовались подзапросы и
- при обработке подзапроса происходила ошибка во время SSL handshake с
- бэкендом.
- Спасибо Aviram Cohen.
-
- *) Исправление: в модуле ngx_http_autoindex_module.
-
- *) Исправление: в модуле ngx_http_spdy_module.
-
-
-Изменения в nginx 1.5.3 30.07.2013
-
- *) Изменение во внутреннем API: теперь при небуферизированной работе с
- бэкендами u->length по умолчанию устанавливается в -1.
-
- *) Изменение: теперь при получении неполного ответа от бэкенда nginx
- отправляет полученную часть ответа, после чего закрывает соединение с
- клиентом.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовался модуль ngx_http_spdy_module и директива
- client_body_in_file_only.
-
- *) Исправление: параметр so_keepalive директивы listen мог работать
- некорректно на DragonFlyBSD.
- Спасибо Sepherosa Ziehau.
-
- *) Исправление: в модуле ngx_http_xslt_filter_module.
-
- *) Исправление: в модуле ngx_http_sub_filter_module.
-
-
-Изменения в nginx 1.5.2 02.07.2013
-
- *) Добавление: теперь можно использовать несколько директив error_log.
-
- *) Исправление: метод $r->header_in() встроенного перла не возвращал
- значения строк "Cookie" и "X-Forwarded-For" из заголовка запроса;
- ошибка появилась в 1.3.14.
-
- *) Исправление: в модуле ngx_http_spdy_module.
- Спасибо Jim Radford.
-
- *) Исправление: nginx не собирался на Linux при использовании x32 ABI.
- Спасибо Сергею Иванцову.
-
-
-Изменения в nginx 1.5.1 04.06.2013
-
- *) Добавление: директивы ssi_last_modified, sub_filter_last_modified и
- xslt_last_modified.
- Спасибо Алексею Колпакову.
-
- *) Добавление: параметр http_403 в директивах proxy_next_upstream,
- fastcgi_next_upstream, scgi_next_upstream и uwsgi_next_upstream.
-
- *) Добавление: директивы allow и deny теперь поддерживают unix domain
- сокеты.
-
- *) Исправление: nginx не собирался с модулем ngx_mail_ssl_module, но без
- модуля ngx_http_ssl_module; ошибка появилась в 1.3.14.
-
- *) Исправление: в директиве proxy_set_body.
- Спасибо Lanshun Zhou.
-
- *) Исправление: в директиве lingering_time.
- Спасибо Lanshun Zhou.
-
- *) Исправление: параметр fail_timeout директивы server в блоке upstream
- мог не работать, если использовался параметр max_fails; ошибка
- появилась в 1.3.0.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовалась директива ssl_stapling.
- Спасибо Piotr Sikora.
-
- *) Исправление: в почтовом прокси-сервере.
- Спасибо Filipe Da Silva.
-
- *) Исправление: nginx/Windows мог перестать принимать соединения, если
- использовалось несколько рабочих процессов.
-
-
-Изменения в nginx 1.5.0 07.05.2013
-
- *) Безопасность: при обработке специально созданного запроса мог
- перезаписываться стек рабочего процесса, что могло приводить к
- выполнению произвольного кода (CVE-2013-2028); ошибка появилась в
- 1.3.9.
- Спасибо Greg MacManus, iSIGHT Partners Labs.
-
-
-Изменения в nginx 1.4.0 24.04.2013
-
- *) Исправление: nginx не собирался с модулем ngx_http_perl_module, если
- использовался параметр --with-openssl; ошибка появилась в 1.3.16.
-
- *) Исправление: в работе с телом запроса из модуля ngx_http_perl_module;
- ошибка появилась в 1.3.9.
-
-
-Изменения в nginx 1.3.16 16.04.2013
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовались подзапросы; ошибка появилась в 1.3.9.
-
- *) Исправление: директива tcp_nodelay вызывала ошибку при проксировании
- WebSocket-соединений в unix domain сокет.
-
- *) Исправление: переменная $upstream_response_length возвращала значение
- "0", если не использовалась буферизация.
- Спасибо Piotr Sikora.
-
- *) Исправление: в методах обработки соединений eventport и /dev/poll.
-
-
-Изменения в nginx 1.3.15 26.03.2013
-
- *) Изменение: открытие и закрытие соединения без отправки в нём
- каких-либо данных больше не записывается в access_log с кодом ошибки
- 400.
-
- *) Добавление: модуль ngx_http_spdy_module.
- Спасибо Automattic за спонсирование разработки.
-
- *) Добавление: директивы limit_req_status и limit_conn_status.
- Спасибо Nick Marden.
-
- *) Добавление: директива image_filter_interlace.
- Спасибо Ивану Боброву.
-
- *) Добавление: переменная $connections_waiting в модуле
- ngx_http_stub_status_module.
-
- *) Добавление: теперь почтовый прокси-сервер поддерживает IPv6-бэкенды.
-
- *) Исправление: при повторной отправке запроса на бэкенд тело запроса
- могло передаваться неправильно; ошибка появилась в 1.3.9.
- Спасибо Piotr Sikora.
-
- *) Исправление: в директиве client_body_in_file_only; ошибка появилась в
- 1.3.9.
-
- *) Исправление: ответы могли зависать, если использовались подзапросы и
- при обработке подзапроса происходила DNS-ошибка.
- Спасибо Lanshun Zhou.
-
- *) Исправление: в процедуре учёта использования бэкендов.
-
-
-Изменения в nginx 1.3.14 05.03.2013
-
- *) Добавление: переменные $connections_active, $connections_reading и
- $connections_writing в модуле ngx_http_stub_status_module.
-
- *) Добавление: поддержка WebSocket-соединений в модулях
- ngx_http_uwsgi_module и ngx_http_scgi_module.
-
- *) Исправление: в обработке виртуальных серверов при использовании SNI.
-
- *) Исправление: при использовании директивы "ssl_session_cache shared"
- новые сессии могли не сохраняться, если заканчивалось место в
- разделяемой памяти.
- Спасибо Piotr Sikora.
-
- *) Исправление: несколько заголовков X-Forwarded-For обрабатывались
- неправильно.
- Спасибо Neal Poole за спонсирование разработки.
-
- *) Исправление: в модуле ngx_http_mp4_module.
- Спасибо Gernot Vormayr.
-
-
-Изменения в nginx 1.3.13 19.02.2013
-
- *) Изменение: теперь для сборки по умолчанию используется компилятор с
- именем "cc".
-
- *) Добавление: поддержка проксирования WebSocket-соединений.
- Спасибо Apcera и CloudBees за спонсирование разработки.
-
- *) Добавление: директива auth_basic_user_file поддерживает шифрование
- паролей методом "{SHA}".
- Спасибо Louis Opter.
-
-
-Изменения в nginx 1.3.12 05.02.2013
-
- *) Добавление: директивы proxy_bind, fastcgi_bind, memcached_bind,
- scgi_bind и uwsgi_bind поддерживают переменные.
-
- *) Добавление: переменные $pipe, $request_length, $time_iso8601 и
- $time_local теперь можно использовать не только в директиве
- log_format.
- Спасибо Kiril Kalchev.
-
- *) Добавление: поддержка IPv6 в модуле ngx_http_geoip_module.
- Спасибо Gregor Kališnik.
-
- *) Исправление: директива proxy_method работала неверно, если была
- указана на уровне http.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовался resolver и метод poll.
-
- *) Исправление: nginx мог нагружать процессор во время SSL handshake с
- бэкендом при использовании методов обработки соединений select, poll
- и /dev/poll.
-
- *) Исправление: ошибка "[crit] SSL_write() failed (SSL:)".
-
- *) Исправление: в директиве client_body_in_file_only; ошибка появилась в
- 1.3.9.
-
- *) Исправление: в директиве fastcgi_keep_conn.
-
-
-Изменения в nginx 1.3.11 10.01.2013
-
- *) Исправление: при записи в лог мог происходить segmentation fault;
- ошибка появилась в 1.3.10.
-
- *) Исправление: директива proxy_pass не работала с IP-адресами без
- явного указания порта; ошибка появилась в 1.3.10.
-
- *) Исправление: на старте или во время переконфигурации происходил
- segmentation fault, если директива keepalive была указана несколько
- раз в одном блоке upstream.
-
- *) Исправление: параметр default директивы geo не определял значение по
- умолчанию для IPv6-адресов.
-
-
-Изменения в nginx 1.3.10 25.12.2012
-
- *) Изменение: для указанных в конфигурационном файле доменных имён
- теперь используются не только IPv4, но и IPv6 адреса.
-
- *) Изменение: теперь при использовании директивы include с маской на
- Unix-системах включаемые файлы сортируются в алфавитном порядке.
-
- *) Изменение: директива add_header добавляет строки в ответы с кодом
- 201.
-
- *) Добавление: директива geo теперь поддерживает IPv6 адреса в формате
- CIDR.
-
- *) Добавление: параметры flush и gzip в директиве access_log.
-
- *) Добавление: директива auth_basic поддерживает переменные.
-
- *) Исправление: nginx в некоторых случаях не собирался с модулем
- ngx_http_perl_module.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовался модуль ngx_http_xslt_module.
-
- *) Исправление: nginx мог не собираться на MacOSX.
- Спасибо Piotr Sikora.
-
- *) Исправление: при использовании директивы limit_rate с большими
- значениями скорости на 32-битных системах ответ мог возвращаться не
- целиком.
- Спасибо Алексею Антропову.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовалась директива if.
- Спасибо Piotr Sikora.
-
- *) Исправление: ответ "100 Continue" выдавался вместе с ответом "413
- Request Entity Too Large".
-
- *) Исправление: директивы image_filter, image_filter_jpeg_quality и
- image_filter_sharpen могли наследоваться некорректно.
- Спасибо Ивану Боброву.
-
- *) Исправление: при использовании директивы auth_basic под Linux могли
- возникать ошибки "crypt_r() failed".
-
- *) Исправление: в обработке backup-серверов.
- Спасибо Thomas Chen.
-
- *) Исправление: при проксировании HEAD-запросов мог возвращаться
- некорректный ответ, если использовалась директива gzip.
-
-
-Изменения в nginx 1.3.9 27.11.2012
-
- *) Добавление: поддержка chunked transfer encoding при получении тела
- запроса.
-
- *) Добавление: переменные $request_time и $msec теперь можно
- использовать не только в директиве log_format.
-
- *) Исправление: cache manager и cache loader могли не запускаться, если
- использовалось более 512 listen-сокетов.
-
- *) Исправление: в модуле ngx_http_dav_module.
-
-
-Изменения в nginx 1.3.8 30.10.2012
-
- *) Добавление: параметр optional_no_ca директивы ssl_verify_client.
- Спасибо Михаилу Казанцеву и Eric O'Connor.
-
- *) Добавление: переменные $bytes_sent, $connection и
- $connection_requests теперь можно использовать не только в директиве
- log_format.
- Спасибо Benjamin Grössing.
-
- *) Добавление: параметр auto директивы worker_processes.
-
- *) Исправление: сообщения "cache file ... has md5 collision".
-
- *) Исправление: в модуле ngx_http_gunzip_filter_module.
-
- *) Исправление: в директиве ssl_stapling.
-
-
-Изменения в nginx 1.3.7 02.10.2012
-
- *) Добавление: поддержка OCSP stapling.
- Спасибо Comodo, DigiCert и GlobalSign за спонсирование разработки.
-
- *) Добавление: директива ssl_trusted_certificate.
-
- *) Добавление: теперь resolver случайным образом меняет порядок
- возвращаемых закэшированных адресов.
- Спасибо Антону Жулину.
-
- *) Исправление: совместимость с OpenSSL 0.9.7.
-
-
-Изменения в nginx 1.3.6 12.09.2012
-
- *) Добавление: модуль ngx_http_gunzip_filter_module.
-
- *) Добавление: директива memcached_gzip_flag.
-
- *) Добавление: параметр always директивы gzip_static.
-
- *) Исправление: в директиве "limit_req"; ошибка появилась в 1.1.14.
- Спасибо Charles Chen.
-
- *) Исправление: nginx не собирался gcc 4.7 с оптимизацией -O2 если
- использовался параметр --with-ipv6.
-
-
-Изменения в nginx 1.3.5 21.08.2012
-
- *) Изменение: модуль ngx_http_mp4_module больше не отфильтровывает
- дорожки в форматах, отличных от H.264 и AAC.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если в директиве map в качестве значений использовались переменные.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault при
- использовании директивы geo с параметром ranges, но без параметра
- default; ошибка появилась в 0.8.43.
- Спасибо Zhen Chen и Weibin Yao.
-
- *) Исправление: в обработке параметра командной строки -p.
-
- *) Исправление: в почтовом прокси-сервере.
-
- *) Исправление: незначительных потенциальных ошибок.
- Спасибо Coverity.
-
- *) Исправление: nginx/Windows не собирался с Visual Studio 2005 Express.
- Спасибо HAYASHI Kentaro.
-
-
-Изменения в nginx 1.3.4 31.07.2012
-
- *) Изменение: теперь на слушающих IPv6-сокетах параметр ipv6only включён
- по умолчанию.
-
- *) Добавление: поддержка компилятора Clang.
-
- *) Исправление: могли создаваться лишние слушающие сокеты.
- Спасибо Роману Одайскому.
-
- *) Исправление: nginx/Windows мог нагружать процессор, если при запуске
- рабочего процесса происходила ошибка.
- Спасибо Ricardo Villalobos Guevara.
-
- *) Исправление: директивы proxy_pass_header, fastcgi_pass_header,
- scgi_pass_header, uwsgi_pass_header, proxy_hide_header,
- fastcgi_hide_header, scgi_hide_header и uwsgi_hide_header могли
- наследоваться некорректно.
-
-
-Изменения в nginx 1.3.3 10.07.2012
-
- *) Добавление: поддержка entity tags и директива etag.
-
- *) Исправление: при использовании директивы map с параметром hostnames
- не игнорировалась конечная точка в исходном значении.
-
- *) Исправление: для обработки запроса мог использоваться неверный
- location, если переход в именованный location происходил после
- изменения URI с помощью директивы rewrite.
-
-
-Изменения в nginx 1.3.2 26.06.2012
-
- *) Изменение: параметр single директивы keepalive теперь игнорируется.
-
- *) Изменение: сжатие SSL теперь отключено в том числе при использовании
- OpenSSL старее 1.0.0.
-
- *) Добавление: директиву "ip_hash" теперь можно использовать для
- балансировки IPv6 клиентов.
-
- *) Добавление: переменную $status теперь можно использовать не только в
- директиве log_format.
-
- *) Исправление: при завершении рабочего процесса мог произойти
- segmentation fault, если использовалась директива resolver.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовался модуль ngx_http_mp4_module.
-
- *) Исправление: в модуле ngx_http_mp4_module.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовались конфликтующие имена серверов с масками.
-
- *) Исправление: на платформе ARM nginx мог аварийно завершаться по
- сигналу SIGBUS.
-
- *) Исправление: во время переконфигурации на HP-UX в лог записывался
- alert "sendmsg() failed (9: Bad file number)".
-
-
-Изменения в nginx 1.3.1 05.06.2012
-
- *) Безопасность: теперь nginx/Windows игнорирует точку в конце
- компонента URI и не разрешает URI, содержащие последовательность
- ":$".
- Спасибо Владимиру Кочеткову, Positive Research Center.
-
- *) Добавление: директивы proxy_pass, fastcgi_pass, scgi_pass, uwsgi_pass
- и директива server в блоке upstream теперь поддерживают IPv6-адреса.
-
- *) Добавление: в директиве resolver теперь можно указывать порт и
- задавать IPv6-адреса DNS-серверов.
-
- *) Добавление: директива least_conn в блоке upstream.
-
- *) Добавление: при использовании директивы ip_hash теперь можно задавать
- веса серверов.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовалась директива image_filter; ошибка появилась в 1.3.0.
-
- *) Исправление: nginx не собирался с модулем ngx_cpp_test_module; ошибка
- появилась в 1.1.12.
-
- *) Исправление: доступ к переменным из SSI и встроенного перла мог не
- работать после переконфигурации.
- Спасибо Yichun Zhang.
-
- *) Исправление: в модуле ngx_http_xslt_filter_module.
- Спасибо Kuramoto Eiji.
-
- *) Исправление: утечки памяти при использовании переменной $geoip_org.
- Спасибо Денису Латыпову.
-
- *) Исправление: в директивах proxy_cookie_domain и proxy_cookie_path.
-
-
-Изменения в nginx 1.3.0 15.05.2012
-
- *) Добавление: директива debug_connection теперь поддерживает
- IPv6-адреса и параметр "unix:".
-
- *) Добавление: директива set_real_ip_from и параметр proxy директивы geo
- теперь поддерживают IPv6-адреса.
-
- *) Добавление: директивы real_ip_recursive, geoip_proxy и
- geoip_proxy_recursive.
-
- *) Добавление: параметр proxy_recursive директивы geo.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовалась директива resolver.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовались директивы fastcgi_pass, scgi_pass или uwsgi_pass
- и бэкенд возвращал некорректный ответ.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовалась директива rewrite и в новых аргументах запроса в
- строке замены использовались переменные.
-
- *) Исправление: nginx мог нагружать процессор, если было достигнуто
- ограничение на количество открытых файлов.
-
- *) Исправление: при использовании директивы proxy_next_upstream с
- параметром http_404 nginx мог бесконечно перебирать бэкенды, если в
- блоке upstream был хотя бы один сервер с флагом backup.
-
- *) Исправление: при использовании директивы ip_hash установка параметра
- down директивы server могла приводить к ненужному перераспределению
- клиентов между бэкендами.
-
- *) Исправление: утечки сокетов.
- Спасибо Yichun Zhang.
-
- *) Исправление: в модуле ngx_http_fastcgi_module.
-
-
-Изменения в nginx 1.2.0 23.04.2012
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовалась директива try_files; ошибка появилась в 1.1.19.
-
- *) Исправление: ответ мог быть передан не полностью, если использовалось
- больше IOV_MAX буферов.
-
- *) Исправление: в работе параметра crop директивы image_filter.
- Спасибо Maxim Bublis.
-
-
-Изменения в nginx 1.1.19 12.04.2012
-
- *) Безопасность: при обработке специально созданного mp4 файла модулем
- ngx_http_mp4_module могли перезаписываться области памяти рабочего
- процесса, что могло приводить к выполнению произвольного кода
- (CVE-2012-2089).
- Спасибо Matthew Daley.
-
- *) Исправление: nginx/Windows мог завершаться аварийно.
- Спасибо Vincent Lee.
-
- *) Исправление: nginx нагружал процессор, если все серверы в upstream'е
- были помечены флагом backup.
-
- *) Исправление: директивы allow и deny могли наследоваться некорректно,
- если в них использовались IPv6 адреса.
-
- *) Исправление: директивы modern_browser и ancient_browser могли
- наследоваться некорректно.
-
- *) Исправление: таймауты могли работать некорректно на Solaris/SPARC.
-
- *) Исправление: в модуле ngx_http_mp4_module.
-
-
-Изменения в nginx 1.1.18 28.03.2012
-
- *) Изменение: теперь keepalive соединения не запрещены для Safari по
- умолчанию.
-
- *) Добавление: переменная $connection_requests.
-
- *) Добавление: переменные $tcpinfo_rtt, $tcpinfo_rttvar,
- $tcpinfo_snd_cwnd и $tcpinfo_rcv_space.
-
- *) Добавление: директива worker_cpu_affinity теперь работает на FreeBSD.
-
- *) Добавление: директивы xslt_param и xslt_string_param.
- Спасибо Samuel Behan.
-
- *) Исправление: в configure.
- Спасибо Piotr Sikora.
-
- *) Исправление: в модуле ngx_http_xslt_filter_module.
-
- *) Исправление: nginx не собирался на Debian GNU/Hurd.
-
-
-Изменения в nginx 1.1.17 15.03.2012
-
- *) Безопасность: содержимое ранее освобождённой памяти могло быть
- отправлено клиенту, если бэкенд возвращал специально созданный ответ.
- Спасибо Matthew Daley.
-
- *) Исправление: при использовании встроенного перла из SSI.
- Спасибо Matthew Daley.
-
- *) Исправление: в модуле ngx_http_uwsgi_module.
-
-
-Изменения в nginx 1.1.16 29.02.2012
-
- *) Изменение: ограничение на количество одновременных подзапросов
- поднято до 200.
-
- *) Добавление: параметр from в директиве disable_symlinks.
-
- *) Добавление: директивы return и error_page теперь могут использоваться
- для возврата перенаправлений с кодом 307.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовалась директива resolver и на глобальном уровне не была
- задана директива error_log.
- Спасибо Роману Арутюняну.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовались директивы "proxy_http_version 1.1" или
- "fastcgi_keep_conn on".
-
- *) Исправление: утечек памяти.
- Спасибо Lanshun Zhou.
-
- *) Исправление: в директиве disable_symlinks.
-
- *) Исправление: при использовании ZFS размер кэша на диске мог считаться
- некорректно; ошибка появилась в 1.0.1.
-
- *) Исправление: nginx не собирался компилятором icc 12.1.
-
- *) Исправление: nginx не собирался gcc на Solaris; ошибка появилась в
- 1.1.15.
-
-
-Изменения в nginx 1.1.15 15.02.2012
-
- *) Добавление: директива disable_symlinks.
-
- *) Добавление: директивы proxy_cookie_domain и proxy_cookie_path.
-
- *) Исправление: nginx мог некорректно сообщать об ошибке "upstream
- prematurely closed connection" вместо "upstream sent too big header".
- Спасибо Feibo Li.
-
- *) Исправление: nginx не собирался с модулем ngx_http_perl_module, если
- использовался параметр --with-openssl.
-
- *) Исправление: количество внутренних перенаправлений в именованные
- location'ы не ограничивалось.
-
- *) Исправление: вызов $r->flush() несколько раз подряд мог приводить к
- ошибкам в модуле ngx_http_gzip_filter_module.
-
- *) Исправление: при использовании директивы proxy_store с
- SSI-подзапросами временные файлы могли не удаляться.
-
- *) Исправление: в некоторых случаях некэшируемые переменные (такие, как
- $args) возвращали старое пустое закэшированное значение.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если одновременно создавалось слишком много SSI-подзапросов; ошибка
- появилась в 0.7.25.
-
-
-Изменения в nginx 1.1.14 30.01.2012
-
- *) Добавление: теперь можно указать несколько ограничений limit_req
- одновременно.
-
- *) Исправление: в обработке ошибок при соединении с бэкендом.
- Спасибо Piotr Sikora.
-
- *) Исправление: в обработке ошибок при использовании AIO на FreeBSD.
-
- *) Исправление: в инициализации библиотеки OpenSSL.
-
- *) Исправление: директивы proxy_redirect могли наследоваться
- некорректно.
-
- *) Исправление: утечки памяти при переконфигурации, если использовалась
- директива pcre_jit.
-
-
-Изменения в nginx 1.1.13 16.01.2012
-
- *) Добавление: параметры TLSv1.1 и TLSv1.2 в директиве ssl_protocols.
-
- *) Исправление: параметры директивы limit_req наследовались некорректно;
- ошибка появилась в 1.1.12.
-
- *) Исправление: директива proxy_redirect некорректно обрабатывала
- заголовок Refresh при использовании регулярных выражений.
-
- *) Исправление: директива proxy_cache_use_stale с параметром error не
- возвращала ответ из кэша, если все бэкенды были признаны
- неработающими.
-
- *) Исправление: директива worker_cpu_affinity могла не работать.
-
- *) Исправление: nginx не собирался на Solaris; ошибка появилась в
- 1.1.12.
-
- *) Исправление: в модуле ngx_http_mp4_module.
-
-
-Изменения в nginx 1.1.12 26.12.2011
-
- *) Изменение: после перенаправления запроса с помощью директивы
- error_page директива proxy_pass без URI теперь использует изменённый
- URI.
- Спасибо Lanshun Zhou.
-
- *) Добавление: директивы proxy/fastcgi/scgi/uwsgi_cache_lock,
- proxy/fastcgi/scgi/uwsgi_cache_lock_timeout.
-
- *) Добавление: директива pcre_jit.
-
- *) Добавление: SSI команда if поддерживает выделения в регулярных
- выражениях.
-
- *) Исправление: SSI команда if не работала внутри команды block.
-
- *) Исправление: директивы limit_conn_log_level и limit_req_log_level
- могли не работать.
-
- *) Исправление: директива limit_rate не позволяла передавать на полной
- скорости, даже если был указан очень большой лимит.
-
- *) Исправление: директива sendfile_max_chunk не работала, если
- использовалась директива limit_rate.
-
- *) Исправление: если в директиве proxy_pass использовались переменные и
- не был указан URI, всегда использовался URI исходного запроса.
-
- *) Исправление: после перенаправления запроса с помощью директивы
- try_files директива proxy_pass без URI могла использовать URI
- исходного запроса.
- Спасибо Lanshun Zhou.
-
- *) Исправление: в модуле ngx_http_scgi_module.
-
- *) Исправление: в модуле ngx_http_mp4_module.
-
- *) Исправление: nginx не собирался на Solaris; ошибка появилась в 1.1.9.
-
-
-Изменения в nginx 1.1.11 12.12.2011
-
- *) Добавление: параметр so_keepalive в директиве listen.
- Спасибо Всеволоду Стахову.
-
- *) Добавление: параметр if_not_empty в директивах
- fastcgi/scgi/uwsgi_param.
-
- *) Добавление: переменная $https.
-
- *) Добавление: директива proxy_redirect поддерживает переменные в первом
- параметре.
-
- *) Добавление: директива proxy_redirect поддерживает регулярные
- выражения.
-
- *) Исправление: переменная $sent_http_cache_control могла содержать
- неверное значение при использовании директивы expires.
- Спасибо Yichun Zhang.
-
- *) Исправление: директива read_ahead могла не работать при использовании
- совместно с try_files и open_file_cache.
-
- *) Исправление: если в параметре inactive директивы proxy_cache_path
- было указано малое время, в рабочем процессе мог произойти
- segmentation fault.
-
- *) Исправление: ответы из кэша могли зависать.
-
-
-Изменения в nginx 1.1.10 30.11.2011
-
- *) Исправление: при использовании AIO на Linux в рабочем процессе
- происходил segmentation fault; ошибка появилась в 1.1.9.
-
-
-Изменения в nginx 1.1.9 28.11.2011
-
- *) Изменение: теперь двойные кавычки экранируется при выводе
- SSI-командой echo.
- Спасибо Зауру Абасмирзоеву.
-
- *) Добавление: параметр valid в директиве resolver. По умолчанию теперь
- используется TTL, возвращённый DNS-сервером.
- Спасибо Кириллу Коринскому.
-
- *) Исправление: nginx мог перестать отвечать, если рабочий процесс
- завершался аварийно.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовалось SNI; ошибка появилась в 1.1.2.
-
- *) Исправление: в директиве keepalive_disable; ошибка появилась в 1.1.8.
- Спасибо Александру Усову.
-
- *) Исправление: сигнал SIGWINCH переставал работать после первого
- обновления исполняемого файла; ошибка появилась в 1.1.1.
-
- *) Исправление: теперь ответы бэкендов, длина которых не соответствует
- заголовку Content-Length, не кэширутся.
-
- *) Исправление: в директиве scgi_param при использовании составных
- параметров.
-
- *) Исправление: в методе epoll.
- Спасибо Yichun Zhang.
-
- *) Исправление: в модуле ngx_http_flv_module.
- Спасибо Piotr Sikora.
-
- *) Исправление: в модуле ngx_http_mp4_module.
-
- *) Исправление: теперь nginx понимает IPv6-адреса в строке запроса и в
- заголовке Host.
-
- *) Исправление: директивы add_header и expires не работали для ответов с
- кодом 206, если запрос проксировался.
-
- *) Исправление: nginx не собирался на FreeBSD 10.
-
- *) Исправление: nginx не собирался на AIX.
-
-
-Изменения в nginx 1.1.8 14.11.2011
-
- *) Изменение: модуль ngx_http_limit_zone_module переименован в
- ngx_http_limit_conn_module.
-
- *) Изменение: директива limit_zone заменена директивой limit_conn_zone с
- новым синтаксисом.
-
- *) Добавление: поддержка ограничения по нескольким limit_conn на одном
- уровне.
-
- *) Добавление: директива image_filter_sharpen.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если resolver получил большой DNS-ответ.
- Спасибо Ben Hawkes.
-
- *) Исправление: в вычислении ключа для кэширования, если использовалась
- внутренняя реализация MD5; ошибка появилась в 1.0.4.
-
- *) Исправление: строки "If-Modified-Since", "If-Range" и им подобные в
- заголовке запроса клиента могли передаваться бэкенду при кэшировании;
- или не передаваться при выключенном кэшировании, если кэширование
- было включено в другой части конфигурации.
-
- *) Исправление: модуль ngx_http_mp4_module выдавал неверную строку
- "Content-Length" в заголовке ответа, использовался аргумент start.
- Спасибо Piotr Sikora.
-
-
-Изменения в nginx 1.1.7 31.10.2011
-
- *) Добавление: поддержка нескольких DNS серверов в директиве "resolver".
- Спасибо Кириллу Коринскому.
-
- *) Исправление: на старте или во время переконфигурации происходил
- segmentation fault, если директива ssl использовалась на уровне http
- и не был указан ssl_certificate.
-
- *) Исправление: уменьшено потребление памяти при проксировании больших
- файлов, если они буферизировались на диск.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовалась директива "proxy_http_version 1.1".
-
- *) Исправление: в директиве "expires @time".
-
-
-Изменения в nginx 1.1.6 17.10.2011
-
- *) Изменение во внутреннем API: теперь при внутреннем редиректе в
- именованный location контексты модулей очищаются.
- По запросу Yichun Zhang.
-
- *) Изменение: теперь если сервер, описанный в блоке upstream, был
- признан неработающим, то после истечения fail_timeout на него будет
- отправлен только один запрос; сервер будет считаться работающим, если
- успешно ответит на этот запрос.
-
- *) Изменение: теперь символы 0x7F-0xFF в access_log записываются в виде
- \xXX.
-
- *) Добавление: директивы "proxy/fastcgi/scgi/uwsgi_ignore_headers"
- теперь поддерживают значения X-Accel-Limit-Rate, X-Accel-Buffering и
- X-Accel-Charset.
-
- *) Добавление: уменьшение потребления памяти при использовании SSL.
-
- *) Исправление: некоторые UTF-8 символы обрабатывались неправильно.
- Спасибо Алексею Куцу.
-
- *) Исправление: директивы модуля ngx_http_rewrite_module, заданные на
- уровне server, применялись повторно, если для запроса не находилось
- ни одного location'а.
-
- *) Исправление: при использовании "aio sendfile" могла происходить
- утечка сокетов.
-
- *) Исправление: при использовании файлового AIO соединения с быстрыми
- клиентами могли быть закрыты по истечению send_timeout.
-
- *) Исправление: в модуле ngx_http_autoindex_module.
-
- *) Исправление: модуль ngx_http_mp4_module не поддерживал перемотку на
- 32-битных платформах.
-
-
-Изменения в nginx 1.1.5 05.10.2011
-
- *) Добавление: директивы uwsgi_buffering и scgi_buffering.
- Спасибо Peter Smit.
-
- *) Исправление: при использовании proxy_cache_bypass могли быть
- закэшированы некэшируемые ответы.
- Спасибо John Ferlito.
-
- *) Исправление: в модуле ngx_http_proxy_module при работе с бэкендами по
- HTTP/1.1.
-
- *) Исправление: закэшированные ответы с пустым телом возвращались
- некорректно; ошибка появилась в 0.8.31.
-
- *) Исправление: ответы с кодом 201 модуля ngx_http_dav_module были
- некорректны; ошибка появилась в 0.8.32.
-
- *) Исправление: в директиве return.
-
- *) Исправление: при использовании директивы "ssl_session_cache builtin"
- происходил segmentation fault; ошибка появилась в 1.1.1.
-
-
-Изменения в nginx 1.1.4 20.09.2011
-
- *) Добавление: модуль ngx_http_upstream_keepalive.
-
- *) Добавление: директива proxy_http_version.
-
- *) Добавление: директива fastcgi_keep_conn.
-
- *) Добавление: директива worker_aio_requests.
-
- *) Исправление: если nginx был собран с файловым AIO, он не мог
- запускаться на Linux без поддержки AIO.
-
- *) Исправление: в обработке ошибок при работе с Linux AIO.
- Спасибо Hagai Avrahami.
-
- *) Исправление: уменьшено потребление памяти для долгоживущих запросов.
-
- *) Исправление: модуль ngx_http_mp4_module не поддерживал 64-битный
- MP4-атом co64.
-
-
-Изменения в nginx 1.1.3 14.09.2011
-
- *) Добавление: модуль ngx_http_mp4_module.
-
- *) Исправление: в Linux AIO, используемым совместно с open_file_cache.
-
- *) Исправление: open_file_cache не обновлял информацию о файле, если
- файл был изменён не атомарно.
-
- *) Исправление: nginx не собирался на MacOSX 10.7.
-
-
-Изменения в nginx 1.1.2 05.09.2011
-
- *) Изменение: теперь, если суммарный размер всех диапазонов больше
- размера исходного ответа, то nginx возвращает только исходный ответ,
- не обрабатывая диапазоны.
-
- *) Добавление: директива max_ranges.
-
- *) Исправление: директивы ssl_verify_client, ssl_verify_depth и
- ssl_prefer_server_cipher могли работать некорректно, если
- использовался SNI.
-
- *) Исправление: в директивах proxy/fastcgi/scgi/
- uwsgi_ignore_client_abort.
-
-
-Изменения в nginx 1.1.1 22.08.2011
-
- *) Изменение: теперь загрузчик кэша за каждую итерацию либо обрабатывает
- число файлов, указанное в параметре load_files, либо работает не
- дольше времени, указанного в параметре loader_threshold.
-
- *) Изменение: SIGWINCH сигнал теперь работает только в режиме демона.
-
- *) Добавление: теперь разделяемые зоны и кэши используют семафоры POSIX
- на Solaris.
- Спасибо Денису Иванову.
-
- *) Добавление: теперь на NetBSD поддерживаются accept фильтры.
-
- *) Исправление: nginx не собирался на Linux 3.0.
-
- *) Исправление: в некоторых случаях nginx не использовал сжатие; ошибка
- появилась в 1.1.0.
-
- *) Исправление: обработка тела запроса могла быть неверной, если клиент
- использовал pipelining.
-
- *) Исправление: в директиве request_body_in_single_buf.
-
- *) Исправление: в директивах proxy_set_body и proxy_pass_request_body
- при использовании SSL-соединения с бэкендом.
-
- *) Исправление: nginx нагружал процессор, если все серверы в upstream'е
- были помечены флагом down.
-
- *) Исправление: при переконфигурации мог произойти segmentation fault,
- если в предыдущей конфигурации был определён, но не использовался
- ssl_session_cache.
-
- *) Исправление: при использовании большого количества backup-серверов в
- рабочем процессе мог произойти segmentation fault.
-
- *) Исправление: при использовании директив fastcgi/scgi/uwsgi_param со
- значениями, начинающимися со строки "HTTP_", в рабочем процессе мог
- произойти segmentation fault; ошибка появилась в 0.8.40.
-
-
-Изменения в nginx 1.1.0 01.08.2011
-
- *) Добавление: уменьшение времени работы загрузчика кэша.
-
- *) Добавление: параметры loader_files, loader_sleep и loader_threshold
- директив proxy/fastcgi/scgi/uwsgi_cache_path.
-
- *) Добавление: уменьшение времени загрузки конфигураций с большим
- количеством HTTPS серверов.
-
- *) Добавление: теперь nginx поддерживает шифры с обменом ECDHE-ключами.
- Спасибо Adrian Kotelba.
-
- *) Добавление: директива lingering_close.
- Спасибо Максиму Дунину.
-
- *) Исправление: закрытия соединения для pipelined-запросов.
- Спасибо Максиму Дунину.
-
- *) Исправление: nginx не запрещал сжатие при получении значения
- "gzip;q=0" в строке "Accept-Encoding" в заголовке запроса клиента.
-
- *) Исправление: таймаута при небуферизированном проксировании.
- Спасибо Максиму Дунину.
-
- *) Исправление: утечки памяти при использовании переменных в директиве
- proxy_pass при работе с бэкендом по HTTPS.
- Спасибо Максиму Дунину.
-
- *) Исправление: в проверке параметра директивы proxy_pass, заданного
- переменными.
- Спасибо Lanshun Zhou.
-
- *) Исправление: SSL не работал на QNX.
- Спасибо Максиму Дунину.
-
- *) Исправление: SSL модули не собирались gcc 4.6 без параметра
- --with-debug.
-
-
-Изменения в nginx 1.0.5 19.07.2011
-
- *) Изменение: теперь по умолчанию используются следующие шифры SSL:
- "HIGH:!aNULL:!MD5".
- Спасибо Rob Stradling.
-
- *) Добавление: директивы referer_hash_max_size и
- referer_hash_bucket_size.
- Спасибо Witold Filipczyk.
-
- *) Добавление: переменная $uid_reset.
-
- *) Исправление: при использовании кэширования в рабочем процессе мог
- произойти segmentation fault.
- Спасибо Lanshun Zhou.
-
- *) Исправление: при использовании кэширования рабочие процессы могли
- зациклиться во время переконфигурации; ошибка появилась в 0.8.48.
- Спасибо Максиму Дунину.
-
- *) Исправление: сообщения "stalled cache updating".
- Спасибо Максиму Дунину.
-
-
-Изменения в nginx 1.0.4 01.06.2011
-
- *) Изменение: теперь в регулярных выражениях в директиве map можно
- задать чувствительность к регистру с помощью префиксов "~" и "~*".
-
- *) Добавление: теперь разделяемые зоны и кэши используют семафоры POSIX
- на Linux.
- Спасибо Денису Латыпову.
-
- *) Исправление: сообщения "stalled cache updating".
-
- *) Исправление: nginx не собирался с параметром
- --without-http_auth_basic_module; ошибка появилась в 1.0.3.
-
-
-Изменения в nginx 1.0.3 25.05.2011
-
- *) Добавление: директива auth_basic_user_file поддерживает шифрование
- пароля методами "$apr1", "{PLAIN}" и "{SSHA}".
- Спасибо Максиму Дунину.
-
- *) Добавление: директива geoip_org и переменная $geoip_org.
- Спасибо Александру Ускову, Arnaud Granal и Денису Латыпову.
-
- *) Добавление: модули ngx_http_geo_module и ngx_http_geoip_module
- поддерживают адреса IPv4, отображённые на IPv6 адреса.
-
- *) Исправление: при проверке адреса IPv4, отображённого на адрес IPv6, в
- рабочем процессе происходил segmentation fault, если директивы access
- или deny были определены только для адресов IPv6; ошибка появилась в
- 0.8.22.
-
- *) Исправление: закэшированный ответ мог быть испорчен, если значения
- директив proxy/fastcgi/scgi/uwsgi_cache_bypass и proxy/fastcgi/scgi/
- uwsgi_no_cache были разными; ошибка появилась в 0.8.46.
-
-
-Изменения в nginx 1.0.2 10.05.2011
-
- *) Добавление: теперь разделяемые зоны и кэши используют семафоры POSIX.
-
- *) Исправление: в работе параметра rotate директивы image_filter.
- Спасибо Adam Bocim.
-
- *) Исправление: nginx не собирался на Solaris; ошибка появилась в 1.0.1.
-
-
-Изменения в nginx 1.0.1 03.05.2011
-
- *) Изменение: теперь директива split_clients использует алгоритм
- MurmurHash2 из-за лучшего распределения.
- Спасибо Олегу Мамонтову.
-
- *) Изменение: теперь длинные строки, начинающиеся с нуля, не считаются
- ложными значениями.
- Спасибо Максиму Дунину.
-
- *) Изменение: теперь по умолчанию nginx использует значение 511 для
- listen backlog на Linux.
-
- *) Добавление: переменные $upstream_... можно использовать в SSI и
- перловом модулях.
-
- *) Исправление: теперь nginx лучше ограничивает размер кэша на диске.
- Спасибо Олегу Мамонтову.
-
- *) Исправление: при парсинге неправильного IPv4 адреса мог произойти
- segmentation fault; ошибка появилась в 0.8.22.
- Спасибо Максиму Дунину.
-
- *) Исправление: nginx не собирался gcc 4.6 без параметра --with-debug.
-
- *) Исправление: nginx не собирался на Solaris 9 и более ранних; ошибка
- появилась в 0.9.3.
- Спасибо Dagobert Michelsen.
-
- *) Исправление: переменная $request_time имела неверные значения, если
- использовались подзапросы; ошибка появилась в 0.8.47.
- Спасибо Игорю А. Валькову.
-
-
-Изменения в nginx 1.0.0 12.04.2011
-
- *) Исправление: cache manager мог нагружать процессор после
- переконфигурации.
- Спасибо Максиму Дунину.
-
- *) Исправление: директива "image_filter crop" неправильно работала в
- сочетании с "image_filter rotate 180".
-
- *) Исправление: директива "satisfy any" запрещала выдачу
- пользовательской страницы для 401 кода.
-
-
-Изменения в nginx 0.9.7 04.04.2011
-
- *) Добавление: теперь соединения в состоянии keepalive могут быть
- закрыты преждевременно, если у воркера нет свободных соединений.
- Спасибо Максиму Дунину.
-
- *) Добавление: параметр rotate директивы image_filter.
- Спасибо Adam Bocim.
-
- *) Исправление: ситуации, когда бэкенд в директивах fastcgi_pass,
- scgi_pass или uwsgi_pass задан выражением и ссылается на описанный
- upstream.
-
-
-Изменения в nginx 0.9.6 21.03.2011
-
- *) Добавление: директива map поддерживает регулярные выражения в
- качестве значения первого параметра.
-
- *) Добавление: переменная $time_iso8601 для access_log.
- Спасибо Michael Lustfield.
-
-
-Изменения в nginx 0.9.5 21.02.2011
-
- *) Изменение: теперь по умолчанию nginx использует значение -1 для
- listen backlog на Linux.
- Спасибо Андрею Нигматулину.
-
- *) Добавление: параметр utf8 в директивах geoip_country и geoip_city.
- Спасибо Денису Латыпову.
-
- *) Исправление: исправление в умолчательной директиве proxy_redirect,
- если в директиве proxy_pass не был описан URI.
- Спасибо Максиму Дунину.
-
- *) Исправление: директива error_page не работала с нестандартными кодами
- ошибок; ошибка появилась в 0.8.53.
- Спасибо Максиму Дунину.
-
-
-Изменения в nginx 0.9.4 21.01.2011
-
- *) Добавление: директива server_name поддерживает переменную $hostname.
-
- *) Добавление: 494 код для ошибки "Request Header Too Large".
-
-
-Изменения в nginx 0.9.3 13.12.2010
-
- *) Исправление: если для пары IPv6-адрес:порт описан только один сервер,
- то выделения в регулярных выражениях в директиве server_name не
- работали.
-
- *) Исправление: nginx не собирался под Solaris; ошибка появилась в
- 0.9.0.
-
-
-Изменения в nginx 0.9.2 06.12.2010
-
- *) Добавление: поддержка строки "If-Unmodified-Since" в заголовке
- запросе клиента.
-
- *) Изменение: использование accept(), если accept4() не реализован;
- ошибка появилась в 0.9.0.
-
- *) Исправление: nginx не собирался под Cygwin; ошибка появилась в 0.9.0.
-
- *) Исправление: уязвимости в OpenSSL CVE-2010-4180.
- Спасибо Максиму Дунину.
-
-
-Изменения в nginx 0.9.1 30.11.2010
-
- *) Исправление: директивы вида "return CODE message" не работали; ошибка
- появилась в 0.9.0.
-
-
-Изменения в nginx 0.9.0 29.11.2010
-
- *) Добавление: директива keepalive_disable.
-
- *) Добавление: директива map поддерживает переменные в качестве значения
- определяемой переменной.
-
- *) Добавление: директива map поддерживает пустые строки в качестве
- значения первого параметра.
-
- *) Добавление: директива map поддерживает выражения в первом параметре.
-
- *) Добавление: страница руководства nginx(8).
- Спасибо Сергею Осокину.
-
- *) Добавление: поддержка accept4() в Linux.
- Спасибо Simon Liu.
-
- *) Изменение: устранение предупреждения линкера о "sys_errlist" и
- "sys_nerr" под Linux; предупреждение появилось в 0.8.35.
-
- *) Исправление: при использовании директивы auth_basic в рабочем
- процессе мог произойти segmentation fault.
- Спасибо Михаилу Лалетину.
-
- *) Исправление: совместимость с модулем ngx_http_eval_module; ошибка
- появилась в 0.8.42.
-
-
-Изменения в nginx 0.8.53 18.10.2010
-
- *) Добавление: теперь директива error_page позволяет менять код статуса
- у редиректа.
-
- *) Добавление: директива gzip_disable поддерживает специальную маску
- degradation.
-
- *) Исправление: при использовании файлового AIO могла происходить утечка
- сокетов.
- Спасибо Максиму Дунину.
-
- *) Исправление: если в первом сервере не была описана директива listen и
- нигде явно не описан сервер по умолчанию, то сервером по умолчанию
- становился следующий сервер с директивой listen; ошибка появилась в
- 0.8.21.
-
-
-Изменения в nginx 0.8.52 28.09.2010
-
- *) Исправление: nginx использовал режим SSL для listen сокета, если для
- него был установлен любой listen-параметр; ошибка появилась в 0.8.51.
-
-
-Изменения в nginx 0.8.51 27.09.2010
-
- *) Изменение: директива secure_link_expires упразднена.
-
- *) Изменение: уровень логгирования ошибок resolver'а понижен с уровня
- alert на error.
-
- *) Добавление: теперь параметр "ssl" listen-сокета можно устанавливать
- несколько раз.
-
-
-Изменения в nginx 0.8.50 02.09.2010
-
- *) Добавление: директивы secure_link, secure_link_md5 и
- secure_link_expires модуля ngx_http_secure_link_module.
-
- *) Добавление: ключ -q.
- Спасибо Геннадию Махомеду.
-
- *) Исправление: при использовании кэширования рабочие процессы и могли
- зациклиться во время переконфигурации; ошибка появилась в 0.8.48.
-
- *) Исправление: в директиве gzip_disable.
- Спасибо Derrick Petzold.
-
- *) Исправление: nginx/Windows не мог посылать сигналы stop, quit,
- reopen, reload процессу, запущенному в другой сессии.
-
-
-Изменения в nginx 0.8.49 09.08.2010
-
- *) Добавление: директива image_filter_jpeg_quality поддерживает
- переменные.
-
- *) Исправление: при использовании переменной $geoip_region_name в
- рабочем процессе мог произойти segmentation fault; ошибка появилась в
- 0.8.48.
-
- *) Исправление: ошибки, перехваченные error_page, кэшировались только до
- следующего запроса; ошибка появилась в 0.8.48.
-
-
-Изменения в nginx 0.8.48 03.08.2010
-
- *) Изменение: теперь по умолчанию директива server_name имеет значение
- пустое имя "".
- Спасибо Геннадию Махомеду.
-
- *) Изменение: теперь по умолчанию директива server_name_in_redirect
- имеет значение off.
-
- *) Добавление: переменные $geoip_dma_code, $geoip_area_code и
- $geoip_region_name.
- Спасибо Christine McGonagle.
-
- *) Исправление: директивы proxy_pass, fastcgi_pass, uwsgi_pass и
- scgi_pass не наследовались в блоки limit_except.
-
- *) Исправление: директивы proxy_cache_min_uses, fastcgi_cache_min_uses
- uwsgi_cache_min_uses и scgi_cache_min_uses не работали; ошибка
- появилась в 0.8.46.
-
- *) Исправление: директива fastcgi_split_path_info неверно использовала
- выделения, если в выделения попадала только часть URI.
- Спасибо Юрию Тарадаю и Frank Enderle.
-
- *) Исправление: директива rewrite не экранировала символ ";" при
- копировании из URI в аргументы.
- Спасибо Daisuke Murase.
-
- *) Исправление: модуль ngx_http_image_filter_module закрывал соединение,
- если изображение было больше размера image_filter_buffer.
-
-
-Изменения в nginx 0.8.47 28.07.2010
-
- *) Исправление: переменная $request_time имела неверные значения для
- подзапросов.
-
- *) Исправление: ошибки, перехваченные error_page, не кэшировались.
-
- *) Исправление: если использовался параметр max_size, то cache manager
- мог зациклиться; ошибка появилась в 0.8.46.
-
-
-Изменения в nginx 0.8.46 19.07.2010
-
- *) Изменение: директивы proxy_no_cache, fastcgi_no_cache, uwsgi_no_cache
- и scgi_no_cache теперь влияют только на сохранение закэшированного
- ответа.
-
- *) Добавление: директивы proxy_cache_bypass, fastcgi_cache_bypass,
- uwsgi_cache_bypass и scgi_cache_bypass.
-
- *) Исправление: nginx не освобождал память в keys_zone кэшей в случае
- ошибки работы с бэкендом: память освобождалась только по истечении
- времени неактивности или при недостатке памяти.
-
-
-Изменения в nginx 0.8.45 13.07.2010
-
- *) Добавление: улучшения в модуле ngx_http_xslt_filter.
- Спасибо Laurence Rowe.
-
- *) Исправление: ответ SSI модуля мог передаваться не полностью после
- команды include с параметром wait="yes"; ошибка появилась в 0.7.25.
- Спасибо Максиму Дунину.
-
- *) Исправление: директива listen не поддерживала параметр setfib=0.
-
-
-Изменения в nginx 0.8.44 05.07.2010
-
- *) Изменение: теперь nginx по умолчанию не кэширует ответы бэкендов, в
- заголовке которых есть строка "Set-Cookie".
-
- *) Добавление: директива listen поддерживает параметр setfib.
- Спасибо Андрею Филонову.
-
- *) Исправление: директива sub_filter могла изменять регистр букв при
- частичном совпадении.
-
- *) Исправление: совместимость с HP/UX.
-
- *) Исправление: совместимость с компилятором AIX xlC_r.
-
- *) Исправление: nginx считал большие пакеты SSLv2 как обычные текстовые
- запросы.
- Спасибо Miroslaw Jaworski.
-
-
-Изменения в nginx 0.8.43 30.06.2010
-
- *) Добавление: ускорение загрузки больших баз geo-диапазонов.
-
- *) Исправление: перенаправление ошибки в "location /zero {return 204;}"
- без изменения кода ответа оставляло тело ошибки; ошибка появилась в
- 0.8.42.
-
- *) Исправление: nginx мог закрывать IPv6 listen сокет во время
- переконфигурации.
- Спасибо Максиму Дунину.
-
- *) Исправление: переменную $uid_set можно использовать на любой стадии
- обработки запроса.
-
-
-Изменения в nginx 0.8.42 21.06.2010
-
- *) Изменение: теперь nginx проверяет location'ы, заданные регулярными
- выражениями, если запрос полностью совпал с location'ом, заданным
- строкой префикса. Предыдущее поведение появилось в 0.7.1.
-
- *) Добавление: модуль ngx_http_scgi_module.
- Спасибо Manlio Perillo.
-
- *) Добавление: в директиве return можно добавлять текст ответа.
-
-
-Изменения в nginx 0.8.41 15.06.2010
-
- *) Безопасность: рабочий процесс nginx/Windows мог завершаться аварийно
- при запросе файла с неверной кодировкой UTF-8.
-
- *) Изменение: теперь nginx разрешает использовать пробелы в строке
- запроса.
-
- *) Исправление: директива proxy_redirect неправильно изменяла строку
- "Refresh" в заголовке ответа бэкенда.
- Спасибо Андрею Андрееву и Максиму Согину.
-
- *) Исправление: nginx не поддерживал путь без имени хоста в строке
- "Destination" в заголовке запроса.
-
-
-Изменения в nginx 0.8.40 07.06.2010
-
- *) Безопасность: теперь nginx/Windows игнорирует имя потока файла по
- умолчанию.
- Спасибо Jose Antonio Vazquez Gonzalez.
-
- *) Добавление: модуль ngx_http_uwsgi_module.
- Спасибо Roberto De Ioris.
-
- *) Добавление: директива fastcgi_param со значением, начинающимся со
- строки "HTTP_", изменяет строку заголовка в запросе клиента.
-
- *) Исправление: строки "If-Modified-Since", "If-Range" и им подобные в
- заголовке запроса клиента передавались FastCGI-серверу при
- кэшировании.
-
- *) Исправление: listen unix domain сокет нельзя было изменить во время
- переконфигурации.
- Спасибо Максиму Дунину.
-
-
-Изменения в nginx 0.8.39 31.05.2010
-
- *) Исправление: наследуемая директива alias неправильно работала во
- вложенном location'е.
-
- *) Исправление: в комбинации директив alias с переменными и try_files;
-
- *) Исправление: listen unix domain и IPv6 сокеты не наследовались во
- время обновления без перерыва.
- Спасибо Максиму Дунину.
-
-
-Изменения в nginx 0.8.38 24.05.2010
-
- *) Добавление: директивы proxy_no_cache и fastcgi_no_cache.
-
- *) Добавление: теперь при использовании переменной $scheme в директиве
- rewrite автоматически делается редирект.
- Спасибо Piotr Sikora.
-
- *) Исправление: теперь задержки в директиве limit_req соответствует
- описанному алгоритму.
- Спасибо Максиму Дунину.
-
- *) Исправление: переменную $uid_got нельзя было использовать в SSI и
- перловом модулях.
-
-
-Изменения в nginx 0.8.37 17.05.2010
-
- *) Добавление: модуль ngx_http_split_clients_module.
-
- *) Добавление: директива map поддерживает ключи больше 255 символов.
-
- *) Исправление: nginx игнорировал значения "private" и "no-store" в
- строке "Cache-Control" в заголовке ответа бэкенда.
-
- *) Исправление: параметр stub в SSI-директиве include не использовался,
- если пустой ответ имел код 200.
-
- *) Исправление: если проксированный или FastCGI запрос внутренне
- перенаправлялся в другой проксированный или FastCGI location, то в
- рабочем процессе мог произойти segmentation fault; ошибка появилась в
- 0.8.33.
- Спасибо Yichun Zhang.
-
- *) Исправление: соединения IMAP к серверу Zimbra могло зависнуть до
- таймаута.
- Спасибо Alan Batie.
-
-
-Изменения в nginx 0.8.36 22.04.2010
-
- *) Исправление: модуль ngx_http_dav_module неправильно обрабатывал
- методы DELETE, COPY и MOVE для симлинков.
-
- *) Исправление: модуль SSI в подзапросах использовал закэшированные в
- основном запросе значения переменных $query_string, $arg_... и им
- подобных.
-
- *) Исправление: значение переменной повторно экранировалось после
- каждого вывода SSI-команды echo; ошибка появилась в 0.6.14.
-
- *) Исправление: рабочий процесс зависал при запросе файла FIFO.
- Спасибо Vicente Aguilar и Максиму Дунину.
-
- *) Исправление: совместимость с OpenSSL-1.0.0 на 64-битном Linux.
- Спасибо Максиму Дунину.
-
- *) Исправление: nginx не собирался с параметром --without-http-cache;
- ошибка появилась в 0.8.35.
-
-
-Изменения в nginx 0.8.35 01.04.2010
-
- *) Изменение: теперь charset-фильтр работает до SSI-фильтра.
-
- *) Добавление: директива chunked_transfer_encoding.
-
- *) Исправление: символ "&" при копировании в аргументы в правилах
- rewrite не экранировался.
-
- *) Исправление: nginx мог завершаться аварийно во время обработки
- сигнала или при использовании директивы timer_resolution на
- платформах, не поддерживающих методы kqueue или eventport.
- Спасибо George Xie и Максиму Дунину.
-
- *) Исправление: если временные файлы и постоянное место хранения
- располагались на разных файловых системах, то у постоянных файлов
- время изменения было неверным.
- Спасибо Максиму Дунину.
-
- *) Исправление: модуль ngx_http_memcached_module мог выдавать ошибку
- "memcached sent invalid trailer".
- Спасибо Максиму Дунину.
-
- *) Исправление: nginx не мог собрать библиотеку zlib-1.2.4 из исходных
- текстов.
- Спасибо Максиму Дунину.
-
- *) Исправление: в рабочем процессе происходил segmentation fault, если
- перед ответом FastCGI-сервера было много вывода в stderr; ошибка
- появилась в 0.8.34.
- Спасибо Максиму Дунину.
-
-
-Изменения в nginx 0.8.34 03.03.2010
-
- *) Исправление: nginx не поддерживал все шифры, используемые в
- клиентских сертификатах.
- Спасибо Иннокентию Еникееву.
-
- *) Исправление: nginx неправильно кэшировал FastCGI-ответы, если перед
- ответом было много вывода в stderr.
-
- *) Исправление: nginx не поддерживал HTTPS-рефереры.
-
- *) Исправление: nginx/Windows мог не находить файлы, если путь в
- конфигурации был задан в другом регистре; ошибка появилась в 0.8.33.
-
- *) Исправление: переменная $date_local выдавала неверное время, если
- использовался формат "%s".
- Спасибо Максиму Дунину.
-
- *) Исправление: если ssl_session_cache не был установлен или установлен
- в none, то при проверке клиентского сертификаты могла происходить
- ошибка "session id context uninitialized"; ошибка появилась в 0.7.1.
-
- *) Исправление: geo-диапазон возвращал значение по умолчанию, если
- диапазон включал в себя одну и более сетей размером /16 и не
- начинался на границе сети размером /16.
-
- *) Исправление: блок, используемый в параметре stub в SSI-директиве
- include, выводился с MIME-типом "text/plain".
-
- *) Исправление: $r->sleep() не работал; ошибка появилась в 0.8.11.
-
-
-Изменения в nginx 0.8.33 01.02.2010
-
- *) Безопасность: теперь nginx/Windows игнорирует пробелы в конце URI.
- Спасибо Dan Crowley, Core Security Technologies.
-
- *) Безопасность: теперь nginx/Windows игнорирует короткие имена файлов.
- Спасибо Dan Crowley, Core Security Technologies.
-
- *) Изменение: теперь keepalive соединения после запросов POST не
- запрещаются для MSIE 7.0+.
- Спасибо Adam Lounds.
-
- *) Изменение: теперь keepalive соединения запрещены для Safari.
- Спасибо Joshua Sierles.
-
- *) Исправление: если проксированный или FastCGI запрос внутренне
- перенаправлялся в другой проксированный или FastCGI location, то
- переменная $upstream_response_time могла иметь ненормально большое
- значение; ошибка появилась в 0.8.7.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault при
- отбрасывания тела запроса; ошибка появилась в 0.8.11.
-
-
-Изменения в nginx 0.8.32 11.01.2010
-
- *) Исправление: ошибки при использовании кодировки UTF-8 в
- ngx_http_autoindex_module.
- Спасибо Максиму Дунину.
-
- *) Исправление: именованные выделения в регулярных выражениях работали
- только для двух переменных.
- Спасибо Максиму Дунину.
-
- *) Исправление: теперь в строке заголовка запроса "Host" используется
- имя "localhost", если в директиве auth_http указан unix domain сокет.
- Спасибо Максиму Дунину.
-
- *) Исправление: nginx не поддерживал передачу chunk'ами для 201-ых
- ответов.
- Спасибо Julian Reich.
-
- *) Исправление: если директива "expires modified" выставляла дату в
- прошлом, то в строке заголовка ответа "Cache-Control" выдавалось
- отрицательное число.
- Спасибо Алексею Капранову.
-
-
-Изменения в nginx 0.8.31 23.12.2009
-
- *) Добавление: теперь директива error_page может перенаправлять ответы
- со статусом 301 и 302.
-
- *) Добавление: переменные $geoip_city_continent_code, $geoip_latitude и
- $geoip_longitude.
- Спасибо Arvind Sundararajan.
-
- *) Добавление: модуль ngx_http_image_filter_module теперь всегда удаляет
- EXIF и другие данные, если они занимают больше 5% в JPEG-файле.
-
- *) Исправление: nginx закрывал соединение при запросе закэшированного
- ответа с пустым телом.
- Спасибо Piotr Sikora.
-
- *) Исправление: nginx мог не собираться gcc 4.x при использовании
- оптимизации -O2 и выше.
- Спасибо Максиму Дунину и Денису Латыпову.
-
- *) Исправление: регулярные выражения в location всегда тестировались с
- учётом регистра; ошибка появилась в 0.8.25.
-
- *) Исправление: nginx кэшировал 304 ответ, если в заголовке
- проксируемого запроса была строка "If-None-Match".
- Спасибо Tim Dettrick и David Kostal.
-
- *) Исправление: nginx/Windows пытался дважды удалить временный файл при
- перезаписи уже существующего файла.
-
-
-Изменения в nginx 0.8.30 15.12.2009
-
- *) Изменение: теперь по умолчанию размер буфера директивы
- large_client_header_buffers равен 8K.
- Спасибо Andrew Cholakian.
-
- *) Добавление: файл conf/fastcgi.conf для простых конфигураций FastCGI.
-
- *) Исправление: nginx/Windows пытался дважды переименовать временный
- файл при перезаписи уже существующего файла.
-
- *) Исправление: ошибки double free or corruption, возникающей, если имя
- хоста не было найдено; ошибка появилась в 0.8.22.
- Спасибо Константину Свисту.
-
- *) Исправление: в использовании libatomic на некоторых платформах.
- Спасибо W-Mark Kubacki.
-
-
-Изменения в nginx 0.8.29 30.11.2009
-
- *) Изменение: теперь для проксируемых ответов HTTP/0.9 в лог пишется код
- ответа "009".
-
- *) Добавление: директивы addition_types, charset_types, gzip_types,
- ssi_types, sub_filter_types и xslt_types поддерживают параметр "*".
-
- *) Добавление: использование встроенных атомарных операций GCC 4.1+.
- Спасибо W-Mark Kubacki.
-
- *) Добавление: параметр --with-libatomic[=DIR] в configure.
- Спасибо W-Mark Kubacki.
-
- *) Исправление: listen unix domain сокет имели ограниченные права
- доступа.
-
- *) Исправление: закэшированные ответы ответов HTTP/0.9 неправильно
- обрабатывались.
-
- *) Исправление: именованные выделения в регулярных выражениях, заданные
- как "?P<...>", не работали в директиве server_name.
- Спасибо Максиму Дунину.
-
-
-Изменения в nginx 0.8.28 23.11.2009
-
- *) Исправление: nginx не собирался с параметром --without-pcre; ошибка
- появилась в 0.8.25.
-
-
-Изменения в nginx 0.8.27 17.11.2009
-
- *) Исправление: регулярные выражения не работали в nginx/Windows; ошибка
- появилась в 0.8.25.
-
-
-Изменения в nginx 0.8.26 16.11.2009
-
- *) Исправление: ошибки при использовании выделений в директиве rewrite;
- ошибка появилась в 0.8.25.
-
- *) Исправление: nginx не собирался без параметра --with-debug; ошибка
- появилась в 0.8.25.
-
-
-Изменения в nginx 0.8.25 16.11.2009
-
- *) Изменение: теперь в лог ошибок не пишется сообщение, если переменная
- не найдена с помощью метода $r->variable().
-
- *) Добавление: модуль ngx_http_degradation_module.
-
- *) Добавление: именованные выделения в регулярных выражениях.
-
- *) Добавление: теперь при использовании переменных в директиве
- proxy_pass не требуется задавать URI.
-
- *) Добавление: теперь директива msie_padding работает и для Chrome.
-
- *) Исправление: в рабочем процессе происходил segmentation fault при
- недостатке памяти; ошибка появилась в 0.8.18.
-
- *) Исправление: nginx передавал сжатые ответы клиентам, не
- поддерживающим сжатие, при настройках gzip_static on и gzip_vary off;
- ошибка появилась в 0.8.16.
-
-
-Изменения в nginx 0.8.24 11.11.2009
-
- *) Исправление: nginx всегда добавлял строку "Content-Encoding: gzip" в
- заголовок 304-ых ответов модуля ngx_http_gzip_static_module.
-
- *) Исправление: nginx не собирался без параметра --with-debug; ошибка
- появилась в 0.8.23.
-
- *) Исправление: параметр "unix:" в директиве set_real_ip_from
- неправильно наследовался с предыдущего уровня.
-
- *) Исправление: в resolver'е при определении пустого имени.
-
-
-Изменения в nginx 0.8.23 11.11.2009
-
- *) Безопасность: теперь SSL/TLS renegotiation запрещён.
- Спасибо Максиму Дунину.
-
- *) Исправление: listen unix domain сокет не наследовался во время
- обновления без перерыва.
-
- *) Исправление: параметр "unix:" в директиве set_real_ip_from не работал
- без ещё одной директивы с любым IP-адресом.
-
- *) Исправление: segmentation fault и зацикливания в resolver'е.
-
- *) Исправление: в resolver'е.
- Спасибо Артёму Бохану.
-
-
-Изменения в nginx 0.8.22 03.11.2009
-
- *) Добавление: директивы proxy_bind, fastcgi_bind и memcached_bind.
-
- *) Добавление: директивы access и deny поддерживают IPv6.
-
- *) Добавление: директива set_real_ip_from поддерживает IPv6 адреса в
- заголовках запроса.
-
- *) Добавление: параметр "unix:" в директиве set_real_ip_from.
-
- *) Исправление: nginx не удалял unix domain сокет после тестирования
- конфигурации.
-
- *) Исправление: nginx удалял unix domain сокет во время обновления без
- перерыва.
-
- *) Исправление: оператор "!-x" не работал.
- Спасибо Максиму Дунину.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault при
- использовании limit_rate в HTTPS сервере.
- Спасибо Максиму Дунину.
-
- *) Исправление: при записи в лог переменной $limit_rate в рабочем
- процессе происходил segmentation fault.
- Спасибо Максиму Дунину.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если внутри блока server не было директивы listen; ошибка появилась в
- 0.8.21.
-
-
-Изменения в nginx 0.8.21 26.10.2009
-
- *) Добавление: теперь ключ -V показывает статус поддержки TLS SNI.
-
- *) Добавление: директива listen модуля HTTP поддерживает unix domain
- сокеты.
- Спасибо Hongli Lai.
-
- *) Добавление: параметр "default_server" в директиве listen.
-
- *) Добавление: теперь параметр "default" не обязателен для установки
- параметров listen-сокета.
-
- *) Исправление: nginx не поддерживал даты в 2038 году на 32-битных
- платформах;
-
- *) Исправление: утечки сокетов; ошибка появилась в 0.8.11.
-
-
-Изменения в nginx 0.8.20 14.10.2009
-
- *) Изменение: теперь по умолчанию используются следующие шифры SSL:
- "HIGH:!ADH:!MD5".
-
- *) Исправление: модуль ngx_http_autoindex_module не показывал последний
- слэш для линков на каталоги; ошибка появилась в 0.7.15.
-
- *) Исправление: nginx не закрывал лог, заданный параметром конфигурации
- --error-log-path; ошибка появилась в 0.7.53.
-
- *) Исправление: nginx не считал запятую разделителем в строке
- "Cache-Control" в заголовке ответа бэкенда.
-
- *) Исправление: nginx/Windows мог не создать временный файл, файл в кэше
- или файл с помощью директив proxy/fastcgi_store, если рабочий процесс
- не имел достаточно прав для работы с каталогами верхнего уровня.
-
- *) Исправление: строки "Set-Cookie" и "P3P" в заголовке ответа
- FastCGI-сервера не скрывались при кэшировании, если не использовались
- директивы fastcgi_hide_header с любыми параметрами.
-
- *) Исправление: nginx неверно считал размер кэша на диске.
-
-
-Изменения в nginx 0.8.19 06.10.2009
-
- *) Изменение: теперь протокол SSLv2 по умолчанию запрещён.
-
- *) Изменение: теперь по умолчанию используются следующие шифры SSL:
- "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM".
-
- *) Исправление: директива limit_req не работала; ошибка появилась в
- 0.8.18.
-
-
-Изменения в nginx 0.8.18 06.10.2009
-
- *) Добавление: директива read_ahead.
-
- *) Добавление: теперь можно использовать несколько директив
- perl_modules.
-
- *) Добавление: директивы limit_req_log_level и limit_conn_log_level.
-
- *) Исправление: теперь директива limit_req соответствует алгоритму leaky
- bucket.
- Спасибо Максиму Дунину.
-
- *) Исправление: nginx не работал на Linux/sparc.
- Спасибо Marcus Ramberg.
-
- *) Исправление: nginx слал символ '\0' в строке "Location" в заголовке в
- ответе на запрос MKCOL.
- Спасибо Xie Zhenye.
-
- *) Исправление: вместо кода ответа 499 в лог записывался код 0; ошибка
- появилась в 0.8.11.
-
- *) Исправление: утечки сокетов; ошибка появилась в 0.8.11.
-
-
-Изменения в nginx 0.8.17 28.09.2009
-
- *) Безопасность: теперь символы "/../" запрещены в строке "Destination"
- в заголовке запроса.
-
- *) Изменение: теперь значение переменной $host всегда в нижнем регистре.
-
- *) Добавление: переменная $ssl_session_id.
-
- *) Исправление: утечки сокетов; ошибка появилась в 0.8.11.
-
-
-Изменения в nginx 0.8.16 22.09.2009
-
- *) Добавление: директива image_filter_transparency.
-
- *) Исправление: директива "addition_types" была неверно названа
- "addtion_types".
-
- *) Исправление: порчи кэша resolver'а.
- Спасибо Matthew Dempsky.
-
- *) Исправление: утечки памяти в resolver'е.
- Спасибо Matthew Dempsky.
-
- *) Исправление: неверная строка запроса в переменной $request
- записывалась в access_log только при использовании error_log на
- уровне info или debug.
-
- *) Исправление: в поддержке альфа-канала PNG в модуле
- ngx_http_image_filter_module.
-
- *) Исправление: nginx всегда добавлял строку "Vary: Accept-Encoding" в
- заголовок ответа, если обе директивы gzip_static и gzip_vary были
- включены.
-
- *) Исправление: в поддержке кодировки UTF-8 директивой try_files в
- nginx/Windows.
-
- *) Исправление: ошибки при использовании post_action; ошибка появилась в
- 0.8.11.
- Спасибо Игорю Артемьеву.
-
-
-Изменения в nginx 0.8.15 14.09.2009
-
- *) Безопасность: при обработке специально созданного запроса в рабочем
- процессе мог произойти segmentation fault.
- Спасибо Chris Ries.
-
- *) Исправление: если были описаны имена .domain.tld, .sub.domain.tld и
- .domain-some.tld, то имя .sub.domain.tld попадало под маску
- .domain.tld.
-
- *) Исправление: в поддержке прозрачности в модуле
- ngx_http_image_filter_module.
-
- *) Исправление: в файловом AIO.
-
- *) Исправление: ошибки при использовании X-Accel-Redirect; ошибка
- появилась в 0.8.11.
-
- *) Исправление: ошибки при использовании встроенного перла; ошибка
- появилась в 0.8.11.
-
-
-Изменения в nginx 0.8.14 07.09.2009
-
- *) Исправление: устаревший закэшированный запрос мог залипнуть в
- состоянии "UPDATING".
-
- *) Исправление: при использовании error_log на уровне info или debug в
- рабочем процессе мог произойти segmentation fault.
- Спасибо Сергею Боченкову.
-
- *) Исправление: ошибки при использовании встроенного перла; ошибка
- появилась в 0.8.11.
-
- *) Исправление: директива error_page не перенаправляла ошибку 413;
- ошибка появилась в 0.6.10.
-
-
-Изменения в nginx 0.8.13 31.08.2009
-
- *) Исправление: в директиве "aio sendfile"; ошибка появилась в 0.8.12.
-
- *) Исправление: nginx не собирался без параметра --with-file-aio на
- FreeBSD; ошибка появилась в 0.8.12.
-
-
-Изменения в nginx 0.8.12 31.08.2009
-
- *) Добавление: параметр sendfile в директиве aio во FreeBSD.
-
- *) Исправление: ошибки при использовании try_files; ошибка появилась в
- 0.8.11.
-
- *) Исправление: ошибки при использовании memcached; ошибка появилась в
- 0.8.11.
-
-
-Изменения в nginx 0.8.11 28.08.2009
-
- *) Изменение: теперь директива "gzip_disable msie6" не запрещает сжатие
- для MSIE 6.0 SV1.
-
- *) Добавление: поддержка файлового AIO во FreeBSD и Linux.
-
- *) Добавление: директива directio_alignment.
-
-
-Изменения в nginx 0.8.10 24.08.2009
-
- *) Исправление: утечек памяти при использовании базы GeoIP City.
-
- *) Исправление: ошибки при копировании временных файлов в постоянное
- место хранения; ошибка появилась в 0.8.9.
-
-
-Изменения в nginx 0.8.9 17.08.2009
-
- *) Добавление: теперь стартовый загрузчик кэша работает в отдельном
- процесс; это должно улучшить обработку больших кэшей.
-
- *) Добавление: теперь временные файлы и постоянное место хранения могут
- располагаться на разных файловых системах.
-
-
-Изменения в nginx 0.8.8 10.08.2009
-
- *) Исправление: в обработке заголовков ответа, разделённых в
- FastCGI-записях.
-
- *) Исправление: если запрос обрабатывался в двух проксированных или
- FastCGI location'ах и в первом из них использовалось кэширование, то
- в рабочем процессе происходил segmentation fault; ошибка появилась в
- 0.8.7.
-
-
-Изменения в nginx 0.8.7 27.07.2009
-
- *) Изменение: минимальная поддерживаемая версия OpenSSL - 0.9.7.
-
- *) Изменение: параметр ask директивы ssl_verify_client изменён на
- параметр optional и теперь он проверяет клиентский сертификат, если
- он был предложен.
- Спасибо Brice Figureau.
-
- *) Добавление: переменная $ssl_client_verify.
- Спасибо Brice Figureau.
-
- *) Добавление: директива ssl_crl.
- Спасибо Brice Figureau.
-
- *) Добавление: параметр proxy директивы geo.
-
- *) Добавление: директива image_filter поддерживает переменные для
- задания размеров.
-
- *) Исправление: использование переменной $ssl_client_cert портило
- память; ошибка появилась в 0.7.7.
- Спасибо Сергею Журавлёву.
-
- *) Исправление: директивы proxy_pass_header и fastcgi_pass_header" не
- передавали клиенту строки "X-Accel-Redirect", "X-Accel-Limit-Rate",
- "X-Accel-Buffering" и "X-Accel-Charset" из заголовка ответа бэкенда.
- Спасибо Максиму Дунину.
-
- *) Исправление: в обработке строк "Last-Modified" и "Accept-Ranges" в
- заголовке ответа бэкенда; ошибка появилась в 0.7.44.
- Спасибо Максиму Дунину.
-
- *) Исправление: ошибки "[alert] zero size buf" при получении пустых
- ответы в подзапросах; ошибка появилась в 0.8.5.
-
-
-Изменения в nginx 0.8.6 20.07.2009
-
- *) Добавление: модуль ngx_http_geoip_module.
-
- *) Исправление: XSLT-фильтр мог выдавать ошибку "not well formed XML
- document" для правильного документа.
- Спасибо Kuramoto Eiji.
-
- *) Исправление: в MacOSX, Cygwin и nginx/Windows при проверке
- location'ов, заданных регулярным выражением, теперь всегда делается
- сравнение без учёта регистра символов.
-
- *) Исправление: теперь nginx/Windows игнорирует точки в конце URI.
- Спасибо Hugo Leisink.
-
- *) Исправление: имя файла указанного в --conf-path игнорировалось при
- установке; ошибка появилась в 0.6.6.
- Спасибо Максиму Дунину.
-
-
-Изменения в nginx 0.8.5 13.07.2009
-
- *) Исправление: теперь nginx разрешает подчёркивания в методе запроса.
-
- *) Исправление: при использовании HTTP Basic-аутентификации на Windows
- для неверных имени/пароля возвращалась 500-ая ошибка.
-
- *) Исправление: ответы модуля ngx_http_perl_module не работали в
- подзапросах.
-
- *) Исправление: в модуле ngx_http_limit_req_module.
- Спасибо Максиму Дунину.
-
-
-Изменения в nginx 0.8.4 22.06.2009
-
- *) Исправление: nginx не собирался с параметром --without-http-cache;
- ошибка появилась в 0.8.3.
-
-
-Изменения в nginx 0.8.3 19.06.2009
-
- *) Добавление: переменная $upstream_cache_status.
-
- *) Исправление: nginx не собирался на MacOSX 10.6.
-
- *) Исправление: nginx не собирался с параметром --without-http-cache;
- ошибка появилась в 0.8.2.
-
- *) Исправление: если использовался перехват 401 ошибки от бэкенда и
- бэкенд не возвращал строку "WWW-Authenticate" в заголовке ответа, то
- в рабочем процессе происходил segmentation fault.
- Спасибо Евгению Мычло.
-
-
-Изменения в nginx 0.8.2 15.06.2009
-
- *) Исправление: во взаимодействии open_file_cache и proxy/fastcgi кэша
- на старте.
-
- *) Исправление: open_file_cache мог кэшировать открытые файлы очень
- долго; ошибка появилась в 0.7.4.
-
-
-Изменения в nginx 0.8.1 08.06.2009
-
- *) Добавление: параметр updating в директивах proxy_cache_use_stale и
- fastcgi_cache_use_stale.
-
- *) Исправление: строки "If-Modified-Since", "If-Range" и им подобные в
- заголовке запроса клиента передавались бэкенду при кэшировании, если
- не использовалась директива proxy_set_header с любыми параметрами.
-
- *) Исправление: строки "Set-Cookie" и "P3P" в заголовке ответа бэкенда
- не скрывались при кэшировании, если не использовались директивы
- proxy_hide_header/fastcgi_hide_header с любыми параметрами.
-
- *) Исправление: модуль ngx_http_image_filter_module не понимал формат
- GIF87a.
- Спасибо Денису Ильиных.
-
- *) Исправление: nginx не собирался на Solaris 10 и более ранних; ошибка
- появилась в 0.7.56.
-
-
-Изменения в nginx 0.8.0 02.06.2009
-
- *) Добавление: директива keepalive_requests.
-
- *) Добавление: директива limit_rate_after.
- Спасибо Ivan Debnar.
-
- *) Исправление: XSLT-фильтр не работал в подзапросах.
-
- *) Исправление: обработке относительных путей в nginx/Windows.
-
- *) Исправление: в proxy_store, fastcgi_store, proxy_cache и
- fastcgi_cache в nginx/Windows.
-
- *) Исправление: в обработке ошибок выделения памяти.
- Спасибо Максиму Дунину и Кириллу Коринскому.
-
-
-Изменения в nginx 0.7.59 25.05.2009
-
- *) Добавление: директивы proxy_cache_methods и fastcgi_cache_methods.
-
- *) Исправление: утечки сокетов; ошибка появилась в 0.7.25.
- Спасибо Максиму Дунину.
-
- *) Исправление: при использовании переменной $request_body в рабочем
- процессе происходил segmentation fault, если в запросе не было тела;
- ошибка появилась в 0.7.58.
-
- *) Исправление: SSL-модули могли не собираться на Solaris и Linux;
- ошибка появилась в 0.7.56.
-
- *) Исправление: ответы модуля ngx_http_xslt_filter_module не
- обрабатывались SSI-, charset- и gzip-фильтрами.
-
- *) Исправление: директива charset не ставила кодировку для ответов
- модуля ngx_http_gzip_static_module.
-
-
-Изменения в nginx 0.7.58 18.05.2009
-
- *) Добавление: директива listen почтового прокси-сервера поддерживает
- IPv6.
-
- *) Добавление: директива image_filter_jpeg_quality.
-
- *) Добавление: директива client_body_in_single_buffer.
-
- *) Добавление: переменная $request_body.
-
- *) Исправление: в модуле ngx_http_autoindex_module в ссылках на имена
- файлов, содержащих символ ":".
-
- *) Исправление: процедура "make upgrade" не работала; ошибка появилась в
- 0.7.53.
- Спасибо Денису Латыпову.
-
-
-Изменения в nginx 0.7.57 12.05.2009
-
- *) Исправление: при перенаправлении ошибок модуля
- ngx_http_image_filter_module в именованный location в рабочем
- процессе происходил floating-point fault; ошибка появилась в 0.7.56.
-
-
-Изменения в nginx 0.7.56 11.05.2009
-
- *) Добавление: nginx/Windows поддерживает IPv6 в директиве listen модуля
- HTTP.
-
- *) Исправление: в модуле ngx_http_image_filter_module.
-
-
-Изменения в nginx 0.7.55 06.05.2009
-
- *) Исправление: параметры http_XXX в директивах proxy_cache_use_stale и
- fastcgi_cache_use_stale не работали.
-
- *) Исправление: fastcgi кэш не кэшировал ответы, состоящие только из
- заголовка.
-
- *) Исправление: ошибки "select() failed (9: Bad file descriptor)" в
- nginx/Unix и "select() failed (10038: ...)" в nginx/Windows.
-
- *) Исправление: при использовании директивы debug_connection в рабочем
- процессе мог произойти segmentation fault; ошибка появилась в 0.7.54.
-
- *) Исправление: в сборке модуля ngx_http_image_filter_module.
-
- *) Исправление: файлы больше 2G не передавались с использованием
- $r->sendfile.
- Спасибо Максиму Дунину.
-
-
-Изменения в nginx 0.7.54 01.05.2009
-
- *) Добавление: модуль ngx_http_image_filter_module.
-
- *) Добавление: директивы proxy_ignore_headers и fastcgi_ignore_headers.
-
- *) Исправление: при использовании переменных "open_file_cache_errors on"
- в рабочем процессе мог произойти segmentation fault; ошибка появилась
- в 0.7.53.
-
- *) Исправление: директива "port_in_redirect off" не работала; ошибка
- появилась в 0.7.39.
-
- *) Исправление: улучшение обработки ошибок метода select.
-
- *) Исправление: ошибки "select() failed (10022: ...)" в nginx/Windows.
-
- *) Исправление: в текстовых сообщениях об ошибках в nginx/Windows;
- ошибка появилась в 0.7.53.
-
-
-Изменения в nginx 0.7.53 27.04.2009
-
- *) Изменение: теперь лог, указанный в --error-log-path, создаётся с
- самого начала работы.
-
- *) Добавление: теперь ошибки и предупреждения при старте записываются в
- error_log и выводятся на stderr.
-
- *) Добавление: при сборке с пустым параметром --prefix= nginx использует
- как префикс каталог, в котором он был запущен.
-
- *) Добавление: ключ -p.
-
- *) Добавление: ключ -s на Unix-платформах.
-
- *) Добавление: ключи -? и -h.
- Спасибо Jerome Loyet.
-
- *) Добавление: теперь ключи можно задавать в сжатой форме.
-
- *) Исправление: nginx/Windows не работал, если файл конфигурации был
- задан ключом -c.
-
- *) Исправление: при использовании директив proxy_store, fastcgi_store,
- proxy_cache или fastcgi_cache временные файлы могли не удаляться.
- Спасибо Максиму Дунину.
-
- *) Исправление: в заголовке Auth-Method запроса серверу аутентификации
- почтового прокси-сервера передавалось неверное значение; ошибка
- появилась в 0.7.34.
- Спасибо Simon Lecaille.
-
- *) Исправление: при логгировании на Linux не писались текстовые описания
- системных ошибок; ошибка появилась в 0.7.45.
-
- *) Исправление: директива fastcgi_cache_min_uses не работала.
- Спасибо Андрею Воробьёву.
-
-
-Изменения в nginx 0.7.52 20.04.2009
-
- *) Добавление: первая бинарная версия под Windows.
-
- *) Исправление: корректная обработка метода HEAD при кэшировании.
-
- *) Исправление: корректная обработка строк "If-Modified-Since",
- "If-Range" и им подобных в заголовке запроса клиента при кэшировании.
-
- *) Исправление: теперь строки "Set-Cookie" и "P3P" скрываются в
- заголовке ответа для закэшированных ответов.
-
- *) Исправление: если nginx был собран с модулем ngx_http_perl_module и
- perl поддерживал потоки, то при выходе основного процесса могла
- выдаваться ошибка "panic: MUTEX_LOCK".
-
- *) Исправление: nginx не собирался с параметром --without-http-cache;
- ошибка появилась в 0.7.48.
-
- *) Исправление: nginx не собирался на платформах, отличных от i386,
- amd64, sparc и ppc; ошибка появилась в 0.7.42.
-
-
-Изменения в nginx 0.7.51 12.04.2009
-
- *) Добавление: директива try_files поддерживает код ответа в последнем
- параметре.
-
- *) Добавление: теперь в директиве return можно использовать любой код
- ответа.
-
- *) Исправление: директива error_page делала внешний редирект без строки
- запроса; ошибка появилась в 0.7.44.
-
- *) Исправление: если сервера слушали на нескольких явно описанных
- адресах, то виртуальные сервера могли не работать; ошибка появилась в
- 0.7.39.
-
-
-Изменения в nginx 0.7.50 06.04.2009
-
- *) Исправление: переменные $arg_... не работали; ошибка появилась в
- 0.7.49.
-
-
-Изменения в nginx 0.7.49 06.04.2009
-
- *) Исправление: при использовании переменных $arg_... в рабочем процессе
- мог произойти segmentation fault; ошибка появилась в 0.7.48.
-
-
-Изменения в nginx 0.7.48 06.04.2009
-
- *) Добавление: директива proxy_cache_key.
-
- *) Исправление: теперь nginx учитывает при кэшировании строки
- "X-Accel-Expires", "Expires" и "Cache-Control" в заголовке ответа
- бэкенда.
-
- *) Исправление: теперь nginx кэширует только ответы на запросы GET.
-
- *) Исправление: директива fastcgi_cache_key не наследовалась.
-
- *) Исправление: переменные $arg_... не работали с SSI-подзапросами.
- Спасибо Максиму Дунину.
-
- *) Исправление: nginx не собирался с библиотекой uclibc.
- Спасибо Timothy Redaelli.
-
- *) Исправление: nginx не собирался на OpenBSD; ошибка появилась
- в 0.7.46.
-
-
-Изменения в nginx 0.7.47 01.04.2009
-
- *) Исправление: nginx не собирался на FreeBSD 6 и более ранних версиях;
- ошибка появилась в 0.7.46.
-
- *) Исправление: nginx не собирался на MacOSX; ошибка появилась в 0.7.46.
-
- *) Исправление: если использовался параметр max_size, то cache manager
- мог удалить весь кэш; ошибка появилась в 0.7.46.
-
- *) Изменение: в рабочем процессе мог произойти segmentation fault, если
- директивы proxy_cache/fastcgi_cache и proxy_cache_valid/
- fastcgi_cache_valid не были заданы на одном уровне; ошибка появилась
- в 0.7.46.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault при
- перенаправлении запроса проксированному или FastCGI-серверу с помощью
- error_page или try_files; ошибка появилась в 0.7.44.
-
-
-Изменения в nginx 0.7.46 30.03.2009
-
- *) Исправление: архив предыдущего релиза был неверным.
-
-
-Изменения в nginx 0.7.45 30.03.2009
-
- *) Изменение: теперь директивы proxy_cache и proxy_cache_valid можно
- задавать на разных уровнях.
-
- *) Изменение: параметр clean_time в директиве proxy_cache_path удалён.
-
- *) Добавление: параметр max_size в директиве proxy_cache_path.
-
- *) Добавление: предварительная поддержка кэширования в модуле
- ngx_http_fastcgi_module.
-
- *) Добавление: теперь при ошибках выделения в разделяемой памяти в логе
- указываются названия директивы и зоны.
-
- *) Исправление: директива "add_header last-modified ''" не удаляла в
- заголовке ответа строку "Last-Modified"; ошибка появилась в 0.7.44.
-
- *) Исправление: в директиве auth_basic_user_file не работал
- относительный путь, заданный строкой без переменных; ошибка появилась
- в 0.7.44.
- Спасибо Jerome Loyet.
-
- *) Исправление: в директиве alias, заданной переменными без ссылок на
- выделения в регулярных выражениях; ошибка появилась в 0.7.42.
-
-
-Изменения в nginx 0.7.44 23.03.2009
-
- *) Добавление: предварительная поддержка кэширования в модуле
- ngx_http_proxy_module.
-
- *) Добавление: параметр --with-pcre в configure.
-
- *) Добавление: теперь директива try_files может быть использована на
- уровне server.
-
- *) Исправление: директива try_files неправильно обрабатывала строку
- запроса в последнем параметре.
-
- *) Исправление: директива try_files могла неверно тестировать каталоги.
-
- *) Исправление: если для пары адрес:порт описан только один сервер, то
- выделения в регулярных выражениях в директиве server_name не
- работали.
-
-
-Изменения в nginx 0.7.43 18.03.2009
-
- *) Исправление: запрос обрабатывался неверно, если директива root
- использовала переменные; ошибка появилась в 0.7.42.
-
- *) Исправление: если сервер слушал на адресах типа "*", то значение
- переменной $server_addr было "0.0.0.0"; ошибка появилась в 0.7.36.
-
-
-Изменения в nginx 0.7.42 16.03.2009
-
- *) Изменение: ошибка "Invalid argument", возвращаемая
- setsockopt(TCP_NODELAY) на Solaris, теперь игнорируется.
-
- *) Изменение: при отсутствии файла, указанного в директиве
- auth_basic_user_file, теперь возвращается ошибка 403 вместо 500.
-
- *) Добавление: директива auth_basic_user_file поддерживает переменные.
- Спасибо Кириллу Коринскому.
-
- *) Добавление: директива listen поддерживает параметр ipv6only.
- Спасибо Zhang Hua.
-
- *) Исправление: в директиве alias со ссылками на выделения в регулярных
- выражениях; ошибка появилась в 0.7.40.
-
- *) Исправление: совместимость с Tru64 UNIX.
- Спасибо Dustin Marquess.
-
- *) Исправление: nginx не собирался без библиотеки PCRE; ошибка появилась
- в 0.7.41.
-
-
-Изменения в nginx 0.7.41 11.03.2009
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если в server_name или location были выделения в регулярных
- выражениях; ошибка появилась в 0.7.40.
- Спасибо Владимиру Сопоту.
-
-
-Изменения в nginx 0.7.40 09.03.2009
-
- *) Добавление: директива location поддерживает выделения в регулярных
- выражениях.
-
- *) Добавление: директиву alias с ссылками на выделения в регулярных
- выражениях можно использовать внутри location'а, заданного регулярным
- выражением с выделениями.
-
- *) Добавление: директива server_name поддерживает выделения в регулярных
- выражениях.
-
- *) Изменение: модуль ngx_http_autoindex_module не показывал последний
- слэш для каталогов на файловой системе XFS; ошибка появилась в
- 0.7.15.
- Спасибо Дмитрию Кузьменко.
-
-
-Изменения в nginx 0.7.39 02.03.2009
-
- *) Исправление: при включённом сжатии большие ответы с использованием
- SSI могли зависать; ошибка появилась в 0.7.28.
- Спасибо Артёму Бохану.
-
- *) Исправление: при использовании коротких статических вариантов в
- директиве try_files в рабочем процессе мог произойти segmentation
- fault.
-
-
-Изменения в nginx 0.7.38 23.02.2009
-
- *) Добавление: логгирование ошибок аутентификации.
-
- *) Исправление: имя/пароль, заданные в auth_basic_user_file,
- игнорировались после нечётного числа пустых строк.
- Спасибо Александру Загребину.
-
- *) Исправление: при использовании длинного пути в unix domain сокете в
- главном процессе происходил segmentation fault; ошибка появилась в
- 0.7.36.
-
-
-Изменения в nginx 0.7.37 21.02.2009
-
- *) Исправление: директивы, использующие upstream'ы, не работали; ошибка
- появилась в 0.7.36.
-
-
-Изменения в nginx 0.7.36 21.02.2009
-
- *) Добавление: предварительная поддержка IPv6; директива listen модуля
- HTTP поддерживает IPv6.
-
- *) Исправление: переменная $ancient_browser не работала для браузеров,
- заданных директивами modern_browser.
-
-
-Изменения в nginx 0.7.35 16.02.2009
-
- *) Исправление: директива ssl_engine не использовала SSL-акселератор для
- асимметричных шифров.
- Спасибо Marcin Gozdalik.
-
- *) Исправление: директива try_files выставляла MIME-type, исходя из
- расширения первоначального запроса.
-
- *) Исправление: в директивах server_name, valid_referers и map
- неправильно обрабатывались имена вида "*domain.tld", если
- использовались маски вида ".domain.tld" и ".subdomain.domain.tld";
- ошибка появилась в 0.7.9.
-
-
-Изменения в nginx 0.7.34 10.02.2009
-
- *) Добавление: параметр off в директиве if_modified_since.
-
- *) Добавление: теперь после команды XCLIENT nginx посылает команду
- HELO/EHLO.
- Спасибо Максиму Дунину.
-
- *) Добавление: поддержка Microsoft-специфичного режима
- "AUTH LOGIN with User Name" в почтовом прокси-сервере.
- Спасибо Максиму Дунину.
-
- *) Исправление: в директиве rewrite, возвращающей редирект, старые
- аргументы присоединялись к новым через символ "?" вместо "&";
- ошибка появилась в 0.1.18.
- Спасибо Максиму Дунину.
-
- *) Исправление: nginx не собирался на AIX.
-
-
-Изменения в nginx 0.7.33 02.02.2009
-
- *) Исправление: если на запрос с телом возвращался редирект, то ответ
- мог быть двойным при использовании методов epoll или rtsig.
- Спасибо Eden Li.
-
- *) Исправление: для некоторых типов редиректов в переменной
- $sent_http_location было пустое значение.
-
- *) Исправление: при использовании директивы resolver в SMTP
- прокси-сервере в рабочем процессе мог произойти segmentation fault.
-
-
-Изменения в nginx 0.7.32 26.01.2009
-
- *) Добавление: теперь в директиве try_files можно явно указать проверку
- каталога.
-
- *) Исправление: fastcgi_store не всегда сохранял файлы.
-
- *) Исправление: в гео-диапазонах.
-
- *) Исправление: ошибки выделения больших блоков в разделяемой памяти,
- если nginx был собран без отладки.
- Спасибо Андрею Квасову.
-
-
-Изменения в nginx 0.7.31 19.01.2009
-
- *) Изменение: теперь директива try_files проверяет только файлы,
- игнорируя каталоги.
-
- *) Добавление: директива fastcgi_split_path_info.
-
- *) Исправления в поддержке строки "Expect" в заголовке запроса.
-
- *) Исправления в гео-диапазонах.
-
- *) Исправление: при отсутствии ответа ngx_http_memcached_module
- возвращал в теле ответа строку "END" вместо 404-ой страницы по
- умолчанию; ошибка появилась в 0.7.18.
- Спасибо Максиму Дунину.
-
- *) Исправление: при проксировании SMTP nginx выдавал сообщение
- "250 2.0.0 OK" вместо "235 2.0.0 OK"; ошибка появилась в 0.7.22.
- Спасибо Максиму Дунину.
-
-
-Изменения в nginx 0.7.30 24.12.2008
-
- *) Исправление: в рабочем процессе происходил segmentation fault, если в
- директивах fastcgi_pass или proxy_pass использовались переменные и
- имя хоста должно было резолвиться; ошибка появилась в 0.7.29.
-
-
-Изменения в nginx 0.7.29 24.12.2008
-
- *) Исправление: директивы fastcgi_pass и proxy_pass не поддерживали
- переменные при использовании unix domain сокетов.
-
- *) Исправления в обработке подзапросов; ошибки появились в 0.7.25.
-
- *) Исправление: ответ "100 Continue" выдавался для запросов версии
- HTTP/1.0;
- Спасибо Максиму Дунину.
-
- *) Исправление: в выделении памяти в модуле ngx_http_gzip_filter_module
- под Cygwin.
-
-
-Изменения в nginx 0.7.28 22.12.2008
-
- *) Изменение: в выделении памяти в модуле ngx_http_gzip_filter_module.
-
- *) Изменение: значения по умолчанию для директивы gzip_buffers изменены
- с 4 4k/8k на 32 4k или 16 8k.
-
-
-Изменения в nginx 0.7.27 15.12.2008
-
- *) Добавление: директива try_files.
-
- *) Добавление: директива fastcgi_pass поддерживает переменные.
-
- *) Добавление: теперь директива geo может брать адрес из переменной.
- Спасибо Андрею Нигматулину.
-
- *) Добавление: теперь модификатор location'а можно указывать без пробела
- перед названием.
-
- *) Добавление: переменная $upstream_response_length.
-
- *) Исправление: теперь директива add_header не добавляет пустое
- значение.
-
- *) Исправление: при запросе файла нулевой длины nginx закрывал
- соединение, ничего не передав; ошибка появилась в 0.7.25.
-
- *) Исправление: метод MOVE не мог перемещать файл в несуществующий
- каталог.
-
- *) Исправление: если в сервере не был описан ни один именованный
- location, но такой location использовался в директиве error_page, то
- в рабочем процессе происходил segmentation fault.
- Спасибо Сергею Боченкову.
-
-
-Изменения в nginx 0.7.26 08.12.2008
-
- *) Исправление: в обработке подзапросов; ошибка появилась в 0.7.25.
-
-
-Изменения в nginx 0.7.25 08.12.2008
-
- *) Изменение: в обработке подзапросов.
-
- *) Изменение: теперь разрешаются POST'ы без строки "Content-Length" в
- заголовке запроса.
-
- *) Исправление: теперь директивы limit_req и limit_conn указывают
- причину запрета запроса.
-
- *) Исправление: в параметре delete директивы geo.
-
-
-Изменения в nginx 0.7.24 01.12.2008
-
- *) Добавление: директива if_modified_since.
-
- *) Исправление: nginx не обрабатывал ответ FastCGI-сервера, если перед
- ответом сервер передавал много сообщений в stderr.
-
- *) Исправление: переменные "$cookie_..." не работали в SSI and в
- перловом модуле.
-
-
-Изменения в nginx 0.7.23 27.11.2008
-
- *) Добавление: параметры delete и ranges в директиве geo.
-
- *) Добавление: ускорение загрузки geo-базы с большим числом значений.
-
- *) Добавление: уменьшение памяти, необходимой для загрузки geo-базы.
-
-
-Изменения в nginx 0.7.22 20.11.2008
-
- *) Добавление: параметр none в директиве smtp_auth.
- Спасибо Максиму Дунину.
-
- *) Добавление: переменные "$cookie_...".
-
- *) Исправление: директива directio не работала с файловой системой XFS.
-
- *) Исправление: resolver не понимал большие DNS-ответы.
- Спасибо Zyb.
-
-
-Изменения в nginx 0.7.21 11.11.2008
-
- *) Изменения в модуле ngx_http_limit_req_module.
-
- *) Добавление: поддержка EXSLT в модуле ngx_http_xslt_module.
- Спасибо Денису Латыпову.
-
- *) Изменение: совместимость с glibc 2.3.
- Спасибо Eric Benson и Максиму Дунину.
-
- *) Исправление: nginx не запускался на MacOSX 10.4 и более ранних;
- ошибка появилась в 0.7.6.
-
-
-Изменения в nginx 0.7.20 10.11.2008
-
- *) Изменения в модуле ngx_http_gzip_filter_module.
-
- *) Добавление: модуль ngx_http_limit_req_module.
-
- *) Исправление: на платформах sparc и ppc рабочие процессы могли
- выходить по сигналу SIGBUS; ошибка появилась в 0.7.3.
- Спасибо Максиму Дунину.
-
- *) Исправление: директивы вида "proxy_pass http://host/some:uri" не
- работали; ошибка появилась в 0.7.12.
-
- *) Исправление: при использовании HTTPS запросы могли завершаться с
- ошибкой "bad write retry".
-
- *) Исправление: модуль ngx_http_secure_link_module не работал внутри
- location'ов с именами меньше 3 символов.
-
- *) Исправление: переменная $server_addr могла не иметь значения.
-
-
-Изменения в nginx 0.7.19 13.10.2008
-
- *) Исправление: обновление номера версии.
-
-
-Изменения в nginx 0.7.18 13.10.2008
-
- *) Изменение: директива underscores_in_headers; теперь nginx по
- умолчанию не разрешает подчёркивания в именах строк в заголовке
- запроса клиента.
-
- *) Добавление: модуль ngx_http_secure_link_module.
-
- *) Добавление: директива real_ip_header поддерживает любой заголовок.
-
- *) Добавление: директива log_subrequest.
-
- *) Добавление: переменная $realpath_root.
-
- *) Добавление: параметры http_502 и http_504 в директиве
- proxy_next_upstream.
-
- *) Исправление: параметр http_503 в директивах proxy_next_upstream или
- fastcgi_next_upstream не работал.
-
- *) Исправление: nginx мог выдавать строку "Transfer-Encoding: chunked"
- для запросов HEAD.
-
- *) Исправление: теперь accept-лимит зависит от числа worker_connections.
-
-
-Изменения в nginx 0.7.17 15.09.2008
-
- *) Добавление: директива directio теперь работает на Linux.
-
- *) Добавление: переменная $pid.
-
- *) Исправление: оптимизация directio, появившаяся в 0.7.15, не работала
- при использовании open_file_cache.
-
- *) Исправление: access_log с переменными не работал на Linux; ошибка
- появилась в 0.7.7.
-
- *) Исправление: модуль ngx_http_charset_module не понимал название
- кодировки в кавычках, полученное от бэкенда.
-
-
-Изменения в nginx 0.7.16 08.09.2008
-
- *) Исправление: nginx не собирался на 64-битных платформах; ошибка
- появилась в 0.7.15.
-
-
-Изменения в nginx 0.7.15 08.09.2008
-
- *) Добавление: модуль ngx_http_random_index_module.
-
- *) Добавление: директива directio оптимизирована для запросов файлов,
- начинающихся с произвольной позиции.
-
- *) Добавление: директива directio при необходимости запрещает
- использование sendfile.
-
- *) Добавление: теперь nginx разрешает подчёркивания в именах строк в
- заголовке запроса клиента.
-
-
-Изменения в nginx 0.7.14 01.09.2008
-
- *) Изменение: теперь директивы ssl_certificate и ssl_certificate_key не
- имеют значений по умолчанию.
-
- *) Добавление: директива listen поддерживает параметр ssl.
-
- *) Добавление: теперь при переконфигурации nginx учитывает изменение
- временной зоны на FreeBSD и Linux.
-
- *) Исправление: параметры директивы listen, такие как backlog, rcvbuf и
- прочие, не устанавливались, если сервером по умолчанию был не первый
- сервер.
-
- *) Исправление: при использовании в качестве аргументов части URI,
- выделенного с помощью директивы rewrite, эти аргументы не
- экранировались.
-
- *) Исправление: улучшения тестирования правильности конфигурационного
- файла.
-
-
-Изменения в nginx 0.7.13 26.08.2008
-
- *) Исправление: nginx не собирался на Linux и Solaris; ошибка появилась
- в 0.7.12.
-
-
-Изменения в nginx 0.7.12 26.08.2008
-
- *) Добавление: директива server_name поддерживает пустое имя "".
-
- *) Добавление: директива gzip_disable поддерживает специальную маску
- msie6.
-
- *) Исправление: при использовании параметра max_fails=0 в upstream'е с
- несколькими серверами рабочий процесс выходил по сигналу SIGFPE.
- Спасибо Максиму Дунину.
-
- *) Исправление: при перенаправлении запроса с помощью директивы
- error_page терялось тело запроса.
-
- *) Исправление: при перенаправлении запроса с методом HEAD с помощью
- директивы error_page возвращался полный ответ.
-
- *) Исправление: метод $r->header_in() не возвращал значения строк
- "Host", "User-Agent", и "Connection" из заголовка запроса; ошибка
- появилась в 0.7.0.
-
-
-Изменения в nginx 0.7.11 18.08.2008
-
- *) Изменение: теперь ngx_http_charset_module по умолчанию не работает
- MIME-типом text/css.
-
- *) Добавление: теперь nginx возвращает код 405 для метода POST при
- запросе статического файла, только если файл существует.
-
- *) Добавление: директива proxy_ssl_session_reuse.
-
- *) Исправление: после перенаправления запроса с помощью
- "X-Accel-Redirect" директива proxy_pass без URI могла использовать
- оригинальный запрос.
-
- *) Исправление: если у каталога были права доступа только на поиск
- файлов и первый индексный файл отсутствовал, то nginx возвращал
- ошибку 500.
-
- *) Исправление: ошибок во вложенных location'ах; ошибки появились в
- 0.7.1.
-
-
-Изменения в nginx 0.7.10 13.08.2008
-
- *) Исправление: ошибок в директивах addition_types, charset_types,
- gzip_types, ssi_types, sub_filter_types и xslt_types; ошибки
- появились в 0.7.9.
-
- *) Исправление: рекурсивной error_page для 500 ошибки.
-
- *) Исправление: теперь модуль ngx_http_realip_module устанавливает адрес
- не для всего keepalive соединения, а для каждого запроса по этому
- соединению.
-
-
-Изменения в nginx 0.7.9 12.08.2008
-
- *) Изменение: теперь ngx_http_charset_module по умолчанию работает со
- следующими MIME-типами: text/html, text/css, text/xml, text/plain,
- text/vnd.wap.wml, application/x-javascript и application/rss+xml.
-
- *) Добавление: директивы charset_types и addition_types.
-
- *) Добавление: теперь директивы gzip_types, ssi_types и sub_filter_types
- используют хэш.
-
- *) Добавление: модуль ngx_cpp_test_module.
-
- *) Добавление: директива expires поддерживает суточное время.
-
- *) Добавление: улучшения и исправления в модуле ngx_http_xslt_module.
- Спасибо Денису Латыпову и Максиму Дунину.
-
- *) Исправление: директива log_not_found не работала при поиске индексных
- файлов.
-
- *) Исправление: HTTPS-соединения могли зависнуть, если использовались
- методы kqueue, epoll, rtsig или eventport; ошибка появилась в 0.7.7.
-
- *) Исправление: если в директивах server_name, valid_referers и map
- использовалась маска вида "*.domain.tld" и при этом полное имя вида
- "domain.tld" не было описано, то это имя попадало под маску; ошибка
- появилась в 0.3.18.
-
-
-Изменения в nginx 0.7.8 04.08.2008
-
- *) Добавление: модуль ngx_http_xslt_module.
-
- *) Добавление: переменные "$arg_...".
-
- *) Добавление: поддержка directio в Solaris.
- Спасибо Ivan Debnar.
-
- *) Исправление: теперь, если FastCGI-сервер присылает строку "Location"
- в заголовке ответа без строки статуса, то nginx использует код
- статуса 302.
- Спасибо Максиму Дунину.
-
-
-Изменения в nginx 0.7.7 30.07.2008
-
- *) Изменение: теперь ошибка EAGAIN при вызове connect() не считается
- временной.
-
- *) Изменение: значением переменной $ssl_client_cert теперь является
- сертификат, перед каждой строкой которого, кроме первой, вставляется
- символ табуляции; неизменённый сертификат доступен через переменную
- $ssl_client_raw_cert.
-
- *) Добавление: параметр ask директивы ssl_verify_client.
-
- *) Добавление: улучшения в обработке byte-range.
- Спасибо Максиму Дунину.
-
- *) Добавление: директива directio.
- Спасибо Jiang Hong.
-
- *) Добавление: поддержка sendfile() в MacOSX 10.5.
-
- *) Исправление: в MacOSX и Cygwin при проверке location'ов теперь
- делается сравнение без учёта регистра символов; однако, сравнение
- ограничено только однобайтными locale'ями.
-
- *) Исправление: соединения почтового прокси-сервера зависали в режиме
- SSL, если использовались методы select, poll или /dev/poll.
-
- *) Исправление: ошибки при использовании кодировки UTF-8 в
- ngx_http_autoindex_module.
-
-
-Изменения в nginx 0.7.6 07.07.2008
-
- *) Исправление: теперь при использовании переменных в директиве
- access_log всегда проверяется существовании root'а для запроса.
-
- *) Исправление: модуль ngx_http_flv_module не поддерживал несколько
- значений в аргументах запроса.
-
-
-Изменения в nginx 0.7.5 01.07.2008
-
- *) Исправления в поддержке переменных в директиве access_log; ошибки
- появились в 0.7.4.
-
- *) Исправление: nginx не собирался с параметром
- --without-http_gzip_module; ошибка появилась в 0.7.3.
- Спасибо Кириллу Коринскому.
-
- *) Исправление: при совместном использовании sub_filter и SSI ответы
- могли передаваться неверно.
-
-
-Изменения в nginx 0.7.4 30.06.2008
-
- *) Добавление: директива access_log поддерживает переменные.
-
- *) Добавление: директива open_log_file_cache.
-
- *) Добавление: ключ -g.
-
- *) Добавление: поддержка строки "Expect" в заголовке запроса.
-
- *) Исправление: большие включения в SSI могли передавались не полностью.
-
-
-Изменения в nginx 0.7.3 23.06.2008
-
- *) Изменение: MIME-тип для расширения rss изменён на
- "application/rss+xml".
-
- *) Изменение: теперь директива "gzip_vary on" выдаёт строку
- "Vary: Accept-Encoding" в заголовке ответа и для несжатых ответов.
-
- *) Добавление: теперь при использовании протокола "https://" в директиве
- rewrite автоматически делается редирект.
-
- *) Исправление: директива proxy_pass не работала с протоколом HTTPS;
- ошибка появилась в 0.6.9.
-
-
-Изменения в nginx 0.7.2 16.06.2008
-
- *) Добавление: теперь nginx поддерживает шифры с обменом EDH-ключами.
-
- *) Добавление: директива ssl_dhparam.
-
- *) Добавление: переменная $ssl_client_cert.
- Спасибо Manlio Perillo.
-
- *) Исправление: после изменения URI с помощью директивы rewrite nginx не
- искал новый location; ошибка появилась в 0.7.1.
- Спасибо Максиму Дунину.
-
- *) Исправление: nginx не собирался без библиотеки PCRE; ошибка появилась
- в 0.7.1.
-
- *) Исправление: при редиректе запроса к каталогу с добавлением слэша
- nginx не добавлял аргументы из оригинального запроса.
-
-
-Изменения в nginx 0.7.1 26.05.2008
-
- *) Изменение: теперь поиск location'а делается с помощью дерева.
-
- *) Изменение: директива optimize_server_names упразднена в связи с
- появлением директивы server_name_in_redirect.
-
- *) Изменение: некоторые давно устаревшие директивы больше не
- поддерживаются.
-
- *) Изменение: параметр "none" в директиве ssl_session_cache; теперь этот
- параметр используется по умолчанию.
- Спасибо Rob Mueller.
-
- *) Исправление: рабочие процессы могли не реагировать на сигналы
- переконфигурации и ротации логов.
-
- *) Исправление: nginx не собирался на последних Fedora 9 Linux.
- Спасибо Roxis.
-
-
-Изменения в nginx 0.7.0 19.05.2008
-
- *) Изменение: теперь символы 0x00-0x1F, '"' и '\' в access_log
- записываются в виде \xXX.
- Спасибо Максиму Дунину.
-
- *) Изменение: теперь nginx разрешает несколько строк "Host" в заголовке
- запроса.
-
- *) Добавление: директива expires поддерживает флаг modified.
-
- *) Добавление: переменные $uid_got и $uid_set можно использовать на
- любой стадии обработки запроса.
-
- *) Добавление: переменная $hostname.
- Спасибо Андрею Нигматулину.
-
- *) Добавление: поддержка DESTDIR.
- Спасибо Todd A. Fisher и Andras Voroskoi.
-
- *) Исправление: при использовании keepalive на Linux в рабочем процессе
- мог произойти segmentation fault.
-
-
-Изменения в nginx 0.6.31 12.05.2008
-
- *) Исправление: nginx не обрабатывал ответ FastCGI-сервера, если строка
- заголовка ответ была в конце записи FastCGI; ошибка появилась в
- 0.6.2.
- Спасибо Сергею Серову.
-
- *) Исправление: при удалении файла и использовании директивы
- open_file_cache_errors off в рабочем процессе мог произойти
- segmentation fault.
-
-
-Изменения в nginx 0.6.30 29.04.2008
-
- *) Изменение: теперь, если маске, заданной в директиве include, не
- соответствует ни один файл, то nginx не выдаёт ошибку.
-
- *) Добавление: теперь время в директивах можно задавать без пробела,
- например, "1h50m".
-
- *) Исправление: утечек памяти, если директива ssl_verify_client имела
- значение on.
- Спасибо Chavelle Vincent.
-
- *) Исправление: директива sub_filter могла вставлять заменяемый текст в
- вывод.
-
- *) Исправление: директива error_page не воспринимала параметры в
- перенаправляемом URI.
-
- *) Исправление: теперь при сборке с Cygwin nginx всегда открывает файлы
- в бинарном режиме.
-
- *) Исправление: nginx не собирался под OpenBSD; ошибка появилась в
- 0.6.15.
-
-
-Изменения в nginx 0.6.29 18.03.2008
-
- *) Добавление: модуль ngx_google_perftools_module.
-
- *) Исправление: модуль ngx_http_perl_module не собирался на 64-битных
- платформах; ошибка появилась в 0.6.27.
-
-
-Изменения в nginx 0.6.28 13.03.2008
-
- *) Исправление: метод rtsig не собирался; ошибка появилась в 0.6.27.
-
-
-Изменения в nginx 0.6.27 12.03.2008
-
- *) Изменение: теперь на Linux 2.6.18+ по умолчанию не собирается метод
- rtsig.
-
- *) Изменение: теперь при перенаправлении запроса в именованный location
- с помощью директивы error_page метод запроса не изменяется.
-
- *) Добавление: директивы resolver и resolver_timeout в SMTP
- прокси-сервере.
-
- *) Добавление: директива post_action поддерживает именованные
- location'ы.
-
- *) Исправление: при перенаправлении запроса из location'а c обработчиком
- proxy, FastCGI или memcached в именованный location со статическим
- обработчиком в рабочем процессе происходил segmentation fault.
-
- *) Исправление: браузеры не повторяли SSL handshake, если при первом
- handshake не оказалось правильного клиентского сертификата.
- Спасибо Александру Инюхину.
-
- *) Исправление: при перенаправлении ошибок 495-497 с помощью директивы
- error_page без изменения кода ошибки nginx пытался выделить очень
- много памяти.
-
- *) Исправление: утечки памяти в долгоживущих небуфферизированных
- соединениях.
-
- *) Исправление: утечки памяти в resolver'е.
-
- *) Исправление: при перенаправлении запроса из location'а c обработчиком
- proxy в другой location с обработчиком proxy в рабочем процессе
- происходил segmentation fault.
-
- *) Исправление: ошибки в кэшировании переменных $proxy_host и
- $proxy_port.
- Спасибо Сергею Боченкову.
-
- *) Исправление: директива proxy_pass с переменными использовала порт,
- описанной в другой директиве proxy_pass без переменных, но с таким же
- именем хоста.
- Спасибо Сергею Боченкову.
-
- *) Исправление: во время переконфигурации на некоторых 64-битном
- платформах в лог записывался alert "sendmsg() failed (9: Bad file
- descriptor)".
-
- *) Исправление: при повторном использовании в SSI пустого block'а в
- качестве заглушки в рабочем процессе происходил segmentation fault.
-
- *) Исправление: ошибки при копировании части URI, содержащего
- экранированные символы, в аргументы.
-
-
-Изменения в nginx 0.6.26 11.02.2008
-
- *) Исправление: директивы proxy_store и fastcgi_store не проверяли длину
- ответа.
-
- *) Исправление: при использовании большого значения в директиве expires
- в рабочем процессе происходил segmentation fault.
- Спасибо Joaquin Cuenca Abela.
-
- *) Исправление: nginx неверно определял длину строки кэша на Pentium 4.
- Спасибо Геннадию Махомеду.
-
- *) Исправление: в проксированных подзапросах и подзапросах к
- FastCGI-серверу вместо метода GET использовался оригинальный метод
- клиента.
-
- *) Исправление: утечки сокетов в режиме HTTPS при использовании
- отложенного accept'а.
- Спасибо Ben Maurer.
-
- *) Исправление: nginx выдавал ошибочное сообщение "SSL_shutdown() failed
- (SSL: )"; ошибка появилась в 0.6.23.
-
- *) Исправление: при использовании HTTPS запросы могли завершаться с
- ошибкой "bad write retry"; ошибка появилась в 0.6.23.
-
-
-Изменения в nginx 0.6.25 08.01.2008
-
- *) Изменение: вместо специального параметра "*" в директиве server_name
- теперь используется директива server_name_in_redirect.
-
- *) Изменение: в качестве основного имени в директиве server_name теперь
- можно использовать имена с масками и регулярными выражениями.
-
- *) Изменение: директива satisfy_any заменена директивой satisfy.
-
- *) Изменение: после переконфигурации старые рабочие процесс могли сильно
- нагружать процессор при запуске под Linux OpenVZ.
-
- *) Добавление: директива min_delete_depth.
-
- *) Исправление: методы COPY и MOVE не работали с одиночными файлами.
-
- *) Исправление: модуль ngx_http_gzip_static_module не позволял работать
- модулю ngx_http_dav_module; ошибка появилась в 0.6.23.
-
- *) Исправление: утечки сокетов в режиме HTTPS при использовании
- отложенного accept'а.
- Спасибо Ben Maurer.
-
- *) Исправление: nginx не собирался без библиотеки PCRE; ошибка появилась
- в 0.6.23.
-
-
-Изменения в nginx 0.6.24 27.12.2007
-
- *) Исправление: при использовании HTTPS в рабочем процессе мог произойти
- segmentation fault; ошибка появилась в 0.6.23.
-
-
-Изменения в nginx 0.6.23 27.12.2007
-
- *) Изменение: параметр "off" в директиве ssl_session_cache; теперь этот
- параметр используется по умолчанию.
-
- *) Изменение: директива open_file_cache_retest переименована в
- open_file_cache_valid.
-
- *) Добавление: директива open_file_cache_min_uses.
-
- *) Добавление: модуль ngx_http_gzip_static_module.
-
- *) Добавление: директива gzip_disable.
-
- *) Добавление: директиву memcached_pass можно использовать внутри блока
- if.
-
- *) Исправление: если внутри одного location'а использовались директивы
- "memcached_pass" и "if", то в рабочем процессе происходил
- segmentation fault.
-
- *) Исправление: если при использовании директивы satisfy_any on" были
- заданы директивы не всех модулей доступа, то заданные директивы не
- проверялись.
-
- *) Исправление: параметры, заданные регулярным выражением в директиве
- valid_referers, не наследовалась с предыдущего уровня.
-
- *) Исправление: директива post_action не работала, если запрос
- завершался с кодом 499.
-
- *) Исправление: оптимизация использования 16K буфера для SSL-соединения.
- Спасибо Ben Maurer.
-
- *) Исправление: STARTTLS в режиме SMTP не работал.
- Спасибо Олегу Мотиенко.
-
- *) Исправление: при использовании HTTPS запросы могли завершаться с
- ошибкой "bad write retry"; ошибка появилась в 0.5.13.
-
-
-Изменения в nginx 0.6.22 19.12.2007
-
- *) Изменение: теперь все методы модуля ngx_http_perl_module возвращают
- значения, скопированные в память, выделенную perl'ом.
-
- *) Исправление: если nginx был собран с модулем ngx_http_perl_module,
- использовался perl до версии 5.8.6 и perl поддерживал потоки, то во
- время переконфигурации основной процесс аварийно выходил; ошибка
- появилась в 0.5.9.
- Спасибо Борису Жмурову.
-
- *) Исправление: в методы модуля ngx_http_perl_module могли передаваться
- неверные результаты выделения в регулярных выражениях.
-
- *) Исправление: если метод $r->has_request_body() вызывался для запроса,
- у которого небольшое тело запроса было уже полностью получено, то в
- рабочем процессе происходил segmentation fault.
-
- *) Исправление: large_client_header_buffers не освобождались перед
- переходом в состояние keep-alive.
- Спасибо Олександру Штепе.
-
- *) Исправление: в переменной $upstream_addr не записывался последний
- адрес; ошибка появилась в 0.6.18.
-
- *) Исправление: директива fastcgi_catch_stderr не возвращала ошибку;
- теперь она возвращает ошибку 502, которую можно направить на
- следующий сервер с помощью "fastcgi_next_upstream invalid_header".
-
- *) Исправление: при использовании директивы fastcgi_catch_stderr в
- основном процессе происходил segmentation fault; ошибка появилась в
- 0.6.10.
- Спасибо Manlio Perillo.
-
-
-Изменения в nginx 0.6.21 03.12.2007
-
- *) Изменение: если в значениях переменных директивы proxy_pass
- используются только IP-адреса, то указывать resolver не нужно.
-
- *) Исправление: при использовании директивы proxy_pass c URI-частью в
- рабочем процессе мог произойти segmentation fault; ошибка появилась в
- 0.6.19.
-
- *) Исправление: если resolver использовался на платформах, не
- поддерживающих метод kqueue, то nginx выдавал alert "name is out of
- response".
- Спасибо Андрею Нигматулину.
-
- *) Исправление: При использовании переменной $server_protocol в
- FastCGI-параметрах и запросе, длина которого была близка к значению
- директивы client_header_buffer_size, nginx выдавал alert "fastcgi:
- the request record is too big".
-
- *) Исправление: при обычном запросе версии HTTP/0.9 к HTTPS серверу
- nginx возвращал обычный ответ.
-
-
-Изменения в nginx 0.6.20 28.11.2007
-
- *) Исправление: при использовании директивы proxy_pass c URI-частью в
- рабочем процессе мог произойти segmentation fault; ошибка появилась в
- 0.6.19.
-
-
-Изменения в nginx 0.6.19 27.11.2007
-
- *) Исправление: версия 0.6.18 не собиралась.
-
-
-Изменения в nginx 0.6.18 27.11.2007
-
- *) Изменение: теперь модуль ngx_http_userid_module в поле куки с номером
- процесса добавляет микросекунды на время старта.
-
- *) Изменение: в error_log теперь записывается полная строка запроса
- вместо только URI.
-
- *) Добавление: директива proxy_pass поддерживает переменные.
-
- *) Добавление: директивы resolver и resolver_timeout.
-
- *) Добавление: теперь директива "add_header last-modified ''" удаляет в
- заголовке ответа строку "Last-Modified".
-
- *) Исправление: директива limit_rate не позволяла передавать на полной
- скорости, даже если был указан очень большой лимит.
-
-
-Изменения в nginx 0.6.17 15.11.2007
-
- *) Добавление: поддержка строки "If-Range" в заголовке запроса.
- Спасибо Александру Инюхину.
-
- *) Исправление: при использовании директивы msie_refresh повторно
- экранировались уже экранированные символы; ошибка появилась в 0.6.4.
-
- *) Исправление: директива autoindex не работала при использовании "alias
- /".
-
- *) Исправление: при использовании подзапросов в рабочем процессе мог
- произойти segmentation fault.
-
- *) Исправление: при использовании SSL и gzip большие ответы могли
- передаваться не полностью.
-
- *) Исправление: если ответ проксированного сервера был версии HTTP/0.9,
- то переменная $status была равна 0.
-
-
-Изменения в nginx 0.6.16 29.10.2007
-
- *) Изменение: теперь на Linux используется uname(2) вместо procfs.
- Спасибо Илье Новикову.
-
- *) Исправление: если в директиве error_page использовался символ "?", то
- он экранировался при проксировании запроса; ошибка появилась в
- 0.6.11.
-
- *) Исправление: совместимость с mget.
-
-
-Изменения в nginx 0.6.15 22.10.2007
-
- *) Добавление: совместимость с Cygwin.
- Спасибо Владимиру Кутакову.
-
- *) Добавление: директива merge_slashes.
-
- *) Добавление: директива gzip_vary.
-
- *) Добавление: директива server_tokens.
-
- *) Исправление: nginx не раскодировал URI в команде SSI include.
-
- *) Исправление: при использовании переменной в директивах charset или
- source_charset на старте или во время переконфигурации происходил
- segmentation fault,
-
- *) Исправление: nginx возвращал ошибку 400 на запросы вида
- "GET http://www.domain.com HTTP/1.0".
- Спасибо James Oakley.
-
- *) Исправление: после перенаправления запроса с телом запроса с помощью
- директивы error_page nginx пытался снова прочитать тело запроса;
- ошибка появилась в 0.6.7.
-
- *) Исправление: в рабочем процессе происходил segmentation fault, если у
- сервера, обрабатывающему запрос, не был явно определён server_name;
- ошибка появилась в 0.6.7.
-
-
-Изменения в nginx 0.6.14 15.10.2007
-
- *) Изменение: теперь по умолчанию команда SSI echo использует
- кодирование entity.
-
- *) Добавление: параметр encoding в команде SSI echo.
-
- *) Добавление: директиву access_log можно использовать внутри блока
- limit_except.
-
- *) Исправление: если все сервера апстрима оказывались недоступными, то
- до восстановления работоспособности у всех серверов вес становился
- равным одному; ошибка появилась в 0.6.6.
-
- *) Исправление: при использовании переменных $date_local и $date_gmt вне
- модуля ngx_http_ssi_filter_module в рабочем процессе происходил
- segmentation fault.
-
- *) Исправление: при использовании включённом отладочном логе в рабочем
- процессе мог произойти segmentation fault.
- Спасибо Андрею Нигматулину.
-
- *) Исправление: ngx_http_memcached_module не устанавливал
- $upstream_response_time.
- Спасибо Максиму Дунину.
-
- *) Исправление: рабочий процесс мог зациклиться при использовании
- memcached.
-
- *) Исправление: nginx распознавал параметры "close" и "keep-alive" в
- строке "Connection" в заголовке запроса только, если они были в
- нижнем регистре; ошибка появилась в 0.6.11.
-
- *) Исправление: sub_filter не работал с пустой строкой замены.
-
- *) Исправление: в парсинге sub_filter.
-
-
-Изменения в nginx 0.6.13 24.09.2007
-
- *) Исправление: nginx не закрывал файл каталога для запроса HEAD, если
- использовался autoindex
- Спасибо Arkadiusz Patyk.
-
-
-Изменения в nginx 0.6.12 21.09.2007
-
- *) Изменение: почтовый прокси-сервер разделён на три модуля: pop3, imap
- и smtp.
-
- *) Добавление: параметры конфигурации --without-mail_pop3_module,
- --without-mail_imap_module и --without-mail_smtp_module.
-
- *) Добавление: директивы smtp_greeting_delay и smtp_client_buffer модуля
- ngx_mail_smtp_module.
-
- *) Исправление: wildcard в конце имени сервера не работали; ошибка
- появилась в 0.6.9.
-
- *) Исправление: при использовании разделяемой библиотеки PCRE,
- расположенной в нестандартном месте, nginx не запускался на Solaris.
-
- *) Исправление: директивы proxy_hide_header и fastcgi_hide_header не
- скрывали строки заголовка ответа с именем больше 32 символов.
- Спасибо Manlio Perillo.
-
-
-Изменения в nginx 0.6.11 11.09.2007
-
- *) Исправление: счётчик активных соединений всегда рос при использовании
- почтового прокси-сервера.
-
- *) Исправление: если бэкенд возвращал только заголовок ответа при
- небуферизированном проксировании, то nginx закрывал соединение с
- бэкендом по таймауту.
-
- *) Исправление: nginx не поддерживал несколько строк "Connection" в
- заголовке запроса.
-
- *) Исправление: если в сервере апстрима был задан max_fails, то после
- первой же неудачной попытки вес сервера навсегда становился равным
- одному; ошибка появилась в 0.6.6.
-
-
-Изменения в nginx 0.6.10 03.09.2007
-
- *) Добавление: директивы open_file_cache, open_file_cache_retest и
- open_file_cache_errors.
-
- *) Исправление: утечки сокетов; ошибка появилась в 0.6.7.
-
- *) Исправление: В строку заголовка ответа "Content-Type", указанную в
- методе $r->send_http_header(), не добавлялась кодировка, указанная в
- директиве charset.
-
- *) Исправление: при использовании метода /dev/poll в рабочем процессе
- мог произойти segmentation fault.
-
-
-Изменения в nginx 0.6.9 28.08.2007
-
- *) Исправление: рабочий процесс мог зациклиться при использовании
- протокола HTTPS; ошибка появилась в 0.6.7.
-
- *) Исправление: если сервер слушал на двух адресах или портах, то nginx
- не запускался при использовании wildcard в конце имени сервера.
-
- *) Исправление: директива ip_hash могла неверно помечать сервера как
- нерабочие.
-
- *) Исправление: nginx не собирался на amd64; ошибка появилась в 0.6.8.
-
-
-Изменения в nginx 0.6.8 20.08.2007
-
- *) Изменение: теперь nginx пытается установить директивы
- worker_priority, worker_rlimit_nofile, worker_rlimit_core,
- worker_rlimit_sigpending без привилегий root'а.
-
- *) Изменение: теперь nginx экранирует символы пробела и "%" при передаче
- запроса серверу аутентификации почтового прокси-сервера.
-
- *) Изменение: теперь nginx экранирует символ "%" в переменной
- $memcached_key.
-
- *) Исправление: при указании относительного пути к конфигурационному
- файлу в качестве параметра ключа -c nginx определял путь относительно
- конфигурационного префикса; ошибка появилась в 0.6.6.
-
- *) Исправление: nginx не работал на FreeBSD/sparc64.
-
-
-Изменения в nginx 0.6.7 15.08.2007
-
- *) Изменение: теперь пути, указанные в директивах include,
- auth_basic_user_file, perl_modules, ssl_certificate,
- ssl_certificate_key и ssl_client_certificate, определяются
- относительно каталога конфигурационного файла nginx.conf, а не
- относительно префикса.
-
- *) Изменение: параметр --sysconfdir=PATH в configure упразднён.
-
- *) Изменение: для обновления на лету версий 0.1.x создан специальный
- сценарий make upgrade1.
-
- *) Добавление: директивы server_name и valid_referers поддерживают
- регулярные выражения.
-
- *) Добавление: директива server в блоке upstream поддерживает параметр
- backup.
-
- *) Добавление: модуль ngx_http_perl_module поддерживает метод
- $r->discard_request_body.
-
- *) Добавление: директива "add_header Last-Modified ..." меняет строку
- "Last-Modified" в заголовке ответа.
-
- *) Исправление: если на запрос с телом возвращался ответ с кодом HTTP
- отличным от 200, и после этого запроса соединение переходило в
- состояние keep-alive, то на следующий запрос nginx возвращал 400.
-
- *) Исправление: если в директиве auth_http был задан неправильный адрес,
- то в рабочем процессе происходил segmentation fault.
-
- *) Исправление: теперь по умолчанию nginx использует значение 511 для
- listen backlog на всех платформах, кроме FreeBSD.
- Спасибо Jiang Hong.
-
- *) Исправление: рабочий процесс мог зациклиться, если server в блоке
- upstream был помечен как down; ошибка появилась в 0.6.6.
-
- *) Исправление: sendfilev() в Solaris теперь не используется при
- передаче тела запроса FastCGI-серверу через unix domain сокет.
-
-
-Изменения в nginx 0.6.6 30.07.2007
-
- *) Добавление: параметр --sysconfdir=PATH в configure.
-
- *) Добавление: именованные location'ы.
-
- *) Добавление: переменную $args можно устанавливать с помощью set.
-
- *) Добавление: переменная $is_args.
-
- *) Исправление: равномерное распределение запросов к апстримам с
- большими весами.
-
- *) Исправление: если клиент в почтовом прокси-сервере закрывал
- соединение, то nginx мог не закрывать соединение с бэкендом.
-
- *) Исправление: при использовании одного хоста в качестве бэкендов для
- протоколов HTTP и HTTPS без явного указания портов, nginx использовал
- только один порт - 80 или 443.
-
- *) Исправление: nginx не собирался на Solaris/amd64 Sun Studio 11 и
- более ранними версиями; ошибка появилась в 0.6.4.
-
-
-Изменения в nginx 0.6.5 23.07.2007
-
- *) Добавление: переменная $nginx_version.
- Спасибо Николаю Гречуху.
-
- *) Добавление: почтовый прокси-сервер поддерживает AUTHENTICATE в режиме
- IMAP.
- Спасибо Максиму Дунину.
-
- *) Добавление: почтовый прокси-сервер поддерживает STARTTLS в режиме
- SMTP.
- Спасибо Максиму Дунину.
-
- *) Исправление: теперь nginx экранирует пробел в переменной
- $memcached_key.
-
- *) Исправление: nginx неправильно собирался Sun Studio на Solaris/amd64.
- Спасибо Jiang Hong.
-
- *) Исправление: незначительных потенциальных ошибок.
- Спасибо Coverity's Scan.
-
-
-Изменения в nginx 0.6.4 17.07.2007
-
- *) Безопасность: при использовании директивы msie_refresh был возможен
- XSS.
- Спасибо Максиму Богуку.
-
- *) Изменение: директивы proxy_store и fastcgi_store изменены.
-
- *) Добавление: директивы proxy_store_access и fastcgi_store_access.
-
- *) Исправление: nginx не работал на Solaris/sparc64, если был собран Sun
- Studio.
- Спасибо Андрею Нигматулину.
-
- *) Изменение: обход ошибки в Sun Studio 12.
- Спасибо Jiang Hong.
-
-
-Изменения в nginx 0.6.3 12.07.2007
-
- *) Добавление: директивы proxy_store и fastcgi_store.
-
- *) Исправление: при использовании директивы auth_http_header в рабочем
- процессе мог произойти segmentation fault.
- Спасибо Максиму Дунину.
-
- *) Исправление: если использовался метод аутентификации CRAM-MD5, но он
- не был разрешён, то в рабочем процессе происходил segmentation fault.
-
- *) Исправление: при использовании протокола HTTPS в директиве proxy_pass
- в рабочем процессе мог произойти segmentation fault.
-
- *) Исправление: в рабочем процессе мог произойти segmentation fault,
- если использовался метод eventport.
-
- *) Исправление: директивы proxy_ignore_client_abort и
- fastcgi_ignore_client_abort не работали; ошибка появилась в 0.5.13.
-
-
-Изменения в nginx 0.6.2 09.07.2007
-
- *) Исправление: если заголовок ответа был разделён в FastCGI-записях, то
- nginx передавал клиенту мусор в таких заголовках.
-
-
-Изменения в nginx 0.6.1 17.06.2007
-
- *) Исправление: в парсинге SSI.
-
- *) Исправление: при использовании удалённого подзапроса в SSI
- последующий подзапрос локального файла мог отдаваться клиенту в
- неверном порядке.
-
- *) Исправление: большие включения в SSI, сохранённые во временные файлы,
- передавались не полностью.
-
- *) Исправление: значение perl'овой переменной $$ модуля
- ngx_http_perl_module было равно номеру главного процесса.
-
-
-Изменения в nginx 0.6.0 14.06.2007
-
- *) Добавление: директивы "server_name", "map", and "valid_referers"
- поддерживают маски вида "www.example.*".
-
-
-Изменения в nginx 0.5.25 11.06.2007
-
- *) Исправление: nginx не собирался с параметром
- --without-http_rewrite_module; ошибка появилась в 0.5.24.
-
-
-Изменения в nginx 0.5.24 06.06.2007
-
- *) Безопасность: директива ssl_verify_client не работала, если запрос
- выполнялся по протоколу HTTP/0.9.
-
- *) Исправление: при использовании сжатия часть ответа могла передаваться
- несжатой; ошибка появилась в 0.5.23.
-
-
-Изменения в nginx 0.5.23 04.06.2007
-
- *) Добавление: модуль ngx_http_ssl_module поддерживает расширение TLS
- Server Name Indication.
-
- *) Добавление: директива fastcgi_catch_stderr.
- Спасибо Николаю Гречуху, проект OWOX.
-
- *) Исправление: на Линуксе в основном процессе происходил segmentation
- fault, если два виртуальных сервера должны bind()ится к
- пересекающимся портам.
-
- *) Исправление: если nginx был собран с модулем ngx_http_perl_module и
- perl поддерживал потоки, то во время второй переконфигурации
- выдавались ошибки "panic: MUTEX_LOCK" и "perl_parse() failed".
-
- *) Исправление: в использовании протокола HTTPS в директиве proxy_pass.
-
-
-Изменения в nginx 0.5.22 29.05.2007
-
- *) Исправление: большое тело запроса могло не передаваться бэкенду;
- ошибка появилась в 0.5.21.
-
-
-Изменения в nginx 0.5.21 28.05.2007
-
- *) Исправление: если внутри сервера описано больше примерно десяти
- location'ов, то location'ы, заданные с помощью регулярного выражения,
- могли выполняться не в том, порядке, в каком они описаны.
-
- *) Исправление: на 64-битной платформе рабочий процесс мог зациклиться,
- если 33-тий по счёту или последующий бэкенд упал.
- Спасибо Антону Поварову.
-
- *) Исправление: при использовании библиотеки PCRE на Solaris/sparc64 мог
- произойти bus error.
- Спасибо Андрею Нигматулину.
-
- *) Исправление: в использовании протокола HTTPS в директиве proxy_pass.
-
-
-Изменения в nginx 0.5.20 07.05.2007
-
- *) Добавление: директива sendfile_max_chunk.
-
- *) Добавление: переменные "$http_...", "$sent_http_..." и
- "$upstream_http_..." можно менять директивой set.
-
- *) Исправление: при использовании SSI-команды 'if expr="$var = /"' в
- рабочем процессе мог произойти segmentation fault.
-
- *) Исправление: завершающая строка multipart range ответа передавалась
- неверно.
- Спасибо Evan Miller.
-
- *) Исправление: nginx не работал на Solaris/sparc64, если был собран Sun
- Studio.
- Спасибо Андрею Нигматулину.
-
- *) Исправление: модуль ngx_http_perl_module не собирался make в Solaris.
- Спасибо Андрею Нигматулину.
-
-
-Изменения в nginx 0.5.19 24.04.2007
-
- *) Изменение: значение переменной $request_time теперь записывается с
- точностью до миллисекунд.
-
- *) Изменение: метод $r->rflush в модуле ngx_http_perl_module
- переименован в $r->flush.
-
- *) Добавление: переменная $upstream_addr.
-
- *) Добавление: директивы proxy_headers_hash_max_size и
- proxy_headers_hash_bucket_size.
- Спасибо Володымыру Костырко.
-
- *) Исправление: при использовании sendfile и limit_rate на 64-битных
- платформах нельзя было передавать файлы больше 2G.
-
- *) Исправление: при использовании sendfile на 64-битном Linux нельзя
- было передавать файлы больше 2G.
-
-
-Изменения в nginx 0.5.18 19.04.2007
-
- *) Добавление: модуль ngx_http_sub_filter_module.
-
- *) Добавление: переменные "$upstream_http_...".
-
- *) Добавление: теперь переменные $upstream_status и
- $upstream_response_time содержат данные о всех обращениях к
- апстримам, сделанным до X-Accel-Redirect.
-
- *) Исправление: если nginx был собран с модулем ngx_http_perl_module и
- perl не поддерживал multiplicity, то после первой переконфигурации и
- после получения любого сигнала в основном процессе происходил
- segmentation fault; ошибка появилась в 0.5.9.
-
- *) Исправление: если perl не поддерживал multiplicity, то после
- переконфигурации перловый код не работал; ошибка появилась в 0.3.38.
-
-
-Изменения в nginx 0.5.17 02.04.2007
-
- *) Изменение: теперь nginx для метода TRACE всегда возвращает код 405.
-
- *) Добавление: теперь nginx поддерживает директиву include внутри блока
- types.
-
- *) Исправление: использование переменной $document_root в директиве root
- и alias запрещено: оно вызывало рекурсивное переполнение стека.
-
- *) Исправление: в использовании протокола HTTPS в директиве proxy_pass.
-
- *) Исправление: в некоторых случаях некэшируемые переменные (такие, как
- $uri) возвращали старое закэшированное значение.
-
-
-Изменения в nginx 0.5.16 26.03.2007
-
- *) Исправление: в качестве ключа для хэша в директиве ip_hash не
- использовалась сеть класса С.
- Спасибо Павлу Ярковому.
-
- *) Исправление: если в строке "Content-Type" в заголовке ответа бэкенда
- был указан charset и строка завершалась символом ";", то в рабочем
- процессе мог произойти segmentation fault; ошибка появилась в 0.3.50.
-
- *) Исправление: ошибки "[alert] zero size buf" при работе с
- FastCGI-сервером, если тело запроса, записанное во временный файл,
- было кратно 32K.
-
- *) Исправление: nginx не собирался на Solaris без параметра
- --with-debug; ошибка появилась в 0.5.15.
-
-
-Изменения в nginx 0.5.15 19.03.2007
-
- *) Добавление: почтовый прокси-сервер поддерживает аутентифицированное
- SMTP-проксирование и директивы smtp_auth, smtp_capablities и xclient.
- Спасибо Антону Южанинову и Максиму Дунину.
-
- *) Добавление: теперь keep-alive соединения закрываются сразу же по
- получении сигнала переконфигурации.
-
- *) Изменение: директивы imap и auth переименованы соответственно в mail
- и pop3_auth.
-
- *) Исправление: если использовался метод аутентификации CRAM-MD5 и не
- был разрешён метод APOP, то в рабочем процессе происходил
- segmentation fault.
-
- *) Исправление: при использовании директивы starttls only в протоколе
- POP3 nginx разрешал аутентификацию без перехода в режим SSL.
-
- *) Исправление: рабочие процессы не выходили после переконфигурации и не
- переоткрывали логи, если использовался метод eventport.
-
- *) Исправление: при использовании директивы ip_hash рабочий процесс мог
- зациклиться.
-
- *) Исправление: теперь nginx не пишет в лог некоторые alert'ы, если
- используются методы eventport или /dev/poll.
-
-
-Изменения в nginx 0.5.14 23.02.2007
-
- *) Исправление: nginx игнорировал лишние закрывающие скобки "}" в конце
- конфигурационного файла.
-
-
-Изменения в nginx 0.5.13 19.02.2007
-
- *) Добавление: методы COPY и MOVE.
-
- *) Исправление: модуль ngx_http_realip_module устанавливал мусор для
- запросов, переданных по keep-alive соединению.
-
- *) Исправление: nginx не работал на 64-битном big-endian Linux.
- Спасибо Андрею Нигматулину.
-
- *) Исправление: при получении слишком длинной команды IMAP/POP3-прокси
- теперь сразу закрывает соединение, а не по таймауту.
-
- *) Исправление: если при использовании метода epoll клиент закрывал
- преждевременно соединение со своей стороны, то nginx закрывал это
- соединение только по истечении таймаута на передачу.
-
- *) Исправление: nginx не собирался на платформах, отличных от i386,
- amd64, sparc и ppc; ошибка появилась в 0.5.8.
-
-
-Изменения в nginx 0.5.12 12.02.2007
-
- *) Исправление: nginx не собирался на платформах, отличных от i386,
- amd64, sparc и ppc; ошибка появилась в 0.5.8.
-
- *) Исправление: при использовании временных файлов в время работы с
- FastCGI-сервером в рабочем процессе мог произойти segmentation fault;
- ошибка появилась в 0.5.8.
-
- *) Исправление: если переменная $fastcgi_script_name записывалась в лог,
- то в рабочем процессе мог произойти segmentation fault.
-
- *) Исправление: ngx_http_perl_module не собирался на Solaris.
-
-
-Изменения в nginx 0.5.11 05.02.2007
-
- *) Добавление: теперь configure определяет библиотеку PCRE в MacPorts.
- Спасибо Chris McGrath.
-
- *) Исправление: ответ был неверным, если запрашивалось несколько
- диапазонов; ошибка появилась в 0.5.6.
-
- *) Исправление: директива create_full_put_path не могла создавать
- промежуточные каталоги, если не была установлена директива
- dav_access.
- Спасибо Evan Miller.
-
- *) Исправление: вместо кодов ошибок "400" и "408" в access_log мог
- записываться код "0".
-
- *) Исправление: при сборке с оптимизацией -O2 в рабочем процессе мог
- произойти segmentation fault.
-
-
-Изменения в nginx 0.5.10 26.01.2007
-
- *) Исправление: во время обновления исполняемого файла новый процесс не
- наследовал слушающие сокеты; ошибка появилась в 0.5.9.
-
- *) Исправление: при сборке с оптимизацией -O2 в рабочем процессе мог
- произойти segmentation fault; ошибка появилась в 0.5.1.
-
-
-Изменения в nginx 0.5.9 25.01.2007
-
- *) Изменение: модуль ngx_http_memcached_module теперь в качестве ключа
- использует значение переменной $memcached_key.
-
- *) Добавление: переменная $memcached_key.
-
- *) Добавление: параметр clean в директиве client_body_in_file_only.
-
- *) Добавление: директива env.
-
- *) Добавление: директива sendfile работает внутри блока if.
-
- *) Добавление: теперь при ошибке записи в access_log nginx записывает
- сообщение в error_log, но не чаще одного раза в минуту.
-
- *) Исправление: директива "access_log off" не всегда запрещала запись в
- лог.
-
-
-Изменения в nginx 0.5.8 19.01.2007
-
- *) Исправление: если использовалась директива
- "client_body_in_file_only on" и тело запроса было небольшое, то мог
- произойти segmentation fault.
-
- *) Исправление: происходил segmentation fault, если использовались
- директивы "client_body_in_file_only on" и
- "proxy_pass_request_body off" или "fastcgi_pass_request_body off", и
- делался переход к следующему бэкенду.
-
- *) Исправление: если при использовании директивы "proxy_buffering off"
- соединение с клиентом было неактивно, то оно закрывалось по таймауту,
- заданному директивой send_timeout; ошибка появилась в 0.4.7.
-
- *) Исправление: если при использовании метода epoll клиент закрывал
- преждевременно соединение со своей стороны, то nginx закрывал это
- соединение только по истечении таймаута на передачу.
-
- *) Исправление: ошибки "[alert] zero size buf" при работе с
- FastCGI-сервером.
-
- *) Исправление ошибок в директиве limit_zone.
-
-
-Изменения в nginx 0.5.7 15.01.2007
-
- *) Добавление: оптимизация использования памяти в ssl_session_cache.
-
- *) Исправление ошибок в директивах ssl_session_cache и limit_zone.
-
- *) Исправление: на старте или во время переконфигурации происходил
- segmentation fault, если директивы ssl_session_cache или limit_zone
- использовались на 64-битных платформах.
-
- *) Исправление: при использовании директив add_before_body или
- add_after_body происходил segmentation fault, если в заголовке ответа
- нет строки "Content-Type".
-
- *) Исправление: библиотека OpenSSL всегда собиралась с поддержкой
- потоков.
- Спасибо Дену Иванову.
-
- *) Исправление: совместимость библиотеки PCRE-6.5+ и компилятора icc.
-
-
-Изменения в nginx 0.5.6 09.01.2007
-
- *) Изменение: теперь модуль ngx_http_index_module игнорирует все методы,
- кроме GET, HEAD и POST.
-
- *) Добавление: модуль ngx_http_limit_zone_module.
-
- *) Добавление: переменная $binary_remote_addr.
-
- *) Добавление: директивы ssl_session_cache модулей ngx_http_ssl_module и
- ngx_imap_ssl_module.
-
- *) Добавление: метод DELETE поддерживает рекурсивное удаление.
-
- *) Исправление: при использовании $r->sendfile() byte-ranges
- передавались неверно.
-
-
-Изменения в nginx 0.5.5 24.12.2006
-
- *) Изменение: ключ -v больше не выводит информацию о компиляторе.
-
- *) Добавление: ключ -V.
-
- *) Добавление: директива worker_rlimit_core поддерживает указание
- размера в K, M и G.
-
- *) Исправление: модуль nginx.pm теперь может устанавливаться
- непривилегированным пользователем.
-
- *) Исправление: при использовании методов $r->request_body или
- $r->request_body_file мог произойти segmentation fault.
-
- *) Исправление: ошибок, специфичных для платформы ppc.
-
-
-Изменения в nginx 0.5.4 15.12.2006
-
- *) Добавление: директиву perl можно использовать внутри блока
- limit_except.
-
- *) Исправление: модуль ngx_http_dav_module требовал строку "Date" в
- заголовке запроса для метода DELETE.
-
- *) Исправление: при использовании одного параметра в директиве
- dav_access nginx мог сообщить об ошибке в конфигурации.
-
- *) Исправление: при использовании переменной $host мог произойти
- segmentation fault; ошибка появилась в 0.4.14.
-
-
-Изменения в nginx 0.5.3 13.12.2006
-
- *) Добавление: модуль ngx_http_perl_module поддерживает методы
- $r->status, $r->log_error и $r->sleep.
-
- *) Добавление: метод $r->variable поддерживает переменные, неописанные в
- конфигурации nginx'а.
-
- *) Исправление: метод $r->has_request_body не работал.
-
-
-Изменения в nginx 0.5.2 11.12.2006
-
- *) Исправление: если в директивах proxy_pass использовалось имя,
- указанное в upstream, то nginx пытался найти IP-адрес этого имени;
- ошибка появилась в 0.5.1.
-
-
-Изменения в nginx 0.5.1 11.12.2006
-
- *) Исправление: директива post_action могла не работать после неудачного
- завершения запроса.
-
- *) Изменение: обход ошибки в Eudora для Mac; ошибка появилась в 0.4.11.
- Спасибо Bron Gondwana.
-
- *) Исправление: при указании в директиве fastcgi_pass имени описанного
- upstream'а выдавалось сообщение "no port in upstream"; ошибка
- появилась в 0.5.0.
-
- *) Исправление: если в директивах proxy_pass и fastcgi_pass
- использовались одинаковых имена серверов, но с разными портами, то
- эти директивы использовали первый описанный порт; ошибка появилась в
- 0.5.0.
-
- *) Исправление: если в директивах proxy_pass и fastcgi_pass
- использовались unix domain сокеты, то эти директивы использовали
- первый описанный сокет; ошибка появилась в 0.5.0.
-
- *) Исправление: ngx_http_auth_basic_module игнорировал пользователя,
- если он был указан в последней строке файла паролей и после пароля не
- было перевода строки, возврата каретки или символа ":".
-
- *) Исправление: переменная $upstream_response_time могла быть равна
- "0.000", хотя время обработки было больше 1 миллисекунды.
-
-
-Изменения в nginx 0.5.0 04.12.2006
-
- *) Изменение: параметры в виде "%name" в директиве log_format больше не
- поддерживаются.
-
- *) Изменение: директивы proxy_upstream_max_fails,
- proxy_upstream_fail_timeout, fastcgi_upstream_max_fails, и
- fastcgi_upstream_fail_timeout, memcached_upstream_max_fails и
- memcached_upstream_fail_timeout больше не поддерживаются.
-
- *) Добавление: директива server в блоке upstream поддерживает параметры
- max_fails, fail_timeout и down.
-
- *) Добавление: директива ip_hash в блоке upstream.
-
- *) Добавление: статус WAIT в строке "Auth-Status" в заголовка ответа
- сервера аутентификации IMAP/POP3 прокси.
-
- *) Исправление: nginx не собирался на 64-битных платформах; ошибка
- появилась в 0.4.14.
-
-
-Изменения в nginx 0.4.14 27.11.2006
-
- *) Добавление: директива proxy_pass_error_message в IMAP/POP3 прокси.
-
- *) Добавление: теперь configure определяет библиотеку PCRE на FreeBSD,
- Linux и NetBSD.
-
- *) Исправление: ngx_http_perl_module не работал с перлом, собранным с
- поддержкой потоков; ошибка появилась в 0.3.38.
-
- *) Исправление: ngx_http_perl_module не работал корректно, если перл
- вызывался рекурсивно.
-
- *) Исправление: nginx игнорировал имя сервера в строке запроса.
-
- *) Исправление: если FastCGI сервер передавал много в stderr, то рабочий
- процесс мог зациклиться.
-
- *) Исправление: при изменении системного времени переменная
- $upstream_response_time могла быть отрицательной.
-
- *) Исправление: при использовании POP3 серверу аутентификации IMAP/POP3
- прокси не передавался параметр Auth-Login-Attempt.
-
- *) Исправление: при ошибке соединения с сервером аутентификации
- IMAP/POP3 прокси мог произойти segmentation fault.
-
-
-Изменения в nginx 0.4.13 15.11.2006
-
- *) Добавление: директиву proxy_pass можно использовать внутри блока
- limit_except.
-
- *) Добавление: директива limit_except поддерживает все WebDAV методы.
-
- *) Исправление: при использовании директивы add_before_body без
- директивы add_after_body ответ передавался не полностью.
-
- *) Исправление: большое тело запроса не принималось, если использовались
- метод epoll и deferred accept().
-
- *) Исправление: для ответов модуля ngx_http_autoindex_module не
- выставлялась кодировка; ошибка появилась в 0.3.50.
-
- *) Исправление: ошибки "[alert] zero size buf" при работе с
- FastCGI-сервером;
-
- *) Исправление: параметр конфигурации --group= игнорировался.
- Спасибо Thomas Moschny.
-
- *) Исправление: 50-й подзапрос в SSI ответе не работал; ошибка появилась
- в 0.3.50.
-
-
-Изменения в nginx 0.4.12 31.10.2006
-
- *) Добавление: модуль ngx_http_perl_module поддерживает метод
- $r->variable.
-
- *) Исправление: при включении в ответ большого статического файла с
- помощью SSI ответ мог передаваться не полностью.
-
- *) Исправление: nginx не убирал "#fragment" в URI.
-
-
-Изменения в nginx 0.4.11 25.10.2006
-
- *) Добавление: POP3 прокси поддерживает AUTH LOIGN PLAIN и CRAM-MD5.
-
- *) Добавление: модуль ngx_http_perl_module поддерживает метод
- $r->allow_ranges.
-
- *) Исправление: при включённой поддержке команды APOP в POP3 прокси
- могли не работать команды USER/PASS; ошибка появилась в 0.4.10.
-
-
-Изменения в nginx 0.4.10 23.10.2006
-
- *) Добавление: POP3 прокси поддерживает APOP.
-
- *) Исправление: при использовании методов select, poll и /dev/poll во
- время ожидания ответа от сервера аутентификации IMAP/POP3 прокси
- нагружал процессор.
-
- *) Исправление: при использовании переменной $server_addr в директиве
- map мог произойти segmentation fault.
-
- *) Исправление: модуль ngx_http_flv_module не поддерживал byte ranges
- для полных ответов; ошибка появилась в 0.4.7.
-
- *) Исправление: nginx не собирался на Debian amd64; ошибка появилась в
- 0.4.9.
-
-
-Изменения в nginx 0.4.9 13.10.2006
-
- *) Добавление: параметр set в команде SSI include.
-
- *) Добавление: модуль ngx_http_perl_module теперь проверяет версию
- модуля nginx.pm.
-
-
-Изменения в nginx 0.4.8 11.10.2006
-
- *) Исправление: если до команды SSI include с параметром wait
- выполнялась ещё одна команда SSI include, то параметр wait мог не
- работать.
-
- *) Исправление: модуль ngx_http_flv_module добавлял FLV-заголовок для
- полных ответов.
- Спасибо Алексею Ковырину.
-
-
-Изменения в nginx 0.4.7 10.10.2006
-
- *) Добавление: модуль ngx_http_flv_module.
-
- *) Добавление: переменная $request_body_file.
-
- *) Добавление: директивы charset и source_charset поддерживают
- переменные.
-
- *) Исправление: если до команды SSI include с параметром wait
- выполнялась ещё одна команда SSI include, то параметр wait мог не
- работать.
-
- *) Исправление: при использовании директивы "proxy_buffering off" или
- при работе с memcached соединения могли не закрываться по таймауту.
-
- *) Исправление: nginx не запускался на 64-битных платформах, отличных от
- amd64, sparc64 и ppc64.
-
-
-Изменения в nginx 0.4.6 06.10.2006
-
- *) Исправление: nginx не запускался на 64-битных платформах, отличных от
- amd64, sparc64 и ppc64.
-
- *) Исправление: при запросе версии HTTP/1.1 nginx передавал ответ
- chunk'ами, если длина ответа в методе
- $r->headers_out("Content-Length", ...) была задана текстовой строкой.
-
- *) Исправление: после перенаправления ошибки с помощью директивы
- error_page любая директива модуля ngx_http_rewrite_module возвращала
- эту ошибку; ошибка появилась в 0.4.4.
-
-
-Изменения в nginx 0.4.5 02.10.2006
-
- *) Исправление: nginx не собирался на Linux и Solaris; ошибка появилась
- в 0.4.4.
-
-
-Изменения в nginx 0.4.4 02.10.2006
-
- *) Добавление: переменная $scheme.
-
- *) Добавление: директива expires поддерживает параметр max.
-
- *) Добавление: директива include поддерживает маску "*".
- Спасибо Jonathan Dance.
-
- *) Исправление: директива return всегда изменяла код ответа,
- перенаправленного директивой error_page.
-
- *) Исправление: происходил segmentation fault, если в методе PUT
- передавалось тело нулевой длины.
-
- *) Исправление: при использовании переменных в директиве proxy_redirect
- редирект изменялся неверно.
-
-
-Изменения в nginx 0.4.3 26.09.2006
-
- *) Изменение: ошибку 499 теперь нельзя перенаправить с помощью директивы
- error_page.
-
- *) Добавление: поддержка Solaris 10 event ports.
-
- *) Добавление: модуль ngx_http_browser_module.
-
- *) Исправление: при перенаправлении ошибки 400 проксированному серверу
- помощью директивы error_page мог произойти segmentation fault.
-
- *) Исправление: происходил segmentation fault, если в директиве
- proxy_pass использовался unix domain сокет; ошибка появилась в
- 0.3.47.
-
- *) Исправление: SSI не работал с ответами memcached и
- небуферизированными проксированными ответами.
-
- *) Изменение: обход ошибки PAUSE hardware capability в Sun Studio.
-
-
-Изменения в nginx 0.4.2 14.09.2006
-
- *) Исправление: убрана поддержка флага O_NOATIME на Linux; ошибка
- появилась в 0.4.1.
-
-
-Изменения в nginx 0.4.1 14.09.2006
-
- *) Исправление: совместимость с DragonFlyBSD.
- Спасибо Павлу Назарову.
-
- *) Изменение: обход ошибки в sendfile() в 64-битном Linux при передаче
- файлов больше 2G.
-
- *) Добавление: теперь на Linux nginx для статических запросов использует
- флаг O_NOATIME.
- Спасибо Yusuf Goolamabbas.
-
-
-Изменения в nginx 0.4.0 30.08.2006
-
- *) Изменение во внутреннем API: инициализация модулей HTTP перенесена из
- фазы init module в фазу HTTP postconfiguration.
-
- *) Изменение: теперь тело запроса в модуле ngx_http_perl_module не
- считывается заранее: нужно явно инициировать чтение с помощью метода
- $r->has_request_body.
-
- *) Добавление: модуль ngx_http_perl_module поддерживает код возврата
- DECLINED.
-
- *) Добавление: модуль ngx_http_dav_module поддерживает входящую строку
- заголовка "Date" для метода PUT.
-
- *) Добавление: директива ssi работает внутри блока if.
-
- *) Исправление: происходил segmentation fault, если в директиве index
- использовалась переменные и при этом первое имя индексного файла было
- без переменных; ошибка появилась в 0.1.29.
-
-
-Изменения в nginx 0.3.61 28.08.2006
-
- *) Изменение: директива tcp_nodelay теперь по умолчанию включена.
-
- *) Добавление: директива msie_refresh.
-
- *) Добавление: директива recursive_error_pages.
-
- *) Исправление: директива rewrite возвращала неправильный редирект, если
- редирект включал в себя выделенные закодированные символы из
- оригинального URI.
-
-
-Изменения в nginx 0.3.60 18.08.2006
-
- *) Исправление: во время перенаправления ошибки рабочий процесс мог
- зациклиться; ошибка появилась в 0.3.59.
-
-
-Изменения в nginx 0.3.59 16.08.2006
-
- *) Добавление: теперь можно делать несколько перенаправлений через
- директиву error_page.
-
- *) Исправление: директива dav_access не поддерживала три параметра.
-
- *) Исправление: директива error_page не изменяла строку "Content-Type"
- после перенаправления с помощью "X-Accel-Redirect"; ошибка появилась
- в 0.3.58.
-
-
-Изменения в nginx 0.3.58 14.08.2006
-
- *) Добавление: директива error_page поддерживает переменные.
-
- *) Изменение: теперь на Linux используется интерфейс procfs вместо
- sysctl.
-
- *) Изменение: теперь при использовании "X-Accel-Redirect" строка
- "Content-Type" наследуется из первоначального ответа.
-
- *) Исправление: директива error_page не перенаправляла ошибку 413.
-
- *) Исправление: завершающий "?" не удалял старые аргументы, если в
- переписанном URI не было новых аргументов.
-
- *) Исправление: nginx не запускался на 64-битной FreeBSD 7.0-CURRENT.
-
-
-Изменения в nginx 0.3.57 09.08.2006
-
- *) Добавление: переменная $ssl_client_serial.
-
- *) Исправление: в операторе "!-e" в директиве if.
- Спасибо Андриану Буданцову.
-
- *) Исправление: при проверке клиентского сертификата nginx не передавал
- клиенту информацию о требуемых сертификатах.
-
- *) Исправление: переменная $document_root не поддерживала переменные в
- директиве root.
-
-
-Изменения в nginx 0.3.56 04.08.2006
-
- *) Добавление: директива dav_access.
-
- *) Добавление: директива if поддерживает операторы "-d", "!-d", "-e",
- "!-e", "-x" и "!-x".
-
- *) Исправление: при записи в access_log некоторых передаваемых клиенту
- строк заголовков происходил segmentation fault, если запрос возвращал
- редирект.
-
-
-Изменения в nginx 0.3.55 28.07.2006
-
- *) Добавление: параметр stub в команде SSI include.
-
- *) Добавление: команда SSI block.
-
- *) Добавление: скрипт unicode2nginx добавлен в contrib.
-
- *) Исправление: если root был задан только переменной, то корень
- задавался относительно префикса сервера.
-
- *) Исправление: если в запросе был "//" или "/.", и после этого
- закодированные символы в виде "%XX", то проксируемый запрос
- передавался незакодированным.
-
- *) Исправление: метод $r->header_in("Cookie") модуля
- ngx_http_perl_module теперь возвращает все строки "Cookie" в
- заголовке запроса.
-
- *) Исправление: происходил segmentation fault, если использовался
- "client_body_in_file_only on" и делался переход к следующему бэкенду.
-
- *) Исправление: при некоторых условиях во время переконфигурации коды
- символов внутри директивы charset_map могли считаться неверными;
- ошибка появилась в 0.3.50.
-
-
-Изменения в nginx 0.3.54 11.07.2006
-
- *) Добавление: nginx теперь записывает в лог информацию о подзапросах.
-
- *) Добавление: директивы proxy_next_upstream, fastcgi_next_upstream и
- memcached_next_upstream поддерживают параметр off.
-
- *) Добавление: директива debug_connection поддерживает запись адресов в
- формате CIDR.
-
- *) Исправление: при перекодировании ответа проксированного сервера или
- сервера FastCGI в UTF-8 или наоборот ответ мог передаваться не
- полностью.
-
- *) Исправление: переменная $upstream_response_time содержала время
- только первого обращения к бэкенду.
-
- *) Исправление: nginx не собирался на платформе amd64; ошибка появилась
- в 0.3.53.
-
-
-Изменения в nginx 0.3.53 07.07.2006
-
- *) Изменение: директива add_header добавляет строки в ответы с кодом
- 204, 301 и 302.
-
- *) Добавление: директива server в блоке upstream поддерживает параметр
- weight.
-
- *) Добавление: директива server_name поддерживает маску "*".
-
- *) Добавление: nginx поддерживает тело запроса больше 2G.
-
- *) Исправление: если при использовании "satisfy_any on" клиент успешно
- проходил аутентификацию, в лог всё равно записалоcь сообщение "access
- forbidden by rule".
-
- *) Исправление: метод PUT мог ошибочно не создать файл и вернуть код
- 409.
-
- *) Исправление: если во время аутентификации IMAP/POP3 бэкенд возвращал
- ошибку, nginx продолжал проксирование.
-
-
-Изменения в nginx 0.3.52 03.07.2006
-
- *) Изменение: восстановлено поведение модуля ngx_http_index_module для
- запросов "POST /": как в версии до 0.3.40, модуль теперь не выдаёт
- ошибку 405.
-
- *) Исправление: при использовании ограничения скорости рабочий процесс
- мог зациклиться; ошибка появилась в 0.3.37.
-
- *) Исправление: модуль ngx_http_charset_module записывал в лог ошибку
- "unknown charset", даже если перекодировка не требовалась; ошибка
- появилась в 0.3.50.
-
- *) Исправление: если в результате запроса PUT возвращался код 409, то
- временный файл не удалялся.
-
-
-Изменения в nginx 0.3.51 30.06.2006
-
- *) Исправление: при некоторых условиях в SSI мог пропадать символы "<";
- ошибка появилась в 0.3.50.
-
-
-Изменения в nginx 0.3.50 28.06.2006
-
- *) Изменение: директивы proxy_redirect_errors и fastcgi_redirect_errors
- переименованы соответственно в proxy_intercept_errors и
- fastcgi_intercept_errors.
-
- *) Добавление: модуль ngx_http_charset_module поддерживает
- перекодирование из однобайтных кодировок в UTF-8 и обратно.
-
- *) Добавление: в режиме прокси и FastCGI поддерживается строка заголовка
- "X-Accel-Charset" в ответе бэкенда.
-
- *) Исправление: символ "\" в парах "\"" и "\'" в SSI командах убирался,
- только если также использовался символ "$".
-
- *) Исправление: при некоторых условиях в SSI после вставки могла быть
- добавлена строка "<!--".
-
- *) Исправление: если в заголовке ответа была строка "Content-Length: 0",
- то при использовании небуферизированного проксировании не закрывалось
- соединение с клиентом.
-
-
-Изменения в nginx 0.3.49 31.05.2006
-
- *) Исправление: в директиве set.
-
- *) Исправление: при включении в ssi двух и более подзапросов,
- обрабатываемых через FastCGI, вместо вывода второго и остальных
- подзапросов в ответ включался вывод первого подзапроса.
-
-
-Изменения в nginx 0.3.48 29.05.2006
-
- *) Изменение: теперь модуль ngx_http_charset_module работает для
- подзапросов, в ответах которых нет строки заголовка "Content-Type".
-
- *) Исправление: если в директиве proxy_pass не было URI, то директива
- "proxy_redirect default" добавляла в переписанный редирект в начало
- лишний слэш.
-
- *) Исправление: внутренний редирект всегда превращал любой HTTP-метод в
- GET, теперь это делается только для редиректов, выполняемых с помощью
- X-Accel-Redirect, и у которых метод не равен HEAD; ошибка появилась в
- 0.3.42.
-
- *) Исправление: модуль ngx_http_perl_module не собирался, если перл был
- с поддержкой потоков; ошибка появилась в 0.3.46.
-
-
-Изменения в nginx 0.3.47 23.05.2006
-
- *) Добавление: директива upstream.
-
- *) Изменение: символ "\" в парах "\"" и "\'" в SSI командах теперь
- всегда убирается.
-
-
-Изменения в nginx 0.3.46 11.05.2006
-
- *) Добавление: директивы proxy_hide_header, proxy_pass_header,
- fastcgi_hide_header и fastcgi_pass_header.
-
- *) Изменение: директивы proxy_pass_x_powered_by, fastcgi_x_powered_by и
- proxy_pass_server упразднены.
-
- *) Добавление: в режиме прокси поддерживается строка заголовка
- "X-Accel-Buffering" в ответе бэкенда.
-
- *) Исправление: ошибок и утечек памяти при переконфигурации в модуле
- ngx_http_perl_module.
-
-
-Изменения в nginx 0.3.45 06.05.2006
-
- *) Добавление: директивы ssl_verify_client, ssl_verify_depth и
- ssl_client_certificate.
-
- *) Изменение: теперь переменная $request_method возвращает метод только
- основного запроса.
-
- *) Изменение: в таблице перекодировки koi-win изменены коды символа
- &deg;.
-
- *) Добавление: в таблицу перекодировки koi-win добавлены символы евро и
- номера.
-
- *) Исправление: если nginx распределял запросы на несколько машин, то
- при падении одной из них запросы, предназначенные для этой машины,
- перенаправлялись только на одну машину вместо того, чтобы равномерно
- распределяться между остальными.
-
-
-Изменения в nginx 0.3.44 04.05.2006
-
- *) Добавление: параметр wait в команде SSI include.
-
- *) Добавление: в таблицу перекодировки koi-win добавлены украинские и
- белорусские символы.
-
- *) Исправление: в SSI.
-
-
-Изменения в nginx 0.3.43 26.04.2006
-
- *) Исправление: в SSI.
-
-
-Изменения в nginx 0.3.42 26.04.2006
-
- *) Добавление: параметр bind в директиве listen в IMAP/POP3 прокси.
-
- *) Исправление: ошибки при использовании в директиве rewrite одного и
- того же выделения более одного раза.
-
- *) Исправление: в лог не записывались переменные
- $sent_http_content_type, $sent_http_content_length,
- $sent_http_last_modified, $sent_http_connection,
- $sent_http_keep_alive и $sent_http_transfer_encoding.
-
- *) Исправление: переменная $sent_http_cache_control возвращала
- содержимое только одной строки "Cache-Control" в заголовке ответа.
-
-
-Изменения в nginx 0.3.41 21.04.2006
-
- *) Добавление: ключ -v.
-
- *) Исправление: при включении в SSI удалённых подзапросов мог произойти
- segmentation fault.
-
- *) Исправление: в обработке FastCGI.
-
- *) Исправление: если путь к перловым модулям не был указан с помощью
- --with-perl_modules_path=PATH или директивы perl_modules, то на
- старте происходил segmentation fault.
-
-
-Изменения в nginx 0.3.40 19.04.2006
-
- *) Добавление: модуль ngx_http_dav_module поддерживает метод MKCOL.
-
- *) Добавление: директива create_full_put_path.
-
- *) Добавление: переменная $limit_rate.
-
-
-Изменения в nginx 0.3.39 17.04.2006
-
- *) Добавление: директива uninitialized_variable_warn; уровень
- логгирования сообщения о неинициализированной переменной понижен с
- уровня alert на warn.
-
- *) Добавление: директива override_charset.
-
- *) Изменение: при использовании неизвестной переменной в SSI-командах
- echo и if expr='$name' теперь не записывается в лог сообщение о
- неизвестной переменной.
-
- *) Исправление: счётчик активных соединений рос при превышении лимита
- соединений, заданного директивой worker_connections; ошибка появилась
- в 0.2.0.
-
- *) Исправление: при некоторых условия ограничение скорости соединения
- могло не работать; ошибка появилась в 0.3.38.
-
-
-Изменения в nginx 0.3.38 14.04.2006
-
- *) Добавление: модуль ngx_http_dav_module.
-
- *) Изменение: оптимизация модуля ngx_http_perl_module.
- Спасибо Сергею Скворцову.
-
- *) Добавление: модуль ngx_http_perl_module поддерживает метод
- $r->request_body_file.
-
- *) Добавление: директива client_body_in_file_only.
-
- *) Изменение: теперь при переполнении диска nginx пытается писать
- access_log'и только раз в секунду.
- Спасибо Антону Южанинову и Максиму Дунину.
-
- *) Исправление: теперь директива limit_rate точнее ограничивает скорость
- при значениях больше 100 Kbyte/s.
- Спасибо ForJest.
-
- *) Исправление: IMAP/POP3 прокси теперь передаёт серверу авторизации
- символы "\r" и "\n" в логине и пароле в закодированном виде.
- Спасибо Максиму Дунину.
-
-
-Изменения в nginx 0.3.37 07.04.2006
-
- *) Добавление: директива limit_except.
-
- *) Добавление: директива if поддерживает операторы "!~", "!~*", "-f" и
- "!-f".
-
- *) Добавление: модуль ngx_http_perl_module поддерживает метод
- $r->request_body.
-
- *) Исправление: в модуле ngx_http_addition_filter_module.
-
-
-Изменения в nginx 0.3.36 05.04.2006
-
- *) Добавление: модуль ngx_http_addition_filter_module.
-
- *) Добавление: директивы proxy_pass и fastcgi_pass можно использовать
- внутри блока if.
-
- *) Добавление: директивы proxy_ignore_client_abort и
- fastcgi_ignore_client_abort.
-
- *) Добавление: переменная $request_completion.
-
- *) Добавление: модуль ngx_http_perl_module поддерживает методы
- $r->request_method и $r->remote_addr.
-
- *) Добавление: модуль ngx_http_ssi_module поддерживает команду elif.
-
- *) Исправление: строка "\/" в начале выражения команды if модуля
- ngx_http_ssi_module воспринималась неверно.
-
- *) Исправление: в использовании регулярных выражениях в команде if
- модуля ngx_http_ssi_module.
-
- *) Исправление: при задании относительного пути в директивах
- client_body_temp_path, proxy_temp_path, fastcgi_temp_path и
- perl_modules использовался каталог относительно текущего каталога, а
- не относительно префикса сервера.
-
-
-Изменения в nginx 0.3.35 22.03.2006
-
- *) Исправление: accept-фильтр и TCP_DEFER_ACCEPT устанавливались только
- для первой директивы listen; ошибка появилась в 0.3.31.
-
- *) Исправление: в директиве proxy_pass без URI при использовании в
- подзапросе.
-
-
-Изменения в nginx 0.3.34 21.03.2006
-
- *) Добавление: директива add_header поддерживает переменные.
-
-
-Изменения в nginx 0.3.33 15.03.2006
-
- *) Добавление: параметр http_503 в директивах proxy_next_upstream или
- fastcgi_next_upstream.
-
- *) Исправление: ngx_http_perl_module не работал со встроенным в
- конфигурационный файл кодом, если он не начинался сразу же с "sub".
-
- *) Исправление: в директиве post_action.
-
-
-Изменения в nginx 0.3.32 11.03.2006
-
- *) Исправление: удаление отладочного логгирования на старте и при
- переконфигурации; ошибка появилась в 0.3.31.
-
-
-Изменения в nginx 0.3.31 10.03.2006
-
- *) Изменение: теперь nginx передаёт неверные ответы проксированного
- бэкенда.
-
- *) Добавление: директивы listen поддерживают адрес в виде "*:порт".
-
- *) Добавление: поддержка EVFILER_TIMER в MacOSX 10.4.
-
- *) Изменение: обход ошибки обработки миллисекундных таймаутов kqueue в
- 64-битном ядре MacOSX.
- Спасибо Андрею Нигматулину.
-
- *) Исправление: если внутри одного сервера описаны несколько директив
- listen, слушающих на разных адресах, то имена серверов вида
- "*.domain.tld" работали только для первого адреса; ошибка появилась в
- 0.3.18.
-
- *) Исправление: при использовании протокола HTTPS в директиве proxy_pass
- не передавались запросы с телом, записанным во временный файл.
-
- *) Исправление: совместимость с perl 5.8.8.
-
-
-Изменения в nginx 0.3.30 22.02.2006
-
- *) Изменение: уровень записи в лог ошибки ECONNABORTED изменён на error
- с уровня crit.
-
- *) Исправление: модуль ngx_http_perl_module не собирался без модуля
- ngx_http_ssi_filter_module.
-
- *) Исправление: nginx не собирался на i386 платформе, если использовался
- PIC; ошибка появилась в 0.3.27.
-
-
-Изменения в nginx 0.3.29 20.02.2006
-
- *) Добавление: теперь nginx использует меньше памяти, если PHP в режиме
- FastCGI передаёт большое количество предупреждений перед ответом.
-
- *) Исправление: в ответах 204 для запросов версии HTTP/1.1 выдавалась
- строка заголовка "Transfer-Encoding: chunked".
-
- *) Исправление: nginx возвращал 502 код ответа, если FastCGI сервер
- передавал полные строки заголовка ответа в отдельных FastCGI записях.
-
- *) Исправление: если в директиве post_action был указан проксируемый
- URI, то он выполнялся только после успешного завершения запроса.
-
-
-Изменения в nginx 0.3.28 16.02.2006
-
- *) Добавление: директива restrict_host_names упразднена.
-
- *) Добавление: параметр конфигурации --with-cpu-opt=ppc64.
-
- *) Исправление: при некоторых условиях проксированное соединение с
- клиентом завершалось преждевременно.
- Спасибо Владимиру Шутову.
-
- *) Исправление: строка заголовка "X-Accel-Limit-Rate" не учитывалась для
- запросов, перенаправленных с помощью строки "X-Accel-Redirect".
-
- *) Исправление: директива post_action работала только после успешного
- завершения запроса.
-
- *) Исправление: тело проксированного ответа, создаваемого директивой
- post_action, передавалось клиенту.
-
-
-Изменения в nginx 0.3.27 08.02.2006
-
- *) Изменение: директивы variables_hash_max_size и
- variables_hash_bucket_size.
-
- *) Добавление: переменная $body_bytes_sent доступна не только в
- директиве log_format.
-
- *) Добавление: переменные $ssl_protocol и $ssl_cipher.
-
- *) Добавление: определение размера строки кэша распространённых
- процессоров при старте.
-
- *) Добавление: директива accept_mutex теперь поддерживается посредством
- fcntl(2) на платформах, отличных от i386, amd64, sparc64 и ppc.
-
- *) Добавление: директива lock_file и параметр автоконфигурации
- --with-lock-path=PATH.
-
- *) Исправление: при использовании протокола HTTPS в директиве proxy_pass
- не передавались запросы с телом.
-
-
-Изменения в nginx 0.3.26 03.02.2006
-
- *) Изменение: директива optimize_host_names переименована в
- optimize_server_names.
-
- *) Исправление: при проксировании подзапроса в SSI бэкенду передавался
- URI основного запроса, если в директиве proxy_pass отсутствовал URI.
-
-
-Изменения в nginx 0.3.25 01.02.2006
-
- *) Исправление: при неверной конфигурации на старте или во время
- переконфигурации происходил segmentation fault; ошибка появилась в
- 0.3.24.
-
-
-Изменения в nginx 0.3.24 01.02.2006
-
- *) Изменение: обход ошибки в kqueue во FreeBSD.
-
- *) Исправление: ответ, создаваемый директивой post_action, теперь не
- передаётся клиенту.
-
- *) Исправление: при использовании большого количества лог-файлов
- происходила утечка памяти.
-
- *) Исправление: внутри одного location работала только первая директива
- proxy_redirect.
-
- *) Исправление: на 64-битных платформах при старте мог произойти
- segmentation fault, если использовалось большое количество имён в
- директивах server_name; ошибка появилась в 0.3.18.
-
-
-Изменения в nginx 0.3.23 24.01.2006
-
- *) Добавление: директива optimize_host_names.
-
- *) Исправление: ошибки при использовании переменных в директивах path и
- alias.
-
- *) Исправление: модуль ngx_http_perl_module неправильно собирался на
- Linux и Solaris.
-
-
-Изменения в nginx 0.3.22 17.01.2006
-
- *) Добавление: модуль ngx_http_perl_module поддерживает методы $r->args
- и $r->unescape.
-
- *) Добавление: метод $r->query_string в модуле ngx_http_perl_module
- упразднён.
-
- *) Исправление: если в директиве valid_referers указаны только none или
- blocked, то происходил segmentation fault; ошибка появилась в 0.3.18.
-
-
-Изменения в nginx 0.3.21 16.01.2006
-
- *) Добавление: модуль ngx_http_perl_module.
-
- *) Изменение: директива valid_referers разрешает использовать рефереры
- совсем без URI.
-
-
-Изменения в nginx 0.3.20 11.01.2006
-
- *) Исправление: ошибки в обработке SSI.
-
- *) Исправление: модуль ngx_http_memcached_module не поддерживал ключи в
- виде /uri?args.
-
-
-Изменения в nginx 0.3.19 28.12.2005
-
- *) Добавление: директивы path и alias поддерживают переменные.
-
- *) Изменение: теперь директива valid_referers опять учитывает URI.
-
- *) Исправление: ошибки в обработке SSI.
-
-
-Изменения в nginx 0.3.18 26.12.2005
-
- *) Добавление: директива server_names поддерживает имена вида
- ".domain.tld".
-
- *) Добавление: директива server_names использует хэш для имён вида
- "*.domain.tld" и более эффективный хэш для обычных имён.
-
- *) Изменение: директивы server_names_hash_max_size и
- server_names_hash_bucket_size.
-
- *) Изменение: директивы server_names_hash и server_names_hash_threshold
- упразднены.
-
- *) Добавление: директива valid_referers использует хэш для имён сайтов.
-
- *) Изменение: теперь директива valid_referers проверяет только имена
- сайтов без учёта URI.
-
- *) Исправление: некоторые имена вида ".domain.tld" неверно
- обрабатывались модулем ngx_http_map_module.
-
- *) Исправление: если конфигурационного файла не было, то происходил
- segmentation fault; ошибка появилась в 0.3.12.
-
- *) Исправление: на 64-битных платформах при старте мог произойти
- segmentation fault; ошибка появилась в 0.3.16.
-
-
-Изменения в nginx 0.3.17 18.12.2005
-
- *) Изменение: на Linux configure теперь проверяет наличие epoll и
- sendfile64() в ядре.
-
- *) Добавление: директива map поддерживает доменные имена в формате
- ".domain.tld".
-
- *) Исправление: во время SSL handshake не иcпользовались таймауты;
- ошибка появилась в 0.2.4.
-
- *) Исправление: в использовании протокола HTTPS в директиве proxy_pass.
-
- *) Исправление: при использовании протокола HTTPS в директиве proxy_pass
- по умолчанию использовался порт 80.
-
-
-Изменения в nginx 0.3.16 16.12.2005
-
- *) Добавление: модуль ngx_http_map_module.
-
- *) Добавление: директивы types_hash_max_size и types_hash_bucket_size.
-
- *) Добавление: директива ssi_value_length.
-
- *) Добавление: директива worker_rlimit_core.
-
- *) Изменение: при сборке компиляторами icc 8.1 и 9.0 с оптимизацией для
- Pentium 4 номер соединения в логах всегда был равен 1.
-
- *) Исправление: команда config timefmt в SSI задавала неверный формат
- времени.
-
- *) Исправление: nginx не закрывал соединения с IMAP/POP3 бэкендом при
- использовании SSL соединений; ошибка появилась в 0.3.13.
- Спасибо Rob Mueller.
-
- *) Исправление: segmentation fault мог произойти во время SSL shutdown;
- ошибка появилась в 0.3.13.
-
-
-Изменения в nginx 0.3.15 07.12.2005
-
- *) Добавление: новой код 444 в директиве return для закрытия соединения.
-
- *) Добавление: директива so_keepalive в IMAP/POP3 прокси.
-
- *) Исправление: nginx теперь вызывает abort() при обнаружении незакрытых
- соединений только при планом выходе и включённой директиве
- debug_points.
-
-
-Изменения в nginx 0.3.14 05.12.2005
-
- *) Исправление: в ответе 304 передавалось тело ответа; ошибка появилась
- в 0.3.13.
-
-
-Изменения в nginx 0.3.13 05.12.2005
-
- *) Добавление: IMAP/POP3 прокси поддерживает STARTTLS и STLS.
-
- *) Исправление: IMAP/POP3 прокси не работала с методами select, poll и
- /dev/poll.
-
- *) Исправление: ошибки в обработке SSI.
-
- *) Исправление: sendfilev() в Solaris теперь не используется при
- передаче тела запроса FastCGI-серверу через unix domain сокет.
-
- *) Исправление: директива auth_basic не запрещала аутентификацию; ошибка
- появилась в 0.3.11.
-
-
-Изменения в nginx 0.3.12 26.11.2005
-
- *) Безопасность: если nginx был собран с модулем ngx_http_realip_module,
- то при использовании директивы "satisfy_any on" директивы доступа и
- аутентификации не работали. Модуль ngx_http_realip_module не
- собирался и не собирается по умолчанию.
-
- *) Изменение: имя переменной "$time_gmt" изменено на "$time_local".
-
- *) Изменение: директивы proxy_header_buffer_size и
- fastcgi_header_buffer_size переименованы соответственно в
- proxy_buffer_size и fastcgi_buffer_size.
-
- *) Добавление: модуль ngx_http_memcached_module.
-
- *) Добавление: директива proxy_buffering.
-
- *) Исправление: изменение в работе с accept mutex при использовании
- метода rtsig; ошибка появилась в 0.3.0.
-
- *) Исправление: если клиент передал строку "Transfer-Encoding: chunked"
- в заголовке запроса, то nginx теперь выдаёт ошибку 411.
-
- *) Исправление: при наследовании директивы auth_basic с уровня http в
- строке "WWW-Authenticate" заголовка ответа выводился realm без текста
- "Basic realm".
-
- *) Исправление: если в директиве access_log был явно указан формат
- combined, то в лог записывались пустые строки; ошибка появилась в
- 0.3.8.
-
- *) Исправление: nginx не работал на платформе sparc под любыми OS, кроме
- Solaris.
-
- *) Исправление: в директиве if теперь не нужно разделять пробелом строку
- в кавычках и закрывающую скобку.
-
-
-Изменения в nginx 0.3.11 15.11.2005
-
- *) Исправление: nginx не передавал при проксировании тело запроса и
- строки заголовка клиента; ошибка появилась в 0.3.10.
-
-
-Изменения в nginx 0.3.10 15.11.2005
-
- *) Изменение: директива valid_referers и переменная $invalid_referer
- перенесены из модуля ngx_http_rewrite_module в новый модуль
- ngx_http_referer_module.
-
- *) Изменение: имя переменной "$apache_bytes_sent" изменено на
- "$body_bytes_sent".
-
- *) Добавление: переменные "$sent_http_...".
-
- *) Добавление: директива if поддерживает операции "=" и "!=".
-
- *) Добавление: директива proxy_pass поддерживает протокол HTTPS.
-
- *) Добавление: директива proxy_set_body.
-
- *) Добавление: директива post_action.
-
- *) Добавление: модуль ngx_http_empty_gif_module.
-
- *) Добавление: директива worker_cpu_affinity для Linux.
-
- *) Исправление: директива rewrite не раскодировала символы в редиректах
- в URI, теперь символы раскодируются, кроме символов %00-%25 и
- %7F-%FF.
-
- *) Исправление: nginx не собирался компилятором icc 9.0.
-
- *) Исправление: если для статического файла нулевого размера был
- разрешён SSI, то ответ передавался неверно при кодировании chunk'ами.
-
-
-Изменения в nginx 0.3.9 10.11.2005
-
- *) Исправление: nginx считал небезопасными URI, в которых между двумя
- слэшами находилось два любых символа; ошибка появилась в 0.3.8.
-
-
-Изменения в nginx 0.3.8 09.11.2005
-
- *) Безопасность: nginx теперь проверят URI, полученные от бэкенда в
- строке "X-Accel-Redirect" в заголовке ответа, или в SSI файле на
- наличие путей "/../" и нулей.
-
- *) Изменение: nginx теперь не воспринимает пустое имя как правильное в
- строке "Authorization" в заголовке запроса.
-
- *) Добавление: директива ssl_session_timeout модулей ngx_http_ssl_module
- и ngx_imap_ssl_module.
-
- *) Добавление: директива auth_http_header модуля
- ngx_imap_auth_http_module.
-
- *) Добавление: директива add_header.
-
- *) Добавление: модуль ngx_http_realip_module.
-
- *) Добавление: новые переменные для использования в директиве
- log_format: $bytes_sent, $apache_bytes_sent, $status, $time_gmt,
- $uri, $request_time, $request_length, $upstream_status,
- $upstream_response_time, $gzip_ratio, $uid_got, $uid_set,
- $connection, $pipe и $msec. Параметры в виде "%name" скоро будут
- упразднены.
-
- *) Изменение: в директиве "if" ложными значениями переменных теперь
- являются пустая строка "" и строки, начинающиеся на "0".
-
- *) Исправление: при работает с проксированными или FastCGI-серверами
- nginx мог оставлять открытыми соединения и временные файлы с
- запросами клиентов.
-
- *) Исправление: рабочие процессы не сбрасывали буферизированные логи при
- плавном выходе.
-
- *) Исправление: если URI запроса изменялось с помощью rewrite, а затем
- запрос проксировался в location, заданном регулярным выражением, то
- бэкенду передавался неверный запрос; ошибка появилась в 0.2.6.
-
- *) Исправление: директива expires не удаляла уже установленную строку
- заголовка "Expires".
-
- *) Исправление: при использовании метода rtsig и нескольких рабочих
- процессах nginx мог перестать принимать запросы.
-
- *) Исправление: в SSI командах неверно обрабатывались строки "\"" и
- "\'".
-
- *) Исправление: если ответ заканчивался сразу же после SSI команды, то
- при использовании сжатия ответ передавался не до конца или не
- передавался вообще.
-
-
-Изменения в nginx 0.3.7 27.10.2005
-
- *) Добавление: директива access_log поддерживает параметр buffer=.
-
- *) Исправление: nginx не собирался на платформах, отличных от i386,
- amd64, sparc и ppc; ошибка появилась в 0.3.2.
-
-
-Изменения в nginx 0.3.6 24.10.2005
-
- *) Изменение: IMAP/POP3 прокси теперь не передаёт серверу авторизации
- пустой логин.
-
- *) Добавление: директива log_format поддерживает переменные в виде
- $name.
-
- *) Исправление: если хотя бы в одном сервере не было описано ни одной
- директивы listen, то nginx не слушал на 80 порту; ошибка появилась в
- 0.3.3.
-
- *) Исправление: если в директиве proxy_pass отсутствовал URI, то всегда
- использовался порт 80.
-
-
-Изменения в nginx 0.3.5 21.10.2005
-
- *) Исправление: если логин IMAP/POP3 менялся сервером авторизации, то
- мог произойти segmentation fault; ошибка появилась в 0.2.2.
-
- *) Исправление: accept mutex не работал, все соединения обрабатывались
- одним рабочим процессом; ошибка появилась в 0.3.3.
-
- *) Исправление: при использовании метода rtsig и директивы
- timer_resolution не работали таймауты.
-
-
-Изменения в nginx 0.3.4 19.10.2005
-
- *) Исправление: nginx не собирался на Linux 2.4+ и MacOS X; ошибка
- появилась в 0.3.3.
-
-
-Изменения в nginx 0.3.3 19.10.2005
-
- *) Изменение: параметры "bl" и "af" директивы listen переименованы в
- "backlog" и "accept_filter".
-
- *) Добавление: параметры "rcvbuf" и "sndbuf" в директиве listen.
-
- *) Изменение: параметр лога $msec теперь не требует дополнительного
- системного вызова gettimeofday().
-
- *) Добавление: ключ -t теперь проверяет директивы listen.
-
- *) Исправление: если в директиве listen был указан неверный адрес, то
- nginx после сигнала -HUP оставлял открытый сокет в состоянии CLOSED.
-
- *) Исправление: для индексных файлов, содержащих в имени переменную, мог
- неверно выставляться тип mime по умолчанию; ошибка появилась в 0.3.0.
-
- *) Добавление: директива timer_resolution.
-
- *) Добавление: параметр лога $upstream_response_time в миллисекундах.
-
- *) Исправление: временный файл с телом запроса клиента теперь удаляется
- сразу после того, как клиенту передан заголовок ответа.
-
- *) Исправление: совместимость с OpenSSL 0.9.6.
-
- *) Исправление: пути к файлам с SSL сертификатом и ключом не могли быть
- относительными.
-
- *) Исправление: директива ssl_prefer_server_ciphers не работала для
- модуля ngx_imap_ssl_module.
-
- *) Исправление: директива ssl_protocols позволяла задать только один
- протокол.
-
-
-Изменения в nginx 0.3.2 12.10.2005
-
- *) Добавление: поддержка Sun Studio 10 C compiler.
-
- *) Добавление: директивы proxy_upstream_max_fails,
- proxy_upstream_fail_timeout, fastcgi_upstream_max_fails и
- fastcgi_upstream_fail_timeout.
-
-
-Изменения в nginx 0.3.1 10.10.2005
-
- *) Исправление: во время переполнения очереди сигналов при использовании
- метода rtsig происходил segmentation fault; ошибка появилась в 0.2.0.
-
- *) Изменение: корректная обработка пар "\\", "\"", "\'" и "\$" в SSI.
-
-
-Изменения в nginx 0.3.0 07.10.2005
-
- *) Изменение: убрано десятидневное ограничение времени работы рабочего
- процесса. Ограничение было введено из-за переполнения миллисекундных
- таймеров.
-
-
-Изменения в nginx 0.2.6 05.10.2005
-
- *) Изменение: с 60 до 10 секунд уменьшено время повторного обращения к
- бэкенду при использовании распределения нагрузки.
-
- *) Изменение: директива proxy_pass_unparsed_uri упразднена, оригинальный
- запрос теперь передаётся, если в директиве proxy_pass отсутствует
- URI.
-
- *) Добавление: директива error_page поддерживает редиректы и позволяет
- более гибко менять код ошибки.
-
- *) Изменение: в проксированных подзапросах теперь игнорируется
- переданный charset.
-
- *) Исправление: если после изменения URI в блоке if для запроса не
- находилась новая конфигурация, то правила модуля
- ngx_http_rewrite_module выполнялись снова.
-
- *) Исправление: если директива set устанавливала переменную модуля
- ngx_http_geo_module в какой-либо части конфигурации, то эта
- переменная не была доступна в других частях конфигурации и выдавалась
- ошибка "using uninitialized variable"; ошибка появилась в 0.2.2.
-
-
-Изменения в nginx 0.2.5 04.10.2005
-
- *) Изменение: дублирующее значение переменной модуля ngx_http_geo_module
- теперь выдаёт предупреждение и изменяет старое значение.
-
- *) Добавление: модуль ngx_http_ssi_module поддерживает команду set.
-
- *) Добавление: модуль ngx_http_ssi_module поддерживает параметр file в
- команде include.
-
- *) Добавление: модуль ngx_http_ssi_module поддерживает подстановку
- значений переменных в выражениях команды if.
-
-
-Изменения в nginx 0.2.4 03.10.2005
-
- *) Добавление: модуль ngx_http_ssi_module поддерживает выражения
- "$var=text", "$var!=text", "$var=/text/" и "$var!=/text/" в команде
- if.
-
- *) Исправление: ошибки при проксировании location без слэша в конце;
- ошибка появилась в 0.1.44.
-
- *) Исправление: при использовании метода rtsig мог произойти
- segmentation fault; ошибка появилась в 0.2.0.
-
-
-Изменения в nginx 0.2.3 30.09.2005
-
- *) Исправление: nginx не собирался без параметра --with-debug; ошибка
- появилась в 0.2.2.
-
-
-Изменения в nginx 0.2.2 30.09.2005
-
- *) Добавление: команда config errmsg в модуле ngx_http_ssi_module.
-
- *) Изменение: переменные модуля ngx_http_geo_module можно переопределять
- директивой set.
-
- *) Добавление: директивы ssl_protocols и ssl_prefer_server_ciphers
- модулей ngx_http_ssl_module и ngx_imap_ssl_module.
-
- *) Исправление: ошибка в модуле ngx_http_autoindex_module при показе
- длинных имён файлов;
-
- *) Исправление: модуль ngx_http_autoindex_module теперь не показывает
- файлы, начинающиеся на точку.
-
- *) Исправление: если SSL handshake завершался с ошибкой, то это могло
- привести также к закрытию другого соединения.
- Спасибо Rob Mueller.
-
- *) Исправление: экспортные версии MSIE 5.x не могли соединиться по
- HTTPS.
-
-
-Изменения в nginx 0.2.1 23.09.2005
-
- *) Исправление: если все бэкенды, используемые для балансировки
- нагрузки, оказывались в нерабочем состоянии после одной ошибки, то
- nginx мог зациклится; ошибка появилась в 0.2.0.
-
-
-Изменения в nginx 0.2.0 23.09.2005
-
- *) Изменились имена pid-файлов, используемые во время обновления
- исполняемого файла. Ручное переименование теперь не нужно. Старый
- основной процесс добавляет к своему pid-файл суффикс ".oldbin" и
- запускает новый исполняемый файл. Новый основной процесс создаёт
- обычный pid-файл без суффикса ".newbin". Если новый основной процесс
- выходит, то старый процесс переименовывает свой pid-файл c суффиксом
- ".oldbin" в pid-файл без суффикса. При обновлении с версии 0.1.х до
- 0.2.0 нужно учитывать, что оба процесса - старый 0.1.x и новый
- 0.2.0 - используют pid-файл без суффиксов.
-
- *) Изменение: директива worker_connections, новое название директивы
- connections; директива теперь задаёт максимальное число соединений, а
- не максимально возможный номер дескриптора для сокета.
-
- *) Добавление: SSL поддерживает кэширование сессий в пределах одного
- рабочего процесса.
-
- *) Добавление: директива satisfy_any.
-
- *) Изменение: модули ngx_http_access_module и ngx_http_auth_basic_module
- не работают для подзапросов.
-
- *) Добавление: директивы worker_rlimit_nofile и
- worker_rlimit_sigpending.
-
- *) Исправление: если все бэкенды, используемые для балансировки
- нагрузки, оказывались в нерабочем состоянии после одной ошибки, то
- nginx не обращался к ним в течение 60 секунд.
-
- *) Исправление: в парсинге аргументов IMAP/POP3 команд.
- Спасибо Rob Mueller.
-
- *) Исправление: ошибки при использовании SSL в IMAP/POP3 прокси.
-
- *) Исправление: ошибки при использовании SSI и сжатия.
-
- *) Исправление: в ответах 304 не добавлялись строки заголовка ответа
- "Expires" и "Cache-Control".
- Спасибо Александру Кукушкину.
-
-
-Изменения в nginx 0.1.45 08.09.2005
-
- *) Изменение: директива ssl_engine упразднена в модуле
- ngx_http_ssl_module и перенесена на глобальный уровень.
-
- *) Исправление: ответы с подзапросами, включённые с помощью SSI, не
- передавались через SSL соединение.
-
- *) Разные исправления в IMAP/POP3 прокси.
-
-
-Изменения в nginx 0.1.44 06.09.2005
-
- *) Добавление: IMAP/POP3 прокси поддерживает SSL.
-
- *) Добавление: директива proxy_timeout модуля ngx_imap_proxy_module.
-
- *) Добавление: директива userid_mark.
-
- *) Добавление: значение переменной $remote_user определяется независимо
- от того, используется ли авторизация или нет.
-
-
-Изменения в nginx 0.1.43 30.08.2005
-
- *) Добавление: listen(2) backlog в директиве listen можно менять по
- сигналу -HUP.
-
- *) Добавление: скрипт geo2nginx.pl добавлен в contrib.
-
- *) Изменение: параметры FastCGI с пустым значениями теперь передаются
- серверу.
-
- *) Исправление: если в ответе проксированного сервера или FastCGI
- сервера была строка "Cache-Control", то при использовании директивы
- expires происходил segmentation fault или рабочий процесс мог
- зациклится; в режиме прокси ошибка появилась в 0.1.29.
-
-
-Изменения в nginx 0.1.42 23.08.2005
-
- *) Исправление: если URI запроса получался нулевой длины после обработки
- модулем ngx_http_rewrite_module, то в модуле ngx_http_proxy_module
- происходил segmentation fault или bus error.
-
- *) Исправление: директива limit_rate не работала внутри блока if; ошибка
- появилась в 0.1.38.
-
-
-Изменения в nginx 0.1.41 25.07.2005
-
- *) Исправление: если переменная использовалась в файле конфигурации, то
- она не могла использоваться в SSI.
-
-
-Изменения в nginx 0.1.40 22.07.2005
-
- *) Исправление: если клиент слал очень длинную строку заголовка, то в
- логе не помещалась информация, связанная с этим запросом.
-
- *) Исправление: при использовании "X-Accel-Redirect" не передавалась
- строка "Set-Cookie"; ошибка появилась в 0.1.39.
-
- *) Исправление: при использовании "X-Accel-Redirect" не передавалась
- строка "Content-Disposition".
-
- *) Исправление: по сигналу SIGQUIT основной процесс не закрывал сокеты,
- на которых он слушал.
-
- *) Исправление: после обновления исполняемого файла на лету на Linux и
- Solaris название процесса в команде ps становилось короче.
-
-
-Изменения в nginx 0.1.39 14.07.2005
-
- *) Изменения в модуле ngx_http_charset_module: директива default_charset
- упразднена; директива charset задаёт кодировку ответа; директива
- source_charset задаёт только исходную кодировку.
-
- *) Исправление: при перенаправлении ошибки 401, полученной от бэкенда,
- не передавалась строка заголовка "WWW-Authenticate".
-
- *) Исправление: модули ngx_http_proxy_module и ngx_http_fastcgi_module
- могли закрыть соединение до того, как что-нибудь было передано
- клиенту; ошибка появилась в 0.1.38.
-
- *) Изменение: обработка ошибки инициализации в crypt_r() в Linux glibc.
-
- *) Исправление: модуль ngx_http_ssi_module не поддерживал относительные
- URI в команде include virtual.
-
- *) Исправление: если в строке заголовка ответа бэкенда была строка
- "Location", которую nginx не должен был изменять, то в ответе
- передавалось тело 500 ошибки; ошибка появилась в 0.1.29.
-
- *) Исправление: некоторые директивы модулей ngx_http_proxy_module и
- ngx_http_fastcgi_module не наследовались с уровня server на уровень
- location; ошибка появилась в 0.1.29.
-
- *) Исправление: модуль ngx_http_ssl_module не поддерживал цепочки
- сертификатов.
-
- *) Исправление: ошибка в модуле ngx_http_autoindex_module при показе
- длинных имён файлов; ошибка появилась в 0.1.38.
-
- *) Исправления в IMAP/POP3 прокси при взаимодействии с бэкендом на
- стадии login.
-
-
-Изменения в nginx 0.1.38 08.07.2005
-
- *) Добавление: директива limit_rate поддерживается в режиме прокси и
- FastCGI.
-
- *) Добавление: в режиме прокси и FastCGI поддерживается строка заголовка
- "X-Accel-Limit-Rate" в ответе бэкенда.
-
- *) Добавление: директива break.
-
- *) Добавление: директива log_not_found.
-
- *) Исправление: при перенаправлении запроса с помощью строки заголовка
- "X-Accel-Redirect" не изменялся код ответа.
-
- *) Исправление: переменные, установленные директивой set не могли
- использоваться в SSI.
-
- *) Исправление: при включении в SSI более одного удалённого подзапроса
- мог произойти segmentation fault.
-
- *) Исправление: если статусная строка в ответе бэкенда передавалась в
- двух пакетах, то nginx считал ответ неверным; ошибка появилась в
- 0.1.29.
-
- *) Добавление: директива ssi_types.
-
- *) Добавление: директива autoindex_exact_size.
-
- *) Исправление: модуль ngx_http_autoindex_module не поддерживал длинные
- имена файлов в UTF-8.
-
- *) Добавление: IMAP/POP3 прокси.
-
-
-Изменения в nginx 0.1.37 23.06.2005
-
- *) Изменение: в конце файла nginx.pid теперь добавляется "\n".
-
- *) Исправление: при включении большого количества вставок или нескольких
- больших вставок с помощью SSI ответ мог передаваться не полностью.
-
- *) Исправление: если все бэкенды возвращали ответ 404, то при
- использовании параметра http_404 в директивах proxy_next_upstream или
- fastcgi_next_upstream, nginx начинал запрашивать все бэкенды снова.
-
-
-Изменения в nginx 0.1.36 15.06.2005
-
- *) Изменение: если в заголовке запросе есть дублирующиеся строки "Host",
- "Connection", "Content-Length" и "Authorization", то nginx теперь
- выдаёт ошибку 400.
-
- *) Изменение: директива post_accept_timeout упразднена.
-
- *) Добавление: параметры default, af=, bl=, deferred и bind в директиве
- listen.
-
- *) Добавление: поддержка accept фильтров во FreeBSD.
-
- *) Добавление: поддержка TCP_DEFER_ACCEPT в Linux.
-
- *) Исправление: модуль ngx_http_autoindex_module не поддерживал имена
- файлов в UTF-8.
-
- *) Исправление: после добавления новый лог-файл ротация этого лога по
- сигналу -USR1 выполнялась, только если переконфигурировать nginx два
- раза по сигналу -HUP.
-
-
-Изменения в nginx 0.1.35 07.06.2005
-
- *) Добавление: директива working_directory.
-
- *) Добавление: директива port_in_redirect.
-
- *) Исправление: если заголовок ответа бэкенда не помещался в один пакет,
- то происходил segmentation fault; ошибка появилась в 0.1.29.
-
- *) Исправление: если было сконфигурировано более 10 серверов или в
- сервере не описана директива "listen", то при запуске мог произойти
- segmentation fault.
-
- *) Исправление: если ответ не помещался во временный файл, то мог
- произойти segmentation fault.
-
- *) Исправление: nginx возвращал ошибку 400 на запросы вида
- "GET http://www.domain.com/uri HTTP/1.0"; ошибка появилась в 0.1.28.
-
-
-Изменения в nginx 0.1.34 26.05.2005
-
- *) Исправление: при включении больших ответов с помощью SSI рабочий
- процесс мог зациклиться.
-
- *) Исправление: переменные, устанавливаемые директивой "set", не были
- доступны в SSI.
-
- *) Добавление: директива autoindex_localtime.
-
- *) Исправление: пустое значение в директиве proxy_set_header запрещает
- передачу заголовка.
-
-
-Изменения в nginx 0.1.33 23.05.2005
-
- *) Исправление: nginx не собирался с параметром --without-pcre; ошибка
- появилась в 0.1.29.
-
- *) Исправление: 3, 5, 7 и 8 директив proxy_set_header на одном уровне
- вызывали bus fault при запуске.
-
- *) Исправление: в редиректах внутри HTTPS сервера был указан протокол
- HTTP.
-
- *) Исправление: если директива rewrite использовала выделения внутри
- директивы if, то возвращалась ошибка 500.
-
-
-Изменения в nginx 0.1.32 19.05.2005
-
- *) Исправление: в редиректах, выдаваемых с помощью директивы rewrite, не
- передавались аргументы; ошибка появилась в 0.1.29.
-
- *) Добавление: директива if поддерживает выделения в регулярных
- выражениях.
-
- *) Добавление: директива set поддерживает переменные и выделения из
- регулярных выражений.
-
- *) Добавление: в режиме прокси и FastCGI поддерживается строка заголовка
- "X-Accel-Redirect" в ответе бэкенда.
-
-
-Изменения в nginx 0.1.31 16.05.2005
-
- *) Исправление: при использовании SSL ответ мог передаваться не до
- конца.
-
- *) Исправление: ошибки при обработке SSI в ответе, полученного от
- FastCGI-сервера.
-
- *) Исправление: ошибки при использовании SSI и сжатия.
-
- *) Исправление: редирект с кодом 301 передавался без тела ответа; ошибка
- появилась в 0.1.30.
-
-
-Изменения в nginx 0.1.30 14.05.2005
-
- *) Исправление: при использовании SSI рабочий процесс мог зациклиться.
-
- *) Исправление: при использовании SSL ответ мог передаваться не до
- конца.
-
- *) Исправление: если длина части ответа, полученного за один раз от
- проксируемого или FastCGI сервера была равна 500 байт, то nginx
- возвращал код ответа 500; в режиме прокси ошибка появилась только в
- 0.1.29.
-
- *) Исправление: nginx не считал неверными директивы с 8-ю или 9-ю
- параметрами.
-
- *) Добавление: директива return может возвращать код ответа 204.
-
- *) Добавление: директива ignore_invalid_headers.
-
-
-Изменения в nginx 0.1.29 12.05.2005
-
- *) Добавление: модуль ngx_http_ssi_module поддерживает команду include
- virtual.
-
- *) Добавление: модуль ngx_http_ssi_module поддерживает условную команду
- вида 'if expr="$NAME"' и команды else и endif. Допускается только
- один уровень вложенности.
-
- *) Добавление: модуль ngx_http_ssi_module поддерживает две переменные
- DATE_LOCAL и DATE_GMT и команду config timefmt.
-
- *) Добавление: директива ssi_ignore_recycled_buffers.
-
- *) Исправление: если переменная QUERY_STRING не была определена, то в
- команде echo не ставилось значение по умолчанию.
-
- *) Изменение: модуль ngx_http_proxy_module полностью переписан.
-
- *) Добавление: директивы proxy_redirect, proxy_pass_request_headers,
- proxy_pass_request_body и proxy_method.
-
- *) Добавление: директива proxy_set_header. Директива proxy_x_var
- упразднена и должна быть заменена директивой proxy_set_header.
-
- *) Изменение: директива proxy_preserve_host упразднена и должна быть
- заменена директивами "proxy_set_header Host $host" и "proxy_redirect
- off" или директивой "proxy_set_header Host $host:$proxy_port" и
- соответствующими ей директивами proxy_redirect.
-
- *) Изменение: директива proxy_set_x_real_ip упразднена и должна быть
- заменена директивой "proxy_set_header X-Real-IP $remote_addr".
-
- *) Изменение: директива proxy_add_x_forwarded_for упразднена и должна
- быть заменена директивой
- "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for".
-
- *) Изменение: директива proxy_set_x_url упразднена и должна быть
- заменена директивой
- "proxy_set_header X-URL http://$host:$server_port$request_uri".
-
- *) Добавление: директива fastcgi_param.
-
- *) Изменение: директивы fastcgi_root, fastcgi_set_var и fastcgi_params
- упразднены и должны быть замены директивами fastcgi_param.
-
- *) Добавление: директива index может использовать переменные.
-
- *) Добавление: директива index может быть указана на уровне http и
- server.
-
- *) Изменение: только последний параметр в директиве index может быть
- абсолютным.
-
- *) Добавление: в директиве rewrite могут использоваться переменные.
-
- *) Добавление: директива internal.
-
- *) Добавление: переменные CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT,
- SERVER_ADDR, SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT,
- SERVER_NAME, REQUEST_METHOD, REQUEST_URI и REMOTE_USER.
-
- *) Изменение: nginx теперь передаёт неверные строки в заголовках запроса
- клиента и ответа бэкенда.
-
- *) Исправление: если бэкенд долго не передавал ответ и send_timeout был
- меньше, чем proxy_read_timeout, то клиенту возвращался ответ 408.
-
- *) Исправление: если бэкенд передавал неверную строку в заголовке
- ответа, то происходил segmentation fault; ошибка появилась в 0.1.26.
-
- *) Исправление: при использовании отказоустойчивой конфигурации в
- FastCGI мог происходить segmentation fault.
-
- *) Исправление: директива expires не удаляла уже установленные строки
- заголовка "Expires" и "Cache-Control".
-
- *) Исправление: nginx не учитывал завершающую точку в строке заголовка
- запроса "Host".
-
- *) Исправление: модуль ngx_http_auth_module не работал на Linux.
-
- *) Исправление: директива rewrite неверно работала, если в запросе
- присутствовали аргументы.
-
- *) Исправление: nginx не собирался на MacOS X.
-
-
-Изменения в nginx 0.1.28 08.04.2005
-
- *) Исправление: при проксировании больших файлов nginx сильно нагружал
- процессор.
-
- *) Исправление: nginx не собирался gcc 4.0 на Linux.
-
-
-Изменения в nginx 0.1.27 28.03.2005
-
- *) Добавление: параметр blocked в директиве valid_referers.
-
- *) Изменение: ошибки обработки заголовка запроса теперь записываются на
- уровне info, в лог также записывается имя сервера и строки заголовка
- запроса "Host" и "Referer".
-
- *) Изменение: при записи ошибок в лог записывается также строка
- заголовка запроса "Host".
-
- *) Добавление: директива proxy_pass_unparsed_uri. Специальная обработка
- символов "://" в URI, введённая в версии 0.1.11, теперь упразднена.
-
- *) Исправление: nginx не собирался на FreeBSD и Linux, если был указан
- параметр конфигурации --without-ngx_http_auth_basic_module.
-
-
-Изменения в nginx 0.1.26 22.03.2005
-
- *) Изменение: неверные строки заголовка, переданные клиентом, теперь
- игнорируется и записываются в error_log на уровне info.
-
- *) Изменение: при записи ошибок в лог записывается также имя сервера,
- при обращении к которому произошла ошибка.
-
- *) Добавление: модуль ngx_http_auth_basic_module и директивы auth_basic
- и auth_basic_user_file.
-
-
-Изменения в nginx 0.1.25 19.03.2005
-
- *) Исправление: nginx не работал на Linux parisc.
-
- *) Добавление: nginx теперь не запускается под FreeBSD, если значение
- sysctl kern.ipc.somaxconn слишком большое.
-
- *) Исправление: если модуль ngx_http_index_module делал внутреннее
- перенаправление запроса в модули ngx_http_proxy_module или
- ngx_http_fastcgi_module, то файл индекса не закрывался после
- обслуживания запроса.
-
- *) Добавление: директива proxy_pass может использоваться в location,
- заданных регулярным выражением.
-
- *) Добавление: модуль ngx_http_rewrite_filter_module поддерживает
- условия вида "if ($HTTP_USER_AGENT ~ MSIE)".
-
- *) Исправление: nginx очень медленно запускался при большом количестве
- адресов и использовании текстовых значений в директиве geo.
-
- *) Изменение: имя переменной в директиве geo нужно указывать, как $name.
- Прежний вариант без "$" пока работает, но вскоре будет убран.
-
- *) Добавление: параметр лога "%{VARIABLE}v".
-
- *) Добавление: директива "set $name value".
-
- *) Исправление: совместимость с gcc 4.0.
-
- *) Добавление: параметр автоконфигурации --with-openssl-opt=OPTIONS.
-
-
-Изменения в nginx 0.1.24 04.03.2005
-
- *) Добавление: модуль ngx_http_ssi_filter_module поддерживает переменные
- QUERY_STRING и DOCUMENT_URI.
-
- *) Исправление: модуль ngx_http_autoindex_module мог выдавать ответ 404
- на существующий каталог, если этот каталог был указан как alias.
-
- *) Исправление: модуль ngx_http_ssi_filter_module неправильно работал
- при больших ответах.
-
- *) Исправление: отсутствие строки заголовка "Referer" всегда считалось
- правильным referrer'ом.
-
-
-Изменения в nginx 0.1.23 01.03.2005
-
- *) Добавление: модуль ngx_http_ssi_filter_module и директивы ssi,
- ssi_silent_errors и ssi_min_file_chunk. Поддерживаются команды 'echo
- var="HTTP_..." default=""' и 'echo var="REMOTE_ADDR"'.
-
- *) Добавление: параметр лога %request_time.
-
- *) Добавление: если запрос пришёл без строки заголовка "Host", то
- директива proxy_preserve_host устанавливает в качестве этого
- заголовка первое имя сервера из директивы server_name.
-
- *) Исправление: nginx не собирался на платформах, отличных от i386,
- amd64, sparc и ppc; ошибка появилась в 0.1.22.
-
- *) Исправление: модуль ngx_http_autoindex_module теперь показывает
- информацию не о символическом линке, а о файле или каталоге, на
- который он указывает.
-
- *) Исправление: если клиенту ничего не передавалось, то параметр
- %apache_length записывал в лог отрицательную длину заголовка ответа.
-
-
-Изменения в nginx 0.1.22 22.02.2005
-
- *) Исправление: модуль ngx_http_stub_status_module показывал неверную
- статистику для обработанных соединений, если использовалось
- проксирование или FastCGI-сервер.
-
- *) Исправление: на Linux и Solaris установочные пути были неверно
- заключены в кавычки; ошибка появилась в 0.1.21.
-
-
-Изменения в nginx 0.1.21 22.02.2005
-
- *) Исправление: модуль ngx_http_stub_status_module показывал неверную
- статистику при использовании метода rtsig или при использовании
- нескольких рабочих процессов на SMP машине.
-
- *) Исправление: nginx не собирался компилятором icc под Линуксом или
- если библиотека zlib-1.2.x собиралась из исходных текстов.
-
- *) Исправление: nginx не собирался под NetBSD 2.0.
-
-
-Изменения в nginx 0.1.20 17.02.2005
-
- *) Добавление: новые параметры script_filename и remote_port в директиве
- fastcgi_params.
-
- *) Исправление: неправильно обрабатывался поток stderr от
- FastCGI-сервера.
-
-
-Изменения в nginx 0.1.19 16.02.2005
-
- *) Исправление: если в запросе есть нуль, то для локальных запросов
- теперь возвращается ошибка 404.
-
- *) Исправление: nginx не собирался под NetBSD 2.0.
-
- *) Исправление: во время чтения тела запроса клиента в SSL соединении
- мог произойти таймаут.
-
-
-Изменения в nginx 0.1.18 09.02.2005
-
- *) Изменение: для совместимости с Solaris 10 в директивах devpoll_events
- и devpoll_changes значения по умолчанию уменьшены с 512 до 32.
-
- *) Исправление: директивы proxy_set_x_var и fastcgi_set_var не
- наследовались.
-
- *) Исправление: в директиве rewrite, возвращающей редирект, аргументы
- присоединялись к URI через символ "&" вместо "?".
-
- *) Исправление: строки для модуля ngx_http_geo_module без символа ";" во
- включённом файле игнорировались.
-
- *) Добавление: модуль ngx_http_stub_status_module.
-
- *) Исправление: неизвестный формат лог-файла в директиве access_log
- вызывал segmentation fault.
-
- *) Добавление: новый параметр document_root в директиве fastcgi_params.
-
- *) Добавление: директива fastcgi_redirect_errors.
-
- *) Добавление: новый модификатор break в директиве rewrite позволяет
- прекратить цикл rewrite/location и устанавливает текущую конфигурацию
- для запроса.
-
-
-Изменения в nginx 0.1.17 03.02.2005
-
- *) Изменение: модуль ngx_http_rewrite_module полностью переписан. Теперь
- можно делать редиректы, возвращать коды ошибок и проверять переменные
- и рефереры. Эти директивы можно использовать внутри location.
- Директива redirect упразднена.
-
- *) Добавление: модуль ngx_http_geo_module.
-
- *) Добавление: директивы proxy_set_x_var и fastcgi_set_var.
-
- *) Исправление: конфигурация location с модификатором "=" могла
- использоваться в другом location.
-
- *) Исправление: правильный тип ответа выставлялся только для запросов, у
- которых в расширении были только маленькие буквы.
-
- *) Исправление: если для location установлен proxy_pass или
- fastcgi_pass, и доступ к нему запрещался, а ошибка перенаправлялась
- на статическую страницу, то происходил segmentation fault.
-
- *) Исправление: если в проксированном ответе в заголовке "Location"
- передавался относительный URL, то к нему добавлялось имя хоста и
- слэш; ошибка появилась в 0.1.14.
-
- *) Исправление: на Linux в лог не записывался текст системной ошибки.
-
-
-Изменения в nginx 0.1.16 25.01.2005
-
- *) Исправление: если ответ передавался chunk'ами, то при запросе HEAD
- выдавался завершающий chunk.
-
- *) Исправление: заголовок "Connection: keep-alive" выдавался, даже если
- директива keepalive_timeout запрещала использование keep-alive.
-
- *) Исправление: ошибки в модуле ngx_http_fastcgi_module вызывали
- segmentation fault.
-
- *) Исправление: при использовании SSL сжатый ответ мог передаваться не
- до конца.
-
- *) Исправление: опции TCP_NODELAY, TCP_NOPUSH и TCP_CORK, специфичные
- для TCP сокетов, не используются для unix domain сокетов.
-
- *) Добавление: директива rewrite поддерживает перезаписывание
- аргументов.
-
- *) Исправление: на запрос POST с заголовком "Content-Length: 0"
- возвращался ответ 400; ошибка появилась в 0.1.14.
-
-
-Изменения в nginx 0.1.15 19.01.2005
-
- *) Исправление: ошибка соединения с FastCGI-сервером вызывала
- segmentation fault.
-
- *) Исправление: корректная обработка регулярного выражения, в котором
- число выделенных частей не совпадает с числом подстановок.
-
- *) Добавление: location, который передаётся FastCGI-серверу, может быть
- задан с помощью регулярного выражения.
-
- *) Исправление: параметр FastCGI REQUEST_URI теперь передаётся вместе с
- аргументами и в том виде, в котором был получен от клиента.
-
- *) Исправление: для использования регулярных выражений в location нужно
- было собирать nginx вместе с ngx_http_rewrite_module.
-
- *) Исправление: если бэкенд слушал на 80-ом порту, то при использовании
- директивы "proxy_preserve_host on" в заголовке "Host" указывался
- также порт 80; ошибка появилась в 0.1.14.
-
- *) Исправление: если задать одинаковые пути в параметрах
- автоконфигурации --http-client-body-temp-path=PATH и
- --http-proxy-temp-path=PATH или --http-client-body-temp-path=PATH и
- --http-fastcgi-temp-path=PATH, то происходил segmentation fault.
-
-
-Изменения в nginx 0.1.14 18.01.2005
-
- *) Добавление: параметры автоконфигурации
- --http-client-body-temp-path=PATH, --http-proxy-temp-path=PATH и
- --http-fastcgi-temp-path=PATH
-
- *) Изменение: имя каталога с временными файлами, содержащие тело запроса
- клиента, задаётся директивой client_body_temp_path, по умолчанию
- <prefix>/client_body_temp.
-
- *) Добавление: модуль ngx_http_fastcgi_module и директивы fastcgi_pass,
- fastcgi_root, fastcgi_index, fastcgi_params, fastcgi_connect_timeout,
- fastcgi_send_timeout, fastcgi_read_timeout, fastcgi_send_lowat,
- fastcgi_header_buffer_size, fastcgi_buffers,
- fastcgi_busy_buffers_size, fastcgi_temp_path,
- fastcgi_max_temp_file_size, fastcgi_temp_file_write_size,
- fastcgi_next_upstream и fastcgi_x_powered_by.
-
- *) Исправление: ошибка "[alert] zero size buf"; ошибка появилась в
- 0.1.3.
-
- *) Изменение: в директиве proxy_pass нужно обязательно указывать URI
- после имени хоста.
-
- *) Изменение: если в URI встречался символ %3F, то он считался началом
- строки аргументов.
-
- *) Добавление: поддержка unix domain сокетов в модуле
- ngx_http_proxy_module.
-
- *) Добавление: директивы ssl_engine и ssl_ciphers.
- Спасибо Сергею Скворцову за SSL-акселератор.
-
-
-Изменения в nginx 0.1.13 21.12.2004
-
- *) Добавление: директивы server_names_hash и
- server_names_hash_threshold.
-
- *) Исправление: имена *.domain.tld в директиве server_name не работали.
-
- *) Исправление: параметр лога %request_length записывал неверную длину.
-
-
-Изменения в nginx 0.1.12 06.12.2004
-
- *) Добавление: параметр лога %request_length.
-
- *) Исправление: при использовании /dev/poll, select и poll на
- платформах, где возможны ложные срабатывания указанных методов, могли
- быть длительные задержки при обработке запроса по keep-alive
- соединению. Наблюдалось по крайней мере на Solaris с использованием
- /dev/poll.
-
- *) Исправление: директива send_lowat игнорируется на Linux, так как
- Linux не поддерживает опцию SO_SNDLOWAT.
-
-
-Изменения в nginx 0.1.11 02.12.2004
-
- *) Добавление: директива worker_priority.
-
- *) Изменение: под FreeBSD директивы tcp_nopush и tcp_nodelay вместе
- влияют на передачу ответа.
-
- *) Исправление: nginx не вызывал initgroups().
- Спасибо Андрею Ситникову и Андрею Нигматулину.
-
- *) Изменение: ngx_http_auto_index_module теперь выдаёт размер файлов в
- байтах.
-
- *) Исправление: ngx_http_auto_index_module возвращал ошибку 500, если в
- каталоге есть битый symlink.
-
- *) Исправление: файлы больше 4G не передавались с использованием
- sendfile.
-
- *) Исправление: если бэкенд резолвился в несколько адресов и при
- ожидании от него ответа происходила ошибка, то процесс зацикливался.
-
- *) Исправление: при использовании метода /dev/poll рабочий процесс мог
- завершиться с сообщением "unknown cycle".
-
- *) Исправление: ошибки "close() channel failed".
-
- *) Исправление: автоматическое определение групп nobody и nogroup.
-
- *) Исправление: директива send_lowat не работала на Linux.
-
- *) Исправление: если в конфигурации не было раздела events, то
- происходил segmentation fault.
-
- *) Исправление: nginx не собирался под OpenBSD.
-
- *) Исправление: двойные слэшы в "://" в URI превращались в ":/".
-
-
-Изменения в nginx 0.1.10 26.11.2004
-
- *) Исправление: если в запросе без аргументов есть "//", "/./", "/../"
- или "%XX", то терялся последний символ в строке запроса; ошибка
- появилась в 0.1.9.
-
- *) Исправление: исправление в версии 0.1.9 для файлов больше 2G на Linux
- не работало.
-
-
-Изменения в nginx 0.1.9 25.11.2004
-
- *) Исправление: если в запросе есть "//", "/./", "/../" или "%XX", то
- проксируемый запрос передавался без аргументов.
-
- *) Исправление: при сжатии больших ответов иногда они передавались не
- полностью.
-
- *) Исправление: не передавались файлы больше 2G на Linux,
- неподдерживающем sendfile64().
-
- *) Исправление: на Linux при конфигурации сборки нужно было обязательно
- использовать параметр --with-poll_module; ошибка появилась в 0.1.8.
-
-
-Изменения в nginx 0.1.8 20.11.2004
-
- *) Исправление: ошибка в модуле ngx_http_autoindex_module при показе
- длинных имён файлов.
-
- *) Добавление: модификатор "^~" в директиве location.
-
- *) Добавление: директива proxy_max_temp_file_size.
-
-
-Изменения в nginx 0.1.7 12.11.2004
-
- *) Исправление: при использовании sendfile, если передаваемый файл
- менялся, то мог произойти segmentation fault на FreeBSD; ошибка
- появилась в 0.1.5.
-
-
-Изменения в nginx 0.1.6 11.11.2004
-
- *) Исправление: при некоторых комбинациях директив location c
- регулярными выражениями использовалась конфигурация не из того
- location.
-
-
-Изменения в nginx 0.1.5 11.11.2004
-
- *) Исправление: на Solaris и Linux могло быть очень много сообщений
- "recvmsg() returned not enough data".
-
- *) Исправление: в режиме прокси без использования sendfile на Solaris
- возникала ошибка "writev() failed (22: Invalid argument)". На других
- платформах, не поддерживающих sendfile, процесс зацикливался.
-
- *) Исправление: при использовании sendfile в режиме прокси на Solaris
- возникал segmentation fault.
-
- *) Исправление: segmentation fault на Solaris.
-
- *) Исправление: обновление исполняемого файла на лету не работало на
- Linux.
-
- *) Исправление: в списке файлов, выдаваемом модулем
- ngx_http_autoindex_module, не перекодировались пробелы, кавычки и
- знаки процента.
-
- *) Изменение: уменьшение операций копирования.
-
- *) Добавление: директива userid_p3p.
-
-
-Изменения в nginx 0.1.4 26.10.2004
-
- *) Исправление: ошибка в модуле ngx_http_autoindex_module.
-
-
-Изменения в nginx 0.1.3 25.10.2004
-
- *) Добавление: модуль ngx_http_autoindex_module и директива autoindex.
-
- *) Добавление: директива proxy_set_x_url.
-
- *) Исправление: модуль проксировании мог привести к зацикливанию, если
- не использовался sendfile.
-
-
-Изменения в nginx 0.1.2 21.10.2004
-
- *) Добавление: параметры --user=USER, --group=GROUP и
- --with-ld-opt=OPTIONS в configure.
-
- *) Добавление: директива server_name поддерживает *.domain.tld.
-
- *) Исправление: улучшена переносимость на неизвестные платформы.
-
- *) Исправление: нельзя переконфигурировать nginx, если конфигурационный
- файл указан в командной строке; ошибка появилась в 0.1.1.
-
- *) Исправление: модуль проксировании мог привести к зацикливанию, если
- не использовался sendfile.
-
- *) Исправление: при использовании sendfile текст ответа не
- перекодировался согласно директивам модуля charset; ошибка появилась
- в 0.1.1.
-
- *) Исправление: очень редкая ошибка при обработке kqueue.
-
- *) Исправление: модуль сжатия сжимал уже сжатые ответы, полученные при
- проксировании.
-
-
-Изменения в nginx 0.1.1 11.10.2004
-
- *) Добавление: директива gzip_types.
-
- *) Добавление: директива tcp_nodelay.
-
- *) Добавление: директива send_lowat работает не только на платформах,
- поддерживающих kqueue NOTE_LOWAT, но и на всех, поддерживающих
- SO_SNDLOWAT.
-
- *) Добавление: эмуляция setproctitle() для Linux и Solaris.
-
- *) Исправление: ошибка при переписывании заголовка "Location" при
- проксировании.
-
- *) Исправление: ошибка в модуле ngx_http_chunked_module, приводившая к
- зацикливанию.
-
- *) Исправление: ошибки в модуле /dev/poll.
-
- *) Исправление: при проксировании и использовании временных файлов
- ответы портились.
-
- *) Исправление: бэкенду передавались запросы с неперекодированными
- символами.
-
- *) Исправление: на Linux 2.4 при конфигурации сборки нужно было
- обязательно использовать параметр --with-poll_module.
-
-
-Изменения в nginx 0.1.0 04.10.2004
-
- *) Первая публично доступная версия.
-
diff --git a/usr.sbin/nginx/LICENSE b/usr.sbin/nginx/LICENSE
deleted file mode 100644
index 4ed7a6fc7c6..00000000000
--- a/usr.sbin/nginx/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2002-2014 Igor Sysoev
- * Copyright (C) 2011-2014 Nginx, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
diff --git a/usr.sbin/nginx/Makefile.bsd-wrapper b/usr.sbin/nginx/Makefile.bsd-wrapper
deleted file mode 100644
index a9321ca953b..00000000000
--- a/usr.sbin/nginx/Makefile.bsd-wrapper
+++ /dev/null
@@ -1,104 +0,0 @@
-# Build wrapper for Nginx
-# $OpenBSD: Makefile.bsd-wrapper,v 1.17 2014/06/12 15:27:08 robert Exp $
-
-LNDIR= /usr/bin/lndir
-
-.include <bsd.own.mk>
-
-CONFIGURE_ARGS= --prefix=/var/www \
- --conf-path=/etc/nginx/nginx.conf \
- --sbin-path=/usr/sbin/nginx \
- --pid-path=/var/run/nginx.pid \
- --lock-path=/var/run/nginx.lock \
- --http-log-path=logs/access.log \
- --error-log-path=logs/error.log \
- --http-client-body-temp-path=/var/www/cache/client_body_temp \
- --http-proxy-temp-path=/var/www/cache/proxy_temp \
- --http-fastcgi-temp-path=/var/www/cache/fastcgi_temp \
- --http-scgi-temp-path=/var/www/cache/scgi_temp \
- --http-uwsgi-temp-path=/var/www/cache/uwsgi_temp \
- --user=www \
- --group=www \
- --with-http_gzip_static_module \
- --with-http_ssl_module \
- --with-http_stub_status_module \
- --with-ipv6 \
- --without-mail_pop3_module \
- --without-mail_imap_module \
- --without-mail_smtp_module
-
-MAN+= ${.OBJDIR}/objs/nginx.8 man/nginx.conf.5
-
-all: ${.OBJDIR}/objs/ngx_auto_config.h
- @cd ${.OBJDIR} && ${MAKE}
-
-BEFOREMAN=${.OBJDIR}/objs/ngx_auto_config.h
-
-${.OBJDIR}/objs/nginx.8: ${BEFOREMAN}
- cd ${.OBJDIR} && ${MAKE} -f objs/Makefile manpage
-
-${.OBJDIR}/objs/ngx_auto_config.h: ${.OBJDIR}/configure
- @cd ${.OBJDIR} && CC="${CC}" CORE_LINK="${CORE_LINK}" \
- OPTIM="${CFLAGS} ${COPTS}" \
- PATH="/sbin:/usr/sbin:/bin:/usr/bin" \
- sh configure ${CONFIGURE_ARGS}
-
-.if !exists(${.OBJDIR}/configure)
-${.OBJDIR}/configure: ${.CURDIR}/configure
- ${LNDIR} -s -e obj -e obj.${MACHINE_ARCH} -e Makefile.bsd-wrapper ${.CURDIR}
-.endif
-
-.if ${.OBJDIR} == ${.CURDIR}
-clean:
- -@cd ${.OBJDIR} && ${MAKE} clean
-.else
-clean:
- @cd ${.OBJDIR} && find . \! -type d -print0 | xargs -0r rm
-.endif
-
-cleandir: clean
-
-prereq:
-# nothing left
-
-test:
- # Nothing here so far...
-
-depend:
- # Nothing here so far...
-
-lint:
- # Nothing here so far...
-
-tags:
- # Nothing here so far...
-
-distribution:
- ${INSTALL} -C -o root -g wheel -m 0644 \
- ${.CURDIR}/conf/fastcgi_params \
- ${.CURDIR}/conf/koi-utf \
- ${.CURDIR}/conf/koi-win \
- ${.CURDIR}/conf/mime.types \
- ${.CURDIR}/conf/nginx.conf \
- ${.CURDIR}/conf/scgi_params \
- ${.CURDIR}/conf/uwsgi_params \
- ${.CURDIR}/conf/win-utf \
- ${DESTDIR}/etc/nginx/
- ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 0444 \
- ${.CURDIR}/html/50x.html \
- ${DESTDIR}/var/www/htdocs/
-
-.ifdef NOMAN
-maninstall:
- @echo NOMAN is set
-.endif
-
-install: maninstall
- ${INSTALL} ${INSTALL_COPY} ${INSTALL_STRIP} -o ${BINOWN} \
- -g ${BINGRP} -m ${BINMODE} objs/nginx ${DESTDIR}/usr/sbin/nginx
-
-.include <bsd.obj.mk>
-.include <bsd.subdir.mk>
-.ifndef NOMAN
-.include <bsd.man.mk>
-.endif
diff --git a/usr.sbin/nginx/README b/usr.sbin/nginx/README
deleted file mode 100644
index 2f68e14e0d8..00000000000
--- a/usr.sbin/nginx/README
+++ /dev/null
@@ -1,3 +0,0 @@
-
-Documentation is available at http://nginx.org
-
diff --git a/usr.sbin/nginx/README.OpenBSD b/usr.sbin/nginx/README.OpenBSD
deleted file mode 100644
index b157be9eb79..00000000000
--- a/usr.sbin/nginx/README.OpenBSD
+++ /dev/null
@@ -1,33 +0,0 @@
-Modified files by OpenBSD:
-- auto/cc/gcc
-- auto/install
-- auto/lib/pcre/conf
-- auto/make
-- auto/sources
-- conf/fastcgi_params
-- conf/koi-utf
-- conf/koi-win
-- conf/mime.types
-- conf/nginx.conf
-- conf/scgi_params
-- conf/uwsgi_params
-- conf/win-utf
-- man/nginx.8
-- src/core/nginx.c
-- src/core/ngx_cycle.c
-- src/core/ngx_file.c
-- src/core/ngx_log.c
-- src/core/ngx_log.h
-- src/core/ngx_string.c
-- src/core/ngx_string.h
-- src/http/modules/ngx_http_auth_basic_module.c
-- src/http/modules/ngx_http_log_module.c
-- src/http/ngx_http_core_module.c
-- src/http/ngx_http_request.c
-- src/os/unix/ngx_process_cycle.c
-- src/os/unix/ngx_process_cycle.h
-- src/pcre/pcre_compile.c
-- src/pcre/pcre_exec.c
-
-The syslog patch has been applied from:
-https://github.com/yaoweibin/nginx_syslog_patch
diff --git a/usr.sbin/nginx/auto/cc/acc b/usr.sbin/nginx/auto/cc/acc
deleted file mode 100644
index 6baee672ad4..00000000000
--- a/usr.sbin/nginx/auto/cc/acc
+++ /dev/null
@@ -1,15 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-# aCC: HP ANSI C++ B3910B A.03.55.02
-
-# C89 mode
-
-CFLAGS="$CFLAGS -Ae"
-CC_TEST_FLAGS="-Ae"
-
-PCRE_OPT="$PCRE_OPT -Ae"
-ZLIB_OPT="$ZLIB_OPT -Ae"
-MD5_OPT="$MD5_OPT -Ae"
diff --git a/usr.sbin/nginx/auto/cc/bcc b/usr.sbin/nginx/auto/cc/bcc
deleted file mode 100644
index ec82e60fb13..00000000000
--- a/usr.sbin/nginx/auto/cc/bcc
+++ /dev/null
@@ -1,72 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-# Borland C++ 5.5
-
-# optimizations
-
-# maximize speed
-CFLAGS="$CFLAGS -O2"
-
-case $CPU in
- pentium)
- # optimize for Pentium and Athlon
- CPU_OPT="-5"
- ;;
-
- pentiumpro)
- # optimize for Pentium Pro, Pentium II and Pentium III
- CPU_OPT="-6"
- ;;
-esac
-
-# __stdcall
-#CPU_OPT="$CPU_OPT -ps"
-# __fastcall
-#CPU_OPT="$CPU_OPT -pr"
-
-CFLAGS="$CFLAGS $CPU_OPT"
-
-# multithreaded
-CFLAGS="$CFLAGS -tWM"
-
-# stop on warning
-CFLAGS="$CFLAGS -w!"
-
-# disable logo
-CFLAGS="$CFLAGS -q"
-
-
-# precompiled headers
-CORE_DEPS="$CORE_DEPS $NGX_OBJS/ngx_config.csm"
-NGX_PCH="$NGX_OBJS/ngx_config.csm"
-NGX_BUILD_PCH="-H=$NGX_OBJS/ngx_config.csm"
-NGX_USE_PCH="-Hu -H=$NGX_OBJS/ngx_config.csm"
-
-
-# Win32 GUI mode application
-#LINK="\$(CC) -laa"
-
-
-# the resource file
-NGX_RES="$NGX_OBJS/nginx.res"
-NGX_RCC="brcc32 -fo$NGX_OBJS/nginx.res \$(CORE_INCS) $NGX_WIN32_RC"
-# the pragma allows to link the resource file using bcc32 and
-# to avoid the direct ilink32 calling and the c0w32.obj's WinMain/main problem
-NGX_PRAGMA="#pragma resource \"$NGX_OBJS/nginx.res\""
-
-
-ngx_include_opt="-I"
-ngx_objout="-o"
-ngx_binout="-e"
-ngx_objext="obj"
-ngx_binext=".exe"
-
-ngx_long_start='@&&|
- '
-ngx_long_end='|'
-
-ngx_regex_dirsep='\\'
-ngx_dirsep="\\"
diff --git a/usr.sbin/nginx/auto/cc/ccc b/usr.sbin/nginx/auto/cc/ccc
deleted file mode 100644
index c964045105d..00000000000
--- a/usr.sbin/nginx/auto/cc/ccc
+++ /dev/null
@@ -1,46 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-# Compaq C V6.5-207
-
-ngx_include_opt="-I"
-
-# warnings
-
-CFLAGS="$CFLAGS -msg_enable level6 -msg_fatal level6"
-
-CFLAGS="$CFLAGS -msg_disable unknownmacro"
-CFLAGS="$CFLAGS -msg_disable unusedincl"
-CFLAGS="$CFLAGS -msg_disable unnecincl"
-CFLAGS="$CFLAGS -msg_disable nestincl"
-CFLAGS="$CFLAGS -msg_disable strctpadding"
-CFLAGS="$CFLAGS -msg_disable ansialiascast"
-CFLAGS="$CFLAGS -msg_disable inlinestoclsmod"
-CFLAGS="$CFLAGS -msg_disable cxxkeyword"
-CFLAGS="$CFLAGS -msg_disable longlongsufx"
-CFLAGS="$CFLAGS -msg_disable valuepres"
-
-# STUB
-CFLAGS="$CFLAGS -msg_disable truncintcast"
-CFLAGS="$CFLAGS -msg_disable trunclongcast"
-
-CFLAGS="$CFLAGS -msg_disable truncintasn"
-CFLAGS="$CFLAGS -msg_disable trunclongint"
-CFLAGS="$CFLAGS -msg_disable intconcastsgn"
-CFLAGS="$CFLAGS -msg_disable intconstsign"
-CFLAGS="$CFLAGS -msg_disable switchlong"
-CFLAGS="$CFLAGS -msg_disable subscrbounds2"
-
-CFLAGS="$CFLAGS -msg_disable hexoctunsign"
-
-CFLAGS="$CFLAGS -msg_disable ignorecallval"
-CFLAGS="$CFLAGS -msg_disable nonstandcast"
-CFLAGS="$CFLAGS -msg_disable embedcomment"
-CFLAGS="$CFLAGS -msg_disable unreachcode"
-CFLAGS="$CFLAGS -msg_disable questcompare2"
-CFLAGS="$CFLAGS -msg_disable unusedtop"
-CFLAGS="$CFLAGS -msg_disable unrefdecl"
-
-CFLAGS="$CFLAGS -msg_disable bitnotint"
diff --git a/usr.sbin/nginx/auto/cc/clang b/usr.sbin/nginx/auto/cc/clang
deleted file mode 100644
index baaf4baa23a..00000000000
--- a/usr.sbin/nginx/auto/cc/clang
+++ /dev/null
@@ -1,99 +0,0 @@
-
-# Copyright (C) Nginx, Inc.
-
-
-# clang
-
-
-NGX_CLANG_VER=`$CC -v 2>&1 | grep '\(clang\|LLVM\) version' 2>&1 \
- | sed -e 's/^.* version \(.*\)/\1/'`
-
-echo " + clang version: $NGX_CLANG_VER"
-
-have=NGX_COMPILER value="\"clang $NGX_CLANG_VER\"" . auto/define
-
-
-CC_TEST_FLAGS="-pipe"
-
-
-# optimizations
-
-#NGX_CLANG_OPT="-O2"
-#NGX_CLANG_OPT="-Oz"
-NGX_CLANG_OPT="-O"
-
-case $CPU in
- pentium)
- # optimize for Pentium
- CPU_OPT="-march=pentium"
- NGX_CPU_CACHE_LINE=32
- ;;
-
- pentiumpro | pentium3)
- # optimize for Pentium Pro, Pentium II and Pentium III
- CPU_OPT="-march=pentiumpro"
- NGX_CPU_CACHE_LINE=32
- ;;
-
- pentium4)
- # optimize for Pentium 4
- CPU_OPT="-march=pentium4"
- NGX_CPU_CACHE_LINE=128
- ;;
-
- athlon)
- # optimize for Athlon
- CPU_OPT="-march=athlon"
- NGX_CPU_CACHE_LINE=64
- ;;
-
- opteron)
- # optimize for Opteron
- CPU_OPT="-march=opteron"
- NGX_CPU_CACHE_LINE=64
- ;;
-
-esac
-
-CC_AUX_FLAGS="$CC_AUX_FLAGS $CPU_OPT"
-
-
-CFLAGS="$CFLAGS -pipe $CPU_OPT"
-
-if [ ".$PCRE_OPT" = "." ]; then
- PCRE_OPT="-O2 -pipe $CPU_OPT"
-else
- PCRE_OPT="$PCRE_OPT -pipe"
-fi
-
-if [ ".$MD5_OPT" = "." ]; then
- MD5_OPT="-O2 -pipe $CPU_OPT"
-else
- MD5_OPT="$MD5_OPT -pipe"
-fi
-
-if [ ".$ZLIB_OPT" = "." ]; then
- ZLIB_OPT="-O2 -pipe $CPU_OPT"
-else
- ZLIB_OPT="$ZLIB_OPT -pipe"
-fi
-
-
-# warnings
-
-CFLAGS="$CFLAGS $NGX_CLANG_OPT -Wall -Wextra -Wpointer-arith"
-CFLAGS="$CFLAGS -Wconditional-uninitialized"
-#CFLAGS="$CFLAGS -Wmissing-prototypes"
-
-# we have a lot of unused function arguments
-CFLAGS="$CFLAGS -Wno-unused-parameter"
-
-# stop on warning
-CFLAGS="$CFLAGS -Werror"
-
-# debug
-CFLAGS="$CFLAGS -g"
-
-if [ ".$CPP" = "." ]; then
- CPP="$CC -E"
-fi
diff --git a/usr.sbin/nginx/auto/cc/conf b/usr.sbin/nginx/auto/cc/conf
deleted file mode 100644
index edc6d74ddfa..00000000000
--- a/usr.sbin/nginx/auto/cc/conf
+++ /dev/null
@@ -1,218 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-LINK="\$(CC)"
-
-ngx_include_opt="-I "
-ngx_compile_opt="-c"
-ngx_objout="-o "
-ngx_binout="-o "
-ngx_objext="o"
-ngx_binext=
-
-ngx_long_start=
-ngx_long_end=
-
-ngx_regex_dirsep="\/"
-ngx_dirsep='/'
-
-ngx_regex_cont=' \\\
- '
-ngx_cont=' \
- '
-ngx_tab=' \
- '
-ngx_spacer=
-
-ngx_long_regex_cont=$ngx_regex_cont
-ngx_long_cont=$ngx_cont
-
-. auto/cc/name
-
-if test -n "$CFLAGS"; then
-
- CC_TEST_FLAGS="$CFLAGS $NGX_CC_OPT"
-
- case $NGX_CC_NAME in
-
- ccc)
- # Compaq C V6.5-207
-
- ngx_include_opt="-I"
- ;;
-
- sunc)
-
- case "$NGX_MACHINE" in
-
- i86pc)
- NGX_AUX=" src/os/unix/ngx_sunpro_x86.il"
- ;;
-
- sun4u | sun4v)
- NGX_AUX=" src/os/unix/ngx_sunpro_sparc64.il"
- ;;
-
- esac
-
- case $CPU in
-
- amd64)
- NGX_AUX=" src/os/unix/ngx_sunpro_amd64.il"
- ;;
-
- esac
- ;;
-
- esac
-
-else
-
- case $NGX_CC_NAME in
- gcc)
- # gcc 2.7.2.3, 2.8.1, 2.95.4, egcs-1.1.2
- # 3.0.4, 3.1.1, 3.2.3, 3.3.2, 3.3.3, 3.3.4, 3.4.0, 3.4.2
- # 4.0.0, 4.0.1, 4.1.0
-
- . auto/cc/gcc
- ;;
-
- clang)
- # Clang C compiler
-
- . auto/cc/clang
- ;;
-
- icc)
- # Intel C++ compiler 7.1, 8.0, 8.1
-
- . auto/cc/icc
- ;;
-
- sunc)
- # Sun C 5.7 Patch 117837-04 2005/05/11
-
- . auto/cc/sunc
- ;;
-
- ccc)
- # Compaq C V6.5-207
-
- . auto/cc/ccc
- ;;
-
- acc)
- # aCC: HP ANSI C++ B3910B A.03.55.02
-
- . auto/cc/acc
- ;;
-
- msvc*)
- # MSVC++ 6.0 SP2, MSVC++ Toolkit 2003
-
- . auto/cc/msvc
- ;;
-
- owc)
- # Open Watcom C 1.0, 1.2
-
- . auto/cc/owc
- ;;
-
- bcc)
- # Borland C++ 5.5
-
- . auto/cc/bcc
- ;;
-
- esac
-
- CC_TEST_FLAGS="$CC_TEST_FLAGS $NGX_CC_OPT"
-
-fi
-
-CFLAGS="$CFLAGS $NGX_CC_OPT"
-NGX_TEST_LD_OPT="$NGX_LD_OPT"
-
-if [ "$NGX_PLATFORM" != win32 ]; then
-
- if test -n "$NGX_LD_OPT"; then
- ngx_feature=--with-ld-opt=\"$NGX_LD_OPT\"
- ngx_feature_name=
- ngx_feature_run=no
- ngx_feature_incs=
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test=
- . auto/feature
-
- if [ $ngx_found = no ]; then
- echo $0: error: the invalid value in --with-ld-opt=\"$NGX_LD_OPT\"
- echo
- exit 1
- fi
- fi
-
-
- ngx_feature="gcc builtin atomic operations"
- ngx_feature_name=NGX_HAVE_GCC_ATOMIC
- ngx_feature_run=yes
- ngx_feature_incs=
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test="long n = 0;
- if (!__sync_bool_compare_and_swap(&n, 0, 1))
- return 1;
- if (__sync_fetch_and_add(&n, 1) != 1)
- return 1;
- if (n != 2)
- return 1;
- __sync_synchronize();"
- . auto/feature
-
-
- if [ "$NGX_CC_NAME" = "ccc" ]; then
- echo "checking for C99 variadic macros ... disabled"
- else
- ngx_feature="C99 variadic macros"
- ngx_feature_name="NGX_HAVE_C99_VARIADIC_MACROS"
- ngx_feature_run=yes
- ngx_feature_incs="#include <stdio.h>
-#define var(dummy, ...) sprintf(__VA_ARGS__)"
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test="char buf[30]; buf[0] = '0';
- var(0, buf, \"%d\", 1);
- if (buf[0] != '1') return 1"
- . auto/feature
- fi
-
-
- ngx_feature="gcc variadic macros"
- ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS"
- ngx_feature_run=yes
- ngx_feature_incs="#include <stdio.h>
-#define var(dummy, args...) sprintf(args)"
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test="char buf[30]; buf[0] = '0';
- var(0, buf, \"%d\", 1);
- if (buf[0] != '1') return 1"
- . auto/feature
-
-
-# ngx_feature="inline"
-# ngx_feature_name=
-# ngx_feature_run=no
-# ngx_feature_incs="int inline f(void) { return 1 }"
-# ngx_feature_path=
-# ngx_feature_libs=
-# ngx_feature_test=
-# . auto/feature
-#
-# if [ $ngx_found = yes ]; then
-# fi
-
-fi
diff --git a/usr.sbin/nginx/auto/cc/gcc b/usr.sbin/nginx/auto/cc/gcc
deleted file mode 100644
index eb4bf92bd4f..00000000000
--- a/usr.sbin/nginx/auto/cc/gcc
+++ /dev/null
@@ -1,181 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-# gcc 2.7.2.3, 2.8.1, 2.95.4, egcs-1.1.2
-# 3.0.4, 3.1.1, 3.2.3, 3.3.2, 3.3.3, 3.3.4, 3.4.0, 3.4.2
-# 4.0.0, 4.0.1, 4.1.0
-
-
-NGX_GCC_VER=`$CC -v 2>&1 | grep 'gcc version' 2>&1 \
- | sed -e 's/^.* version \(.*\)/\1/'`
-
-echo " + gcc version: $NGX_GCC_VER"
-
-have=NGX_COMPILER value="\"gcc $NGX_GCC_VER\"" . auto/define
-
-
-# Solaris 7's /usr/ccs/bin/as does not support "-pipe"
-
-CC_TEST_FLAGS="-pipe"
-
-ngx_feature="gcc -pipe switch"
-ngx_feature_name=
-ngx_feature_run=no
-ngx_feature_incs=
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test=
-. auto/feature
-
-CC_TEST_FLAGS=
-
-#if [ $ngx_found = yes ]; then
-# PIPE="-pipe"
-#fi
-
-
-case "$NGX_MACHINE" in
-
- sun4u | sun4v | sparc | sparc64 )
- # "-mcpu=v9" enables the "casa" assembler instruction
- CFLAGS="$CFLAGS -mcpu=v9"
- ;;
-
-esac
-
-
-# optimizations
-
-#NGX_GCC_OPT="-O2"
-#NGX_GCC_OPT="-Os"
-NGX_GCC_OPT="$OPTIM"
-
-#CFLAGS="$CFLAGS -fomit-frame-pointer"
-
-case $CPU in
- pentium)
- # optimize for Pentium and Athlon
- CPU_OPT="-march=pentium"
- NGX_CPU_CACHE_LINE=32
- ;;
-
- pentiumpro | pentium3)
- # optimize for Pentium Pro, Pentium II and Pentium III
- CPU_OPT="-march=pentiumpro"
- NGX_CPU_CACHE_LINE=32
- ;;
-
- pentium4)
- # optimize for Pentium 4, gcc 3.x
- CPU_OPT="-march=pentium4"
- NGX_CPU_CACHE_LINE=128
- ;;
-
- athlon)
- # optimize for Athlon, gcc 3.x
- CPU_OPT="-march=athlon"
- NGX_CPU_CACHE_LINE=64
- ;;
-
- opteron)
- # optimize for Opteron, gcc 3.x
- CPU_OPT="-march=opteron"
- NGX_CPU_CACHE_LINE=64
- ;;
-
- sparc32)
- # build 32-bit UltraSparc binary
- CPU_OPT="-m32"
- CORE_LINK="$CORE_LINK -m32"
- NGX_CPU_CACHE_LINE=64
- ;;
-
- sparc64)
- # build 64-bit UltraSparc binary
- CPU_OPT="-m64"
- CORE_LINK="$CORE_LINK -m64"
- NGX_CPU_CACHE_LINE=64
- ;;
-
- ppc64)
- # build 64-bit PowerPC binary
- CPU_OPT="-m64"
- CPU_OPT="$CPU_OPT -falign-functions=32 -falign-labels=32"
- CPU_OPT="$CPU_OPT -falign-loops=32 -falign-jumps=32"
- CORE_LINK="$CORE_LINK -m64"
- NGX_CPU_CACHE_LINE=128
- ;;
-
-esac
-
-CC_AUX_FLAGS="$CC_AUX_FLAGS $CPU_OPT"
-
-case "$NGX_GCC_VER" in
- 2.7*)
- # batch build
- CPU_OPT=
- ;;
-esac
-
-
-CFLAGS="$CFLAGS $PIPE $CPU_OPT"
-
-if [ ".$PCRE_OPT" = "." ]; then
- PCRE_OPT="-O2 -fomit-frame-pointer $PIPE $CPU_OPT"
-else
- PCRE_OPT="$PCRE_OPT $PIPE"
-fi
-
-if [ ".$MD5_OPT" = "." ]; then
- MD5_OPT="-O2 -fomit-frame-pointer $PIPE $CPU_OPT"
-else
- MD5_OPT="$MD5_OPT $PIPE"
-fi
-
-if [ ".$ZLIB_OPT" = "." ]; then
- ZLIB_OPT="-O2 -fomit-frame-pointer $PIPE $CPU_OPT"
-else
- ZLIB_OPT="$ZLIB_OPT $PIPE"
-fi
-
-
-# warnings
-
-# -W requires at least -O
-CFLAGS="$CFLAGS ${NGX_GCC_OPT:--O} -W"
-
-CFLAGS="$CFLAGS -Wall -Wpointer-arith"
-#CFLAGS="$CFLAGS -Wconversion"
-#CFLAGS="$CFLAGS -Winline"
-#CFLAGS="$CFLAGS -Wmissing-prototypes"
-
-
-case "$NGX_GCC_VER" in
- 3.* | 4.* )
- # we have a lot of the unused function arguments
- CFLAGS="$CFLAGS -Wno-unused-parameter"
- # 4.2.1 shows the warning in wrong places
- #CFLAGS="$CFLAGS -Wunreachable-code"
- ;;
-
- *)
- # we have a lot of the unused function arguments
- CFLAGS="$CFLAGS -Wno-unused"
- ;;
-esac
-
-
-# stop on warning
-CFLAGS="$CFLAGS -Werror"
-
-# debug
-CFLAGS="$CFLAGS -g"
-
-# DragonFly's gcc3 generates DWARF
-#CFLAGS="$CFLAGS -g -gstabs"
-
-if [ ".$CPP" = "." ]; then
- CPP="$CC -E"
-fi
diff --git a/usr.sbin/nginx/auto/cc/icc b/usr.sbin/nginx/auto/cc/icc
deleted file mode 100644
index 1d83ed37a03..00000000000
--- a/usr.sbin/nginx/auto/cc/icc
+++ /dev/null
@@ -1,121 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-# Intel C++ compiler 7.1, 8.0, 8.1, 9.0, 11.1
-
-NGX_ICC_VER=`$CC -V 2>&1 | grep 'Version' 2>&1 \
- | sed -e 's/^.* Version \([^ ]*\) *Build.*$/\1/'`
-
-echo " + icc version: $NGX_ICC_VER"
-
-have=NGX_COMPILER value="\"Intel C Compiler $NGX_ICC_VER\"" . auto/define
-
-
-# optimizations
-
-CFLAGS="$CFLAGS -O"
-
-CORE_LINK="$CORE_LINK -opt_report_file=$NGX_OBJS/opt_report_file"
-
-
-case $CPU in
- pentium)
- # optimize for Pentium and Athlon
- CPU_OPT="-march=pentium"
- ;;
-
- pentiumpro)
- # optimize for Pentium Pro, Pentium II and Pentium III
- CPU_OPT="-mcpu=pentiumpro -march=pentiumpro"
- ;;
-
- pentium4)
- # optimize for Pentium 4, default
- CPU_OPT="-march=pentium4"
- ;;
-esac
-
-CFLAGS="$CFLAGS $CPU_OPT"
-
-if [ ".$PCRE_OPT" = "." ]; then
- PCRE_OPT="-O $CPU_OPT"
-fi
-
-if [ ".$MD5_OPT" = "." ]; then
- MD5_OPT="-O $CPU_OPT"
-fi
-
-if [ ".$ZLIB_OPT" = "." ]; then
- ZLIB_OPT="-O $CPU_OPT"
-fi
-
-
-# warnings
-
-CFLAGS="$CFLAGS -w2"
-
-# disable some warnings
-
-# invalid type conversion: "int" to "char *"
-CFLAGS="$CFLAGS -wd171"
-# argument is incompatible with corresponding format string conversion
-CFLAGS="$CFLAGS -wd181"
-# zero used for undefined preprocessing identifier
-CFLAGS="$CFLAGS -wd193"
-# the format string ends before this argument
-CFLAGS="$CFLAGS -wd268"
-# invalid format string conversion
-CFLAGS="$CFLAGS -wd269"
-# conversion from "long long" to "size_t" may lose significant bits
-CFLAGS="$CFLAGS -wd810"
-# parameter was never referenced
-CFLAGS="$CFLAGS -wd869"
-# attribute "unused" is only allowed in a function definition, warning on pTHX_
-CFLAGS="$CFLAGS -wd1301"
-
-# STUB
-# enumerated type mixed with another type
-CFLAGS="$CFLAGS -wd188"
-# controlling expression is constant
-CFLAGS="$CFLAGS -wd279"
-# operands are evaluated in unspecified order
-CFLAGS="$CFLAGS -wd981"
-# external definition with no prior declaration
-CFLAGS="$CFLAGS -wd1418"
-# external declaration in primary source file
-CFLAGS="$CFLAGS -wd1419"
-
-case "$NGX_ICC_VER" in
- 9.*)
- # "cc" clobber ignored, warnings for Liunx's htonl()/htons()
- CFLAGS="$CFLAGS -wd1469"
- # explicit conversion of a 64-bit integral type to a smaller
- # integral type
- CFLAGS="$CFLAGS -wd1683"
- # conversion from pointer to same-sized integral type,
- # warning on offsetof()
- CFLAGS="$CFLAGS -wd1684"
- # floating-point equality and inequality comparisons are unreliable,
- # warning on SvTRUE()
- CFLAGS="$CFLAGS -wd1572"
- ;;
-
- 8.*)
- # "cc" clobber ignored, warnings for Liunx's htonl()/htons()
- CFLAGS="$CFLAGS -wd1469"
- # floating-point equality and inequality comparisons are unreliable,
- # warning on SvTRUE()
- CFLAGS="$CFLAGS -wd1572"
- ;;
-
- *)
- ;;
-esac
-
-# stop on warning
-CFLAGS="$CFLAGS -Werror"
-
-# debug
-CFLAGS="$CFLAGS -g"
diff --git a/usr.sbin/nginx/auto/cc/msvc b/usr.sbin/nginx/auto/cc/msvc
deleted file mode 100644
index 393ba321499..00000000000
--- a/usr.sbin/nginx/auto/cc/msvc
+++ /dev/null
@@ -1,136 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-# MSVC 6.0 SP2
-# MSVC Toolkit 2003 (7.1)
-# MSVC 2005 Express Edition SP1 (8.0)
-
-# optimizations
-
-# maximize speed, equivalent to -Og -Oi -Ot -Oy -Ob2 -Gs -GF -Gy
-CFLAGS="$CFLAGS -O2"
-
-# enable global optimization
-#CFLAGS="$CFLAGS -Og"
-# enable intrinsic functions
-#CFLAGS="$CFLAGS -Oi"
-
-# disable inline expansion
-#CFLAGS="$CFLAGS -Ob0"
-# explicit inline expansion
-#CFLAGS="$CFLAGS -Ob1"
-# explicit and implicit inline expansion
-#CFLAGS="$CFLAGS -Ob2"
-
-# enable frame pointer omission
-#CFLAGS="$CFLAGS -Oy"
-# disable stack checking calls
-#CFLAGS="$CFLAGS -Gs"
-
-# pools strings as read/write
-#CFLAGS="$CFLAGS -Gf"
-# pools strings as read-only
-#CFLAGS="$CFLAGS -GF"
-
-
-case $CPU in
- pentium)
- # optimize for Pentium and Athlon
- CPU_OPT="-G5"
- ;;
-
- pentiumpro)
- # optimize for Pentium Pro, Pentium II and Pentium III
- CPU_OPT="-G6"
- ;;
-
- pentium4)
- # optimize for Pentium 4, MSVC 7
- CPU_OPT="-G7"
- ;;
-esac
-
-# __cdecl, default, must be used with OpenSSL, md5 asm, and sha1 asm
-#CPU_OPT="$CPU_OPT -Gd"
-# __stdcall
-#CPU_OPT="$CPU_OPT -Gz"
-# __fastcall
-#CPU_OPT="$CPU_OPT -Gr"
-
-
-CFLAGS="$CFLAGS $CPU_OPT"
-
-
-# warnings
-
-CFLAGS="$CFLAGS -W4"
-
-# stop on warning
-CFLAGS="$CFLAGS -WX"
-
-# disable logo
-CFLAGS="$CFLAGS -nologo"
-
-# the link flags
-CORE_LINK="$CORE_LINK -link -verbose:lib"
-
-# link with libcmt.lib, multithreaded
-LIBC="-MT"
-# link with msvcrt.dll
-# however, MSVC Toolkit 2003 has no MSVCRT.LIB
-#LIBC="-MD"
-
-CFLAGS="$CFLAGS $LIBC"
-
-CORE_LIBS="$CORE_LIBS kernel32.lib user32.lib"
-
-# Win32 GUI mode application
-#CORE_LINK="$CORE_LINK -subsystem:windows -entry:mainCRTStartup"
-
-# debug
-# msvc8 under Wine issues
-# Program database manager mismatch; please check your installation
-if [ $NGX_CC_NAME != msvc8 ]; then
- CFLAGS="$CFLAGS -Zi"
- CORE_LINK="$CORE_LINK -debug"
-fi
-
-
-# MSVC 2005 supports C99 variadic macros
-if [ $NGX_CC_NAME = msvc8 ]; then
- have=NGX_HAVE_C99_VARIADIC_MACROS . auto/have
-fi
-
-
-# precompiled headers
-CORE_DEPS="$CORE_DEPS $NGX_OBJS/ngx_config.pch"
-CORE_LINK="$CORE_LINK $NGX_OBJS/ngx_pch.obj"
-NGX_PCH="$NGX_OBJS/ngx_config.pch"
-NGX_BUILD_PCH="-Ycngx_config.h -Fp$NGX_OBJS/ngx_config.pch"
-NGX_USE_PCH="-Yungx_config.h -Fp$NGX_OBJS/ngx_config.pch"
-
-
-# the resource file
-NGX_RES="$NGX_OBJS/nginx.res"
-NGX_RCC="rc -fo$NGX_RES \$(CORE_INCS) $NGX_WIN32_RC"
-CORE_LINK="$NGX_RES $CORE_LINK"
-
-
-ngx_objout="-Fo"
-ngx_binout="-Fe"
-ngx_objext="obj"
-ngx_binext=".exe"
-
-ngx_long_start='@<<
- '
-ngx_long_end='<<'
-ngx_long_regex_cont=' \
- '
-ngx_long_cont='
- '
-
-# MSVC understand / in path
-#ngx_regex_dirsep='\\'
-#ngx_dirsep="\\"
diff --git a/usr.sbin/nginx/auto/cc/name b/usr.sbin/nginx/auto/cc/name
deleted file mode 100644
index 51a7ed92e1d..00000000000
--- a/usr.sbin/nginx/auto/cc/name
+++ /dev/null
@@ -1,89 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-if [ "$NGX_PLATFORM" != win32 ]; then
-
- ngx_feature="C compiler"
- ngx_feature_name=
- ngx_feature_run=yes
- ngx_feature_incs=
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test=
- . auto/feature
-
- if [ $ngx_found = no ]; then
- echo
- echo $0: error: C compiler $CC is not found
- echo
- exit 1
- fi
-
-fi
-
-
-if [ "$CC" = cl ]; then
- if `$NGX_WINE $CC -v 2>&1 \
- | grep '^Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16' \
- >/dev/null 2>&1`; then
-
- NGX_CC_NAME=msvc10
- echo " + using Microsoft Visual C++ 10 compiler"
-
- elif `$NGX_WINE $CC -v 2>&1 \
- | grep '^Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14' \
- >/dev/null 2>&1`; then
-
- NGX_CC_NAME=msvc8
- echo " + using Microsoft Visual C++ 8 compiler"
-
- elif `$NGX_WINE $CC -v 2>&1 \
- | grep '^Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13' \
- >/dev/null 2>&1`; then
-
- NGX_CC_NAME=msvc7
- echo " + using Microsoft Visual C++ 7 compiler"
-
- else
- NGX_CC_NAME=msvc
- echo " + using Microsoft Visual C++ compiler"
- fi
-
-elif [ "$CC" = wcl386 ]; then
- NGX_CC_NAME=owc
- echo " + using Open Watcom C compiler"
-
-elif [ "$CC" = bcc32 ]; then
- NGX_CC_NAME=bcc
- echo " + using Borland C++ compiler"
-
-elif `$CC -V 2>&1 | grep '^Intel(R) C' >/dev/null 2>&1`; then
- NGX_CC_NAME=icc
- echo " + using Intel C++ compiler"
-
-elif `$CC -v 2>&1 | grep 'gcc version' >/dev/null 2>&1`; then
- NGX_CC_NAME=gcc
- echo " + using GNU C compiler"
-
-elif `$CC -v 2>&1 | grep '\(clang\|LLVM\) version' >/dev/null 2>&1`; then
- NGX_CC_NAME=clang
- echo " + using Clang C compiler"
-
-elif `$CC -V 2>&1 | grep 'Sun C' >/dev/null 2>&1`; then
- NGX_CC_NAME=sunc
- echo " + using Sun C compiler"
-
-elif `$CC -V 2>&1 | grep '^Compaq C' >/dev/null 2>&1`; then
- NGX_CC_NAME=ccc
- echo " + using Compaq C compiler"
-
-elif `$CC -V 2>&1 | grep '^aCC: ' >/dev/null 2>&1`; then
- NGX_CC_NAME=acc
- echo " + using HP aC++ compiler"
-
-else
- NGX_CC_NAME=unknown
-
-fi
diff --git a/usr.sbin/nginx/auto/cc/owc b/usr.sbin/nginx/auto/cc/owc
deleted file mode 100644
index a063aa34121..00000000000
--- a/usr.sbin/nginx/auto/cc/owc
+++ /dev/null
@@ -1,104 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-# Open Watcom C 1.0, 1.2, 1.3
-
-# optimizations
-
-# maximize speed
-CFLAGS="$CFLAGS -ot"
-# reorder instructions for best pipeline usage
-CFLAGS="$CFLAGS -op"
-# inline intrinsic functions
-CFLAGS="$CFLAGS -oi"
-# inline expansion
-CFLAGS="$CFLAGS -oe"
-# disable stack checking calls
-CFLAGS="$CFLAGS -s"
-
-case $CPU in
- pentium)
- # optimize for Pentium and Athlon
- # register-based arguments passing conventions
- CPU_OPT="-5r"
- # stack-based arguments passing conventions
- #CPU_OPT="-5s"
- ;;
-
- pentiumpro)
- # optimize for Pentium Pro, Pentium II and Pentium III
- # register-based arguments passing conventions
- CPU_OPT="-6r"
- # stack-based arguments passing conventions
- #CPU_OPT="-6s"
- ;;
-esac
-
-CFLAGS="$CFLAGS $CPU_OPT"
-
-
-# warnings
-
-# maximum level
-CFLAGS="$CFLAGS -wx"
-#CFLAGS="$CFLAGS -w3"
-
-# stop on warning
-CFLAGS="$CFLAGS -we"
-
-# built target is NT
-CFLAGS="$CFLAGS -bt=nt"
-
-# multithreaded
-CFLAGS="$CFLAGS -bm"
-
-# debug
-CFLAGS="$CFLAGS -d2"
-
-# quiet
-CFLAGS="$CFLAGS -zq"
-
-# Open Watcom C 1.2
-have=NGX_HAVE_C99_VARIADIC_MACROS . auto/have
-
-
-# the precompiled headers
-#CORE_DEPS="$CORE_DEPS $NGX_OBJS/ngx_config.pch"
-#NGX_PCH="$NGX_OBJS/ngx_config.pch"
-#NGX_BUILD_PCH="-fhq=$NGX_OBJS/ngx_config.pch"
-#NGX_USE_PCH="-fh=$NGX_OBJS/ngx_config.pch"
-
-
-# the link flags, built target is NT GUI mode application
-#CORE_LINK="$CORE_LINK -l=nt_win"
-
-
-# the resource file
-NGX_RCC="wrc \$(CORE_INCS) -fo=$NGX_OBJS/nginx.res "
-NGX_RCC="$NGX_RCC $NGX_WIN32_RC $NGX_OBJS/nginx.exe"
-
-
-ngx_include_opt="-i="
-ngx_objout="-fo"
-ngx_binout="-fe="
-ngx_objext="obj"
-ngx_binext=".exe"
-
-ngx_regex_dirsep='\\'
-ngx_dirsep="\\"
-
-ngx_long_start=' '
-ngx_long_end=' '
-ngx_long_regex_cont=' \&\
- '
-ngx_long_cont=' &
- '
-
-ngx_regex_cont=' \&\
- '
-ngx_cont=' &
- '
-ngx_tab=' &
- '
diff --git a/usr.sbin/nginx/auto/cc/sunc b/usr.sbin/nginx/auto/cc/sunc
deleted file mode 100644
index 8f12d7cd7fe..00000000000
--- a/usr.sbin/nginx/auto/cc/sunc
+++ /dev/null
@@ -1,158 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-# 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
-# Sun C 5.10 SunOS_i386 2009/06/03 Sun Studio 12.1
-# Sun C 5.11 SunOS_i386 2010/08/13 Sun Studio 12.2
-
-NGX_SUNC_VER=`$CC -V 2>&1 | grep 'Sun C' 2>&1 \
- | sed -e 's/^.* Sun C \(.*\)/\1/'`
-
-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 -rf $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)
- NGX_AUX=" src/os/unix/ngx_sunpro_x86.il"
- ;;
-
- sun4u | sun4v)
- NGX_AUX=" src/os/unix/ngx_sunpro_sparc64.il"
- ;;
-
-esac
-
-
-# optimizations
-
-# 20736 == 0x5100, Sun Studio 12.1
-
-if [ "$ngx_sunc_ver" -ge 20736 ]; then
- ngx_fast="-fast"
-
-else
- # older versions had problems with bit-fields
- ngx_fast="-fast -xalias_level=any"
-fi
-
-IPO=-xipo
-CFLAGS="$CFLAGS $ngx_fast $IPO"
-CORE_LINK="$CORE_LINK $ngx_fast $IPO"
-
-
-case $CPU in
- pentium)
- # optimize for Pentium and Athlon
- CPU_OPT="-xchip=pentium"
- ;;
-
- pentiumpro)
- # optimize for Pentium Pro, Pentium II
- CPU_OPT="-xchip=pentium_pro"
- ;;
-
- pentium3)
- # optimize for Pentium III
- CPU_OPT="-xchip=pentium3"
- #CPU_OPT="$CPU_OPT -xarch=sse"
- CPU_OPT="$CPU_OPT -xcache=16/32/4:256/32/4"
- ;;
-
- pentium4)
- # optimize for Pentium 4
- CPU_OPT="-xchip=pentium4"
- #CPU_OPT="$CPU_OPT -xarch=sse2"
- CPU_OPT="$CPU_OPT -xcache=8/64/4:256/128/8"
- ;;
-
- opteron)
- # optimize for Opteron
- CPU_OPT="-xchip=opteron"
- #CPU_OPT="$CPU_OPT -xarch=sse2"
- 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="$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
-
-
-CFLAGS="$CFLAGS $CPU_OPT"
-
-
-if [ ".$PCRE_OPT" = "." ]; then
- PCRE_OPT="$ngx_fast $IPO $CPU_OPT"
-fi
-
-if [ ".$MD5_OPT" = "." ]; then
- MD5_OPT="$ngx_fast $IPO $CPU_OPT"
-fi
-
-if [ ".$ZLIB_OPT" = "." ]; then
- ZLIB_OPT="$ngx_fast $IPO $CPU_OPT"
-fi
-
-
-# stop on warning
-CFLAGS="$CFLAGS -errwarn=%all"
-
-# debug
-CFLAGS="$CFLAGS -g"
diff --git a/usr.sbin/nginx/auto/define b/usr.sbin/nginx/auto/define
deleted file mode 100644
index b5a7622590d..00000000000
--- a/usr.sbin/nginx/auto/define
+++ /dev/null
@@ -1,12 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-cat << END >> $NGX_AUTO_CONFIG_H
-
-#ifndef $have
-#define $have $value
-#endif
-
-END
diff --git a/usr.sbin/nginx/auto/endianness b/usr.sbin/nginx/auto/endianness
deleted file mode 100644
index 93da2f80d99..00000000000
--- a/usr.sbin/nginx/auto/endianness
+++ /dev/null
@@ -1,45 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-echo $ngx_n "checking for system byte ordering ...$ngx_c"
-echo >> $NGX_ERR
-echo "checking for system byte ordering" >> $NGX_ERR
-
-
-cat << END > $NGX_AUTOTEST.c
-
-int main() {
- int i = 0x11223344;
- char *p;
-
- p = (char *) &i;
- if (*p == 0x44) return 0;
- return 1;
-}
-
-END
-
-ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
- -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
-
-eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
-
-if [ -x $NGX_AUTOTEST ]; then
- if $NGX_AUTOTEST >/dev/null 2>&1; then
- echo " little endian"
- have=NGX_HAVE_LITTLE_ENDIAN . auto/have
- else
- echo " big endian"
- fi
-
- rm -rf $NGX_AUTOTEST*
-
-else
- rm -rf $NGX_AUTOTEST*
-
- echo
- echo "$0: error: cannot detect system byte ordering"
- exit 1
-fi
diff --git a/usr.sbin/nginx/auto/feature b/usr.sbin/nginx/auto/feature
deleted file mode 100644
index 1145f28684b..00000000000
--- a/usr.sbin/nginx/auto/feature
+++ /dev/null
@@ -1,123 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-echo $ngx_n "checking for $ngx_feature ...$ngx_c"
-
-cat << END >> $NGX_AUTOCONF_ERR
-
-----------------------------------------
-checking for $ngx_feature
-
-END
-
-ngx_found=no
-
-if test -n "$ngx_feature_name"; then
- ngx_have_feature=`echo $ngx_feature_name \
- | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
-fi
-
-if test -n "$ngx_feature_path"; then
- for ngx_temp in $ngx_feature_path; do
- ngx_feature_inc_path="$ngx_feature_inc_path -I $ngx_temp"
- done
-fi
-
-cat << END > $NGX_AUTOTEST.c
-
-#include <sys/types.h>
-$NGX_INCLUDE_UNISTD_H
-$ngx_feature_incs
-
-int main() {
- $ngx_feature_test;
- return 0;
-}
-
-END
-
-
-ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS $ngx_feature_inc_path \
- -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_TEST_LD_OPT $ngx_feature_libs"
-
-ngx_feature_inc_path=
-
-eval "/bin/sh -c \"$ngx_test\" >> $NGX_AUTOCONF_ERR 2>&1"
-
-
-if [ -x $NGX_AUTOTEST ]; then
-
- case "$ngx_feature_run" in
-
- yes)
- # /bin/sh is used to intercept "Killed" or "Abort trap" messages
- if /bin/sh -c $NGX_AUTOTEST >> $NGX_AUTOCONF_ERR 2>&1; then
- echo " found"
- ngx_found=yes
-
- if test -n "$ngx_feature_name"; then
- have=$ngx_have_feature . auto/have
- fi
-
- else
- echo " found but is not working"
- fi
- ;;
-
- value)
- # /bin/sh is used to intercept "Killed" or "Abort trap" messages
- if /bin/sh -c $NGX_AUTOTEST >> $NGX_AUTOCONF_ERR 2>&1; then
- echo " found"
- ngx_found=yes
-
- cat << END >> $NGX_AUTO_CONFIG_H
-
-#ifndef $ngx_feature_name
-#define $ngx_feature_name `$NGX_AUTOTEST`
-#endif
-
-END
- else
- echo " found but is not working"
- fi
- ;;
-
- bug)
- # /bin/sh is used to intercept "Killed" or "Abort trap" messages
- if /bin/sh -c $NGX_AUTOTEST >> $NGX_AUTOCONF_ERR 2>&1; then
- echo " not found"
-
- else
- echo " found"
- ngx_found=yes
-
- if test -n "$ngx_feature_name"; then
- have=$ngx_have_feature . auto/have
- fi
- fi
- ;;
-
- *)
- echo " found"
- ngx_found=yes
-
- if test -n "$ngx_feature_name"; then
- have=$ngx_have_feature . auto/have
- fi
- ;;
-
- esac
-
-else
- echo " not found"
-
- echo "----------" >> $NGX_AUTOCONF_ERR
- cat $NGX_AUTOTEST.c >> $NGX_AUTOCONF_ERR
- echo "----------" >> $NGX_AUTOCONF_ERR
- echo $ngx_test >> $NGX_AUTOCONF_ERR
- echo "----------" >> $NGX_AUTOCONF_ERR
-fi
-
-rm -rf $NGX_AUTOTEST*
diff --git a/usr.sbin/nginx/auto/have b/usr.sbin/nginx/auto/have
deleted file mode 100644
index f8e3751c5f0..00000000000
--- a/usr.sbin/nginx/auto/have
+++ /dev/null
@@ -1,12 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-cat << END >> $NGX_AUTO_CONFIG_H
-
-#ifndef $have
-#define $have 1
-#endif
-
-END
diff --git a/usr.sbin/nginx/auto/have_headers b/usr.sbin/nginx/auto/have_headers
deleted file mode 100644
index a3a75430aa4..00000000000
--- a/usr.sbin/nginx/auto/have_headers
+++ /dev/null
@@ -1,12 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-cat << END >> $NGX_AUTO_HEADERS_H
-
-#ifndef $have
-#define $have 1
-#endif
-
-END
diff --git a/usr.sbin/nginx/auto/headers b/usr.sbin/nginx/auto/headers
deleted file mode 100644
index 5a2e6b9023f..00000000000
--- a/usr.sbin/nginx/auto/headers
+++ /dev/null
@@ -1,13 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-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="sys/param.h"; . auto/include
-ngx_include="sys/mount.h"; . auto/include
-ngx_include="sys/statvfs.h"; . auto/include
-ngx_include="crypt.h"; . auto/include
diff --git a/usr.sbin/nginx/auto/include b/usr.sbin/nginx/auto/include
deleted file mode 100644
index e34dabdae1d..00000000000
--- a/usr.sbin/nginx/auto/include
+++ /dev/null
@@ -1,61 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-echo $ngx_n "checking for $ngx_include ...$ngx_c"
-
-cat << END >> $NGX_AUTOCONF_ERR
-
-----------------------------------------
-checking for $ngx_include
-
-END
-
-
-ngx_found=no
-
-cat << END > $NGX_AUTOTEST.c
-
-$NGX_INCLUDE_SYS_PARAM_H
-#include <$ngx_include>
-
-int main() {
- return 0;
-}
-
-END
-
-
-ngx_test="$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c"
-
-eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
-
-if [ -x $NGX_AUTOTEST ]; then
-
- ngx_found=yes
-
- echo " found"
-
- ngx_name=`echo $ngx_include \
- | tr abcdefghijklmnopqrstuvwxyz/. ABCDEFGHIJKLMNOPQRSTUVWXYZ__`
-
-
- have=NGX_HAVE_$ngx_name . auto/have_headers
-
- eval "NGX_INCLUDE_$ngx_name='#include <$ngx_include>'"
-
- #STUB
- eval "NGX_$ngx_name='#include <$ngx_include>'"
-
-else
- echo " not found"
-
- echo "----------" >> $NGX_AUTOCONF_ERR
- cat $NGX_AUTOTEST.c >> $NGX_AUTOCONF_ERR
- echo "----------" >> $NGX_AUTOCONF_ERR
- echo $ngx_test >> $NGX_AUTOCONF_ERR
- echo "----------" >> $NGX_AUTOCONF_ERR
-fi
-
-rm -rf $NGX_AUTOTEST*
diff --git a/usr.sbin/nginx/auto/init b/usr.sbin/nginx/auto/init
deleted file mode 100644
index 910f5294b66..00000000000
--- a/usr.sbin/nginx/auto/init
+++ /dev/null
@@ -1,51 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-NGX_MAKEFILE=$NGX_OBJS/Makefile
-NGX_MODULES_C=$NGX_OBJS/ngx_modules.c
-
-NGX_AUTO_HEADERS_H=$NGX_OBJS/ngx_auto_headers.h
-NGX_AUTO_CONFIG_H=$NGX_OBJS/ngx_auto_config.h
-
-NGX_AUTOTEST=$NGX_OBJS/autotest
-NGX_AUTOCONF_ERR=$NGX_OBJS/autoconf.err
-
-# STUBs
-NGX_ERR=$NGX_OBJS/autoconf.err
-MAKEFILE=$NGX_OBJS/Makefile
-
-
-NGX_PCH=
-NGX_USE_PCH=
-
-
-# check the echo's "-n" option and "\c" capability
-
-if echo "test\c" | grep c >/dev/null; then
-
- if echo -n test | grep n >/dev/null; then
- ngx_n=
- ngx_c=
-
- else
- ngx_n=-n
- ngx_c=
- fi
-
-else
- ngx_n=
- ngx_c='\c'
-fi
-
-
-# create Makefile
-
-cat << END > Makefile
-
-default: build
-
-clean:
- rm -rf Makefile $NGX_OBJS
-END
diff --git a/usr.sbin/nginx/auto/install b/usr.sbin/nginx/auto/install
deleted file mode 100644
index a9cca350454..00000000000
--- a/usr.sbin/nginx/auto/install
+++ /dev/null
@@ -1,121 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-if [ $USE_PERL = YES ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-install_perl_modules:
- cd $NGX_OBJS/src/http/modules/perl && \$(MAKE) install
-END
-
- NGX_INSTALL_PERL_MODULES=install_perl_modules
-
-fi
-
-
-case ".$NGX_SBIN_PATH" in
- ./*)
- ;;
-
- .)
- NGX_SBIN_PATH=$NGX_PREFIX/sbin/nginx
- ;;
-
- *)
- NGX_SBIN_PATH=$NGX_PREFIX/$NGX_SBIN_PATH
- ;;
-esac
-
-
-case ".$NGX_CONF_PATH" in
- ./*)
- ;;
-
- *)
- NGX_CONF_PATH=$NGX_PREFIX/$NGX_CONF_PATH
- ;;
-esac
-
-
-NGX_CONF_PREFIX=`dirname $NGX_CONF_PATH`
-
-
-case ".$NGX_PID_PATH" in
- ./*)
- ;;
-
- *)
- NGX_PID_PATH=$NGX_PREFIX/$NGX_PID_PATH
- ;;
-esac
-
-
-case ".$NGX_ERROR_LOG_PATH" in
- ./* | .)
- ;;
-
- *)
- NGX_ERROR_LOG_PATH=$NGX_PREFIX/$NGX_ERROR_LOG_PATH
- ;;
-esac
-
-
-case ".$NGX_HTTP_LOG_PATH" in
- ./*)
- ;;
-
- *)
- NGX_HTTP_LOG_PATH=$NGX_PREFIX/$NGX_HTTP_LOG_PATH
- ;;
-esac
-
-
-if test -f man/nginx.8 ; then
- NGX_MAN=man/nginx.8
-else
- NGX_MAN=docs/man/nginx.8
-fi
-
-if test -d html ; then
- NGX_HTML=html
-else
- NGX_HTML=docs/html
-fi
-
-cat << END >> $NGX_MAKEFILE
-
-manpage: $NGX_OBJS/nginx.8
-
-$NGX_OBJS/nginx.8: $NGX_MAN $NGX_AUTO_CONFIG_H
- sed -e "s|%%PREFIX%%|$NGX_PREFIX|" \\
- -e "s|%%PID_PATH%%|$NGX_PID_PATH|" \\
- -e "s|%%CONF_PATH%%|$NGX_CONF_PATH|" \\
- -e "s|%%ERROR_LOG_PATH%%|${NGX_ERROR_LOG_PATH:-stderr}|" \\
- < $NGX_MAN > \$@
-install:
- # Dummy
-END
-
-# create Makefile
-
-cat << END >> Makefile
-
-build:
- \$(MAKE) -f $NGX_MAKEFILE
- \$(MAKE) -f $NGX_MAKEFILE manpage
-
-install:
- \$(MAKE) -f $NGX_MAKEFILE install
-
-upgrade:
- $NGX_SBIN_PATH -t
-
- kill -USR2 \`cat $NGX_PID_PATH\`
- sleep 1
- test -f $NGX_PID_PATH.oldbin
-
- kill -QUIT \`cat $NGX_PID_PATH.oldbin\`
-END
diff --git a/usr.sbin/nginx/auto/lib/conf b/usr.sbin/nginx/auto/lib/conf
deleted file mode 100644
index e1e447557e9..00000000000
--- a/usr.sbin/nginx/auto/lib/conf
+++ /dev/null
@@ -1,83 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-if [ $USE_PCRE = YES -o $PCRE != NONE ]; then
- . auto/lib/pcre/conf
-
-else
- if [ $USE_PCRE = DISABLED -a $HTTP_REWRITE = YES ]; then
-
-cat << END
-
-$0: error: the HTTP rewrite module requires the PCRE library.
-You can either disable the module by using --without-http_rewrite_module
-option or you have to enable the PCRE support.
-
-END
- exit 1
- fi
-fi
-
-
-if [ $USE_OPENSSL = YES ]; then
- . auto/lib/openssl/conf
-fi
-
-if [ $USE_MD5 = YES ]; then
-
- if [ $USE_OPENSSL = YES ]; then
- have=NGX_HAVE_OPENSSL_MD5_H . auto/have
- have=NGX_OPENSSL_MD5 . auto/have
- have=NGX_HAVE_MD5 . auto/have
- MD5=YES
- MD5_LIB=OpenSSL
-
- else
- . auto/lib/md5/conf
- fi
-
-fi
-
-if [ $USE_SHA1 = YES ]; then
-
- if [ $USE_OPENSSL = YES ]; then
- have=NGX_HAVE_OPENSSL_SHA1_H . auto/have
- have=NGX_HAVE_SHA1 . auto/have
- SHA1=YES
- SHA1_LIB=OpenSSL
-
- else
- . auto/lib/sha1/conf
- fi
-
-fi
-
-if [ $USE_ZLIB = YES ]; then
- . auto/lib/zlib/conf
-fi
-
-if [ $USE_LIBXSLT = YES ]; then
- . auto/lib/libxslt/conf
-fi
-
-if [ $USE_LIBGD = YES ]; then
- . auto/lib/libgd/conf
-fi
-
-if [ $USE_PERL = YES ]; then
- . auto/lib/perl/conf
-fi
-
-if [ $HTTP_GEOIP = YES ]; then
- . auto/lib/geoip/conf
-fi
-
-if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then
- . auto/lib/google-perftools/conf
-fi
-
-if [ $NGX_LIBATOMIC != NO ]; then
- . auto/lib/libatomic/conf
-fi
diff --git a/usr.sbin/nginx/auto/lib/geoip/conf b/usr.sbin/nginx/auto/lib/geoip/conf
deleted file mode 100644
index 53c274d54dc..00000000000
--- a/usr.sbin/nginx/auto/lib/geoip/conf
+++ /dev/null
@@ -1,94 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
- ngx_feature="GeoIP library"
- ngx_feature_name=
- ngx_feature_run=no
- ngx_feature_incs="#include <GeoIP.h>"
- ngx_feature_path=
- ngx_feature_libs="-lGeoIP"
- ngx_feature_test="GeoIP_open(NULL, 0)"
- . auto/feature
-
-
-if [ $ngx_found = no ]; then
-
- # FreeBSD port
-
- ngx_feature="GeoIP library in /usr/local/"
- ngx_feature_path="/usr/local/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lGeoIP"
- else
- ngx_feature_libs="-L/usr/local/lib -lGeoIP"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = no ]; then
-
- # NetBSD port
-
- ngx_feature="GeoIP library in /usr/pkg/"
- ngx_feature_path="/usr/pkg/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lGeoIP"
- else
- ngx_feature_libs="-L/usr/pkg/lib -lGeoIP"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = no ]; then
-
- # MacPorts
-
- ngx_feature="GeoIP library in /opt/local/"
- ngx_feature_path="/opt/local/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lGeoIP"
- else
- ngx_feature_libs="-L/opt/local/lib -lGeoIP"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = yes ]; then
-
- CORE_INCS="$CORE_INCS $ngx_feature_path"
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
-
- if [ $NGX_IPV6 = YES ]; then
- ngx_feature="GeoIP IPv6 support"
- ngx_feature_name="NGX_HAVE_GEOIP_V6"
- ngx_feature_run=no
- ngx_feature_incs="#include <stdio.h>
- #include <GeoIP.h>"
- #ngx_feature_path=
- #ngx_feature_libs=
- ngx_feature_test="printf(\"%d\", GEOIP_CITY_EDITION_REV0_V6);"
- . auto/feature
- fi
-
-else
-
-cat << END
-
-$0: error: the GeoIP module requires the GeoIP library.
-You can either do not enable the module or install the library.
-
-END
-
- exit 1
-fi
diff --git a/usr.sbin/nginx/auto/lib/google-perftools/conf b/usr.sbin/nginx/auto/lib/google-perftools/conf
deleted file mode 100644
index 7a9de30020b..00000000000
--- a/usr.sbin/nginx/auto/lib/google-perftools/conf
+++ /dev/null
@@ -1,61 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
- ngx_feature="Google perftools"
- ngx_feature_name=
- ngx_feature_run=no
- ngx_feature_incs=
- ngx_feature_path=
- ngx_feature_libs="-lprofiler"
- ngx_feature_test="ProfilerStop()"
- . auto/feature
-
-
-if [ $ngx_found = no ]; then
-
- # FreeBSD port
-
- ngx_feature="Google perftools in /usr/local/"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lprofiler"
- else
- ngx_feature_libs="-L/usr/local/lib -lprofiler"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = no ]; then
-
- # MacPorts
-
- ngx_feature="Google perftools in /opt/local/"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lprofiler"
- else
- ngx_feature_libs="-L/opt/local/lib -lprofiler"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = yes ]; then
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
-
-else
-
-cat << END
-
-$0: error: the Google perftool module requires the Google perftools
-library. You can either do not enable the module or install the library.
-
-END
-
- exit 1
-fi
diff --git a/usr.sbin/nginx/auto/lib/libatomic/conf b/usr.sbin/nginx/auto/lib/libatomic/conf
deleted file mode 100644
index d1e484ab32e..00000000000
--- a/usr.sbin/nginx/auto/lib/libatomic/conf
+++ /dev/null
@@ -1,43 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-if [ $NGX_LIBATOMIC != YES ]; then
-
- have=NGX_HAVE_LIBATOMIC . auto/have
- CORE_INCS="$CORE_INCS $NGX_LIBATOMIC/src"
- LINK_DEPS="$LINK_DEPS $NGX_LIBATOMIC/src/libatomic_ops.a"
- CORE_LIBS="$CORE_LIBS $NGX_LIBATOMIC/src/libatomic_ops.a"
-
-else
-
- ngx_feature="atomic_ops library"
- ngx_feature_name=NGX_HAVE_LIBATOMIC
- ngx_feature_run=yes
- ngx_feature_incs="#define AO_REQUIRE_CAS
- #include <atomic_ops.h>"
- ngx_feature_path=
- ngx_feature_libs="-latomic_ops"
- ngx_feature_test="long n = 0;
- if (!AO_compare_and_swap(&n, 0, 1))
- return 1;
- if (AO_fetch_and_add(&n, 1) != 1)
- return 1;
- if (n != 2)
- return 1;
- AO_nop();"
- . auto/feature
-
- if [ $ngx_found = yes ]; then
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
- else
-
-cat << END
-
-$0: error: libatomic_ops library was not found.
-
-END
- exit 1
- fi
-fi
diff --git a/usr.sbin/nginx/auto/lib/libatomic/make b/usr.sbin/nginx/auto/lib/libatomic/make
deleted file mode 100644
index c90318ea122..00000000000
--- a/usr.sbin/nginx/auto/lib/libatomic/make
+++ /dev/null
@@ -1,16 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
- cat << END >> $NGX_MAKEFILE
-
-$NGX_LIBATOMIC/src/libatomic_ops.a: $NGX_LIBATOMIC/Makefile
- cd $NGX_LIBATOMIC && \$(MAKE)
-
-$NGX_LIBATOMIC/Makefile: $NGX_MAKEFILE
- cd $NGX_LIBATOMIC \\
- && if [ -f Makefile ]; then \$(MAKE) distclean; fi \\
- && ./configure
-
-END
diff --git a/usr.sbin/nginx/auto/lib/libgd/conf b/usr.sbin/nginx/auto/lib/libgd/conf
deleted file mode 100644
index ff99054db68..00000000000
--- a/usr.sbin/nginx/auto/lib/libgd/conf
+++ /dev/null
@@ -1,83 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
- ngx_feature="GD library"
- ngx_feature_name=
- ngx_feature_run=no
- ngx_feature_incs="#include <gd.h>"
- ngx_feature_path=
- ngx_feature_libs="-lgd"
- ngx_feature_test="gdImagePtr img = gdImageCreateFromGifPtr(1, NULL);"
- . auto/feature
-
-
-if [ $ngx_found = no ]; then
-
- # FreeBSD port
-
- ngx_feature="GD library in /usr/local/"
- ngx_feature_path="/usr/local/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lgd"
- else
- ngx_feature_libs="-L/usr/local/lib -lgd"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = no ]; then
-
- # NetBSD port
-
- ngx_feature="GD library in /usr/pkg/"
- ngx_feature_path="/usr/pkg/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lgd"
- else
- ngx_feature_libs="-L/usr/pkg/lib -lgd"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = no ]; then
-
- # MacPorts
-
- ngx_feature="GD library in /opt/local/"
- ngx_feature_path="/opt/local/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lgd"
- else
- ngx_feature_libs="-L/opt/local/lib -lgd"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = yes ]; then
-
- CORE_INCS="$CORE_INCS $ngx_feature_path"
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
-
-else
-
-cat << END
-
-$0: error: the HTTP image filter module requires the GD library.
-You can either do not enable the module or install the libraries.
-
-END
-
- exit 1
-
-fi
diff --git a/usr.sbin/nginx/auto/lib/libxslt/conf b/usr.sbin/nginx/auto/lib/libxslt/conf
deleted file mode 100644
index bc19d83ddce..00000000000
--- a/usr.sbin/nginx/auto/lib/libxslt/conf
+++ /dev/null
@@ -1,156 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
- ngx_feature="libxslt"
- ngx_feature_name=
- ngx_feature_run=no
- ngx_feature_incs="#include <libxml/parser.h>
- #include <libxml/tree.h>
- #include <libxslt/xslt.h>
- #include <libxslt/xsltInternals.h>
- #include <libxslt/transform.h>
- #include <libxslt/xsltutils.h>"
- ngx_feature_path="/usr/include/libxml2"
- ngx_feature_libs="-lxml2 -lxslt"
- ngx_feature_test="xmlParserCtxtPtr ctxt = NULL;
- xsltStylesheetPtr sheet = NULL;
- xmlDocPtr doc;
- doc = xmlParseChunk(ctxt, NULL, 0, 0);
- xsltApplyStylesheet(sheet, doc, NULL);"
- . auto/feature
-
-
-if [ $ngx_found = no ]; then
-
- # FreeBSD port
-
- ngx_feature="libxslt in /usr/local/"
- ngx_feature_path="/usr/local/include/libxml2 /usr/local/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lxml2 -lxslt"
- else
- ngx_feature_libs="-L/usr/local/lib -lxml2 -lxslt"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = no ]; then
-
- # NetBSD port
-
- ngx_feature="libxslt in /usr/pkg/"
- ngx_feature_path="/usr/pkg/include/libxml2 /usr/pkg/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lxml2 -lxslt"
- else
- ngx_feature_libs="-L/usr/pkg/lib -lxml2 -lxslt"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = no ]; then
-
- # MacPorts
-
- ngx_feature="libxslt in /opt/local/"
- ngx_feature_path="/opt/local/include/libxml2 /opt/local/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lxml2 -lxslt"
- else
- ngx_feature_libs="-L/opt/local/lib -lxml2 -lxslt"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = yes ]; then
-
- CORE_INCS="$CORE_INCS $ngx_feature_path"
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
-
-else
-
-cat << END
-
-$0: error: the HTTP XSLT module requires the libxml2/libxslt
-libraries. You can either do not enable the module or install the libraries.
-
-END
-
- exit 1
-fi
-
-
- ngx_feature="libexslt"
- ngx_feature_name=NGX_HAVE_EXSLT
- ngx_feature_run=no
- ngx_feature_incs="#include <libexslt/exslt.h>"
- ngx_feature_path="/usr/include/libxml2"
- ngx_feature_libs="-lexslt"
- ngx_feature_test="exsltRegisterAll();"
- . auto/feature
-
-if [ $ngx_found = no ]; then
-
- # FreeBSD port
-
- ngx_feature="libexslt in /usr/local/"
- ngx_feature_path="/usr/local/include/libxml2 /usr/local/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lexslt"
- else
- ngx_feature_libs="-L/usr/local/lib -lexslt"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = no ]; then
-
- # NetBSD port
-
- ngx_feature="libexslt in /usr/pkg/"
- ngx_feature_path="/usr/pkg/include/libxml2 /usr/local/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lexslt"
- else
- ngx_feature_libs="-L/usr/pkg/lib -lexslt"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = no ]; then
-
- # MacPorts
-
- ngx_feature="libexslt in /opt/local/"
- ngx_feature_path="/opt/local/include/libxml2 /opt/local/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lexslt"
- else
- ngx_feature_libs="-L/opt/local/lib -lexslt"
- fi
-
- . auto/feature
-fi
-
-
-if [ $ngx_found = yes ]; then
- CORE_LIBS="$CORE_LIBS -lexslt"
-fi
diff --git a/usr.sbin/nginx/auto/lib/make b/usr.sbin/nginx/auto/lib/make
deleted file mode 100644
index 58a84a34cac..00000000000
--- a/usr.sbin/nginx/auto/lib/make
+++ /dev/null
@@ -1,32 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-if [ $PCRE != NONE -a $PCRE != NO -a $PCRE != YES ]; then
- . auto/lib/pcre/make
-fi
-
-if [ $MD5 != NONE -a $MD5 != NO -a $MD5 != YES ]; then
- . auto/lib/md5/make
-fi
-
-if [ $SHA1 != NONE -a $SHA1 != NO -a $SHA1 != YES ]; then
- . auto/lib/sha1/make
-fi
-
-if [ $OPENSSL != NONE -a $OPENSSL != NO -a $OPENSSL != YES ]; then
- . auto/lib/openssl/make
-fi
-
-if [ $ZLIB != NONE -a $ZLIB != NO -a $ZLIB != YES ]; then
- . auto/lib/zlib/make
-fi
-
-if [ $NGX_LIBATOMIC != NO -a $NGX_LIBATOMIC != YES ]; then
- . auto/lib/libatomic/make
-fi
-
-if [ $USE_PERL = YES ]; then
- . auto/lib/perl/make
-fi
diff --git a/usr.sbin/nginx/auto/lib/md5/conf b/usr.sbin/nginx/auto/lib/md5/conf
deleted file mode 100644
index eb5dfd1f236..00000000000
--- a/usr.sbin/nginx/auto/lib/md5/conf
+++ /dev/null
@@ -1,103 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-if [ $MD5 != NONE ]; then
-
- if grep MD5_Init $MD5/md5.h 2>&1 >/dev/null; then
- # OpenSSL md5
- OPENSSL_MD5=YES
- have=NGX_HAVE_OPENSSL_MD5 . auto/have
- have=NGX_OPENSSL_MD5 . auto/have
- else
- # rsaref md5
- OPENSSL_MD5=NO
- fi
-
- have=NGX_HAVE_MD5 . auto/have
- CORE_INCS="$CORE_INCS $MD5"
-
- case "$NGX_CC_NAME" in
-
- msvc* | owc* | bcc)
- LINK_DEPS="$LINK_DEPS $MD5/md5.lib"
- CORE_LIBS="$CORE_LIBS $MD5/md5.lib"
- ;;
-
- icc*)
- LINK_DEPS="$LINK_DEPS $MD5/libmd5.a"
-
- # to allow -ipo optimization we link with the *.o but not library
- CORE_LIBS="$CORE_LIBS $MD5/md5_dgst.o"
-
- if [ $MD5_ASM = YES ]; then
- CORE_LIBS="$CORE_LIBS $MD5/asm/mx86-elf.o"
- fi
- ;;
-
- *)
- LINK_DEPS="$LINK_DEPS $MD5/libmd5.a"
- CORE_LIBS="$CORE_LIBS $MD5/libmd5.a"
- #CORE_LIBS="$CORE_LIBS -L $MD5 -lmd5"
- ;;
-
- esac
-
-else
-
- if [ "$NGX_PLATFORM" != win32 ]; then
-
- MD5=NO
-
- # FreeBSD, Solaris 10
-
- ngx_feature="md5 in system md library"
- ngx_feature_name=NGX_HAVE_MD5
- ngx_feature_run=no
- ngx_feature_incs="#include <md5.h>"
- ngx_feature_path=
- ngx_feature_libs="-lmd"
- ngx_feature_test="MD5_CTX md5; MD5Init(&md5)"
- . auto/feature
-
- ngx_md5_lib="system md"
-
- if [ $ngx_found = no ]; then
-
- # Solaris 8/9
-
- ngx_feature="md5 in system md5 library"
- ngx_feature_libs="-lmd5"
- . auto/feature
-
- ngx_md5_lib="system md5"
- fi
-
- if [ $ngx_found = no ]; then
-
- # OpenSSL crypto library
-
- ngx_feature="md5 in system OpenSSL crypto library"
- ngx_feature_name="NGX_OPENSSL_MD5"
- ngx_feature_incs="#include <openssl/md5.h>"
- ngx_feature_libs="-lcrypto"
- ngx_feature_test="MD5_CTX md5; MD5_Init(&md5)"
- . auto/feature
-
- ngx_md5_lib="system crypto"
-
- if [ $ngx_found = yes ]; then
- have=NGX_HAVE_OPENSSL_MD5_H . auto/have
- have=NGX_HAVE_MD5 . auto/have
- fi
- fi
-
- if [ $ngx_found = yes ]; then
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
- MD5=YES
- MD5_LIB=$ngx_md5_lib
- fi
- fi
-
-fi
diff --git a/usr.sbin/nginx/auto/lib/md5/make b/usr.sbin/nginx/auto/lib/md5/make
deleted file mode 100644
index 81f138ab671..00000000000
--- a/usr.sbin/nginx/auto/lib/md5/make
+++ /dev/null
@@ -1,96 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-case "$NGX_CC_NAME" in
-
- msvc*)
- ngx_makefile=makefile.msvc
- ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC MD5_ASM=$MD5_ASM"
- ngx_md5="MD5=\"$MD5\""
- ;;
-
- owc*)
- ngx_makefile=makefile.owc
- ngx_opt="CPU_OPT=\"$CPU_OPT\""
- ngx_md5=`echo MD5=\"$MD5\" | sed -e "s/\//$ngx_regex_dirsep/g"`
- ;;
-
- bcc)
- ngx_makefile=makefile.bcc
- ngx_opt="-DCPU_OPT=\"$CPU_OPT\" -DMD5_ASM=$MD5_ASM"
- ngx_md5=`echo \-DMD5=\"$MD5\" | sed -e "s/\//$ngx_regex_dirsep/g"`
- ;;
-
-esac
-
-
-done=NO
-
-
-case "$NGX_PLATFORM" in
-
- win32)
- cat << END >> $NGX_MAKEFILE
-
-`echo "$MD5/md5.lib: $NGX_MAKEFILE" | sed -e "s/\//$ngx_regex_dirsep/g"`
- \$(MAKE) -f auto/lib/md5/$ngx_makefile $ngx_opt $ngx_md5
-
-END
-
- done=YES
- ;;
-
- SunOS:*:i86pc)
- if [ $MD5_ASM = YES ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$MD5/libmd5.a: $NGX_MAKEFILE
- cd $MD5 \\
- && \$(MAKE) CFLAGS="$MD5_OPT -DSOL -DMD5_ASM -DL_ENDIAN" \\
- CC="\$(CC)" CPP="\$(CPP)" \\
- MD5_ASM_OBJ=asm/mx86-sol.o clean libmd5.a
-
-END
-
- done=YES
- fi
- ;;
-
- # FreeBSD: i386
- # Linux: i686
-
- *:i386 | *:i686)
- if [ $MD5_ASM = YES ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$MD5/libmd5.a: $NGX_MAKEFILE
- cd $MD5 \\
- && \$(MAKE) CFLAGS="$MD5_OPT -DELF -DMD5_ASM -DL_ENDIAN" \\
- CC="\$(CC)" CPP="\$(CPP)" \\
- MD5_ASM_OBJ=asm/mx86-elf.o clean libmd5.a
-
-END
-
- done=YES
- fi
- ;;
-
-esac
-
-
-if [ $done = NO ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$MD5/libmd5.a: $NGX_MAKEFILE
- cd $MD5 \\
- && \$(MAKE) CFLAGS="$MD5_OPT" \\
- CC="\$(CC)" MD5_ASM_OBJ= clean libmd5.a
-
-END
-
-fi
diff --git a/usr.sbin/nginx/auto/lib/md5/makefile.bcc b/usr.sbin/nginx/auto/lib/md5/makefile.bcc
deleted file mode 100644
index eb6fb624178..00000000000
--- a/usr.sbin/nginx/auto/lib/md5/makefile.bcc
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -q -O2 -tWM $(CPU_OPT) -DL_ENDIAN
-
-!if "$(MD5_ASM)" == "YES"
-
-md5.lib:
- cd $(MD5)
- bcc32 -c $(CFLAGS) -DMD5_ASM md5_dgst.c
- tlib md5.lib +md5_dgst.obj +"asm\m-win32.obj"
-
-!else
-
-md5.lib:
- cd $(MD5)
- bcc32 -c $(CFLAGS) md5_dgst.c
- tlib md5.lib +md5_dgst.obj
-
-!endif
diff --git a/usr.sbin/nginx/auto/lib/md5/makefile.msvc b/usr.sbin/nginx/auto/lib/md5/makefile.msvc
deleted file mode 100644
index 90d62fac7f0..00000000000
--- a/usr.sbin/nginx/auto/lib/md5/makefile.msvc
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -nologo -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT) -D L_ENDIAN
-
-!IF "$(MD5_ASM)" == "YES"
-
-md5.lib:
- cd $(MD5)
- cl -c $(CFLAGS) -D MD5_ASM md5_dgst.c
- link -lib -out:md5.lib md5_dgst.obj asm/m-win32.obj
-
-!ELSE
-
-md5.lib:
- cd $(MD5)
- cl -c $(CFLAGS) md5_dgst.c
- link -lib -out:md5.lib md5_dgst.obj
-
-!ENDIF
diff --git a/usr.sbin/nginx/auto/lib/md5/makefile.owc b/usr.sbin/nginx/auto/lib/md5/makefile.owc
deleted file mode 100644
index 78c1e61dde7..00000000000
--- a/usr.sbin/nginx/auto/lib/md5/makefile.owc
+++ /dev/null
@@ -1,11 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -zq -bt=nt -bm -ot -op -oi -oe -s $(CPU_OPT)
-
-md5.lib:
- cd $(MD5)
- wcl386 -c $(CFLAGS) -dL_ENDIAN md5_dgst.c
- wlib -n md5.lib md5_dgst.obj
diff --git a/usr.sbin/nginx/auto/lib/openssl/conf b/usr.sbin/nginx/auto/lib/openssl/conf
deleted file mode 100644
index a65815f6364..00000000000
--- a/usr.sbin/nginx/auto/lib/openssl/conf
+++ /dev/null
@@ -1,78 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-if [ $OPENSSL != NONE ]; then
-
- case "$CC" in
-
- cl | bcc32)
- have=NGX_OPENSSL . auto/have
- have=NGX_SSL . auto/have
-
- CFLAGS="$CFLAGS -DNO_SYS_TYPES_H"
-
- CORE_INCS="$CORE_INCS $OPENSSL/openssl/include"
- CORE_DEPS="$CORE_DEPS $OPENSSL/openssl/include/openssl/ssl.h"
- CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/ssleay32.lib"
- CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libeay32.lib"
-
- # libeay32.lib requires gdi32.lib
- CORE_LIBS="$CORE_LIBS gdi32.lib"
- # OpenSSL 1.0.0 requires crypt32.lib
- CORE_LIBS="$CORE_LIBS crypt32.lib"
- ;;
-
- *)
- have=NGX_OPENSSL . auto/have
- have=NGX_SSL . auto/have
-
- CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"
- CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"
- CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"
- CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a"
- CORE_LIBS="$CORE_LIBS $NGX_LIBDL"
-
- if [ "$NGX_PLATFORM" = win32 ]; then
- CORE_LIBS="$CORE_LIBS -lgdi32 -lcrypt32 -lws2_32"
- fi
- ;;
- esac
-
-else
-
- if [ "$NGX_PLATFORM" != win32 ]; then
-
- OPENSSL=NO
-
- ngx_feature="OpenSSL library"
- ngx_feature_name="NGX_OPENSSL"
- ngx_feature_run=no
- ngx_feature_incs="#include <openssl/ssl.h>"
- ngx_feature_path=
- ngx_feature_libs="-lssl -lcrypto"
- ngx_feature_test="SSL_library_init()"
- . auto/feature
-
- if [ $ngx_found = yes ]; then
- have=NGX_SSL . auto/have
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs $NGX_LIBDL"
- OPENSSL=YES
- fi
- fi
-
- if [ $OPENSSL != YES ]; then
-
-cat << END
-
-$0: error: SSL modules require the OpenSSL library.
-You can either do not enable the modules, or install the OpenSSL library
-into the system, or build the OpenSSL library statically from the source
-with nginx by using --with-openssl=<path> option.
-
-END
- exit 1
- fi
-
-fi
diff --git a/usr.sbin/nginx/auto/lib/openssl/make b/usr.sbin/nginx/auto/lib/openssl/make
deleted file mode 100644
index e64acd973ec..00000000000
--- a/usr.sbin/nginx/auto/lib/openssl/make
+++ /dev/null
@@ -1,67 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-case "$CC" in
-
- cl)
-
- cat << END >> $NGX_MAKEFILE
-
-$OPENSSL/openssl/include/openssl/ssl.h: $NGX_MAKEFILE
- \$(MAKE) -f auto/lib/openssl/makefile.msvc \
- OPENSSL="$OPENSSL" OPENSSL_OPT="$OPENSSL_OPT"
-
-END
-
- ;;
-
- bcc32)
-
- ngx_opt=`echo "-DOPENSSL=\"$OPENSSL\" -DOPENSSL_OPT=\"$OPENSSL_OPT\"" \
- | sed -e "s/\//$ngx_regex_dirsep/g"`
-
- cat << END >> $NGX_MAKEFILE
-
-`echo "$OPENSSL\\openssl\\lib\\libeay32.lib: \
- $OPENSSL\\openssl\\include\\openssl\\ssl.h" \
- | sed -e "s/\//$ngx_regex_dirsep/g"`
-
-`echo "$OPENSSL\\openssl\\lib\\ssleay32.lib: \
- $OPENSSL\\openssl\\include\\openssl\\ssl.h" \
- | sed -e "s/\//$ngx_regex_dirsep/g"`
-
-`echo "$OPENSSL\\openssl\\include\\openssl\\ssl.h: $NGX_MAKEFILE" \
- | sed -e "s/\//$ngx_regex_dirsep/g"`
- \$(MAKE) -f auto/lib/openssl/makefile.bcc $ngx_opt
-
-END
-
- ;;
-
- *)
- case $USE_THREADS in
- NO) OPENSSL_OPT="$OPENSSL_OPT no-threads" ;;
- *) OPENSSL_OPT="$OPENSSL_OPT threads" ;;
- esac
-
- case $OPENSSL in
- /*) ngx_prefix="$OPENSSL/.openssl" ;;
- *) ngx_prefix="$PWD/$OPENSSL/.openssl" ;;
- esac
-
- cat << END >> $NGX_MAKEFILE
-
-$OPENSSL/.openssl/include/openssl/ssl.h: $NGX_MAKEFILE
- cd $OPENSSL \\
- && if [ -f Makefile ]; then \$(MAKE) clean; fi \\
- && ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\
- && \$(MAKE) \\
- && \$(MAKE) install LIBDIR=lib
-
-END
-
- ;;
-
-esac
diff --git a/usr.sbin/nginx/auto/lib/openssl/makefile.bcc b/usr.sbin/nginx/auto/lib/openssl/makefile.bcc
deleted file mode 100644
index 6a94ff74982..00000000000
--- a/usr.sbin/nginx/auto/lib/openssl/makefile.bcc
+++ /dev/null
@@ -1,18 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-all:
- cd $(OPENSSL)
-
- perl Configure BC-32 no-shared --prefix=openssl $(OPENSSL_OPT)
-
- ms\do_nasm
-
- $(MAKE) -f ms\bcb.mak
- $(MAKE) -f ms\bcb.mak install
-
- # Borland's make does not expand "[ch]" in
- # copy "inc32\openssl\*.[ch]" "openssl\include\openssl"
- copy inc32\openssl\*.h openssl\include\openssl
diff --git a/usr.sbin/nginx/auto/lib/openssl/makefile.msvc b/usr.sbin/nginx/auto/lib/openssl/makefile.msvc
deleted file mode 100644
index fc9e57864ae..00000000000
--- a/usr.sbin/nginx/auto/lib/openssl/makefile.msvc
+++ /dev/null
@@ -1,14 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-all:
- cd $(OPENSSL)
-
- perl Configure VC-WIN32 no-shared --prefix=openssl $(OPENSSL_OPT)
-
- ms\do_ms
-
- $(MAKE) -f ms\nt.mak
- $(MAKE) -f ms\nt.mak install
diff --git a/usr.sbin/nginx/auto/lib/pcre/conf b/usr.sbin/nginx/auto/lib/pcre/conf
deleted file mode 100644
index eeecffb0dc9..00000000000
--- a/usr.sbin/nginx/auto/lib/pcre/conf
+++ /dev/null
@@ -1,209 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-if [ $PCRE != NONE ]; then
- CORE_INCS="$CORE_INCS $PCRE"
-
- case "$NGX_CC_NAME" in
-
- msvc* | owc* | bcc)
- have=NGX_PCRE . auto/have
- have=PCRE_STATIC . auto/have
- CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
- LINK_DEPS="$LINK_DEPS $PCRE/pcre.lib"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre.lib"
- ;;
-
- icc* )
- have=NGX_PCRE . auto/have
- CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
-
- LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
-
- echo $ngx_n "checking for PCRE library ...$ngx_c"
-
- if [ -f $PCRE/pcre.h ]; then
- ngx_pcre_ver=`grep PCRE_MAJOR $PCRE/pcre.h \
- | sed -e 's/^.*PCRE_MAJOR.* \(.*\)$/\1/'`
-
- 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"
-
- # to allow -ipo optimization we link with the *.o but not library
-
- case "$ngx_pcre_ver" in
- 4|5)
- CORE_LIBS="$CORE_LIBS $PCRE/pcre.o"
- ;;
-
- 6)
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_chartables.o"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_compile.o"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_exec.o"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_fullinfo.o"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_globals.o"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_tables.o"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_try_flipped.o"
- ;;
-
- *)
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_chartables.o"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_compile.o"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_exec.o"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_fullinfo.o"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_globals.o"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_tables.o"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_try_flipped.o"
- CORE_LIBS="$CORE_LIBS $PCRE/pcre_newline.o"
- ;;
-
- esac
- ;;
-
- *)
- have=NGX_PCRE . auto/have
-
- if [ "$NGX_PLATFORM" = win32 ]; then
- have=PCRE_STATIC . auto/have
- fi
-
- CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
- LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
- CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre.a"
- ;;
-
- esac
-
-
- if [ $PCRE_JIT = YES ]; then
- have=NGX_HAVE_PCRE_JIT . auto/have
- PCRE_CONF_OPT="$PCRE_CONF_OPT --enable-jit"
- fi
-
-else
-
- if [ "$NGX_PLATFORM" != win32 -a `uname -s` != OpenBSD ]; then
-
- PCRE=NO
-
- ngx_feature="PCRE library"
- ngx_feature_name="NGX_PCRE"
- ngx_feature_run=no
- ngx_feature_incs="#include <pcre.h>"
- ngx_feature_path=
- ngx_feature_libs="-lpcre"
- ngx_feature_test="pcre *re;
- re = pcre_compile(NULL, 0, NULL, 0, NULL);
- if (re == NULL) return 1"
- . auto/feature
-
- if [ $ngx_found = no ]; then
-
- # FreeBSD port
-
- ngx_feature="PCRE library in /usr/local/"
- ngx_feature_path="/usr/local/include"
-
- 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
-
- . auto/feature
- fi
-
- if [ $ngx_found = no ]; then
-
- # RedHat RPM, Solaris package
-
- ngx_feature="PCRE library in /usr/include/pcre/"
- ngx_feature_path="/usr/include/pcre"
- ngx_feature_libs="-lpcre"
-
- . auto/feature
- fi
-
- if [ $ngx_found = no ]; then
-
- # NetBSD port
-
- ngx_feature="PCRE library in /usr/pkg/"
- ngx_feature_path="/usr/pkg/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lpcre"
- else
- ngx_feature_libs="-L/usr/pkg/lib -lpcre"
- fi
-
- . auto/feature
- fi
-
- if [ $ngx_found = no ]; then
-
- # MacPorts
-
- ngx_feature="PCRE library in /opt/local/"
- ngx_feature_path="/opt/local/include"
-
- if [ $NGX_RPATH = YES ]; then
- ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lpcre"
- else
- ngx_feature_libs="-L/opt/local/lib -lpcre"
- fi
-
- . auto/feature
- fi
-
- if [ $ngx_found = yes ]; then
- CORE_INCS="$CORE_INCS $ngx_feature_path"
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
- PCRE=YES
- fi
-
- if [ $PCRE = YES ]; then
- ngx_feature="PCRE JIT support"
- ngx_feature_name="NGX_HAVE_PCRE_JIT"
- ngx_feature_test="int jit = 0;
- pcre_free_study(NULL);
- pcre_config(PCRE_CONFIG_JIT, &jit);
- if (jit != 1) return 1;"
- . auto/feature
-
- if [ $ngx_found = yes ]; then
- PCRE_JIT=YES
- fi
- fi
- fi
-
- have=NGX_PCRE . auto/have
- CORE_SRCS="$CORE_SRCS $PCRE_SRCS"
- CORE_INCS="$CORE_INCS src/pcre"
- CFLAGS="$CFLAGS -DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10"
- PCRE=YES
-
- if [ $PCRE != YES ]; then
-cat << END
-
-$0: error: the HTTP rewrite module requires the PCRE library.
-You can either disable the module by using --without-http_rewrite_module
-option, or install the PCRE library into the system, or build the PCRE library
-statically from the source with nginx by using --with-pcre=<path> option.
-
-END
- exit 1
- fi
-
-fi
diff --git a/usr.sbin/nginx/auto/lib/pcre/make b/usr.sbin/nginx/auto/lib/pcre/make
deleted file mode 100644
index 0a27a112c11..00000000000
--- a/usr.sbin/nginx/auto/lib/pcre/make
+++ /dev/null
@@ -1,64 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-case "$NGX_CC_NAME" in
-
- msvc*)
- ngx_makefile=makefile.msvc
- ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC"
- ngx_pcre="PCRE=\"$PCRE\""
- ;;
-
- owc*)
- ngx_makefile=makefile.owc
- ngx_opt="CPU_OPT=\"$CPU_OPT\""
- ngx_pcre=`echo PCRE=\"$PCRE\" | sed -e "s/\//$ngx_regex_dirsep/g"`
- ;;
-
- bcc)
- ngx_makefile=makefile.bcc
- ngx_opt="-DCPU_OPT=\"$CPU_OPT\""
- ngx_pcre=`echo \-DPCRE=\"$PCRE\" | sed -e "s/\//$ngx_regex_dirsep/g"`
- ;;
-
- *)
- ngx_makefile=
- ;;
-
-esac
-
-
-if [ -n "$ngx_makefile" ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-`echo "$PCRE/pcre.lib: $PCRE/pcre.h $NGX_MAKEFILE" \
- | sed -e "s/\//$ngx_regex_dirsep/g"`
- \$(MAKE) -f auto/lib/pcre/$ngx_makefile $ngx_pcre $ngx_opt
-
-`echo "$PCRE/pcre.h:" | sed -e "s/\//$ngx_regex_dirsep/g"`
- \$(MAKE) -f auto/lib/pcre/$ngx_makefile $ngx_pcre pcre.h
-
-END
-
-else
-
- cat << END >> $NGX_MAKEFILE
-
-$PCRE/pcre.h: $PCRE/Makefile
-
-$PCRE/Makefile: $NGX_MAKEFILE
- cd $PCRE \\
- && if [ -f Makefile ]; then \$(MAKE) distclean; fi \\
- && CC="\$(CC)" CFLAGS="$PCRE_OPT" \\
- ./configure --disable-shared $PCRE_CONF_OPT
-
-$PCRE/.libs/libpcre.a: $PCRE/Makefile
- cd $PCRE \\
- && \$(MAKE) libpcre.la
-
-END
-
-fi
diff --git a/usr.sbin/nginx/auto/lib/pcre/makefile.bcc b/usr.sbin/nginx/auto/lib/pcre/makefile.bcc
deleted file mode 100644
index 7a0f2beafc6..00000000000
--- a/usr.sbin/nginx/auto/lib/pcre/makefile.bcc
+++ /dev/null
@@ -1,27 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -q -O2 -tWM -w-8004 $(CPU_OPT)
-PCREFLAGS = -DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10 \
- -DSUPPORT_PCRE8 -DHAVE_MEMMOVE
-
-
-pcre.lib:
- cd $(PCRE)
-
- bcc32 -c $(CFLAGS) -I. $(PCREFLAGS) pcre_*.c
-
- copy /y nul pcre.lst
- for %n in (*.obj) do @echo +%n ^^& >> pcre.lst
- echo + >> pcre.lst
-
- tlib pcre.lib @pcre.lst
-
-pcre.h:
- cd $(PCRE)
-
- copy /y pcre.h.generic pcre.h
- copy /y config.h.generic config.h
- copy /y pcre_chartables.c.dist pcre_chartables.c
diff --git a/usr.sbin/nginx/auto/lib/pcre/makefile.msvc b/usr.sbin/nginx/auto/lib/pcre/makefile.msvc
deleted file mode 100644
index 07fd9a2853a..00000000000
--- a/usr.sbin/nginx/auto/lib/pcre/makefile.msvc
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT)
-PCREFLAGS = -DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10 \
- -DSUPPORT_PCRE8 -DHAVE_MEMMOVE
-
-
-pcre.lib:
- cd $(PCRE)
-
- cl -nologo -c $(CFLAGS) -I . $(PCREFLAGS) pcre_*.c
-
- link -lib -out:pcre.lib -verbose:lib pcre_*.obj
-
-pcre.h:
- cd $(PCRE)
-
- copy /y pcre.h.generic pcre.h
- copy /y config.h.generic config.h
- copy /y pcre_chartables.c.dist pcre_chartables.c
diff --git a/usr.sbin/nginx/auto/lib/pcre/makefile.owc b/usr.sbin/nginx/auto/lib/pcre/makefile.owc
deleted file mode 100644
index 122fd5b27f2..00000000000
--- a/usr.sbin/nginx/auto/lib/pcre/makefile.owc
+++ /dev/null
@@ -1,25 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -c -zq -bt=nt -ot -op -oi -oe -s -bm $(CPU_OPT)
-PCREFLAGS = -DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10 &
- -DSUPPORT_PCRE8 -DHAVE_MEMMOVE
-
-
-pcre.lib:
- cd $(PCRE)
-
- wcl386 $(CFLAGS) -i=. $(PCREFLAGS) pcre_*.c
-
- dir /b *.obj > pcre.lst
-
- wlib -n pcre.lib @pcre.lst
-
-pcre.h:
- cd $(PCRE)
-
- copy /y pcre.h.generic pcre.h
- copy /y config.h.generic config.h
- copy /y pcre_chartables.c.dist pcre_chartables.c
diff --git a/usr.sbin/nginx/auto/lib/perl/conf b/usr.sbin/nginx/auto/lib/perl/conf
deleted file mode 100644
index 2fbaa76b716..00000000000
--- a/usr.sbin/nginx/auto/lib/perl/conf
+++ /dev/null
@@ -1,70 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-echo "checking for perl"
-
-
-NGX_PERL_VER=`$NGX_PERL -v 2>&1 | grep '^This is perl' 2>&1 \
- | sed -e 's/^This is perl, \(.*\)/\1/'`
-
-if test -n "$NGX_PERL_VER"; then
- echo " + perl version: $NGX_PERL_VER"
-
- if [ "`$NGX_PERL -e 'use 5.006001; print "OK"'`" != "OK" ]; then
- echo
- echo "$0: error: perl 5.6.1 or higher is required"
- echo
-
- exit 1;
- fi
-
- if [ "`$NGX_PERL -MExtUtils::Embed -e 'print "OK"'`" != "OK" ]; then
- echo
- echo "$0: error: perl module ExtUtils::Embed is required"
- echo
-
- exit 1;
- fi
-
- NGX_PERL_CFLAGS="$CFLAGS `$NGX_PERL -MExtUtils::Embed -e ccopts`"
- NGX_PM_CFLAGS=`$NGX_PERL -MExtUtils::Embed -e ccopts`
-
- # gcc 4.1/4.2 warn about unused values in pTHX_
- NGX_PERL_CFLAGS=`echo $NGX_PERL_CFLAGS \
- | sed -e 's/-Wunused-value/-Wno-unused-value/'`
- # icc8 warns 'declaration hides parameter "my_perl"' in ENTER and LEAVE
- NGX_PERL_CFLAGS=`echo $NGX_PERL_CFLAGS \
- | sed -e 's/-wd171/-wd171 -wd1599/'`
-
- ngx_perl_ldopts=`$NGX_PERL -MExtUtils::Embed -e ldopts`
-
- ngx_perl_dlext=`$NGX_PERL -MConfig -e 'print $Config{dlext}'`
-
- if $NGX_PERL -V:usemultiplicity | grep define > /dev/null; then
- have=NGX_HAVE_PERL_MULTIPLICITY . auto/have
- echo " + perl interpreter multiplicity found"
- fi
-
- if $NGX_PERL -V:useithreads | grep undef > /dev/null; then
- # FreeBSD port wants to link with -pthread non-threaded perl
- ngx_perl_ldopts=`echo $ngx_perl_ldopts | sed 's/ -pthread//'`
- fi
-
- CORE_LINK="$CORE_LINK $ngx_perl_ldopts"
- LINK_DEPS="$LINK_DEPS $NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.$ngx_perl_dlext"
-
- if test -n "$NGX_PERL_MODULES"; then
- have=NGX_PERL_MODULES value="(u_char *) \"$NGX_PERL_MODULES\""
- . auto/define
- NGX_PERL_MODULES_MAN=$NGX_PERL_MODULES/man3
- fi
-
-else
- echo
- echo "$0: error: perl 5.6.1 or higher is required"
- echo
-
- exit 1;
-fi
diff --git a/usr.sbin/nginx/auto/lib/perl/make b/usr.sbin/nginx/auto/lib/perl/make
deleted file mode 100644
index d1c1b9e48c1..00000000000
--- a/usr.sbin/nginx/auto/lib/perl/make
+++ /dev/null
@@ -1,41 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-v=`grep 'define NGINX_VERSION' src/core/nginx.h | sed -e 's/^.*"\(.*\)".*/\1/'`
-
-
-cat << END >> $NGX_MAKEFILE
-
-$NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.$ngx_perl_dlext: \\
- \$(CORE_DEPS) \$(HTTP_DEPS) \\
- src/http/modules/perl/ngx_http_perl_module.h \\
- $NGX_OBJS/src/http/modules/perl/Makefile
- cd $NGX_OBJS/src/http/modules/perl && \$(MAKE)
-
- rm -rf $NGX_OBJS/install_perl
-
-
-$NGX_OBJS/src/http/modules/perl/Makefile: \\
- $NGX_AUTO_CONFIG_H \\
- src/core/nginx.h \\
- src/http/modules/perl/Makefile.PL \\
- src/http/modules/perl/nginx.pm \\
- src/http/modules/perl/nginx.xs \\
- src/http/modules/perl/typemap
- sed "s/%%VERSION%%/$v/" src/http/modules/perl/nginx.pm > \\
- $NGX_OBJS/src/http/modules/perl/nginx.pm
- cp -p src/http/modules/perl/nginx.xs $NGX_OBJS/src/http/modules/perl/
- cp -p src/http/modules/perl/typemap $NGX_OBJS/src/http/modules/perl/
- cp -p src/http/modules/perl/Makefile.PL $NGX_OBJS/src/http/modules/perl/
-
- cd $NGX_OBJS/src/http/modules/perl \\
- && NGX_PM_CFLAGS="\$(NGX_PM_CFLAGS) -g $NGX_CC_OPT" \\
- NGX_INCS="$CORE_INCS $NGX_OBJS $HTTP_INCS" \\
- NGX_DEPS="\$(CORE_DEPS) \$(HTTP_DEPS)" \\
- $NGX_PERL Makefile.PL \\
- LIB=$NGX_PERL_MODULES \\
- INSTALLSITEMAN3DIR=$NGX_PERL_MODULES_MAN
-
-END
diff --git a/usr.sbin/nginx/auto/lib/sha1/conf b/usr.sbin/nginx/auto/lib/sha1/conf
deleted file mode 100644
index fd69afda22b..00000000000
--- a/usr.sbin/nginx/auto/lib/sha1/conf
+++ /dev/null
@@ -1,79 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-if [ $SHA1 != NONE ]; then
-
- have=NGX_HAVE_SHA1 . auto/have
- CORE_INCS="$CORE_INCS $SHA1"
-
- case "$NGX_CC_NAME" in
-
- msvc* | owc* | bcc)
- LINK_DEPS="$LINK_DEPS $SHA1/sha1.lib"
- CORE_LIBS="$CORE_LIBS $SHA1/sha1.lib"
- ;;
-
- icc*)
- LINK_DEPS="$LINK_DEPS $SHA1/libsha.a"
-
- # to allow -ipo optimization we link with the *.o but not library
- CORE_LIBS="$CORE_LIBS $SHA1/sha1_dgst.o"
-
- if [ $SHA1_ASM = YES ]; then
- CORE_LIBS="$CORE_LIBS $SHA1/asm/sx86-elf.o"
- fi
- ;;
-
- *)
- LINK_DEPS="$LINK_DEPS $SHA1/libsha.a"
- CORE_LIBS="$CORE_LIBS $SHA1/libsha.a"
- #CORE_LIBS="$CORE_LIBS -L $SHA1 -lsha"
- ;;
-
- esac
-
-else
-
- if [ "$NGX_PLATFORM" != win32 ]; then
-
- SHA1=NO
-
- # FreeBSD
-
- ngx_feature="sha1 in system md library"
- ngx_feature_name=NGX_HAVE_SHA1
- ngx_feature_run=no
- ngx_feature_incs="#include <sha.h>"
- ngx_feature_path=
- ngx_feature_libs="-lmd"
- ngx_feature_test="SHA_CTX sha1; SHA1_Init(&sha1)"
- . auto/feature
-
- ngx_sha1_lib="system md"
-
- if [ $ngx_found = no ]; then
-
- # OpenSSL crypto library
-
- ngx_feature="sha1 in system OpenSSL crypto library"
- ngx_feature_incs="#include <openssl/sha.h>"
- ngx_feature_libs="-lcrypto"
- . auto/feature
-
- ngx_sha1_lib="system crypto"
-
- if [ $ngx_found = yes ]; then
- have=NGX_HAVE_OPENSSL_SHA1_H . auto/have
- fi
- fi
-
- if [ $ngx_found = yes ]; then
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
- SHA1=YES
- SHA1_LIB=$ngx_sha1_lib
- fi
- fi
-
-fi
diff --git a/usr.sbin/nginx/auto/lib/sha1/make b/usr.sbin/nginx/auto/lib/sha1/make
deleted file mode 100644
index fc10aaef38b..00000000000
--- a/usr.sbin/nginx/auto/lib/sha1/make
+++ /dev/null
@@ -1,96 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-case "$NGX_CC_NAME" in
-
- msvc*)
- ngx_makefile=makefile.msvc
- ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC SHA1_ASM=$SHA1_ASM"
- ngx_sha1="SHA1=\"$SHA1\""
- ;;
-
- owc*)
- ngx_makefile=makefile.owc
- ngx_opt="CPU_OPT=\"$CPU_OPT\""
- ngx_sha1=`echo SHA1=\"$SHA1\" | sed -e "s/\//$ngx_regex_dirsep/g"`
- ;;
-
- bcc)
- ngx_makefile=makefile.bcc
- ngx_opt="-DCPU_OPT=\"$CPU_OPT\" -DSHA1_ASM=$SHA1_ASM"
- ngx_sha1=`echo \-DSHA1=\"$SHA1\" | sed -e "s/\//$ngx_regex_dirsep/g"`
- ;;
-
-esac
-
-
-done=NO
-
-
-case "$NGX_PLATFORM" in
-
- win32)
- cat << END >> $NGX_MAKEFILE
-
-`echo "$SHA1/sha1.lib: $NGX_MAKEFILE" | sed -e "s/\//$ngx_regex_dirsep/g"`
- \$(MAKE) -f auto/lib/sha1/$ngx_makefile $ngx_opt $ngx_sha1
-
-END
-
- done=YES
- ;;
-
- SunOS:*:i86pc)
- if [ $SHA1_ASM = YES ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$SHA1/libsha.a: $NGX_MAKEFILE
- cd $SHA1 \\
- && \$(MAKE) CFLAGS="$SHA1_OPT -DSOL -DSHA1_ASM -DL_ENDIAN" \\
- CC="\$(CC)" CPP="\$(CPP)" \\
- SHA_ASM_OBJ=asm/sx86-sol.o clean libsha.a
-
-END
-
- done=YES
- fi
- ;;
-
- # FreeBSD: i386
- # Linux: i686
-
- *:i386 | *:i686)
- if [ $SHA1_ASM = YES ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$SHA1/libsha.a: $NGX_MAKEFILE
- cd $SHA1 \\
- && \$(MAKE) CFLAGS="$SHA1_OPT -DELF -DSHA1_ASM -DL_ENDIAN" \\
- CC="\$(CC)" CPP="\$(CPP)" \\
- SHA_ASM_OBJ=asm/sx86-elf.o clean libsha.a
-
-END
-
- done=YES
- fi
- ;;
-
-esac
-
-
-if [ $done = NO ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$SHA1/libsha.a: $NGX_MAKEFILE
- cd $SHA1 \\
- && \$(MAKE) CFLAGS="$SHA1_OPT" \\
- CC="\$(CC)" SHA_ASM_OBJ= clean libsha.a
-
-END
-
-fi
diff --git a/usr.sbin/nginx/auto/lib/sha1/makefile.bcc b/usr.sbin/nginx/auto/lib/sha1/makefile.bcc
deleted file mode 100644
index b0685fa4512..00000000000
--- a/usr.sbin/nginx/auto/lib/sha1/makefile.bcc
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -q -O2 -tWM $(CPU_OPT) -DL_ENDIAN
-
-!if "$(SHA1_ASM)" == "YES"
-
-sha1.lib:
- cd $(SHA1)
- bcc32 -c $(CFLAGS) -DSHA1_ASM sha1dgst.c
- tlib sha1.lib +sha1dgst.obj +"asm\s-win32.obj"
-
-!else
-
-sha1.lib:
- cd $(SHA1)
- bcc32 -c $(CFLAGS) sha1dgst.c
- tlib sha1.lib +sha1dgst.obj
-
-!endif
diff --git a/usr.sbin/nginx/auto/lib/sha1/makefile.msvc b/usr.sbin/nginx/auto/lib/sha1/makefile.msvc
deleted file mode 100644
index 3cbd21b3dbd..00000000000
--- a/usr.sbin/nginx/auto/lib/sha1/makefile.msvc
+++ /dev/null
@@ -1,22 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -nologo -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT) -D L_ENDIAN
-
-!IF "$(SHA1_ASM)" == "YES"
-
-sha1.lib:
- cd $(SHA1)
- cl -c $(CFLAGS) -D SHA1_ASM sha1dgst.c
- link -lib -out:sha1.lib sha1dgst.obj asm/s-win32.obj
-
-!ELSE
-
-sha1.lib:
- cd $(SHA1)
- cl -c $(CFLAGS) sha1dgst.c
- link -lib -out:sha1.lib sha1dgst.obj
-
-!ENDIF
diff --git a/usr.sbin/nginx/auto/lib/sha1/makefile.owc b/usr.sbin/nginx/auto/lib/sha1/makefile.owc
deleted file mode 100644
index fc095cc980a..00000000000
--- a/usr.sbin/nginx/auto/lib/sha1/makefile.owc
+++ /dev/null
@@ -1,11 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -zq -bt=nt -bm -ot -op -oi -oe -s $(CPU_OPT)
-
-sha1.lib:
- cd $(SHA1)
- wcl386 -c $(CFLAGS) -dL_ENDIAN sha1dgst.c
- wlib -n sha1.lib sha1dgst.obj
diff --git a/usr.sbin/nginx/auto/lib/test b/usr.sbin/nginx/auto/lib/test
deleted file mode 100644
index ba943a29d40..00000000000
--- a/usr.sbin/nginx/auto/lib/test
+++ /dev/null
@@ -1,40 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-echo $ngx_n "checking for $ngx_lib ...$ngx_c"
-
-cat << END >> $NGX_AUTOCONF_ERR
-
-----------------------------------------
-checking for $ngx_lib
-
-END
-
-ngx_found=no
-
-cat << END > $NGX_AUTOTEST.c
-
-$ngx_lib_incs
-
-int main() {
- $ngx_lib_test;
- return 0;
-}
-
-
-eval "$CC $cc_test_flags $ngx_lib_cflags \
- -o $NGX_AUTOTEST $NGX_AUTOTEST.c $ngx_libs \
- >> $NGX_ERR 2>&1"
-
-if [ -x $NGX_AUTOTEST ]; then
- echo " found"
-
- ngx_found=yes
-
-else
- echo " not found"
-fi
-
-rm -rf $NGX_AUTOTEST*
diff --git a/usr.sbin/nginx/auto/lib/zlib/conf b/usr.sbin/nginx/auto/lib/zlib/conf
deleted file mode 100644
index 26db642ac90..00000000000
--- a/usr.sbin/nginx/auto/lib/zlib/conf
+++ /dev/null
@@ -1,79 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-if [ $ZLIB != NONE ]; then
- CORE_INCS="$CORE_INCS $ZLIB"
-
- case "$NGX_CC_NAME" in
-
- msvc* | owc* | bcc)
- have=NGX_ZLIB . auto/have
- LINK_DEPS="$LINK_DEPS $ZLIB/zlib.lib"
- CORE_LIBS="$CORE_LIBS $ZLIB/zlib.lib"
- ;;
-
- icc*)
- have=NGX_ZLIB . auto/have
- LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
-
- # to allow -ipo optimization we link with the *.o but not library
- CORE_LIBS="$CORE_LIBS $ZLIB/adler32.o"
- CORE_LIBS="$CORE_LIBS $ZLIB/crc32.o"
- CORE_LIBS="$CORE_LIBS $ZLIB/deflate.o"
- CORE_LIBS="$CORE_LIBS $ZLIB/trees.o"
- CORE_LIBS="$CORE_LIBS $ZLIB/zutil.o"
- CORE_LIBS="$CORE_LIBS $ZLIB/compress.o"
-
- if [ $ZLIB_ASM != NO ]; then
- CORE_LIBS="$CORE_LIBS $ZLIB/match.o"
- fi
- ;;
-
- *)
- have=NGX_ZLIB . auto/have
- LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
- CORE_LIBS="$CORE_LIBS $ZLIB/libz.a"
- #CORE_LIBS="$CORE_LIBS -L $ZLIB -lz"
- ;;
-
- esac
-
-else
-
- if [ "$NGX_PLATFORM" != win32 ]; then
- ZLIB=NO
-
- # FreeBSD, Solaris, Linux
-
- ngx_feature="zlib library"
- ngx_feature_name="NGX_ZLIB"
- ngx_feature_run=no
- ngx_feature_incs="#include <zlib.h>"
- ngx_feature_path=
- ngx_feature_libs="-lz"
- ngx_feature_test="z_stream z; deflate(&z, Z_NO_FLUSH)"
- . auto/feature
-
-
- if [ $ngx_found = yes ]; then
- CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
- ZLIB=YES
- ngx_found=no
- fi
- fi
-
- if [ $ZLIB != YES ]; then
-cat << END
-
-$0: error: the HTTP gzip module requires the zlib library.
-You can either disable the module by using --without-http_gzip_module
-option, or install the zlib library into the system, or build the zlib library
-statically from the source with nginx by using --with-zlib=<path> option.
-
-END
- exit 1
- fi
-
-fi
diff --git a/usr.sbin/nginx/auto/lib/zlib/make b/usr.sbin/nginx/auto/lib/zlib/make
deleted file mode 100644
index 7875ef67fe0..00000000000
--- a/usr.sbin/nginx/auto/lib/zlib/make
+++ /dev/null
@@ -1,135 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-case "$NGX_CC_NAME" in
-
- msvc*)
- ngx_makefile=makefile.msvc
- ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC"
- ngx_zlib="ZLIB=\"$ZLIB\""
-
- ;;
-
- owc*)
- ngx_makefile=makefile.owc
- ngx_opt="CPU_OPT=\"$CPU_OPT\""
- ngx_zlib=`echo ZLIB=\"$ZLIB\" | sed -e "s/\//$ngx_regex_dirsep/g"`
- ;;
-
- bcc)
- ngx_makefile=makefile.bcc
- ngx_opt="-DCPU_OPT=\"$CPU_OPT\""
- ngx_zlib=`echo \-DZLIB=\"$ZLIB\" | sed -e "s/\//$ngx_regex_dirsep/g"`
- ;;
-
- *)
- ngx_makefile=
- ;;
-
-esac
-
-
-done=NO
-
-
-case "$NGX_PLATFORM" in
-
- win32)
-
- if [ -n "$ngx_makefile" ]; then
- cat << END >> $NGX_MAKEFILE
-
-`echo "$ZLIB/zlib.lib: $NGX_MAKEFILE" | sed -e "s/\//$ngx_regex_dirsep/g"`
- \$(MAKE) -f auto/lib/zlib/$ngx_makefile $ngx_opt $ngx_zlib
-
-END
-
- else
-
- cat << END >> $NGX_MAKEFILE
-
-$ZLIB/libz.a: $NGX_MAKEFILE
- cd $ZLIB \\
- && \$(MAKE) distclean \\
- && \$(MAKE) -f win32/Makefile.gcc \\
- CFLAGS="$ZLIB_OPT" CC="\$(CC)" \\
- libz.a
-
-END
-
- fi
-
- done=YES
- ;;
-
- # FreeBSD: i386
- # Linux: i686
-
- *:i386 | *:i686)
- case $ZLIB_ASM in
- pentium)
-
- cat << END >> $NGX_MAKEFILE
-
-$ZLIB/libz.a: $NGX_MAKEFILE
- cd $ZLIB \\
- && \$(MAKE) distclean \\
- && cp contrib/asm586/match.S . \\
- && CFLAGS="$ZLIB_OPT -DASMV" CC="\$(CC)" \\
- ./configure \\
- && \$(MAKE) OBJA=match.o libz.a
-
-END
-
- done=YES
- ;;
-
- pentiumpro)
-
- cat << END >> $NGX_MAKEFILE
-
-$ZLIB/libz.a: $NGX_MAKEFILE
- cd $ZLIB \\
- && \$(MAKE) distclean \\
- && cp contrib/asm686/match.S . \\
- && CFLAGS="$ZLIB_OPT -DASMV" CC="\$(CC)" \\
- ./configure \\
- && \$(MAKE) OBJA=match.o libz.a
-
-END
-
- done=YES
- ;;
-
- NO)
- ;;
-
- *)
- echo "$0: error: invalid --with-zlib-asm=$ZLIB_ASM option."
- echo "The valid values are \"pentium\" and \"pentiumpro\" only".
- echo
-
- exit 1;
- ;;
- esac
- ;;
-
-esac
-
-
-if [ $done = NO ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$ZLIB/libz.a: $NGX_MAKEFILE
- cd $ZLIB \\
- && \$(MAKE) distclean \\
- && CFLAGS="$ZLIB_OPT" CC="\$(CC)" \\
- ./configure \\
- && \$(MAKE) libz.a
-
-END
-
-fi
diff --git a/usr.sbin/nginx/auto/lib/zlib/makefile.bcc b/usr.sbin/nginx/auto/lib/zlib/makefile.bcc
deleted file mode 100644
index 97a30ea3951..00000000000
--- a/usr.sbin/nginx/auto/lib/zlib/makefile.bcc
+++ /dev/null
@@ -1,17 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -q -O2 -tWM -w-8004 -w-8012 $(CPU_OPT)
-
-zlib.lib:
- cd $(ZLIB)
-
- bcc32 -c $(CFLAGS) adler32.c crc32.c deflate.c \
- trees.c zutil.c compress.c \
- inflate.c inffast.c inftrees.c
-
- tlib zlib.lib +adler32.obj +crc32.obj +deflate.obj \
- +trees.obj +zutil.obj +compress.obj \
- +inflate.obj +inffast.obj +inftrees.obj
diff --git a/usr.sbin/nginx/auto/lib/zlib/makefile.msvc b/usr.sbin/nginx/auto/lib/zlib/makefile.msvc
deleted file mode 100644
index 6fbd6918c2f..00000000000
--- a/usr.sbin/nginx/auto/lib/zlib/makefile.msvc
+++ /dev/null
@@ -1,17 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -nologo -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT)
-
-zlib.lib:
- cd $(ZLIB)
-
- cl -c $(CFLAGS) adler32.c crc32.c deflate.c \
- trees.c zutil.c compress.c \
- inflate.c inffast.c inftrees.c
-
- link -lib -out:zlib.lib adler32.obj crc32.obj deflate.obj \
- trees.obj zutil.obj compress.obj \
- inflate.obj inffast.obj inftrees.obj
diff --git a/usr.sbin/nginx/auto/lib/zlib/makefile.owc b/usr.sbin/nginx/auto/lib/zlib/makefile.owc
deleted file mode 100644
index 9e123be83e9..00000000000
--- a/usr.sbin/nginx/auto/lib/zlib/makefile.owc
+++ /dev/null
@@ -1,14 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CFLAGS = -zq -bt=nt -ot -op -oi -oe -s -bm $(CPU_OPT)
-
-zlib.lib:
- cd $(ZLIB)
-
- wcl386 -c $(CFLAGS) adler32.c crc32.c deflate.c trees.c zutil.c &
- compress.c inflate.c inffast.c inftrees.c
- wlib -n zlib.lib adler32.obj crc32.obj deflate.obj trees.obj &
- zutil.obj compress.obj inflate.obj inffast.obj inftrees.obj
diff --git a/usr.sbin/nginx/auto/lib/zlib/patch.zlib.h b/usr.sbin/nginx/auto/lib/zlib/patch.zlib.h
deleted file mode 100644
index 122f7fa86a4..00000000000
--- a/usr.sbin/nginx/auto/lib/zlib/patch.zlib.h
+++ /dev/null
@@ -1,10 +0,0 @@
---- zlib.h Thu Jul 9 20:06:56 1998
-+++ zlib-1.1.3/zlib.h Tue Mar 22 13:41:04 2005
-@@ -709,7 +709,6 @@
- (0 in case of error).
- */
-
--ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
- /*
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
diff --git a/usr.sbin/nginx/auto/make b/usr.sbin/nginx/auto/make
deleted file mode 100644
index 7923d789e3f..00000000000
--- a/usr.sbin/nginx/auto/make
+++ /dev/null
@@ -1,418 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-echo "creating $NGX_MAKEFILE"
-
-mkdir -p $NGX_OBJS/src/core $NGX_OBJS/src/event $NGX_OBJS/src/event/modules \
- $NGX_OBJS/src/os/unix $NGX_OBJS/src/os/win32 \
- $NGX_OBJS/src/http $NGX_OBJS/src/http/modules \
- $NGX_OBJS/src/http/modules/perl \
- $NGX_OBJS/src/mail \
- $NGX_OBJS/src/misc \
- $NGX_OBJS/src/pcre
-
-
-ngx_objs_dir=$NGX_OBJS$ngx_regex_dirsep
-ngx_use_pch=`echo $NGX_USE_PCH | sed -e "s/\//$ngx_regex_dirsep/g"`
-
-
-cat << END > $NGX_MAKEFILE
-
-CC = $CC
-CFLAGS = $CFLAGS
-CPP = $CPP
-LINK = $LINK
-
-END
-
-
-if test -n "$NGX_PERL_CFLAGS"; then
- echo NGX_PERL_CFLAGS = $NGX_PERL_CFLAGS >> $NGX_MAKEFILE
- echo NGX_PM_CFLAGS = $NGX_PM_CFLAGS >> $NGX_MAKEFILE
-fi
-
-
-# ALL_INCS, required by the addons and by OpenWatcom C precompiled headers
-
-ngx_incs=`echo $CORE_INCS $NGX_OBJS $HTTP_INCS $MAIL_INCS\
- | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont$ngx_include_opt\1/g" \
- -e "s/\//$ngx_regex_dirsep/g"`
-
-cat << END >> $NGX_MAKEFILE
-
-ALL_INCS = $ngx_include_opt$ngx_incs
-
-END
-
-
-ngx_all_srcs="$CORE_SRCS"
-
-
-# the core dependences and include paths
-
-ngx_deps=`echo $CORE_DEPS $NGX_AUTO_CONFIG_H $NGX_PCH \
- | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
- -e "s/\//$ngx_regex_dirsep/g"`
-
-ngx_incs=`echo $CORE_INCS $NGX_OBJS \
- | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont$ngx_include_opt\1/g" \
- -e "s/\//$ngx_regex_dirsep/g"`
-
-cat << END >> $NGX_MAKEFILE
-
-CORE_DEPS = $ngx_deps
-
-
-CORE_INCS = $ngx_include_opt$ngx_incs
-
-END
-
-
-# the http dependences and include paths
-
-if [ $HTTP = YES ]; then
-
- ngx_all_srcs="$ngx_all_srcs $HTTP_SRCS"
-
- ngx_deps=`echo $HTTP_DEPS \
- | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
- -e "s/\//$ngx_regex_dirsep/g"`
-
- ngx_incs=`echo $HTTP_INCS \
- | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont$ngx_include_opt\1/g" \
- -e "s/\//$ngx_regex_dirsep/g"`
-
- cat << END >> $NGX_MAKEFILE
-
-HTTP_DEPS = $ngx_deps
-
-
-HTTP_INCS = $ngx_include_opt$ngx_incs
-
-END
-
-fi
-
-
-# the mail dependences and include paths
-
-if [ $MAIL = YES ]; then
-
- ngx_all_srcs="$ngx_all_srcs $MAIL_SRCS"
-
- ngx_deps=`echo $MAIL_DEPS \
- | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
- -e "s/\//$ngx_regex_dirsep/g"`
-
- ngx_incs=`echo $MAIL_INCS \
- | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont$ngx_include_opt\1/g" \
- -e "s/\//$ngx_regex_dirsep/g"`
-
- cat << END >> $NGX_MAKEFILE
-
-MAIL_DEPS = $ngx_deps
-
-
-MAIL_INCS = $ngx_include_opt$ngx_incs
-
-END
-
-fi
-
-
-ngx_all_srcs="$ngx_all_srcs $NGX_MISC_SRCS"
-
-
-if test -n "$NGX_ADDON_SRCS"; then
-
-cat << END >> $NGX_MAKEFILE
-
-ADDON_DEPS = \$(CORE_DEPS) $NGX_ADDON_DEPS
-
-END
-
-fi
-
-
-# nginx
-
-ngx_all_srcs=`echo $ngx_all_srcs | sed -e "s/\//$ngx_regex_dirsep/g"`
-
-for ngx_src in $NGX_ADDON_SRCS
-do
- ngx_obj="addon/`basename \`dirname $ngx_src\``"
-
- test -d $NGX_OBJS/$ngx_obj || mkdir -p $NGX_OBJS/$ngx_obj
-
- ngx_obj=`echo $ngx_obj/\`basename $ngx_src\` \
- | sed -e "s/\//$ngx_regex_dirsep/g"`
-
- ngx_all_srcs="$ngx_all_srcs $ngx_obj"
-done
-
-ngx_all_objs=`echo $ngx_all_srcs \
- | sed -e "s#\([^ ]*\.\)cpp#$NGX_OBJS\/\1$ngx_objext#g" \
- -e "s#\([^ ]*\.\)cc#$NGX_OBJS\/\1$ngx_objext#g" \
- -e "s#\([^ ]*\.\)c#$NGX_OBJS\/\1$ngx_objext#g" \
- -e "s#\([^ ]*\.\)S#$NGX_OBJS\/\1$ngx_objext#g"`
-
-ngx_modules_c=`echo $NGX_MODULES_C | sed -e "s/\//$ngx_regex_dirsep/g"`
-
-ngx_modules_obj=`echo $ngx_modules_c | sed -e "s/\(.*\.\)c/\1$ngx_objext/"`
-
-
-if test -n "$NGX_RES"; then
- ngx_res=$NGX_RES
-else
- ngx_res="$NGX_RC $NGX_ICONS"
- ngx_rcc=`echo $NGX_RCC | sed -e "s/\//$ngx_regex_dirsep/g"`
-fi
-
-ngx_deps=`echo $ngx_all_objs $ngx_modules_obj $ngx_res $LINK_DEPS \
- | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
- -e "s/\//$ngx_regex_dirsep/g"`
-
-ngx_objs=`echo $ngx_all_objs $ngx_modules_obj \
- | sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \
- -e "s/\//$ngx_regex_dirsep/g"`
-
-if test -n "$NGX_LD_OPT$CORE_LIBS"; then
- ngx_libs=`echo $NGX_LD_OPT $CORE_LIBS \
- | sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`
-fi
-
-ngx_link=${CORE_LINK:+`echo $CORE_LINK \
- | sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`}
-
-
-cat << END >> $NGX_MAKEFILE
-
-$NGX_OBJS${ngx_dirsep}nginx${ngx_binext}: $ngx_deps$ngx_spacer
- \$(LINK) ${ngx_long_start}${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link
- $ngx_rcc
-${ngx_long_end}
-END
-
-
-# ngx_modules.c
-
-if test -n "$NGX_PCH"; then
- ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
-else
- ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS)"
-fi
-
-cat << END >> $NGX_MAKEFILE
-
-$ngx_modules_obj: \$(CORE_DEPS)$ngx_cont$ngx_modules_c
- $ngx_cc$ngx_tab$ngx_objout$ngx_modules_obj$ngx_tab$ngx_modules_c$NGX_AUX
-
-END
-
-
-# the core sources
-
-for ngx_src in $CORE_SRCS
-do
- ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
- ngx_obj=`echo $ngx_src \
- | sed -e "s#^\(.*\.\)cpp\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)cc\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"`
-
- cat << END >> $NGX_MAKEFILE
-
-$ngx_obj: \$(CORE_DEPS)$ngx_cont$ngx_src
- $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
-
-END
-
-done
-
-
-# the http sources
-
-if [ $HTTP = YES ]; then
-
- if test -n "$NGX_PCH"; then
- ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
- else
- ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS) \$(HTTP_INCS)"
- ngx_perl_cc="\$(CC) $ngx_compile_opt \$(NGX_PERL_CFLAGS) "
- ngx_perl_cc="$ngx_perl_cc \$(CORE_INCS) \$(HTTP_INCS)"
- fi
-
- for ngx_source in $HTTP_SRCS
- do
- ngx_src=`echo $ngx_source | sed -e "s/\//$ngx_regex_dirsep/g"`
- ngx_obj=`echo $ngx_src \
- | sed -e "s#^\(.*\.\)cpp\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)cc\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"`
-
- if [ $ngx_source = src/http/modules/perl/ngx_http_perl_module.c ]; then
-
- cat << END >> $NGX_MAKEFILE
-
-$ngx_obj: \$(CORE_DEPS) \$(HTTP_DEPS)$ngx_cont$ngx_src
- $ngx_perl_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
-
-END
- else
-
- cat << END >> $NGX_MAKEFILE
-
-$ngx_obj: \$(CORE_DEPS) \$(HTTP_DEPS)$ngx_cont$ngx_src
- $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
-
-END
-
- fi
- done
-
-fi
-
-
-# the mail sources
-
-if [ $MAIL = YES ]; then
-
- if test -n "$NGX_PCH"; then
- ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
- else
- ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS) \$(MAIL_INCS)"
- fi
-
- for ngx_src in $MAIL_SRCS
- do
- ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
- ngx_obj=`echo $ngx_src \
- | sed -e "s#^\(.*\.\)cpp\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)cc\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"`
-
- cat << END >> $NGX_MAKEFILE
-
-$ngx_obj: \$(CORE_DEPS) \$(MAIL_DEPS)$ngx_cont$ngx_src
- $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
-
-END
- done
-
-fi
-
-
-# the misc sources
-
-if test -n "$NGX_MISC_SRCS"; then
-
- ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
-
- for ngx_src in $NGX_MISC_SRCS
- do
- ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
- ngx_obj=`echo $ngx_src \
- | sed -e "s#^\(.*\.\)cpp\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)cc\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"`
-
- cat << END >> $NGX_MAKEFILE
-
-$ngx_obj: \$(CORE_DEPS) $ngx_cont$ngx_src
- $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
-
-END
- done
-
-fi
-
-
-# the addons sources
-
-if test -n "$NGX_ADDON_SRCS"; then
-
- ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
-
- for ngx_src in $NGX_ADDON_SRCS
- do
- ngx_obj="addon/`basename \`dirname $ngx_src\``"
-
- ngx_obj=`echo $ngx_obj/\`basename $ngx_src\` \
- | sed -e "s/\//$ngx_regex_dirsep/g"`
-
- ngx_obj=`echo $ngx_obj \
- | sed -e "s#^\(.*\.\)cpp\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)cc\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \
- -e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"`
-
- ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
-
- cat << END >> $NGX_MAKEFILE
-
-$ngx_obj: \$(ADDON_DEPS)$ngx_cont$ngx_src
- $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
-
-END
- done
-
-fi
-
-
-# the addons config.make
-
-if test -n "$NGX_ADDONS"; then
-
- for ngx_addon_dir in $NGX_ADDONS
- do
- if test -f $ngx_addon_dir/config.make; then
- . $ngx_addon_dir/config.make
- fi
- done
-fi
-
-
-# Win32 resource file
-
-if test -n "$NGX_RES"; then
-
- ngx_res=`echo "$NGX_RES: $NGX_RC $NGX_ICONS" \
- | sed -e "s/\//$ngx_regex_dirsep/g"`
- ngx_rcc=`echo $NGX_RCC | sed -e "s/\//$ngx_regex_dirsep/g"`
-
- cat << END >> $NGX_MAKEFILE
-
-$ngx_res
- $ngx_rcc
-
-END
-
-fi
-
-
-# the precompiled headers
-
-if test -n "$NGX_PCH"; then
- echo "#include <ngx_config.h>" > $NGX_OBJS/ngx_pch.c
-
- ngx_pch="src/core/ngx_config.h $OS_CONFIG $NGX_OBJS/ngx_auto_config.h"
- ngx_pch=`echo "$NGX_PCH: $ngx_pch" | sed -e "s/\//$ngx_regex_dirsep/g"`
-
- ngx_src="\$(CC) \$(CFLAGS) $NGX_BUILD_PCH $ngx_compile_opt \$(ALL_INCS)"
- ngx_src="$ngx_src $ngx_objout$NGX_OBJS/ngx_pch.obj $NGX_OBJS/ngx_pch.c"
- ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
-
- cat << END >> $NGX_MAKEFILE
-
-$ngx_pch
- $ngx_src
-
-END
-
-fi
diff --git a/usr.sbin/nginx/auto/modules b/usr.sbin/nginx/auto/modules
deleted file mode 100644
index e1eda943fd3..00000000000
--- a/usr.sbin/nginx/auto/modules
+++ /dev/null
@@ -1,529 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-if [ $EVENT_SELECT = NO -a $EVENT_FOUND = NO ]; then
- EVENT_SELECT=YES
-fi
-
-if [ $EVENT_SELECT = YES ]; then
- have=NGX_HAVE_SELECT . auto/have
- CORE_SRCS="$CORE_SRCS $SELECT_SRCS"
- EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE"
-fi
-
-
-if [ $EVENT_POLL = NO -a $EVENT_FOUND = NO ]; then
- EVENT_POLL=YES
-fi
-
-if [ $EVENT_POLL = YES ]; then
- have=NGX_HAVE_POLL . auto/have
- CORE_SRCS="$CORE_SRCS $POLL_SRCS"
- EVENT_MODULES="$EVENT_MODULES $POLL_MODULE"
-fi
-
-
-if [ $NGX_TEST_BUILD_DEVPOLL = YES ]; then
- have=NGX_HAVE_DEVPOLL . auto/have
- have=NGX_TEST_BUILD_DEVPOLL . auto/have
- EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE"
- CORE_SRCS="$CORE_SRCS $DEVPOLL_SRCS"
-fi
-
-
-if [ $NGX_TEST_BUILD_EVENTPORT = YES ]; then
- have=NGX_HAVE_EVENTPORT . auto/have
- have=NGX_TEST_BUILD_EVENTPORT . auto/have
- EVENT_MODULES="$EVENT_MODULES $EVENTPORT_MODULE"
- CORE_SRCS="$CORE_SRCS $EVENTPORT_SRCS"
-fi
-
-if [ $NGX_TEST_BUILD_EPOLL = YES ]; then
- have=NGX_HAVE_EPOLL . auto/have
- have=NGX_HAVE_EPOLLRDHUP . auto/have
- have=NGX_HAVE_EVENTFD . auto/have
- have=NGX_TEST_BUILD_EPOLL . auto/have
- EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
- CORE_SRCS="$CORE_SRCS $EPOLL_SRCS"
-fi
-
-if [ $NGX_TEST_BUILD_RTSIG = YES ]; then
- have=NGX_HAVE_RTSIG . auto/have
- have=NGX_TEST_BUILD_RTSIG . auto/have
- EVENT_MODULES="$EVENT_MODULES $RTSIG_MODULE"
- CORE_SRCS="$CORE_SRCS $RTSIG_SRCS"
-fi
-
-if [ $NGX_TEST_BUILD_SOLARIS_SENDFILEV = YES ]; then
- have=NGX_TEST_BUILD_SOLARIS_SENDFILEV . auto/have
- CORE_SRCS="$CORE_SRCS $SOLARIS_SENDFILEV_SRCS"
-fi
-
-
-if [ $HTTP != YES ]; then
- have=NGX_CRYPT . auto/nohave
- CRYPT_LIB=
-fi
-
-
-if [ $HTTP_CACHE = YES ]; then
- USE_MD5=YES
- have=NGX_HTTP_CACHE . auto/have
- HTTP_SRCS="$HTTP_SRCS $HTTP_FILE_CACHE_SRCS"
-fi
-
-
-if [ $HTTP_SSI = YES ]; then
- HTTP_POSTPONE=YES
-fi
-
-
-if [ $HTTP_ADDITION = YES ]; then
- HTTP_POSTPONE=YES
-fi
-
-
-# the module order is important
-# ngx_http_static_module
-# ngx_http_gzip_static_module
-# ngx_http_dav_module
-# ngx_http_autoindex_module
-# ngx_http_index_module
-# ngx_http_random_index_module
-#
-# ngx_http_access_module
-# ngx_http_realip_module
-#
-#
-# the filter order is important
-# ngx_http_write_filter
-# ngx_http_header_filter
-# ngx_http_chunked_filter
-# ngx_http_spdy_filter
-# ngx_http_range_header_filter
-# ngx_http_gzip_filter
-# ngx_http_postpone_filter
-# ngx_http_ssi_filter
-# ngx_http_charset_filter
-# ngx_http_xslt_filter
-# ngx_http_image_filter
-# ngx_http_sub_filter
-# ngx_http_addition_filter
-# ngx_http_gunzip_filter
-# ngx_http_userid_filter
-# ngx_http_headers_filter
-# ngx_http_copy_filter
-# ngx_http_range_body_filter
-# ngx_http_not_modified_filter
-
-HTTP_FILTER_MODULES="$HTTP_WRITE_FILTER_MODULE \
- $HTTP_HEADER_FILTER_MODULE \
- $HTTP_CHUNKED_FILTER_MODULE"
-
-if [ $HTTP_SPDY = YES ]; then
- HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SPDY_FILTER_MODULE"
-fi
-
-HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_RANGE_HEADER_FILTER_MODULE"
-
-if [ $HTTP_GZIP = YES ]; then
- have=NGX_HTTP_GZIP . auto/have
- USE_ZLIB=YES
- HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_GZIP_FILTER_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_GZIP_SRCS"
-fi
-
-if [ $HTTP_POSTPONE = YES ]; then
- HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_POSTPONE_FILTER_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_POSTPONE_FILTER_SRCS"
-fi
-
-if [ $HTTP_SSI = YES ]; then
- have=NGX_HTTP_SSI . auto/have
- HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SSI_FILTER_MODULE"
- HTTP_DEPS="$HTTP_DEPS $HTTP_SSI_DEPS"
- HTTP_SRCS="$HTTP_SRCS $HTTP_SSI_SRCS"
-fi
-
-if [ $HTTP_CHARSET = YES ]; then
- HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_CHARSET_FILTER_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_CHARSET_SRCS"
-fi
-
-if [ $HTTP_XSLT = YES ]; then
- USE_LIBXSLT=YES
- HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_XSLT_FILTER_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_XSLT_SRCS"
-fi
-
-if [ $HTTP_IMAGE_FILTER = YES ]; then
- USE_LIBGD=YES
- HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_IMAGE_FILTER_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_IMAGE_SRCS"
-fi
-
-if [ $HTTP_SUB = YES ]; then
- HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SUB_FILTER_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_SUB_SRCS"
-fi
-
-if [ $HTTP_ADDITION = YES ]; then
- HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_ADDITION_FILTER_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_ADDITION_SRCS"
-fi
-
-if [ $HTTP_GUNZIP = YES ]; then
- have=NGX_HTTP_GZIP . auto/have
- USE_ZLIB=YES
- HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_GUNZIP_FILTER_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_GUNZIP_SRCS"
-fi
-
-if [ $HTTP_USERID = YES ]; then
- HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_USERID_FILTER_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_USERID_SRCS"
-fi
-
-
-if [ $HTTP_SPDY = YES ]; then
- have=NGX_HTTP_SPDY . auto/have
- USE_ZLIB=YES
- HTTP_MODULES="$HTTP_MODULES $HTTP_SPDY_MODULE"
- HTTP_DEPS="$HTTP_DEPS $HTTP_SPDY_DEPS"
- HTTP_SRCS="$HTTP_SRCS $HTTP_SPDY_SRCS"
-fi
-
-HTTP_MODULES="$HTTP_MODULES $HTTP_STATIC_MODULE"
-
-if [ $HTTP_GZIP_STATIC = YES ]; then
- have=NGX_HTTP_GZIP . auto/have
- HTTP_MODULES="$HTTP_MODULES $HTTP_GZIP_STATIC_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_GZIP_STATIC_SRCS"
-fi
-
-if [ $HTTP_DAV = YES ]; then
- have=NGX_HTTP_DAV . auto/have
- HTTP_MODULES="$HTTP_MODULES $HTTP_DAV_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_DAV_SRCS"
-fi
-
-if [ $HTTP_AUTOINDEX = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_AUTOINDEX_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_AUTOINDEX_SRCS"
-fi
-
-HTTP_MODULES="$HTTP_MODULES $HTTP_INDEX_MODULE"
-
-if [ $HTTP_RANDOM_INDEX = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_RANDOM_INDEX_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_RANDOM_INDEX_SRCS"
-fi
-
-if [ $HTTP_AUTH_REQUEST = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_AUTH_REQUEST_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_AUTH_REQUEST_SRCS"
-fi
-
-if [ $HTTP_AUTH_BASIC = YES ]; then
- USE_MD5=YES
- USE_SHA1=YES
- have=NGX_CRYPT . auto/have
- HTTP_MODULES="$HTTP_MODULES $HTTP_AUTH_BASIC_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_AUTH_BASIC_SRCS"
- CORE_LIBS="$CORE_LIBS $CRYPT_LIB"
-fi
-
-if [ $HTTP_ACCESS = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_ACCESS_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_ACCESS_SRCS"
-fi
-
-if [ $HTTP_LIMIT_CONN = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_LIMIT_CONN_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_LIMIT_CONN_SRCS"
-fi
-
-if [ $HTTP_LIMIT_REQ = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_LIMIT_REQ_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_LIMIT_REQ_SRCS"
-fi
-
-if [ $HTTP_REALIP = YES ]; then
- have=NGX_HTTP_REALIP . auto/have
- have=NGX_HTTP_X_FORWARDED_FOR . auto/have
- HTTP_MODULES="$HTTP_MODULES $HTTP_REALIP_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_REALIP_SRCS"
-fi
-
-if [ $HTTP_STATUS = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_STATUS_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_STATUS_SRCS"
-fi
-
-if [ $HTTP_GEO = YES ]; then
- have=NGX_HTTP_X_FORWARDED_FOR . auto/have
- HTTP_MODULES="$HTTP_MODULES $HTTP_GEO_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_GEO_SRCS"
-fi
-
-if [ $HTTP_GEOIP = YES ]; then
- have=NGX_HTTP_X_FORWARDED_FOR . auto/have
- HTTP_MODULES="$HTTP_MODULES $HTTP_GEOIP_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_GEOIP_SRCS"
-fi
-
-if [ $HTTP_MAP = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_MAP_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_MAP_SRCS"
-fi
-
-if [ $HTTP_SPLIT_CLIENTS = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_SPLIT_CLIENTS_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_SPLIT_CLIENTS_SRCS"
-fi
-
-if [ $HTTP_REFERER = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_REFERER_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_REFERER_SRCS"
-fi
-
-if [ $HTTP_REWRITE = YES -a $USE_PCRE != DISABLED ]; then
- USE_PCRE=YES
- HTTP_MODULES="$HTTP_MODULES $HTTP_REWRITE_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_REWRITE_SRCS"
-fi
-
-if [ $HTTP_SSL = YES ]; then
- USE_OPENSSL=YES
- have=NGX_HTTP_SSL . auto/have
- HTTP_MODULES="$HTTP_MODULES $HTTP_SSL_MODULE"
- HTTP_DEPS="$HTTP_DEPS $HTTP_SSL_DEPS"
- HTTP_SRCS="$HTTP_SRCS $HTTP_SSL_SRCS"
-fi
-
-if [ $HTTP_PROXY = YES ]; then
- have=NGX_HTTP_X_FORWARDED_FOR . auto/have
- #USE_MD5=YES
- HTTP_MODULES="$HTTP_MODULES $HTTP_PROXY_MODULE"
- HTTP_DEPS="$HTTP_DEPS $HTTP_PROXY_DEPS"
- HTTP_SRCS="$HTTP_SRCS $HTTP_PROXY_SRCS"
-fi
-
-if [ $HTTP_FASTCGI = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_FASTCGI_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_FASTCGI_SRCS"
-fi
-
-if [ $HTTP_UWSGI = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_UWSGI_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_UWSGI_SRCS"
-fi
-
-if [ $HTTP_SCGI = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_SCGI_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_SCGI_SRCS"
-fi
-
-if [ $HTTP_PERL = YES ]; then
- USE_PERL=YES
- HTTP_MODULES="$HTTP_MODULES $HTTP_PERL_MODULE"
- HTTP_INCS="$HTTP_INCS $HTTP_PERL_INCS"
- HTTP_DEPS="$HTTP_DEPS $HTTP_PERL_DEPS"
- HTTP_SRCS="$HTTP_SRCS $HTTP_PERL_SRCS"
-fi
-
-if [ $HTTP_MEMCACHED = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_MEMCACHED_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_MEMCACHED_SRCS"
-fi
-
-if [ $HTTP_EMPTY_GIF = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_EMPTY_GIF_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_EMPTY_GIF_SRCS"
-fi
-
-if [ $HTTP_BROWSER = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_BROWSER_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_BROWSER_SRCS"
-fi
-
-if [ $HTTP_SECURE_LINK = YES ]; then
- USE_MD5=YES
- HTTP_MODULES="$HTTP_MODULES $HTTP_SECURE_LINK_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_SECURE_LINK_SRCS"
-fi
-
-if [ $HTTP_DEGRADATION = YES ]; then
- have=NGX_HTTP_DEGRADATION . auto/have
- HTTP_MODULES="$HTTP_MODULES $HTTP_DEGRADATION_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_DEGRADATION_SRCS"
-fi
-
-if [ $HTTP_FLV = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_FLV_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_FLV_SRCS"
-fi
-
-if [ $HTTP_MP4 = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_MP4_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_MP4_SRCS"
-fi
-
-if [ $HTTP_UPSTREAM_IP_HASH = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_IP_HASH_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_IP_HASH_SRCS"
-fi
-
-if [ $HTTP_UPSTREAM_LEAST_CONN = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_LEAST_CONN_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_LEAST_CONN_SRCS"
-fi
-
-if [ $HTTP_UPSTREAM_KEEPALIVE = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_KEEPALIVE_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_KEEPALIVE_SRCS"
-fi
-
-if [ $HTTP_STUB_STATUS = YES ]; then
- have=NGX_STAT_STUB . auto/have
- HTTP_MODULES="$HTTP_MODULES ngx_http_stub_status_module"
- HTTP_SRCS="$HTTP_SRCS src/http/modules/ngx_http_stub_status_module.c"
-fi
-
-#if [ -r $NGX_OBJS/auto ]; then
-# . $NGX_OBJS/auto
-#fi
-
-
-if test -n "$NGX_ADDONS"; then
-
- echo configuring additional modules
-
- for ngx_addon_dir in $NGX_ADDONS
- do
- echo "adding module in $ngx_addon_dir"
-
- if test -f $ngx_addon_dir/config; then
- . $ngx_addon_dir/config
-
- echo " + $ngx_addon_name was configured"
-
- else
- echo "$0: error: no $ngx_addon_dir/config was found"
- exit 1
- fi
- done
-fi
-
-
-if [ $MAIL_SSL = YES ]; then
- have=NGX_MAIL_SSL . auto/have
- USE_OPENSSL=YES
-fi
-
-
-modules="$CORE_MODULES $EVENT_MODULES"
-
-
-if [ $USE_OPENSSL = YES ]; then
- modules="$modules $OPENSSL_MODULE"
- CORE_DEPS="$CORE_DEPS $OPENSSL_DEPS"
- CORE_SRCS="$CORE_SRCS $OPENSSL_SRCS"
-fi
-
-if [ $USE_PCRE = YES ]; then
- modules="$modules $REGEX_MODULE"
- CORE_DEPS="$CORE_DEPS $REGEX_DEPS"
- CORE_SRCS="$CORE_SRCS $REGEX_SRCS"
-fi
-
-if [ $HTTP = YES ]; then
- modules="$modules $HTTP_MODULES $HTTP_FILTER_MODULES \
- $HTTP_HEADERS_FILTER_MODULE \
- $HTTP_AUX_FILTER_MODULES \
- $HTTP_COPY_FILTER_MODULE \
- $HTTP_RANGE_BODY_FILTER_MODULE \
- $HTTP_NOT_MODIFIED_FILTER_MODULE"
-
- NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(HTTP_DEPS)"
-fi
-
-
-if [ $MAIL = YES ]; then
- modules="$modules $MAIL_MODULES"
-
- 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"
- MAIL_SRCS="$MAIL_SRCS $MAIL_AUTH_HTTP_SRCS"
-
- modules="$modules $MAIL_PROXY_MODULE"
- MAIL_SRCS="$MAIL_SRCS $MAIL_PROXY_SRCS"
-
- NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(MAIL_DEPS)"
-fi
-
-
-if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then
- modules="$modules $NGX_GOOGLE_PERFTOOLS_MODULE"
- NGX_MISC_SRCS="$NGX_MISC_SRCS $NGX_GOOGLE_PERFTOOLS_SRCS"
-fi
-
-
-if [ $NGX_CPP_TEST = YES ]; then
- NGX_MISC_SRCS="$NGX_MISC_SRCS $NGX_CPP_TEST_SRCS"
- CORE_LIBS="$CORE_LIBS -lstdc++"
-fi
-
-
-cat << END > $NGX_MODULES_C
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-$NGX_PRAGMA
-
-END
-
-for mod in $modules
-do
- echo "extern ngx_module_t $mod;" >> $NGX_MODULES_C
-done
-
-echo >> $NGX_MODULES_C
-echo 'ngx_module_t *ngx_modules[] = {' >> $NGX_MODULES_C
-
-for mod in $modules
-do
- echo " &$mod," >> $NGX_MODULES_C
-done
-
-cat << END >> $NGX_MODULES_C
- NULL
-};
-
-END
diff --git a/usr.sbin/nginx/auto/nohave b/usr.sbin/nginx/auto/nohave
deleted file mode 100644
index dfb171837c5..00000000000
--- a/usr.sbin/nginx/auto/nohave
+++ /dev/null
@@ -1,12 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-cat << END >> $NGX_AUTO_CONFIG_H
-
-#ifndef $have
-#define $have 0
-#endif
-
-END
diff --git a/usr.sbin/nginx/auto/options b/usr.sbin/nginx/auto/options
deleted file mode 100644
index 6cea8c7c200..00000000000
--- a/usr.sbin/nginx/auto/options
+++ /dev/null
@@ -1,520 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-help=no
-
-NGX_PREFIX=
-NGX_SBIN_PATH=
-NGX_CONF_PREFIX=
-NGX_CONF_PATH=
-NGX_ERROR_LOG_PATH=
-NGX_PID_PATH=
-NGX_LOCK_PATH=
-NGX_USER=
-NGX_GROUP=
-
-CC=${CC:-cc}
-CPP=
-NGX_OBJS=objs
-
-NGX_DEBUG=NO
-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
-NGX_TEST_BUILD_RTSIG=NO
-NGX_TEST_BUILD_SOLARIS_SENDFILEV=NO
-
-NGX_PLATFORM=
-NGX_WINE=
-
-EVENT_FOUND=NO
-
-EVENT_RTSIG=NO
-EVENT_SELECT=NO
-EVENT_POLL=NO
-EVENT_AIO=NO
-
-USE_THREADS=NO
-
-NGX_FILE_AIO=NO
-NGX_IPV6=NO
-
-HTTP=YES
-
-NGX_HTTP_LOG_PATH=
-NGX_HTTP_CLIENT_TEMP_PATH=
-NGX_HTTP_PROXY_TEMP_PATH=
-NGX_HTTP_FASTCGI_TEMP_PATH=
-NGX_HTTP_UWSGI_TEMP_PATH=
-NGX_HTTP_SCGI_TEMP_PATH=
-
-HTTP_CACHE=YES
-HTTP_CHARSET=YES
-HTTP_GZIP=YES
-HTTP_SSL=NO
-HTTP_SPDY=NO
-HTTP_SSI=YES
-HTTP_POSTPONE=NO
-HTTP_REALIP=NO
-HTTP_XSLT=NO
-HTTP_IMAGE_FILTER=NO
-HTTP_SUB=NO
-HTTP_ADDITION=NO
-HTTP_DAV=NO
-HTTP_ACCESS=YES
-HTTP_AUTH_BASIC=YES
-HTTP_AUTH_REQUEST=NO
-HTTP_USERID=YES
-HTTP_AUTOINDEX=YES
-HTTP_RANDOM_INDEX=NO
-HTTP_STATUS=NO
-HTTP_GEO=YES
-HTTP_GEOIP=NO
-HTTP_MAP=YES
-HTTP_SPLIT_CLIENTS=YES
-HTTP_REFERER=YES
-HTTP_REWRITE=YES
-HTTP_PROXY=YES
-HTTP_FASTCGI=YES
-HTTP_UWSGI=YES
-HTTP_SCGI=YES
-HTTP_PERL=NO
-HTTP_MEMCACHED=YES
-HTTP_LIMIT_CONN=YES
-HTTP_LIMIT_REQ=YES
-HTTP_EMPTY_GIF=YES
-HTTP_BROWSER=YES
-HTTP_SECURE_LINK=NO
-HTTP_DEGRADATION=NO
-HTTP_FLV=NO
-HTTP_MP4=NO
-HTTP_GUNZIP=NO
-HTTP_GZIP_STATIC=NO
-HTTP_UPSTREAM_IP_HASH=YES
-HTTP_UPSTREAM_LEAST_CONN=YES
-HTTP_UPSTREAM_KEEPALIVE=YES
-
-# STUB
-HTTP_STUB_STATUS=NO
-
-MAIL=NO
-MAIL_SSL=NO
-MAIL_POP3=YES
-MAIL_IMAP=YES
-MAIL_SMTP=YES
-
-NGX_ADDONS=
-
-USE_PCRE=NO
-PCRE=NONE
-PCRE_OPT=
-PCRE_CONF_OPT=
-PCRE_JIT=NO
-
-USE_OPENSSL=NO
-OPENSSL=NONE
-
-USE_MD5=NO
-MD5=NONE
-MD5_OPT=
-MD5_ASM=NO
-
-USE_SHA1=NO
-SHA1=NONE
-SHA1_OPT=
-SHA1_ASM=NO
-
-USE_ZLIB=NO
-ZLIB=NONE
-ZLIB_OPT=
-ZLIB_ASM=NO
-
-USE_PERL=NO
-NGX_PERL=perl
-
-USE_LIBXSLT=NO
-USE_LIBGD=NO
-
-NGX_GOOGLE_PERFTOOLS=NO
-NGX_CPP_TEST=NO
-
-NGX_LIBATOMIC=NO
-
-NGX_CPU_CACHE_LINE=
-
-NGX_POST_CONF_MSG=
-
-opt=
-
-for option
-do
- opt="$opt `echo $option | sed -e \"s/\(--[^=]*=\)\(.* .*\)/\1'\2'/\"`"
-
- case "$option" in
- -*=*) value=`echo "$option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;;
- *) value="" ;;
- esac
-
- case "$option" in
- --help) help=yes ;;
-
- --prefix=) NGX_PREFIX="!" ;;
- --prefix=*) NGX_PREFIX="$value" ;;
- --sbin-path=*) NGX_SBIN_PATH="$value" ;;
- --conf-path=*) NGX_CONF_PATH="$value" ;;
- --error-log-path=*) NGX_ERROR_LOG_PATH="$value";;
- --pid-path=*) NGX_PID_PATH="$value" ;;
- --lock-path=*) NGX_LOCK_PATH="$value" ;;
- --user=*) NGX_USER="$value" ;;
- --group=*) NGX_GROUP="$value" ;;
-
- --crossbuild=*) NGX_PLATFORM="$value" ;;
-
- --builddir=*) NGX_OBJS="$value" ;;
-
- --with-rtsig_module) EVENT_RTSIG=YES ;;
- --with-select_module) EVENT_SELECT=YES ;;
- --without-select_module) EVENT_SELECT=NONE ;;
- --with-poll_module) EVENT_POLL=YES ;;
- --without-poll_module) EVENT_POLL=NONE ;;
- --with-aio_module) EVENT_AIO=YES ;;
-
- #--with-threads=*) USE_THREADS="$value" ;;
- #--with-threads) USE_THREADS="pthreads" ;;
-
- --with-file-aio) NGX_FILE_AIO=YES ;;
- --with-ipv6) NGX_IPV6=YES ;;
-
- --without-http) HTTP=NO ;;
- --without-http-cache) HTTP_CACHE=NO ;;
-
- --http-log-path=*) NGX_HTTP_LOG_PATH="$value" ;;
- --http-client-body-temp-path=*) NGX_HTTP_CLIENT_TEMP_PATH="$value" ;;
- --http-proxy-temp-path=*) NGX_HTTP_PROXY_TEMP_PATH="$value" ;;
- --http-fastcgi-temp-path=*) NGX_HTTP_FASTCGI_TEMP_PATH="$value" ;;
- --http-uwsgi-temp-path=*) NGX_HTTP_UWSGI_TEMP_PATH="$value" ;;
- --http-scgi-temp-path=*) NGX_HTTP_SCGI_TEMP_PATH="$value" ;;
-
- --with-http_ssl_module) HTTP_SSL=YES ;;
- --with-http_spdy_module) HTTP_SPDY=YES ;;
- --with-http_realip_module) HTTP_REALIP=YES ;;
- --with-http_addition_module) HTTP_ADDITION=YES ;;
- --with-http_xslt_module) HTTP_XSLT=YES ;;
- --with-http_image_filter_module) HTTP_IMAGE_FILTER=YES ;;
- --with-http_geoip_module) HTTP_GEOIP=YES ;;
- --with-http_sub_module) HTTP_SUB=YES ;;
- --with-http_dav_module) HTTP_DAV=YES ;;
- --with-http_flv_module) HTTP_FLV=YES ;;
- --with-http_mp4_module) HTTP_MP4=YES ;;
- --with-http_gunzip_module) HTTP_GUNZIP=YES ;;
- --with-http_gzip_static_module) HTTP_GZIP_STATIC=YES ;;
- --with-http_auth_request_module) HTTP_AUTH_REQUEST=YES ;;
- --with-http_random_index_module) HTTP_RANDOM_INDEX=YES ;;
- --with-http_secure_link_module) HTTP_SECURE_LINK=YES ;;
- --with-http_degradation_module) HTTP_DEGRADATION=YES ;;
-
- --without-http_charset_module) HTTP_CHARSET=NO ;;
- --without-http_gzip_module) HTTP_GZIP=NO ;;
- --without-http_ssi_module) HTTP_SSI=NO ;;
- --without-http_userid_module) HTTP_USERID=NO ;;
- --without-http_access_module) HTTP_ACCESS=NO ;;
- --without-http_auth_basic_module) HTTP_AUTH_BASIC=NO ;;
- --without-http_autoindex_module) HTTP_AUTOINDEX=NO ;;
- --without-http_status_module) HTTP_STATUS=NO ;;
- --without-http_geo_module) HTTP_GEO=NO ;;
- --without-http_map_module) HTTP_MAP=NO ;;
- --without-http_split_clients_module) HTTP_SPLIT_CLIENTS=NO ;;
- --without-http_referer_module) HTTP_REFERER=NO ;;
- --without-http_rewrite_module) HTTP_REWRITE=NO ;;
- --without-http_proxy_module) HTTP_PROXY=NO ;;
- --without-http_fastcgi_module) HTTP_FASTCGI=NO ;;
- --without-http_uwsgi_module) HTTP_UWSGI=NO ;;
- --without-http_scgi_module) HTTP_SCGI=NO ;;
- --without-http_memcached_module) HTTP_MEMCACHED=NO ;;
- --without-http_limit_zone_module)
- HTTP_LIMIT_CONN=NO
- NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG
-$0: warning: the \"--without-http_limit_zone_module\" option is deprecated, \
-use the \"--without-http_limit_conn_module\" option instead"
- ;;
- --without-http_limit_conn_module) HTTP_LIMIT_CONN=NO ;;
- --without-http_limit_req_module) HTTP_LIMIT_REQ=NO ;;
- --without-http_empty_gif_module) HTTP_EMPTY_GIF=NO ;;
- --without-http_browser_module) HTTP_BROWSER=NO ;;
- --without-http_upstream_ip_hash_module) HTTP_UPSTREAM_IP_HASH=NO ;;
- --without-http_upstream_least_conn_module)
- HTTP_UPSTREAM_LEAST_CONN=NO ;;
- --without-http_upstream_keepalive_module) HTTP_UPSTREAM_KEEPALIVE=NO ;;
-
- --with-http_perl_module) HTTP_PERL=YES ;;
- --with-perl_modules_path=*) NGX_PERL_MODULES="$value" ;;
- --with-perl=*) NGX_PERL="$value" ;;
-
- # STUB
- --with-http_stub_status_module) HTTP_STUB_STATUS=YES ;;
-
- --with-mail) MAIL=YES ;;
- --with-mail_ssl_module) MAIL_SSL=YES ;;
- # 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 ;;
-
- --with-google_perftools_module) NGX_GOOGLE_PERFTOOLS=YES ;;
- --with-cpp_test_module) NGX_CPP_TEST=YES ;;
-
- --add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;;
-
- --with-cc=*) CC="$value" ;;
- --with-cpp=*) CPP="$value" ;;
- --with-cc-opt=*) NGX_CC_OPT="$value" ;;
- --with-ld-opt=*) NGX_LD_OPT="$value" ;;
- --with-cpu-opt=*) CPU="$value" ;;
- --with-debug) NGX_DEBUG=YES ;;
-
- --without-pcre) USE_PCRE=DISABLED ;;
- --with-pcre) USE_PCRE=YES ;;
- --with-pcre=*) PCRE="$value" ;;
- --with-pcre-opt=*) PCRE_OPT="$value" ;;
- --with-pcre-jit) PCRE_JIT=YES ;;
-
- --with-openssl=*) OPENSSL="$value" ;;
- --with-openssl-opt=*) OPENSSL_OPT="$value" ;;
-
- --with-md5=*) MD5="$value" ;;
- --with-md5-opt=*) MD5_OPT="$value" ;;
- --with-md5-asm) MD5_ASM=YES ;;
-
- --with-sha1=*) SHA1="$value" ;;
- --with-sha1-opt=*) SHA1_OPT="$value" ;;
- --with-sha1-asm) SHA1_ASM=YES ;;
-
- --with-zlib=*) ZLIB="$value" ;;
- --with-zlib-opt=*) ZLIB_OPT="$value" ;;
- --with-zlib-asm=*) ZLIB_ASM="$value" ;;
-
- --with-libatomic) NGX_LIBATOMIC=YES ;;
- --with-libatomic=*) NGX_LIBATOMIC="$value" ;;
-
- --test-build-devpoll) NGX_TEST_BUILD_DEVPOLL=YES ;;
- --test-build-eventport) NGX_TEST_BUILD_EVENTPORT=YES ;;
- --test-build-epoll) NGX_TEST_BUILD_EPOLL=YES ;;
- --test-build-rtsig) NGX_TEST_BUILD_RTSIG=YES ;;
- --test-build-solaris-sendfilev) NGX_TEST_BUILD_SOLARIS_SENDFILEV=YES ;;
-
- *)
- echo "$0: error: invalid option \"$option\""
- exit 1
- ;;
- esac
-done
-
-
-NGX_CONFIGURE="$opt"
-
-
-if [ $help = yes ]; then
-
-cat << END
-
- --help print this message
-
- --prefix=PATH set installation prefix
- --sbin-path=PATH set nginx binary pathname
- --conf-path=PATH set nginx.conf pathname
- --error-log-path=PATH set error log pathname
- --pid-path=PATH set nginx.pid pathname
- --lock-path=PATH set nginx.lock pathname
-
- --user=USER set non-privileged user for
- worker processes
- --group=GROUP set non-privileged group for
- worker processes
-
- --builddir=DIR set build directory
-
- --with-rtsig_module enable rtsig module
- --with-select_module enable select module
- --without-select_module disable select module
- --with-poll_module enable poll module
- --without-poll_module disable poll module
-
- --with-file-aio enable file AIO support
- --with-ipv6 enable IPv6 support
-
- --with-http_ssl_module enable ngx_http_ssl_module
- --with-http_spdy_module enable ngx_http_spdy_module
- --with-http_realip_module enable ngx_http_realip_module
- --with-http_addition_module enable ngx_http_addition_module
- --with-http_xslt_module enable ngx_http_xslt_module
- --with-http_image_filter_module enable ngx_http_image_filter_module
- --with-http_geoip_module enable ngx_http_geoip_module
- --with-http_sub_module enable ngx_http_sub_module
- --with-http_dav_module enable ngx_http_dav_module
- --with-http_flv_module enable ngx_http_flv_module
- --with-http_mp4_module enable ngx_http_mp4_module
- --with-http_gunzip_module enable ngx_http_gunzip_module
- --with-http_gzip_static_module enable ngx_http_gzip_static_module
- --with-http_auth_request_module enable ngx_http_auth_request_module
- --with-http_random_index_module enable ngx_http_random_index_module
- --with-http_secure_link_module enable ngx_http_secure_link_module
- --with-http_degradation_module enable ngx_http_degradation_module
- --with-http_stub_status_module enable ngx_http_stub_status_module
-
- --without-http_charset_module disable ngx_http_charset_module
- --without-http_gzip_module disable ngx_http_gzip_module
- --without-http_ssi_module disable ngx_http_ssi_module
- --without-http_userid_module disable ngx_http_userid_module
- --without-http_access_module disable ngx_http_access_module
- --without-http_auth_basic_module disable ngx_http_auth_basic_module
- --without-http_autoindex_module disable ngx_http_autoindex_module
- --without-http_geo_module disable ngx_http_geo_module
- --without-http_map_module disable ngx_http_map_module
- --without-http_split_clients_module disable ngx_http_split_clients_module
- --without-http_referer_module disable ngx_http_referer_module
- --without-http_rewrite_module disable ngx_http_rewrite_module
- --without-http_proxy_module disable ngx_http_proxy_module
- --without-http_fastcgi_module disable ngx_http_fastcgi_module
- --without-http_uwsgi_module disable ngx_http_uwsgi_module
- --without-http_scgi_module disable ngx_http_scgi_module
- --without-http_memcached_module disable ngx_http_memcached_module
- --without-http_limit_conn_module disable ngx_http_limit_conn_module
- --without-http_limit_req_module disable ngx_http_limit_req_module
- --without-http_empty_gif_module disable ngx_http_empty_gif_module
- --without-http_browser_module disable ngx_http_browser_module
- --without-http_upstream_ip_hash_module
- disable ngx_http_upstream_ip_hash_module
- --without-http_upstream_least_conn_module
- disable ngx_http_upstream_least_conn_module
- --without-http_upstream_keepalive_module
- disable ngx_http_upstream_keepalive_module
-
- --with-http_perl_module enable ngx_http_perl_module
- --with-perl_modules_path=PATH set Perl modules path
- --with-perl=PATH set perl binary pathname
-
- --http-log-path=PATH set http access log pathname
- --http-client-body-temp-path=PATH set path to store
- http client request body temporary files
- --http-proxy-temp-path=PATH set path to store
- http proxy temporary files
- --http-fastcgi-temp-path=PATH set path to store
- http fastcgi temporary files
- --http-uwsgi-temp-path=PATH set path to store
- http uwsgi temporary files
- --http-scgi-temp-path=PATH set path to store
- http scgi temporary files
-
- --without-http disable HTTP server
- --without-http-cache disable HTTP cache
-
- --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
-
- --with-google_perftools_module enable ngx_google_perftools_module
- --with-cpp_test_module enable ngx_cpp_test_module
-
- --add-module=PATH enable an external module
-
- --with-cc=PATH set C compiler pathname
- --with-cpp=PATH set C preprocessor pathname
- --with-cc-opt=OPTIONS set additional C compiler options
- --with-ld-opt=OPTIONS set additional linker options
- --with-cpu-opt=CPU build for the specified CPU, valid values:
- pentium, pentiumpro, pentium3, pentium4,
- athlon, opteron, sparc32, sparc64, ppc64
-
- --without-pcre disable PCRE library usage
- --with-pcre force PCRE library usage
- --with-pcre=DIR set path to PCRE library sources
- --with-pcre-opt=OPTIONS set additional build options for PCRE
- --with-pcre-jit build PCRE with JIT compilation support
-
- --with-md5=DIR set path to md5 library sources
- --with-md5-opt=OPTIONS set additional build options for md5
- --with-md5-asm use md5 assembler sources
-
- --with-sha1=DIR set path to sha1 library sources
- --with-sha1-opt=OPTIONS set additional build options for sha1
- --with-sha1-asm use sha1 assembler sources
-
- --with-zlib=DIR set path to zlib library sources
- --with-zlib-opt=OPTIONS set additional build options for zlib
- --with-zlib-asm=CPU use zlib assembler sources optimized
- for the specified CPU, valid values:
- pentium, pentiumpro
-
- --with-libatomic force libatomic_ops library usage
- --with-libatomic=DIR set path to libatomic_ops library sources
-
- --with-openssl=DIR set path to OpenSSL library sources
- --with-openssl-opt=OPTIONS set additional build options for OpenSSL
-
- --with-debug enable debug logging
-
-END
-
- exit 1
-fi
-
-
-if [ $HTTP = NO ]; then
- HTTP_CHARSET=NO
- HTTP_GZIP=NO
- HTTP_SSI=NO
- HTTP_USERID=NO
- HTTP_ACCESS=NO
- HTTP_STATUS=NO
- HTTP_REWRITE=NO
- HTTP_PROXY=NO
- HTTP_FASTCGI=NO
-fi
-
-
-if [ ".$NGX_PLATFORM" = ".win32" ]; then
- NGX_WINE=$WINE
-fi
-
-
-NGX_CONF_PATH=${NGX_CONF_PATH:-conf/nginx.conf}
-NGX_CONF_PREFIX=`dirname $NGX_CONF_PATH`
-NGX_PID_PATH=${NGX_PID_PATH:-logs/nginx.pid}
-NGX_LOCK_PATH=${NGX_LOCK_PATH:-logs/nginx.lock}
-
-if [ ".$NGX_ERROR_LOG_PATH" = ".stderr" ]; then
- NGX_ERROR_LOG_PATH=
-else
- NGX_ERROR_LOG_PATH=${NGX_ERROR_LOG_PATH:-logs/error.log}
-fi
-
-NGX_HTTP_LOG_PATH=${NGX_HTTP_LOG_PATH:-logs/access.log}
-NGX_HTTP_CLIENT_TEMP_PATH=${NGX_HTTP_CLIENT_TEMP_PATH:-client_body_temp}
-NGX_HTTP_PROXY_TEMP_PATH=${NGX_HTTP_PROXY_TEMP_PATH:-proxy_temp}
-NGX_HTTP_FASTCGI_TEMP_PATH=${NGX_HTTP_FASTCGI_TEMP_PATH:-fastcgi_temp}
-NGX_HTTP_UWSGI_TEMP_PATH=${NGX_HTTP_UWSGI_TEMP_PATH:-uwsgi_temp}
-NGX_HTTP_SCGI_TEMP_PATH=${NGX_HTTP_SCGI_TEMP_PATH:-scgi_temp}
-
-case ".$NGX_PERL_MODULES" in
- ./*)
- ;;
-
- .)
- ;;
-
- *)
- NGX_PERL_MODULES=$NGX_PREFIX/$NGX_PERL_MODULES
- ;;
-esac
diff --git a/usr.sbin/nginx/auto/os/conf b/usr.sbin/nginx/auto/os/conf
deleted file mode 100644
index fe720160ada..00000000000
--- a/usr.sbin/nginx/auto/os/conf
+++ /dev/null
@@ -1,107 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-echo "checking for $NGX_SYSTEM specific features"
-
-case "$NGX_PLATFORM" in
-
- FreeBSD:*)
- . auto/os/freebsd
- ;;
-
- Linux:*)
- . auto/os/linux
- ;;
-
- SunOS:*)
- . auto/os/solaris
- ;;
-
- Darwin:*)
- . auto/os/darwin
- ;;
-
- win32)
- . auto/os/win32
- ;;
-
- DragonFly:*)
- have=NGX_FREEBSD . auto/have_headers
- CORE_INCS="$UNIX_INCS"
- CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS"
- CORE_SRCS="$UNIX_SRCS $FREEBSD_SRCS"
-
- echo " + sendfile() found"
- have=NGX_HAVE_SENDFILE . auto/have
- CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS"
-
- ngx_spacer='
-'
- ;;
-
- HP-UX:*)
- # HP/UX
- have=NGX_HPUX . auto/have_headers
- CORE_INCS="$UNIX_INCS"
- CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
- CORE_SRCS="$UNIX_SRCS"
- CC_AUX_FLAGS="$CC_AUX_FLAGS -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1"
- CC_AUX_FLAGS="$CC_AUX_FLAGS -D_HPUX_ALT_XOPEN_SOCKET_API"
- ;;
-
- OSF1:*)
- # Tru64 UNIX
- have=NGX_TRU64 . auto/have_headers
- have=NGX_HAVE_STRERROR_R . auto/nohave
- CORE_INCS="$UNIX_INCS"
- CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
- CORE_SRCS="$UNIX_SRCS"
- ;;
-
- *)
- CORE_INCS="$UNIX_INCS"
- CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
- CORE_SRCS="$UNIX_SRCS"
- ;;
-
-esac
-
-
-case "$NGX_MACHINE" in
-
- i386 | i686 | i86pc)
- have=NGX_HAVE_NONALIGNED . auto/have
- NGX_MACH_CACHE_LINE=32
- ;;
-
- amd64 | x86_64)
- have=NGX_HAVE_NONALIGNED . auto/have
- NGX_MACH_CACHE_LINE=64
- ;;
-
- sun4u | sun4v | sparc | sparc64)
- have=NGX_ALIGNMENT value=16 . auto/define
- # TODO
- NGX_MACH_CACHE_LINE=64
- ;;
-
- ia64 )
- have=NGX_ALIGNMENT value=16 . auto/define
- # TODO
- NGX_MACH_CACHE_LINE=64
- ;;
-
- *)
- have=NGX_ALIGNMENT value=16 . auto/define
- NGX_MACH_CACHE_LINE=32
- ;;
-
-esac
-
-if test -z "$NGX_CPU_CACHE_LINE"; then
- NGX_CPU_CACHE_LINE=$NGX_MACH_CACHE_LINE
-fi
-
-have=NGX_CPU_CACHE_LINE value=$NGX_CPU_CACHE_LINE . auto/define
diff --git a/usr.sbin/nginx/auto/os/darwin b/usr.sbin/nginx/auto/os/darwin
deleted file mode 100644
index b97518a6ea0..00000000000
--- a/usr.sbin/nginx/auto/os/darwin
+++ /dev/null
@@ -1,116 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-have=NGX_DARWIN . auto/have_headers
-
-CORE_INCS="$UNIX_INCS"
-CORE_DEPS="$UNIX_DEPS $DARWIN_DEPS"
-CORE_SRCS="$UNIX_SRCS $DARWIN_SRCS"
-
-
-
-ngx_spacer='
-'
-
-# kqueue
-
-echo " + kqueue found"
-have=NGX_HAVE_KQUEUE . auto/have
-have=NGX_HAVE_CLEAR_EVENT . auto/have
-EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE"
-CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS"
-EVENT_FOUND=YES
-NGX_KQUEUE_CHECKED=YES
-
-ngx_feature="kqueue's EVFILT_TIMER"
-ngx_feature_name="NGX_HAVE_TIMER_EVENT"
-ngx_feature_run=yes
-ngx_feature_incs="#include <sys/event.h>
- #include <sys/time.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int kq;
- struct kevent kev;
- struct timespec ts;
-
- if ((kq = kqueue()) == -1) return 1;
-
- kev.ident = 0;
- kev.filter = EVFILT_TIMER;
- kev.flags = EV_ADD|EV_ENABLE;
- kev.fflags = 0;
- kev.data = 1000;
- kev.udata = 0;
-
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
-
- if (kevent(kq, &kev, 1, &kev, 1, &ts) == -1) return 1;
-
- if (kev.flags & EV_ERROR) return 1;"
-
-. auto/feature
-
-
-ngx_feature="Darwin 64-bit kqueue millisecond timeout bug"
-ngx_feature_name=NGX_DARWIN_KEVENT_BUG
-ngx_feature_run=bug
-ngx_feature_incs="#include <sys/event.h>
- #include <sys/time.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int kq;
- struct kevent kev;
- struct timespec ts;
- struct timeval tv, tv0;
-
- kq = kqueue();
-
- ts.tv_sec = 0;
- ts.tv_nsec = 999000000;
-
- gettimeofday(&tv, 0);
- kevent(kq, NULL, 0, &kev, 1, &ts);
- gettimeofday(&tv0, 0);
- timersub(&tv0, &tv, &tv);
-
- if (tv.tv_sec * 1000000 + tv.tv_usec < 900000) return 1;"
-
-. auto/feature
-
-
-# sendfile()
-
-CC_AUX_FLAGS="$CC_AUX_FLAGS"
-ngx_feature="sendfile()"
-ngx_feature_name="NGX_HAVE_SENDFILE"
-ngx_feature_run=yes
-ngx_feature_incs="#include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/uio.h>
- #include <sys/errno.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int s = 0, fd = 1;
- off_t n; off_t off = 0;
- n = sendfile(s, fd, off, &n, NULL, 0);
- if (n == -1 && errno == ENOSYS) return 1"
-. auto/feature
-
-if [ $ngx_found = yes ]; then
- have=NGX_HAVE_SENDFILE . auto/have
- CORE_SRCS="$CORE_SRCS $DARWIN_SENDFILE_SRCS"
-fi
-
-
-ngx_feature="atomic(3)"
-ngx_feature_name=NGX_DARWIN_ATOMIC
-ngx_feature_run=no
-ngx_feature_incs="#include <libkern/OSAtomic.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int32_t lock, n;
- n = OSAtomicCompareAndSwap32Barrier(0, 1, &lock)"
-. auto/feature
diff --git a/usr.sbin/nginx/auto/os/freebsd b/usr.sbin/nginx/auto/os/freebsd
deleted file mode 100644
index 6aa823f9250..00000000000
--- a/usr.sbin/nginx/auto/os/freebsd
+++ /dev/null
@@ -1,144 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-have=NGX_FREEBSD . auto/have_headers
-
-CORE_INCS="$UNIX_INCS"
-CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS"
-CORE_SRCS="$UNIX_SRCS $FREEBSD_SRCS"
-
-ngx_spacer='
-'
-
-
-# __FreeBSD_version and sysctl kern.osreldate are the best ways
-# to determine whether some capability exists and is safe to use.
-# __FreeBSD_version is used for the testing of the build environment.
-# sysctl kern.osreldate is used for the testing of the kernel capabilities.
-
-version=`grep "#define __FreeBSD_version" /usr/include/osreldate.h \
- | sed -e 's/^.* \(.*\)$/\1/'`
-
-osreldate=`/sbin/sysctl -n kern.osreldate`
-
-
-# setproctitle() in libutil
-
-if [ \( $version -ge 500000 -a $version -lt 500012 \) \
- -o $version -lt 410002 ]
-then
- echo " + setproctitle() in libutil"
-
- CORE_LIBS="$CORE_LIBS -lutil"
- NGX_SETPROCTITLE_LIB="-lutil"
-fi
-
-# sendfile
-
-if [ $osreldate -gt 300007 ]; then
- echo " + sendfile() found"
-
- have=NGX_HAVE_SENDFILE . auto/have
- CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS"
-fi
-
-if [ $osreldate -gt 502103 ]; then
- echo " + sendfile()'s SF_NODISKIO found"
-
- have=NGX_HAVE_AIO_SENDFILE . auto/have
-fi
-
-# POSIX semaphores
-# http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/127545
-
-if [ $osreldate -ge 701106 ]; then
- echo " + POSIX semaphores should work"
-else
- have=NGX_HAVE_POSIX_SEM . auto/nohave
-fi
-
-
-# kqueue
-
-if [ \( $osreldate -lt 500000 -a $osreldate -ge 410000 \) \
- -o $osreldate -ge 500011 ]
-then
- echo " + kqueue found"
-
- have=NGX_HAVE_KQUEUE . auto/have
- have=NGX_HAVE_CLEAR_EVENT . auto/have
- EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE"
- CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS"
- EVENT_FOUND=YES
-fi
-
-
-NGX_KQUEUE_CHECKED=YES
-
-
-# kqueue's NOTE_LAWAT
-
-if [ \( $version -lt 500000 -a $version -ge 430000 \) \
- -o $version -ge 500018 ]
-then
- echo " + kqueue's NOTE_LOWAT found"
- have=NGX_HAVE_LOWAT_EVENT . auto/have
-fi
-
-# kqueue's EVFILT_TIMER
-
-if [ \( $version -lt 500000 -a $version -ge 440001 \) \
- -o $version -ge 500023 ]
-then
- echo " + kqueue's EVFILT_TIMER found"
- have=NGX_HAVE_TIMER_EVENT . auto/have
-fi
-
-
-if [ $USE_THREADS = "rfork" ]; then
-
- echo " + using rfork()"
-
-# # kqueue's EVFILT_SIGNAL is safe
-#
-# if [ $version -gt 460101 ]; then
-# echo " + kqueue's EVFILT_SIGNAL is safe"
-# have=NGX_HAVE_SAFE_EVFILT_SIGNAL . auto/have
-# else
-# echo "$0: error: the kqueue's EVFILT_SIGNAL is unsafe on this"
-# echo "FreeBSD version, so --with-threads=rfork could not be used"
-# echo
-#
-# exit 1
-# fi
-fi
-
-
-if [ $EVENT_AIO = YES ]; then
- if [ \( $version -lt 500000 -a $version -ge 430000 \) \
- -o $version -ge 500014 ]
- then
- have=NGX_HAVE_AIO . auto/have
- EVENT_MODULES="$EVENT_MODULES $AIO_MODULE"
- CORE_SRCS="$CORE_SRCS $AIO_SRCS"
- else
-
-cat << END
-
-$0: error: the kqueue does not support AIO on this FreeBSD version
-
-END
-
- exit 1
- fi
-fi
-
-
-# cpuset_setaffinity()
-
-if [ $version -ge 701000 ]; then
- echo " + cpuset_setaffinity() found"
- have=NGX_HAVE_CPUSET_SETAFFINITY . auto/have
-fi
diff --git a/usr.sbin/nginx/auto/os/linux b/usr.sbin/nginx/auto/os/linux
deleted file mode 100644
index 19bf832ce3e..00000000000
--- a/usr.sbin/nginx/auto/os/linux
+++ /dev/null
@@ -1,185 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-have=NGX_LINUX . auto/have_headers
-
-CORE_INCS="$UNIX_INCS"
-CORE_DEPS="$UNIX_DEPS $LINUX_DEPS"
-CORE_SRCS="$UNIX_SRCS $LINUX_SRCS"
-
-ngx_spacer='
-'
-
-cc_aux_flags="$CC_AUX_FLAGS"
-CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
-
-
-# Linux kernel version
-
-version=$((`uname -r \
- | sed -n -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/ \
- \1*256*256+\2*256+\3/p' \
- -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\1*256*256+\2*256/p'`))
-
-version=${version:-0}
-
-
-# enable the rt signals on Linux between 2.2.19 and 2.6.17
-
-if [ \( $version -ge 131603 -a $version -lt 132626 \) -o $EVENT_RTSIG = YES ]
-then
- echo " + rt signals found"
- have=NGX_HAVE_RTSIG . auto/have
- EVENT_MODULES="$EVENT_MODULES $RTSIG_MODULE"
- CORE_SRCS="$CORE_SRCS $RTSIG_SRCS"
- EVENT_FOUND=YES
-fi
-
-
-# posix_fadvise64() had been implemented in 2.5.60
-
-if [ $version -lt 132412 ]; then
- have=NGX_HAVE_POSIX_FADVISE . auto/nohave
-fi
-
-# epoll, EPOLLET version
-
-ngx_feature="epoll"
-ngx_feature_name="NGX_HAVE_EPOLL"
-ngx_feature_run=yes
-ngx_feature_incs="#include <sys/epoll.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int efd = 0;
- struct epoll_event ee;
- ee.events = EPOLLIN|EPOLLOUT|EPOLLET;
- ee.data.ptr = NULL;
- efd = epoll_create(100);
- if (efd == -1) return 1;"
-. auto/feature
-
-if [ $ngx_found = yes ]; then
- have=NGX_HAVE_CLEAR_EVENT . auto/have
- CORE_SRCS="$CORE_SRCS $EPOLL_SRCS"
- EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
- EVENT_FOUND=YES
-
-
- # EPOLLRDHUP appeared in Linux 2.6.17, glibc 2.8
-
- ngx_feature="EPOLLRDHUP"
- ngx_feature_name="NGX_HAVE_EPOLLRDHUP"
- ngx_feature_run=no
- ngx_feature_incs="#include <sys/epoll.h>"
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test="int efd = 0, fd = 0;
- struct epoll_event ee;
- ee.events = EPOLLIN|EPOLLRDHUP|EPOLLET;
- ee.data.ptr = NULL;
- epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ee)"
- . auto/feature
-fi
-
-
-# O_PATH and AT_EMPTY_PATH were introduced in 2.6.39, glibc 2.14
-
-ngx_feature="O_PATH"
-ngx_feature_name="NGX_HAVE_O_PATH"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int fd; struct stat sb;
- fd = openat(AT_FDCWD, \".\", O_PATH|O_DIRECTORY|O_NOFOLLOW);
- if (fstatat(fd, \"\", &sb, AT_EMPTY_PATH) != 0) return 1"
-. auto/feature
-
-
-# sendfile()
-
-CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE"
-ngx_feature="sendfile()"
-ngx_feature_name="NGX_HAVE_SENDFILE"
-ngx_feature_run=yes
-ngx_feature_incs="#include <sys/sendfile.h>
- #include <errno.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int s = 0, fd = 1;
- ssize_t n; off_t off = 0;
- n = sendfile(s, fd, &off, 1);
- if (n == -1 && errno == ENOSYS) return 1"
-. auto/feature
-
-if [ $ngx_found = yes ]; then
- CORE_SRCS="$CORE_SRCS $LINUX_SENDFILE_SRCS"
-fi
-
-
-# sendfile64()
-
-CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
-ngx_feature="sendfile64()"
-ngx_feature_name="NGX_HAVE_SENDFILE64"
-ngx_feature_run=yes
-ngx_feature_incs="#include <sys/sendfile.h>
- #include <errno.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int s = 0, fd = 1;
- ssize_t n; off_t off = 0;
- n = sendfile(s, fd, &off, 1);
- if (n == -1 && errno == ENOSYS) return 1"
-. auto/feature
-
-
-ngx_include="sys/prctl.h"; . auto/include
-
-# prctl(PR_SET_DUMPABLE)
-
-ngx_feature="prctl(PR_SET_DUMPABLE)"
-ngx_feature_name="NGX_HAVE_PR_SET_DUMPABLE"
-ngx_feature_run=yes
-ngx_feature_incs="#include <sys/prctl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) return 1"
-. auto/feature
-
-
-# sched_setaffinity()
-
-ngx_feature="sched_setaffinity()"
-ngx_feature_name="NGX_HAVE_SCHED_SETAFFINITY"
-ngx_feature_run=no
-ngx_feature_incs="#include <sched.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="cpu_set_t mask;
- CPU_ZERO(&mask);
- sched_setaffinity(0, sizeof(cpu_set_t), &mask)"
-. auto/feature
-
-
-# crypt_r()
-
-ngx_feature="crypt_r()"
-ngx_feature_name="NGX_HAVE_GNU_CRYPT_R"
-ngx_feature_run=no
-ngx_feature_incs="#include <crypt.h>"
-ngx_feature_path=
-ngx_feature_libs=-lcrypt
-ngx_feature_test="struct crypt_data cd;
- crypt_r(\"key\", \"salt\", &cd);"
-. auto/feature
-
-
-ngx_include="sys/vfs.h"; . auto/include
-
-
-CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
diff --git a/usr.sbin/nginx/auto/os/solaris b/usr.sbin/nginx/auto/os/solaris
deleted file mode 100644
index d39df0bf713..00000000000
--- a/usr.sbin/nginx/auto/os/solaris
+++ /dev/null
@@ -1,61 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-have=NGX_SOLARIS . auto/have_headers
-
-CORE_INCS="$UNIX_INCS"
-CORE_DEPS="$UNIX_DEPS $SOLARIS_DEPS"
-CORE_SRCS="$UNIX_SRCS $SOLARIS_SRCS "
-CORE_LIBS="$CORE_LIBS -lsocket -lnsl"
-
-NGX_RPATH=YES
-
-# Solaris's make does not support a blank line between target and rules
-ngx_spacer=
-
-CC_AUX_FLAGS="$CC_AUX_FLAGS -D_FILE_OFFSET_BITS=64 -lsocket -lnsl"
-
-
-if [ $ZLIB_ASM != NO ]; then
- echo "$0: error: the --with-zlib-asm=CPU option is not supported"
- echo "on that platform"
- echo
-
- exit 1
-fi
-
-
-ngx_feature="sendfilev()"
-ngx_feature_name="NGX_HAVE_SENDFILE"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/sendfile.h>"
-ngx_feature_path=
-ngx_feature_libs="-lsendfile"
-ngx_feature_test="int fd = 1; sendfilevec_t vec[1];
- size_t sent; ssize_t n;
- n = sendfilev(fd, vec, 1, &sent);
- if (n == -1) return 1"
-. auto/feature
-
-
-if [ $ngx_found = yes ]; then
- CORE_SRCS="$CORE_SRCS $SOLARIS_SENDFILEV_SRCS"
- CORE_LIBS="$CORE_LIBS -lsendfile"
-fi
-
-
-ngx_feature="event ports"
-ngx_feature_name="NGX_HAVE_EVENTPORT"
-ngx_feature_run=no
-ngx_feature_incs="#include <port.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int n = port_create()"
-. auto/feature
-
-if [ $ngx_found = yes ]; then
- CORE_SRCS="$CORE_SRCS $EVENTPORT_SRCS"
- EVENT_MODULES="$EVENT_MODULES $EVENTPORT_MODULE"
-fi
diff --git a/usr.sbin/nginx/auto/os/win32 b/usr.sbin/nginx/auto/os/win32
deleted file mode 100644
index 0b9b461875f..00000000000
--- a/usr.sbin/nginx/auto/os/win32
+++ /dev/null
@@ -1,40 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-have=NGX_WIN32 . auto/have_headers
-
-CORE_INCS="$WIN32_INCS"
-CORE_DEPS="$WIN32_DEPS"
-CORE_SRCS="$WIN32_SRCS $IOCP_SRCS"
-OS_CONFIG="$WIN32_CONFIG"
-NGX_ICONS="$NGX_WIN32_ICONS"
-SELECT_SRCS=$WIN32_SELECT_SRCS
-
-case "$NGX_CC_NAME" in
-
- gcc)
- CORE_LIBS="$CORE_LIBS -ladvapi32 -lws2_32"
- ;;
-
- *)
- CORE_LIBS="$CORE_LIBS advapi32.lib ws2_32.lib"
- ;;
-
-esac
-
-EVENT_MODULES="$EVENT_MODULES $IOCP_MODULE"
-EVENT_FOUND=YES
-
-if [ $EVENT_SELECT = NO ]; then
- CORE_SRCS="$CORE_SRCS $SELECT_SRCS"
- EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE"
-fi
-
-if [ $NGX_IPV6 = YES ]; then
- have=NGX_HAVE_INET6 . auto/have
-fi
-
-have=NGX_HAVE_AIO . auto/have
-have=NGX_HAVE_IOCP . auto/have
diff --git a/usr.sbin/nginx/auto/sources b/usr.sbin/nginx/auto/sources
deleted file mode 100644
index 613a39a17e4..00000000000
--- a/usr.sbin/nginx/auto/sources
+++ /dev/null
@@ -1,565 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-CORE_MODULES="ngx_core_module ngx_errlog_module ngx_conf_module"
-
-CORE_INCS="src/core"
-
-CORE_DEPS="src/core/nginx.h \
- src/core/ngx_config.h \
- src/core/ngx_core.h \
- src/core/ngx_log.h \
- src/core/ngx_palloc.h \
- src/core/ngx_array.h \
- src/core/ngx_list.h \
- src/core/ngx_hash.h \
- src/core/ngx_buf.h \
- src/core/ngx_queue.h \
- src/core/ngx_string.h \
- src/core/ngx_parse.h \
- src/core/ngx_inet.h \
- src/core/ngx_file.h \
- src/core/ngx_crc.h \
- src/core/ngx_crc32.h \
- src/core/ngx_murmurhash.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 \
- src/core/ngx_times.h \
- src/core/ngx_shmtx.h \
- src/core/ngx_connection.h \
- src/core/ngx_cycle.h \
- src/core/ngx_conf_file.h \
- src/core/ngx_resolver.h \
- src/core/ngx_open_file_cache.h \
- src/core/ngx_crypt.h \
- src/core/ngx_proxy_protocol.h \
- src/core/ngx_syslog.h"
-
-
-CORE_SRCS="src/core/nginx.c \
- src/core/ngx_log.c \
- src/core/ngx_palloc.c \
- src/core/ngx_array.c \
- src/core/ngx_list.c \
- src/core/ngx_hash.c \
- src/core/ngx_buf.c \
- src/core/ngx_queue.c \
- src/core/ngx_output_chain.c \
- src/core/ngx_string.c \
- src/core/ngx_parse.c \
- src/core/ngx_inet.c \
- src/core/ngx_file.c \
- src/core/ngx_crc32.c \
- src/core/ngx_murmurhash.c \
- src/core/ngx_md5.c \
- src/core/ngx_rbtree.c \
- src/core/ngx_radix_tree.c \
- src/core/ngx_slab.c \
- src/core/ngx_times.c \
- src/core/ngx_shmtx.c \
- src/core/ngx_connection.c \
- src/core/ngx_cycle.c \
- src/core/ngx_spinlock.c \
- src/core/ngx_cpuinfo.c \
- src/core/ngx_conf_file.c \
- src/core/ngx_resolver.c \
- src/core/ngx_open_file_cache.c \
- src/core/ngx_crypt.c \
- src/core/ngx_proxy_protocol.c \
- src/core/ngx_syslog.c"
-
-
-REGEX_MODULE=ngx_regex_module
-REGEX_DEPS=src/core/ngx_regex.h
-REGEX_SRCS=src/core/ngx_regex.c
-
-PCRE_SRCS="src/pcre/pcre_chartables.c \
- src/pcre/pcre_compile.c \
- src/pcre/pcre_exec.c \
- src/pcre/pcre_fullinfo.c \
- src/pcre/pcre_globals.c \
- src/pcre/pcre_newline.c \
- src/pcre/pcre_ord2utf8.c \
- src/pcre/pcre_study.c \
- src/pcre/pcre_tables.c \
- src/pcre/pcre_ucd.c \
- src/pcre/pcre_valid_utf8.c \
- src/pcre/pcre_xclass.c"
-
-OPENSSL_MODULE=ngx_openssl_module
-OPENSSL_DEPS=src/event/ngx_event_openssl.h
-OPENSSL_SRCS="src/event/ngx_event_openssl.c \
- src/event/ngx_event_openssl_stapling.c"
-
-
-EVENT_MODULES="ngx_events_module ngx_event_core_module"
-
-EVENT_INCS="src/event src/event/modules"
-
-EVENT_DEPS="src/event/ngx_event.h \
- src/event/ngx_event_timer.h \
- src/event/ngx_event_posted.h \
- src/event/ngx_event_busy_lock.h \
- src/event/ngx_event_connect.h \
- src/event/ngx_event_pipe.h"
-
-EVENT_SRCS="src/event/ngx_event.c \
- src/event/ngx_event_timer.c \
- src/event/ngx_event_posted.c \
- src/event/ngx_event_busy_lock.c \
- src/event/ngx_event_accept.c \
- src/event/ngx_event_connect.c \
- src/event/ngx_event_pipe.c"
-
-
-SELECT_MODULE=ngx_select_module
-SELECT_SRCS=src/event/modules/ngx_select_module.c
-WIN32_SELECT_SRCS=src/event/modules/ngx_win32_select_module.c
-
-POLL_MODULE=ngx_poll_module
-POLL_SRCS=src/event/modules/ngx_poll_module.c
-
-KQUEUE_MODULE=ngx_kqueue_module
-KQUEUE_SRCS=src/event/modules/ngx_kqueue_module.c
-
-DEVPOLL_MODULE=ngx_devpoll_module
-DEVPOLL_SRCS=src/event/modules/ngx_devpoll_module.c
-
-EVENTPORT_MODULE=ngx_eventport_module
-EVENTPORT_SRCS=src/event/modules/ngx_eventport_module.c
-
-EPOLL_MODULE=ngx_epoll_module
-EPOLL_SRCS=src/event/modules/ngx_epoll_module.c
-
-RTSIG_MODULE=ngx_rtsig_module
-RTSIG_SRCS=src/event/modules/ngx_rtsig_module.c
-
-IOCP_MODULE=ngx_iocp_module
-IOCP_SRCS=src/event/modules/ngx_iocp_module.c
-
-AIO_MODULE=ngx_aio_module
-AIO_SRCS="src/event/modules/ngx_aio_module.c \
- src/os/unix/ngx_aio_read.c \
- src/os/unix/ngx_aio_write.c \
- src/os/unix/ngx_aio_read_chain.c \
- src/os/unix/ngx_aio_write_chain.c"
-
-FILE_AIO_SRCS="src/os/unix/ngx_file_aio_read.c"
-LINUX_AIO_SRCS="src/os/unix/ngx_linux_aio_read.c"
-
-UNIX_INCS="$CORE_INCS $EVENT_INCS src/os/unix"
-
-UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \
- src/os/unix/ngx_time.h \
- src/os/unix/ngx_errno.h \
- src/os/unix/ngx_alloc.h \
- src/os/unix/ngx_files.h \
- src/os/unix/ngx_channel.h \
- src/os/unix/ngx_shmem.h \
- src/os/unix/ngx_process.h \
- src/os/unix/ngx_setaffinity.h \
- src/os/unix/ngx_setproctitle.h \
- src/os/unix/ngx_atomic.h \
- src/os/unix/ngx_gcc_atomic_x86.h \
- src/os/unix/ngx_thread.h \
- src/os/unix/ngx_socket.h \
- src/os/unix/ngx_os.h \
- src/os/unix/ngx_user.h \
- src/os/unix/ngx_process_cycle.h"
-
-# add to UNIX_DEPS
-# src/os/unix/ngx_gcc_atomic_amd64.h \
-# src/os/unix/ngx_gcc_atomic_sparc64.h \
-# src/os/unix/ngx_gcc_atomic_ppc.h \
-# src/os/unix/ngx_sunpro_atomic_sparc64.h \
-# src/os/unix/ngx_sunpro_x86.il \
-# src/os/unix/ngx_sunpro_amd64.il \
-# src/os/unix/ngx_sunpro_sparc64.il \
-
-
-UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \
- src/os/unix/ngx_time.c \
- src/os/unix/ngx_errno.c \
- src/os/unix/ngx_alloc.c \
- src/os/unix/ngx_files.c \
- src/os/unix/ngx_socket.c \
- src/os/unix/ngx_recv.c \
- src/os/unix/ngx_readv_chain.c \
- src/os/unix/ngx_udp_recv.c \
- src/os/unix/ngx_send.c \
- src/os/unix/ngx_writev_chain.c \
- src/os/unix/ngx_channel.c \
- src/os/unix/ngx_shmem.c \
- src/os/unix/ngx_process.c \
- src/os/unix/ngx_daemon.c \
- src/os/unix/ngx_setaffinity.c \
- src/os/unix/ngx_setproctitle.c \
- src/os/unix/ngx_posix_init.c \
- src/os/unix/ngx_user.c \
- src/os/unix/ngx_process_cycle.c"
-
-POSIX_DEPS=src/os/unix/ngx_posix_config.h
-
-FREEBSD_DEPS="src/os/unix/ngx_freebsd_config.h src/os/unix/ngx_freebsd.h"
-FREEBSD_SRCS=src/os/unix/ngx_freebsd_init.c
-FREEBSD_SENDFILE_SRCS=src/os/unix/ngx_freebsd_sendfile_chain.c
-FREEBSD_RFORK_DEPS="src/os/unix/ngx_freebsd_rfork_thread.h"
-FREEBSD_RFORK_SRCS="src/os/unix/ngx_freebsd_rfork_thread.c"
-FREEBSD_RFORK_THREAD_SRCS="src/os/unix/rfork_thread.S"
-
-PTHREAD_SRCS="src/os/unix/ngx_pthread_thread.c"
-
-LINUX_DEPS="src/os/unix/ngx_linux_config.h src/os/unix/ngx_linux.h"
-LINUX_SRCS=src/os/unix/ngx_linux_init.c
-LINUX_SENDFILE_SRCS=src/os/unix/ngx_linux_sendfile_chain.c
-
-
-SOLARIS_DEPS="src/os/unix/ngx_solaris_config.h src/os/unix/ngx_solaris.h"
-SOLARIS_SRCS=src/os/unix/ngx_solaris_init.c
-SOLARIS_SENDFILEV_SRCS=src/os/unix/ngx_solaris_sendfilev_chain.c
-
-
-DARWIN_DEPS="src/os/unix/ngx_darwin_config.h src/os/unix/ngx_darwin.h"
-DARWIN_SRCS=src/os/unix/ngx_darwin_init.c
-DARWIN_SENDFILE_SRCS=src/os/unix/ngx_darwin_sendfile_chain.c
-
-
-WIN32_INCS="$CORE_INCS $EVENT_INCS src/os/win32"
-
-WIN32_DEPS="$CORE_DEPS $EVENT_DEPS \
- src/os/win32/ngx_win32_config.h \
- src/os/win32/ngx_time.h \
- src/os/win32/ngx_errno.h \
- src/os/win32/ngx_alloc.h \
- src/os/win32/ngx_files.h \
- src/os/win32/ngx_shmem.h \
- src/os/win32/ngx_process.h \
- src/os/win32/ngx_atomic.h \
- src/os/win32/ngx_thread.h \
- src/os/win32/ngx_socket.h \
- src/os/win32/ngx_os.h \
- src/os/win32/ngx_user.h \
- src/os/win32/ngx_process_cycle.h"
-
-WIN32_CONFIG=src/os/win32/ngx_win32_config.h
-
-WIN32_SRCS="$CORE_SRCS $EVENT_SRCS \
- src/os/win32/ngx_errno.c \
- src/os/win32/ngx_alloc.c \
- src/os/win32/ngx_files.c \
- src/os/win32/ngx_shmem.c \
- src/os/win32/ngx_time.c \
- src/os/win32/ngx_process.c \
- src/os/win32/ngx_thread.c \
- src/os/win32/ngx_socket.c \
- src/os/win32/ngx_wsarecv.c \
- src/os/win32/ngx_wsarecv_chain.c \
- src/os/win32/ngx_udp_wsarecv.c \
- src/os/win32/ngx_wsasend.c \
- src/os/win32/ngx_wsasend_chain.c \
- src/os/win32/ngx_win32_init.c \
- src/os/win32/ngx_user.c \
- src/os/win32/ngx_event_log.c \
- src/os/win32/ngx_process_cycle.c \
- src/event/ngx_event_acceptex.c"
-
-NGX_WIN32_ICONS="src/os/win32/nginx.ico"
-NGX_WIN32_RC="src/os/win32/nginx.rc"
-
-
-# the http modules that have their logging formats
-# must be after ngx_http_log_module
-
-HTTP_MODULES="ngx_http_module \
- ngx_http_core_module \
- ngx_http_log_module \
- ngx_http_upstream_module"
-
-HTTP_WRITE_FILTER_MODULE="ngx_http_write_filter_module"
-HTTP_HEADER_FILTER_MODULE="ngx_http_header_filter_module"
-
-HTTP_POSTPONE_FILTER_MODULE=ngx_http_postpone_filter_module
-HTTP_COPY_FILTER_MODULE=ngx_http_copy_filter_module
-
-HTTP_CHUNKED_FILTER_MODULE=ngx_http_chunked_filter_module
-HTTP_HEADERS_FILTER_MODULE=ngx_http_headers_filter_module
-
-HTTP_RANGE_HEADER_FILTER_MODULE=ngx_http_range_header_filter_module
-HTTP_RANGE_BODY_FILTER_MODULE=ngx_http_range_body_filter_module
-
-HTTP_NOT_MODIFIED_FILTER_MODULE=ngx_http_not_modified_filter_module
-
-HTTP_STATIC_MODULE=ngx_http_static_module
-HTTP_INDEX_MODULE=ngx_http_index_module
-
-HTTP_INCS="src/http src/http/modules"
-
-HTTP_DEPS="src/http/ngx_http.h \
- src/http/ngx_http_request.h \
- src/http/ngx_http_config.h \
- src/http/ngx_http_core_module.h \
- src/http/ngx_http_cache.h \
- src/http/ngx_http_variables.h \
- src/http/ngx_http_script.h \
- src/http/ngx_http_upstream.h \
- src/http/ngx_http_upstream_round_robin.h \
- src/http/ngx_http_busy_lock.h"
-
-HTTP_SRCS="src/http/ngx_http.c \
- src/http/ngx_http_core_module.c \
- src/http/ngx_http_special_response.c \
- src/http/ngx_http_request.c \
- src/http/ngx_http_parse.c \
- src/http/ngx_http_header_filter_module.c \
- src/http/ngx_http_write_filter_module.c \
- src/http/ngx_http_copy_filter_module.c \
- src/http/modules/ngx_http_log_module.c \
- src/http/ngx_http_request_body.c \
- src/http/ngx_http_variables.c \
- src/http/ngx_http_script.c \
- src/http/ngx_http_upstream.c \
- src/http/ngx_http_upstream_round_robin.c \
- src/http/ngx_http_parse_time.c \
- src/http/modules/ngx_http_static_module.c \
- src/http/modules/ngx_http_index_module.c \
- src/http/modules/ngx_http_chunked_filter_module.c \
- src/http/modules/ngx_http_range_filter_module.c \
- src/http/modules/ngx_http_headers_filter_module.c \
- src/http/modules/ngx_http_not_modified_filter_module.c"
-
-# STUB
-HTTP_SRCS="$HTTP_SRCS src/http/ngx_http_busy_lock.c"
-
-HTTP_POSTPONE_FILTER_SRCS=src/http/ngx_http_postpone_filter_module.c
-
-HTTP_FILE_CACHE_SRCS=src/http/ngx_http_file_cache.c
-
-
-HTTP_SPDY_MODULE=ngx_http_spdy_module
-HTTP_SPDY_FILTER_MODULE=ngx_http_spdy_filter_module
-HTTP_SPDY_DEPS="src/http/ngx_http_spdy.h \
- src/http/ngx_http_spdy_module.h"
-HTTP_SPDY_SRCS="src/http/ngx_http_spdy.c \
- src/http/ngx_http_spdy_module.c \
- src/http/ngx_http_spdy_filter_module.c"
-
-
-HTTP_CHARSET_FILTER_MODULE=ngx_http_charset_filter_module
-HTTP_CHARSET_SRCS=src/http/modules/ngx_http_charset_filter_module.c
-
-
-HTTP_GZIP_FILTER_MODULE=ngx_http_gzip_filter_module
-HTTP_GZIP_SRCS=src/http/modules/ngx_http_gzip_filter_module.c
-
-
-HTTP_GUNZIP_FILTER_MODULE=ngx_http_gunzip_filter_module
-HTTP_GUNZIP_SRCS=src/http/modules/ngx_http_gunzip_filter_module.c
-
-
-HTTP_SSI_FILTER_MODULE=ngx_http_ssi_filter_module
-HTTP_SSI_DEPS=src/http/modules/ngx_http_ssi_filter_module.h
-HTTP_SSI_SRCS=src/http/modules/ngx_http_ssi_filter_module.c
-
-
-HTTP_XSLT_FILTER_MODULE=ngx_http_xslt_filter_module
-HTTP_XSLT_SRCS=src/http/modules/ngx_http_xslt_filter_module.c
-
-
-HTTP_IMAGE_FILTER_MODULE=ngx_http_image_filter_module
-HTTP_IMAGE_SRCS=src/http/modules/ngx_http_image_filter_module.c
-
-
-HTTP_SUB_FILTER_MODULE=ngx_http_sub_filter_module
-HTTP_SUB_SRCS=src/http/modules/ngx_http_sub_filter_module.c
-
-
-HTTP_USERID_FILTER_MODULE=ngx_http_userid_filter_module
-HTTP_USERID_SRCS=src/http/modules/ngx_http_userid_filter_module.c
-
-
-HTTP_REALIP_MODULE=ngx_http_realip_module
-HTTP_REALIP_SRCS=src/http/modules/ngx_http_realip_module.c
-
-
-HTTP_ADDITION_FILTER_MODULE=ngx_http_addition_filter_module
-HTTP_ADDITION_SRCS=src/http/modules/ngx_http_addition_filter_module.c
-
-
-HTTP_DAV_MODULE=ngx_http_dav_module
-HTTP_DAV_SRCS=src/http/modules/ngx_http_dav_module.c
-
-
-HTTP_ACCESS_MODULE=ngx_http_access_module
-HTTP_ACCESS_SRCS=src/http/modules/ngx_http_access_module.c
-
-
-HTTP_AUTH_BASIC_MODULE=ngx_http_auth_basic_module
-HTTP_AUTH_BASIC_SRCS=src/http/modules/ngx_http_auth_basic_module.c
-
-
-HTTP_AUTH_REQUEST_MODULE=ngx_http_auth_request_module
-HTTP_AUTH_REQUEST_SRCS=src/http/modules/ngx_http_auth_request_module.c
-
-
-HTTP_AUTOINDEX_MODULE=ngx_http_autoindex_module
-HTTP_AUTOINDEX_SRCS=src/http/modules/ngx_http_autoindex_module.c
-
-
-HTTP_RANDOM_INDEX_MODULE=ngx_http_random_index_module
-HTTP_RANDOM_INDEX_SRCS=src/http/modules/ngx_http_random_index_module.c
-
-
-HTTP_STATUS_MODULE=ngx_http_status_module
-HTTP_STATUS_SRCS=src/http/modules/ngx_http_status_module.c
-
-
-HTTP_GEO_MODULE=ngx_http_geo_module
-HTTP_GEO_SRCS=src/http/modules/ngx_http_geo_module.c
-
-
-HTTP_GEOIP_MODULE=ngx_http_geoip_module
-HTTP_GEOIP_SRCS=src/http/modules/ngx_http_geoip_module.c
-
-
-HTTP_MAP_MODULE=ngx_http_map_module
-HTTP_MAP_SRCS=src/http/modules/ngx_http_map_module.c
-
-
-HTTP_SPLIT_CLIENTS_MODULE=ngx_http_split_clients_module
-HTTP_SPLIT_CLIENTS_SRCS=src/http/modules/ngx_http_split_clients_module.c
-
-
-HTTP_REFERER_MODULE=ngx_http_referer_module
-HTTP_REFERER_SRCS=src/http/modules/ngx_http_referer_module.c
-
-
-HTTP_REWRITE_MODULE=ngx_http_rewrite_module
-HTTP_REWRITE_SRCS=src/http/modules/ngx_http_rewrite_module.c
-
-
-HTTP_SSL_MODULE=ngx_http_ssl_module
-HTTP_SSL_DEPS=src/http/modules/ngx_http_ssl_module.h
-HTTP_SSL_SRCS=src/http/modules/ngx_http_ssl_module.c
-
-
-HTTP_PROXY_MODULE=ngx_http_proxy_module
-HTTP_PROXY_SRCS=src/http/modules/ngx_http_proxy_module.c
-
-
-HTTP_FASTCGI_MODULE=ngx_http_fastcgi_module
-HTTP_FASTCGI_SRCS=src/http/modules/ngx_http_fastcgi_module.c
-
-
-HTTP_UWSGI_MODULE=ngx_http_uwsgi_module
-HTTP_UWSGI_SRCS=src/http/modules/ngx_http_uwsgi_module.c
-
-
-HTTP_SCGI_MODULE=ngx_http_scgi_module
-HTTP_SCGI_SRCS=src/http/modules/ngx_http_scgi_module.c
-
-
-HTTP_PERL_MODULE=ngx_http_perl_module
-HTTP_PERL_INCS=src/http/modules/perl
-HTTP_PERL_DEPS=src/http/modules/perl/ngx_http_perl_module.h
-HTTP_PERL_SRCS=src/http/modules/perl/ngx_http_perl_module.c
-
-
-HTTP_MEMCACHED_MODULE=ngx_http_memcached_module
-HTTP_MEMCACHED_SRCS=src/http/modules/ngx_http_memcached_module.c
-
-
-HTTP_LIMIT_CONN_MODULE=ngx_http_limit_conn_module
-HTTP_LIMIT_CONN_SRCS=src/http/modules/ngx_http_limit_conn_module.c
-
-
-HTTP_LIMIT_REQ_MODULE=ngx_http_limit_req_module
-HTTP_LIMIT_REQ_SRCS=src/http/modules/ngx_http_limit_req_module.c
-
-
-HTTP_EMPTY_GIF_MODULE=ngx_http_empty_gif_module
-HTTP_EMPTY_GIF_SRCS=src/http/modules/ngx_http_empty_gif_module.c
-
-
-HTTP_BROWSER_MODULE=ngx_http_browser_module
-HTTP_BROWSER_SRCS=src/http/modules/ngx_http_browser_module.c
-
-
-HTTP_SECURE_LINK_MODULE=ngx_http_secure_link_module
-HTTP_SECURE_LINK_SRCS=src/http/modules/ngx_http_secure_link_module.c
-
-
-HTTP_DEGRADATION_MODULE=ngx_http_degradation_module
-HTTP_DEGRADATION_SRCS=src/http/modules/ngx_http_degradation_module.c
-
-
-HTTP_FLV_MODULE=ngx_http_flv_module
-HTTP_FLV_SRCS=src/http/modules/ngx_http_flv_module.c
-
-
-HTTP_MP4_MODULE=ngx_http_mp4_module
-HTTP_MP4_SRCS=src/http/modules/ngx_http_mp4_module.c
-
-
-HTTP_GZIP_STATIC_MODULE=ngx_http_gzip_static_module
-HTTP_GZIP_STATIC_SRCS=src/http/modules/ngx_http_gzip_static_module.c
-
-
-HTTP_UPSTREAM_IP_HASH_MODULE=ngx_http_upstream_ip_hash_module
-HTTP_UPSTREAM_IP_HASH_SRCS=src/http/modules/ngx_http_upstream_ip_hash_module.c
-
-
-HTTP_UPSTREAM_LEAST_CONN_MODULE=ngx_http_upstream_least_conn_module
-HTTP_UPSTREAM_LEAST_CONN_SRCS=" \
- src/http/modules/ngx_http_upstream_least_conn_module.c"
-
-
-HTTP_UPSTREAM_KEEPALIVE_MODULE=ngx_http_upstream_keepalive_module
-HTTP_UPSTREAM_KEEPALIVE_SRCS=" \
- src/http/modules/ngx_http_upstream_keepalive_module.c"
-
-
-MAIL_INCS="src/mail"
-
-MAIL_DEPS="src/mail/ngx_mail.h"
-
-MAIL_MODULES="ngx_mail_module ngx_mail_core_module"
-
-MAIL_SRCS="src/mail/ngx_mail.c \
- src/mail/ngx_mail_core_module.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"
-
-MAIL_AUTH_HTTP_MODULE="ngx_mail_auth_http_module"
-MAIL_AUTH_HTTP_SRCS="src/mail/ngx_mail_auth_http_module.c"
-
-MAIL_PROXY_MODULE="ngx_mail_proxy_module"
-MAIL_PROXY_SRCS="src/mail/ngx_mail_proxy_module.c"
-
-NGX_GOOGLE_PERFTOOLS_MODULE=ngx_google_perftools_module
-NGX_GOOGLE_PERFTOOLS_SRCS=src/misc/ngx_google_perftools_module.c
-
-NGX_CPP_TEST_SRCS=src/misc/ngx_cpp_test_module.cpp
diff --git a/usr.sbin/nginx/auto/stubs b/usr.sbin/nginx/auto/stubs
deleted file mode 100644
index d8bc1f0e02a..00000000000
--- a/usr.sbin/nginx/auto/stubs
+++ /dev/null
@@ -1,8 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-have=NGX_SUPPRESS_WARN . auto/have
-
-have=NGX_SMP . auto/have
diff --git a/usr.sbin/nginx/auto/summary b/usr.sbin/nginx/auto/summary
deleted file mode 100644
index dcebec9f0fe..00000000000
--- a/usr.sbin/nginx/auto/summary
+++ /dev/null
@@ -1,116 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-### STUB
-
-if [ $USE_THREADS != NO ]; then
-
-cat << END
-
-$0: error: the threads support is broken now.
-
-END
- exit 1
- fi
-
-###
-
-
-echo
-echo "Configuration summary"
-
-
-#case $USE_THREADS in
-# rfork) echo " + using rfork()ed threads" ;;
-# pthreads) echo " + using libpthread threads library" ;;
-# libthr) echo " + using FreeBSD libthr threads library" ;;
-# libc_r) echo " + using FreeBSD libc_r threads library" ;;
-# linuxthreads) echo " + using FreeBSD LinuxThreads port library" ;;
-# NO) echo " + threads are not used" ;;
-# *) echo " + using lib$USE_THREADS threads library" ;;
-#esac
-
-if [ $USE_PCRE = DISABLED ]; then
- echo " + PCRE library is disabled"
-
-else
- case $PCRE in
- YES) echo " + using system PCRE library" ;;
- NONE) echo " + PCRE library is not used" ;;
- *) echo " + using PCRE library: $PCRE" ;;
- esac
-fi
-
-case $OPENSSL in
- YES) echo " + using system OpenSSL library" ;;
- NONE) echo " + OpenSSL library is not used" ;;
- *) echo " + using OpenSSL library: $OPENSSL" ;;
-esac
-
-case $MD5 in
- YES) echo " + md5: using $MD5_LIB library" ;;
- NONE) echo " + md5 library is not used" ;;
- NO) echo " + using builtin md5 code" ;;
- *) echo " + using md5 library: $MD5" ;;
-esac
-
-case $SHA1 in
- YES) echo " + sha1: using $SHA1_LIB library" ;;
- NONE) echo " + sha1 library is not used" ;;
- NO) echo " + sha1 library is not found" ;;
- *) echo " + using sha1 library: $SHA1" ;;
-esac
-
-case $ZLIB in
- YES) echo " + using system zlib library" ;;
- NONE) echo " + zlib library is not used" ;;
- *) echo " + using zlib library: $ZLIB" ;;
-esac
-
-case $NGX_LIBATOMIC in
- YES) echo " + using system libatomic_ops library" ;;
- NO) ;; # not used
- *) echo " + using libatomic_ops library: $NGX_LIBATOMIC" ;;
-esac
-
-echo
-
-
-cat << END
- nginx path prefix: "$NGX_PREFIX"
- nginx binary file: "$NGX_SBIN_PATH"
- nginx configuration prefix: "$NGX_CONF_PREFIX"
- nginx configuration file: "$NGX_CONF_PATH"
- nginx pid file: "$NGX_PID_PATH"
-END
-
-if test -n "$NGX_ERROR_LOG_PATH"; then
- echo " nginx error log file: \"$NGX_ERROR_LOG_PATH\""
-else
- echo " nginx logs errors to stderr"
-fi
-
-cat << END
- nginx http access log file: "$NGX_HTTP_LOG_PATH"
- nginx http client request body temporary files: "$NGX_HTTP_CLIENT_TEMP_PATH"
-END
-
-if [ $HTTP_PROXY = YES ]; then
- echo " nginx http proxy temporary files: \"$NGX_HTTP_PROXY_TEMP_PATH\""
-fi
-
-if [ $HTTP_FASTCGI = YES ]; then
- echo " nginx http fastcgi temporary files: \"$NGX_HTTP_FASTCGI_TEMP_PATH\""
-fi
-
-if [ $HTTP_UWSGI = YES ]; then
- echo " nginx http uwsgi temporary files: \"$NGX_HTTP_UWSGI_TEMP_PATH\""
-fi
-
-if [ $HTTP_SCGI = YES ]; then
- echo " nginx http scgi temporary files: \"$NGX_HTTP_SCGI_TEMP_PATH\""
-fi
-
-echo "$NGX_POST_CONF_MSG"
diff --git a/usr.sbin/nginx/auto/types/sizeof b/usr.sbin/nginx/auto/types/sizeof
deleted file mode 100644
index 9215a545fc4..00000000000
--- a/usr.sbin/nginx/auto/types/sizeof
+++ /dev/null
@@ -1,84 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-echo $ngx_n "checking for $ngx_type size ...$ngx_c"
-
-cat << END >> $NGX_AUTOCONF_ERR
-
-----------------------------------------
-checking for $ngx_type size
-
-END
-
-ngx_size=
-
-cat << END > $NGX_AUTOTEST.c
-
-#include <sys/types.h>
-#include <sys/time.h>
-$NGX_INCLUDE_UNISTD_H
-#include <signal.h>
-#include <stdio.h>
-#include <sys/resource.h>
-$NGX_INCLUDE_INTTYPES_H
-$NGX_INCLUDE_AUTO_CONFIG_H
-
-int main() {
- printf("%d", (int) sizeof($ngx_type));
- return 0;
-}
-
-END
-
-
-ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
- -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
-
-eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
-
-
-if [ -x $NGX_AUTOTEST ]; then
- ngx_size=`$NGX_AUTOTEST`
- echo " $ngx_size bytes"
-fi
-
-
-rm -rf $NGX_AUTOTEST*
-
-
-case $ngx_size in
- 4)
- if [ "$ngx_type"="long" ]; then
- ngx_max_value=2147483647L
- else
- ngx_max_value=2147483647
- fi
-
- ngx_max_len='(sizeof("-2147483648") - 1)'
- ;;
-
- 8)
- if [ "$ngx_type"="long long" ]; then
- ngx_max_value=9223372036854775807LL
- else
- ngx_max_value=9223372036854775807L
- fi
-
- ngx_max_len='(sizeof("-9223372036854775808") - 1)'
- ;;
-
- *)
- echo
- echo "$0: error: can not detect $ngx_type size"
-
- echo "----------" >> $NGX_AUTOCONF_ERR
- cat $NGX_AUTOTEST.c >> $NGX_AUTOCONF_ERR
- echo "----------" >> $NGX_AUTOCONF_ERR
- echo $ngx_test >> $NGX_AUTOCONF_ERR
- echo "----------" >> $NGX_AUTOCONF_ERR
-
- exit 1
-esac
-
diff --git a/usr.sbin/nginx/auto/types/typedef b/usr.sbin/nginx/auto/types/typedef
deleted file mode 100644
index 8b5c3689ced..00000000000
--- a/usr.sbin/nginx/auto/types/typedef
+++ /dev/null
@@ -1,77 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-echo $ngx_n "checking for $ngx_type ...$ngx_c"
-
-cat << END >> $NGX_AUTOCONF_ERR
-
-----------------------------------------
-checking for $ngx_type
-
-END
-
-ngx_found=no
-
-for ngx_try in $ngx_type $ngx_types
-do
-
- cat << END > $NGX_AUTOTEST.c
-
-#include <sys/types.h>
-#include <signal.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <netinet/in.h>
-$NGX_INCLUDE_INTTYPES_H
-
-int main() {
- $ngx_try i = 0;
- return (int) i;
-}
-
-END
-
- ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
- -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
-
- eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
-
- if [ -x $NGX_AUTOTEST ]; then
- if [ $ngx_try = $ngx_type ]; then
- echo " found"
- ngx_found=yes
- else
- echo ", $ngx_try used"
- ngx_found=$ngx_try
- fi
- fi
-
- rm -rf $NGX_AUTOTEST*
-
- if [ $ngx_found = no ]; then
- echo $ngx_n " $ngx_try not found$ngx_c"
-
- echo "----------" >> $NGX_AUTOCONF_ERR
- cat $NGX_AUTOTEST.c >> $NGX_AUTOCONF_ERR
- echo "----------" >> $NGX_AUTOCONF_ERR
- echo $ngx_test >> $NGX_AUTOCONF_ERR
- echo "----------" >> $NGX_AUTOCONF_ERR
-
- else
- break
- fi
-done
-
-if [ $ngx_found = no ]; then
- echo
- echo "$0: error: can not define $ngx_type"
-
- exit 1
-fi
-
-if [ $ngx_found != yes ]; then
- echo "typedef $ngx_found $ngx_type;" >> $NGX_AUTO_CONFIG_H
-fi
diff --git a/usr.sbin/nginx/auto/types/uintptr_t b/usr.sbin/nginx/auto/types/uintptr_t
deleted file mode 100644
index f3cdccb2274..00000000000
--- a/usr.sbin/nginx/auto/types/uintptr_t
+++ /dev/null
@@ -1,45 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-echo $ngx_n "checking for uintptr_t ...$ngx_c"
-echo >> $NGX_AUTOCONF_ERR
-echo "checking for uintptr_t" >> $NGX_AUTOCONF_ERR
-
-found=no
-
-cat << END > $NGX_AUTOTEST.c
-
-#include <sys/types.h>
-$NGX_INTTYPES_H
-
-int main() {
- uintptr_t i = 0;
- return (int) i;
-}
-
-END
-
-ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
- -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT"
-
-eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
-
-if [ -x $NGX_AUTOTEST ]; then
- echo " uintptr_t found"
- found=yes
-else
- echo $ngx_n " uintptr_t not found" $ngx_c
-fi
-
-rm -rf $NGX_AUTOTEST*
-
-
-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 intptr_t;" | sed -e 's/u//g' >> $NGX_AUTO_CONFIG_H
-fi
diff --git a/usr.sbin/nginx/auto/types/value b/usr.sbin/nginx/auto/types/value
deleted file mode 100644
index ac88a3919ef..00000000000
--- a/usr.sbin/nginx/auto/types/value
+++ /dev/null
@@ -1,12 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-cat << END >> $NGX_AUTO_CONFIG_H
-
-#ifndef $ngx_param
-#define $ngx_param $ngx_value
-#endif
-
-END
diff --git a/usr.sbin/nginx/auto/unix b/usr.sbin/nginx/auto/unix
deleted file mode 100755
index 10fd3d29334..00000000000
--- a/usr.sbin/nginx/auto/unix
+++ /dev/null
@@ -1,806 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-NGX_USER=${NGX_USER:-nobody}
-
-if [ -z "$NGX_GROUP" ]; then
- if [ $NGX_USER = nobody ]; then
- if grep nobody /etc/group 2>&1 >/dev/null; then
- echo "checking for nobody group ... found"
- NGX_GROUP=nobody
- else
- echo "checking for nobody group ... not found"
-
- if grep nogroup /etc/group 2>&1 >/dev/null; then
- echo "checking for nogroup group ... found"
- NGX_GROUP=nogroup
- else
- echo "checking for nogroup group ... not found"
- NGX_GROUP=nobody
- fi
- fi
- else
- NGX_GROUP=$NGX_USER
- fi
-fi
-
-
-ngx_feature="poll()"
-ngx_feature_name=
-ngx_feature_run=no
-ngx_feature_incs="#include <poll.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int n; struct pollfd pl;
- pl.fd = 0;
- pl.events = 0;
- pl.revents = 0;
- n = poll(&pl, 1, 0);
- if (n == -1) return 1"
-. auto/feature
-
-if [ $ngx_found = no ]; then
- EVENT_POLL=NONE
-fi
-
-
-ngx_feature="/dev/poll"
-ngx_feature_name="NGX_HAVE_DEVPOLL"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/devpoll.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int n, dp; struct dvpoll dvp;
- dp = 0;
- dvp.dp_fds = NULL;
- dvp.dp_nfds = 0;
- dvp.dp_timeout = 0;
- n = ioctl(dp, DP_POLL, &dvp);
- if (n == -1) return 1"
-. auto/feature
-
-if [ $ngx_found = yes ]; then
- CORE_SRCS="$CORE_SRCS $DEVPOLL_SRCS"
- EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE"
- EVENT_FOUND=YES
-fi
-
-
-if test -z "$NGX_KQUEUE_CHECKED"; then
- ngx_feature="kqueue"
- ngx_feature_name="NGX_HAVE_KQUEUE"
- ngx_feature_run=no
- ngx_feature_incs="#include <sys/event.h>"
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test="int kq; kq = kqueue()"
- . auto/feature
-
- if [ $ngx_found = yes ]; then
-
- have=NGX_HAVE_CLEAR_EVENT . auto/have
- EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE"
- CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS"
- EVENT_FOUND=YES
-
- ngx_feature="kqueue's NOTE_LOWAT"
- ngx_feature_name="NGX_HAVE_LOWAT_EVENT"
- ngx_feature_run=no
- ngx_feature_incs="#include <sys/event.h>"
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test="struct kevent kev;
- kev.fflags = NOTE_LOWAT;"
- . auto/feature
-
-
- ngx_feature="kqueue's EVFILT_TIMER"
- ngx_feature_name="NGX_HAVE_TIMER_EVENT"
- ngx_feature_run=yes
- ngx_feature_incs="#include <sys/event.h>
- #include <sys/time.h>"
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test="int kq;
- struct kevent kev;
- struct timespec ts;
-
- if ((kq = kqueue()) == -1) return 1;
-
- kev.ident = 0;
- kev.filter = EVFILT_TIMER;
- kev.flags = EV_ADD|EV_ENABLE;
- kev.fflags = 0;
- kev.data = 1000;
- kev.udata = 0;
-
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
-
- if (kevent(kq, &kev, 1, &kev, 1, &ts) == -1) return 1;
-
- if (kev.flags & EV_ERROR) return 1;"
-
- . auto/feature
- fi
-fi
-
-
-if [ "$NGX_SYSTEM" = "NetBSD" ]; then
-
- # NetBSD 2.0 incompatibly defines kevent.udata as "intptr_t"
-
- cat << END >> $NGX_AUTO_CONFIG_H
-
-#define NGX_KQUEUE_UDATA_T
-
-END
-
-else
- cat << END >> $NGX_AUTO_CONFIG_H
-
-#define NGX_KQUEUE_UDATA_T (void *)
-
-END
-
-fi
-
-
-ngx_feature="crypt()"
-ngx_feature_name=
-ngx_feature_run=no
-ngx_feature_incs=
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="crypt(\"test\", \"salt\");"
-. auto/feature
-
-
-if [ $ngx_found = no ]; then
-
- ngx_feature="crypt() in libcrypt"
- ngx_feature_name=
- ngx_feature_run=no
- ngx_feature_incs=
- ngx_feature_path=
- ngx_feature_libs=-lcrypt
- . auto/feature
-
- if [ $ngx_found = yes ]; then
- CRYPT_LIB="-lcrypt"
- fi
-fi
-
-
-ngx_feature="F_READAHEAD"
-ngx_feature_name="NGX_HAVE_F_READAHEAD"
-ngx_feature_run=no
-ngx_feature_incs="#include <fcntl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="fcntl(0, F_READAHEAD, 1);"
-. auto/feature
-
-
-ngx_feature="posix_fadvise()"
-ngx_feature_name="NGX_HAVE_POSIX_FADVISE"
-ngx_feature_run=no
-ngx_feature_incs="#include <fcntl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);"
-. auto/feature
-
-
-ngx_feature="O_DIRECT"
-ngx_feature_name="NGX_HAVE_O_DIRECT"
-ngx_feature_run=no
-ngx_feature_incs="#include <fcntl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="fcntl(0, F_SETFL, O_DIRECT);"
-. auto/feature
-
-
-if [ $ngx_found = yes -a "$NGX_SYSTEM" = "Linux" ]; then
- have=NGX_HAVE_ALIGNED_DIRECTIO . auto/have
-fi
-
-ngx_feature="F_NOCACHE"
-ngx_feature_name="NGX_HAVE_F_NOCACHE"
-ngx_feature_run=no
-ngx_feature_incs="#include <fcntl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="fcntl(0, F_NOCACHE, 1);"
-. auto/feature
-
-
-ngx_feature="directio()"
-ngx_feature_name="NGX_HAVE_DIRECTIO"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/types.h>
- #include <sys/fcntl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="directio(0, DIRECTIO_ON);"
-. auto/feature
-
-
-ngx_feature="statfs()"
-ngx_feature_name="NGX_HAVE_STATFS"
-ngx_feature_run=no
-ngx_feature_incs="$NGX_INCLUDE_SYS_PARAM_H
- $NGX_INCLUDE_SYS_MOUNT_H
- $NGX_INCLUDE_SYS_VFS_H"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="struct statfs fs;
- statfs(\".\", &fs);"
-. auto/feature
-
-
-ngx_feature="statvfs()"
-ngx_feature_name="NGX_HAVE_STATVFS"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/types.h>
- #include <sys/statvfs.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="struct statvfs fs;
- statvfs(\".\", &fs);"
-. auto/feature
-
-
-ngx_feature="dlopen()"
-ngx_feature_name=
-ngx_feature_run=no
-ngx_feature_incs="#include <dlfcn.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="dlopen(NULL, 0)"
-. auto/feature
-
-
-if [ $ngx_found != yes ]; then
-
- ngx_feature="dlopen() in libdl"
- ngx_feature_libs="-ldl"
- . auto/feature
-
- if [ $ngx_found = yes ]; then
- NGX_LIBDL="-ldl"
- fi
-fi
-
-
-ngx_feature="sched_yield()"
-ngx_feature_name="NGX_HAVE_SCHED_YIELD"
-ngx_feature_run=no
-ngx_feature_incs="#include <sched.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="sched_yield()"
-. auto/feature
-
-
-if [ $ngx_found != yes ]; then
-
- ngx_feature="sched_yield() in librt"
- ngx_feature_libs="-lrt"
- . auto/feature
-
- if [ $ngx_found = yes ]; then
- CORE_LIBS="$CORE_LIBS -lrt"
- fi
-fi
-
-
-ngx_feature="SO_SETFIB"
-ngx_feature_name="NGX_HAVE_SETFIB"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/socket.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_SETFIB, NULL, 4)"
-. auto/feature
-
-
-ngx_feature="SO_ACCEPTFILTER"
-ngx_feature_name="NGX_HAVE_DEFERRED_ACCEPT"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/socket.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)"
-. auto/feature
-
-
-ngx_feature="TCP_DEFER_ACCEPT"
-ngx_feature_name="NGX_HAVE_DEFERRED_ACCEPT"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_DEFER_ACCEPT, NULL, 0)"
-. auto/feature
-
-
-ngx_feature="TCP_KEEPIDLE"
-ngx_feature_name="NGX_HAVE_KEEPALIVE_TUNABLE"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_KEEPIDLE, NULL, 0);
- setsockopt(0, IPPROTO_TCP, TCP_KEEPINTVL, NULL, 0);
- setsockopt(0, IPPROTO_TCP, TCP_KEEPCNT, NULL, 0)"
-. auto/feature
-
-
-ngx_feature="TCP_FASTOPEN"
-ngx_feature_name="NGX_HAVE_TCP_FASTOPEN"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_FASTOPEN, NULL, 0)"
-. auto/feature
-
-
-ngx_feature="TCP_INFO"
-ngx_feature_name="NGX_HAVE_TCP_INFO"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="socklen_t optlen = sizeof(struct tcp_info);
- struct tcp_info ti;
- ti.tcpi_rtt = 0;
- ti.tcpi_rttvar = 0;
- ti.tcpi_snd_cwnd = 0;
- ti.tcpi_rcv_space = 0;
- getsockopt(0, IPPROTO_TCP, TCP_INFO, &ti, &optlen)"
-. auto/feature
-
-
-ngx_feature="accept4()"
-ngx_feature_name="NGX_HAVE_ACCEPT4"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/socket.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="accept4(0, NULL, NULL, SOCK_NONBLOCK)"
-. auto/feature
-
-if [ $NGX_FILE_AIO = YES ]; then
-
- ngx_feature="kqueue AIO support"
- ngx_feature_name="NGX_HAVE_FILE_AIO"
- ngx_feature_run=no
- ngx_feature_incs="#include <aio.h>"
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test="int n; struct aiocb iocb;
- iocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
- n = aio_read(&iocb)"
- . auto/feature
-
- if [ $ngx_found = yes ]; then
- CORE_SRCS="$CORE_SRCS $FILE_AIO_SRCS"
-
- elif [ $ngx_found = no ]; then
-
- ngx_feature="Linux AIO support"
- ngx_feature_name="NGX_HAVE_FILE_AIO"
- ngx_feature_run=no
- ngx_feature_incs="#include <linux/aio_abi.h>
- #include <sys/syscall.h>"
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test="int n = SYS_eventfd;
- struct iocb iocb;
- iocb.aio_lio_opcode = IOCB_CMD_PREAD;
- iocb.aio_flags = IOCB_FLAG_RESFD;
- iocb.aio_resfd = -1;"
- . auto/feature
-
- if [ $ngx_found = yes ]; then
- have=NGX_HAVE_EVENTFD . auto/have
- CORE_SRCS="$CORE_SRCS $LINUX_AIO_SRCS"
-
- else
- cat << END
-
-$0: no supported file AIO was found
-Currently file AIO is supported on FreeBSD 4.3+ and Linux 2.6.22+ only
-
-END
- exit 1
- fi
- fi
-fi
-
-
-have=NGX_HAVE_UNIX_DOMAIN . auto/have
-
-ngx_feature_libs=
-
-
-# C types
-
-ngx_type="int"; . auto/types/sizeof
-
-ngx_type="long"; . auto/types/sizeof
-
-ngx_type="long long"; . auto/types/sizeof
-
-ngx_type="void *"; . auto/types/sizeof; ngx_ptr_size=$ngx_size
-ngx_param=NGX_PTR_SIZE; ngx_value=$ngx_size; . auto/types/value
-
-
-# POSIX types
-
-case "$NGX_AUTO_CONFIG_H" in
- /*)
- NGX_INCLUDE_AUTO_CONFIG_H="#include \"$NGX_AUTO_CONFIG_H\""
- ;;
- *)
- NGX_INCLUDE_AUTO_CONFIG_H="#include \"../$NGX_AUTO_CONFIG_H\""
- ;;
-esac
-
-ngx_type="uint64_t"; ngx_types="u_int64_t"; . auto/types/typedef
-
-ngx_type="sig_atomic_t"; ngx_types="int"; . auto/types/typedef
-. auto/types/sizeof
-ngx_param=NGX_SIG_ATOMIC_T_SIZE; ngx_value=$ngx_size; . auto/types/value
-
-ngx_type="socklen_t"; ngx_types="int"; . auto/types/typedef
-
-ngx_type="in_addr_t"; ngx_types="uint32_t"; . auto/types/typedef
-
-ngx_type="in_port_t"; ngx_types="u_short"; . auto/types/typedef
-
-ngx_type="rlim_t"; ngx_types="int"; . auto/types/typedef
-
-. auto/types/uintptr_t
-
-. auto/endianness
-
-ngx_type="size_t"; . auto/types/sizeof
-ngx_param=NGX_MAX_SIZE_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
-ngx_param=NGX_SIZE_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
-
-ngx_type="off_t"; . auto/types/sizeof
-ngx_param=NGX_MAX_OFF_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
-ngx_param=NGX_OFF_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
-
-ngx_type="time_t"; . auto/types/sizeof
-ngx_param=NGX_TIME_T_SIZE; ngx_value=$ngx_size; . auto/types/value
-ngx_param=NGX_TIME_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
-
-
-# syscalls, libc calls and some features
-
-
-if [ $NGX_IPV6 = YES ]; then
- ngx_feature="AF_INET6"
- ngx_feature_name="NGX_HAVE_INET6"
- ngx_feature_run=no
- ngx_feature_incs="#include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>"
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test="struct sockaddr_in6 sin6;
- sin6.sin6_family = AF_INET6;"
- . auto/feature
-fi
-
-
-ngx_feature="setproctitle()"
-ngx_feature_name="NGX_HAVE_SETPROCTITLE"
-ngx_feature_run=no
-ngx_feature_incs="#include <stdlib.h>"
-ngx_feature_path=
-ngx_feature_libs=$NGX_SETPROCTITLE_LIB
-ngx_feature_test="setproctitle(\"test\");"
-. auto/feature
-
-
-ngx_feature="pread()"
-ngx_feature_name="NGX_HAVE_PREAD"
-ngx_feature_run=no
-ngx_feature_incs=
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="char buf[1]; ssize_t n; n = pread(0, buf, 1, 0);
- if (n == -1) return 1"
-. auto/feature
-
-
-ngx_feature="pwrite()"
-ngx_feature_name="NGX_HAVE_PWRITE"
-ngx_feature_run=no
-ngx_feature_incs=
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="char buf[1]; ssize_t n; n = pwrite(1, buf, 1, 0);
- if (n == -1) return 1"
-. auto/feature
-
-
-ngx_feature="sys_nerr"
-ngx_feature_name="NGX_SYS_NERR"
-ngx_feature_run=value
-ngx_feature_incs='#include <errno.h>
- #include <stdio.h>'
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test='printf("%d", sys_nerr);'
-. auto/feature
-
-
-if [ $ngx_found = no ]; then
-
- # Cygiwn defines _sys_nerr
- ngx_feature="_sys_nerr"
- ngx_feature_name="NGX_SYS_NERR"
- ngx_feature_run=value
- ngx_feature_incs='#include <errno.h>
- #include <stdio.h>'
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test='printf("%d", _sys_nerr);'
- . auto/feature
-fi
-
-
-if [ $ngx_found = no ]; then
-
- # Solaris has no sys_nerr
- ngx_feature='maximum errno'
- ngx_feature_name=NGX_SYS_NERR
- ngx_feature_run=value
- ngx_feature_incs='#include <errno.h>
- #include <string.h>
- #include <stdio.h>'
- ngx_feature_path=
- ngx_feature_libs=
- ngx_feature_test='int n;
- char *p;
- for (n = 1; n < 1000; n++) {
- errno = 0;
- p = strerror(n);
- if (errno == EINVAL
- || p == NULL
- || strncmp(p, "Unknown error", 13) == 0)
- {
- break;
- }
- }
- printf("%d", n);'
- . auto/feature
-fi
-
-
-ngx_feature="localtime_r()"
-ngx_feature_name="NGX_HAVE_LOCALTIME_R"
-ngx_feature_run=no
-ngx_feature_incs="#include <time.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="struct tm t; time_t c=0; localtime_r(&c, &t)"
-. auto/feature
-
-
-ngx_feature="posix_memalign()"
-ngx_feature_name="NGX_HAVE_POSIX_MEMALIGN"
-ngx_feature_run=no
-ngx_feature_incs="#include <stdlib.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="void *p; int n; n = posix_memalign(&p, 4096, 4096);
- if (n != 0) return 1"
-. auto/feature
-
-
-ngx_feature="memalign()"
-ngx_feature_name="NGX_HAVE_MEMALIGN"
-ngx_feature_run=no
-ngx_feature_incs="#include <stdlib.h>
- #include <malloc.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="void *p; p = memalign(4096, 4096);
- if (p == NULL) return 1"
-. auto/feature
-
-
-ngx_feature="mmap(MAP_ANON|MAP_SHARED)"
-ngx_feature_name="NGX_HAVE_MAP_ANON"
-ngx_feature_run=yes
-ngx_feature_incs="#include <sys/mman.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="void *p;
- p = mmap(NULL, 4096, PROT_READ|PROT_WRITE,
- MAP_ANON|MAP_SHARED, -1, 0);
- if (p == MAP_FAILED) return 1;"
-. auto/feature
-
-
-ngx_feature='mmap("/dev/zero", MAP_SHARED)'
-ngx_feature_name="NGX_HAVE_MAP_DEVZERO"
-ngx_feature_run=yes
-ngx_feature_incs="#include <sys/mman.h>
- #include <sys/stat.h>
- #include <fcntl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test='void *p; int fd;
- fd = open("/dev/zero", O_RDWR);
- p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if (p == MAP_FAILED) return 1;'
-. auto/feature
-
-
-ngx_feature="System V shared memory"
-ngx_feature_name="NGX_HAVE_SYSVSHM"
-ngx_feature_run=yes
-ngx_feature_incs="#include <sys/ipc.h>
- #include <sys/shm.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int id;
- id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT));
- if (id == -1) return 1;
- shmctl(id, IPC_RMID, NULL);"
-. auto/feature
-
-
-ngx_feature="POSIX semaphores"
-ngx_feature_name="NGX_HAVE_POSIX_SEM"
-ngx_feature_run=yes
-ngx_feature_incs="#include <semaphore.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="sem_t sem;
- if (sem_init(&sem, 1, 0) == -1) return 1;
- sem_destroy(&sem);"
-. auto/feature
-
-
-if [ $ngx_found = no ]; then
-
- # Linux has POSIX semaphores in libpthread
- ngx_feature="POSIX semaphores in libpthread"
- ngx_feature_libs=-lpthread
- . auto/feature
-
- if [ $ngx_found = yes ]; then
- CORE_LIBS="$CORE_LIBS -lpthread"
- fi
-fi
-
-
-if [ $ngx_found = no ]; then
-
- # Solaris has POSIX semaphores in librt
- ngx_feature="POSIX semaphores in librt"
- ngx_feature_libs=-lrt
- . auto/feature
-
- if [ $ngx_found = yes ]; then
- CORE_LIBS="$CORE_LIBS -lrt"
- fi
-fi
-
-
-ngx_feature="struct msghdr.msg_control"
-ngx_feature_name="NGX_HAVE_MSGHDR_MSG_CONTROL"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/socket.h>
- #include <stdio.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="struct msghdr msg;
- printf(\"%d\", (int) sizeof(msg.msg_control))"
-. auto/feature
-
-
-ngx_feature="ioctl(FIONBIO)"
-ngx_feature_name="NGX_HAVE_FIONBIO"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/ioctl.h>
- #include <stdio.h>
- $NGX_INCLUDE_SYS_FILIO_H"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="int i = FIONBIO; printf(\"%d\", i)"
-. auto/feature
-
-
-ngx_feature="struct tm.tm_gmtoff"
-ngx_feature_name="NGX_HAVE_GMTOFF"
-ngx_feature_run=no
-ngx_feature_incs="#include <time.h>
- #include <stdio.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="struct tm tm; tm.tm_gmtoff = 0;
- printf(\"%d\", (int) tm.tm_gmtoff)"
-. auto/feature
-
-
-ngx_feature="struct dirent.d_namlen"
-ngx_feature_name="NGX_HAVE_D_NAMLEN"
-ngx_feature_run=no
-ngx_feature_incs="#include <dirent.h>
- #include <stdio.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="struct dirent dir; dir.d_namlen = 0;
- printf(\"%d\", (int) dir.d_namlen)"
-. auto/feature
-
-
-ngx_feature="struct dirent.d_type"
-ngx_feature_name="NGX_HAVE_D_TYPE"
-ngx_feature_run=no
-ngx_feature_incs="#include <dirent.h>
- #include <stdio.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="struct dirent dir; dir.d_type = DT_REG;
- printf(\"%d\", (int) dir.d_type)"
-. auto/feature
-
-
-ngx_feature="sysconf(_SC_NPROCESSORS_ONLN)"
-ngx_feature_name="NGX_HAVE_SC_NPROCESSORS_ONLN"
-ngx_feature_run=no
-ngx_feature_incs=
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="sysconf(_SC_NPROCESSORS_ONLN)"
-. auto/feature
-
-
-ngx_feature="openat(), fstatat()"
-ngx_feature_name="NGX_HAVE_OPENAT"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="struct stat sb;
- openat(AT_FDCWD, \".\", O_RDONLY|O_NOFOLLOW);
- fstatat(AT_FDCWD, \".\", &sb, AT_SYMLINK_NOFOLLOW);"
-. auto/feature
-
-
-ngx_feature="getaddrinfo()"
-ngx_feature_name="NGX_HAVE_GETADDRINFO"
-ngx_feature_run=no
-ngx_feature_incs="#include <sys/types.h>
- #include <sys/socket.h>
- #include <netdb.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test='struct addrinfo *res;
- if (getaddrinfo("localhost", NULL, NULL, &res) != 0) return 1;
- freeaddrinfo(res)'
-. auto/feature
diff --git a/usr.sbin/nginx/conf/fastcgi.conf b/usr.sbin/nginx/conf/fastcgi.conf
deleted file mode 100644
index ac9ff92049f..00000000000
--- a/usr.sbin/nginx/conf/fastcgi.conf
+++ /dev/null
@@ -1,25 +0,0 @@
-
-fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
-fastcgi_param QUERY_STRING $query_string;
-fastcgi_param REQUEST_METHOD $request_method;
-fastcgi_param CONTENT_TYPE $content_type;
-fastcgi_param CONTENT_LENGTH $content_length;
-
-fastcgi_param SCRIPT_NAME $fastcgi_script_name;
-fastcgi_param REQUEST_URI $request_uri;
-fastcgi_param DOCUMENT_URI $document_uri;
-fastcgi_param DOCUMENT_ROOT $document_root;
-fastcgi_param SERVER_PROTOCOL $server_protocol;
-fastcgi_param HTTPS $https if_not_empty;
-
-fastcgi_param GATEWAY_INTERFACE CGI/1.1;
-fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
-
-fastcgi_param REMOTE_ADDR $remote_addr;
-fastcgi_param REMOTE_PORT $remote_port;
-fastcgi_param SERVER_ADDR $server_addr;
-fastcgi_param SERVER_PORT $server_port;
-fastcgi_param SERVER_NAME $server_name;
-
-# PHP only, required if PHP was built with --enable-force-cgi-redirect
-fastcgi_param REDIRECT_STATUS 200;
diff --git a/usr.sbin/nginx/conf/fastcgi_params b/usr.sbin/nginx/conf/fastcgi_params
deleted file mode 100644
index 91539e1fe81..00000000000
--- a/usr.sbin/nginx/conf/fastcgi_params
+++ /dev/null
@@ -1,25 +0,0 @@
-# $OpenBSD: fastcgi_params,v 1.3 2012/10/30 13:00:35 ajacoutot Exp $
-
-fastcgi_param QUERY_STRING $query_string;
-fastcgi_param REQUEST_METHOD $request_method;
-fastcgi_param CONTENT_TYPE $content_type;
-fastcgi_param CONTENT_LENGTH $content_length;
-
-fastcgi_param SCRIPT_NAME $fastcgi_script_name;
-fastcgi_param REQUEST_URI $request_uri;
-fastcgi_param DOCUMENT_URI $document_uri;
-fastcgi_param DOCUMENT_ROOT $document_root;
-fastcgi_param SERVER_PROTOCOL $server_protocol;
-fastcgi_param HTTPS $https if_not_empty;
-
-fastcgi_param GATEWAY_INTERFACE CGI/1.1;
-fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
-
-fastcgi_param REMOTE_ADDR $remote_addr;
-fastcgi_param REMOTE_PORT $remote_port;
-fastcgi_param SERVER_ADDR $server_addr;
-fastcgi_param SERVER_PORT $server_port;
-fastcgi_param SERVER_NAME $server_name;
-
-# PHP only, required if PHP was built with --enable-force-cgi-redirect
-fastcgi_param REDIRECT_STATUS 200;
diff --git a/usr.sbin/nginx/conf/koi-utf b/usr.sbin/nginx/conf/koi-utf
deleted file mode 100644
index 21b06dd8e56..00000000000
--- a/usr.sbin/nginx/conf/koi-utf
+++ /dev/null
@@ -1,110 +0,0 @@
-# $OpenBSD: koi-utf,v 1.2 2012/10/30 13:00:35 ajacoutot Exp $
-
-# This map is not a full koi8-r <> utf8 map: it does not contain
-# box-drawing and some other characters. Besides this map contains
-# several koi8-u and Byelorussian letters which are not in koi8-r.
-# If you need a full and standard map, use contrib/unicode2nginx/koi-utf
-# map instead.
-
-charset_map koi8-r utf-8 {
-
- 80 E282AC ; # euro
-
- 95 E280A2 ; # bullet
-
- 9A C2A0 ; # &nbsp;
-
- 9E C2B7 ; # &middot;
-
- A3 D191 ; # small yo
- A4 D194 ; # small Ukrainian ye
-
- A6 D196 ; # small Ukrainian i
- A7 D197 ; # small Ukrainian yi
-
- AD D291 ; # small Ukrainian soft g
- AE D19E ; # small Byelorussian short u
-
- B0 C2B0 ; # &deg;
-
- B3 D081 ; # capital YO
- B4 D084 ; # capital Ukrainian YE
-
- B6 D086 ; # capital Ukrainian I
- B7 D087 ; # capital Ukrainian YI
-
- B9 E28496 ; # numero sign
-
- BD D290 ; # capital Ukrainian soft G
- BE D18E ; # capital Byelorussian short U
-
- BF C2A9 ; # (C)
-
- C0 D18E ; # small yu
- C1 D0B0 ; # small a
- C2 D0B1 ; # small b
- C3 D186 ; # small ts
- C4 D0B4 ; # small d
- C5 D0B5 ; # small ye
- C6 D184 ; # small f
- C7 D0B3 ; # small g
- C8 D185 ; # small kh
- C9 D0B8 ; # small i
- CA D0B9 ; # small j
- CB D0BA ; # small k
- CC D0BB ; # small l
- CD D0BC ; # small m
- CE D0BD ; # small n
- CF D0BE ; # small o
-
- D0 D0BF ; # small p
- D1 D18F ; # small ya
- D2 D180 ; # small r
- D3 D181 ; # small s
- D4 D182 ; # small t
- D5 D183 ; # small u
- D6 D0B6 ; # small zh
- D7 D0B2 ; # small v
- D8 D18C ; # small soft sign
- D9 D18B ; # small y
- DA D0B7 ; # small z
- DB D188 ; # small sh
- DC D18D ; # small e
- DD D189 ; # small shch
- DE D187 ; # small ch
- DF D18A ; # small hard sign
-
- E0 D0AE ; # capital YU
- E1 D090 ; # capital A
- E2 D091 ; # capital B
- E3 D0A6 ; # capital TS
- E4 D094 ; # capital D
- E5 D095 ; # capital YE
- E6 D0A4 ; # capital F
- E7 D093 ; # capital G
- E8 D0A5 ; # capital KH
- E9 D098 ; # capital I
- EA D099 ; # capital J
- EB D09A ; # capital K
- EC D09B ; # capital L
- ED D09C ; # capital M
- EE D09D ; # capital N
- EF D09E ; # capital O
-
- F0 D09F ; # capital P
- F1 D0AF ; # capital YA
- F2 D0A0 ; # capital R
- F3 D0A1 ; # capital S
- F4 D0A2 ; # capital T
- F5 D0A3 ; # capital U
- F6 D096 ; # capital ZH
- F7 D092 ; # capital V
- F8 D0AC ; # capital soft sign
- F9 D0AB ; # capital Y
- FA D097 ; # capital Z
- FB D0A8 ; # capital SH
- FC D0AD ; # capital E
- FD D0A9 ; # capital SHCH
- FE D0A7 ; # capital CH
- FF D0AA ; # capital hard sign
-}
diff --git a/usr.sbin/nginx/conf/koi-win b/usr.sbin/nginx/conf/koi-win
deleted file mode 100644
index 2370ec84844..00000000000
--- a/usr.sbin/nginx/conf/koi-win
+++ /dev/null
@@ -1,104 +0,0 @@
-# $OpenBSD: koi-win,v 1.2 2012/10/30 13:00:35 ajacoutot Exp $
-
-charset_map koi8-r windows-1251 {
-
- 80 88 ; # euro
-
- 95 95 ; # bullet
-
- 9A A0 ; # &nbsp;
-
- 9E B7 ; # &middot;
-
- A3 B8 ; # small yo
- A4 BA ; # small Ukrainian ye
-
- A6 B3 ; # small Ukrainian i
- A7 BF ; # small Ukrainian yi
-
- AD B4 ; # small Ukrainian soft g
- AE A2 ; # small Byelorussian short u
-
- B0 B0 ; # &deg;
-
- B3 A8 ; # capital YO
- B4 AA ; # capital Ukrainian YE
-
- B6 B2 ; # capital Ukrainian I
- B7 AF ; # capital Ukrainian YI
-
- B9 B9 ; # numero sign
-
- BD A5 ; # capital Ukrainian soft G
- BE A1 ; # capital Byelorussian short U
-
- BF A9 ; # (C)
-
- C0 FE ; # small yu
- C1 E0 ; # small a
- C2 E1 ; # small b
- C3 F6 ; # small ts
- C4 E4 ; # small d
- C5 E5 ; # small ye
- C6 F4 ; # small f
- C7 E3 ; # small g
- C8 F5 ; # small kh
- C9 E8 ; # small i
- CA E9 ; # small j
- CB EA ; # small k
- CC EB ; # small l
- CD EC ; # small m
- CE ED ; # small n
- CF EE ; # small o
-
- D0 EF ; # small p
- D1 FF ; # small ya
- D2 F0 ; # small r
- D3 F1 ; # small s
- D4 F2 ; # small t
- D5 F3 ; # small u
- D6 E6 ; # small zh
- D7 E2 ; # small v
- D8 FC ; # small soft sign
- D9 FB ; # small y
- DA E7 ; # small z
- DB F8 ; # small sh
- DC FD ; # small e
- DD F9 ; # small shch
- DE F7 ; # small ch
- DF FA ; # small hard sign
-
- E0 DE ; # capital YU
- E1 C0 ; # capital A
- E2 C1 ; # capital B
- E3 D6 ; # capital TS
- E4 C4 ; # capital D
- E5 C5 ; # capital YE
- E6 D4 ; # capital F
- E7 C3 ; # capital G
- E8 D5 ; # capital KH
- E9 C8 ; # capital I
- EA C9 ; # capital J
- EB CA ; # capital K
- EC CB ; # capital L
- ED CC ; # capital M
- EE CD ; # capital N
- EF CE ; # capital O
-
- F0 CF ; # capital P
- F1 DF ; # capital YA
- F2 D0 ; # capital R
- F3 D1 ; # capital S
- F4 D2 ; # capital T
- F5 D3 ; # capital U
- F6 C6 ; # capital ZH
- F7 C2 ; # capital V
- F8 DC ; # capital soft sign
- F9 DB ; # capital Y
- FA C7 ; # capital Z
- FB D8 ; # capital SH
- FC DD ; # capital E
- FD D9 ; # capital SHCH
- FE D7 ; # capital CH
- FF DA ; # capital hard sign
-}
diff --git a/usr.sbin/nginx/conf/mime.types b/usr.sbin/nginx/conf/mime.types
deleted file mode 100644
index 4f428ab6522..00000000000
--- a/usr.sbin/nginx/conf/mime.types
+++ /dev/null
@@ -1,105 +0,0 @@
-# $OpenBSD: mime.types,v 1.8 2014/06/13 20:53:17 robert Exp $
-
-types {
- text/html html htm shtml;
- text/css css;
- text/xml xml;
- image/gif gif;
- image/jpeg jpeg jpg;
- application/javascript js;
- application/atom+xml atom;
- application/rss+xml rss;
-
- text/mathml mml;
- text/plain txt;
- text/vnd.sun.j2me.app-descriptor jad;
- text/vnd.wap.wml wml;
- text/x-component htc;
-
- image/png png;
- image/tiff tif tiff;
- image/vnd.wap.wbmp wbmp;
- image/x-icon ico;
- image/x-jng jng;
- image/x-ms-bmp bmp;
- image/svg+xml svg svgz;
- image/webp webp;
-
- application/font-woff woff;
- application/java-archive jar war ear;
- application/json json;
- application/mac-binhex40 hqx;
- application/msword doc;
- application/pdf pdf;
- application/postscript ps eps ai;
- application/rtf rtf;
- application/vnd.apple.mpegurl m3u8;
- application/vnd.ms-excel xls;
- application/vnd.ms-fontobject eot;
- application/vnd.ms-powerpoint ppt;
- application/vnd.wap.wmlc wmlc;
- application/vnd.google-earth.kml+xml kml;
- application/vnd.google-earth.kmz kmz;
- application/x-7z-compressed 7z;
- application/x-cocoa cco;
- application/x-java-archive-diff jardiff;
- application/x-java-jnlp-file jnlp;
- application/x-makeself run;
- application/x-ns-proxy-autoconfig pac;
- application/x-perl pl pm;
- application/x-pilot prc pdb;
- application/x-rar-compressed rar;
- application/x-redhat-package-manager rpm;
- application/x-sea sea;
- application/x-shockwave-flash swf;
- application/x-stuffit sit;
- application/x-tcl tcl tk;
- application/x-x509-ca-cert der pem crt;
- application/x-xpinstall xpi;
- application/xhtml+xml xhtml;
- application/zip zip;
-
- application/vnd.oasis.opendocument.chart odc;
- application/vnd.oasis.opendocument.chart-template otc;
- application/vnd.oasis.opendocument.database odb;
- application/vnd.oasis.opendocument.formula odf;
- application/vnd.oasis.opendocument.formula-template otf;
- application/vnd.oasis.opendocument.graphics odg;
- application/vnd.oasis.opendocument.graphics-template otg;
- application/vnd.oasis.opendocument.image odi;
- application/vnd.oasis.opendocument.image-template oti;
- application/vnd.oasis.opendocument.presentation odp;
- application/vnd.oasis.opendocument.presentation-template otp;
- application/vnd.oasis.opendocument.spreadsheet ods;
- application/vnd.oasis.opendocument.spreadsheet-template ots;
- application/vnd.oasis.opendocument.text odt;
- application/vnd.oasis.opendocument.text-master odm;
- application/vnd.oasis.opendocument.text-template ott;
- application/vnd.oasis.opendocument.text-web oth;
-
- application/octet-stream bin exe dll;
- application/octet-stream deb;
- application/octet-stream dmg;
- application/octet-stream iso img;
- application/octet-stream msi msp msm;
-
- audio/basic au snd;
- audio/midi mid midi kar;
- audio/mpeg mp3;
- audio/ogg ogg;
- audio/x-m4a m4a;
- audio/x-realaudio ra;
-
- video/3gpp 3gpp 3gp;
- video/mp2t ts;
- video/mp4 mp4;
- video/mpeg mpeg mpg;
- video/quicktime mov;
- video/webm webm;
- video/x-flv flv;
- video/x-m4v m4v;
- video/x-mng mng;
- video/x-ms-asf asx asf;
- video/x-ms-wmv wmv;
- video/x-msvideo avi;
-}
diff --git a/usr.sbin/nginx/conf/nginx.conf b/usr.sbin/nginx/conf/nginx.conf
deleted file mode 100644
index ee8d684a47f..00000000000
--- a/usr.sbin/nginx/conf/nginx.conf
+++ /dev/null
@@ -1,123 +0,0 @@
-# $OpenBSD: nginx.conf,v 1.20 2014/06/12 15:27:08 robert Exp $
-
-# Take note of http://wiki.nginx.org/Pitfalls
-
-#user www;
-worker_processes 1;
-
-#error_log logs/error.log;
-#error_log logs/error.log notice;
-#error_log logs/error.log info;
-#error_log syslog:server=unix:/dev/log,severity=notice;
-
-#pid logs/nginx.pid;
-
-worker_rlimit_nofile 1024;
-events {
- worker_connections 800;
-}
-
-
-http {
- include mime.types;
- default_type application/octet-stream;
- index index.html index.htm;
-
- #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
- # '$status $body_bytes_sent "$http_referer" '
- # '"$http_user_agent" "$http_x_forwarded_for"';
-
- #access_log logs/access.log main;
- #access_log syslog:server=unix:/dev/log,severity=notice main;
-
- #tcp_nopush on;
-
- #keepalive_timeout 0;
- keepalive_timeout 65;
-
- #gzip on;
-
- server_tokens off;
-
- server {
- listen 80;
- listen [::]:80;
- server_name localhost;
- root /var/www/htdocs;
-
- #charset koi8-r;
-
- #access_log logs/host.access.log main;
-
- #error_page 404 /404.html;
-
- # redirect server error pages to the static page /50x.html
- #
- error_page 500 502 503 504 /50x.html;
- location = /50x.html {
- root /var/www/htdocs;
- }
-
- # FastCGI to CGI wrapper server
- #
- #location /cgi-bin/ {
- # fastcgi_pass unix:run/slowcgi.sock;
- # fastcgi_split_path_info ^(/cgi-bin/[^/]+)(.*);
- # fastcgi_param PATH_INFO $fastcgi_path_info;
- # include fastcgi_params;
- #}
-
- # proxy the PHP scripts to Apache listening on 127.0.0.1:80
- #
- #location ~ \.php$ {
- # proxy_pass http://127.0.0.1;
- #}
-
- # pass the PHP scripts to FastCGI server listening on unix socket
- #
- #location ~ \.php$ {
- # try_files $uri $uri/ =404;
- # fastcgi_pass unix:run/php-fpm.sock;
- # fastcgi_index index.php;
- # fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
- # include fastcgi_params;
- #}
-
- # deny access to .htaccess files, if Apache's document root
- # concurs with nginx's one
- #
- #location ~ /\.ht {
- # deny all;
- #}
- }
-
-
- # another virtual host using mix of IP-, name-, and port-based configuration
- #
- #server {
- # listen 8000;
- # listen somename:8080;
- # server_name somename alias another.alias;
- # root /var/www/htdocs;
- #}
-
-
- # HTTPS server
- #
- #server {
- # listen 443;
- # server_name localhost;
- # root /var/www/htdocs;
-
- # ssl on;
- # ssl_certificate /etc/ssl/server.crt;
- # ssl_certificate_key /etc/ssl/private/server.key;
-
- # ssl_session_timeout 5m;
- # ssl_session_cache shared:SSL:1m;
-
- # ssl_ciphers HIGH:!aNULL:!MD5:!RC4;
- # ssl_prefer_server_ciphers on;
- #}
-
-}
diff --git a/usr.sbin/nginx/conf/scgi_params b/usr.sbin/nginx/conf/scgi_params
deleted file mode 100644
index 5d45ba88047..00000000000
--- a/usr.sbin/nginx/conf/scgi_params
+++ /dev/null
@@ -1,17 +0,0 @@
-# $OpenBSD: scgi_params,v 1.3 2012/10/30 13:00:35 ajacoutot Exp $
-
-scgi_param REQUEST_METHOD $request_method;
-scgi_param REQUEST_URI $request_uri;
-scgi_param QUERY_STRING $query_string;
-scgi_param CONTENT_TYPE $content_type;
-
-scgi_param DOCUMENT_URI $document_uri;
-scgi_param DOCUMENT_ROOT $document_root;
-scgi_param SCGI 1;
-scgi_param SERVER_PROTOCOL $server_protocol;
-scgi_param HTTPS $https if_not_empty;
-
-scgi_param REMOTE_ADDR $remote_addr;
-scgi_param REMOTE_PORT $remote_port;
-scgi_param SERVER_PORT $server_port;
-scgi_param SERVER_NAME $server_name;
diff --git a/usr.sbin/nginx/conf/uwsgi_params b/usr.sbin/nginx/conf/uwsgi_params
deleted file mode 100644
index 17fb1096bf6..00000000000
--- a/usr.sbin/nginx/conf/uwsgi_params
+++ /dev/null
@@ -1,17 +0,0 @@
-# $OpenBSD: uwsgi_params,v 1.3 2012/10/30 13:00:35 ajacoutot Exp $
-
-uwsgi_param QUERY_STRING $query_string;
-uwsgi_param REQUEST_METHOD $request_method;
-uwsgi_param CONTENT_TYPE $content_type;
-uwsgi_param CONTENT_LENGTH $content_length;
-
-uwsgi_param REQUEST_URI $request_uri;
-uwsgi_param PATH_INFO $document_uri;
-uwsgi_param DOCUMENT_ROOT $document_root;
-uwsgi_param SERVER_PROTOCOL $server_protocol;
-uwsgi_param HTTPS $https if_not_empty;
-
-uwsgi_param REMOTE_ADDR $remote_addr;
-uwsgi_param REMOTE_PORT $remote_port;
-uwsgi_param SERVER_PORT $server_port;
-uwsgi_param SERVER_NAME $server_name;
diff --git a/usr.sbin/nginx/conf/win-utf b/usr.sbin/nginx/conf/win-utf
deleted file mode 100644
index 3afe3a40117..00000000000
--- a/usr.sbin/nginx/conf/win-utf
+++ /dev/null
@@ -1,127 +0,0 @@
-# $OpenBSD: win-utf,v 1.2 2012/10/30 13:00:35 ajacoutot Exp $
-
-# This map is not a full windows-1251 <> utf8 map: it does not
-# contain Serbian and Macedonian letters. If you need a full map,
-# use contrib/unicode2nginx/win-utf map instead.
-
-charset_map windows-1251 utf-8 {
-
- 82 E2809A ; # single low-9 quotation mark
-
- 84 E2809E ; # double low-9 quotation mark
- 85 E280A6 ; # ellipsis
- 86 E280A0 ; # dagger
- 87 E280A1 ; # double dagger
- 88 E282AC ; # euro
- 89 E280B0 ; # per mille
-
- 91 E28098 ; # left single quotation mark
- 92 E28099 ; # right single quotation mark
- 93 E2809C ; # left double quotation mark
- 94 E2809D ; # right double quotation mark
- 95 E280A2 ; # bullet
- 96 E28093 ; # en dash
- 97 E28094 ; # em dash
-
- 99 E284A2 ; # trade mark sign
-
- A0 C2A0 ; # &nbsp;
- A1 D18E ; # capital Byelorussian short U
- A2 D19E ; # small Byelorussian short u
-
- A4 C2A4 ; # currency sign
- A5 D290 ; # capital Ukrainian soft G
- A6 C2A6 ; # borken bar
- A7 C2A7 ; # section sign
- A8 D081 ; # capital YO
- A9 C2A9 ; # (C)
- AA D084 ; # capital Ukrainian YE
- AB C2AB ; # left-pointing double angle quotation mark
- AC C2AC ; # not sign
- AD C2AD ; # soft hypen
- AE C2AE ; # (R)
- AF D087 ; # capital Ukrainian YI
-
- B0 C2B0 ; # &deg;
- B1 C2B1 ; # plus-minus sign
- B2 D086 ; # capital Ukrainian I
- B3 D196 ; # small Ukrainian i
- B4 D291 ; # small Ukrainian soft g
- B5 C2B5 ; # micro sign
- B6 C2B6 ; # pilcrow sign
- B7 C2B7 ; # &middot;
- B8 D191 ; # small yo
- B9 E28496 ; # numero sign
- BA D194 ; # small Ukrainian ye
- BB C2BB ; # right-pointing double angle quotation mark
-
- BF D197 ; # small Ukrainian yi
-
- C0 D090 ; # capital A
- C1 D091 ; # capital B
- C2 D092 ; # capital V
- C3 D093 ; # capital G
- C4 D094 ; # capital D
- C5 D095 ; # capital YE
- C6 D096 ; # capital ZH
- C7 D097 ; # capital Z
- C8 D098 ; # capital I
- C9 D099 ; # capital J
- CA D09A ; # capital K
- CB D09B ; # capital L
- CC D09C ; # capital M
- CD D09D ; # capital N
- CE D09E ; # capital O
- CF D09F ; # capital P
-
- D0 D0A0 ; # capital R
- D1 D0A1 ; # capital S
- D2 D0A2 ; # capital T
- D3 D0A3 ; # capital U
- D4 D0A4 ; # capital F
- D5 D0A5 ; # capital KH
- D6 D0A6 ; # capital TS
- D7 D0A7 ; # capital CH
- D8 D0A8 ; # capital SH
- D9 D0A9 ; # capital SHCH
- DA D0AA ; # capital hard sign
- DB D0AB ; # capital Y
- DC D0AC ; # capital soft sign
- DD D0AD ; # capital E
- DE D0AE ; # capital YU
- DF D0AF ; # capital YA
-
- E0 D0B0 ; # small a
- E1 D0B1 ; # small b
- E2 D0B2 ; # small v
- E3 D0B3 ; # small g
- E4 D0B4 ; # small d
- E5 D0B5 ; # small ye
- E6 D0B6 ; # small zh
- E7 D0B7 ; # small z
- E8 D0B8 ; # small i
- E9 D0B9 ; # small j
- EA D0BA ; # small k
- EB D0BB ; # small l
- EC D0BC ; # small m
- ED D0BD ; # small n
- EE D0BE ; # small o
- EF D0BF ; # small p
-
- F0 D180 ; # small r
- F1 D181 ; # small s
- F2 D182 ; # small t
- F3 D183 ; # small u
- F4 D184 ; # small f
- F5 D185 ; # small kh
- F6 D186 ; # small ts
- F7 D187 ; # small ch
- F8 D188 ; # small sh
- F9 D189 ; # small shch
- FA D18A ; # small hard sign
- FB D18B ; # small y
- FC D18C ; # small soft sign
- FD D18D ; # small e
- FE D18E ; # small yu
- FF D18F ; # small ya
-}
diff --git a/usr.sbin/nginx/configure b/usr.sbin/nginx/configure
deleted file mode 100644
index d7d8189af93..00000000000
--- a/usr.sbin/nginx/configure
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/bin/sh
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-
-LC_ALL=C
-export LC_ALL
-
-. auto/options
-. auto/init
-. auto/sources
-
-test -d $NGX_OBJS || mkdir $NGX_OBJS
-
-echo > $NGX_AUTO_HEADERS_H
-echo > $NGX_AUTOCONF_ERR
-
-echo "#define NGX_CONFIGURE \"$NGX_CONFIGURE\"" > $NGX_AUTO_CONFIG_H
-
-
-if [ $NGX_DEBUG = YES ]; then
- have=NGX_DEBUG . auto/have
-fi
-
-
-if test -z "$NGX_PLATFORM"; then
- echo "checking for OS"
-
- NGX_SYSTEM=`uname -s 2>/dev/null`
- NGX_RELEASE=`uname -r 2>/dev/null`
- NGX_MACHINE=`uname -m 2>/dev/null`
-
- echo " + $NGX_SYSTEM $NGX_RELEASE $NGX_MACHINE"
-
- NGX_PLATFORM="$NGX_SYSTEM:$NGX_RELEASE:$NGX_MACHINE";
-
- case "$NGX_SYSTEM" in
- MINGW32_*)
- NGX_PLATFORM=win32
- ;;
- esac
-
-else
- echo "building for $NGX_PLATFORM"
- NGX_SYSTEM=$NGX_PLATFORM
-fi
-
-. auto/cc/conf
-
-if [ "$NGX_PLATFORM" != win32 ]; then
- . auto/headers
-fi
-
-. auto/os/conf
-
-if [ "$NGX_PLATFORM" != win32 ]; then
- . auto/unix
-fi
-
-. auto/modules
-. auto/lib/conf
-
-case ".$NGX_PREFIX" in
- .)
- NGX_PREFIX=${NGX_PREFIX:-/usr/local/nginx}
- have=NGX_PREFIX value="\"$NGX_PREFIX/\"" . auto/define
- ;;
-
- .!)
- NGX_PREFIX=
- ;;
-
- *)
- have=NGX_PREFIX value="\"$NGX_PREFIX/\"" . auto/define
- ;;
-esac
-
-if [ ".$NGX_CONF_PREFIX" != "." ]; then
- have=NGX_CONF_PREFIX value="\"$NGX_CONF_PREFIX/\"" . auto/define
-fi
-
-have=NGX_SBIN_PATH value="\"$NGX_SBIN_PATH\"" . auto/define
-have=NGX_CONF_PATH value="\"$NGX_CONF_PATH\"" . auto/define
-have=NGX_PID_PATH value="\"$NGX_PID_PATH\"" . auto/define
-have=NGX_LOCK_PATH value="\"$NGX_LOCK_PATH\"" . auto/define
-have=NGX_ERROR_LOG_PATH value="\"$NGX_ERROR_LOG_PATH\"" . auto/define
-
-have=NGX_HTTP_LOG_PATH value="\"$NGX_HTTP_LOG_PATH\"" . auto/define
-have=NGX_HTTP_CLIENT_TEMP_PATH value="\"$NGX_HTTP_CLIENT_TEMP_PATH\""
-. auto/define
-have=NGX_HTTP_PROXY_TEMP_PATH value="\"$NGX_HTTP_PROXY_TEMP_PATH\""
-. auto/define
-have=NGX_HTTP_FASTCGI_TEMP_PATH value="\"$NGX_HTTP_FASTCGI_TEMP_PATH\""
-. auto/define
-have=NGX_HTTP_UWSGI_TEMP_PATH value="\"$NGX_HTTP_UWSGI_TEMP_PATH\""
-. auto/define
-have=NGX_HTTP_SCGI_TEMP_PATH value="\"$NGX_HTTP_SCGI_TEMP_PATH\""
-. auto/define
-
-. auto/make
-. auto/lib/make
-. auto/install
-
-# STUB
-. auto/stubs
-
-have=NGX_USER value="\"$NGX_USER\"" . auto/define
-have=NGX_GROUP value="\"$NGX_GROUP\"" . auto/define
-
-. auto/summary
diff --git a/usr.sbin/nginx/contrib/README b/usr.sbin/nginx/contrib/README
deleted file mode 100644
index fec4b200863..00000000000
--- a/usr.sbin/nginx/contrib/README
+++ /dev/null
@@ -1,21 +0,0 @@
-
-geo2nginx.pl by Andrei Nigmatulin
-
- The perl script to convert CSV geoip database ( free download
- at http://www.maxmind.com/app/geoip_country ) to format, suitable
- for use by the ngx_http_geo_module.
-
-
-unicode2nginx by Maxim Dounin
-
- The perl script to convert unicode mappings ( available
- at http://www.unicode.org/Public/MAPPINGS/ ) to the nginx
- configuration file format.
- Two generated full maps for windows-1251 and koi8-r.
-
-
-vim by Evan Miller
-
- Syntax highlighting of nginx configuration for vim, to be
- placed into ~/.vim/.
-
diff --git a/usr.sbin/nginx/contrib/geo2nginx.pl b/usr.sbin/nginx/contrib/geo2nginx.pl
deleted file mode 100644
index 29243ecf2b2..00000000000
--- a/usr.sbin/nginx/contrib/geo2nginx.pl
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/perl -w
-
-# (c) Andrei Nigmatulin, 2005
-#
-# this script provided "as is", without any warranties. use it at your own risk.
-#
-# special thanx to Andrew Sitnikov for perl port
-#
-# this script converts CSV geoip database (free download at http://www.maxmind.com/app/geoip_country)
-# to format, suitable for use with nginx_http_geo module (http://sysoev.ru/nginx)
-#
-# for example, line with ip range
-#
-# "62.16.68.0","62.16.127.255","1041253376","1041268735","RU","Russian Federation"
-#
-# will be converted to four subnetworks:
-#
-# 62.16.68.0/22 RU;
-# 62.16.72.0/21 RU;
-# 62.16.80.0/20 RU;
-# 62.16.96.0/19 RU;
-
-
-use warnings;
-use strict;
-
-while( <STDIN> ){
- if (/"[^"]+","[^"]+","([^"]+)","([^"]+)","([^"]+)"/){
- print_subnets($1, $2, $3);
- }
-}
-
-sub print_subnets {
- my ($a1, $a2, $c) = @_;
- my $l;
- while ($a1 <= $a2) {
- for ($l = 0; ($a1 & (1 << $l)) == 0 && ($a1 + ((1 << ($l + 1)) - 1)) <= $a2; $l++){};
- print long2ip($a1) . "/" . (32 - $l) . " " . $c . ";\n";
- $a1 += (1 << $l);
- }
-}
-
-sub long2ip {
- my $ip = shift;
-
- my $str = 0;
-
- $str = ($ip & 255);
-
- $ip >>= 8;
- $str = ($ip & 255).".$str";
-
- $ip >>= 8;
- $str = ($ip & 255).".$str";
-
- $ip >>= 8;
- $str = ($ip & 255).".$str";
-}
diff --git a/usr.sbin/nginx/contrib/unicode2nginx/koi-utf b/usr.sbin/nginx/contrib/unicode2nginx/koi-utf
deleted file mode 100644
index 48853af9af9..00000000000
--- a/usr.sbin/nginx/contrib/unicode2nginx/koi-utf
+++ /dev/null
@@ -1,131 +0,0 @@
-charset_map koi8-r utf-8 {
-
- 80 E29480 ; # BOX DRAWINGS LIGHT HORIZONTAL
- 81 E29482 ; # BOX DRAWINGS LIGHT VERTICAL
- 82 E2948C ; # BOX DRAWINGS LIGHT DOWN AND RIGHT
- 83 E29490 ; # BOX DRAWINGS LIGHT DOWN AND LEFT
- 84 E29494 ; # BOX DRAWINGS LIGHT UP AND RIGHT
- 85 E29498 ; # BOX DRAWINGS LIGHT UP AND LEFT
- 86 E2949C ; # BOX DRAWINGS LIGHT VERTICAL AND RIGHT
- 87 E294A4 ; # BOX DRAWINGS LIGHT VERTICAL AND LEFT
- 88 E294AC ; # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
- 89 E294B4 ; # BOX DRAWINGS LIGHT UP AND HORIZONTAL
- 8A E294BC ; # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
- 8B E29680 ; # UPPER HALF BLOCK
- 8C E29684 ; # LOWER HALF BLOCK
- 8D E29688 ; # FULL BLOCK
- 8E E2968C ; # LEFT HALF BLOCK
- 8F E29690 ; # RIGHT HALF BLOCK
- 90 E29691 ; # LIGHT SHADE
- 91 E29692 ; # MEDIUM SHADE
- 92 E29693 ; # DARK SHADE
- 93 E28CA0 ; # TOP HALF INTEGRAL
- 94 E296A0 ; # BLACK SQUARE
- 95 E28899 ; # BULLET OPERATOR
- 96 E2889A ; # SQUARE ROOT
- 97 E28988 ; # ALMOST EQUAL TO
- 98 E289A4 ; # LESS-THAN OR EQUAL TO
- 99 E289A5 ; # GREATER-THAN OR EQUAL TO
- 9A C2A0 ; # NO-BREAK SPACE
- 9B E28CA1 ; # BOTTOM HALF INTEGRAL
- 9C C2B0 ; # DEGREE SIGN
- 9D C2B2 ; # SUPERSCRIPT TWO
- 9E C2B7 ; # MIDDLE DOT
- 9F C3B7 ; # DIVISION SIGN
- A0 E29590 ; # BOX DRAWINGS DOUBLE HORIZONTAL
- A1 E29591 ; # BOX DRAWINGS DOUBLE VERTICAL
- A2 E29592 ; # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
- A3 D191 ; # CYRILLIC SMALL LETTER IO
- A4 E29593 ; # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
- A5 E29594 ; # BOX DRAWINGS DOUBLE DOWN AND RIGHT
- A6 E29595 ; # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
- A7 E29596 ; # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
- A8 E29597 ; # BOX DRAWINGS DOUBLE DOWN AND LEFT
- A9 E29598 ; # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
- AA E29599 ; # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
- AB E2959A ; # BOX DRAWINGS DOUBLE UP AND RIGHT
- AC E2959B ; # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
- AD E2959C ; # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
- AE E2959D ; # BOX DRAWINGS DOUBLE UP AND LEFT
- AF E2959E ; # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
- B0 E2959F ; # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
- B1 E295A0 ; # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
- B2 E295A1 ; # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
- B3 D081 ; # CYRILLIC CAPITAL LETTER IO
- B4 E295A2 ; # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
- B5 E295A3 ; # BOX DRAWINGS DOUBLE VERTICAL AND LEFT
- B6 E295A4 ; # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
- B7 E295A5 ; # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
- B8 E295A6 ; # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
- B9 E295A7 ; # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
- BA E295A8 ; # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
- BB E295A9 ; # BOX DRAWINGS DOUBLE UP AND HORIZONTAL
- BC E295AA ; # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
- BD E295AB ; # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
- BE E295AC ; # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
- BF C2A9 ; # COPYRIGHT SIGN
- C0 D18E ; # CYRILLIC SMALL LETTER YU
- C1 D0B0 ; # CYRILLIC SMALL LETTER A
- C2 D0B1 ; # CYRILLIC SMALL LETTER BE
- C3 D186 ; # CYRILLIC SMALL LETTER TSE
- C4 D0B4 ; # CYRILLIC SMALL LETTER DE
- C5 D0B5 ; # CYRILLIC SMALL LETTER IE
- C6 D184 ; # CYRILLIC SMALL LETTER EF
- C7 D0B3 ; # CYRILLIC SMALL LETTER GHE
- C8 D185 ; # CYRILLIC SMALL LETTER HA
- C9 D0B8 ; # CYRILLIC SMALL LETTER I
- CA D0B9 ; # CYRILLIC SMALL LETTER SHORT I
- CB D0BA ; # CYRILLIC SMALL LETTER KA
- CC D0BB ; # CYRILLIC SMALL LETTER EL
- CD D0BC ; # CYRILLIC SMALL LETTER EM
- CE D0BD ; # CYRILLIC SMALL LETTER EN
- CF D0BE ; # CYRILLIC SMALL LETTER O
- D0 D0BF ; # CYRILLIC SMALL LETTER PE
- D1 D18F ; # CYRILLIC SMALL LETTER YA
- D2 D180 ; # CYRILLIC SMALL LETTER ER
- D3 D181 ; # CYRILLIC SMALL LETTER ES
- D4 D182 ; # CYRILLIC SMALL LETTER TE
- D5 D183 ; # CYRILLIC SMALL LETTER U
- D6 D0B6 ; # CYRILLIC SMALL LETTER ZHE
- D7 D0B2 ; # CYRILLIC SMALL LETTER VE
- D8 D18C ; # CYRILLIC SMALL LETTER SOFT SIGN
- D9 D18B ; # CYRILLIC SMALL LETTER YERU
- DA D0B7 ; # CYRILLIC SMALL LETTER ZE
- DB D188 ; # CYRILLIC SMALL LETTER SHA
- DC D18D ; # CYRILLIC SMALL LETTER E
- DD D189 ; # CYRILLIC SMALL LETTER SHCHA
- DE D187 ; # CYRILLIC SMALL LETTER CHE
- DF D18A ; # CYRILLIC SMALL LETTER HARD SIGN
- E0 D0AE ; # CYRILLIC CAPITAL LETTER YU
- E1 D090 ; # CYRILLIC CAPITAL LETTER A
- E2 D091 ; # CYRILLIC CAPITAL LETTER BE
- E3 D0A6 ; # CYRILLIC CAPITAL LETTER TSE
- E4 D094 ; # CYRILLIC CAPITAL LETTER DE
- E5 D095 ; # CYRILLIC CAPITAL LETTER IE
- E6 D0A4 ; # CYRILLIC CAPITAL LETTER EF
- E7 D093 ; # CYRILLIC CAPITAL LETTER GHE
- E8 D0A5 ; # CYRILLIC CAPITAL LETTER HA
- E9 D098 ; # CYRILLIC CAPITAL LETTER I
- EA D099 ; # CYRILLIC CAPITAL LETTER SHORT I
- EB D09A ; # CYRILLIC CAPITAL LETTER KA
- EC D09B ; # CYRILLIC CAPITAL LETTER EL
- ED D09C ; # CYRILLIC CAPITAL LETTER EM
- EE D09D ; # CYRILLIC CAPITAL LETTER EN
- EF D09E ; # CYRILLIC CAPITAL LETTER O
- F0 D09F ; # CYRILLIC CAPITAL LETTER PE
- F1 D0AF ; # CYRILLIC CAPITAL LETTER YA
- F2 D0A0 ; # CYRILLIC CAPITAL LETTER ER
- F3 D0A1 ; # CYRILLIC CAPITAL LETTER ES
- F4 D0A2 ; # CYRILLIC CAPITAL LETTER TE
- F5 D0A3 ; # CYRILLIC CAPITAL LETTER U
- F6 D096 ; # CYRILLIC CAPITAL LETTER ZHE
- F7 D092 ; # CYRILLIC CAPITAL LETTER VE
- F8 D0AC ; # CYRILLIC CAPITAL LETTER SOFT SIGN
- F9 D0AB ; # CYRILLIC CAPITAL LETTER YERU
- FA D097 ; # CYRILLIC CAPITAL LETTER ZE
- FB D0A8 ; # CYRILLIC CAPITAL LETTER SHA
- FC D0AD ; # CYRILLIC CAPITAL LETTER E
- FD D0A9 ; # CYRILLIC CAPITAL LETTER SHCHA
- FE D0A7 ; # CYRILLIC CAPITAL LETTER CHE
- FF D0AA ; # CYRILLIC CAPITAL LETTER HARD SIGN
-}
diff --git a/usr.sbin/nginx/contrib/unicode2nginx/unicode-to-nginx.pl b/usr.sbin/nginx/contrib/unicode2nginx/unicode-to-nginx.pl
deleted file mode 100755
index daaf354a830..00000000000
--- a/usr.sbin/nginx/contrib/unicode2nginx/unicode-to-nginx.pl
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/perl -w
-
-# Convert unicode mappings to nginx configuration file format.
-
-# You may find useful mappings in various places, including
-# unicode.org official site:
-#
-# http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT
-# http://www.unicode.org/Public/MAPPINGS/VENDORS/MISC/KOI8-R.TXT
-
-# Needs perl 5.6 or later.
-
-# Written by Maxim Dounin, mdounin@rambler-co.ru
-
-###############################################################################
-
-require 5.006;
-
-while (<>) {
- # Skip comments and empty lines
-
- next if /^#/;
- next if /^\s*$/;
- chomp;
-
- # Convert mappings
-
- if (/^\s*0x(..)\s*0x(....)\s*(#.*)/) {
- # Mapping <from-code> <unicode-code> "#" <unicode-name>
- my $cs_code = $1;
- my $un_code = $2;
- my $un_name = $3;
-
- # Produce UTF-8 sequence from character code;
-
- my $un_utf8 = join('', map { sprintf("%02X", $_) } unpack("C*", pack("U", hex($un_code))));
-
- print " $cs_code $un_utf8 ; $un_name\n";
-
- } else {
- warn "Unrecognized line: '$_'";
- }
-}
-
-###############################################################################
diff --git a/usr.sbin/nginx/contrib/unicode2nginx/win-utf b/usr.sbin/nginx/contrib/unicode2nginx/win-utf
deleted file mode 100644
index af9f9aaa502..00000000000
--- a/usr.sbin/nginx/contrib/unicode2nginx/win-utf
+++ /dev/null
@@ -1,130 +0,0 @@
-charset_map windows-1251 utf-8 {
-
- 80 D082 ; #CYRILLIC CAPITAL LETTER DJE
- 81 D083 ; #CYRILLIC CAPITAL LETTER GJE
- 82 E2809A ; #SINGLE LOW-9 QUOTATION MARK
- 83 D193 ; #CYRILLIC SMALL LETTER GJE
- 84 E2809E ; #DOUBLE LOW-9 QUOTATION MARK
- 85 E280A6 ; #HORIZONTAL ELLIPSIS
- 86 E280A0 ; #DAGGER
- 87 E280A1 ; #DOUBLE DAGGER
- 88 E282AC ; #EURO SIGN
- 89 E280B0 ; #PER MILLE SIGN
- 8A D089 ; #CYRILLIC CAPITAL LETTER LJE
- 8B E280B9 ; #SINGLE LEFT-POINTING ANGLE QUOTATION MARK
- 8C D08A ; #CYRILLIC CAPITAL LETTER NJE
- 8D D08C ; #CYRILLIC CAPITAL LETTER KJE
- 8E D08B ; #CYRILLIC CAPITAL LETTER TSHE
- 8F D08F ; #CYRILLIC CAPITAL LETTER DZHE
- 90 D192 ; #CYRILLIC SMALL LETTER DJE
- 91 E28098 ; #LEFT SINGLE QUOTATION MARK
- 92 E28099 ; #RIGHT SINGLE QUOTATION MARK
- 93 E2809C ; #LEFT DOUBLE QUOTATION MARK
- 94 E2809D ; #RIGHT DOUBLE QUOTATION MARK
- 95 E280A2 ; #BULLET
- 96 E28093 ; #EN DASH
- 97 E28094 ; #EM DASH
- 99 E284A2 ; #TRADE MARK SIGN
- 9A D199 ; #CYRILLIC SMALL LETTER LJE
- 9B E280BA ; #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
- 9C D19A ; #CYRILLIC SMALL LETTER NJE
- 9D D19C ; #CYRILLIC SMALL LETTER KJE
- 9E D19B ; #CYRILLIC SMALL LETTER TSHE
- 9F D19F ; #CYRILLIC SMALL LETTER DZHE
- A0 C2A0 ; #NO-BREAK SPACE
- A1 D08E ; #CYRILLIC CAPITAL LETTER SHORT U
- A2 D19E ; #CYRILLIC SMALL LETTER SHORT U
- A3 D088 ; #CYRILLIC CAPITAL LETTER JE
- A4 C2A4 ; #CURRENCY SIGN
- A5 D290 ; #CYRILLIC CAPITAL LETTER GHE WITH UPTURN
- A6 C2A6 ; #BROKEN BAR
- A7 C2A7 ; #SECTION SIGN
- A8 D081 ; #CYRILLIC CAPITAL LETTER IO
- A9 C2A9 ; #COPYRIGHT SIGN
- AA D084 ; #CYRILLIC CAPITAL LETTER UKRAINIAN IE
- AB C2AB ; #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
- AC C2AC ; #NOT SIGN
- AD C2AD ; #SOFT HYPHEN
- AE C2AE ; #REGISTERED SIGN
- AF D087 ; #CYRILLIC CAPITAL LETTER YI
- B0 C2B0 ; #DEGREE SIGN
- B1 C2B1 ; #PLUS-MINUS SIGN
- B2 D086 ; #CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
- B3 D196 ; #CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
- B4 D291 ; #CYRILLIC SMALL LETTER GHE WITH UPTURN
- B5 C2B5 ; #MICRO SIGN
- B6 C2B6 ; #PILCROW SIGN
- B7 C2B7 ; #MIDDLE DOT
- B8 D191 ; #CYRILLIC SMALL LETTER IO
- B9 E28496 ; #NUMERO SIGN
- BA D194 ; #CYRILLIC SMALL LETTER UKRAINIAN IE
- BB C2BB ; #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
- BC D198 ; #CYRILLIC SMALL LETTER JE
- BD D085 ; #CYRILLIC CAPITAL LETTER DZE
- BE D195 ; #CYRILLIC SMALL LETTER DZE
- BF D197 ; #CYRILLIC SMALL LETTER YI
- C0 D090 ; #CYRILLIC CAPITAL LETTER A
- C1 D091 ; #CYRILLIC CAPITAL LETTER BE
- C2 D092 ; #CYRILLIC CAPITAL LETTER VE
- C3 D093 ; #CYRILLIC CAPITAL LETTER GHE
- C4 D094 ; #CYRILLIC CAPITAL LETTER DE
- C5 D095 ; #CYRILLIC CAPITAL LETTER IE
- C6 D096 ; #CYRILLIC CAPITAL LETTER ZHE
- C7 D097 ; #CYRILLIC CAPITAL LETTER ZE
- C8 D098 ; #CYRILLIC CAPITAL LETTER I
- C9 D099 ; #CYRILLIC CAPITAL LETTER SHORT I
- CA D09A ; #CYRILLIC CAPITAL LETTER KA
- CB D09B ; #CYRILLIC CAPITAL LETTER EL
- CC D09C ; #CYRILLIC CAPITAL LETTER EM
- CD D09D ; #CYRILLIC CAPITAL LETTER EN
- CE D09E ; #CYRILLIC CAPITAL LETTER O
- CF D09F ; #CYRILLIC CAPITAL LETTER PE
- D0 D0A0 ; #CYRILLIC CAPITAL LETTER ER
- D1 D0A1 ; #CYRILLIC CAPITAL LETTER ES
- D2 D0A2 ; #CYRILLIC CAPITAL LETTER TE
- D3 D0A3 ; #CYRILLIC CAPITAL LETTER U
- D4 D0A4 ; #CYRILLIC CAPITAL LETTER EF
- D5 D0A5 ; #CYRILLIC CAPITAL LETTER HA
- D6 D0A6 ; #CYRILLIC CAPITAL LETTER TSE
- D7 D0A7 ; #CYRILLIC CAPITAL LETTER CHE
- D8 D0A8 ; #CYRILLIC CAPITAL LETTER SHA
- D9 D0A9 ; #CYRILLIC CAPITAL LETTER SHCHA
- DA D0AA ; #CYRILLIC CAPITAL LETTER HARD SIGN
- DB D0AB ; #CYRILLIC CAPITAL LETTER YERU
- DC D0AC ; #CYRILLIC CAPITAL LETTER SOFT SIGN
- DD D0AD ; #CYRILLIC CAPITAL LETTER E
- DE D0AE ; #CYRILLIC CAPITAL LETTER YU
- DF D0AF ; #CYRILLIC CAPITAL LETTER YA
- E0 D0B0 ; #CYRILLIC SMALL LETTER A
- E1 D0B1 ; #CYRILLIC SMALL LETTER BE
- E2 D0B2 ; #CYRILLIC SMALL LETTER VE
- E3 D0B3 ; #CYRILLIC SMALL LETTER GHE
- E4 D0B4 ; #CYRILLIC SMALL LETTER DE
- E5 D0B5 ; #CYRILLIC SMALL LETTER IE
- E6 D0B6 ; #CYRILLIC SMALL LETTER ZHE
- E7 D0B7 ; #CYRILLIC SMALL LETTER ZE
- E8 D0B8 ; #CYRILLIC SMALL LETTER I
- E9 D0B9 ; #CYRILLIC SMALL LETTER SHORT I
- EA D0BA ; #CYRILLIC SMALL LETTER KA
- EB D0BB ; #CYRILLIC SMALL LETTER EL
- EC D0BC ; #CYRILLIC SMALL LETTER EM
- ED D0BD ; #CYRILLIC SMALL LETTER EN
- EE D0BE ; #CYRILLIC SMALL LETTER O
- EF D0BF ; #CYRILLIC SMALL LETTER PE
- F0 D180 ; #CYRILLIC SMALL LETTER ER
- F1 D181 ; #CYRILLIC SMALL LETTER ES
- F2 D182 ; #CYRILLIC SMALL LETTER TE
- F3 D183 ; #CYRILLIC SMALL LETTER U
- F4 D184 ; #CYRILLIC SMALL LETTER EF
- F5 D185 ; #CYRILLIC SMALL LETTER HA
- F6 D186 ; #CYRILLIC SMALL LETTER TSE
- F7 D187 ; #CYRILLIC SMALL LETTER CHE
- F8 D188 ; #CYRILLIC SMALL LETTER SHA
- F9 D189 ; #CYRILLIC SMALL LETTER SHCHA
- FA D18A ; #CYRILLIC SMALL LETTER HARD SIGN
- FB D18B ; #CYRILLIC SMALL LETTER YERU
- FC D18C ; #CYRILLIC SMALL LETTER SOFT SIGN
- FD D18D ; #CYRILLIC SMALL LETTER E
- FE D18E ; #CYRILLIC SMALL LETTER YU
- FF D18F ; #CYRILLIC SMALL LETTER YA
-}
diff --git a/usr.sbin/nginx/html/50x.html b/usr.sbin/nginx/html/50x.html
deleted file mode 100644
index f60f5e72d17..00000000000
--- a/usr.sbin/nginx/html/50x.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>Error</title>
-<style>
- body {
- width: 35em;
- margin: 0 auto;
- font-family: Tahoma, Verdana, Arial, sans-serif;
- }
-</style>
-</head>
-<body>
-<h1>An error occurred.</h1>
-<p>Sorry, the page you are looking for is currently unavailable.<br/>
-Please try again later.</p>
-<p>If you are the system administrator of this resource then you should check
-the <a href="http://nginx.org/r/error_log">error log</a> for details.</p>
-<p><em>Faithfully yours, nginx.</em></p>
-</body>
-</html>
diff --git a/usr.sbin/nginx/html/index.html b/usr.sbin/nginx/html/index.html
deleted file mode 100644
index 2ca3b9543c0..00000000000
--- a/usr.sbin/nginx/html/index.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>Welcome to nginx!</title>
-<style>
- body {
- width: 35em;
- margin: 0 auto;
- font-family: Tahoma, Verdana, Arial, sans-serif;
- }
-</style>
-</head>
-<body>
-<h1>Welcome to nginx!</h1>
-<p>If you see this page, the nginx web server is successfully installed and
-working. Further configuration is required.</p>
-
-<p>For online documentation and support please refer to
-<a href="http://nginx.org/">nginx.org</a>.<br/>
-Commercial support is available at
-<a href="http://nginx.com/">nginx.com</a>.</p>
-
-<p><em>Thank you for using nginx.</em></p>
-</body>
-</html>
diff --git a/usr.sbin/nginx/man/nginx.8 b/usr.sbin/nginx/man/nginx.8
deleted file mode 100644
index 5550462d776..00000000000
--- a/usr.sbin/nginx/man/nginx.8
+++ /dev/null
@@ -1,213 +0,0 @@
-.\" $OpenBSD: nginx.8,v 1.9 2014/01/27 12:30:21 jmc Exp $
-.\"
-.\" Copyright (c) 2010 Sergey A. Osokin
-.\" Copyright (c) 2011,2012 Nginx, Inc.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\"
-.Dd $Mdocdate: January 27 2014 $
-.Dt NGINX 8
-.Os
-.Sh NAME
-.Nm nginx
-.Nd HTTP and reverse proxy server, mail proxy server
-.Sh SYNOPSIS
-.Nm
-.Op Fl ?hqtuVv
-.Op Fl c Ar file
-.Op Fl g Ar directives
-.Op Fl p Ar prefix
-.Op Fl s Ar signal
-.Sh DESCRIPTION
-.Nm
-(pronounced
-.Dq engine x )
-is an HTTP and reverse proxy server, as well as a mail proxy server.
-It is known for its high performance, stability, rich feature set, simple
-configuration, and low resource consumption.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl ?\& | h
-Print help.
-.It Fl c Ar file
-Use an alternative configuration
-.Ar file .
-.It Fl g Ar directives
-Set global configuration directives.
-See
-.Sx EXAMPLES
-for details.
-.It Fl p Ar prefix
-Set the prefix path.
-The default value is
-.Pa %%PREFIX%% .
-.It Fl q
-Suppress non-error messages during configuration testing.
-.It Fl s Ar signal
-Send a signal to the master process.
-The argument
-.Ar signal
-can be one of:
-.Cm stop , quit , reopen , reload .
-The following table shows the corresponding system signals.
-.Pp
-.Bl -tag -width ".It Cm reopen" -offset indent -compact
-.It Cm stop
-.Dv SIGTERM
-.It Cm quit
-.Dv SIGQUIT
-.It Cm reopen
-.Dv SIGUSR1
-.It Cm reload
-.Dv SIGHUP
-.El
-.It Fl t
-Don't run, just test the configuration file.
-.Nm
-checks the configuration file syntax and then tries to open any files
-referred to in the configuration file.
-.It Fl u
-By default
-.Nm
-will
-.Xr chroot 2
-to the home directory of the user running the daemon,
-typically
-.Dq www ,
-or to the home directory of
-.Ic user
-in
-.Pa nginx.conf .
-The
-.Fl u
-option disables this behaviour, and returns
-.Nm
-to the original "unsecure" behaviour.
-.It Fl V
-Print the
-.Nm
-version, compiler version, and
-.Pa configure
-script parameters.
-.It Fl v
-Print the
-.Nm
-version.
-.El
-.Pp
-The master process of
-.Nm
-can handle the following signals.
-.Pp
-.Bl -tag -width ".It Dv SIGINT , SIGTERM" -compact
-.It Dv SIGINT , SIGTERM
-Shut down quickly.
-.It Dv SIGHUP
-Reload configuration, start the new worker process with a new
-configuration, and gracefully shut down old worker processes.
-.It Dv SIGQUIT
-Shut down gracefully.
-.It Dv SIGUSR1
-Reopen log files.
-.It Dv SIGUSR2
-Upgrade the
-.Nm
-executable on the fly.
-.It Dv SIGWINCH
-Shut down worker processes gracefully.
-.El
-.Pp
-While there's no need to explicitly control worker processes normally,
-they support some signals too:
-.Pp
-.Bl -tag -width ".It Dv SIGINT , SIGTERM" -compact
-.It Dv SIGTERM
-Shut down quickly.
-.It Dv SIGQUIT
-Shut down gracefully.
-.It Dv SIGUSR1
-Reopen log files.
-.El
-.Sh DEBUGGING LOG
-To enable a debugging log, reconfigure
-.Nm
-to build with debugging:
-.Pp
-.Dl "./configure --with-debug ..."
-.Pp
-and then set the
-.Cm debug
-level of the
-.Va error_log :
-.Pp
-.Dl "error_log /path/to/log debug;"
-.Pp
-It is also possible to enable the debugging for a particular IP address:
-.Bd -literal -offset indent
-events {
- debug_connection 127.0.0.1;
-}
-.Ed
-.Sh FILES
-.Bl -tag -width indent -compact
-.It Pa %%PID_PATH%%
-Contains the process ID of
-.Nm .
-The contents of this file are not sensitive, so it can be world-readable.
-.It Pa %%CONF_PATH%%
-The main configuration file.
-.It Pa %%ERROR_LOG_PATH%%
-Error log file.
-.El
-.Sh EXIT STATUS
-.Ex -std nginx
-.Sh EXAMPLES
-Test configuration file
-.Pa ~/mynginx.conf
-with global directives for PID and quantity of worker processes:
-.Bd -literal -offset indent
-nginx -t -c ~/mynginx.conf \e
- -g "pid /var/run/mynginx.pid; worker_processes 2;"
-.Ed
-.Sh SEE ALSO
-.Xr nginx.conf 5
-.Pp
-Documentation at
-.Lk http://nginx.org/en/docs/ .
-For questions and technical support, please refer to
-.Lk http://nginx.org/en/support.html .
-.Sh HISTORY
-Development of
-.Nm
-started in 2002, with the first public release on October 4, 2004.
-.Sh AUTHORS
-.An -nosplit
-.An Igor Sysoev Aq Mt igor@sysoev.ru .
-.Pp
-This manual page was written by
-.An Sergey A. Osokin Aq Mt osa@FreeBSD.org.ru
-as a result of compiling many
-.Nm
-documents from all over the world.
diff --git a/usr.sbin/nginx/man/nginx.conf.5 b/usr.sbin/nginx/man/nginx.conf.5
deleted file mode 100644
index 49e3327b031..00000000000
--- a/usr.sbin/nginx/man/nginx.conf.5
+++ /dev/null
@@ -1,8753 +0,0 @@
-.\" $OpenBSD: nginx.conf.5,v 1.8 2014/01/27 12:43:58 jmc Exp $
-.\"
-.\" Copyright (C) 2002-2012 Igor Sysoev
-.\" Copyright (C) 2011-2013 Nginx, Inc.
-.\" Copyright (C) 2013 Florian Obser <florian@openbsd.org>
-.\" Copyright (C) 2013 Ingo Schwarze <schwarze@openbsd.org>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.Dd $Mdocdate: January 27 2014 $
-.Dt NGINX.CONF 5
-.Os
-.Sh NAME
-.Nm nginx.conf
-.Nd nginx daemon configuration file
-.Sh DESCRIPTION
-.Xr nginx 8
-.Pq pronounced Dq engine x
-is an HTTP and reverse proxy server, as well as a mail proxy server.
-It is known for its high performance, stability, rich feature set, simple
-configuration, and low resource consumption.
-.Pp
-The configuration file consists of a list of configuration directives:
-.Bd -ragged -offset indent
-.Ar list
-.Li ::=
-.Op Ar directive
-.Op Ar opt-ws
-.Op Ar list
-.Ed
-.Pp
-Lists may be empty, they may contain leading and trailing whitespace
-and comments, and they may contain whitespace and comments between
-directives.
-Such whitespace is semantically insignificant.
-.Pp
-The syntax of a configuration directive is:
-.Bd -ragged -offset indent
-.Ar directive
-.Li ::=
-.Ar keyword
-.Ar ws
-.Ar arguments
-.Op Ar ws
-.Qq Li \&;
-.Li \&|
-.Ar context
-.Ed
-.Pp
-In this case, whitespace is required to separate the keyword from
-the arguments.
-A context may not be followed by a semicolon, but after every other
-directive, a semicolon is required, even at the end of a list.
-.Pp
-As a special cases of a configuration directive, the syntax of a
-configuration context is:
-.Bd -ragged -offset indent
-.Ar context
-.Li ::=
-.Ar keyword
-.Op Ar ws
-.Qq Li \&{
-.Op Ar list
-.Qq Li \&}
-.Ed
-.Pp
-Contexts may be nested, and they freely intermix with other directives
-on each nesting level.
-.Pp
-The syntax of whitespace is:
-.Bd -ragged -offset indent
-.Ar ws
-.Li ::=
-.Ar ws-char
-.Op Ar opt-ws
-.Ed
-.Bd -ragged -offset indent
-.Ar ws-char
-.Li ::=
-.Aq space
-.Li \&|
-.Aq tab
-.Li \&|
-.Aq newline
-.Ed
-.Bd -ragged -offset indent
-.Ar opt-ws
-.Li ::=
-.Pq Ar comment | ws-char
-.Op Ar opt-ws
-.Ed
-.Bd -ragged -offset indent
-.Ar comment
-.Li ::=
-.Qq #
-.Op Ao non-newline character Ac ...
-.Aq newline
-.Ed
-.Pp
-Comments start with a hash character and extend to the end of the line.
-They can start at the beginning of a line, after the semicolon or closing
-brace at the end of a directive, or after any whitespace character,
-even in the middle of a directive.
-.Pp
-In the following, all keywords are listed, and their arguments are
-explained.
-.Ss Core functionality
-.Bl -tag -width Ds
-.It Ic accept_mutex Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic events
-.El
-.Pp
-If
-.Ic accept_mutex
-is enabled, worker processes will accept new connections by turn.
-Otherwise, all worker processes will be notified about new connections, and if
-volume of new connections is low, some of the worker processes may just waste
-system resources.
-The use of
-.Cm rtsig
-connection processing method requires
-.Ic accept_mutex
-to be enabled.
-.It Ic accept_mutex_delay Ar time
-.Bl -tag -width Ds -compact
-.It default: 500ms
-.It context: Ic events
-.El
-.Pp
-If
-.Ic accept_mutex
-is enabled, specifies the maximum time during which a worker process will try to
-restart accepting new connections if another worker process is currently
-accepting new connections.
-.It Ic daemon Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: main
-.El
-.Pp
-Determines whether nginx should become a daemon.
-Mainly used during development.
-.It Ic debug_connection Ar address | Ar CIDR | Cm unix:
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic events
-.El
-.Pp
-Enables debugging log for selected client connections.
-Other connections will use logging level set by the
-.Ic error_log
-directive.
-Debugged connections are specified by IPv4 or IPv6 (1.3.0, 1.2.1) address or
-network.
-A connection may also be specified using a hostname.
-For connections using UNIX-domain sockets (1.3.0, 1.2.1), debugging log is
-enabled by the
-.Cm unix:
-parameter.
-.Bd -literal -offset indent
-events {
- debug_connection 127.0.0.1;
- debug_connection localhost;
- debug_connection 192.0.2.0/24;
- debug_connection ::1;
- debug_connection 2001:0db8::/32;
- debug_connection unix:;
- ...
-}
-.Ed
-.Pp
-For this directive to work, nginx needs to be built with
-.Fl -with-debug .
-.It Ic debug_points Cm abort | Cm stop
-.Bl -tag -width Ds -compact
-.It default:
-.It context: main
-.El
-.Pp
-This directive is used for debugging.
-When internal error is detected, e.g. the leak of sockets on restart of working
-processes, enabling
-.Ic debug_points
-leads to a core file creation
-.Pq Cm abort
-or to stopping of a process
-.Pq Cm stop
-for further analysis using a system debugger.
-.It Ic error_log Ar file | Cm stderr | Cm syslog Ns : Ns Cm server Ns = Ns Ar address Oo , Ar parameter Ns = Ns Ar value Oc Oo Cm debug | Cm info | Cm notice | Cm warn | Cm error | Cm crit | Cm alert | Cm emerg Oc
-.Bl -tag -width Ds -compact
-.It default: Pa logs/error.log Cm error
-.It context: main , Ic http , Ic server , Ic location
-.El
-.Pp
-Configures logging.
-Several logs can be specified on the same level (1.5.2).
-The first parameter defines a file that will store the log.
-The special value
-.Cm stderr
-selects the standard error file.
-Logging to syslog can be configured by specifying the
-.Cm syslog:
-prefix.
-The second parameter determines the level of logging.
-Log levels above are listed in the order of increasing severity.
-Setting a certain log level will cause all messages of the specified and more
-severe log levels to be logged.
-For example, the default level
-.Cm error
-will cause
-.Cm error ,
-.Cm crit ,
-.Cm alert ,
-and
-.Cm emerg
-messages to be logged.
-If this parameter is omitted then
-.Cm error
-is used.
-For
-.Cm debug
-logging to work, nginx needs to be built with
-.Fl -with-debug .
-The following parameters configure logging to syslog:
-.Bl -tag -width Ds
-.It Cm server Ns = Ns Ar address
-Defines an address of a syslog server.
-An address can be specified as a domain name or IP address, and an optional
-port, or as a UNIX-domain socket path specified after the
-.Cm unix:
-prefix.
-If port is not specified, the port 514 is used.
-If a domain name resolves to several IP addresses, the first resolved address is
-used.
-.It Cm facility Ns = Ns Ar string
-Sets facility of syslog messages, as defined in
-RFC 3164.
-Facility can be one of
-.Cm kern ,
-.Cm user ,
-.Cm mail ,
-.Cm daemon ,
-.Cm auth ,
-.Cm intern ,
-.Cm lpr ,
-.Cm news ,
-.Cm uucp ,
-.Cm clock ,
-.Cm authpriv ,
-.Cm ftp ,
-.Cm ntp ,
-.Cm audit ,
-.Cm alert ,
-.Cm cron ,
-.Cm local0 No .. Cm local7 .
-Default is
-.Cm local7 .
-.It Cm tag Ns = Ns Ar string
-Sets tag of syslog messages.
-Default is
-.Qq nginx .
-.El
-.Pp
-Example syslog configuration:
-.Bd -literal -offset indent
-error_log syslog:server=192.168.1.1 debug;
-error_log syslog:server=unix:/var/log/nginx.sock;
-error_log syslog:server=[2001:db8::1]:12345,facility=local7,tag=nginx error;
-.Ed
-.It Ic env Ar variable Ns Oo = Ns Ar value Oc
-.Bl -tag -width Ds -compact
-.It default: Ev TZ
-.It context: main
-.El
-.Pp
-By default, nginx removes all environment variables inherited from its parent
-process except the
-.Ev TZ
-variable.
-This directive allows preserving some of the inherited variables, changing their
-values, or creating new environment variables.
-These variables are then:
-.Bl -bullet
-.It
-inherited during a live upgrade of an executable file;
-.It
-used by the
-.Sx Module ngx_http_perl_module
-module;
-.It
-used by worker processes.
-One should bear in mind that controlling system libraries in this way is not
-always possible as it is common for libraries to check variables only during
-initialization, well before they can be set using this directive.
-An exception from this is an above mentioned live upgrade of an executable file.
-.El
-.Pp
-The
-.Ev TZ
-variable is always inherited and available to the
-.Sx Module ngx_http_perl_module
-module, unless it is configured explicitly.
-Usage example:
-.Bd -literal -offset indent
-env MALLOC_OPTIONS;
-env PERL5LIB=/data/site/modules;
-env OPENSSL_ALLOW_PROXY_CERTS=1;
-.Ed
-.Pp
-The
-.Ev NGINX
-environment variable is used internally by nginx and should not be set directly
-by the user.
-.It Ic events Brq No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: main
-.El
-.Pp
-Provides the configuration file context in which the directives that affect
-connection processing are specified.
-.It Ic include Ar file | Ar mask
-.Bl -tag -width Ds -compact
-.It default:
-.It context: any
-.El
-.Pp
-Includes another
-.Ar file ,
-or files matching the specified
-.Ar mask ,
-into configuration.
-Included files should consist of syntactically correct directives and blocks.
-Usage example:
-.Bd -literal -offset indent
-include mime.types;
-include vhosts/*.conf;
-.Ed
-.It Ic lock_file Ar file
-.Bl -tag -width Ds -compact
-.It default: Pa logs/nginx.lock
-.It context: main
-.El
-.Pp
-nginx uses the locking mechanism to implement
-.Ic accept_mutex
-and serialize access to shared memory.
-On most systems the locks are implemented using atomic operations, and this
-directive is ignored.
-On other systems the lock file mechanism is used.
-This directive specifies a prefix for the names of lock files.
-.It Ic master_process Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: main
-.El
-.Pp
-Determines whether worker processes are started.
-This directive is intended for nginx developers.
-.It Ic multi_accept Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic events
-.El
-.Pp
-If
-.Ic multi_accept
-is disabled, a worker process will accept one new connection at a time.
-Otherwise, a worker process will accept all new connections at a time.
-The directive is ignored if
-.Cm kqueue
-connection processing method is used, because it reports the number of new
-connections waiting to be accepted.
-The use of
-.Cm rtsig
-connection processing method automatically enables
-.Ic multi_accept .
-.It Ic pcre_jit Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: main
-.El
-.Pp
-Enables or disables the use of just-in-time compilation (PCRE JIT) for the
-regular expressions known by the time of configuration parsing.
-PCRE JIT can speed up processing of regular expressions significantly.
-The JIT is available in PCRE libraries starting from version 8.20 built with the
-.Fl -enable-jit
-configuration parameter.
-When the PCRE library is built with nginx
-.Pq Fl -with-pcre Ns = Ns ,
-the JIT support is enabled via the
-.Fl -with-pcre-jit
-configuration parameter.
-.It Ic pid Ar file
-.Bl -tag -width Ds -compact
-.It default: Pa nginx.pid
-.It context: main
-.El
-.Pp
-Defines a
-.Ar file
-that will store the process ID of the main process.
-.It Ic ssl_engine Ar device
-.Bl -tag -width Ds -compact
-.It default:
-.It context: main
-.El
-.Pp
-Defines the name of the hardware SSL accelerator.
-.It Ic timer_resolution Ar interval
-.Bl -tag -width Ds -compact
-.It default:
-.It context: main
-.El
-.Pp
-Reduces timer resolution in worker processes, thus reducing the number of
-.Fn gettimeofday
-system calls made.
-By default,
-.Fn gettimeofday
-is called each time a kernel event is received.
-With reduced resolution,
-.Fn gettimeofday
-is only called once per specified
-.Ar interval .
-Example:
-.Bd -literal -offset indent
-timer_resolution 100ms;
-.Ed
-.Pp
-Internal implementation of the interval depends on the method used:
-.Bl -bullet
-.It
-the
-.Dv EVFILT_TIMER
-filter if
-.Cm kqueue
-is used;
-.It
-.Fn timer_create
-if
-.Cm eventport
-is used;
-.It
-.Fn setitimer
-otherwise.
-.El
-.It Ic use Ar method
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic events
-.El
-.Pp
-Specifies the
-connection processing
-.Ar method
-to use.
-There is normally no need to specify it explicitly, because nginx will by
-default use the most efficient method.
-.It Ic user Ar user Oo Ar group Oc
-.Bl -tag -width Ds -compact
-.It default: nobody nobody
-.It context: main
-.El
-.Pp
-Defines
-.Ar user
-and
-.Ar group
-credentials used by worker processes.
-If
-.Ar group
-is omitted, a group whose name equals that of
-.Ar user
-is used.
-.It Ic worker_aio_requests Ar number
-.Bl -tag -width Ds -compact
-.It default: 32
-.It context: Ic events
-.El
-.Pp
-When using
-.Ic aio
-with the
-.Cm epoll
-connection processing method, sets the maximum
-.Ar number
-of outstanding asynchronous I/O operations for a single worker process.
-.It Ic worker_connections Ar number
-.Bl -tag -width Ds -compact
-.It default: 512
-.It context: Ic events
-.El
-.Pp
-Sets the maximum number of simultaneous connections that can be opened by a
-worker process.
-It should be kept in mind that this number includes all connections (e.g.
-connections with proxied servers, among others), not only connections with
-clients.
-Another consideration is that the actual number of simultaneous connections
-cannot exceed the current limit on the maximum number of open files, which can
-be changed by
-.Ic worker_rlimit_nofile .
-.It Ic worker_cpu_affinity Ar cpumask No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: main
-.El
-.Pp
-Binds worker processes to the sets of CPUs.
-Each CPU set is represented by a bitmask of allowed CPUs.
-There should be a separate set defined for each of the worker processes.
-By default, worker processes are not bound to any specific CPUs.
-For example,
-.Bd -literal -offset indent
-worker_processes 4;
-worker_cpu_affinity 0001 0010 0100 1000;
-.Ed
-.Pp
-binds each worker process to a separate CPU, while
-.Bd -literal -offset indent
-worker_processes 2;
-worker_cpu_affinity 0101 1010;
-.Ed
-.Pp
-binds the first worker process to CPU0/CPU2, and the second worker process to
-CPU1/CPU3.
-The second example is suitable for hyper-threading.
-The directive is only available on FreeBSD and Linux.
-.It Ic worker_priority Ar number
-.Bl -tag -width Ds -compact
-.It default: 0
-.It context: main
-.El
-.Pp
-Defines the scheduling priority for worker processes like it is done by the
-.Ic nice
-command: a negative
-.Ar number
-means higher priority.
-Allowed range normally varies from -20 to 20.
-Example:
-.Bd -literal -offset indent
-worker_priority -10;
-.Ed
-.It Ic worker_processes Ar number | Cm auto
-.Bl -tag -width Ds -compact
-.It default: 1
-.It context: main
-.El
-.Pp
-Defines the number of worker processes.
-The optimal value depends on many factors including (but not limited to) the
-number of CPU cores, the number of hard disk drives that store data, and load
-pattern.
-When one is in doubt, setting it to the number of available CPU cores would be a
-good start (the value
-.Cm auto
-will try to autodetect it).
-The
-.Cm auto
-parameter is supported starting from versions 1.3.8 and 1.2.5.
-.It Ic worker_rlimit_core Ar size
-.Bl -tag -width Ds -compact
-.It default:
-.It context: main
-.El
-.Pp
-Changes the limit on the largest size of a core file
-.Pq Dv RLIMIT_CORE
-for worker processes.
-Used to increase the limit without restarting the main process.
-.It Ic worker_rlimit_nofile Ar number
-.Bl -tag -width Ds -compact
-.It default:
-.It context: main
-.El
-.Pp
-Changes the limit on the maximum number of open files
-.Pq Dv RLIMIT_NOFILE
-for worker processes.
-Used to increase the limit without restarting the main process.
-.It Ic worker_rlimit_sigpending Ar number
-.Bl -tag -width Ds -compact
-.It default:
-.It context: main
-.El
-.Pp
-On systems that support
-.Cm rtsig
-connection processing method, changes the limit on the number of signals that
-may be queued
-.Pq Dv RLIMIT_SIGPENDING
-for worker processes.
-Used to increase the limit without restarting the main process.
-.It Ic working_directory Ar directory
-.Bl -tag -width Ds -compact
-.It default:
-.It context: main
-.El
-.Pp
-Defines the current working directory for a worker process.
-It is primarily used when writing a core-file, in which case a worker process
-should have write permission for the specified directory.
-.El
-.Ss Module ngx_http_core_module
-.Bl -tag -width Ds
-.It Ic aio Cm on | Cm off | Cm sendfile
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables the use of asynchronous file I/O (AIO) on FreeBSD and Linux.
-On FreeBSD, AIO can be used starting from FreeBSD 4.3.
-AIO can either be linked statically into a kernel:
-.Bd -literal -offset indent
-options VFS_AIO
-.Ed
-.Pp
-or loaded dynamically as a kernel loadable module:
-.Bd -literal -offset indent
-kldload aio
-.Ed
-.Pp
-In FreeBSD versions 5 and 6, enabling AIO statically, or dynamically when
-booting the kernel, will cause the entire networking subsystem to use the Giant
-lock, which can impact overall performance negatively.
-This limitation has been removed in FreeBSD 6.4-STABLE in 2009, and in FreeBSD
-7.
-However, starting from FreeBSD 5.3 it is possible to enable AIO without the
-penalty of running the networking subsystem under a Giant lock-for this to work,
-the AIO module needs to be loaded after the kernel has booted.
-In this case, the following message will appear in
-.Pa /var/log/messages
-.Bd -literal -offset indent
-WARNING: Network stack Giant-free, but aio requires Giant.
-Consider adding 'options NET_WITH_GIANT' or setting debug.mpsafenet=0
-.Ed
-.Pp
-and can safely be ignored.
-The requirement to use the Giant lock with AIO is related to the fact that
-FreeBSD supports asynchronous calls
-.Fn aio_read
-and
-.Fn aio_write
-when working with sockets.
-However, since nginx uses AIO only for disk I/O, no problems should arise.
-For AIO to work,
-.Ic sendfile
-needs to be disabled:
-.Bd -literal -offset indent
-location /video/ {
- sendfile off;
- aio on;
- output_buffers 1 64k;
-}
-.Ed
-.Pp
-In addition, starting from FreeBSD 5.2.1 and nginx 0.8.12, AIO can also be used
-to pre-load data for
-.Fn sendfile :
-.Bd -literal -offset indent
-location /video/ {
- sendfile on;
- tcp_nopush on;
- aio sendfile;
-}
-.Ed
-.Pp
-In this configuration,
-.Fn sendfile
-is called with the
-.Dv SF_NODISKIO
-flag which causes it not to block on disk I/O, but, instead, report back that
-the data are not in memory.
-nginx then initiates an asynchronous data load by reading one byte.
-On the first read, the FreeBSD kernel loads the first 128K bytes of a file into
-memory, although next reads will only load data in 16K chunks.
-This can be changed using the
-.Ic read_ahead
-directive.
-On Linux, AIO can be used starting from kernel version 2.6.22.
-Also, it is necessary to enable
-.Ic directio ,
-or otherwise reading will be blocking:
-.Bd -literal -offset indent
-location /video/ {
- aio on;
- directio 512;
- output_buffers 1 128k;
-}
-.Ed
-.Pp
-On Linux,
-.Ic directio
-can only be used for reading blocks that are aligned on 512-byte boundaries (or
-4K for XFS).
-File's unaligned end is read in blocking mode.
-The same holds true for byte range requests and for FLV requests not from the
-beginning of a file: reading of unaligned data at the beginning and end of a
-file will be blocking.
-There is no need to turn off
-.Ic sendfile
-explicitly, as it is turned off automatically when
-.Ic directio
-is used.
-.It Ic alias Ar path
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-Defines a replacement for the specified location.
-For example, with the following configuration
-.Bd -literal -offset indent
-location /i/ {
- alias /data/w3/images/;
-}
-.Ed
-.Pp
-on request of
-.Pa /i/top.gif ,
-the file
-.Pa /data/w3/images/top.gif
-will be sent.
-The
-.Ar path
-value can contain variables, except
-.Va $document_root
-and
-.Va $realpath_root .
-If
-.Ic alias
-is used inside a location defined with a regular expression then such regular
-expression should contain captures and
-.Ic alias
-should refer to these captures (0.7.40), for example:
-.Bd -literal -offset indent
-location ~ ^/users/(.+\\.(?:gif |jpe?g |png))$ {
- alias /data/w3/images/$1;
-}
-.Ed
-.Pp
-When location matches the last part of the directive's value:
-.Bd -literal -offset indent
-location /images/ {
- alias /data/w3/images/;
-}
-.Ed
-.Pp
-it is better to use the
-.Ic root
-directive instead:
-.Bd -literal -offset indent
-location /images/ {
- root /data/w3;
-}
-.Ed
-.It Ic chunked_transfer_encoding Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Allows disabling chunked transfer encoding in HTTP/1.1.
-It may come in handy when using a software failing to support chunked encoding
-despite the standard's requirement.
-.It Ic client_body_buffer_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 8k | 16k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets buffer size for reading client request body.
-In case the request body is larger than the buffer, the whole body or only its
-part is written to a
-.Ic client_body_temp_path
-temporary file.
-By default, buffer size is equal to two memory pages.
-This is 8K on x86, other 32-bit platforms, and x86-64.
-It is usually 16K on other 64-bit platforms.
-.It Ic client_body_in_file_only Cm on | Cm clean | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Determines whether nginx should save the entire client request body into a file.
-This directive can be used during debugging, or when using the
-.Va $request_body_file
-variable, or the
-methods
-.Ic $r->request_body_file
-method of the module
-.Sx Module ngx_http_perl_module .
-When set to the value
-.Cm on ,
-temporary files are not removed after request processing.
-The value
-.Cm clean
-will cause the temporary files left after request processing to be removed.
-.It Ic client_body_in_single_buffer Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Determines whether nginx should save the entire client request body in a single
-buffer.
-The directive is recommended when using the
-.Va $request_body
-variable, to save the number of copy operations involved.
-.It Ic client_body_temp_path Ar path Oo Ar level1 Oo Ar level2 Oo Ar level3 Oc Oc Oc
-.Bl -tag -width Ds -compact
-.It default: client_body_temp
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a directory for storing temporary files holding client request bodies.
-Up to three-level subdirectory hierarchy can be used under the specified
-directory.
-For example, in the following configuration
-.Bd -literal -offset indent
-client_body_temp_path /spool/nginx/client_temp 1 2;
-.Ed
-.Pp
-a path to a temporary file might look like this:
-.Pa /spool/nginx/client_temp/7/45/00000123457
-.It Ic client_body_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 60s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a timeout for reading client request body.
-The timeout is set only for a period between two successive read operations, not
-for the transmission of the whole request body.
-If a client does not transmit anything within this time, the 408 (Request
-Time-out) error is returned to the client.
-.It Ic client_header_buffer_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 1k
-.It context: Ic http , Ic server
-.El
-.Pp
-Sets buffer size for reading client request header.
-For most requests, a buffer of 1K bytes is enough.
-However, if a request includes long cookies, or comes from a WAP client, it may
-not fit into 1K.
-If a request line or a request header field does not fit into this buffer then
-larger buffers, configured by the
-.Ic large_client_header_buffers
-directive, are allocated.
-.It Ic client_header_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 60s
-.It context: Ic http , Ic server
-.El
-.Pp
-Defines a timeout for reading client request header.
-If a client does not transmit the entire header within this time, the 408
-(Request Time-out) error is returned to the client.
-.It Ic client_max_body_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 1m
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the maximum allowed size of the client request body, specified in the
-Content-Length request header field.
-If the size in a request exceeds the configured value, the 413 (Request Entity
-Too Large) error is returned to the client.
-Please be aware that browsers cannot correctly display this error.
-Setting
-.Ar size
-to 0 disables checking of client request body size.
-.It Ic connection_pool_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 256
-.It context: Ic http , Ic server
-.El
-.Pp
-Allows accurate tuning of per-connection memory allocations.
-This directive has minimal impact on performance and should not generally be
-used.
-.It Ic default_type Ar mime-type
-.Bl -tag -width Ds -compact
-.It default: text/plain
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines the default MIME type of a response.
-Mapping of file name extensions to MIME types can be set with the
-.Ic types
-directive.
-.It Ic directio Ar size | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables the use of the
-.Dv O_DIRECT
-flag (FreeBSD, Linux), the
-.Dv F_NOCACHE
-flag (Mac OS X), or the
-.Fn directio
-function (Solaris), when reading files that are larger than or equal to the
-specified
-.Ar size .
-The directive automatically disables (0.7.15) the use of
-.Ic sendfile
-for a given request.
-It can be useful for serving large files:
-.Bd -literal -offset indent
-directio 4m;
-.Ed
-.Pp
-or when using
-.Ic aio
-on Linux.
-.It Ic directio_alignment Ar size
-.Bl -tag -width Ds -compact
-.It default: 512
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the alignment for
-.Ic directio .
-In most cases, a 512-byte alignment is enough.
-However, when using XFS under Linux, it needs to be increased to 4K.
-.It Ic disable_symlinks Cm off
-.It Ic disable_symlinks Cm on | Cm if_not_owner Oo Cm from Ns = Ns Ar part Oc
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Determines how symbolic links should be treated when opening files:
-.Bl -tag -width Ds
-.It Cm off
-Symbolic links in the pathname are allowed and not checked.
-This is the default behavior.
-.It Cm on
-If any component of the pathname is a symbolic link, access to a file is denied.
-.It Cm if_not_owner
-Access to a file is denied if any component of the pathname is a symbolic link,
-and the link and object that the link points to have different owners.
-.It Cm from Ns = Ns Ar part
-When checking symbolic links (parameters
-.Cm on
-and
-.Cm if_not_owner ) ,
-all components of the pathname are normally checked.
-Checking of symbolic links in the initial part of the pathname may be avoided by
-specifying additionally the
-.Cm from Ns = Ns Ar part
-parameter.
-In this case, symbolic links are checked only from the pathname component that
-follows the specified initial part.
-If the value is not an initial part of the pathname checked, the whole pathname
-is checked as if this parameter was not specified at all.
-If the value matches the whole file name, symbolic links are not checked.
-The parameter value can contain variables.
-.El
-.Pp
-Example:
-.Bd -literal -offset indent
-disable_symlinks on from=$document_root;
-.Ed
-.Pp
-This directive is only available on systems that have the
-.Fn openat
-and
-.Fn fstatat
-interfaces.
-Such systems include modern versions of FreeBSD, Linux, and Solaris.
-Parameters
-.Cm on
-and
-.Cm if_not_owner
-add a processing overhead.
-On systems that do not support opening of directories only for search, to use
-these parameters it is required that worker processes have read permissions for
-all directories being checked.
-The
-.Sx Module ngx_http_autoindex_module ,
-.Sx Module ngx_http_random_index_module ,
-and
-.Sx Module ngx_http_dav_module
-modules currently ignore this directive.
-.It Ic error_page Ar code No ... Oo = Ns Oo Ar response Oc Oc Ar uri
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location , Ic if in location
-.El
-.Pp
-Defines the URI that will be shown for the specified errors.
-.Ic error_page
-directives are inherited from the previous level only if there are no
-.Ic error_page
-directives defined on the current level.
-A
-.Ar uri
-value can contain variables.
-Example:
-.Bd -literal -offset indent
-error_page 404 /404.html;
-error_page 500 502 503 504 /50x.html;
-.Ed
-.Pp
-Furthermore, it is possible to change the response code to another using the
-.Ar =response
-syntax, for example:
-.Bd -literal -offset indent
-error_page 404 =200 /empty.gif;
-.Ed
-.Pp
-If an error response is processed by a proxied server or a FastCGI server, and
-the server may return different response codes (e.g., 200, 302, 401 or 404), it
-is possible to respond with the code it returns:
-.Bd -literal -offset indent
-error_page 404 = /404.php;
-.Ed
-.Pp
-It is also possible to use redirects for error processing:
-.Bd -literal -offset indent
-error_page 403 http://example.com/forbidden.html;
-error_page 404 =301 http://example.com/notfound.html;
-.Ed
-.Pp
-In this case, by default, the response code 302 is returned to the client.
-It can only be changed to one of the redirect status codes (301, 302, 303, and
-307).
-If there is no need to change URI during internal redirection it is possible to
-pass error processing into a named location:
-.Bd -literal -offset indent
-location / {
- error_page 404 = @fallback;
-}
-location @fallback {
- proxy_pass http://backend;
-}
-.Ed
-.Pp
-If
-.Ar uri
-processing leads to an error, the status code of the last occurred error is
-returned to the client.
-.It Ic etag Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables automatic generation of the ETag response header field for
-static resources.
-.It Ic http Brq No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: main
-.El
-.Pp
-Provides the configuration file context in which the HTTP server directives are
-specified.
-.It Ic if_modified_since Cm off | Cm exact | Cm before
-.Bl -tag -width Ds -compact
-.It default: Cm exact
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Specifies how to compare modification time of a response with the time in the
-If-Modified-Since request header field:
-.Bl -tag -width Ds
-.It Cm off
-the If-Modified-Since request header field is ignored (0.7.34);
-.It Cm exact
-exact match;
-.It Cm before
-modification time of a response is less than or equal to the time in the
-If-Modified-Since request header field.
-.El
-.It Ic ignore_invalid_headers Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server
-.El
-.Pp
-Controls whether header fields with invalid names should be ignored.
-Valid names are composed of English letters, digits, hyphens, and possibly
-underscores (as controlled by the
-.Ic underscores_in_headers
-directive).
-A directive can be specified on the
-.Ic server
-level in the default server.
-In this case, its value will cover all virtual servers listening on the same
-address and port.
-.It Ic internal
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-Specifies that a given location can only be used for internal requests.
-For external requests, the client error 404 (Not Found) is returned.
-Internal requests are the following:
-.Bl -bullet
-.It
-requests redirected by the
-.Ic error_page ,
-.Ic index ,
-.Ic random_index ,
-and
-.Ic try_files
-directives;
-.It
-requests redirected by the X-Accel-Redirect response header field from an
-upstream server;
-.It
-subrequests formed by the
-.Ic include virtual
-command of the
-.Sx Module ngx_http_ssi_module
-module and by the
-.Sx Module ngx_http_addition_module
-module directives;
-.It
-requests changed by the
-.Ic rewrite
-directive.
-.El
-.Pp
-Example:
-.Bd -literal -offset indent
-error_page 404 /404.html;
-location /404.html {
- internal;
-}
-.Ed
-.Pp
-There is a limit of 10 internal redirects per request to prevent request
-processing cycles that can occur in incorrect configurations.
-If this limit is reached, the error 500 (Internal Server Error) is returned.
-In such cases, the rewrite or internal redirection cycle message can be seen in
-the error log.
-.It Ic keepalive_disable Cm none | Ar browser No ...
-.Bl -tag -width Ds -compact
-.It default: Cm msie6
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Disables keep-alive connections with misbehaving browsers.
-The
-.Ar browser
-parameters specify which browsers will be affected.
-The value
-.Cm msie6
-disables keep-alive connections with old versions of MSIE, once a POST request
-is received.
-The value
-.Cm safari
-disables keep-alive connections with Safari and Safari-like browsers on Mac OS X
-and Mac OS X-like operating systems.
-The value
-.Cm none
-enables keep-alive connections with all browsers.
-Prior to version 1.1.18, the value
-.Cm safari
-matched all Safari and Safari-like browsers on all operating systems, and
-keep-alive connections with them were disabled by default.
-.It Ic keepalive_requests Ar number
-.Bl -tag -width Ds -compact
-.It default: 100
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the maximum number of requests that can be served through one keep-alive
-connection.
-After the maximum number of requests are made, the connection is closed.
-.It Ic keepalive_timeout Ar timeout Oo Ar header_timeout Oc
-.Bl -tag -width Ds -compact
-.It default: 75s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-The first parameter sets a timeout during which a keep-alive client connection
-will stay open on the server side.
-The zero value disables keep-alive client connections.
-The optional second parameter sets a value in the Keep-Alive: timeout=time
-response header field.
-Two parameters may differ.
-The Keep-Alive: timeout=time header field is recognized by Mozilla and
-Konqueror.
-MSIE closes keep-alive connections by itself in about 60 seconds.
-.It Ic large_client_header_buffers Ar number Ar size
-.Bl -tag -width Ds -compact
-.It default: 4 8k
-.It context: Ic http , Ic server
-.El
-.Pp
-Sets the maximum
-.Ar number
-and
-.Ar size
-of buffers used for reading large client request header.
-A request line cannot exceed the size of one buffer, or the 414 (Request-URI Too
-Large) error is returned to the client.
-A request header field cannot exceed the size of one buffer as well, or the 400
-(Bad Request) error is returned to the client.
-Buffers are allocated only on demand.
-By default, the buffer size is equal to 8K bytes.
-If after the end of request processing a connection is transitioned into the
-keep-alive state, these buffers are released.
-.It Ic limit_except Ar method No ... Brq No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-Limits allowed HTTP methods inside a location.
-The
-.Ar method
-parameter can be one of the following:
-.Cm GET ,
-.Cm HEAD ,
-.Cm POST ,
-.Cm PUT ,
-.Cm DELETE ,
-.Cm MKCOL ,
-.Cm COPY ,
-.Cm MOVE ,
-.Cm OPTIONS ,
-.Cm PROPFIND ,
-.Cm PROPPATCH ,
-.Cm LOCK ,
-.Cm UNLOCK ,
-or
-.Cm PATCH.
-Allowing the
-.Cm GET
-method makes the
-.Cm HEAD
-method also allowed.
-Access to other methods can be limited using the
-.Sx Module ngx_http_access_module
-and
-.Sx Module ngx_http_auth_basic_module
-modules directives:
-.Bd -literal -offset indent
-limit_except GET {
- allow 192.168.1.0/32;
- deny all;
-}
-.Ed
-.Pp
-Please note that this will limit access to all methods except
-.Cm GET
-and
-.Cm HEAD .
-.It Ic limit_rate Ar rate
-.Bl -tag -width Ds -compact
-.It default: 0
-.It context: Ic http , Ic server , Ic location , Ic if in location
-.El
-.Pp
-Limits the rate of response transmission to a client.
-The
-.Ar rate
-is specified in bytes per second.
-The zero value disables rate limiting.
-The limit is set per a request, and so if a client simultaneously opens two
-connections, the overall rate will be twice as much as the specified limit.
-Rate limit can also be set in the
-.Va $limit_rate
-variable.
-It may be useful in cases where rate should be limited depending on a certain
-condition:
-.Bd -literal -offset indent
-server {
- if ($slow) {
- set $limit_rate 4k;
- }
- ...
-}
-.Ed
-.Pp
-Rate limit can also be set in the X-Accel-Limit-Rate header field of a proxied
-server response.
-This capability can be disabled using the
-.Ic proxy_ignore_headers
-and
-.Ic fastcgi_ignore_headers
-directives.
-.It Ic limit_rate_after Ar size
-.Bl -tag -width Ds -compact
-.It default: 0
-.It context: Ic http , Ic server , Ic location , Ic if in location
-.El
-.Pp
-Sets the initial amount after which the further transmission of a response to a
-client will be rate limited.
-Example:
-.Bd -literal -offset indent
-location /flv/ {
- flv;
- limit_rate_after 500k;
- limit_rate 50k;
-}
-.Ed
-.It Ic lingering_close Cm off | Cm on | Cm always
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Controls how nginx closes client connections.
-The default value
-.Cm on
-instructs nginx to
-.Ic lingering_timeout
-wait for and
-.Ic lingering_time
-process additional data from a client before fully closing a connection, but
-only if heuristics suggests that a client may be sending more data.
-The value
-.Cm always
-will cause nginx to unconditionally wait for and process additional client data.
-The value
-.Cm off
-tells nginx to never wait for more data and close the connection immediately.
-This behavior breaks the protocol and should not be used under normal
-circumstances.
-.It Ic lingering_time Ar time
-.Bl -tag -width Ds -compact
-.It default: 30s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-When
-.Ic lingering_close
-is in effect, this directive specifies the maximum time during which nginx will
-process (read and ignore) additional data coming from a client.
-After that, the connection will be closed, even if there will be more data.
-.It Ic lingering_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 5s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-When
-.Ic lingering_close
-is in effect, this directive specifies the maximum waiting time for more client
-data to arrive.
-If data are not received during this time, the connection is closed.
-Otherwise, the data are read and ignored, and nginx starts waiting for more data
-again.
-The wait-read-ignore cycle is repeated, but no longer than specified by the
-.Ic lingering_time
-directive.
-.It Ic listen Ar address Ns Oo : Ns Ar port Oc Oo Cm default_server Oc \
- Oo Cm ssl Oc Oo Cm spdy Oc Oo Cm setfib Ns = Ns Ar number Oc \
- Oo Cm backlog Ns = Ns Ar number Oc Oo Cm rcvbuf Ns = Ns Ar size Oc \
- Oo Cm sndbuf Ns = Ns Ar size Oc \
- Oo Cm accept_filter Ns = Ns Ar filter Oc \
- Oo Cm deferred Oc Oo Cm bind Oc \
- Oo Cm ipv6only Ns = Ns Cm on | Cm off Oc \
- Oo Cm so_keepalive Ns = Ns Cm on | Cm off | \
- Oo Ar keepidle Ns Oc : Ns Oo Ar keepintvl Oc : Ns Oo Ar keepcnt Oc Oc
-.It Ic listen Ar port Oo Cm default_server Oc Oo Cm ssl Oc \
- Oo Cm spdy Oc Oo Cm setfib Ns = Ns Ar number Oc \
- Oo Cm backlog Ns = Ns Ar number Oc Oo Cm rcvbuf Ns = Ns Ar size Oc \
- Oo Cm sndbuf Ns = Ns Ar size Oc \
- Oo Cm accept_filter Ns = Ns Ar filter Oc \
- Oo Cm deferred Oc Oo Cm bind Oc \
- Oo Cm ipv6only Ns = Ns Cm on | Cm off Oc \
- Oo Cm so_keepalive Ns = Ns Cm on | Cm off | \
- Oo Ar keepidle Oc : Ns Oo Ar keepintvl Oc : Ns Oo Ar keepcnt Oc Oc
-.It Ic listen Cm unix : Ns Ar path Oo Cm default_server Oc \
- Oo Cm ssl Oc Oo Cm spdy Oc Oo Cm backlog Ns = Ns Ar number Oc \
- Oo Cm rcvbuf Ns = Ns Ar size Oc \
- Oo Cm sndbuf Ns = Ns Ar size Oc \
- Oo Cm accept_filter Ns = Ns Ar filter Oc \
- Oo Cm deferred Oc Oo Cm bind Oc \
- Oo Cm so_keepalive Ns = Ns Cm on | Cm off | \
- Oo Ar keepidle Oc : Ns Oo Ar keepintvl Oc : Ns Oo Ar keepcnt Oc Oc
-.Pp
-.Bl -tag -width Ds -compact
-.It default: *:80 | *:8000
-.It context: Ic server
-.El
-.Pp
-Sets the
-.Ar address
-and
-.Ar port
-for IP, or the
-.Ar path
-for a UNIX-domain socket on which the server will accept requests.
-Both
-.Ar address
-and
-.Ar port ,
-or only
-.Ar address
-or only
-.Ar port
-can be specified.
-An
-.Ar address
-may also be a hostname, for example:
-.Bd -literal -offset indent
-listen 127.0.0.1:8000;
-listen 127.0.0.1;
-listen 8000;
-listen *:8000;
-listen localhost:8000;
-.Ed
-.Pp
-IPv6 addresses (0.7.36) are specified in square brackets:
-.Bd -literal -offset indent
-listen [::]:8000;
-listen [::1];
-.Ed
-.Pp
-UNIX-domain sockets (0.8.21) are specified with the
-.Cm unix:
-prefix:
-.Bd -literal -offset indent
-listen unix:/var/run/nginx.sock;
-.Ed
-.Pp
-If only
-.Ar address
-is given, the port 80 is used.
-If the directive is not present then either
-.Ic *:80
-is used if nginx runs with the superuser privileges, or
-.Ic *:8000
-otherwise.
-The
-.Cm default_server
-parameter, if present, will cause the server to become the default server for
-the specified
-.Ar address Ns : Ns Ar port
-pair.
-If none of the directives have the
-.Cm default_server
-parameter then the first server with the
-.Ar address Ns : Ns Ar port
-pair will be the default server for this pair.
-In versions prior to 0.8.21 this parameter is named simply
-.Cm default .
-The
-.Ar ssl
-parameter (0.7.14) allows specifying that all connections accepted on this port
-should work in SSL mode.
-This allows for a more compact configuration for the server that handles both
-HTTP and HTTPS requests.
-The
-.Cm spdy
-parameter (1.3.15) allows accepting SPDY connections on this port.
-Normally, for this to work the
-.Ar ssl
-parameter should be specified as well, but nginx can also be configured to
-accept SPDY connections without SSL.
-A
-.Ic listen
-directive can have several additional parameters specific to socket-related
-system calls.
-These parameters can be specified in any
-.Ic listen
-directive, but only once for a given
-.Ar address Ns : Ns Ar port
-pair.
-In versions prior to 0.8.21, they could only be specified in the
-.Ic listen
-directive together with the
-.Cm default
-parameter.
-.Bl -tag -width Ds
-.It Cm setfib Ns = Ns Ar number
-this parameter (0.8.44) sets the associated routing table, FIB (the
-.Dv SO_SETFIB
-option) for the listening socket.
-This currently works only on FreeBSD.
-.It Cm backlog Ns = Ns Ar number
-sets the
-.Cm backlog
-parameter in the
-.Fn listen
-call that limits the maximum length for the queue of pending connections.
-By default,
-.Cm backlog
-is set to -1 on FreeBSD and Mac OS X, and to 511 on other platforms.
-.It Cm rcvbuf Ns = Ns Ar size
-sets the receive buffer size (the
-.Dv SO_RCVBUF
-option) for the listening socket.
-.It Cm sndbuf Ns = Ns Ar size
-sets the send buffer size (the
-.Dv SO_SNDBUF
-option) for the listening socket.
-.It Cm accept_filter Ns = Ns Ar filter
-sets the name of accept filter (the
-.Dv SO_ACCEPTFILTER
-option) for the listening socket that filters incoming connections before
-passing them to
-.Fn accept .
-This works only on FreeBSD and NetBSD_5.0+.
-Possible values are
-.Cm dataready
-and
-.Cm httpready .
-.It Cm deferred
-instructs to use a deferred
-.Fn accept
-(the
-.Dv TCP_DEFER_ACCEPT
-socket option) on Linux.
-.It Cm bind
-instructs to make a separate
-.Fn bind
-call for a given
-.Ar address Ns : Ns Ar port
-pair.
-This is useful because if there are several
-.Ic listen
-directives with the same port but different addresses, and one of the
-.Ic listen
-directives listens on all addresses for the given port
-.Pq * Ns : Ns Ar port ,
-nginx will
-.Fn bind
-only to
-.Qq * Ns : Ns Ar port .
-It should be noted that the
-.Fn getsockname
-system call will be made in this case to determine the address that accepted the
-connection.
-If the
-.Cm backlog ,
-.Cm rcvbuf ,
-.Cm sndbuf ,
-.Cm accept_filter ,
-.Cm deferred ,
-or
-.Cm so_keepalive
-parameters are used then for a given
-.Ar address Ns : Ar port
-pair a separate
-.Fn bind
-call will always be made.
-.It Cm ipv6only Ns = Ns Cm on | Cm off
-this parameter (0.7.42) determines (via the
-.Dv IPV6_V6ONLY
-socket option) whether an IPv6 socket listening on a wildcard address
-.Op ::
-will accept only IPv6 connections or both IPv6 and IPv4 connections.
-This parameter is turned on by default.
-It can only be set once on start.
-Prior to version 1.3.4, if this parameter was omitted then the operating
-system's settings were in effect for the socket.
-.It Cm so_keepalive Ns = Ns Cm on | Cm off | \
- Oo Ar keepidle Oc : Ns Oo Ar keepintvl Oc : Ns Oo Ar keepcnt Oc
-this parameter (1.1.11) configures the TCP keepalive behavior for the listening
-socket.
-If this parameter is omitted then the operating system's settings will be in
-effect for the socket.
-If it is set to the value
-.Cm on ,
-the
-.Dv SO_KEEPALIVE
-option is turned on for the socket.
-If it is set to the value
-.Cm off ,
-the
-.Dv SO_KEEPALIVE
-option is turned off for the socket.
-Some operating systems support setting of TCP keepalive parameters on a
-per-socket basis using the
-.Dv TCP_KEEPIDLE ,
-.Dv TCP_KEEPINTVL ,
-and
-.Dv TCP_KEEPCNT
-socket options.
-On such systems (currently, Linux_2.4+, NetBSD_5+, and FreeBSD_9.0-STABLE), they
-can be configured using the
-.Ar keepidle ,
-.Ar keepintvl ,
-and
-.Ar keepcnt
-parameters.
-One or two parameters may be omitted, in which case the system default setting
-for the corresponding socket option will be in effect.
-For example,
-.Bd -literal -offset indent
-so_keepalive=30m::10
-.Ed
-.Pp
-will set the idle timeout
-.Pq Dv TCP_KEEPIDLE
-to 30 minutes, leave the probe interval
-.Pq Dv TCP_KEEPINTVL
-at its system default, and set the probes count
-.Pq Dv TCP_KEEPCNT
-to 10 probes.
-.El
-.Pp
-Example:
-.Bd -literal -offset indent
-listen 127.0.0.1 default_server accept_filter=dataready backlog=1024;
-.Ed
-.It Ic location Oo Cm = | Cm ~ | Cm ~* | Cm ^~ Oc Ar uri Brq No ...
-.It Ic location Cm @ Ar name Brq No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic server , Ic location
-.El
-.Pp
-Sets configuration depending on a request URI.
-The matching is performed against a normalized URI, after decoding the text
-encoded in the
-.Qq %XX
-form, resolving references to relative path components
-.Qo . Qc
-and
-.Qq .. ,
-and possible
-.Ic merge_slashes
-compression
-of two or more adjacent slashes into a single slash.
-A location can either be defined by a prefix string, or by a regular expression.
-Regular expressions are specified with the preceding
-.Qq ~*
-modifier (for case-insensitive matching), or the
-.Qq ~
-modifier (for case-sensitive matching).
-To find location matching a given request, nginx first checks locations defined
-using the prefix strings (prefix locations).
-Among them, the location with the longest matching prefix is selected and
-remembered.
-Then regular expressions are checked, in the order of their appearance in the
-configuration file.
-The search of regular expressions terminates on the first match, and the
-corresponding configuration is used.
-If no match with a regular expression is found then the configuration of the
-prefix location remembered earlier is used.
-.Ic location
-blocks can be nested, with some exceptions mentioned below.
-For case-insensitive operating systems such as Mac OS X and Cygwin, matching
-with prefix strings ignores a case (0.7.7).
-However, comparison is limited to one-byte locales.
-Regular expressions can contain captures (0.7.40) that can later be used in
-other directives.
-If the longest matching prefix location has the
-.Qq ^~
-modifier then regular expressions are not checked.
-Also, using the
-.Cm =
-modifier it is possible to define an exact match of URI and location.
-If an exact match is found, the search terminates.
-For example, if a / request happens frequently, defining
-.Qq location=/
-will speed up the processing of these requests, as search terminates right after
-the first comparison.
-Such a location cannot obviously contain nested locations.
-In versions from 0.7.1 to 0.8.41, if a request matched the prefix location
-without the
-.Qq =
-and
-.Qq ^~
-modifiers, the search also terminated and regular expressions were not checked.
-Let's illustrate the above by an example:
-.Bd -literal -offset indent
-location = / {
- [ configuration A ]
-}
-location / {
- [ configuration B ]
-}
-location /documents/ {
- [ configuration C ]
-}
-location ^~ /images/ {
- [ configuration D ]
-}
-location ~* \\.(gif |jpg |jpeg)$ {
- [ configuration E ]
-}
-.Ed
-.Pp
-The
-.Qq /
-request will match configuration A, the
-.Qq /index.html
-request will match configuration B, the
-.Qq /documents/document.html
-request will match configuration C, the
-.Qq /images/1.gif
-request will match configuration D, and the
-.Qq /documents/1.jpg
-request will match configuration E.
-The
-.Cm @
-prefix defines a named location.
-Such a location is not used for a regular request processing, but instead used
-for request redirection.
-They cannot be nested, and cannot contain nested locations.
-If a location is defined by a prefix string that ends with the slash character,
-and requests are processed by one of
-.Ic proxy_pass ,
-.Ic fastcgi_pass ,
-.Ic scgi_pass ,
-.Ic uwsgi_pass ,
-or
-.Ic memcached_pass ,
-then in response to a request with URI equal to this string, but without the
-trailing slash, a permanent redirect with the code 301 will be returned to the
-requested URI with the slash appended.
-If this is not desired, an exact match of the URI and location could be defined
-like this:
-.Bd -literal -offset indent
-location /user/ {
- proxy_pass http://user.example.com;
-}
-location = /user {
- proxy_pass http://login.example.com;
-}
-.Ed
-.It Ic log_not_found Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables logging of errors about not found files into
-.Ic error_log .
-.It Ic log_subrequest Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables logging of subrequests into
-.Ic access_log .
-.It Ic max_ranges Ar number
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Limits the maximum allowed number of ranges in byte-range requests.
-Requests that exceed the limit are processed as if there were no byte ranges
-specified.
-By default, the number of ranges is not limited.
-The zero value disables the byte-range support completely.
-.It Ic merge_slashes Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server
-.El
-.Pp
-Enables or disables compression of two or more adjacent slashes in a URI into a
-single slash.
-Note that compression is essential for the correct matching of prefix string and
-regular expression locations.
-Without it, the
-.Qq //scripts/one.php
-request would not match
-.Bd -literal -offset indent
-location /scripts/ {
- ...
-}
-.Ed
-.Pp
-and might be processed as a static file.
-So it gets converted to
-.Qq /scripts/one.php .
-Turning the compression
-.Cm off
-can become necessary if a URI contains base64-encoded names, since base64 uses
-the
-.Qq /
-character internally.
-However, for security considerations, it is better to avoid turning the
-compression off.
-A directive can be specified on the
-.Ic server
-level in the default server.
-In this case, its value will apply to all virtual servers listening on the same
-address and port.
-.It Ic msie_padding Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables adding comments to responses for MSIE clients with status
-greater than 400 to increase the response size to 512 bytes.
-.It Ic msie_refresh Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables issuing refreshes instead of redirects for MSIE clients.
-.It Ic open_file_cache Cm off
-.It Ic open_file_cache Cm max Ns = Ns Ar N Oo Cm inactive Ns = Ns Ar time Oc
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Configures a cache that can store:
-.Bl -bullet
-.It
-open file descriptors, their sizes and modification times;
-.It
-information on existence of directories;
-.It
-file lookup errors, such as file not found, no read permission, and so on.
-Caching of errors should be enabled separately by the
-.Ic open_file_cache_errors
-directive.
-.El
-.Pp
-The directive has the following parameters:
-.Bl -tag -width Ds
-.It Cm max
-sets the maximum number of elements in the cache; on cache overflow the least
-recently used (LRU) elements are removed;
-.It Cm inactive
-defines a time after which an element is removed from the cache if it has not
-been accessed during this time; by default, it is 60 seconds;
-.It Cm off
-disables the cache.
-.El
-.Pp
-Example:
-.Bd -literal -offset indent
-open_file_cache max=1000 inactive=20s;
-open_file_cache_valid 30s;
-open_file_cache_min_uses 2;
-open_file_cache_errors on;
-.Ed
-.It Ic open_file_cache_errors Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables caching of file lookup errors by
-.Ic open_file_cache .
-.It Ic open_file_cache_min_uses Ar number
-.Bl -tag -width Ds -compact
-.It default: 1
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the minimum
-.Ar number
-of file accesses during the period configured by the
-.Cm inactive
-parameter of the
-.Ic open_file_cache
-directive, required for a file descriptor to remain open in the cache.
-.It Ic open_file_cache_valid Ar time
-.Bl -tag -width Ds -compact
-.It default: 60s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a time after which
-.Ic open_file_cache
-elements should be validated.
-.It Ic optimize_server_names Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server
-.El
-.Pp
-This directive is obsolete.
-The
-.Ic server_name_in_redirect
-directive should be used instead.
-.It Ic port_in_redirect Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables specifying the port in redirects issued by nginx.
-The use of the primary server name in redirects is controlled by the
-.Ic server_name_in_redirect
-directive.
-.It Ic postpone_output Ar size
-.Bl -tag -width Ds -compact
-.It default: 1460
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-If possible, the transmission of client data will be postponed until nginx has
-at least
-.Ar size
-bytes of data to send.
-The zero value disables postponing data transmission.
-.It Ic read_ahead Ar size
-.Bl -tag -width Ds -compact
-.It default: 0
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the amount of pre-reading for the kernel when working with file.
-On Linux, the
-.Fn posix_fadvise 0 0 0 POSIX_FADV_SEQUENTIAL
-system call is used, and so the
-.Ar size
-parameter is ignored.
-On FreeBSD, the
-.Fn fcntl O_READAHEAD size
-system call, supported since FreeBSD 9.0-CURRENT, is used.
-FreeBSD 7 has to be patched.
-.It Ic recursive_error_pages Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables doing several redirects using the
-.Ic error_page
-directive.
-The number of such redirects is
-.Ic internal
-limited .
-.It Ic request_pool_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 4k
-.It context: Ic http , Ic server
-.El
-.Pp
-Allows accurate tuning of per-request memory allocations.
-This directive has minimal impact on performance and should not generally be
-used.
-.It Ic reset_timedout_connection Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables resetting timed out connections.
-The reset is performed as follows.
-Before closing a socket, the
-.Dv SO_LINGER
-option is set on it with a timeout value of 0.
-When the socket is closed, TCP RST is sent to the client, and all memory
-occupied by this socket is released.
-This helps avoid keeping an already closed socket with filled buffers in a
-FIN_WAIT1 state for a long time.
-It should be noted that timed out keep-alive connections are closed normally.
-.It Ic resolver Ar address No ... Oo Cm valid Ns = Ns Ar time Oc
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Configures name servers used to resolve names of upstream servers into
-addresses, for example:
-.Bd -literal -offset indent
-resolver 127.0.0.1 [::1]:5353;
-.Ed
-.Pp
-An
-.Ar address
-can be specified as a domain name or IP address, and an optional port
-(1.3.1, 1.2.2).
-If port is not specified, the port 53 is used.
-Name servers are queried in a round-robin fashion.
-Before version 1.1.7, only a single name server could be configured.
-Specifying name servers using IPv6 addresses is supported starting from versions
-1.3.1 and 1.2.2.By default, nginx caches answers using the TTL value of a
-response.
-An optional
-.Cm valid
-parameter allows overriding it:
-.Bd -literal -offset indent
-resolver 127.0.0.1 [::1]:5353 valid=30s;
-.Ed
-.Pp
-Before version 1.1.9, tuning of caching time was not possible, and nginx always
-cached answers for the duration of 5 minutes.
-.It Ic resolver_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 30s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a timeout for name resolution, for example:
-.Bd -literal -offset indent
-resolver_timeout 5s;
-.Ed
-.It Ic root Ar path
-.Bl -tag -width Ds -compact
-.It default: Pa html
-.It context: Ic http , Ic server , Ic location , Ic if in location
-.El
-.Pp
-Sets the root directory for requests.
-For example, with the following configuration
-.Bd -literal -offset indent
-location /i/ {
- root /data/w3;
-}
-.Ed
-.Pp
-The
-.Pa /data/w3/i/top.gif
-file will be sent in response to the
-.Qq /i/top.gif
-request.
-The
-.Ar path
-value can contain variables, except
-.Va $document_root
-and
-.Va $realpath_root .
-A path to the file is constructed by merely adding a URI to the value of the
-.Ic root
-directive.
-If a URI has to be modified, the
-.Ic alias
-directive should be used.
-.It Ic satisfy Cm all | Cm any
-.Bl -tag -width Ds -compact
-.It default: all
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Allows access if all
-.Pq Ic all
-or at least one
-.Pq Ic any
-of the
-.Sx Module ngx_http_access_module ,
-.Sx Module ngx_http_auth_basic_module
-or
-.Sx Module ngx_http_auth_request_module
-modules allow access.
-Example:
-.Bd -literal -offset indent
-location / {
- satisfy any;
- allow 192.168.1.0/32;
- deny all;
- auth_basic "closed site";
- auth_basic_user_file conf/htpasswd;
-}
-.Ed
-.It Ic satisfy_any Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-This directive has been replaced by the
-.Cm any
-parameter of the
-.Ic satisfy
-directive.
-.It Ic send_lowat Ar size
-.Bl -tag -width Ds -compact
-.It default: 0
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-If the directive is set to a non-zero value, nginx will try to minimize the
-number of send operations on client sockets by using either
-.Dv NOTE_LOWAT
-flag of the
-.Cm kqueue
-method or the
-.Dv SO_SNDLOWAT
-socket option.
-In both cases the specified
-.Ar size
-is used.
-This directive is ignored on Linux, Solaris, and Windows.
-.It Ic send_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 60s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a timeout for transmitting a response to the client.
-A timeout is set only between two successive write operations, not for the
-transmission of the whole response.
-If a client does not receive anything within this time, a connection is closed.
-.It Ic sendfile Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location , Ic if in location
-.El
-.Pp
-Enables or disables the use of
-.Fn sendfile .
-.It Ic sendfile_max_chunk Ar size
-.Bl -tag -width Ds -compact
-.It default: 0
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-When set to a non-zero value, limits the amount of data that can be transferred
-in a single
-.Fn sendfile
-call.
-Without the limit, one fast connection may seize the worker process entirely.
-.It Ic server Brq No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Sets configuration for a virtual server.
-There is no clear separation between IP-based (based on the IP address) and
-name-based (based on the Host request header field) virtual servers.
-Instead, the
-.Ic listen
-directives describe all addresses and ports that should accept connections for
-the server, and the
-.Ic server_name
-directive lists all server names.
-.It Ic server_name Ar name No ...
-.Bl -tag -width Ds -compact
-.It default: Qq
-.It context: Ic server
-.El
-.Pp
-Sets names of a virtual server, for example:
-.Bd -literal -offset indent
-server {
- server_name example.com www.example.com;
-}
-.Ed
-.Pp
-The first name becomes the primary server name.
-Server names can include an asterisk
-.Pq Ic *
-replacing the first or last part of a name:
-.Bd -literal -offset indent
-server {
- server_name example.com *.example.com www.example.*;
-}
-.Ed
-.Pp
-Such names are called wildcard names.
-The first two of the names mentioned above can be combined in one:
-.Bd -literal -offset indent
-server {
- server_name .example.com;
-}
-.Ed
-.Pp
-It is also possible to use regular expressions in server names, preceding the
-name with a tilde
-.Pq Ic ~ :
-.Bd -literal -offset indent
-server {
- server_name www.example.com ~^www\\d+\\.example\\.com$;
-}
-.Ed
-.Pp
-Regular expressions can contain captures (0.7.40) that can later be used in
-other directives:
-.Bd -literal -offset indent
-server {
- server_name ~^(www\\.)?(.+)$;
- location / {
- root /sites/$2;
- }
-}
-server {
- server_name _;
- location / {
- root /sites/default;
- }
-}
-.Ed
-.Pp
-Named captures in regular expressions create variables (0.8.25) that can later
-be used in other directives:
-.Bd -literal -offset indent
-server {
- server_name ~^(www\\.)?(?<domain>.+)$;
- location / {
- root /sites/$domain;
- }
-}
-server {
- server_name _;
- location / {
- root /sites/default;
- }
-}
-.Ed
-.Pp
-If the directive's parameter is set to
-.Va $hostname
-(0.9.4), the machine's hostname is inserted.
-It is also possible to specify an empty server name (0.7.11):
-.Bd -literal -offset indent
-server {
- server_name www.example.com "";
-}
-.Ed
-.Pp
-It allows this server to process requests without the Host header field -
-instead of the default server - for the given
-.Ar address Ns : Ns Ar port
-pair.
-This is the default setting.
-Before 0.8.48, the machine's hostname was used by default.
-During searching for a virtual server by name, if the name matches more than one
-of the specified variants, (e.g. both a wildcard name and regular expression
-match), the first matching variant will be chosen, in the following order of
-priority:
-.Bl -bullet
-.It
-the exact name
-.It
-the longest wildcard name starting with an asterisk, e.g.
-.Ic *.example.com
-.It
-the longest wildcard name ending with an asterisk, e.g.
-.Cm mail.*
-.It
-the first matching regular expression (in order of appearance in the
-configuration file)
-.El
-Detailed description of server names is provided in a separate document.
-.It Ic server_name_in_redirect Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables the use of the primary server name, specified by the
-.Ic server_name
-directive, in redirects issued by nginx.
-When the use of the primary server name is disabled, the name from the Host
-request header field is used.
-If this field is not present, the IP address of the server is used.
-The use of a port in redirects is controlled by the
-.Ic port_in_redirect
-directive.
-.It Ic server_names_hash_bucket_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 32 | 64 | 128
-.It context: Ic http
-.El
-.Pp
-Sets the bucket size for the server names hash tables.
-The default value depends on the size of the processor's cache line.
-The details of setting up hash tables are provided in a separate document.
-.It Ic server_names_hash_max_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 512
-.It context: Ic http
-.El
-.Pp
-Sets the maximum
-.Ar size
-of the server names hash tables.
-The details of setting up hash tables are provided in a separate document.
-.It Ic server_tokens Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables emitting nginx version in error messages and in the Server
-response header field.
-.It Ic tcp_nodelay Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables the use of the
-.Dv TCP_NODELAY
-option.
-The option is enabled only when a connection is transitioned into the keep-alive
-state.
-.It Ic tcp_nopush Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables the use of the
-.Dv TCP_NOPUSH
-socket option on FreeBSD or the
-.Dv TCP_CORK
-socket option on Linux.
-The options are enabled only when
-.Ic sendfile
-is used.
-Enabling the option allows
-.Bl -bullet
-.It
-sending the response header and the beginning of a file in one packet, on Linux
-and FreeBSD 4.*;
-.It
-sending a file in full packets.
-.El
-.It Ic try_files Ar file No ... Ar uri
-.It Ic try_files Ar file No ... = Ns Ar code
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic server , Ic location
-.El
-.Pp
-Checks the existence of files in the specified order and uses the first found
-file for request processing; the processing is performed in the current context.
-The path to a file is constructed from the
-.Ar file
-parameter according to the
-.Ic root
-and
-.Ic alias
-directives.
-It is possible to check directory's existence by specifying a slash at the end
-of a name, e.g.
-.Qq $uri/ .
-If none of the files were found, an internal redirect to the
-.Ar uri
-specified in the last parameter is made.
-For example:
-.Bd -literal -offset indent
-location /images/ {
- try_files $uri /images/default.gif;
-}
-location = /images/default.gif {
- expires 30s;
-}
-.Ed
-.Pp
-The last parameter can also point to a named location, as shown in examples
-below.
-Starting from version 0.7.51, the last parameter can also be a
-.Ar code :
-.Bd -literal -offset indent
-location / {
- try_files $uri $uri/index.html $uri.html =404;
-}
-.Ed
-.Pp
-Example in proxying Mongrel:
-.Bd -literal -offset indent
-location / {
- try_files /system/maintenance.html
- $uri $uri/index.html $uri.html
- @mongrel;
-}
-location @mongrel {
- proxy_pass http://mongrel;
-}
-.Ed
-.Pp
-Example for Drupal/FastCGI:
-.Bd -literal -offset indent
-location / {
- try_files $uri $uri/ @drupal;
-}
-location ~ \\.php$ {
- try_files $uri @drupal;
- fastcgi_pass ...;
- fastcgi_param SCRIPT_FILENAME /path/to$fastcgi_script_name;
- fastcgi_param SCRIPT_NAME $fastcgi_script_name;
- fastcgi_param QUERY_STRING $args;
- ... other fastcgi_param's
-}
-location @drupal {
- fastcgi_pass ...;
- fastcgi_param SCRIPT_FILENAME /path/to/index.php;
- fastcgi_param SCRIPT_NAME /index.php;
- fastcgi_param QUERY_STRING q=$uri&$args;
- ... other fastcgi_param's
-}
-.Ed
-.Pp
-In the following example,
-.Bd -literal -offset indent
-location / {
- try_files $uri $uri/ @drupal;
-}
-.Ed
-.Pp
-the
-.Ic try_files
-directive is equivalent to
-.Bd -literal -offset indent
-location / {
- error_page 404 = @drupal;
- log_not_found off;
-}
-.Ed
-.Pp
-And here,
-.Bd -literal -offset indent
-location ~ \\.php$ {
- try_files $uri @drupal;
- fastcgi_pass ...;
- fastcgi_param SCRIPT_FILENAME /path/to$fastcgi_script_name;
- ...
-}
-.Ed
-.Pp
-.Ic try_files
-checks the existence of the PHP file before passing the request to the FastCGI
-server.
-Example for Wordpress and Joomla:
-.Bd -literal -offset indent
-location / {
- try_files $uri $uri/ @wordpress;
-}
-location ~ \\.php$ {
- try_files $uri @wordpress;
- fastcgi_pass ...;
- fastcgi_param SCRIPT_FILENAME /path/to$fastcgi_script_name;
- ... other fastcgi_param's
-}
-location @wordpress {
- fastcgi_pass ...;
- fastcgi_param SCRIPT_FILENAME /path/to/index.php;
- ... other fastcgi_param's
-}
-.Ed
-.It Ic types Brq No ...
-.Bl -tag -width Ds -compact
-.It default:
-.Bd -literal -offset indent
- text/html html;
- image/gif gif;
- image/jpeg jpg;
-.Ed
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Maps file name extensions to MIME types of responses.
-Extensions are case-insensitive.
-Several extensions can be mapped to one type, for example:
-.Bd -literal -offset indent
-types {
- application/octet-stream bin exe dll;
- application/octet-stream deb;
- application/octet-stream dmg;
-}
-.Ed
-.Pp
-A sufficiently full mapping table is distributed with nginx in the
-.Pa conf/mime.types
-file.
-To make a particular location emit the
-application/octet-stream
-MIME type for all requests, the following configuration can be used:
-.Bd -literal -offset indent
-location /download/ {
- types { }
- default_type application/octet-stream;
-}
-.Ed
-.It Ic types_hash_bucket_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 32 | 64 | 128
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the bucket size for the types hash tables.
-The default value depends on the size of the processor's cache line.
-The details of setting up hash tables are provided in a separate document.
-.It Ic types_hash_max_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 1024
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the maximum
-.Ar size
-of the types hash tables.
-The details of setting up hash tables are provided in a separate document.
-.It Ic underscores_in_headers Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server
-.El
-.Pp
-Enables or disables the use of underscores in client request header fields.
-When the use of underscores is disabled, request header fields whose names
-contain underscores are marked as invalid and become subject to the
-.Ic ignore_invalid_headers
-directive.
-A directive can be specified on the
-.Ic server
-level in a default server.
-In this case, its value will apply to all virtual servers listening on the same
-address and port.
-.It Ic variables_hash_bucket_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 64
-.It context: Ic http
-.El
-.Pp
-Sets the bucket size for the variables hash table.
-The details of setting up hash tables are provided in a separate document.
-.It Ic variables_hash_max_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 512
-.It context: Ic http
-.El
-.Pp
-Sets the maximum
-.Ar size
-of the variables hash table.
-The details of setting up hash tables are provided in a separate document.
-.El
-.Ss Embedded Variables
-The
-.Sx Module ngx_http_core_module
-module supports embedded variables with names matching the Apache Server
-variables.
-First of all, these are variables representing client request header fields,
-such as
-.Va $http_user_agent ,
-.Va $http_cookie ,
-and so on.
-Also there are other variables:
-.Bl -tag -width Ds
-.It Va $arg_ Ns Ar name
-argument
-.Ar name
-in the request line
-.It Va $args
-arguments in the request line
-.It Va $binary_remote_addr
-client address in a binary form, value's length is always 4 bytes
-.It Va $body_bytes_sent
-number of bytes sent to a client, not counting the response header; this
-variable is compatible with the
-.Qq \&%B
-parameter of the mod_log_config Apache module
-.It Va $bytes_sent
-number of bytes sent to a client (1.3.8, 1.2.5)
-.It Va $connection
-connection serial number (1.3.8, 1.2.5)
-.It Va $connection_requests
-current number of requests made through a connection (1.3.8, 1.2.5)
-.It Va $content_length
-Content-Length request header field
-.It Va $content_type
-Content-Type request header field
-.It Va $cookie_ Ns Ar name
-the
-.Ar name
-cookie
-.It Va $document_root
-.Ic root
-or
-.Ic alias
-directive's value for the current request
-.It Va $document_uri
-same as
-.Va $uri
-.It Va $host
-in this order of precedence: host name from the request line, or host name from
-the Host request header field, or the server name matching a request
-.It Va $hostname
-host name
-.It Va $http_ Ns Ar name
-arbitrary request header field; the last part of a variable name is the field
-name converted to lower case with dashes replaced by underscores
-.It Va $https
-.Qq on
-if connection operates in SSL mode, or an empty string otherwise
-.It Va $is_args
-.Qo ? Qc
-if a request line has arguments, or an empty string otherwise
-.It Va $limit_rate
-setting this variable enables response rate limiting; see
-.Ic limit_rate
-.It Va $msec
-current time in seconds with the milliseconds resolution (1.3.9, 1.2.6)
-.It Va $nginx_version
-nginx version
-.It Va $pid
-PID of the worker process
-.It Va $pipe
-.Qq p
-if request was pipelined,
-.Qo . Qc
-otherwise (1.3.12, 1.2.7)
-.It Va $query_string
-same as
-.Va $args
-.It Va $realpath_root
-an absolute pathname corresponding to the
-.Ic root
-or
-.Ic alias
-directive's value for the current request, with all symbolic links resolved to
-real paths
-.It Va $remote_addr
-client address
-.It Va $remote_port
-client port
-.It Va $remote_user
-user name supplied with the Basic authentication
-.It Va $request
-full original request line
-.It Va $request_body
-request body
-.Pp
-The variable's value is made available in locations processed by the
-.Ic proxy_pass
-and
-.Ic fastcgi_pass
-directives.
-.It Va $request_body_file
-name of a temporary file with the request body
-.Pp
-At the end of processing, the file needs to be removed.
-To always write the request body to a file,
-.Ic client_body_in_file_only
-needs to be enabled.
-When the name of a temporary file is passed in a proxied request or in a request
-to a FastCGI server, passing the request body should be disabled by the
-.Ic proxy_pass_request_body Cm off
-and
-.Ic fastcgi_pass_request_body Cm off
-directives, respectively.
-.It Va $request_completion
-.Qq OK
-if a request has completed, or an empty string otherwise
-.It Va $request_filename
-file path for the current request, based on the
-.Ic root
-or
-.Ic alias
-directives, and the request URI
-.It Va $request_length
-request length (including request line, header, and request body) (1.3.12,
-1.2.7)
-.It Va $request_method
-request method, usually
-.Cm GET
-or
-.Cm POST
-.It Va $request_time
-request processing time in seconds with a milliseconds resolution (1.3.9,
-1.2.6); time elapsed since the first bytes were read from the client
-.It Va $request_uri
-full original request URI (with arguments)
-.It Va $scheme
-request scheme,
-.Qq http
-or
-.Qq https
-.It Va $sent_http_ Ns Ar name
-arbitrary response header field; the last part of a variable name is the field
-name converted to lower case with dashes replaced by underscores
-.It Va $server_addr
-an address of the server which accepted a request
-.Pp
-Computing a value of this variable usually requires one system call.
-To avoid a system call, the
-.Ic listen
-directives must specify addresses and use the
-.Ic bind
-parameter.
-.It Va $server_name
-name of the server which accepted a request
-.It Va $server_port
-port of the server which accepted a request
-.It Va $server_protocol
-request protocol, usually
-.Qq HTTP/1.0
-or
-.Qq HTTP/1.1
-.It Va $status
-response status (1.3.2, 1.2.2)
-.It Va $tcpinfo_rtt ,
-.Va $tcpinfo_rttvar ,
-.Va $tcpinfo_snd_cwnd ,
-.Va $tcpinfo_rcv_space
-information about the client TCP connection; available on systems that support
-the
-.Dv TCP_INFO
-socket option
-.It Va $time_iso8601
-local time in the ISO 8601 standard format (1.3.12, 1.2.7)
-.It Va $time_local
-local time in the Common Log Format (1.3.12, 1.2.7)
-.It Va $uri
-current URI in request, normalized
-.Pp
-The value of
-.Va $uri
-may change during request processing, e.g. when doing internal redirects, or
-when using index files.
-.El
-.Ss Module ngx_http_access_module
-.Bl -tag -width Ds
-.It Ic allow Ar address | Ar CIDR | Cm unix: | Cm all
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location , Ic limit_except
-.El
-.Pp
-Allows access for the specified network or address.
-If the special value
-.Cm unix:
-is specified (1.5.1), allows access for all UNIX-domain sockets.
-.It Ic deny Ar address | Ar CIDR | Cm unix: | Cm all
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location , Ic limit_except
-.El
-.Pp
-Denies access for the specified network or address.
-If the special value
-.Cm unix:
-is specified (1.5.1), denies access for all UNIX-domain sockets.
-.El
-.Ss Module ngx_http_addition_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic add_before_body Ar uri
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Adds the text returned as a result of processing a given subrequest before the
-response body.
-An empty string
-.Pq Ic ""
-as a parameter cancels addition inherited from the previous configuration
-level.
-.It Ic add_after_body Ar uri
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Adds the text returned as a result of processing a given subrequest after the
-response body.
-An empty string
-.Pq Ic ""
-as a parameter cancels addition inherited from the previous configuration
-level.
-.It Ic addition_types Ar mime-type No ...
-.Bl -tag -width Ds -compact
-.It default: text/html
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Allows adding text in responses with the specified MIME types, in addition to
-.Qq text/html .
-The special value
-.Qq *
-matches any MIME type (0.8.29).
-.El
-.Ss Module ngx_http_auth_basic_module
-.Bl -tag -width Ds
-.It Ic auth_basic Ar string | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location , Ic limit_except
-.El
-.Pp
-Enables validation of user name and password using the HTTP Basic Authentication
-protocol.
-The specified parameter is used as a realm.
-Parameter value can contain variables (1.3.10, 1.2.7).
-The special value
-.Cm off
-allows cancelling the effect of the
-.Ic auth_basic
-directive inherited from the previous configuration level.
-.It Ic auth_basic_user_file Ar file
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location , Ic limit_except
-.El
-.Pp
-Specifies a file that keeps user names and passwords, in the following format:
-.Bd -literal -offset indent
-# comment
-name1:password1
-name2:password2:comment
-name3:password3
-.Ed
-.Pp
-The following password types are supported:
-.Bl -bullet
-.It
-encrypted with the
-.Fn crypt
-function; can be generated using the
-.Ic htpasswd
-utility from the Apache HTTP Server distribution or the
-.Ic openssl passwd
-command;
-.It
-hashed with the Apache variant of the MD5-based password algorithm (apr1); can
-be generated with the same tools;
-.It
-specified by the
-.Brq Ar scheme
-data syntax (1.0.3+) as described in RFC 2307; currently implemented schemes
-include
-.Cm PLAIN
-(an example one, should not be used),
-.Cm SHA
-(1.3.13) (plain SHA-1 hashing, should not be used) and
-.Cm SSHA
-(salted SHA-1 hashing, used by some software packages, notably OpenLDAP and
-Dovecot).
-Support for
-.Cm SHA
-scheme was added only to aid in migration from other web servers.
-It should not be used for new passwords, since unsalted SHA-1 hashing that it
-employs is vulnerable to
-rainbow table
-attacks.
-.El
-.El
-.Ss Module ngx_http_auth_request_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic auth_request Ar uri | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables authorization based on the result of a subrequest and sets the URI to
-which the subrequest will be sent.
-.It Ic auth_request_set Ar variable Ar value
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the request
-.Ar variable
-to the given
-.Ar value
-after the authorization request completes.
-The value may contain variables from the authorization request, such as
-.Va $upstream_http_* .
-.El
-.Ss Module ngx_http_autoindex_module
-.Bl -tag -width Ds
-.It Ic autoindex Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables the directory listing output.
-.It Ic autoindex_exact_size Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Specifies whether exact file sizes should be output in the directory listing, or
-rather rounded to kilobytes, megabytes, and gigabytes.
-.It Ic autoindex_localtime Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Specifies whether times in the directory listing should be output in the local
-time zone or UTC.
-.El
-.Ss Module ngx_http_browser_module
-.Bl -tag -width Ds
-.It Ic ancient_browser Ar string No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-If any of the specified substrings is found in the User-Agent request header
-field, the browser will be considered ancient.
-The special string
-.Cm netscape4
-corresponds to the regular expression
-.Qq ^Mozilla Ns / Ns Oo 1-4 Oc .
-.It Ic ancient_browser_value Ar string
-.Bl -tag -width Ds -compact
-.It default: 1
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a value for the
-.Va $ancient_browser
-variables.
-.It Ic modern_browser Ar browser Ar version
-.It Ic modern_browser Cm unlisted
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Specifies a version starting from which a browser is considered modern.
-A browser can be any one of the following:
-.Cm msie ,
-.Cm gecko
-(browsers based on Mozilla),
-.Cm opera ,
-.Cm safari ,
-or
-.Cm konqueror .
-Versions can be specified in the following formats: X, X.X, X.X.X, or X.X.X.X.
-The maximum values for each of the format are 4000, 4000.99, 4000.99.99, and
-4000.99.99.99, respectively.
-The special value
-.Cm unlisted
-specifies to consider a browser as modern if it was not listed by the
-.Ic modern_browser
-and
-.Ic ancient_browser
-directives.
-Otherwise such a browser is considered ancient.
-If a request does not provide the User-Agent field in the header, the browser is
-treated as not being listed.
-.It Ic modern_browser_value Ar string
-.Bl -tag -width Ds -compact
-.It default: 1
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a value for the
-.Va $modern_browser
-variables.
-.El
-.Ss Module ngx_http_charset_module
-.Bl -tag -width Ds
-.It Ic charset Ar charset | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location , Ic if in location
-.El
-.Pp
-Adds the specified
-.Ar charset
-to the Content-Type response header field.
-If this charset is different from the charset specified in the
-.Ic source_charset
-directive, a conversion is performed.
-The parameter
-.Cm off
-cancels the addition of charset to the Content-Type response header field.
-A charset can be defined with a variable:
-.Bd -literal -offset indent
-charset $charset;
-.Ed
-.Pp
-In such a case, all possible values of a variable need to be present in the
-configuration at least once in the form of the
-.Ic charset_map ,
-.Ic charset ,
-or
-.Ic source_charset
-directives.
-For
-.Cm utf-8 ,
-.Cm windows-1251 ,
-and
-.Cm koi8-r
-charsets, it is sufficient to include the files
-.Pa conf/koi-win ,
-.Pa conf/koi-utf ,
-and
-.Pa conf/win-utf
-into configuration.
-For other charsets, simply making a fictitious conversion table works, for
-example:
-.Bd -literal -offset indent
-charset_map iso-8859-5 _ { }
-.Ed
-.Pp
-In addition, a charset can be set in the X-Accel-Charset response header field.
-This capability can be disabled using the
-.Ic proxy_ignore_headers
-and
-.Ic fastcgi_ignore_headers
-directives.
-.It Ic charset_map Ar charset1 Ar charset2 Brq No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Describes the conversion table from one charset to another.
-A reverse conversion table is built using the same data.
-Character codes are given in hexadecimal.
-Missing characters in the range 80-FF are replaced with
-.Qq ? .
-When converting from UTF-8, characters missing in a one-byte charset are
-replaced with
-.Qq &#XXXX; .
-Example:
-.Bd -literal -offset indent
-charset_map koi8-r windows-1251 {
- C0 FE ; # small yu
- C1 E0 ; # small a
- C2 E1 ; # small b
- C3 F6 ; # small ts
- ...
-}
-.Ed
-.Pp
-When describing a conversion table to UTF-8, codes for the UTF-8 charset should
-be given in the second column, for example:
-.Bd -literal -offset indent
-charset_map koi8-r utf-8 {
- C0 D18E ; # small yu
- C1 D0B0 ; # small a
- C2 D0B1 ; # small b
- C3 D186 ; # small ts
- ...
-}
-.Ed
-.Pp
-Full conversion tables from
-.Cm koi8-r
-to
-.Cm windows-1251 ,
-and from
-.Cm koi8-r
-and
-.Cm windows-1251
-to
-.Cm utf-8
-are provided in the distribution files
-.Pa conf/koi-win ,
-.Pa conf/koi-utf ,
-and
-.Pa conf/win-utf .
-.It Ic charset_types Ar mime-type No ...
-.Bl -tag -width Ds -compact
-.It default: text/html text/xml text/plain text/vnd.wap.wml
-application/javascript application/rss+xml
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables module processing in responses with the specified MIME types in addition
-to
-.Ar text/html.
-The special value
-.Qq *
-matches any MIME type (0.8.29).
-Until version 1.5.4,
-application/x-javascript
-was used as the default MIME type instead of
-application/javascript .
-.It Ic override_charset Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location , Ic if in location
-.El
-.Pp
-Determines whether a conversion should be performed for answers received from a
-proxied or FastCGI server when the answers already carry a charset in the
-Content-Type response header field.
-If conversion is enabled, a charset specified in the received response is used
-as a source charset.
-It should be noted that if a response is received in a subrequest then the
-conversion from the response charset to the main request charset is always
-performed, regardless of the
-.Ic override_charset
-directive setting.
-.It Ic source_charset Ar charset
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location , Ic if in location
-.El
-.Pp
-Defines the source charset of a response.
-If this charset is different from the charset specified in the
-.Ic charset
-directive, a conversion is performed.
-.El
-.Ss Module ngx_http_dav_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic dav_access Ar users Ns : Ns Ar permissions No ...
-.Bl -tag -width Ds -compact
-.It default: user:rw
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets access permissions for newly created files and directories, e.g.:
-.Bd -literal -offset indent
-dav_access user:rw group:rw all:r;
-.Ed
-.Pp
-If any
-.Ar group
-or
-.Cm all
-access permissions are specified then
-.Ar user
-permissions may be omitted:
-.Bd -literal -offset indent
-dav_access group:rw all:r;
-.Ed
-.It Ic dav_methods Cm off | Ar method No ...
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Allows the specified HTTP and WebDAV methods.
-The parameter
-.Cm off
-denies all methods processed by this module.
-The following methods are supported:
-.Cm PUT ,
-.Cm DELETE ,
-.Cm MKCOL ,
-.Cm COPY ,
-and
-.Cm MOVE .
-A file uploaded with the
-.Cm PUT
-method is first written to a temporary file, and then the file is renamed.
-Starting from version 0.8.9, temporary files and the persistent store can be put
-on different file systems.
-However, be aware that in this case a file is copied across two file systems
-instead of the cheap renaming operation.
-It is thus recommended that for any given location both saved files and a
-directory holding temporary files, set by the
-.Ic client_body_temp_path
-directive, are put on the same file system.
-When creating a file with the
-.Cm PUT
-method, it is possible to specify the modification date by passing it in the
-Date header field.
-.It Ic create_full_put_path Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-The WebDAV specification only allows creating files in already existing
-directories.
-This directive allows creating all needed intermediate directories.
-.It Ic min_delete_depth Ar number
-.Bl -tag -width Ds -compact
-.It default: 0
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Allows the DELETE method to remove files provided that the number of elements in
-a request path is not less than the specified number.
-For example, the directive
-.Bd -literal -offset indent
-min_delete_depth 4;
-.Ed
-.Pp
-allows removing files on requests
-.Bd -literal -offset indent
-/users/00/00/name
-/users/00/00/name/pic.jpg
-/users/00/00/page.html
-.Ed
-.Pp
-and denies the removal of
-.Bd -literal -offset indent
-/users/00/00
-.Ed
-.El
-.Ss Module ngx_http_empty_gif_module
-.Bl -tag -width Ds
-.It Ic empty_gif
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-Turns on module processing in a surrounding location.
-.El
-.Ss Module ngx_http_f4f_module
-.Em This module is only available in the commercial version of nginx.
-.Bl -tag -width Ds
-.It Ic f4f
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-Turns on module processing in the surrounding location.
-.It Ic f4f_buffer_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 512k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the size of a memory buffer used for reading the
-.Pa .f4x
-index file.
-.El
-.Ss Module ngx_http_fastcgi_module
-.Bl -tag -width Ds
-.It Ic fastcgi_bind Ar address | Cm off
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Makes outgoing connections to a FastCGI server originate from the specified
-local IP
-.Ar address.
-Parameter value can contain variables (1.3.12).
-The special value
-.Cm off
-(1.3.12) cancels the effect of the
-.Ic fastcgi_bind
-directive inherited from the previous configuration level, which allows the
-system to auto-assign the local IP address.
-.It Ic fastcgi_buffer_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 4k | 8k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the
-.Ar size
-of the buffer used for reading the first part of a response received from the
-FastCGI server.
-This part usually contains a small response header.
-By default, the buffer size is equal to the size of one buffer set by the
-.Ic fastcgi_buffers
-directive.
-It can be made smaller however.
-.It Ic fastcgi_buffering Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables buffering of responses from the FastCGI server.
-When buffering is enabled,
-nginx receives a response from the FastCGI server as
-soon as possible, saving it into the buffers set by the
-.Ic fastcgi_buffer_size
-and
-.Ic fastcgi_buffers
-directives.
-If the whole response does not fit into memory, a part of it can be saved to a
-.Ic fastcgi_temp_path
-temporary file
-on the disk.
-Writing to temporary files is controlled by the
-.Ic fastcgi_max_temp_file_size
-and
-.Ic fastcgi_temp_file_write_size
-directives.
-When buffering is disabled, a response is passed to a client synchronously,
-immediately as it is received.
-nginx will not try to read the whole response from the FastCGI server.
-The maximum size of the data that nginx can receive from the server at a time is
-set by the
-.Ic fastcgi_buffer_size
-directive.
-Buffering can also be enabled or disabled by passing
-.Cm yes
-or
-.Cm no
-in the X-Accel-Buffering response header field.
-This capability can be disabled using the
-.Ic fastcgi_ignore_headers
-directive.
-.It Ic fastcgi_buffers Ar number Ar size
-.Bl -tag -width Ds -compact
-.It default: 8 4k | 8k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the
-.Ar number
-and
-.Ar size
-of buffers used for reading a response from the FastCGI server, for a single
-connection.
-By default, the buffer size is equal to one memory page.
-This is either 4K or 8K, depending on a platform.
-.It Ic fastcgi_busy_buffers_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 8k | 16k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-When
-.Ic fastcgi_buffering
-buffering
-of responses from the FastCGI server is enabled, limits the total
-.Ar size
-of buffers that can be busy sending a response to the client while the response
-is not yet fully read.
-In the mean time, the rest of the buffers can be used for reading a response
-and, if needed, buffering part of a response to a temporary file.
-By default,
-.Ar size
-is limited by the size of two buffers set by the
-.Ic fastcgi_buffer_size
-and
-.Ic fastcgi_buffers
-directives.
-.It Ic fastcgi_cache Ar zone | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a shared memory zone used for caching.
-The same zone can be used in several places.
-The
-.Cm off
-parameter disables caching inherited from the previous configuration level.
-.It Ic fastcgi_cache_bypass Ar string No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines conditions under which the response will not be taken from a cache.
-If at least one value of the
-.Ar string
-parameters is not empty and is not equal to 0 then the response will not be
-taken from the cache:
-.Bd -literal -offset indent
-fastcgi_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
-fastcgi_cache_bypass $http_pragma $http_authorization;
-.Ed
-.Pp
-Can be used along with the
-.Ic fastcgi_no_cache
-directive.
-.It Ic fastcgi_cache_key Ar string
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a key for caching, for example
-.Bd -literal -offset indent
-fastcgi_cache_key localhost:9000$request_uri;
-.Ed
-.It Ic fastcgi_cache_lock Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-When enabled, only one request at a time will be allowed to populate a new cache
-element identified according to the
-.Ic fastcgi_cache_key
-directive by passing a request to a FastCGI server.
-Other requests of the same cache element will either wait for a response to
-appear in the cache or the cache lock for this element to be released, up to the
-time set by the
-.Ic fastcgi_cache_lock_timeout
-directive.
-.It Ic fastcgi_cache_lock_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 5s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a timeout for
-.Ic fastcgi_cache_lock .
-.It Ic fastcgi_cache_methods Cm GET | Cm HEAD | Cm POST No ...
-.Bl -tag -width Ds -compact
-.It default: Cm GET Cm HEAD
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-If the client request method is listed in this directive then the response will
-be cached.
-.Cm GET
-and
-.Cm HEAD
-methods are always added to the list, though it is recommended to specify them
-explicitly.
-See also the
-.Ic fastcgi_no_cache
-directive.
-.It Ic fastcgi_cache_min_uses Ar number
-.Bl -tag -width Ds -compact
-.It default: 1
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the
-.Ar number
-of requests after which the response will be cached.
-.It Ic fastcgi_cache_path Ar path Oo Cm levels Ns = Ns Ar levels Oc Cm keys_zone Ns = Ns Ar name Ns : Ns Ar size Oo Cm inactive Ns = Ns Ar time Oc Oo Cm max_size Ns = Ns Ar size Oc Oo Cm loader_files Ns = Ns Ar number Oc Oo Cm loader_sleep Ns = Ns Ar time Oc Oo Cm loader_threshold Ns = Ns Ar time Oc
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Sets the path and other parameters of a cache.
-Cache data are stored in files.
-Both the key and file name in a cache are a result of applying the MD5 function
-to the proxied URL.
-The
-.Ar levels
-parameter defines hierarchy levels of a cache.
-For example, in the following configuration
-.Bd -literal -offset indent
-fastcgi_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m;
-.Ed
-.Pp
-file names in a cache will look like this:
-.Bd -literal -offset indent
-/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c
-.Ed
-.Pp
-A cached response is first written to a temporary file, and then the file is
-renamed.
-Starting from version 0.8.9, temporary files and the cache can be put on
-different file systems.
-However, be aware that in this case a file is copied across two file systems
-instead of the cheap renaming operation.
-It is thus recommended that for any given location both cache and a directory
-holding temporary files, set by the
-.Ic fastcgi_temp_path
-directive, are put on the same file system.
-In addition, all active keys and information about data are stored in a shared
-memory zone, whose
-.Ar name
-and
-.Ar size
-are configured by the
-.Cm keys_zone
-parameter.
-Cached data that are not accessed during the time specified by the
-.Cm inactive
-parameter get removed from the cache regardless of their freshness.
-By default,
-.Cm inactive
-is set to 10 minutes.
-The special cache manager process monitors the maximum cache size set by the
-.Cm max_size
-parameter.
-When this size is exceeded, it removes the least recently used data.
-A minute after the start the special cache loader process is activated.
-It loads information about previously cached data stored on file system into a
-cache zone.
-The loading is done in iterations.
-During one iteration no more than
-.Cm loader_files
-items are loaded (by default, 100).
-Besides, the duration of one iteration is limited by the
-.Cm loader_threshold
-parameter (by default, 200 milliseconds).
-Between iterations, a pause configured by the
-.Cm loader_sleep
-parameter (by default, 50 milliseconds) is made.
-.It Ic fastcgi_cache_use_stale Cm error | Cm timeout | Cm invalid_header | Cm updating | Cm http_500 | Cm http_503 | Cm http_403 | Cm http_404 | Cm off No ...
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Determines in which cases a stale cached response can be used when an error
-occurs during communication with the FastCGI server.
-The directive's parameters match the parameters of the
-.Ic fastcgi_next_upstream
-directive.
-Additionally, the
-.Cm updating
-parameter permits using a stale cached response if it is currently being
-updated.
-This allows minimizing the number of accesses to FastCGI servers when updating
-cached data.
-To minimize the number of accesses to FastCGI servers when populating a new
-cache element, the
-.Ic fastcgi_cache_lock
-directive can be used.
-.It Ic fastcgi_cache_valid Oo Ar code No ... Oc Ar time
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets caching time for different response codes.
-For example, the following directives
-.Bd -literal -offset indent
-fastcgi_cache_valid 200 302 10m;
-fastcgi_cache_valid 404 1m;
-.Ed
-.Pp
-set 10 minutes of caching for responses with codes 200 and 302 and 1 minute for
-responses with code 404.
-If only caching
-.Ar time
-is specified
-.Bd -literal -offset indent
-fastcgi_cache_valid 5m;
-.Ed
-.Pp
-then only 200, 301, and 302 responses are cached.
-In addition, the
-.Cm any
-parameter can be specified to cache any responses:
-.Bd -literal -offset indent
-fastcgi_cache_valid 200 302 10m;
-fastcgi_cache_valid 301 1h;
-fastcgi_cache_valid any 1m;
-.Ed
-.Pp
-Parameters of caching can also be set directly in the response header.
-This has higher priority than setting of caching time using the directive.
-The X-Accel-Expires header field sets caching time of a response in seconds.
-The zero value disables caching for a response.
-If a value starts with the
-.Qq @
-prefix, it sets an absolute time in seconds since Epoch, up to which the
-response may be cached.
-If header does not include the X-Accel-Expires field, parameters of caching may
-be set in the header fields Expires or Cache-Control .
-If a header includes the Set-Cookie field, such a response will not be cached.
-Processing of one or more of these response header fields can be disabled using
-the
-.Ic fastcgi_ignore_headers
-directive.
-.It Ic fastcgi_catch_stderr Ar string
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a string to search for in the error stream of a response received from a
-FastCGI server.
-If the
-.Ar string
-is found then it is considered that the FastCGI server has returned an
-.Ic fastcgi_next_upstream
-invalid response.
-This allows handling application errors in nginx, for example:
-.Bd -literal -offset indent
-location /php {
- fastcgi_pass backend:9000;
- ...
- fastcgi_catch_stderr "PHP Fatal error";
- fastcgi_next_upstream error timeout invalid_header;
-}
-.Ed
-.It Ic fastcgi_connect_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 60s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a timeout for establishing a connection with a FastCGI server.
-It should be noted that this timeout cannot usually exceed 75 seconds.
-.It Ic fastcgi_hide_header Ar field
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-By default, nginx does not pass the header fields Status and X-Accel-...
-from the response of a FastCGI server to a client.
-The
-.Ic fastcgi_hide_header
-directive sets additional fields that will not be passed.
-If, on the contrary, the passing of fields needs to be permitted, the
-.Ic fastcgi_pass_header
-directive can be used.
-.It Ic fastcgi_ignore_client_abort Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Determines whether the connection with a FastCGI server should be closed when a
-client closes a connection without waiting for a response.
-.It Ic fastcgi_ignore_headers Ar field No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Disables processing of certain response header fields from the FastCGI server.
-The following fields can be ignored: X-Accel-Redirect, X-Accel-Expires,
-X-Accel-Limit-Rate (1.1.6), X-Accel-Buffering (1.1.6), X-Accel-Charset (1.1.6),
-Expires, Cache-Control and Set-Cookie (0.8.44).
-If not disabled, processing of these header fields has the following effect:
-.Bl -bullet
-.It
-X-Accel-Expires, Expires, Cache-Control and Set-Cookie set the parameters of
-response
-.Ic fastcgi_cache_valid
-caching;
-.It
-X-Accel-Redirect performs an
-.Ic internal
-redirect
-to the specified URI;
-.It
-X-Accel-Limit-Rate sets the
-.Ic limit_rate
-rate
-limit
-for transmission of a response to a client;
-.It
-X-Accel-Buffering enables or disables
-.Ic fastcgi_buffering
-buffering
-of a response;
-.It
-X-Accel-Charset sets the desired
-.Ic charset
-of a response.
-.El
-.It Ic fastcgi_index Ar name
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a file name that will be appended after a URI that ends with a slash, in
-the value of the
-.Va $fastcgi_script_name
-variable.
-For example, with these settings
-.Bd -literal -offset indent
-fastcgi_index index.php;
-fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
-.Ed
-.Pp
-and the
-.Qq /page.php
-request, the SCRIPT_FILENAME parameter will be equal to
-.Pa /home/www/scripts/php/page.php ,
-and with the
-.Qq /
-request it will be equal to
-.Pa /home/www/scripts/php/index.php .
-.It Ic fastcgi_intercept_errors Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Determines whether FastCGI server responses with codes greater than or equal to
-300 should be passed to a client or be redirected to nginx for processing with
-the
-.Ic error_page
-directive.
-.It Ic fastcgi_keep_conn Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-By default, a FastCGI server will close a connection right after sending the
-response.
-However, when this directive is set to the value
-.Cm on ,
-nginx will instruct a FastCGI server to keep connections open.
-This is necessary, in particular, for
-.Ic keepalive
-connections to FastCGI servers to function.
-.It Ic fastcgi_max_temp_file_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 1024m
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-When buffering of responses from the FastCGI server is enabled, and the whole
-response does not fit into the memory buffers set by the
-.Ic fastcgi_buffer_size
-and
-.Ic fastcgi_buffers
-directives, a part of the response can be saved to a temporary file.
-This directive sets the maximum
-.Ar size
-of a temporary file.
-The size of data written to a temporary file at a time is set by the
-.Ic fastcgi_temp_file_write_size
-directive.
-The zero value disables buffering of responses to temporary files.
-.It Ic fastcgi_next_upstream Cm error | Cm timeout | Cm invalid_header | Cm http_500 | Cm http_503 | Cm http_403 | Cm http_404 | Cm off No ...
-.Bl -tag -width Ds -compact
-.It default: Cm error Cm timeout
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Specifies in which cases a request should be passed to the next server:
-.Bl -tag -width Ds
-.It Cm error
-an error occurred while establishing a connection with the server, passing a
-request to it, or reading the response header;
-.It Cm timeout
-a timeout has occurred while establishing a connection with the server, passing
-a request to it, or reading the response header;
-.It Cm invalid_header
-a server returned an empty or invalid response;
-.It Cm http_500
-a server returned a response with the code 500;
-.It Cm http_503
-a server returned a response with the code 503;
-.It Cm http_403
-a server returned a response with the code 403;
-.It Cm http_404
-a server returned a response with the code 404;
-.It Cm off
-disables passing a request to the next server.
-.El
-.Pp
-One should bear in mind that passing a request to the next server is only
-possible if nothing has been sent to a client yet.
-That is, if an error or timeout occurs in the middle of the transferring of a
-response, fixing this is impossible.
-The directive also defines what is considered an unsuccessful attempt of
-communication with a server.
-The cases of
-.Cm error ,
-.Cm timeout
-and
-.Cm invalid_header
-are always considered unsuccessful attempts, even if they are not specified in
-the directive.
-The cases of
-.Cm http_500
-and
-.Cm http_503
-are considered unsuccessful attempts only if they are specified in the
-directive.
-The cases of
-.Cm http_403
-and
-.Cm http_404
-are never considered unsuccessful attempts.
-.It Ic fastcgi_no_cache Ar string No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines conditions under which the response will not be saved to a cache.
-If at least one value of the
-.Ar string
-parameters is not empty and is not equal to 0 then the response will not be
-saved:
-.Bd -literal -offset indent
-fastcgi_no_cache $cookie_nocache $arg_nocache$arg_comment;
-fastcgi_no_cache $http_pragma $http_authorization;
-.Ed
-.Pp
-Can be used along with the
-.Ic fastcgi_cache_bypass
-directive.
-.It Ic fastcgi_param Ar parameter Ar value Oo Cm if_not_empty Oc
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a
-.Ar parameter
-that should be passed to the FastCGI server.
-A
-.Ar value
-can contain text, variables, and their combination.
-These directives are inherited from the previous level if and only if there are
-no
-.Ic fastcgi_param
-directives defined on the current level.
-The following example shows the minimum required settings for PHP:
-.Bd -literal -offset indent
-fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
-fastcgi_param QUERY_STRING $query_string;
-.Ed
-.Pp
-The SCRIPT_FILENAME parameter is used in PHP for determining the script name,
-and the QUERY_STRING parameter is used to pass request parameters.
-For scripts that process POST requests, the following three parameters are
-also required:
-.Bd -literal -offset indent
-fastcgi_param REQUEST_METHOD $request_method;
-fastcgi_param CONTENT_TYPE $content_type;
-fastcgi_param CONTENT_LENGTH $content_length;
-.Ed
-.Pp
-If PHP was built with the
-.Fl -enable-force-cgi-redirect
-configuration parameter, the REDIRECT_STATUS parameter should also be passed
-with the value 200:
-.Bd -literal -offset indent
-fastcgi_param REDIRECT_STATUS 200;
-.Ed
-.Pp
-If a directive is specified with
-.Cm if_not_empty
-(1.1.11) then such a parameter will not be passed to the server until its value
-is not empty:
-.Bd -literal -offset indent
-fastcgi_param HTTPS $https if_not_empty;
-.Ed
-.It Ic fastcgi_pass Ar address
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location , Ic if in location
-.El
-.Pp
-Sets the address of a FastCGI server.
-The address can be specified as a domain name or IP address, and an optional
-port:
-.Bd -literal -offset indent
-fastcgi_pass localhost:9000;
-.Ed
-.Pp
-or as a UNIX-domain socket path:
-.Bd -literal -offset indent
-fastcgi_pass unix:/tmp/fastcgi.socket;
-.Ed
-.Pp
-If a domain name resolves to several addresses, all of them will be used in a
-round-robin fashion.
-In addition, an address can be specified as a server group.
-.It Ic fastcgi_pass_header Ar field
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Permits passing
-.Ic fastcgi_hide_header
-otherwise disabled
-header fields from a FastCGI server to a client.
-.It Ic fastcgi_read_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 60s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a timeout for reading a response from the FastCGI server.
-A timeout is set only between two successive read operations, not for the
-transmission of the whole response.
-If a FastCGI server does not transmit anything within this time, a connection is
-closed.
-.It Ic fastcgi_pass_request_body Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Indicates whether the original request body is passed to the FastCGI server.
-See also the
-.Ic fastcgi_pass_request_headers
-directive.
-.It Ic fastcgi_pass_request_headers Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Indicates whether the header fields of the original request are passed to the
-FastCGI server.
-See also the
-.Ic fastcgi_pass_request_body
-directive.
-.It Ic fastcgi_send_lowat Ar size
-.Bl -tag -width Ds -compact
-.It default: 0
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-If the directive is set to a non-zero value, nginx will try to minimize the
-number of send operations on outgoing connections to a FastCGI server by using
-either
-.Dv NOTE_LOWAT
-flag of the
-.Cm kqueue
-method, or the
-.Dv SO_SNDLOWAT
-socket option, with the specified
-.Ar size .
-This directive is ignored on Linux, Solaris, and Windows.
-.It Ic fastcgi_send_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 60s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a timeout for transmitting a request to the FastCGI server.
-A timeout is set only between two successive write operations, not for the
-transmission of the whole request.
-If a FastCGI server does not receive anything within this time, a connection is
-closed.
-.It Ic fastcgi_split_path_info Ar regex
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-Defines a regular expression that captures a value for the
-.Va $fastcgi_path_info
-variable.
-A regular expression should have two captures: the first becomes a value of the
-.Va $fastcgi_script_name
-variable, the second becomes a value of the
-.Va $fastcgi_path_info
-variable.
-For example, with these settings
-.Bd -literal -offset indent
-location ~ ^(.+\\.php)(.*)$ {
- fastcgi_split_path_info ^(.+\\.php)(.*)$;
- fastcgi_param SCRIPT_FILENAME /path/to/php$fastcgi_script_name;
- fastcgi_param PATH_INFO $fastcgi_path_info;
-.Ed
-.Pp
-and the
-.Qq /show.php/article/0001
-request, the SCRIPT_FILENAME
-parameter will be equal to
-.Pa /path/to/php/show.php ,
-and the PATH_INFO
-parameter will be equal to
-.Pa /article/0001 .
-.It Ic fastcgi_store Cm on | Cm off | Ar string
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables saving of files to a disk.
-The
-.Cm on
-parameter saves files with paths corresponding to the directives
-.Ic alias
-or
-.Ic root.
-The
-.Cm off
-parameter disables saving of files.
-In addition, the file name can be set explicitly using the
-.Ar string
-with variables:
-.Bd -literal -offset indent
-fastcgi_store /data/www$original_uri;
-.Ed
-.Pp
-The modification time of files is set according to the received Last-Modified
-response header field.
-A response is first written to a temporary file, and then the file is renamed.
-Starting from version 0.8.9, temporary files and the persistent store can be put
-on different file systems.
-However, be aware that in this case a file is copied across two file systems
-instead of the cheap renaming operation.
-It is thus recommended that for any given location both saved files and a
-directory holding temporary files, set by the
-.Ic fastcgi_temp_path
-directive, are put on the same file system.
-This directive can be used to create local copies of static unchangeable files,
-e.g.:
-.Bd -literal -offset indent
-location /images/ {
- root /data/www;
- open_file_cache_errors off;
- error_page 404 = /fetch$uri;
-}
-location /fetch/ {
- internal;
- fastcgi_pass backend:9000;
- ...
- fastcgi_store on;
- fastcgi_store_access user:rw group:rw all:r;
- fastcgi_temp_path /data/temp;
- alias /data/www/;
-}
-.Ed
-.It Ic fastcgi_store_access Ar users Ns : Ns Ar permissions No ...
-.Bl -tag -width Ds -compact
-.It default: user:rw
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets access permissions for newly created files and directories, e.g.:
-.Bd -literal -offset indent
-fastcgi_store_access user:rw group:rw all:r;
-.Ed
-.Pp
-If any
-.Ar group
-or
-.Cm all
-access permissions are specified then
-.Ar user
-permissions may be omitted:
-.Bd -literal -offset indent
-fastcgi_store_access group:rw all:r;
-.Ed
-.It Ic fastcgi_temp_file_write_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 8k | 16k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Limits the
-.Ar size
-of data written to a temporary file at a time, when buffering of responses from
-the FastCGI server to temporary files is enabled.
-By default,
-.Ar size
-is limited by two buffers set by the
-.Ic fastcgi_buffer_size
-and
-.Ic fastcgi_buffers
-directives.
-The maximum size of a temporary file is set by the
-.Ic fastcgi_max_temp_file_size
-directive.
-.It Ic fastcgi_temp_path Ar path Oo Ar level1 Oo Ar level2 Oo Ar level3 Oc Oc Oc
-.Bl -tag -width Ds -compact
-.It default: fastcgi_temp
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a directory for storing temporary files with data received from FastCGI
-servers.
-Up to three-level subdirectory hierarchy can be used underneath the specified
-directory.
-For example, in the following configuration
-.Bd -literal -offset indent
-fastcgi_temp_path /spool/nginx/fastcgi_temp 1 2;
-.Ed
-.Pp
-a temporary file might look like this:
-.Bd -literal -offset indent
-/spool/nginx/fastcgi_temp/7/45/00000123457
-.Ed
-.El
-.Ss Module ngx_http_flv_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic flv
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-Turns on module processing in a surrounding location.
-.El
-.Ss Module ngx_http_geo_module
-.Bl -tag -width Ds
-.It Ic geo Oo Ar $address Oc Ar $variable Brq No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Describes the dependency of values of the specified variable on the client IP
-address.
-By default, the address is taken from the
-.Va $remote_addr
-variable, but it can also be taken from another variable (0.7.27), for example:
-.Bd -literal -offset indent
-geo $arg_remote_addr $geo {
- ...;
-}
-.Ed
-.Pp
-Since variables are evaluated only when used, the mere existence of even a large
-number of declared
-.Ic geo
-variables does not cause any extra costs for request processing.
-If the value of a variable does not represent a valid IP address then the
-255.255.255.255
-address is used.
-Addresses are specified either as prefixes in CIDR notation (including
-individual addresses) or as ranges (0.7.23).
-IPv6 prefixes are supported starting from versions 1.3.10 and 1.2.7.
-The following special parameters are also supported:
-.Bl -tag -width Ds
-.It Cm delete
-deletes the specified network (0.7.23).
-.It Cm default
-a value set to the variable if the client address does not match any of the
-specified addresses.
-When addresses are specified in CIDR notation,
-0.0.0.0/0
-and
-::/0
-can be used instead of
-.Cm default.
-When
-.Cm default
-is not specified, the default value will be an empty string.
-.It Cm include
-includes a file with addresses and values.
-There can be several inclusions.
-.It Cm proxy
-defines trusted addresses (0.8.7, 0.7.63).
-When a request comes from a trusted address, an address from the X-Forwarded-For
-request header field will be used instead.
-In contrast to the regular addresses, trusted addresses are checked
-sequentially.
-Trusted IPv6 addresses are supported starting from versions 1.3.0 and 1.2.1.
-.It Cm proxy_recursive
-enables recursive address search (1.3.0, 1.2.1).
-If recursive search is disabled then instead of the original client address that
-matches one of the trusted addresses, the last address sent in X-Forwarded-For
-will be used.
-If recursive search is enabled then instead of the original client address that
-matches one of the trusted addresses, the last non-trusted address sent in
-X-Forwarded-For will be used.
-.It Cm ranges
-indicates that addresses are specified as ranges (0.7.23).
-This parameter should be the first.
-To speed up loading of a geo base, addresses should be put in ascending order.
-.El
-.Pp
-Example:
-.Bd -literal -offset indent
-geo $country {
- default ZZ;
- include conf/geo.conf;
- delete 127.0.0.0/16;
- proxy 192.168.100.0/24;
- proxy 2001:0db8::/32;
- 127.0.0.0/24 US;
- 127.0.0.1/32 RU;
- 10.1.0.0/16 RU;
- 192.168.1.0/24 UK;
-}
-.Ed
-.Pp
-The
-.Pa conf/geo.conf
-file could contain the following lines:
-.Bd -literal -offset indent
-10.2.0.0/16 RU;
-192.168.2.0/24 RU;
-.Ed
-.Pp
-A value of the most specific match is used.
-For example, for the 127.0.0.1 address the value
-RU
-will be chosen, not
-US .
-Example with ranges:
-.Bd -literal -offset indent
-geo $country {
- ranges;
- default ZZ;
- 127.0.0.0-127.0.0.0 US;
- 127.0.0.1-127.0.0.1 RU;
- 127.0.0.1-127.0.0.255 US;
- 10.1.0.0-10.1.255.255 RU;
- 192.168.1.0-192.168.1.255 UK;
-}
-.Ed
-.El
-.Ss Module ngx_http_geoip_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic geoip_country Ar file
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Specifies a database used to determine the country depending on the client IP
-address.
-The following variables are available when using this database:
-.Bl -tag -width Ds
-.It Va $geoip_country_code
-two-letter country code, for example, RU, US.
-.It Va $geoip_country_code3
-three-letter country code, for example, RUS, USA.
-.It Va $geoip_country_name
-country name, for example, Russian Federation, United States.
-.El
-.It Ic geoip_city Ar file
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Specifies a database used to determine the country, region, and city depending
-on the client IP address.
-The following variables are available when using this database:
-.Bl -tag -width Ds
-.It Va $geoip_area_code
-telephone area code (US only).
-This variable may contain outdated information since the corresponding database
-field is deprecated.
-.It Va $geoip_city_continent_code
-two-letter continent code, for example, EU, NA.
-.It Va $geoip_city_country_code
-two-letter country code, for example, RU, US.
-.It Va $geoip_city_country_code3
-three-letter country code, for example, RUS, USA.
-.It Va $geoip_city_country_name
-country name, for example, Russian Federation, United States.
-.It Va $geoip_dma_code
-DMA region code in US (also known as metro code), according to the
-geotargeting in Google AdWords API.
-.It Va $geoip_latitude
-latitude.
-.It Va $geoip_longitude
-longitude.
-.It Va $geoip_region
-two-symbol country region code (region, territory, state, province, federal
-land and the like), for example, 48, DC.
-.It Va $geoip_region_name
-country region name (region, territory, state, province, federal land and the
-like), for example, Moscow City, District of Columbia.
-.It Va $geoip_city
-city name, for example, Moscow, Washington.
-.It Va $geoip_postal_code
-postal code.
-.El
-.It Ic geoip_org Ar file
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Specifies a database used to determine the organization depending on the client
-IP address.
-The following variable is available when using this database:
-.Bl -tag -width Ds
-.It Va $geoip_org
-organization name, for example, The University of Melbourne.
-.El
-.It Ic geoip_proxy Ar address | Ar CIDR
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Defines trusted addresses.
-When a request comes from a trusted address, an address from the X-Forwarded-For
-request header field will be used instead.
-.It Ic geoip_proxy_recursive Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http
-.El
-.Pp
-If recursive search is disabled then instead of the original client address that
-matches one of the trusted addresses, the last address sent in X-Forwarded-For
-will be used.
-If recursive search is enabled then instead of the original client address that
-matches one of the trusted addresses, the last non-trusted address sent in
-X-Forwarded-For will be used.
-.El
-.Ss Module ngx_http_gunzip_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic gunzip Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables decompression of gzipped responses for clients that lack
-gzip support.
-If enabled, the following directives are also taken into account when
-determining if clients support gzip:
-.Ic gzip_http_version ,
-.Ic gzip_proxied ,
-and
-.Ic gzip_disable .
-See also the
-.Ic gzip_vary
-directive.
-.It Ic gunzip_buffers Ar number Ar size
-.Bl -tag -width Ds -compact
-.It default: 32 4k | 16 8k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the
-.Ar number
-and
-.Ar size
-of buffers used to decompress a response.
-By default, the buffer size is equal to one memory page.
-This is either 4K or 8K, depending on a platform.
-.El
-.Ss Module ngx_http_gzip_module
-.Bl -tag -width Ds
-.It Ic gzip Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location , Ic if in location
-.El
-.Pp
-Enables or disables gzipping of responses.
-.It Ic gzip_buffers Ar number Ar size
-.Bl -tag -width Ds -compact
-.It default: 32 4k | 16 8k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the
-.Ar number
-and
-.Ar size
-of buffers used to compress a response.
-By default, the buffer size is equal to one memory page.
-This is either 4K or 8K, depending on a platform.
-Until version 0.7.28, four 4K or 8K buffers were used by default.
-.It Ic gzip_comp_level Ar level
-.Bl -tag -width Ds -compact
-.It default: 1
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a gzip compression
-.Ar level
-of a response.
-Acceptable values are in the range from 1 to 9.
-.It Ic gzip_disable Ar regex No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Disables gzipping of responses for requests with User-Agent header fields
-matching any of the specified regular expressions.
-The special mask
-.Cm msie6
-(0.7.12) corresponds to the regular expression
-.Qq MSIE Ns Oo 4-6 Oc \\. ,
-but works faster.
-Starting from version 0.8.11,
-.Qq MSIE 6.0; ... SV1
-is excluded from this mask.
-.It Ic gzip_min_length Ar length
-.Bl -tag -width Ds -compact
-.It default: 20
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the minimum length of a response that will be gzipped.
-The length is determined only from the Content-Length response header field.
-.It Ic gzip_http_version Cm 1.0 | Cm 1.1
-.Bl -tag -width Ds -compact
-.It default: 1.1
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the minimum HTTP version of a request required to compress a response.
-.It Ic gzip_proxied Cm off | Cm expired | Cm no-cache | Cm no-store | Cm private | Cm no_last_modified | Cm no_etag | Cm auth | Cm any No ...
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables gzipping of responses for proxied requests depending on the
-request and response.
-The fact that the response is proxied is determined by the presence of the Via
-request header field.
-A directive accepts multiple parameters:
-.Bl -tag -width Ds
-.It Cm off
-disables compression for all proxied requests, ignoring other parameters;
-.It Cm expired
-enables compression if a response header includes the Expires field with a value
-that disables caching;
-.It Cm no-cache
-enables compression if a response header includes the Cache-Control field with
-the
-.Cm no-cache
-parameter;
-.It Cm no-store
-enables compression if a response header includes the Cache-Control field with
-the
-.Cm no-store
-parameter;
-.It Cm private
-enables compression if a response header includes the Cache-Control field with
-the
-.Cm private
-parameter;
-.It Cm no_last_modified
-enables compression if a response header does not include the Last-Modified
-field;
-.It Cm no_etag
-enables compression if a response header does not include the ETag field;
-.It Cm auth
-enables compression if a request header includes the Authorization field;
-.It Cm any
-enables compression for all proxied requests.
-.El
-.It Ic gzip_types Ar mime-type No ...
-.Bl -tag -width Ds -compact
-.It default: text/html
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables gzipping of responses for the specified MIME types in addition to
-.Ar text/html .
-The special value
-.Qq *
-matches any MIME type (0.8.29).
-Responses with the
-.Ar text/html
-type are always compressed.
-.It Ic gzip_vary Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables inserting the Vary: Accept-Encoding response header field if
-the directives
-.Ic gzip ,
-.Ic gzip_static ,
-or
-.Ic gunzip
-are active.
-.El
-.Ss Module ngx_http_gzip_static_module
-.Bl -tag -width Ds
-.It Ic gzip_static Cm on | Cm off | Cm always
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables
-.Pq Ic on
-or disables
-.Pq Ic off
-checking the existence of precompressed files.
-The following directives are also taken into account:
-.Ic gzip_http_version ,
-.Ic gzip_proxied ,
-.Ic gzip_disable ,
-and
-.Ic gzip_vary .
-With the
-.Cm always
-value (1.3.6), gzipped file is used in all cases, without checking if the client
-supports it.
-It is useful if there are no uncompressed files on the disk anyway or the
-.Sx Module ngx_http_gunzip_module
-is used.
-The files can be compressed using the
-.Ic gzip
-command, or any other compatible one.
-It is recommended that the modification date and time of original and compressed
-files be the same.
-.El
-.Ss Module ngx_http_headers_module
-.Bl -tag -width Ds
-.It Ic add_header Ar name Ar value
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location , Ic if in location
-.El
-.Pp
-Adds the specified field to a response header provided that the response code
-equals 200, 201, 204, 206, 301, 302, 303, 304, or 307.
-A value can contain variables.
-.It Ic expires Oo Cm modified Oc Ar time
-.It Ic expires Cm epoch | Cm max | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location , Ic if in location
-.El
-.Pp
-Enables or disables adding or modifying the Expires and Cache-Control response
-header fields provided that the response code equals 200, 201, 204, 206, 301,
-302, 303, 304, or 307.
-A parameter can be a positive or negative
-.Ar time .
-A time in the Expires field is computed as a sum of the current time and
-.Ar time
-specified in the directive.
-If the
-.Cm modified
-parameter is used (0.7.0, 0.6.32) then time is computed as a sum of the file's
-modification time and
-.Ar time
-specified in the directive.
-In addition, it is possible to specify a time of the day using the
-.Qq @
-prefix (0.7.9, 0.6.34):
-.Bd -literal -offset indent
-expires @15h30m;
-.Ed
-.Pp
-The
-.Cm epoch
-parameter corresponds to the absolute time
-Thu, 01 Jan 1970 00:00:01 GMT.
-The contents of the Cache-Control field depends on the sign of the specified
-time:
-.Bl -bullet
-.It
-time is negative - Cache-Control: no-cache.
-.It
-time is positive or zero - Cache-Control: max-age=t, where t is a time
-specified in the directive, in seconds.
-.El
-.Pp
-The
-.Cm max
-parameter sets Expires to the value
-.Qq Thu, 31 Dec 2037 23:55:55 GMT ,
-and Cache-Control to 10 years.
-The
-.Cm off
-parameter disables adding or modifying the Expires and Cache-Control response
-header fields.
-.El
-.Ss Module ngx_http_hls_module
-.Em This module is only available in the commercial version of nginx.
-.Bl -tag -width Ds
-.It Ic hls
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-Turns on HLS streaming in the surrounding location.
-.It Ic hls_buffers Ar number Ar size
-.Bl -tag -width Ds -compact
-.It default: 8 2m
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the maximum
-.Ar number
-and
-.Ar size
-of buffers that are used for reading and writing data frames.
-.It Ic hls_fragment Ar time
-.Bl -tag -width Ds -compact
-.It default: 5s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines the default fragment length for playlist URIs requested without the
-len
-argument.
-.It Ic hls_mp4_buffer_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 512k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the initial
-.Ar size
-of the memory buffer used to process MP4 files.
-.It Ic hls_mp4_max_buffer_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 10m
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-During metadata processing, a larger buffer may become necessary.
-Its size cannot exceed the specified
-.Ar size ,
-or else nginx will return the server error 500 (Internal Server Error), and
-log the following message:
-.Bd -literal -offset indent
-"/some/movie/file.mp4" mp4 moov atom is too large:
-12583268, you may want to increase hls_mp4_max_buffer_size
-.Ed
-.El
-.Ss Module ngx_http_image_filter_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic image_filter Cm off
-.It Ic image_filter Cm test
-.It Ic image_filter Cm size
-.It Ic image_filter Cm rotate Cm 90 | Cm 180 | Cm 270
-.It Ic image_filter Cm resize Ar width Ar height
-.It Ic image_filter Cm crop Ar width Ar height
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic location
-.El
-.Pp
-Sets the type of transformation to perform on images:
-.Bl -tag -width Ds
-.It Cm off
-turns off module processing in a surrounding location.
-.It Cm test
-ensures that responses are images in either JPEG, GIF, or PNG format.
-Otherwise, the 415 (Unsupported Media Type) error is returned.
-.It Cm size
-outputs information about images in a JSON format, e.g.:
-.Bd -literal -offset indent
-{ "img" : { "width": 100, "height": 100, "type": "gif" } }
-.Ed
-.Pp
-In case of an error, the output is as follows:
-.Bd -literal -offset indent
-{}
-.Ed
-.It Cm rotate Cm 90 | Cm 180 | Cm 270
-rotates images counter-clockwise by the specified number of degrees.
-Parameter value can contain variables.
-This mode can be used either alone or along with the
-.Cm resize
-and
-.Cm crop
-transformations.
-.It Cm resize Ar width Ar height
-proportionally reduces an image to the specified sizes.
-To reduce by only one dimension, another dimension can be specified as
-.Qq - .
-In case of an error, the server will return code 415 (Unsupported Media Type).
-Parameter values can contain variables.
-When used along with the
-.Cm rotate
-parameter, the rotation happens after reduction.
-.It Cm crop Ar width Ar height
-proportionally reduces an image to the larger side size and crops extraneous
-edges by another side.
-To reduce by only one dimension, another dimension can be specified as
-.Qq - .
-In case of an error, the server will return code 415 (Unsupported Media Type).
-Parameter values can contain variables.
-When used along with the
-.Cm rotate
-parameter, the rotation happens before reduction.
-.El
-.It Ic image_filter_buffer Ar size
-.Bl -tag -width Ds -compact
-.It default: 1M
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the maximum size of the buffer used for reading images.
-When the size is exceeded the server returns error 415 (Unsupported Media Type).
-.It Ic image_filter_interlace Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-If enabled, final images will be interlaced.
-For JPEG, final images will be in progressive JPEG format.
-.It Ic image_filter_jpeg_quality Ar quality
-.Bl -tag -width Ds -compact
-.It default: 75
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the desired
-.Ar quality
-of the transformed JPEG images.
-Acceptable values are in the range from 1 to 100.
-Lesser values usually imply both lower image quality and less data to transfer.
-The maximum recommended value is 95.
-Parameter value can contain variables.
-.It Ic image_filter_sharpen Ar percent
-.Bl -tag -width Ds -compact
-.It default: 0
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Increases sharpness of the final image.
-The sharpness percentage can exceed 100.
-The zero value disables sharpening.
-Parameter value can contain variables.
-.It Ic image_filter_transparency Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines whether transparency should be preserved when transforming GIF images or
-PNG images with colors specified by a palette.
-The loss of transparency results in images of a better quality.
-The alpha channel transparency in PNG is always preserved.
-.El
-.Ss Module ngx_http_index_module
-.Bl -tag -width Ds
-.It Ic index Ar file No ...
-.Bl -tag -width Ds -compact
-.It default: Pa index.html
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines files that will be used as an index.
-The
-.Ar file
-name can contain variables.
-Files are checked in the specified order.
-The last element of the list can be a file with an absolute path.
-Example:
-.Bd -literal -offset indent
-index index.$geo.html index.0.html /index.html;
-.Ed
-.Pp
-It should be noted that using an index file causes an internal redirect, and the
-request can be processed in a different location.
-For example, with the following configuration:
-.Bd -literal -offset indent
-location = / {
- index index.html;
-}
-location / {
- ...
-}
-.Ed
-.Pp
-a
-.Qq /
-request will actually be processed in the second location as
-.Pa /index.html .
-.El
-.Ss Module ngx_http_limit_conn_module
-.Bl -tag -width Ds
-.It Ic limit_conn Ar zone Ar number
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the shared memory zone and the maximum allowed number of connections for a
-given key value.
-When this limit is exceeded, the server will return the 503 (Service Temporarily
-Unavailable) error in reply to a request.
-For example, the directives
-.Bd -literal -offset indent
-limit_conn_zone $binary_remote_addr zone=addr:10m;
-server {
- location /download/ {
- limit_conn addr 1;
- }
-.Ed
-.Pp
-allow only one connection per an IP address at a time.
-When several
-.Ic limit_conn
-directives are specified, any configured limit will apply.
-For example, the following configuration will limit the number of connections to
-the server per a client IP and, at the same time, the total number of
-connections to the virtual host:
-.Bd -literal -offset indent
-limit_conn_zone $binary_remote_addr zone=perip:10m;
-limit_conn_zone $server_name zone=perserver:10m;
-server {
- ...
- limit_conn perip 10;
- limit_conn perserver 100;
-}
-.Ed
-.Pp
-These directives are inherited from the previous level if and only if there are
-no
-.Ic limit_conn
-directives on the current level.
-.It Ic limit_conn_log_level Cm info | Cm notice | Cm warn | Cm error
-.Bl -tag -width Ds -compact
-.It default: Cm error
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the desired logging level for cases when the server limits the number of
-connections.
-.It Ic limit_conn_status Ar code
-.Bl -tag -width Ds -compact
-.It default: 503
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the status code to return in response to rejected requests.
-.It Ic limit_conn_zone Ar $variable Cm zone Ns = Ns Ar name Ns : Ns Ar size
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Sets parameters for a shared memory zone that will keep states for various keys.
-In particular, the state includes the current number of connections.
-The key is any non-empty value of the specified variable (empty values are not
-accounted).
-Usage example:
-.Bd -literal -offset indent
-limit_conn_zone $binary_remote_addr zone=addr:10m;
-.Ed
-.Pp
-Here, a client IP address serves as a key.
-Note that instead of
-.Va $remote_addr ,
-the
-.Va $binary_remote_addr
-variable is used here.
-The
-.Va $remote_addr
-variable's size can vary from 7 to 15 bytes.
-The stored state occupies either 32 or 64 bytes of memory on 32-bit platforms
-and always 64 bytes on 64-bit platforms.
-The
-.Va $binary_remote_addr
-variable's size is always 4 bytes.
-The stored state always occupies 32 bytes on 32-bit platforms and 64 bytes on
-64-bit platforms.
-One megabyte zone can keep about 32 thousand 32-byte states or about 16 thousand
-64-byte states.
-If the zone storage is exhausted, the server will return the 503 (Service
-Temporarily Unavailable) error to all further requests.
-.It Ic limit_zone Ar name Ar $variable Ar size
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-This directive is made obsolete in version 1.1.8, an equivalent
-.Ic limit_conn_zone
-directive with a changed syntax should be used instead:
-.Ic limit_conn_zone Ar $variable Cm zone Ns = Ns Ar name Ns : Ns Ar size ;
-.El
-.Ss Module ngx_http_limit_req_module
-.Bl -tag -width Ds
-.It Ic limit_req Cm zone Ns = Ns Ar name Oo Cm burst Ns = Ns Ar number Oc Oo Cm nodelay Oc
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the shared memory zone and the maximum burst size of requests.
-If the requests rate exceeds the rate configured for a zone, their processing is
-delayed such that requests are processed at a defined rate.
-Excessive requests are delayed until their number exceeds the maximum burst size
-in which case the request is terminated with an error 503 (Service Temporarily
-Unavailable).
-By default, the maximum burst size is equal to zero.
-For example, the directives
-.Bd -literal -offset indent
-limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
-server {
- location /search/ {
- limit_req zone=one burst=5;
- }
-.Ed
-.Pp
-allow not more than 1 request per second at an average, with bursts not
-exceeding 5 requests.
-If delaying of excessive requests while requests are being limited is not
-desired, the parameter
-.Cm nodelay
-should be used:
-.Bd -literal -offset indent
-limit_req zone=one burst=5 nodelay;
-.Ed
-.It Ic limit_req_log_level Cm info | Cm notice | Cm warn | Cm error
-.Bl -tag -width Ds -compact
-.It default: Cm error
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the desired logging level for cases when the server refuses to process
-requests due to rate exceeding, or delays request processing.
-Logging level for delays is one point less than for refusals; for example, if
-.Ic limit_req_log_level notice
-is specified, delays are logged with the
-.Cm info
-level.
-.It Ic limit_req_status Ar code
-.Bl -tag -width Ds -compact
-.It default: 503
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the status code to return in response to rejected requests.
-.It Ic limit_req_zone Ar $variable Cm zone Ns = Ns Ar name Ns : Ns Ar size Cm rate Ns = Ns Ar rate
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Sets parameters for a shared memory zone that will keep states for various keys.
-In particular, the state stores the current number of excessive requests.
-The key is any non-empty value of the specified variable (empty values are not
-accounted).
-Usage example:
-.Bd -literal -offset indent
-limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
-.Ed
-.Pp
-Here, the states are kept in a 10 megabyte zone one, and an average request
-processing rate for this zone cannot exceed 1 request per second.
-A client IP address serves as a key.
-Note that instead of
-.Va $remote_addr ,
-the
-.Va $binary_remote_addr
-variable is used here, that allows to decrease the state size down to 64 bytes.
-One megabyte zone can keep about 16 thousand 64-byte states.
-If the zone storage is exhausted, the server will return the 503 (Service
-Temporarily Unavailable) error to all further requests.
-The rate is specified in requests per second (r/s).
-If a rate of less than one request per second is desired, it is specified in
-request per minute (r/m).
-For example, half-request per second is 30r/m.
-.El
-.Ss Module ngx_http_log_module
-.Bl -tag -width Ds
-.It Ic access_log Ar path Oo Ar format Oo Cm buffer Ns = Ns Ar size \
- Oo Cm flush Ns = Ns Ar time Oc Oc Oc
-.It Ic access_log Ar path Ar format Cm gzip Ns Oo = Ns level Oc \
- Oo Cm buffer Ns = Ns Ar size Oc Oo Cm flush Ns = Ns Ar time Oc
-.It Ic access_log Cm syslog : Ns Cm server Ns = Ns Ar address \
- Oo , Ar parameter Ns = Ns Ar value Oc Oo Ar format Oc
-.It Ic access_log Cm off
-.Bl -tag -width Ds -compact
-.It default: Pa logs/access.log Cm combined
-.It context: Ic http , Ic server , Ic location , Ic if in location , Ic limit_except
-.El
-.Pp
-Sets the path, format, and configuration for a buffered log write.
-Several logs can be specified on the same level.
-Logging to syslog can be configured by specifying the
-.Cm syslog:
-prefix in the first parameter.
-The special value
-.Cm off
-cancels all
-.Ic access_log
-directives on the current level.
-If the format is not specified then the predefined
-combined
-format is used.
-If either the
-.Cm buffer
-or
-.Ic gzip
-(1.3.10, 1.2.7) parameter is used, writes to log will be buffered.
-The buffer size must not exceed the size of an atomic write to a disk file.
-For FreeBSD this size is unlimited.
-When buffering is enabled, the data will be written to the file:
-.Bl -bullet
-.It
-if the next log line does not fit into the buffer;
-.It
-if the buffered data is older than specified by the
-.Cm flush
-parameter (1.3.10, 1.2.7);
-.It
-when a worker process is
-re-opening
-log files or is shutting down.
-.El
-.Pp
-If the
-.Ic gzip
-parameter is used, then the buffered data will be compressed before writing to
-the file.
-The compression level can be set between 1 (fastest, less compression) and 9
-(slowest, best compression).
-By default, the buffer size is equal to 64K bytes, and the compression level is
-set to 1.
-Since the data is compressed in atomic blocks, the log file can be decompressed
-or read by
-.Ic zcat
-at any time.
-Example:
-.Bd -literal -offset indent
-access_log /path/to/log.gz combined gzip flush=5m;
-.Ed
-.Pp
-For gzip compression to work, nginx must be built with the zlib library.
-The file path can contain variables (0.7.6+), but such logs have some
-constraints:
-.Bl -bullet
-.It
-the
-.Ar user
-whose credentials are used by worker processes should have permissions to create
-files in a directory with such logs;
-.It
-buffered writes do not work;
-.It
-the file is opened and closed for each log write.
-However, since the descriptors of frequently used files can be stored in a
-.Ic open_log_file_cache
-cache, writing to the old file can continue during the time specified by the
-.Ic open_log_file_cache
-directive's
-.Cm valid
-parameter
-.It
-during each log write the existence of the request's root directory is checked,
-and if it does not exist the log is not created.
-It is thus a good idea to specify both
-.Ic root
-and
-.Ic access_log
-on the same level:
-.Bd -literal -offset indent
-server {
- root /spool/vhost/data/$host;
- access_log /spool/vhost/logs/$host;
- ...
-.Ed
-.El
-.Pp
-The following parameters configure logging to syslog:
-.Bl -tag -width Ds
-.It Cm server Ns = Ns Ar address
-Defines the address of a syslog server.
-The address can be specified as a domain name, IP address, or a UNIX-domain
-socket path (specified after the
-.Cm unix:
-prefix).
-With a domain name or IP address, the port can be specified.
-If port is not specified, the port 514 is used.
-If a domain name resolves to several IP addresses, the first resolved address is
-used.
-.It Cm facility Ns = Ns Ar string
-Sets facility of syslog messages, as defined in
-RFC 3164.
-Facility can be one of
-.Cm kern ,
-.Cm user ,
-.Cm mail ,
-.Cm daemon ,
-.Cm auth ,
-.Cm intern ,
-.Cm lpr ,
-.Cm news ,
-.Cm uucp ,
-.Cm clock ,
-.Cm authpriv ,
-.Cm ftp ,
-.Cm ntp ,
-.Cm audit ,
-.Cm alert ,
-.Cm cron ,
-.Cm local0 No .. Cm local7 .
-Default is
-.Cm local7 .
-.It Cm severity Ns = Ns Ar string
-Sets severity of syslog messages, as defined in RFC 3164.
-Possible values are the same as for the second parameter (level) of the
-.Ic error_log
-directive.
-Default is
-.Cm info .
-.It Cm tag Ns = Ns Ar string
-Sets the tag of syslog messages.
-Default is
-.Qq nginx .
-.El
-.Pp
-Example syslog configuration:
-.Bd -literal -offset indent
-access_log syslog:server=192.168.1.1;
-access_log syslog:server=unix:/var/log/nginx.sock;
-access_log syslog:server=[2001:db8::1]:12345,facility=local7,tag=nginx,severity=info combined;
-.Ed
-.It Ic log_format Ar name Ar string No ...
-.Bl -tag -width Ds -compact
-.It default: combined Qq ...
-.It context: Ic http
-.El
-.Pp
-Specifies log format.
-The log format can contain common variables, and variables that exist only at
-the time of a log write:
-.Bl -tag -width Ds
-.It Va $bytes_sent
-the number of bytes sent to a client
-.It Va $connection
-connection serial number
-.It Va $connection_requests
-the current number of requests made through a connection (1.1.18)
-.It Va $msec
-time in seconds with a milliseconds resolution at the time of the log write
-.It Va $pipe
-.Qq p
-if request was pipelined,
-.Qo . Qc
-otherwise
-.It Va $request_length
-request length (including request line, header, and request body)
-.It Va $request_time
-request processing time in seconds with a milliseconds resolution; time elapsed
-between the first bytes were read from the client and the log write after the
-last bytes were sent to the client
-.It Va $status
-response status
-.It Va $time_iso8601
-local time in the ISO 8601 standard format
-.It Va $time_local
-local time in the Common Log Format
-.El
-.Pp
-In the modern nginx versions variables
-.Va $status
-(1.3.2, 1.2.2),
-.Va $bytes_sent
-(1.3.8, 1.2.5),
-.Va $connection
-(1.3.8, 1.2.5),
-.Va $connection_requests
-(1.3.8, 1.2.5),
-.Va $msec
-(1.3.9, 1.2.6),
-.Va $request_time
-(1.3.9, 1.2.6),
-.Va $pipe
-(1.3.12, 1.2.7),
-.Va $request_length
-(1.3.12, 1.2.7),
-.Va $time_iso8601
-(1.3.12, 1.2.7), and
-.Va $time_local
-(1.3.12, 1.2.7) are also available as common variables.
-Header lines sent to a client have the prefix sent_http_, for example,
-.Va $sent_http_content_range .
-The configuration always includes the predefined
-.Cm combined
-format:
-.Bd -literal -offset indent
-log_format combined '$remote_addr - $remote_user [$time_local] '
- '"$request" $status $body_bytes_sent '
- '"$http_referer" "$http_user_agent"';
-.Ed
-.It Ic open_log_file_cache Cm max Ns = Ns Ar N Oo Cm inactive Ns = Ns Ar time Oc Oo Cm min_uses Ns = Ns Ar N Oc Oo Cm valid Ns = Ns Ar time Oc
-.It Ic open_log_file_cache Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a cache that stores the file descriptors of frequently used logs whose
-names contain variables.
-The directive has the following parameters:
-.Bl -tag -width Ds
-.It Cm max
-sets the maximum number of descriptors in a cache; if the cache becomes full the
-least recently used (LRU) descriptors are closed
-.It Cm inactive
-sets the time after which the cached descriptor is closed if there were no
-access during this time; by default, 10 seconds
-.It Cm min_uses
-sets the minimum number of file uses during the time defined by the
-.Cm inactive
-parameter to let the descriptor stay open in a cache; by default, 1
-.It Cm valid
-sets the time after which it should be checked that the file still exists with
-the same name; by default, 60 seconds
-.It Cm off
-disables caching
-.El
-.Pp
-Usage example:
-.Bd -literal -offset indent
-open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;
-.Ed
-.El
-.Ss Module ngx_http_map_module
-.Bl -tag -width Ds
-.It Ic map Ar string Ar $variable Brq No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Creates a new variable whose value depends on values of one or more of the
-source variables specified in the first parameter.
-Before version 0.9.0 only a single variable could be specified in the first
-parameter.
-Since variables are evaluated only when they are used, the mere declaration even
-of a large number of
-.Ic map
-variables does not add any extra costs to request processing.
-Parameters inside the
-.Ic map
-block specify a mapping between source and resulting values.
-Source values are specified as strings or regular expressions (0.9.6).
-A regular expression should either start from the
-.Qq ~
-symbol for a case-sensitive matching, or from the
-.Qq ~*
-symbols (1.0.4) for case-insensitive matching.
-A regular expression can contain named and positional captures that can later be
-used in other directives along with the resulting variable.
-If a source value matches one of the names of special parameters described
-below, it should be prefixed with the \\ symbol.
-The resulting value can be a string or another variable (0.9.0).
-The directive also supports three special parameters:
-.Bl -tag -width Ds
-.It Cm default Ar value
-sets the resulting value if the source value matches none of the specified
-variants.
-When
-.Cm default
-is not specified, the default resulting value will be an empty string.
-.It Cm hostnames
-indicates that source values can be hostnames with a prefix or suffix mask:
-.Bd -literal -offset indent
-*.example.com 1;
-example.* 1;
-.Ed
-.Pp
-The following two records
-.Bd -literal -offset indent
-example.com 1;
-*.example.com 1;
-.Ed
-.Pp
-can be combined:
-.Bd -literal -offset indent
- .example.com 1;
-.Ed
-.Pp
-This parameter should be specified before the list of values.
-.It Cm include Ar file
-includes a file with values.
-There can be several inclusions.
-.El
-.Pp
-If the source value matches more than one of the specified variants, e.g. both a
-mask and a regular expression match, the first matching variant will be chosen,
-in the following order of priority:
-.Bl -bullet
-.It
-string value without a mask
-.It
-longest string value with a prefix mask, e.g.
-.Qq *.example.com
-.It
-longest string value with a suffix mask, e.g.
-.Qq mail.*
-.It
-first matching regular expression (in order of appearance in a configuration
-file)
-.It
-default value
-.El
-.It Ic map_hash_bucket_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 32 | 64 | 128
-.It context: Ic http
-.El
-.Pp
-Sets the bucket size for the
-.Ic map
-variables hash tables.
-Default value depends on the processor's cache line size.
-The details of setting up hash tables are provided in a separate document.
-.It Ic map_hash_max_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 2048
-.It context: Ic http
-.El
-.Pp
-Sets the maximum
-.Ar size
-of the
-.Ic map
-variables hash tables.
-The details of setting up hash tables are provided in a separate document.
-.El
-.Ss Module ngx_http_memcached_module
-.Bl -tag -width Ds
-.It Ic memcached_bind Ar address | Cm off
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Makes outgoing connections to a memcached server originate from the specified
-local IP
-.Ar address .
-Parameter value can contain variables (1.3.12).
-The special value
-.Cm off
-(1.3.12) cancels the effect of the
-.Ic memcached_bind
-directive inherited from the previous configuration level, which allows the
-system to auto-assign the local IP address.
-.It Ic memcached_buffer_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 4k | 8k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the
-.Ar size
-of the buffer used for reading a response received from the memcached server.
-A response is passed to a client synchronously, as soon as it is received.
-.It Ic memcached_connect_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 60s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a timeout for establishing a connection with a memcached server.
-It should be noted that this timeout cannot usually exceed 75 seconds.
-.It Ic memcached_gzip_flag Ar flag
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables the test for the
-.Ar flag
-presence in the memcached server response and sets the
-Content-Encoding
-response header field to
-.Ic gzip
-if the flag is set.
-.It Ic memcached_next_upstream Cm error | Cm timeout | Cm invalid_response | Cm not_found | Cm off No ...
-.Bl -tag -width Ds -compact
-.It default: Cm error Cm timeout
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Specifies in which cases a request should be passed to the next server:
-.Bl -tag -width Ds
-.It Cm error
-an error occurred while establishing a connection with the server, passing a
-request to it, or reading the response header;
-.It Cm timeout
-a timeout has occurred while establishing a connection with the server, passing
-a request to it, or reading the response header;
-.It Cm invalid_response
-a server returned an empty or invalid response;
-.It Cm not_found
-a response was not found on the server;
-.It Cm off
-disables passing a request to the next server.
-.El
-.Pp
-One should bear in mind that passing a request to the next server is only
-possible if nothing has been sent to a client yet.
-That is, if an error or timeout occurs in the middle of the transferring of a
-response, fixing this is impossible.
-The directive also defines what is considered an unsuccessful attempt of
-communication with a
-.Ic server .
-The cases of
-.Cm error ,
-.Cm timeout
-and
-.Cm invalid_header
-are always considered unsuccessful attempts, even if they are not specified in
-the directive.
-The case of
-.Cm not_found
-is never considered an unsuccessful attempt.
-.It Ic memcached_pass Ar address
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location , Ic if in location
-.El
-.Pp
-Sets the memcached server address.
-The address can be specified as a domain name or an address, and a port:
-.Bd -literal -offset indent
-memcached_pass localhost:11211;
-.Ed
-.Pp
-or as a UNIX-domain socket path:
-.Bd -literal -offset indent
-memcached_pass unix:/tmp/memcached.socket;
-.Ed
-.Pp
-If a domain name resolves to several addresses, all of them will be used in a
-round-robin fashion.
-In addition, an address can be specified as a server group.
-.It Ic memcached_read_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 60s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a timeout for reading a response from the memcached server.
-A timeout is set only between two successive read operations, not for the
-transmission of the whole response.
-If a memcached server does not transmit anything within this time, the
-connection is closed.
-.It Ic memcached_send_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 60s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a timeout for transmitting a request to the memcached server.
-A timeout is set only between two successive write operations, not for the
-transmission of the whole request.
-If a memcached server does not receive anything within this time, a connection
-is closed.
-.El
-.Ss Module ngx_http_mp4_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic mp4
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-Turns on module processing in a surrounding location.
-.It Ic mp4_buffer_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 512K
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the initial size of a memory buffer used for processing MP4 files.
-.It Ic mp4_max_buffer_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 10M
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-During metadata processing, a larger buffer may become necessary.
-Its size cannot exceed the specified
-.Ar size ,
-or else nginx will return the 500 (Internal Server Error) server error, and
-log the following message:
-.Bd -literal -offset indent
-"/some/movie/file.mp4" mp4 moov atom is too large:
-12583268, you may want to increase mp4_max_buffer_size
-.Ed
-.It Ic mp4_limit_rate Cm on | Cm off | Ar factor
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-.Em This directive is only available in the commercial version of nginx.
-.Pp
-Enables or disables rate limiting based on the average bitrate of the MP4 file
-served.
-To calculate the rate, the bitrate is multiplied by the specified
-.Ar factor .
-The special value
-.Cm on
-corresponds to the factor of 1.1.
-.It Ic mp4_limit_rate_after Ar time
-.Bl -tag -width Ds -compact
-.It default: 1m
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-.Em This directive is only available in the commercial version of nginx.
-.Pp
-Limits the rate after sending the specified amount of media data.
-.El
-.Ss Module ngx_http_perl_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic perl Ar module Ns :: Ns Ar function | 'sub { ... }'
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location , Ic limit_except
-.El
-.Pp
-Sets a Perl handler for the given location.
-.It Ic perl_modules Ar path
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Sets an additional path for Perl modules.
-.It Ic perl_require Ar module
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Defines the name of a module that will be loaded during each reconfiguration.
-Several
-.Ic perl_require
-directives can be present.
-.It Ic perl_set Ar $variable Ar module Ns :: Ns Ar function | 'sub { ... }'
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Installs a Perl handler for the specified variable.
-.El
-.Ss Module ngx_http_proxy_module
-.Bl -tag -width Ds
-.It Ic proxy_bind Ar address | Cm off
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Makes outgoing connections to a proxied server originate from the specified
-local IP
-.Ar address .
-Parameter value can contain variables (1.3.12).
-The special value
-.Cm off
-(1.3.12) cancels the effect of the
-.Ic proxy_bind
-directive inherited from the previous configuration level, which allows the
-system to auto-assign the local IP address.
-.It Ic proxy_buffer_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 4k | 8k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the
-.Ar size
-of the buffer used for reading the first part of a response received from the
-proxied server.
-This part usually contains a small response header.
-By default, the buffer size is equal to the size of one buffer set by the
-.Ic proxy_buffers
-directive.
-It can be made smaller however.
-.It Ic proxy_buffering Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables buffering of responses from the proxied server.
-When buffering is enabled, nginx receives a response from the proxied server as
-soon as possible, saving it into the buffers set by the
-.Ic proxy_buffer_size
-and
-.Ic proxy_buffers
-directives.
-If the whole response does not fit into memory, a part of it can be saved to a
-.Ic proxy_temp_path
-temporary file
-on the disk.
-Writing to temporary files is controlled by the
-.Ic proxy_max_temp_file_size
-and
-.Ic proxy_temp_file_write_size
-directives.
-When buffering is disabled, a response is passed to a client synchronously,
-immediately as it is received.
-nginx will not try to read the whole response from the proxied server.
-The maximum size of the data that nginx can receive from the server at a time is
-set by the
-.Ic proxy_buffer_size
-directive.
-Buffering can also be enabled or disabled by passing
-.Cm yes
-or
-.Cm no
-in the X-Accel-Buffering response header field.
-This capability can be disabled using the
-.Ic proxy_ignore_headers
-directive.
-.It Ic proxy_buffers Ar number Ar size
-.Bl -tag -width Ds -compact
-.It default: 8 4k | 8k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the
-.Ar number
-and
-.Ar size
-of buffers used for reading a response from the proxied server, for a single
-connection.
-By default, the buffer size is equal to one memory page.
-This is either 4K or 8K, depending on a platform.
-.It Ic proxy_busy_buffers_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 8k | 16k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-When buffering of responses from the proxied server is enabled, limits the total
-.Ar size
-of buffers that can be busy sending a response to the client while the response
-is not yet fully read.
-In the mean time, the rest of the buffers can be used for reading a response
-and, if needed, buffering part of a response to a temporary file.
-By default,
-.Ar size
-is limited by the size of two buffers set by the
-.Ic proxy_buffer_size
-and
-.Ic proxy_buffers
-directives.
-.It Ic proxy_cache Ar zone | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a shared memory zone used for caching.
-The same zone can be used in several places.
-The
-.Cm off
-parameter disables caching inherited from the previous configuration level.
-.It Ic proxy_cache_bypass Ar string No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines conditions under which the response will not be taken from a cache.
-If at least one value of the string parameters is not empty and is not equal to
-0 then the response will not be taken from the cache:
-.Bd -literal -offset indent
-proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
-proxy_cache_bypass $http_pragma $http_authorization;
-.Ed
-.Pp
-Can be used along with the
-.Ic proxy_no_cache
-directive.
-.It Ic proxy_cache_key Ar string
-.Bl -tag -width Ds -compact
-.It default: $scheme$proxy_host$request_uri
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a key for caching, for example
-.Bd -literal -offset indent
-proxy_cache_key "$host$request_uri $cookie_user";
-.Ed
-.Pp
-By default, the directive's value is close to the string
-.Bd -literal -offset indent
-proxy_cache_key $scheme$proxy_host$uri$is_args$args;
-.Ed
-.It Ic proxy_cache_lock Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-When enabled, only one request at a time will be allowed to populate a new cache
-element identified according to the
-.Ic proxy_cache_key
-directive by passing a request to a proxied server.
-Other requests of the same cache element will either wait for a response to
-appear in the cache or the cache lock for this element to be released, up to the
-time set by the
-.Ic proxy_cache_lock_timeout
-directive.
-.It Ic proxy_cache_lock_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 5s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a timeout for
-.Ic proxy_cache_lock .
-.It Ic proxy_cache_methods Cm GET | Cm HEAD | Cm POST No ...
-.Bl -tag -width Ds -compact
-.It default: Cm GET Cm HEAD
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-If the client request method is listed in this directive then the response will
-be cached.
-.Cm GET
-and
-.Cm HEAD
-methods are always added to the list, though it is recommended to specify them
-explicitly.
-See also the
-.Ic proxy_no_cache
-directive.
-.It Ic proxy_cache_min_uses Ar number
-.Bl -tag -width Ds -compact
-.It default: 1
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the
-.Ar number
-of requests after which the response will be cached.
-.It Ic proxy_cache_path Ar path Oo Cm levels Ns = Ns Ar levels Oc Cm keys_zone Ns = Ns Ar name Ns : Ns Ar size Oo Cm inactive Ns = Ns Ar time Oc Oo Cm max_size Ns = Ns Ar size Oc Oo Cm loader_files Ns = Ns Ar number Oc Oo Cm loader_sleep Ns = Ns Ar time Oc Oo Cm loader_threshold Ns = Ns Ar time Oc
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Sets the path and other parameters of a cache.
-Cache data are stored in files.
-Both the key and file name in a cache are a result of applying the MD5 function
-to the proxied URL.
-The
-.Ar levels
-parameter defines hierarchy levels of a cache.
-For example, in the following configuration
-.Bd -literal -offset indent
-proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m;
-.Ed
-.Pp
-file names in a cache will look like this:
-.Bd -literal -offset indent
-/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c
-.Ed
-.Pp
-A cached response is first written to a temporary file, and then the file is
-renamed.
-Starting from version 0.8.9, temporary files and the cache can be put on
-different file systems.
-However, be aware that in this case a file is copied across two file systems
-instead of the cheap renaming operation.
-It is thus recommended that for any given location both cache and a directory
-holding temporary files, set by the
-.Ic proxy_temp_path
-directive, are put on the same file system.
-In addition, all active keys and information about data are stored in a shared
-memory zone, whose
-.Ar name
-and
-.Ar size
-are configured by the
-.Cm keys_zone
-parameter.
-Cached data that are not accessed during the time specified by the
-.Cm inactive
-parameter get removed from the cache regardless of their freshness.
-By default,
-.Cm inactive
-is set to 10 minutes.
-The special cache manager process monitors the maximum cache size set by the
-.Cm max_size
-parameter.
-When this size is exceeded, it removes the least recently used data.
-A minute after the start the special cache loader process is activated.
-It loads information about previously cached data stored on file system into a
-cache zone.
-The loading is done in iterations.
-During one iteration no more than
-.Cm loader_files
-items are loaded (by default, 100).
-Besides, the duration of one iteration is limited by the
-.Cm loader_threshold
-parameter (by default, 200 milliseconds).
-Between iterations, a pause configured by the
-.Cm loader_sleep
-parameter (by default, 50 milliseconds) is made.
-.It Ic proxy_cache_use_stale Cm error | Cm timeout | Cm invalid_header | Cm updating | Cm http_500 | Cm http_502 | Cm http_503 | Cm http_504 | Cm http_403 | Cm http_404 | Cm off No ...
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Determines in which cases a stale cached response can be used when an error
-occurs during communication with the proxied server.
-The directive's parameters match the parameters of the
-.Ic proxy_next_upstream
-directive.
-Additionally, the
-.Cm updating
-parameter permits using a stale cached response if it is currently being
-updated.
-This allows minimizing the number of accesses to proxied servers when updating
-cached data.
-To minimize the number of accesses to proxied servers when populating a new
-cache element, the
-.Ic proxy_cache_lock
-directive can be used.
-.It Ic proxy_cache_valid Oo Ar code No ... Oc Ar time
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets caching time for different response codes.
-For example, the following directives
-.Bd -literal -offset indent
-proxy_cache_valid 200 302 10m;
-proxy_cache_valid 404 1m;
-.Ed
-.Pp
-set 10 minutes of caching for responses with codes 200 and 302 and 1 minute for
-responses with code 404.
-If only caching
-.Ar time
-is specified
-.Bd -literal -offset indent
-proxy_cache_valid 5m;
-.Ed
-.Pp
-then only 200, 301, and 302 responses are cached.
-In addition, the
-.Cm any
-parameter can be specified to cache any responses:
-.Bd -literal -offset indent
-proxy_cache_valid 200 302 10m;
-proxy_cache_valid 301 1h;
-proxy_cache_valid any 1m;
-.Ed
-.Pp
-Parameters of caching can also be set directly in the response header.
-This has higher priority than setting of caching time using the directive.
-The X-Accel-Expires header field sets caching time of a response in seconds.
-The zero value disables caching for a response.
-If a value starts with the
-.Qq @
-prefix, it sets an absolute time in seconds since Epoch, up to which the
-response may be cached.
-If header does not include the X-Accel-Expires field, parameters of caching may
-be set in the header fields Expires or Cache-Control.
-If a header includes the Set-Cookie field, such a response will not be cached.
-Processing of one or more of these response header fields can be disabled using
-the
-.Ic proxy_ignore_headers
-directive.
-.It Ic proxy_connect_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 60s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a timeout for establishing a connection with a proxied server.
-It should be noted that this timeout cannot usually exceed 75 seconds.
-.It Ic proxy_cookie_domain Cm off
-.It Ic proxy_cookie_domain Ar domain Ar replacement
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a text that should be changed in the
-.Ar domain
-attribute of the Set-Cookie header fields of a proxied server response.
-Suppose a proxied server returned the Set-Cookie header field with the attribute
-.Ar domain Ns = Ns localhost .
-The directive
-.Bd -literal -offset indent
-proxy_cookie_domain localhost example.org;
-.Ed
-.Pp
-will rewrite this attribute to
-.Ar domain Ns = Ns example.org .
-A dot at the beginning of the
-.Ar domain
-and
-.Ar replacement
-strings and the
-.Ar domain
-attribute is ignored.
-Matching is case-insensitive.
-The
-.Ar domain
-and
-.Ar replacement
-strings can contain variables:
-.Bd -literal -offset indent
-proxy_cookie_domain www.$host $host;
-.Ed
-.Pp
-The directive can also be specified using regular expressions.
-In this case,
-.Ar domain
-should start from the
-.Qq ~
-symbol.
-A regular expression can contain named and positional captures, and
-.Ar replacement
-can reference them:
-.Bd -literal -offset indent
-proxy_cookie_domain ~\\.(?P<sl_domain>[-0-9a-z]+\\.[a-z]+)$ $sl_domain;
-.Ed
-.Pp
-There could be several
-.Ic proxy_cookie_domain
-directives:
-.Bd -literal -offset indent
-proxy_cookie_domain localhost example.org;
-proxy_cookie_domain ~\\.([a-z]+\\.[a-z]+)$ $1;
-.Ed
-.Pp
-The
-.Cm off
-parameter cancels the effect of all
-.Ic proxy_cookie_domain
-directives on the current level:
-.Bd -literal -offset indent
-proxy_cookie_domain off;
-proxy_cookie_domain localhost example.org;
-proxy_cookie_domain www.example.org example.org;
-.Ed
-.It Ic proxy_cookie_path Cm off
-.It Ic proxy_cookie_path Ar path Ar replacement
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a text that should be changed in the
-.Ar path
-attribute of the Set-Cookie header fields of a proxied server response.
-Suppose a proxied server returned the Set-Cookie header field with the attribute
-.Ar path Ns = Ns /two/some/uri/ .
-The directive
-.Bd -literal -offset indent
-proxy_cookie_path /two/ /;
-.Ed
-.Pp
-will rewrite this attribute to
-.Ar path Ns = Ns /some/uri/ .
-The
-.Ar path
-and
-.Ar replacement
-strings can contain variables:
-.Bd -literal -offset indent
-proxy_cookie_path $uri /some$uri;
-.Ed
-.Pp
-The directive can also be specified using regular expressions.
-In this case,
-.Ar path
-should either start from the
-.Qq ~
-symbol for a case-sensitive matching, or from the
-.Qq ~*
-symbols for case-insensitive matching.
-A regular expression can contain named and positional captures, and
-.Ar replacement
-can reference them:
-.Bd -literal -offset indent
-proxy_cookie_path ~*^/user/([^/]+) /u/$1;
-.Ed
-.Pp
-There could be several
-.Ic proxy_cookie_path
-directives:
-.Bd -literal -offset indent
-proxy_cookie_path /one/ /;
-proxy_cookie_path / /two/;
-.Ed
-.Pp
-The
-.Cm off
-parameter cancels the effect of all
-.Ic proxy_cookie_path
-directives on the current level:
-.Bd -literal -offset indent
-proxy_cookie_path off;
-proxy_cookie_path /two/ /;
-proxy_cookie_path ~*^/user/([^/]+) /u/$1;
-.Ed
-.It Ic proxy_headers_hash_bucket_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 64
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the bucket
-.Ar size
-for hash tables used by the
-.Ic proxy_hide_header
-and
-.Ic proxy_set_header
-directives.
-The details of setting up hash tables are provided in a separate document.
-.It Ic proxy_headers_hash_max_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 512
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the maximum
-.Ar size
-of hash tables used by the
-.Ic proxy_hide_header
-and
-.Ic proxy_set_header
-directives.
-The details of setting up hash tables are provided in a separate document.
-.It Ic proxy_hide_header Ar field
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-By default, nginx does not pass the header fields Date, Server, X-Pad and
-X-Accel-... from the response of a proxied server to a client.
-The
-.Ic proxy_hide_header
-directive sets additional fields that will not be passed.
-If, on the contrary, the passing of fields needs to be permitted, the
-.Ic proxy_pass_header
-directive can be used.
-.It Ic proxy_http_version Cm 1.0 | Cm 1.1
-.Bl -tag -width Ds -compact
-.It default: 1.0
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the HTTP protocol version for proxying.
-By default, version 1.0 is used.
-Version 1.1 is recommended for use with
-.Ic keepalive
-connections.
-.It Ic proxy_ignore_client_abort Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Determines whether the connection with a proxied server should be closed when a
-client closes a connection without waiting for a response.
-.It Ic proxy_ignore_headers Ar field No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Disables processing of certain response header fields from the proxied server.
-The following fields can be ignored: X-Accel-Redirect, X-Accel-Expires,
-X-Accel-Limit-Rate (1.1.6), X-Accel-Buffering (1.1.6), X-Accel-Charset (1.1.6),
-Expires, Cache-Control and Set-Cookie (0.8.44).
-If not disabled, processing of these header fields has the following effect:
-.Bl -bullet
-.It
-X-Accel-Expires, Expires, Cache-Control, and Set-Cookie set the parameters of
-response
-.Ic proxy_cache_valid
-caching;
-.It
-X-Accel-Redirect performs an
-.Ic internal
-redirect
-to the specified URI;
-.It
-X-Accel-Limit-Rate sets the
-.Ic limit_rate
-rate
-limit
-for transmission of a response to a client;
-.It
-X-Accel-Buffering enables or disables buffering of a response;
-.It
-X-Accel-Charset sets the desired
-.Ic charset
-of a response.
-.El
-.It Ic proxy_intercept_errors Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Determines whether proxied responses with codes greater than or equal to 300
-should be passed to a client or be redirected to nginx for processing with the
-.Ic error_page
-directive.
-.It Ic proxy_max_temp_file_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 1024m
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-When buffering of responses from the proxied server is enabled, and the whole
-response does not fit into the memory buffers set by the
-.Ic proxy_buffer_size
-and
-.Ic proxy_buffers
-directives, a part of the response can be saved to a temporary file.
-This directive sets the maximum
-.Ar size
-of a temporary file.
-The size of data written to a temporary file at a time is set by the
-.Ic proxy_temp_file_write_size
-directive.
-The zero value disables buffering of responses to temporary files.
-.It Ic proxy_method Ar method
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Specifies the HTTP
-.Ar method
-to use in requests forwarded to the proxied server instead of the method from
-the client request.
-.It Ic proxy_next_upstream Cm error | Cm timeout | Cm invalid_header | Cm http_500 | Cm http_502 | Cm http_503 | Cm http_504 | Cm http_403 | Cm http_404 | Cm off No ...
-.Bl -tag -width Ds -compact
-.It default: Cm error Cm timeout
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Specifies in which cases a request should be passed to the next server:
-.Bl -tag -width Ds
-.It Cm error
-an error occurred while establishing a connection with the server, passing a
-request to it, or reading the response header;
-.It Cm timeout
-a timeout has occurred while establishing a connection with the server, passing
-a request to it, or reading the response header;
-.It Cm invalid_header
-a server returned an empty or invalid response;
-.It Cm http_500
-a server returned a response with the code 500;
-.It Cm http_502
-a server returned a response with the code 502;
-.It Cm http_503
-a server returned a response with the code 503;
-.It Cm http_504
-a server returned a response with the code 504;
-.It Cm http_403
-a server returned a response with the code 403;
-.It Cm http_404
-a server returned a response with the code 404;
-.It Cm off
-disables passing a request to the next server.
-.El
-.Pp
-One should bear in mind that passing a request to the next server is only
-possible if nothing has been sent to a client yet.
-That is, if an error or timeout occurs in the middle of the transferring of a
-response, fixing this is impossible.
-The directive also defines what is considered an unsuccessful attempt of
-communication with a
-.Ic server .
-The cases of
-.Cm error ,
-.Cm timeout
-and
-.Cm invalid_header
-are always considered unsuccessful attempts, even if they are not specified in
-the directive.
-The cases of
-.Cm http_500 ,
-.Cm http_502 ,
-.Cm http_503
-and
-.Cm http_504
-are considered unsuccessful attempts only if they are specified in the
-directive.
-The cases of
-.Cm http_403
-and
-.Cm http_404
-are never considered unsuccessful attempts.
-.It Ic proxy_no_cache Ar string No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines conditions under which the response will not be saved to a cache.
-If at least one value of the string parameters is not empty and is not equal to
-0 then the response will not be saved:
-.Bd -literal -offset indent
-proxy_no_cache $cookie_nocache $arg_nocache$arg_comment;
-proxy_no_cache $http_pragma $http_authorization;
-.Ed
-.Pp
-Can be used along with the
-.Ic proxy_cache_bypass
-directive.
-.It Ic proxy_pass Ar URL
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location , Ic if in location , Ic limit_except
-.El
-.Pp
-Sets the protocol and address of a proxied server and an optional URI to which a
-location should be mapped.
-As a protocol, http or https can be specified.
-The address can be specified as a domain name or IP address, and an optional
-port:
-.Bd -literal -offset indent
-proxy_pass http://localhost:8000/uri/;
-.Ed
-.Pp
-or as a UNIX-domain socket path specified after the word
-.Cm unix
-and enclosed in colons:
-.Bd -literal -offset indent
-proxy_pass http://unix:/tmp/backend.socket:/uri/;
-.Ed
-.Pp
-If a domain name resolves to several addresses, all of them will be used in a
-round-robin fashion.
-In addition, an address can be specified as a server group.
-A request URI is passed to the server as follows:
-.Bl -bullet
-.It
-If the
-.Ic proxy_pass
-directive is specified with a URI, then when a request is passed to the server,
-the part of a
-.Ic location
-normalized
-request URI matching the location is replaced by a URI specified in the
-directive:
-.Bd -literal -offset indent
-location /name/ {
- proxy_pass http://127.0.0.1/remote/;
-}
-.Ed
-.It
-If
-.Ic proxy_pass
-is specified without a URI, the request URI is passed to the server in the same
-form as sent by a client when the original request is processed, or the full
-normalized request URI is passed when processing the changed URI:
-.Bd -literal -offset indent
-location /some/path/ {
- proxy_pass http://127.0.0.1;
-}
-.Ed
-.Pp
-Before version 1.1.12, if
-.Ic proxy_pass
-is specified without a URI, the original request URI might be passed instead of
-the changed URI in some cases.
-.El
-.Pp
-In some cases, the part of a request URI to be replaced cannot be determined:
-.Bl -bullet
-.It
-When location is specified using a regular expression.
-In this case, the directive should be specified without a URI.
-.It
-When the URI is changed inside a proxied location using the
-.Ic rewrite
-directive, and this same configuration will be used to process a request
-.Pq Ic break :
-.Bd -literal -offset indent
-location /name/ {
- rewrite /name/([^/]+) /users?name=$1 break;
- proxy_pass http://127.0.0.1;
-}
-.Ed
-.Pp
-In this case, the URI specified in the directive is ignored and the full changed
-request URI is passed to the server.
-.El
-.Pp
-A server name, its port and the passed URI can also be specified using
-variables:
-.Bd -literal -offset indent
-proxy_pass http://$host$uri;
-.Ed
-.Pp
-or even like this:
-.Bd -literal -offset indent
-proxy_pass $request;
-.Ed
-.Pp
-In this case, the server name is searched among the described server groups,
-and, if not found, is determined using a
-.Ic resolver .
-WebSocket
-proxying requires special configuration and is supported since version 1.3.13.
-.It Ic proxy_pass_header Ar field
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Permits passing
-.Ic proxy_hide_header
-otherwise disabled
-header fields from a proxied server to a client.
-.It Ic proxy_read_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 60s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a timeout for reading a response from the proxied server.
-A timeout is set only between two successive read operations, not for the
-transmission of the whole response.
-If a proxied server does not transmit anything within this time, a connection is
-closed.
-.It Ic proxy_pass_request_body Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Indicates whether the original request body is passed to the proxied server.
-.Bd -literal -offset indent
-location /x-accel-redirect-here/ {
- proxy_method GET;
- proxy_pass_request_body off;
- proxy_set_header Content-Length "";
- proxy_pass ...
-}
-.Ed
-.Pp
-See also the
-.Ic proxy_set_header
-and
-.Ic proxy_pass_request_headers
-directives.
-.It Ic proxy_pass_request_headers Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Indicates whether the header fields of the original request are passed to the
-proxied server.
-.Bd -literal -offset indent
-location /x-accel-redirect-here/ {
- proxy_method GET;
- proxy_pass_request_headers off;
- proxy_pass_request_body off;
- proxy_pass ...
-}
-.Ed
-.Pp
-See also the
-.Ic proxy_set_header
-and
-.Ic proxy_pass_request_body
-directives.
-.It Ic proxy_redirect Cm default
-.It Ic proxy_redirect Cm off
-.It Ic proxy_redirect Ar redirect Ar replacement
-.Bl -tag -width Ds -compact
-.It default: Cm default
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the text that should be changed in the Location and Refresh header fields
-of a proxied server response.
-Suppose a proxied server returned the header field
-.Qq Location: http://localhost:8000/two/some/uri/ .
-The directive
-.Bd -literal -offset indent
-proxy_redirect http://localhost:8000/two/ http://frontend/one/;
-.Ed
-.Pp
-will rewrite this string to
-.Qq Location: http://frontend/one/some/uri/ .
-A server name may be omitted in the
-.Ar replacement
-string:
-.Bd -literal -offset indent
-proxy_redirect http://localhost:8000/two/ /;
-.Ed
-.Pp
-then the primary server's name and port, if different from 80, will be inserted.
-The default replacement specified by the
-.Cm default
-parameter uses the parameters of the
-.Ic location
-and
-.Ic proxy_pass
-directives.
-Hence, the two configurations below are equivalent:
-.Bd -literal -offset indent
-location /one/ {
- proxy_pass http://upstream:port/two/;
- proxy_redirect default;
-.Ed
-.Bd -literal -offset indent
-location /one/ {
- proxy_pass http://upstream:port/two/;
- proxy_redirect http://upstream:port/two/ /one/;
-.Ed
-.Pp
-The
-.Cm default
-parameter is not permitted if
-.Ic proxy_pass
-is specified using variables.
-A
-.Ar replacement
-string can contain variables:
-.Bd -literal -offset indent
-proxy_redirect http://localhost:8000/ http://$host:$server_port/;
-.Ed
-.Pp
-A
-.Ar redirect
-can also contain (1.1.11) variables:
-.Bd -literal -offset indent
-proxy_redirect http://$proxy_host:8000/ /;
-.Ed
-.Pp
-The directive can be specified (1.1.11) using regular expressions.
-In this case,
-.Ar redirect
-should either start with the
-.Qq ~
-symbol for a case-sensitive matching, or with the
-.Qq ~*
-symbols for case-insensitive matching.
-A regular expression can contain named and positional captures, and
-.Ar replacement
-can reference them:
-.Bd -literal -offset indent
-proxy_redirect ~^(http://[^:]+):\\d+(/.+)$ $1$2;
-proxy_redirect ~*/user/([^/]+)/(.+)$ http://$1.example.com/$2;
-.Ed
-.Pp
-There could be several
-.Ic proxy_redirect
-directives:
-.Bd -literal -offset indent
-proxy_redirect default;
-proxy_redirect http://localhost:8000/ /;
-proxy_redirect http://www.example.com/ /;
-.Ed
-.Pp
-The
-.Cm off
-parameter cancels the effect of all
-.Ic proxy_redirect
-directives on the current level:
-.Bd -literal -offset indent
-proxy_redirect off;
-proxy_redirect default;
-proxy_redirect http://localhost:8000/ /;
-proxy_redirect http://www.example.com/ /;
-.Ed
-.Pp
-Using this directive, it is also possible to add host names to relative
-redirects issued by a proxied server:
-.Bd -literal -offset indent
-proxy_redirect / /;
-.Ed
-.It Ic proxy_send_lowat Ar size
-.Bl -tag -width Ds -compact
-.It default: 0
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-If the directive is set to a non-zero value, nginx will try to minimize the
-number of send operations on outgoing connections to a proxied server by using
-either
-.Dv NOTE_LOWAT
-flag of the
-.Cm kqueue
-method, or the
-.Dv SO_SNDLOWAT
-socket option, with the specified
-.Ar size .
-This directive is ignored on Linux, Solaris, and Windows.
-.It Ic proxy_send_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 60s
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a timeout for transmitting a request to the proxied server.
-A timeout is set only between two successive write operations, not for the
-transmission of the whole request.
-If a proxied server does not receive anything within this time, a connection is
-closed.
-.It Ic proxy_set_body Ar value
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Allows redefining the request body passed to the proxied server.
-A
-.Ar value
-can contain text, variables, and their combination.
-.It Ic proxy_set_header Ar field Ar value
-.Bl -tag -width Ds -compact
-.It default: Host $proxy_host
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Allows redefining or appending fields to the request header passed to the
-proxied server.
-A
-.Ar value
-can contain text, variables, and their combinations.
-These directives are inherited from the previous level if and only if there are
-no
-.Ic proxy_set_header
-directives defined on the current level.
-By default, only two fields are redefined:
-.Bd -literal -offset indent
-proxy_set_header Host $proxy_host;
-proxy_set_header Connection close;
-.Ed
-.Pp
-An unchanged Host request header field can be passed like this:
-.Bd -literal -offset indent
-proxy_set_header Host $http_host;
-.Ed
-.Pp
-However, if this field is not present in a client request header then nothing
-will be passed.
-In such a case it is better to use the
-.Va $host
-variable - its value equals the server name in the Host request header field or
-the primary server name if this field is not present:
-.Bd -literal -offset indent
-proxy_set_header Host $host;
-.Ed
-.Pp
-In addition, the server name can be passed together with the port of the proxied
-server:
-.Bd -literal -offset indent
-proxy_set_header Host $host:$proxy_port;
-.Ed
-.Pp
-If the value of a header field is an empty string then this field will not be
-passed to a proxied server:
-.Bd -literal -offset indent
-proxy_set_header Accept-Encoding "";
-.Ed
-.It Ic proxy_ssl_ciphers Ar ciphers
-.Bl -tag -width Ds -compact
-.It default: Cm DEFAULT
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Specifies the enabled ciphers for requests to a proxied HTTPS server.
-The ciphers are specified in the format understood by the OpenSSL library.
-The full list can be viewed using the
-.Ic openssl ciphers
-command.
-.It Ic proxy_ssl_session_reuse Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Determines whether SSL sessions can be reused when working with the proxied
-server.
-If the errors
-SSL3_GET_FINISHED:digest check failed
-appear in the logs, try disabling session reuse.
-.It Ic proxy_ssl_protocols Oo Cm SSLv2 Oc Oo Cm SSLv3 Oc Oo Cm TLSv1 Oc Oo Cm TLSv1.1 Oc Oo Cm TLSv1.2 Oc
-.Bl -tag -width Ds -compact
-.It default: SSLv3 TLSv1 TLSv1.1 TLSv1.2
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables the specified protocols for requests to a proxied HTTPS server.
-.It Ic proxy_store Cm on | Cm off | Ar string
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables saving of files to a disk.
-The
-.Cm on
-parameter saves files with paths corresponding to the directives
-.Ic alias
-or
-.Ic root .
-The
-.Cm off
-parameter disables saving of files.
-In addition, the file name can be set explicitly using the
-.Ar string
-with variables:
-.Bd -literal -offset indent
-proxy_store /data/www$original_uri;
-.Ed
-.Pp
-The modification time of files is set according to the received Last-Modified
-response header field.
-A response is first written to a temporary file, and then the file is renamed.
-Starting from version 0.8.9, temporary files and the persistent store can be put
-on different file systems.
-However, be aware that in this case a file is copied across two file systems
-instead of the cheap renaming operation.
-It is thus recommended that for any given location both saved files and a
-directory holding temporary files, set by the
-.Ic proxy_temp_path
-directive, are put on the same file system.
-This directive can be used to create local copies of static unchangeable files,
-e.g.:
-.Bd -literal -offset indent
-location /images/ {
- root /data/www;
- open_file_cache_errors off;
- error_page 404 = /fetch$uri;
-}
-location /fetch/ {
- internal;
- proxy_pass http://backend/;
- proxy_store on;
- proxy_store_access user:rw group:rw all:r;
- proxy_temp_path /data/temp;
- alias /data/www/;
-}
-.Ed
-.Pp
-or like this:
-.Bd -literal -offset indent
-location /images/ {
- root /data/www;
- error_page 404 = @fetch;
-}
-location @fetch {
- internal;
- proxy_pass http://backend;
- proxy_store on;
- proxy_store_access user:rw group:rw all:r;
- proxy_temp_path /data/temp;
- root /data/www;
-}
-.Ed
-.It Ic proxy_store_access Ar users Ns : Ns Ar permissions No ...
-.Bl -tag -width Ds -compact
-.It default: user:rw
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets access permissions for newly created files and directories, e.g.:
-.Bd -literal -offset indent
-proxy_store_access user:rw group:rw all:r;
-.Ed
-.Pp
-If any
-.Ar group
-or
-.Cm all
-access permissions are specified then
-.Ar user
-permissions may be omitted:
-.Bd -literal -offset indent
-proxy_store_access group:rw all:r;
-.Ed
-.It Ic proxy_temp_file_write_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 8k | 16k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Limits the
-.Ar size
-of data written to a temporary file at a time, when buffering of responses from
-the proxied server to temporary files is enabled.
-By default,
-.Ar size
-is limited by two buffers set by the
-.Ic proxy_buffer_size
-and
-.Ic proxy_buffers
-directives.
-The maximum size of a temporary file is set by the
-.Ic proxy_max_temp_file_size
-directive.
-.It Ic proxy_temp_path Ar path Oo Ar level1 Oo Ar level2 Oo Ar level3 Oc Oc Oc
-.Bl -tag -width Ds -compact
-.It default: proxy_temp
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a directory for storing temporary files with data received from proxied
-servers.
-Up to three-level subdirectory hierarchy can be used underneath the specified
-directory.
-For example, in the following configuration
-.Bd -literal -offset indent
-proxy_temp_path /spool/nginx/proxy_temp 1 2;
-.Ed
-.Pp
-a temporary file might look like this:
-.Bd -literal -offset indent
-/spool/nginx/proxy_temp/7/45/00000123457
-.Ed
-.El
-.Ss Module ngx_http_random_index_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic random_index Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic location
-.El
-.Pp
-Enables or disables module processing in a surrounding location.
-.El
-.Ss Module ngx_http_realip_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic set_real_ip_from Ar address | Ar CIDR | Cm unix:
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines trusted addresses that are known to send correct replacement addresses.
-If the special value
-.Cm unix:
-is specified, all UNIX-domain sockets will be trusted.
-IPv6 addresses are supported starting from versions 1.3.0 and 1.2.1.
-.It Ic real_ip_header Ar field | Cm X-Real-IP | Cm X-Forwarded-For
-.Bl -tag -width Ds -compact
-.It default: X-Real-IP
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a request header field used to send the address for a replacement.
-.It Ic real_ip_recursive Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-If recursive search is disabled, the original client address that matches one of
-the trusted addresses is replaced by the last address sent in the request header
-field defined by the
-.Ic real_ip_header
-directive.
-If recursive search is enabled, the original client address that matches one of
-the trusted addresses is replaced by the last non-trusted address sent in the
-request header field.
-.El
-.Ss Module ngx_http_referer_module
-.Bl -tag -width Ds
-.It Ic referer_hash_bucket_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 64
-.It context: Ic server , Ic location
-.El
-.Pp
-Sets the bucket size for the valid referers hash tables.
-The details of setting up hash tables are provided in a separate document.
-.It Ic referer_hash_max_size Ar size
-.Bl -tag -width Ds -compact
-.It default: 2048
-.It context: Ic server , Ic location
-.El
-.Pp
-Sets the maximum
-.Ar size
-of the valid referers hash tables.
-The details of setting up hash tables are provided in a separate document.
-.It Ic valid_referers Cm none | Cm blocked | Cm server_names | Ar string No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic server , Ic location
-.El
-.Pp
-Specifies the Referer request header field values that will cause the embedded
-.Va $invalid_referer
-variable to be set to an empty string.
-Otherwise, the variable will be set to
-1.
-Search for a match is case-insensitive.
-Parameters can be as follows:
-.Bl -tag -width Ds
-.It Cm none
-the Referer field is missing in the request header;
-.It Cm blocked
-the Referer field is present in the request header, but its value has been
-deleted by a firewall or proxy server; such values are strings that do not start
-with
-.Qq http://
-or
-.Qq https:// ;
-.It Cm server_names
-the Referer request header field contains one of the server names;
-.It Ar arbitrary string
-defines a server name and an optional URI prefix.
-A server name can have an
-.Qq *
-at the beginning or end.
-During the checking, the server's port in the Referer field is ignored;
-.It Ar regular expression
-the first symbol should be a
-.Qq ~ .
-It should be noted that an expression will be matched against the text starting
-after the
-.Qq http://
-or
-.Qq https:// .
-.El
-.Pp
-Example:
-.Bd -literal -offset indent
-valid_referers none blocked server_names
- *.example.com example.* www.example.org/galleries/
- ~\\.google\\.;
-.Ed
-.El
-.Ss Module ngx_http_rewrite_module
-.Bl -tag -width Ds
-.It Ic break
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic server , Ic location , Ic if
-.El
-.Pp
-Stops processing the current set of
-.Sx Module ngx_http_rewrite_module
-directives.
-Example:
-.Bd -literal -offset indent
-if ($slow) {
- limit_rate 10k;
- break;
-}
-.Ed
-.It Ic if Po Ar condition Pc Brq No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic server , Ic location
-.El
-.Pp
-The specified
-.Ar condition
-is evaluated.
-If true, this module directives specified inside the braces are executed, and
-the request is assigned the configuration inside the
-.Ic if
-directive.
-Configurations inside the
-.Ic if
-directives are inherited from the previous configuration level.
-A condition may be any of the following:
-.Bl -bullet
-.It
-a variable name; false if the value of a variable is an empty string or 0;
-Before version 1.0.1, any string starting with 0
-was considered a false value.
-.It
-comparison of a variable with a string using the
-.Qq =
-and
-.Qq !=
-operators;
-.It
-matching of a variable against a regular expression using the
-.Qq ~
-(for case-sensitive matching) and
-.Qq ~*
-(for case-insensitive matching) operators.
-Regular expressions can contain captures that are made available for later reuse
-in the
-.Va $1 No .. Va $9
-variables.
-Negative operators
-.Qq !~
-and
-.Qq !~*
-are also available.
-If a regular expression includes the
-.Qq }
-or
-.Qo ; Qc
-characters, the whole expressions should be enclosed in single or double quotes.
-.It
-checking of a file existence with the
-.Fl f
-and
-.Ic !-f
-operators;
-.It
-checking of a directory existence with the
-.Fl d
-and
-.Ic !-d
-operators;
-.It
-checking of a file, directory, or symbolic link existence with the
-.Fl e
-and
-.Ic !-e
-operators;
-.It
-checking for an executable file with the
-.Fl x
-and
-.Ic !-x
-operators.
-.El
-.Pp
-Examples:
-.Bd -literal -offset indent
-if ($http_user_agent ~ MSIE) {
- rewrite ^(.*)$ /msie/$1 break;
-}
-if ($http_cookie ~* "id=([^;]+)(?:; |$)") {
- set $id $1;
-}
-if ($request_method = POST) {
- return 405;
-}
-if ($slow) {
- limit_rate 10k;
-}
-if ($invalid_referer) {
- return 403;
-}
-.Ed
-.Pp
-A value of the
-.Va $invalid_referer
-embedded variable is set by the
-.Ic valid_referers
-directive.
-.It Ic return Ar code Oo Ar text Oc
-.It Ic return Ar code Ar URL
-.It Ic return Ar URL
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic server , Ic location , Ic if
-.El
-.Pp
-Stops processing and returns the specified
-.Ar code
-to a client.
-The non-standard code 444 closes a connection without sending a response header.
-Starting from version 0.8.42, it is possible to specify either a redirect URL
-(for codes 301, 302, 303, and 307), or the response body
-.Ar text
-(for other codes).
-A response body text and redirect URL can contain variables.
-As a special case, a redirect URL can be specified as a URI local to this
-server, in which case the full redirect URL is formed according to the request
-scheme
-.Pq Va $scheme
-and the
-.Ic server_name_in_redirect
-and
-.Ic port_in_redirect
-directives.
-In addition, a
-.Ar URL
-for temporary redirect with the code 302 can be specified as the sole parameter.
-Such a parameter should start with the
-.Qq http:// ,
-.Qq https:// ,
-or
-.Ic $scheme
-string.
-A
-.Ar URL
-can contain variables.
-Only the following codes could be returned before version 0.7.51: 204, 400,
-402 - 406, 408, 410, 411, 413, 416, and 500 - 504.
-The code 307 was not treated as a redirect until versions 1.1.16 and 1.0.13.
-.It Ic rewrite Ar regex Ar replacement Oo Ar flag Oc
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic server , Ic location , Ic if
-.El
-.Pp
-If the specified regular expression matches a URI, the URI is changed as
-specified in the
-.Ar replacement
-string.
-The
-.Ic rewrite
-directives are executed sequentially in order of their appearance in the
-configuration file.
-It is possible to terminate further processing of the directives using flags.
-If a replacement string starts with
-.Qq http://
-or
-.Qq https:// ,
-the processing stops and the redirect is returned to a client.
-An optional
-.Ar flag
-parameter can be one of:
-.Bl -tag -width Ds
-.It Cm last
-stops processing the current set of
-.Sx Module ngx_http_rewrite_module
-directives and starts a search for a new location matching the changed URI;
-.It Cm break
-stops processing the current set of
-.Sx Module ngx_http_rewrite_module
-directives;
-.It Cm redirect
-returns a temporary redirect with the 302 code; used if a replacement string
-does not start with
-.Qq http://
-or
-.Qq https:// ;
-.It Cm permanent
-returns a permanent redirect with the 301 code.
-.El
-.Pp
-The full redirect URL is formed according to the request scheme
-.Pq Va $scheme
-and the
-.Ic server_name_in_redirect
-and
-.Ic port_in_redirect
-directives.
-Example:
-.Bd -literal -offset indent
-server {
- ...
- rewrite ^(/download/.*)/media/(.*)\\..*$ $1/mp3/$2.mp3 last;
- rewrite ^(/download/.*)/audio/(.*)\\..*$ $1/mp3/$2.ra last;
- return 403;
- ...
-}
-.Ed
-.Pp
-But if these directives are put inside the
-.Qq /download/
-location, the
-.Cm last
-flag should be replaced by
-.Ic break ,
-or otherwise nginx will make 10 cycles and return the 500 error:
-.Bd -literal -offset indent
-location /download/ {
- rewrite ^(/download/.*)/media/(.*)\\..*$ $1/mp3/$2.mp3 break;
- rewrite ^(/download/.*)/audio/(.*)\\..*$ $1/mp3/$2.ra break;
- return 403;
-}
-.Ed
-.Pp
-If a
-.Ar replacement
-string includes the new request arguments, the previous request arguments are
-appended after them.
-If this is undesired, putting a question mark at the end of a replacement string
-avoids having them appended, for example:
-.Bd -literal -offset indent
-rewrite ^/users/(.*)$ /show?user=$1? last;
-.Ed
-.Pp
-If a regular expression includes the
-.Qq }
-or
-.Qo ; Qc
-characters, the whole expressions should be enclosed in single or double quotes.
-.It Ic rewrite_log Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location , Ic if
-.El
-.Pp
-Enables or disables logging of
-.Sx Module ngx_http_rewrite_module
-module directives processing results into the
-.Ic error_log
-at the
-.Cm notice
-level.
-.It Ic set Ar variable Ar value
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic server , Ic location , Ic if
-.El
-.Pp
-Sets a
-.Ar value
-for the specified
-.Ar variable.
-A
-.Ar value
-can contain text, variables, and their combination.
-.It Ic uninitialized_variable_warn Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location , Ic if
-.El
-.Pp
-Controls whether warnings about uninitialized variables are logged.
-.El
-.Ss Module ngx_http_secure_link_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic secure_link Ar expression
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a string with variables from which the checksum value and lifetime of a
-link will be extracted.
-Variables used in an
-.Ar expression
-are usually associated with a request; see
-.Ic secure_link_md5
-example
-below.
-The checksum value extracted from the string is compared with the MD5 hash value
-of the expression defined by the
-.Ic secure_link_md5
-directive.
-If the checksums are different, the
-.Va $secure_link
-variable is set to an empty string.
-If the checksums are the same, the link lifetime is checked.
-If the link has a limited lifetime and the time has expired, the
-.Va $secure_link
-variable is set to
-0.
-Otherwise, it is set to
-1.
-The MD5 hash value passed in a request is encoded in base64url.
-If a link has a limited lifetime, the expiration time is set in seconds since
-Epoch (Thu, 01 Jan 1970 00:00:00 GMT).
-The value is specified in the expression after the MD5 hash, and is separated by
-a comma.
-The expiration time passed in a request is available through the
-.Va $secure_link_expires
-variable for a use in the
-.Ic secure_link_md5
-directive.
-If the expiration time is not specified, a link has the unlimited lifetime.
-.It Ic secure_link_md5 Ar expression
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines an expression for which the MD5 hash value will be computed and compared
-with the value passed in a request.
-The expression should contain the secured part of a link (resource) and a secret
-ingredient.
-If the link has a limited lifetime, the expression should also contain
-.Va $secure_link_expires .
-To prevent unauthorized access, the expression may contain some information
-about the client, such as its address and browser version.
-Example:
-.Bd -literal -offset indent
-location /s/ {
- secure_link $arg_md5,$arg_expires;
- secure_link_md5 "$secure_link_expires$uri$remote_addr secret";
- if ($secure_link = "") {
- return 403;
- }
- if ($secure_link = "0") {
- return 410;
- }
- ...
-}
-.Ed
-.Pp
-The
-.Qq /s/link?md5 Ns = Ns _e4Nc3iduzkWRm01TBBNYw&expires Ns = Ns 2147483647
-link restricts access to
-.Qq /s/link
-for the client with the IP address 127.0.0.1.
-The link also has the limited lifetime until January 19, 2038 (GMT).
-On UNIX, the
-.Ar md5
-request argument value can be obtained as:
-.Bd -literal -offset indent
-echo -n '2147483647/s/link127.0.0.1 secret' | \\
- openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =
-.Ed
-.It Ic secure_link_secret Ar word
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-Defines a secret
-.Ar word
-used to check authenticity of requested links.
-The full URI of a requested link looks as follows:
-.Bd -literal -offset indent
-/prefix/hash/link
-.Ed
-.Pp
-where
-.Ar hash
-is a hexadecimal representation of the MD5 hash computed for the concatenation
-of the link and secret word, and
-.Ar prefix
-is an arbitrary string without slashes.
-If the requested link passes the authenticity check, the
-.Va $secure_link
-variable is set to the link extracted from the request URI.
-Otherwise, the
-.Va $secure_link
-variable is set to an empty string.
-Example:
-.Bd -literal -offset indent
-location /p/ {
- secure_link_secret secret;
- if ($secure_link = "") {
- return 403;
- }
- rewrite ^ /secure/$secure_link;
-}
-location /secure/ {
- internal;
-}
-.Ed
-.Pp
-A request of
-.Qq /p/5e814704a28d9bc1914ff19fa0c4a00a/link
-will be internally redirected to
-.Qq /secure/link .
-On UNIX, the hash value for this example can be obtained as:
-.Bd -literal -offset indent
-echo -n 'linksecret' | openssl md5 -hex
-.Ed
-.El
-.Ss Module ngx_http_session_log_module
-.Em This module is only available in the commercial version of nginx.
-.Bl -tag -width Ds
-.It Ic session_log_format Ar name Ar string No ...
-.Bl -tag -width Ds -compact
-.It default: combined Qq ...
-.It context: Ic http
-.El
-.Pp
-Specifies the output format of a log.
-The value of the
-.Va $body_bytes_sent
-variable is aggregated across all requests in a session.
-The values of all other variables available for logging correspond to the first
-request in a session.
-.It Ic session_log_zone Ar path Cm zone Ns = Ns Ar name Ns : Ns Ar size Oo Cm format Ns = Ns Ar format Oc Oo Cm timeout Ns = Ns Ar time Oc Oo Cm id Ns = Ns Ar id Oc Oo Cm md5 Ns = Ns Ar md5 Oc
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Sets the path to a log file and configures the shared memory zone that is used
-to store currently active sessions.
-A session is considered active for as long as the time elapsed since the last
-request in the session does not exceed the specified
-.Cm timeout
-(by default, 30 seconds).
-Once a session is no longer active, it is written to the log.
-The
-.Ar id
-parameter identifies the session to which a request is mapped.
-The
-.Ar id
-parameter is set to the hexadecimal representation of an MD5 hash (for example,
-obtained from a cookie using variables).
-If this parameter is not specified or does not represent the valid MD5 hash,
-nginx computes the MD5 hash from the value of the
-.Ar md5
-parameter and creates a new session using this hash.
-Both the
-.Ar id
-and
-.Ar md5
-parameters can contain variables.
-The
-.Ar format
-parameter sets the custom session log format configured by the
-.Ic session_log_format
-directive.
-If
-.Ar format
-is not specified, the predefined
-combined
-format is used.
-.It Ic session_log Ar name | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables the use of the specified session log.
-The special value
-.Cm off
-cancels all
-.Ic session_log
-directives inherited from the previous configuration level.
-.El
-.Ss Module ngx_http_spdy_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic spdy_headers_comp Ar level
-.Bl -tag -width Ds -compact
-.It default: 0
-.It context: Ic http , Ic server
-.El
-.Pp
-Sets the header compression
-.Ar level
-of a response in a range from 1 (fastest, less compression) to 9 (slowest, best
-compression).
-The special value 0 turns off the header compression.
-.El
-.Ss Module ngx_http_split_clients_module
-.Bl -tag -width Ds
-.It Ic split_clients Ar string Ar $variable Brq No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Creates a variable for A/B testing, for example:
-.Bd -literal -offset indent
-split_clients "${remote_addr}AAA" $variant {
- 0.5% .one;
- 2.0% .two;
- * "";
-}
-.Ed
-.Pp
-The value of the original string is hashed using MurmurHash2.
-In the example given, hash values from 0 to 21474835 (0.5%) correspond to the
-value
-.Qq .one
-of the
-.Va $variant
-variable, hash values from 21474836 to 107374180 (2%) correspond to the value
-.Qq .two ,
-and hash values from 107374181 to 4294967295 correspond to the value
-.Qq
-(an empty string).
-.El
-.Ss Module ngx_http_ssi_module
-.Bl -tag -width Ds
-.It Ic ssi Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location , Ic if in location
-.El
-.Pp
-Enables or disables processing of SSI commands in responses.
-.It Ic ssi_last_modified Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Allows preserving the Last-Modified header field from the original response
-during SSI processing to facilitate response caching.
-By default, the header field is removed as contents of the response are modified
-during processing and may contain dynamically generated elements or parts that
-are changed independently of the original response.
-.It Ic ssi_min_file_chunk Cm size
-.Bl -tag -width Ds -compact
-.It default: 1k
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the minimum
-.Ar size
-for parts of a response stored on disk, starting from which it makes sense to
-send them using
-.Ic sendfile .
-.It Ic ssi_silent_errors Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-If enabled, suppresses the output of the
-.Qq an error occurred while processing the directive
-string if an error occurred during SSI processing.
-.It Ic ssi_types Ar mime-type No ...
-.Bl -tag -width Ds -compact
-.It default: text/html
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables processing of SSI commands in responses with the specified MIME types in
-addition to text/html.
-The special value
-.Qq *
-matches any MIME type (0.8.29).
-.It Ic ssi_value_length Ar length
-.Bl -tag -width Ds -compact
-.It default: 256
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the maximum length of parameter values in SSI commands.
-.El
-.Ss Module ngx_http_ssl_module
-.Bl -tag -width Ds
-.It Ic ssl Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server
-.El
-.Pp
-Enables the HTTPS protocol for the given virtual server.
-It is recommended to use the
-.Ar ssl
-parameter of the
-.Ic listen
-directive instead of this directive.
-.It Ic ssl_certificate Ar file
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server
-.El
-.Pp
-Specifies a
-.Ar file
-with the certificate in the PEM format for the given virtual server.
-If intermediate certificates should be specified in addition to a primary
-certificate, they should be specified in the same file in the following order:
-the primary certificate comes first, then the intermediate certificates.
-A secret key in the PEM format may be placed in the same file.
-It should be kept in mind that due to the HTTPS protocol limitations virtual
-servers should listen on different IP addresses:
-.Bd -literal -offset indent
-server {
- listen 192.168.1.1:443;
- server_name one.example.com;
- ssl_certificate /usr/local/nginx/conf/one.example.com.cert;
- ...
-}
-server {
- listen 192.168.1.2:443;
- server_name two.example.com;
- ssl_certificate /usr/local/nginx/conf/two.example.com.cert;
- ...
-}
-.Ed
-.Pp
-otherwise the first server's certificate will be issued for the second site.
-.It Ic ssl_certificate_key Ar file
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server
-.El
-.Pp
-Specifies a
-.Ar file
-with the secret key in the PEM format for the given virtual server.
-.It Ic ssl_ciphers Ar ciphers
-.Bl -tag -width Ds -compact
-.It default: HIGH:!aNULL:!MD5
-.It context: Ic http , Ic server
-.El
-.Pp
-Specifies the enabled ciphers.
-The ciphers are specified in the format understood by the OpenSSL library, for
-example:
-.Bd -literal -offset indent
-ssl_ciphers ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
-.Ed
-.Pp
-The full list can be viewed using the
-.Ic openssl ciphers
-command.
-The previous versions of nginx used different ciphers by default.
-.It Ic ssl_client_certificate Ar file
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server
-.El
-.Pp
-Specifies a
-.Ar file
-with trusted CA certificates in the PEM format used to verify client
-certificates and OCSP responses if
-.Ic ssl_stapling
-is enabled.
-The list of certificates will be sent to clients.
-If this is not desired, the
-.Ic ssl_trusted_certificate
-directive can be used.
-.It Ic ssl_crl Ar file
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server
-.El
-.Pp
-Specifies a
-.Ar file
-with revoked certificates (CRL) in the PEM format used to verify client
-certificates.
-.It Ic ssl_dhparam Ar file
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server
-.El
-.Pp
-Specifies a
-.Ar file
-with DH parameters for EDH ciphers.
-.It Ic ssl_prefer_server_ciphers Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server
-.El
-.Pp
-Specifies that server ciphers should be preferred over client ciphers when using
-the SSLv3 and TLS protocols.
-.It Ic ssl_protocols Oo Cm SSLv2 Oc Oo Cm SSLv3 Oc Oo Cm TLSv1 Oc Oo Cm TLSv1.1 Oc Oo Cm TLSv1.2 Oc
-.Bl -tag -width Ds -compact
-.It default: SSLv3 TLSv1 TLSv1.1 TLSv1.2
-.It context: Ic http , Ic server
-.El
-.Pp
-Enables the specified protocols.
-The
-.Cm TLSv1.1
-and
-.Cm TLSv1.2
-parameters work only when the OpenSSL library of version 1.0.1 or higher is
-used.
-The
-.Cm TLSv1.1
-and
-.Cm TLSv1.2
-parameters are supported starting from versions 1.1.13 and 1.0.12, so when the
-OpenSSL version 1.0.1 or higher is used on older nginx versions, these protocols
-work, but cannot be disabled.
-.It Ic ssl_session_cache Cm off | Cm none | \
- Oo Cm builtin Ns Oo : Ns Ar size Oc Oc Oo Cm shared: Ar name: Ar size Oc
-.Bl -tag -width Ds -compact
-.It default: Cm none
-.It context: Ic http , Ic server
-.El
-.Pp
-Sets the types and sizes of caches that store session parameters.
-A cache can be of any of the following types:
-.Bl -tag -width Ds
-.It Cm off
-the use of a session cache is strictly prohibited: nginx explicitly tells a
-client that sessions may not be reused.
-.It Cm none
-the use of a session cache is gently disallowed: nginx tells a client that
-sessions may be reused, but does not actually store session parameters in the
-cache.
-.It Cm builtin
-a cache built in OpenSSL; used by one worker process only.
-The cache size is specified in sessions.
-If size is not given, it is equal to 20480 sessions.
-Use of the built-in cache can cause memory fragmentation.
-.It Cm shared
-a cache shared between all worker processes.
-The cache size is specified in bytes; one megabyte can store about 4000
-sessions.
-Each shared cache should have an arbitrary name.
-A cache with the same name can be used in several virtual servers.
-.El
-.Pp
-Both cache types can be used simultaneously, for example:
-.Bd -literal -offset indent
-ssl_session_cache builtin:1000 shared:SSL:10m;
-.Ed
-.Pp
-but using only shared cache without the built-in cache should be more efficient.
-.It Ic ssl_session_timeout Ar time
-.Bl -tag -width Ds -compact
-.It default: 5m
-.It context: Ic http , Ic server
-.El
-.Pp
-Specifies a time during which a client may reuse the session parameters stored
-in a cache.
-.It Ic ssl_stapling Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server
-.El
-.Pp
-Enables or disables
-stapling
-of OCSP responses
-by the server.
-Example:
-.Bd -literal -offset indent
-ssl_stapling on;
-resolver 192.0.2.1;
-.Ed
-.Pp
-For the OCSP stapling to work, the certificate of the server certificate issuer
-should be known.
-If the
-.Ic ssl_certificate
-file does not contain intermediate certificates, the certificate of the server
-certificate issuer should be present in the
-.Ic ssl_trusted_certificate
-file.
-For a resolution of the OCSP responder hostname, the
-.Ic resolver
-directive should also be specified.
-.It Ic ssl_stapling_file Ar file
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server
-.El
-.Pp
-When set, the stapled OCSP response will be taken from the specified
-.Ar file
-instead of querying the OCSP responder specified in the server certificate.
-The file should be in the DER format as produced by the
-.Ic openssl ocsp
-command.
-.It Ic ssl_stapling_responder Ar url
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server
-.El
-.Pp
-Overrides the URL of the OCSP responder specified in the
-Authority
-Information Access
-certificate extension.
-Only
-.Qq http://
-OCSP responders are supported:
-.Bd -literal -offset indent
-ssl_stapling_responder http://ocsp.example.com/;
-.Ed
-.It Ic ssl_stapling_verify Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server
-.El
-.Pp
-Enables or disables verification of OCSP responses by the server.
-For verification to work, the certificate of the server certificate issuer, the
-root certificate, and all intermediate certificates should be configured as
-trusted using the
-.Ic ssl_trusted_certificate
-directive.
-.It Ic ssl_trusted_certificate Ar file
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server
-.El
-.Pp
-Specifies a
-.Ar file
-with trusted CA certificates in the PEM format used to verify client
-certificates and OCSP responses if
-.Ic ssl_stapling
-is enabled.
-In contrast to the certificate set by
-.Ic ssl_client_certificate ,
-the list of these certificates will not be sent to clients.
-.It Ic ssl_verify_client Cm on | Cm off | Cm optional | Cm optional_no_ca
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server
-.El
-.Pp
-Enables verification of client certificates.
-The verification result is stored in the
-.Va $ssl_client_verify
-variable.
-The
-.Cm optional
-parameter (0.8.7+) requests the client certificate and verifies it if the
-certificate is present.
-The
-.Cm optional_no_ca
-parameter (1.3.8, 1.2.5) requests the client certificate but does not require it
-to be signed by a trusted CA certificate.
-This is intended for the use in cases when a service that is external to nginx
-performs the actual certificate verification.
-The contents of the certificate is accessible through the
-.Va $ssl_client_cert
-variable.
-.It Ic ssl_verify_depth Ar number
-.Bl -tag -width Ds -compact
-.It default: 1
-.It context: Ic http , Ic server
-.El
-.Pp
-Sets the verification depth in the client certificates chain.
-.El
-.Ss Module ngx_http_status_module
-.Em This module is only available in the commercial version of nginx.
-.Bl -tag -width Ds
-.It Ic status
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-The status information will be accessible from the surrounding location.
-.It Ic status_format Cm json
-.It Ic status_format Cm jsonp Oo Ar callback Oc
-.Bl -tag -width Ds -compact
-.It default: json
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-By default, status information is output in the JSON format.
-Alternatively, data may be output as JSONP.
-The
-.Ar callback
-parameter specifies the name of a callback function.
-The value can contain variables.
-If parameter is omitted, or the computed value is an empty string, then
-.Sx Module ngx_status_jsonp_callback
-is used.
-.El
-.Ss Module ngx_http_stub_status_module
-.Bl -tag -width Ds
-.It Ic stub_status Cm on
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-The status information will be accessible from the surrounding location.
-.El
-.Ss Module ngx_http_sub_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic sub_filter Ar string Ar replacement
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a string to replace and a replacement string.
-The string to replace is matched ignoring the case.
-The replacement string can contain variables.
-.It Ic sub_filter_last_modified Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Allows preserving the Last-Modified header field from the original response
-during replacement to facilitate response caching.
-By default, the header field is removed as contents of the response are modified
-during processing.
-.It Ic sub_filter_once Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm on
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Indicates whether to look for a string to replace once or several times.
-.It Ic sub_filter_types Ar mime-type No ...
-.Bl -tag -width Ds -compact
-.It default: text/html
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables string replacement in responses with the specified MIME types in
-addition to
-.Ar text/html .
-The special value
-.Qq *
-matches any MIME type (0.8.29).
-.El
-.Ss Module ngx_http_upstream_module
-.Bl -tag -width Ds
-.It Ic upstream Ar name Brq No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-Defines a group of servers.
-Servers can listen on different ports.
-In addition, servers listening on TCP and UNIX-domain sockets can be mixed.
-Example:
-.Bd -literal -offset indent
-upstream backend {
- server backend1.example.com weight=5;
- server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
- server unix:/tmp/backend3;
-}
-.Ed
-.Pp
-By default, requests are distributed between the servers using a weighted
-round-robin balancing method.
-In the above example, each 7 requests will be distributed as follows: 5 requests
-go to
-backend1.example.com
-and one request to each of the second and third servers.
-If an error occurs during communication with a server, the request will be
-passed to the next server, and so on until all of the functioning servers will
-be tried.
-If a successful response could not be obtained from any of the servers, the
-client will receive the result of the communication with the last server.
-.It Ic server Ar address Oo Ar parameters Oc
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic upstream
-.El
-.Pp
-Defines the
-.Ar address
-and other
-.Ar parameters
-of a server.
-The address can be specified as a domain name or IP address, with an optional
-port, or as a UNIX-domain socket path specified after the
-.Cm unix:
-prefix.
-If a port is not specified, the port 80 is used.
-A domain name that resolves to several IP addresses defines multiple servers at
-once.
-The following parameters can be defined:
-.Bl -tag -width Ds
-.It Cm weight Ns = Ns Ar number
-sets the weight of the server, by default, 1.
-.It Cm max_fails Ns = Ns Ar number
-sets the number of unsuccessful attempts to communicate with the server that
-should happen in the duration set by the
-.Cm fail_timeout
-parameter to consider the server unavailable for a duration also set by the
-.Cm fail_timeout
-parameter.
-By default, the number of unsuccessful attempts is set to 1.
-The zero value disables the accounting of attempts.
-What is considered an unsuccessful attempt is defined by the
-.Ic proxy_next_upstream ,
-.Ic fastcgi_next_upstream ,
-and
-.Ic memcached_next_upstream
-directives.
-.It Cm fail_timeout Ns = Ns Ar time
-sets
-.Bl -bullet
-.It
-the time during which the specified number of unsuccessful attempts to
-communicate with the server should happen to consider the server unavailable;
-.It
-and the period of time the server will be considered unavailable.
-.El
-.Pp
-By default, the parameter is set to 10 seconds.
-.It Cm slow_start Ns = Ns Ar time
-sets the
-.Ar time
-during which the server will recover its weight from zero to a nominal value,
-when unhealthy server becomes healthy, or when the server becomes available
-after a period of time it was considered unavailable.
-Default value is zero,
-i.e. slow start is disabled.
-.Pp
-.Em This option is only available in the commercial version of nginx.
-.It Cm backup
-marks the server as a backup server.
-It will be passed requests when the primary servers are unavailable.
-.It Cm down
-marks the server as permanently unavailable; used along with the
-.Ic ip_hash
-directive.
-.It Cm route Ns = Ns Ar string
-sets the server route name.
-.Pp
-.Em This option is only available in the commercial version of nginx.
-.El
-.Pp
-Example:
-.Bd -literal -offset indent
-upstream backend {
- server backend1.example.com weight=5;
- server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
- server unix:/tmp/backend3;
- server backup1.example.com:8080 backup;
-}
-.Ed
-.Pp
-If there is only a single server in a group,
-.Cm max_fails ,
-.Cm fail_timeout
-and
-.Cm slow_start
-parameters are ignored, and such a server will never be considered unavailable.
-.It Ic zone Ar name Ar size
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic upstream
-.El
-.Pp
-.Em This directive is only available in the commercial version of nginx.
-.Pp
-Makes the group dynamically configurable.
-Defines the
-.Ar name
-and
-.Ar size
-of a shared memory zone that keeps group's configuration and run-time state that
-are shared between worker processes.
-Such groups allow to add, remove, and modify servers at run time.
-The configuration is accessible via a special location handled by
-.Ic upstream_conf .
-.It Ic ip_hash
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic upstream
-.El
-.Pp
-Specifies that a group should use a load balancing method where requests are
-distributed between servers based on client IP addresses.
-The first three octets of the client IPv4 address, or the entire IPv6 address,
-are used as a hashing key.
-The method ensures that requests from the same client will always be passed to
-the same server except when this server is unavailable.
-In the latter case client requests will be passed to another server.
-Most probably, it will always be the same server as well.
-IPv6 addresses are supported starting from versions 1.3.2 and 1.2.2.
-If one of the servers needs to be temporarily removed, it should be marked with
-the
-.Cm down
-parameter in order to preserve the current hashing of client IP addresses.
-Example:
-.Bd -literal -offset indent
-upstream backend {
- ip_hash;
- server backend1.example.com;
- server backend2.example.com;
- server backend3.example.com down;
- server backend4.example.com;
-}
-.Ed
-.Pp
-Until versions 1.3.1 and 1.2.2, it was not possible to specify a weight for
-servers using the
-.Ic ip_hash
-load balancing method.
-.It Ic keepalive Ar connections
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic upstream
-.El
-.Pp
-Activates the cache for connections to upstream servers.
-The
-.Ar connections
-parameter sets the maximum number of idle keepalive connections to upstream
-servers that are preserved in the cache of each worker process.
-When this number is exceeded, the least recently used connections are closed.
-It should be particularly noted that the
-.Ic keepalive
-directive does not limit the total number of connections to upstream servers
-that an nginx worker process can open.
-The
-.Ar connections
-parameter should be set to a number small enough to let upstream servers process
-new incoming connections as well.
-Example configuration of memcached upstream with keepalive connections:
-.Bd -literal -offset indent
-upstream memcached_backend {
- server 127.0.0.1:11211;
- server 10.0.0.2:11211;
- keepalive 32;
-}
-server {
- ...
- location /memcached/ {
- set $memcached_key $uri;
- memcached_pass memcached_backend;
- }
-}
-.Ed
-.Pp
-For HTTP, the
-.Ic proxy_http_version
-directive should be set to
-1.1
-and the Connection header field should be cleared:
-.Bd -literal -offset indent
-upstream http_backend {
- server 127.0.0.1:8080;
- keepalive 16;
-}
-server {
- ...
- location /http/ {
- proxy_pass http://http_backend;
- proxy_http_version 1.1;
- proxy_set_header Connection "";
- ...
- }
-}
-.Ed
-.Pp
-Alternatively, HTTP/1.0 persistent connections can be used by passing the
-Connection: Keep-Alive header field to an upstream server, though this method is
-not recommended.
-For FastCGI servers, it is required to set
-.Ic fastcgi_keep_conn
-for keepalive connections to work:
-.Bd -literal -offset indent
-upstream fastcgi_backend {
- server 127.0.0.1:9000;
- keepalive 8;
-}
-server {
- ...
- location /fastcgi/ {
- fastcgi_pass fastcgi_backend;
- fastcgi_keep_conn on;
- ...
- }
-}
-.Ed
-.Pp
-When using load balancer methods other than the default round-robin method, it
-is necessary to activate them before the
-.Ic keepalive
-directive.
-SCGI and uwsgi protocols do not have a notion of keepalive connections.
-.It Ic least_conn
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic upstream
-.El
-.Pp
-Specifies that a group should use a load balancing method where a request is
-passed to the server with the least number of active connections, taking into
-account weights of servers.
-If there are several such servers, they are tried using a weighted round-robin
-balancing method.
-.It Ic health_check Oo Cm interval Ns = Ns Ar time Oc Oo Cm fails Ns = Ns Ar number Oc Oo Cm passes Ns = Ns Ar number Oc Oo Cm uri Ns = Ns Ar uri Oc Oo Cm match Ns = Ns Ar name Oc
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-.Em This directive is only available in the commercial version of nginx.
-.Pp
-Enables periodic health checks of the servers in a
-.Ic upstream
-.Ar group
-referenced in the surrounding location.
-The following optional parameters are supported:
-.Bl -bullet
-.It
-.Cm interval
-sets the interval between two consecutive health checks, by default, 5 seconds;
-.It
-.Cm fails
-sets the number of consecutive failed health checks of a particular server after
-which this server will be considered unhealthy, by default, 1;
-.It
-.Cm passes
-sets the number of consecutive passed health checks of a particular server after
-which the server will be considered healthy, by default, 1;
-.It
-.Ar uri
-defines the URI used in health check requests, by default,
-.Qq / ;
-.It
-.Ic match
-specifies the
-.Ic match
-block configuring the tests that a response should pass in order for a health
-check to pass; by default, the response should have status code 2xx or 3xx.
-.El
-.Pp
-For example,
-.Bd -literal -offset indent
-location / {
- proxy_pass http://backend;
- health_check;
-}
-.Ed
-.Pp
-will send
-.Qq /
-requests to each server in the
-backend
-group every five seconds.
-If any communication error or timeout occurs, or a proxied server responds with
-the status code other than 2xx or 3xx, the health check will fail, and the
-server will be considered unhealthy.
-Client requests are not passed to unhealthy servers.
-Health checks can be configured to test the status code of a response, presence
-of certain header fields and their values, and the body contents.
-Tests are configured separately using the
-.Ic match
-directive and referenced in the
-.Ic match
-parameter.
-For example:
-.Bd -literal -offset indent
-http {
- server {
- ...
- location / {
- proxy_pass http://backend;
- health_check match=welcome;
- }
- }
- match welcome {
- status 200;
- header Content-Type = text/html;
- body ~ "Welcome to nginx!";
- }
-}
-.Ed
-.Pp
-This configuration tells that for a health check to pass, the response to a
-health check request should succeed, have status 200, content type text/html,
-and contain
-.Qq Welcome to nginx!
-in the body.
-The server group must reside in the shared memory.
-If several health checks are defined for the same group of servers, a single
-failure of any check will make the corresponding server be considered unhealthy.
-.It Ic match Ar name Brq No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http
-.El
-.Pp
-.Em This directive is only available in the commercial version of nginx.
-.Pp
-Defines the named test set used to verify responses to health check requests.
-The following items can be tested in a response:
-.Bl -tag -width Ds
-.It Cm status 200;
-status is 200
-.It Cm status ! 500;
-status is not 500
-.It Cm status 200 204;
-status is 200 or 204
-.It Cm status ! 301 302;
-status is neither 301 nor 302
-.It Cm status 200-399;
-status is in the range from 200 to 399
-.It Cm status ! 400-599;
-status is not in the range from 400 to 599
-.It Cm status 301-303 307;
-status is either 301, 302, 303, or 307
-.El
-.Bl -tag -width Ds
-.It Cm header Content-Type Ns = Ns Cm text/html;
-header contains Content-Type with value text/html
-.It Cm header Content-Type ! Ns = Ns Cm text/html;
-header contains Content-Type with value other than text/html
-.It Cm header Connection ~ close;
-header contains Connection with value matching regular expression
-close
-.It Cm header Connection !~ close;
-header contains Connection with value not matching regular expression
-close
-.It Cm header Host;
-header contains Host
-.It Cm header ! X-Accel-Redirect;
-header lacks X-Accel-Redirect
-.El
-.Bl -tag -width Ds
-.It Cm body ~ "Welcome to nginx!";
-body matches regular expression
-Welcome to nginx!
-.It Cm body !~ "Welcome to nginx!";
-body does not match regular expression
-Welcome to nginx!
-.El
-.Pp
-If several tests are specified, the response matches only if it matches all
-tests.
-Only the first 256k of the response body are examined.
-Examples:
-.Bd -literal -offset indent
-# status is 200, content type is "text/html",
-# and body contains "Welcome to nginx!"
-match welcome {
- status 200;
- header Content-Type = text/html;
- body ~ "Welcome to nginx!";
-}
-.Ed
-.Bd -literal -offset indent
-# status is not one of 301, 302, 303, or 307, and header does not have "Refresh:"
-match not_redirect {
- status ! 301-303 307;
- header ! Refresh;
-}
-.Ed
-.Bd -literal -offset indent
-# status ok and not in maintenance mode
-match server_ok {
- status 200-399;
- body !~ "maintenance mode";
-}
-.Ed
-.It Ic sticky Cm cookie Ar name Oo Cm expires Ns = Ns Ar time Oc Oo Cm domain Ns = Ns Ar domain Oc Oo Cm path Ns = Ns Ar path Oc
-.It Ic sticky Cm route Ar variable No ...
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic upstream
-.El
-.Pp
-.Em This directive is only available in the commercial version of nginx.
-.Pp
-Enables session affinity, which causes requests from the same client to be
-passed to the same server in a group of servers.
-Two methods are available,
-.Cm cookie
-and
-.Cm route .
-When the
-.Cm cookie
-method is used, information about the designated server is passed in an HTTP
-cookie:
-.Bd -literal -offset indent
-upstream backend {
- server backend1.example.com;
- server backend2.example.com;
- sticky cookie srv_id expires=1h domain=.example.com path=/;
-}
-.Ed
-.Pp
-A request that comes from a client not yet bound to a particular server is
-passed to the server selected by the configured balancing method.
-Further requests from the same client are passed to the same server.
-If the designated server cannot process a request, the new server is selected as
-if the client has not been bound yet.
-The first parameter sets the name of the cookie to be set or inspected.
-Additional parameters may be as follows:
-.Bl -tag -width Ds
-.It Cm expires
-Sets the time for which a browser should keep the cookie.
-The special value
-.Cm max
-will cause the cookie to expire on
-31 Dec 2037 23:55:55 GMT.
-This is the maximum time understood by old browsers.
-If the parameter is not specified, it will cause the cookie to expire at the end
-of a browser session.
-.It Cm domain
-Defines the domain for which the cookie is set.
-.It Cm path
-Defines the path for which the cookie is set.
-.El
-.Pp
-If any parameters are omitted, the corresponding cookie fields are not set.
-When the
-.Cm route
-method is used, proxied server assigns client a route on receipt of the first
-request.
-All subsequent requests from this client will carry routing information in a
-cookie or URI.
-This information is compared with the
-.Cm route
-parameter of the
-.Ic server
-directive to identify the server to which the request should be proxied.
-If the designated server cannot process a request, the new server is selected by
-the configured balancing method as if there is no routing information in the
-request.
-The parameters of the
-.Cm route
-method specify variables that may contain routing information.
-The first non-empty variable is used to find the matching server.
-Example:
-.Bd -literal -offset indent
-map $cookie_jsessionid $route_cookie {
- ~.+\\.(?P<route>\\w+)$ $route;
-}
-map $request_uri $route_uri {
- ~jsessionid=.+\\.(?P<route>\\w+)$ $route;
-}
-upstream backend {
- server backend1.example.com route=a;
- server backend2.example.com route=b;
- sticky route $route_cookie $route_uri;
-}
-.Ed
-.Pp
-Here, the route is taken from the
-JSESSIONID
-cookie if present in a request.
-Otherwise, the route from the URI is used.
-.It Ic sticky_cookie_insert Ar name Oo Cm expires Ns = Ns Ar time Oc Oo Cm domain Ns = Ns Ar domain Oc Oo Cm path Ns = Ns Ar path Oc
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic upstream
-.El
-.Pp
-This directive is obsolete since version 1.5.7.
-An equivalent
-.Ic sticky
-directive with a new syntax should be used instead:
-.Ic sticky cookie Ar name Oo Cm expires Ns = Ns Ar time Oc Oo Cm domain Ns = Ns Ar domain Oc Oo Cm path Ns = Ns Ar path Oc ;
-.It Ic upstream_conf
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-.Em This directive is only available in the commercial version of nginx.
-.Pp
-Turns on the HTTP interface of upstream configuration in the surrounding
-location.
-Access to this location should be
-.Ic satisfy
-limited .
-Configuration commands can be used to:
-.Bl -bullet
-.It
-view all primary or backup servers in a group;
-.It
-view an individual server;
-.It
-modify an individual server;
-.It
-add a new server (see the note below);
-.It
-remove an individual server.
-.El
-.Pp
-As noted in the
-.Ic server
-directive, specifying a server as a domain name may result in several servers
-being added to the group.
-Since addresses in a group are not required to be unique, individual servers in
-a group can be uniquely referenced to only by their ID.
-IDs are assigned automatically and shown on viewing of the group configuration.
-A configuration command consists of parameters passed as request arguments, for
-example:
-.Bd -literal -offset indent
-http://127.0.0.1/upstream_conf?upstream=appservers
-.Ed
-.Pp
-The following parameters are supported:
-.Bl -tag -width Ds
-.It Cm upstream Ns = Ns Ar name
-Selects a group.
-This parameter is mandatory.
-.It Cm backup Ns =
-If not set, selects primary servers in the group.
-If set, selects backup servers in the group.
-.It Cm id Ns = Ns Ar number
-Selects an individual primary or backup server in the group.
-.It Cm remove Ns =
-Removes an individual primary or backup server from the group.
-.It Cm add Ns =
-Adds a new primary or backup server to the group.
-.It Cm server Ns = Ns Ar address
-Same as the
-.Ar address
-parameter of the
-.Ic server
-directive.
-.It Cm weight Ns = Ns Ar number
-Same as the
-.Cm weight
-parameter of the
-.Ic server
-directive.
-.It Cm max_fails Ns = Ns Ar number
-Same as the
-.Cm max_fails
-parameter of the
-.Ic server
-directive.
-.It Cm fail_timeout Ns = Ns Ar time
-Same as the
-.Cm fail_timeout
-parameter of the
-.Ic server
-directive.
-.It Cm slow_start Ns = Ns Ar time
-Same as the
-.Cm slow_start
-parameter of the
-.Ic server
-directive.
-.It Cm down Ns =
-Same as the
-.Cm down
-parameter of the
-.Ic server
-directive.
-.It Cm up Ns =
-The opposite of the
-.Cm down
-parameter of the
-.Ic server
-directive.
-.It Cm route Ns = Ns Ar string
-Same as the
-.Cm route
-parameter of the
-.Ic server
-directive.
-.El
-.Pp
-The first three parameters select a target the command applies to.
-Without other parameters, the command shows configuration of the selected
-target.
-For example, to view the primary servers in the group, send:
-.Bd -literal -offset indent
-http://127.0.0.1/upstream_conf?upstream=appservers
-.Ed
-.Pp
-To view the backup servers in the group, send:
-.Bd -literal -offset indent
-http://127.0.0.1/upstream_conf?upstream=appservers&backup=
-.Ed
-.Pp
-To view an individual primary server in the group, send:
-.Bd -literal -offset indent
-http://127.0.0.1/upstream_conf?upstream=appservers&id=42
-.Ed
-.Pp
-To view an individual backup server in the group, send:
-.Bd -literal -offset indent
-http://127.0.0.1/upstream_conf?upstream=appservers&backup=&id=42
-.Ed
-.Pp
-To add a new primary or backup server to the group, specify its address in the
-.Ic server Ns =
-parameter.
-Without other parameters specified, a server will be added with other parameters
-set to their default values (see the
-.Ic server
-directive).
-For example, to add a new primary server to the group, send:
-.Bd -literal -offset indent
-http://127.0.0.1/upstream_conf?add=&upstream=appservers&server=127.0.0.1:8080
-.Ed
-.Pp
-To add a new backup server to the group, send:
-.Bd -literal -offset indent
-http://127.0.0.1/upstream_conf?add=&upstream=appservers&backup=&server=127.0.0.1:8080
-.Ed
-.Pp
-To add a new primary server to the group, set its parameters to non-default
-values and mark it as
-.Cm down ,
-send:
-.Bd -literal -offset indent
-http://127.0.0.1/upstream_conf?add=&upstream=appservers&server=127.0.0.1:8080&weight=2&max_fails=3&fail_timeout=3s&down=
-.Ed
-.Pp
-To remove an individual primary or backup server from the group, select it with
-the
-.Cm id Ns =
-parameter.
-For example, to remove an individual primary server from the group, send:
-.Bd -literal -offset indent
-http://127.0.0.1/upstream_conf?remove=&upstream=appservers&id=42
-.Ed
-.Pp
-To remove an individual backup server from the group, send:
-.Bd -literal -offset indent
-http://127.0.0.1/upstream_conf?remove=&upstream=appservers&backup=&id=42
-.Ed
-.Pp
-To modify an individual primary or backup server in the group, select it with
-the
-.Cm id Ns =
-parameter.
-For example, to modify an individual primary server in the group by marking it
-as
-.Cm down ,
-send:
-.Bd -literal -offset indent
-http://127.0.0.1/upstream_conf?upstream=appservers&id=42&down=
-.Ed
-.Pp
-To modify the address of an individual backup server in the group, send:
-.Bd -literal -offset indent
-http://127.0.0.1/upstream_conf?upstream=appservers&backup=&id=42&server=192.0.2.3:8123
-.Ed
-.Pp
-To modify other parameters of an individual primary server in the group, send:
-.Bd -literal -offset indent
-http://127.0.0.1/upstream_conf?upstream=appservers&id=42&max_fails=3&weight=4
-.Ed
-.El
-.Ss Module ngx_http_userid_module
-.Bl -tag -width Ds
-.It Ic userid Cm on | Cm v1 | Cm log | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables or disables setting cookies and logging the received cookies:
-.Bl -tag -width Ds
-.It Cm on
-enables the setting of version 2 cookies and logging of the received cookies;
-.It Cm v1
-enables the setting of version 1 cookies and logging of the received cookies;
-.It Cm log
-disables the setting of cookies, but enables logging of the received cookies;
-.It Cm off
-disables the setting of cookies and logging of the received cookies.
-.El
-.It Ic userid_domain Ar name | Cm none
-.Bl -tag -width Ds -compact
-.It default: Cm none
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a domain for which the cookie is set.
-The
-.Cm none
-parameter disables setting of a domain for the cookie.
-.It Ic userid_expires Ar time | Cm max | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a time during which a browser should keep the cookie.
-The parameter
-.Cm max
-will cause the cookie to expire on
-31 Dec 2037 23:55:55 GMT.
-This is the maximum time understood by old browsers.
-The parameter
-.Cm off
-will cause the cookie to expire at the end of a browser session.
-.It Ic userid_mark Ar letter | Ar digit | Ns = Ns | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-If the parameter is not
-.Cm off ,
-enables the cookie marking mechanism and sets the character used as a mark.
-This mechanism is used to add or change
-.Ic userid_p3p
-and/or a cookie expiration time while preserving the client identifier.
-A mark can be any letter of the English alphabet (case-sensitive), digit, or the
-.Qq =
-character.
-If the mark is set, it is compared with the first padding symbol in the base64
-representation of the client identifier passed in a cookie.
-If they do not match, the cookie is resent with the specified mark, expiration
-time, and P3P header.
-.It Ic userid_name Ar name
-.Bl -tag -width Ds -compact
-.It default: uid
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets the cookie name.
-.It Ic userid_p3p Ar string | Cm none
-.Bl -tag -width Ds -compact
-.It default: Cm none
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Sets a value for the P3P header field that will be sent along with the cookie.
-If the directive is set to the special value
-.Cm none ,
-the P3P header will not be sent in a response.
-.It Ic userid_path Ar path
-.Bl -tag -width Ds -compact
-.It default: /
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines a path for which the cookie is set.
-.It Ic userid_service Ar number
-.Bl -tag -width Ds -compact
-.It default: IP address of the server
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-If identifiers are issued by multiple servers (services), each service should be
-assigned its own
-.Ar number
-to ensure that client identifiers are unique.
-For version 1 cookies, the default value is zero.
-For version 2 cookies, the default value is the number composed from the last
-four octets of the server's IP address.
-.El
-.Ss Module ngx_http_xslt_module
-.Em This module is not enabled on OpenBSD.
-.Bl -tag -width Ds
-.It Ic xml_entities Ar path
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Specifies the DTD file that declares character entities.
-This file is compiled at the configuration stage.
-For technical reasons, the module is unable to use the external subset declared
-in the processed XML, so it is ignored and a specially defined file is used
-instead.
-This file should not describe the XML structure.
-It is enough to declare just the required character entities, for example:
-.Bd -literal -offset indent
-<!ENTITY nbsp "&#xa0;">
-.Ed
-.It Ic xslt_last_modified Cm on | Cm off
-.Bl -tag -width Ds -compact
-.It default: Cm off
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Allows preserving the Last-Modified header field from the original response
-during XSLT transformations to facilitate response caching.
-By default, the header field is removed as contents of the response are modified
-during transformations and may contain dynamically generated elements or parts
-that are changed independently of the original response.
-.It Ic xslt_param Ar parameter Ar value
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines the parameters for XSLT stylesheets.
-The
-.Ar value
-is treated as an XPath expression.
-The
-.Ar value
-can contain variables.
-To pass a string value to a stylesheet, the
-.Ic xslt_string_param
-directive can be used.
-There could be several
-.Ic xslt_param
-directives.
-These directives are inherited from the previous level if and only if there are
-no
-.Ic xslt_param
-and
-.Ic xslt_string_param
-directives defined on the current level.
-.It Ic xslt_string_param Ar parameter Ar value
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Defines the string parameters for XSLT stylesheets.
-XPath expressions in the
-.Ar value
-are not interpreted.
-The
-.Ar value
-can contain variables.
-There could be several
-.Ic xslt_string_param
-directives.
-These directives are inherited from the previous level if and only if there are
-no
-.Ic xslt_param
-and
-.Ic xslt_string_param
-directives defined on the current level.
-.It Ic xslt_stylesheet Ar stylesheet Oo Ar parameter Ns = Ns Ar value No ... Oc
-.Bl -tag -width Ds -compact
-.It default:
-.It context: Ic location
-.El
-.Pp
-Defines the XSLT stylesheet and its optional parameters.
-A stylesheet is compiled at the configuration stage.
-Parameters can either be specified separately, or grouped in a single line using
-the
-.Qo : Qc
-delimiter.
-If a parameter includes the
-.Qo : Qc
-character, it should be escaped as
-.Qq %3A .
-Also,
-libxslt
-requires to enclose parameters that contain non-alphanumeric characters into
-single or double quotes, for example:
-.Bd -literal -offset indent
-param1='http%3A//www.example.com':param2=value2
-.Ed
-.Pp
-The parameters description can contain variables, for example, the whole line of
-parameters can be taken from a single variable:
-.Bd -literal -offset indent
-location / {
- xslt_stylesheet /site/xslt/one.xslt
- $arg_xslt_params
- param1='$value1':param2=value2
- param3=value3;
-}
-.Ed
-.Pp
-It is possible to specify several stylesheets.
-They will be applied sequentially in the specified order.
-.It Ic xslt_types Ar mime-type No ...
-.Bl -tag -width Ds -compact
-.It default: text/xml
-.It context: Ic http , Ic server , Ic location
-.El
-.Pp
-Enables transformations in responses with the specified MIME types in addition
-to text/xml.
-The special value
-.Qq *
-matches any MIME type (0.8.29).
-If the transformation result is an HTML response, its MIME type is changed to
-text/html.
-.El
-.Sh FILES
-.Pa /etc/nginx/nginx.conf
-.Sh EXAMPLES
-The following is a valid configuration file, but such creative use
-of whitespace is not recommended:
-.Bd -literal -offset indent
-worker_processes #whitespace is required here
-auto
-#a comment is allowed here
-;events{}user #whitespace is again required here
-www
-#and here, too
-www;# but not here
-.Ed
-.Sh SEE ALSO
-.Xr nginx 8
-.Sh HISTORY
-This manual has been available since
-.Ox 5.5 .
-.Sh AUTHORS
-.An -nosplit
-The bulk of the text was semi-automatically converted
-from the XML sources of
-.Lk http://nginx.org/en/docs/#development
-to
-.Xr mdoc 7
-by
-.An Florian Obser Aq Mt florian@openbsd.org .
-The description of the grammar was written by
-.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
diff --git a/usr.sbin/nginx/src/core/nginx.c b/usr.sbin/nginx/src/core/nginx.c
deleted file mode 100644
index 5960fa85658..00000000000
--- a/usr.sbin/nginx/src/core/nginx.c
+++ /dev/null
@@ -1,1369 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <nginx.h>
-
-
-static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle);
-static ngx_int_t ngx_get_options(int argc, char *const *argv);
-static ngx_int_t ngx_process_options(ngx_cycle_t *cycle);
-static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv);
-static void *ngx_core_module_create_conf(ngx_cycle_t *cycle);
-static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf);
-static char *ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static char *ngx_set_env(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static char *ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_conf_enum_t ngx_debug_points[] = {
- { ngx_string("stop"), NGX_DEBUG_POINTS_STOP },
- { ngx_string("abort"), NGX_DEBUG_POINTS_ABORT },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_command_t ngx_core_commands[] = {
-
- { ngx_string("daemon"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- 0,
- offsetof(ngx_core_conf_t, daemon),
- NULL },
-
- { ngx_string("master_process"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- 0,
- offsetof(ngx_core_conf_t, master),
- NULL },
-
- { ngx_string("timer_resolution"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- 0,
- offsetof(ngx_core_conf_t, timer_resolution),
- NULL },
-
- { ngx_string("pid"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- 0,
- offsetof(ngx_core_conf_t, pid),
- NULL },
-
- { ngx_string("lock_file"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- 0,
- offsetof(ngx_core_conf_t, lock_file),
- NULL },
-
- { ngx_string("worker_processes"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_set_worker_processes,
- 0,
- 0,
- NULL },
-
- { ngx_string("debug_points"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- 0,
- offsetof(ngx_core_conf_t, debug_points),
- &ngx_debug_points },
-
- { ngx_string("user"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE12,
- ngx_set_user,
- 0,
- 0,
- NULL },
-
- { ngx_string("worker_priority"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_set_priority,
- 0,
- 0,
- NULL },
-
- { ngx_string("worker_cpu_affinity"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_1MORE,
- ngx_set_cpu_affinity,
- 0,
- 0,
- NULL },
-
- { ngx_string("worker_rlimit_nofile"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_core_conf_t, rlimit_nofile),
- NULL },
-
- { ngx_string("worker_rlimit_core"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_off_slot,
- 0,
- offsetof(ngx_core_conf_t, rlimit_core),
- NULL },
-
- { ngx_string("worker_rlimit_sigpending"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_core_conf_t, rlimit_sigpending),
- NULL },
-
- { ngx_string("working_directory"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- 0,
- offsetof(ngx_core_conf_t, working_directory),
- NULL },
-
- { ngx_string("env"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_set_env,
- 0,
- 0,
- NULL },
-
-#if (NGX_THREADS)
-
- { ngx_string("worker_threads"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_core_conf_t, worker_threads),
- NULL },
-
- { ngx_string("thread_stack_size"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- 0,
- offsetof(ngx_core_conf_t, thread_stack_size),
- NULL },
-
-#endif
-
- ngx_null_command
-};
-
-
-static ngx_core_module_t ngx_core_module_ctx = {
- ngx_string("core"),
- ngx_core_module_create_conf,
- ngx_core_module_init_conf
-};
-
-
-ngx_module_t ngx_core_module = {
- NGX_MODULE_V1,
- &ngx_core_module_ctx, /* module context */
- ngx_core_commands, /* module directives */
- NGX_CORE_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-ngx_uint_t ngx_max_module;
-u_char *ngx_prefix;
-
-static ngx_uint_t ngx_show_help;
-static ngx_uint_t ngx_show_version;
-static ngx_uint_t ngx_show_configure;
-static u_char *ngx_conf_file;
-static u_char *ngx_conf_params;
-static char *ngx_signal;
-
-
-static char **ngx_os_environ;
-
-
-int ngx_cdecl
-main(int argc, char *const *argv)
-{
- ngx_int_t i;
- ngx_log_t *log;
- ngx_cycle_t *cycle, init_cycle;
- ngx_core_conf_t *ccf;
-
- ngx_debug_init();
-
- if (ngx_strerror_init() != NGX_OK) {
- return 1;
- }
-
- if (ngx_get_options(argc, argv) != NGX_OK) {
- return 1;
- }
-
- if (ngx_show_version) {
- ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED);
-
- if (ngx_show_help) {
- ngx_write_stderr(
- "Usage: nginx [-?hvVtq] [-s signal] [-c filename] "
- "[-p prefix] [-g directives]" NGX_LINEFEED
- NGX_LINEFEED
- "Options:" NGX_LINEFEED
- " -?,-h : this help" NGX_LINEFEED
- " -v : show version and exit" NGX_LINEFEED
- " -V : show version and configure options then exit"
- NGX_LINEFEED
- " -t : test configuration and exit" NGX_LINEFEED
- " -q : suppress non-error messages "
- "during configuration testing" NGX_LINEFEED
- " -s signal : send signal to a master process: "
- "stop, quit, reopen, reload" NGX_LINEFEED
-#ifdef NGX_PREFIX
- " -p prefix : set prefix path (default: "
- NGX_PREFIX ")" NGX_LINEFEED
-#else
- " -p prefix : set prefix path (default: NONE)" NGX_LINEFEED
-#endif
- " -c filename : set configuration file (default: "
- NGX_CONF_PATH ")" NGX_LINEFEED
- " -g directives : set global directives out of configuration "
- "file" NGX_LINEFEED NGX_LINEFEED
- " -u : disable chroot(2) "
- "file" NGX_LINEFEED NGX_LINEFEED
- );
- }
-
- if (ngx_show_configure) {
- ngx_write_stderr(
-#ifdef NGX_COMPILER
- "built by " NGX_COMPILER NGX_LINEFEED
-#endif
-#if (NGX_SSL)
-#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
- "TLS SNI support enabled" NGX_LINEFEED
-#else
- "TLS SNI support disabled" NGX_LINEFEED
-#endif
-#endif
- "configure arguments:" NGX_CONFIGURE NGX_LINEFEED);
- }
-
- if (!ngx_test_config) {
- return 0;
- }
- }
-
- /* TODO */ ngx_max_sockets = -1;
-
- ngx_time_init();
-
-#if (NGX_PCRE)
- ngx_regex_init();
-#endif
-
- ngx_pid = ngx_getpid();
-
- log = ngx_log_init(ngx_prefix);
- if (log == NULL) {
- return 1;
- }
-
- /* STUB */
-#if (NGX_OPENSSL)
- ngx_ssl_init(log);
-#endif
-
- /*
- * init_cycle->log is required for signal handlers and
- * ngx_process_options()
- */
-
- ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
- init_cycle.log = log;
- ngx_cycle = &init_cycle;
-
- init_cycle.pool = ngx_create_pool(1024, log);
- if (init_cycle.pool == NULL) {
- return 1;
- }
-
- if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
- return 1;
- }
-
- if (ngx_process_options(&init_cycle) != NGX_OK) {
- return 1;
- }
-
- if (ngx_os_init(log) != NGX_OK) {
- return 1;
- }
-
- /*
- * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
- */
-
- if (ngx_crc32_table_init() != NGX_OK) {
- return 1;
- }
-
- if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
- return 1;
- }
-
- ngx_max_module = 0;
- for (i = 0; ngx_modules[i]; i++) {
- ngx_modules[i]->index = ngx_max_module++;
- }
-
- cycle = ngx_init_cycle(&init_cycle);
- if (cycle == NULL) {
- if (ngx_test_config) {
- ngx_log_stderr(0, "configuration file %s test failed",
- init_cycle.conf_file.data);
- }
-
- return 1;
- }
-
- if (ngx_test_config) {
- if (!ngx_quiet_mode) {
- ngx_log_stderr(0, "configuration file %s test is successful",
- cycle->conf_file.data);
- }
-
- return 0;
- }
-
- if (ngx_signal) {
- return ngx_signal_process(cycle, ngx_signal);
- }
-
- ngx_os_status(cycle->log);
-
- ngx_cycle = cycle;
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-
- if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
- ngx_process = NGX_PROCESS_MASTER;
- }
-
-#if !(NGX_WIN32)
-
- if (ngx_init_signals(cycle->log) != NGX_OK) {
- return 1;
- }
-
- if (!ngx_inherited && ccf->daemon) {
- if (ngx_daemon(cycle->log) != NGX_OK) {
- return 1;
- }
-
- ngx_daemonized = 1;
- }
-
- if (ngx_inherited) {
- ngx_daemonized = 1;
- }
-
-#endif
-
- if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
- return 1;
- }
-
- if (ngx_log_redirect_stderr(cycle) != NGX_OK) {
- return 1;
- }
-
- if (log->file->fd != ngx_stderr) {
- if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- ngx_close_file_n " built-in log failed");
- }
- }
-
- ngx_use_stderr = 0;
-
- if (ngx_process == NGX_PROCESS_SINGLE) {
- ngx_single_process_cycle(cycle);
-
- } else {
- ngx_master_process_cycle(cycle);
- }
-
- return 0;
-}
-
-
-static ngx_int_t
-ngx_add_inherited_sockets(ngx_cycle_t *cycle)
-{
- u_char *p, *v, *inherited;
- ngx_int_t s;
- ngx_listening_t *ls;
-
- inherited = (u_char *) getenv(NGINX_VAR);
-
- if (inherited == NULL) {
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
- "using inherited sockets from \"%s\"", inherited);
-
- if (ngx_array_init(&cycle->listening, cycle->pool, 10,
- sizeof(ngx_listening_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- for (p = inherited, v = p; *p; p++) {
- if (*p == ':' || *p == ';') {
- s = ngx_atoi(v, p - v);
- if (s == NGX_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
- "invalid socket number \"%s\" in " NGINX_VAR
- " environment variable, ignoring the rest"
- " of the variable", v);
- break;
- }
-
- v = p + 1;
-
- ls = ngx_array_push(&cycle->listening);
- if (ls == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memzero(ls, sizeof(ngx_listening_t));
-
- ls->fd = (ngx_socket_t) s;
- }
- }
-
- ngx_inherited = 1;
-
- return ngx_set_inherited_sockets(cycle);
-}
-
-
-char **
-ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last)
-{
- char **p, **env;
- ngx_str_t *var;
- ngx_uint_t i, n;
- ngx_core_conf_t *ccf;
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-
- if (last == NULL && ccf->environment) {
- return ccf->environment;
- }
-
- var = ccf->env.elts;
-
- for (i = 0; i < ccf->env.nelts; i++) {
- if (ngx_strcmp(var[i].data, "TZ") == 0
- || ngx_strncmp(var[i].data, "TZ=", 3) == 0)
- {
- goto tz_found;
- }
- }
-
- var = ngx_array_push(&ccf->env);
- if (var == NULL) {
- return NULL;
- }
-
- var->len = 2;
- var->data = (u_char *) "TZ";
-
- var = ccf->env.elts;
-
-tz_found:
-
- n = 0;
-
- for (i = 0; i < ccf->env.nelts; i++) {
-
- if (var[i].data[var[i].len] == '=') {
- n++;
- continue;
- }
-
- for (p = ngx_os_environ; *p; p++) {
-
- if (ngx_strncmp(*p, var[i].data, var[i].len) == 0
- && (*p)[var[i].len] == '=')
- {
- n++;
- break;
- }
- }
- }
-
- if (last) {
- env = ngx_alloc((*last + n + 1) * sizeof(char *), cycle->log);
- *last = n;
-
- } else {
- env = ngx_palloc(cycle->pool, (n + 1) * sizeof(char *));
- }
-
- if (env == NULL) {
- return NULL;
- }
-
- n = 0;
-
- for (i = 0; i < ccf->env.nelts; i++) {
-
- if (var[i].data[var[i].len] == '=') {
- env[n++] = (char *) var[i].data;
- continue;
- }
-
- for (p = ngx_os_environ; *p; p++) {
-
- if (ngx_strncmp(*p, var[i].data, var[i].len) == 0
- && (*p)[var[i].len] == '=')
- {
- env[n++] = *p;
- break;
- }
- }
- }
-
- env[n] = NULL;
-
- if (last == NULL) {
- ccf->environment = env;
- environ = env;
- }
-
- return env;
-}
-
-
-ngx_pid_t
-ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
-{
- char **env, *var;
- u_char *p;
- ngx_uint_t i, n;
- ngx_pid_t pid;
- ngx_exec_ctx_t ctx;
- ngx_core_conf_t *ccf;
- ngx_listening_t *ls;
-
- ngx_memzero(&ctx, sizeof(ngx_exec_ctx_t));
-
- ctx.path = argv[0];
- ctx.name = "new binary process";
- ctx.argv = argv;
-
- n = 2;
- env = ngx_set_environment(cycle, &n);
- if (env == NULL) {
- return NGX_INVALID_PID;
- }
-
- var = ngx_alloc(sizeof(NGINX_VAR)
- + cycle->listening.nelts * (NGX_INT32_LEN + 1) + 2,
- cycle->log);
- if (var == NULL) {
- ngx_free(env);
- return NGX_INVALID_PID;
- }
-
- p = ngx_cpymem(var, NGINX_VAR "=", sizeof(NGINX_VAR));
-
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
- p = ngx_sprintf(p, "%ud;", ls[i].fd);
- }
-
- *p = '\0';
-
- env[n++] = var;
-
-#if (NGX_SETPROCTITLE_USES_ENV)
-
- /* allocate the spare 300 bytes for the new binary process title */
-
- env[n++] = "SPARE=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
-
-#endif
-
- env[n] = NULL;
-
-#if (NGX_DEBUG)
- {
- char **e;
- for (e = env; *e; e++) {
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, "env: %s", *e);
- }
- }
-#endif
-
- ctx.envp = (char *const *) env;
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-
- if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- ngx_rename_file_n " %s to %s failed "
- "before executing new binary process \"%s\"",
- ccf->pid.data, ccf->oldpid.data, argv[0]);
-
- ngx_free(env);
- ngx_free(var);
-
- return NGX_INVALID_PID;
- }
-
- pid = ngx_execute(cycle, &ctx);
-
- if (pid == NGX_INVALID_PID) {
- if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data)
- == NGX_FILE_ERROR)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- ngx_rename_file_n " %s back to %s failed after "
- "an attempt to execute new binary process \"%s\"",
- ccf->oldpid.data, ccf->pid.data, argv[0]);
- }
- }
-
- ngx_free(env);
- ngx_free(var);
-
- return pid;
-}
-
-
-static ngx_int_t
-ngx_get_options(int argc, char *const *argv)
-{
- u_char *p;
- ngx_int_t i;
-
- for (i = 1; i < argc; i++) {
-
- p = (u_char *) argv[i];
-
- if (*p++ != '-') {
- ngx_log_stderr(0, "invalid option: \"%s\"", argv[i]);
- return NGX_ERROR;
- }
-
- while (*p) {
-
- switch (*p++) {
-
- case '?':
- case 'h':
- ngx_show_version = 1;
- ngx_show_help = 1;
- break;
-
- case 'v':
- ngx_show_version = 1;
- break;
-
- case 'V':
- ngx_show_version = 1;
- ngx_show_configure = 1;
- break;
-
- case 't':
- ngx_test_config = 1;
- break;
-
- case 'q':
- ngx_quiet_mode = 1;
- break;
-
- case 'p':
- if (*p) {
- ngx_prefix = p;
- goto next;
- }
-
- if (argv[++i]) {
- ngx_prefix = (u_char *) argv[i];
- goto next;
- }
-
- ngx_log_stderr(0, "option \"-p\" requires directory name");
- return NGX_ERROR;
-
- case 'c':
- if (*p) {
- ngx_conf_file = p;
- goto next;
- }
-
- if (argv[++i]) {
- ngx_conf_file = (u_char *) argv[i];
- goto next;
- }
-
- ngx_log_stderr(0, "option \"-c\" requires file name");
- return NGX_ERROR;
-
- case 'g':
- if (*p) {
- ngx_conf_params = p;
- goto next;
- }
-
- if (argv[++i]) {
- ngx_conf_params = (u_char *) argv[i];
- goto next;
- }
-
- ngx_log_stderr(0, "option \"-g\" requires parameter");
- return NGX_ERROR;
-
- case 's':
- if (*p) {
- ngx_signal = (char *) p;
-
- } else if (argv[++i]) {
- ngx_signal = argv[i];
-
- } else {
- ngx_log_stderr(0, "option \"-s\" requires parameter");
- return NGX_ERROR;
- }
-
- if (ngx_strcmp(ngx_signal, "stop") == 0
- || ngx_strcmp(ngx_signal, "quit") == 0
- || ngx_strcmp(ngx_signal, "reopen") == 0
- || ngx_strcmp(ngx_signal, "reload") == 0)
- {
- ngx_process = NGX_PROCESS_SIGNALLER;
- goto next;
- }
-
- ngx_log_stderr(0, "invalid option: \"-s %s\"", ngx_signal);
- return NGX_ERROR;
-
- case 'u':
- ngx_chrooted = 0;
- break;
-
- default:
- ngx_log_stderr(0, "invalid option: \"%c\"", *(p - 1));
- return NGX_ERROR;
- }
- }
-
- next:
-
- continue;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv)
-{
-#if (NGX_FREEBSD)
-
- ngx_os_argv = (char **) argv;
- ngx_argc = argc;
- ngx_argv = (char **) argv;
-
-#else
- size_t len;
- ngx_int_t i;
-
- ngx_os_argv = (char **) argv;
- ngx_argc = argc;
-
- ngx_argv = ngx_alloc((argc + 1) * sizeof(char *), cycle->log);
- if (ngx_argv == NULL) {
- return NGX_ERROR;
- }
-
- for (i = 0; i < argc; i++) {
- len = ngx_strlen(argv[i]) + 1;
-
- ngx_argv[i] = ngx_alloc(len, cycle->log);
- if (ngx_argv[i] == NULL) {
- return NGX_ERROR;
- }
-
- (void) ngx_cpystrn((u_char *) ngx_argv[i], (u_char *) argv[i], len);
- }
-
- ngx_argv[i] = NULL;
-
-#endif
-
- ngx_os_environ = environ;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_process_options(ngx_cycle_t *cycle)
-{
- u_char *p;
- size_t len;
-
- if (ngx_prefix) {
- len = ngx_strlen(ngx_prefix);
- p = ngx_prefix;
-
- if (len && !ngx_path_separator(p[len - 1])) {
- p = ngx_pnalloc(cycle->pool, len + 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(p, ngx_prefix, len);
- p[len++] = '/';
- }
-
- cycle->conf_prefix.len = len;
- cycle->conf_prefix.data = p;
- cycle->prefix.len = len;
- cycle->prefix.data = p;
-
- } else {
-
-#ifndef NGX_PREFIX
-
- p = ngx_pnalloc(cycle->pool, NGX_MAX_PATH);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_getcwd(p, NGX_MAX_PATH) == 0) {
- ngx_log_stderr(ngx_errno, "[emerg]: " ngx_getcwd_n " failed");
- return NGX_ERROR;
- }
-
- len = ngx_strlen(p);
-
- p[len++] = '/';
-
- cycle->conf_prefix.len = len;
- cycle->conf_prefix.data = p;
- cycle->prefix.len = len;
- cycle->prefix.data = p;
-
-#else
-
-#ifdef NGX_CONF_PREFIX
- ngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX);
-#else
- ngx_str_set(&cycle->conf_prefix, NGX_PREFIX);
-#endif
- ngx_str_set(&cycle->prefix, NGX_PREFIX);
-
-#endif
- }
-
- if (ngx_conf_file) {
- cycle->conf_file.len = ngx_strlen(ngx_conf_file);
- cycle->conf_file.data = ngx_conf_file;
-
- } else {
- ngx_str_set(&cycle->conf_file, NGX_CONF_PATH);
- }
-
- if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- for (p = cycle->conf_file.data + cycle->conf_file.len - 1;
- p > cycle->conf_file.data;
- p--)
- {
- if (ngx_path_separator(*p)) {
- cycle->conf_prefix.len = p - ngx_cycle->conf_file.data + 1;
- cycle->conf_prefix.data = ngx_cycle->conf_file.data;
- break;
- }
- }
-
- if (ngx_conf_params) {
- cycle->conf_param.len = ngx_strlen(ngx_conf_params);
- cycle->conf_param.data = ngx_conf_params;
- }
-
- if (ngx_test_config) {
- cycle->log->log_level = NGX_LOG_INFO;
- }
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_core_module_create_conf(ngx_cycle_t *cycle)
-{
- ngx_core_conf_t *ccf;
-
- ccf = ngx_pcalloc(cycle->pool, sizeof(ngx_core_conf_t));
- if (ccf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc()
- *
- * ccf->pid = NULL;
- * ccf->oldpid = NULL;
- * ccf->priority = 0;
- * ccf->cpu_affinity_n = 0;
- * ccf->cpu_affinity = NULL;
- */
-
- ccf->daemon = NGX_CONF_UNSET;
- ccf->master = NGX_CONF_UNSET;
- ccf->timer_resolution = NGX_CONF_UNSET_MSEC;
-
- ccf->worker_processes = NGX_CONF_UNSET;
- ccf->debug_points = NGX_CONF_UNSET;
-
- ccf->rlimit_nofile = NGX_CONF_UNSET;
- ccf->rlimit_core = NGX_CONF_UNSET;
- ccf->rlimit_sigpending = NGX_CONF_UNSET;
-
- ccf->user = (ngx_uid_t) NGX_CONF_UNSET_UINT;
- ccf->group = (ngx_gid_t) NGX_CONF_UNSET_UINT;
-
-#if (NGX_THREADS)
- ccf->worker_threads = NGX_CONF_UNSET;
- ccf->thread_stack_size = NGX_CONF_UNSET_SIZE;
-#endif
-
- if (ngx_array_init(&ccf->env, cycle->pool, 1, sizeof(ngx_str_t))
- != NGX_OK)
- {
- return NULL;
- }
-
- return ccf;
-}
-
-
-static char *
-ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
-{
- ngx_core_conf_t *ccf = conf;
-
- ngx_conf_init_value(ccf->daemon, 1);
- ngx_conf_init_value(ccf->master, 1);
- ngx_conf_init_msec_value(ccf->timer_resolution, 0);
-
- ngx_conf_init_value(ccf->worker_processes, 1);
- ngx_conf_init_value(ccf->debug_points, 0);
-
-#if (NGX_HAVE_CPU_AFFINITY)
-
- if (ccf->cpu_affinity_n
- && ccf->cpu_affinity_n != 1
- && ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes)
- {
- ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
- "the number of \"worker_processes\" is not equal to "
- "the number of \"worker_cpu_affinity\" masks, "
- "using last mask for remaining worker processes");
- }
-
-#endif
-
-#if (NGX_THREADS)
-
- ngx_conf_init_value(ccf->worker_threads, 0);
- ngx_threads_n = ccf->worker_threads;
- ngx_conf_init_size_value(ccf->thread_stack_size, 2 * 1024 * 1024);
-
-#endif
-
-
- if (ccf->pid.len == 0) {
- ngx_str_set(&ccf->pid, NGX_PID_PATH);
- }
-
- if (ngx_conf_full_name(cycle, &ccf->pid, 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- ccf->oldpid.len = ccf->pid.len + sizeof(NGX_OLDPID_EXT);
-
- ccf->oldpid.data = ngx_pnalloc(cycle->pool, ccf->oldpid.len);
- if (ccf->oldpid.data == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memcpy(ngx_cpymem(ccf->oldpid.data, ccf->pid.data, ccf->pid.len),
- NGX_OLDPID_EXT, sizeof(NGX_OLDPID_EXT));
-
-
-#if !(NGX_WIN32)
-
- if (ccf->user == (uid_t) NGX_CONF_UNSET_UINT && geteuid() == 0) {
- struct group *grp;
- struct passwd *pwd;
-
- ngx_set_errno(0);
- pwd = getpwnam(NGX_USER);
- if (pwd == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "getpwnam(\"" NGX_USER "\") failed");
- return NGX_CONF_ERROR;
- }
-
- 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,
- "getgrnam(\"" NGX_GROUP "\") failed");
- return NGX_CONF_ERROR;
- }
-
- ccf->group = grp->gr_gid;
- }
-
-
- if (ccf->lock_file.len == 0) {
- ngx_str_set(&ccf->lock_file, NGX_LOCK_PATH);
- }
-
- if (ngx_conf_full_name(cycle, &ccf->lock_file, 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- {
- ngx_str_t lock_file;
-
- lock_file = cycle->old_cycle->lock_file;
-
- if (lock_file.len) {
- lock_file.len--;
-
- if (ccf->lock_file.len != lock_file.len
- || ngx_strncmp(ccf->lock_file.data, lock_file.data, lock_file.len)
- != 0)
- {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
- "\"lock_file\" could not be changed, ignored");
- }
-
- cycle->lock_file.len = lock_file.len + 1;
- lock_file.len += sizeof(".accept");
-
- cycle->lock_file.data = ngx_pstrdup(cycle->pool, &lock_file);
- if (cycle->lock_file.data == NULL) {
- return NGX_CONF_ERROR;
- }
-
- } else {
- cycle->lock_file.len = ccf->lock_file.len + 1;
- cycle->lock_file.data = ngx_pnalloc(cycle->pool,
- ccf->lock_file.len + sizeof(".accept"));
- if (cycle->lock_file.data == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memcpy(ngx_cpymem(cycle->lock_file.data, ccf->lock_file.data,
- ccf->lock_file.len),
- ".accept", sizeof(".accept"));
- }
- }
-
-#endif
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_set_user(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
-#if (NGX_WIN32)
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "\"user\" is not supported, ignored");
-
- return NGX_CONF_OK;
-
-#else
-
- ngx_core_conf_t *ccf = conf;
-
- char *group;
- struct passwd *pwd;
- struct group *grp;
- ngx_str_t *value;
-
- if (ccf->user != (uid_t) NGX_CONF_UNSET_UINT) {
- return "is duplicate";
- }
-
- if (geteuid() != 0) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "the \"user\" directive makes sense only "
- "if the master process runs "
- "with super-user privileges, ignored");
- return NGX_CONF_OK;
- }
-
- value = (ngx_str_t *) cf->args->elts;
-
- 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,
- "getpwnam(\"%s\") failed", value[1].data);
- return NGX_CONF_ERROR;
- }
-
- ccf->user = pwd->pw_uid;
-
- 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,
- "getgrnam(\"%s\") failed", group);
- return NGX_CONF_ERROR;
- }
-
- ccf->group = grp->gr_gid;
-
- return NGX_CONF_OK;
-
-#endif
-}
-
-
-static char *
-ngx_set_env(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_core_conf_t *ccf = conf;
-
- ngx_str_t *value, *var;
- ngx_uint_t i;
-
- var = ngx_array_push(&ccf->env);
- if (var == NULL) {
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
- *var = value[1];
-
- for (i = 0; i < value[1].len; i++) {
-
- if (value[1].data[i] == '=') {
-
- var->len = i;
-
- return NGX_CONF_OK;
- }
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_core_conf_t *ccf = conf;
-
- ngx_str_t *value;
- ngx_uint_t n, minus;
-
- if (ccf->priority != 0) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- if (value[1].data[0] == '-') {
- n = 1;
- minus = 1;
-
- } else if (value[1].data[0] == '+') {
- n = 1;
- minus = 0;
-
- } else {
- n = 0;
- minus = 0;
- }
-
- ccf->priority = ngx_atoi(&value[1].data[n], value[1].len - n);
- if (ccf->priority == NGX_ERROR) {
- return "invalid number";
- }
-
- if (minus) {
- ccf->priority = -ccf->priority;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
-#if (NGX_HAVE_CPU_AFFINITY)
- ngx_core_conf_t *ccf = conf;
-
- u_char ch;
- uint64_t *mask;
- ngx_str_t *value;
- ngx_uint_t i, n;
-
- if (ccf->cpu_affinity) {
- return "is duplicate";
- }
-
- mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(uint64_t));
- if (mask == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ccf->cpu_affinity_n = cf->args->nelts - 1;
- ccf->cpu_affinity = mask;
-
- value = cf->args->elts;
-
- for (n = 1; n < cf->args->nelts; n++) {
-
- if (value[n].len > 64) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"worker_cpu_affinity\" supports up to 64 CPUs only");
- return NGX_CONF_ERROR;
- }
-
- mask[n - 1] = 0;
-
- for (i = 0; i < value[n].len; i++) {
-
- ch = value[n].data[i];
-
- if (ch == ' ') {
- continue;
- }
-
- mask[n - 1] <<= 1;
-
- if (ch == '0') {
- continue;
- }
-
- if (ch == '1') {
- mask[n - 1] |= 1;
- continue;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid character \"%c\" in \"worker_cpu_affinity\"",
- ch);
- return NGX_CONF_ERROR;
- }
- }
-
-#else
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "\"worker_cpu_affinity\" is not supported "
- "on this platform, ignored");
-#endif
-
- return NGX_CONF_OK;
-}
-
-
-uint64_t
-ngx_get_cpu_affinity(ngx_uint_t n)
-{
- ngx_core_conf_t *ccf;
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
- ngx_core_module);
-
- if (ccf->cpu_affinity == NULL) {
- return 0;
- }
-
- if (ccf->cpu_affinity_n > n) {
- return ccf->cpu_affinity[n];
- }
-
- return ccf->cpu_affinity[ccf->cpu_affinity_n - 1];
-}
-
-
-static char *
-ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_str_t *value;
- ngx_core_conf_t *ccf;
-
- ccf = (ngx_core_conf_t *) conf;
-
- if (ccf->worker_processes != NGX_CONF_UNSET) {
- return "is duplicate";
- }
-
- value = (ngx_str_t *) cf->args->elts;
-
- if (ngx_strcmp(value[1].data, "auto") == 0) {
- ccf->worker_processes = ngx_ncpu;
- return NGX_CONF_OK;
- }
-
- ccf->worker_processes = ngx_atoi(value[1].data, value[1].len);
-
- if (ccf->worker_processes == NGX_ERROR) {
- return "invalid value";
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/core/nginx.h b/usr.sbin/nginx/src/core/nginx.h
deleted file mode 100644
index 0ef0f2e110f..00000000000
--- a/usr.sbin/nginx/src/core/nginx.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGINX_H_INCLUDED_
-#define _NGINX_H_INCLUDED_
-
-
-#define nginx_version 1006000
-#define NGINX_VERSION "1.6.0"
-#define NGINX_VER "nginx/" NGINX_VERSION
-
-#define NGINX_VAR "NGINX"
-#define NGX_OLDPID_EXT ".oldbin"
-
-
-#endif /* _NGINX_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_array.c b/usr.sbin/nginx/src/core/ngx_array.c
deleted file mode 100644
index 4ea226f0682..00000000000
--- a/usr.sbin/nginx/src/core/ngx_array.c
+++ /dev/null
@@ -1,141 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-ngx_array_t *
-ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)
-{
- ngx_array_t *a;
-
- a = ngx_palloc(p, sizeof(ngx_array_t));
- if (a == NULL) {
- return NULL;
- }
-
- if (ngx_array_init(a, p, n, size) != NGX_OK) {
- return NULL;
- }
-
- return a;
-}
-
-
-void
-ngx_array_destroy(ngx_array_t *a)
-{
- ngx_pool_t *p;
-
- p = a->pool;
-
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
- p->d.last -= a->size * a->nalloc;
- }
-
- if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
- p->d.last = (u_char *) a;
- }
-}
-
-
-void *
-ngx_array_push(ngx_array_t *a)
-{
- void *elt, *new;
- size_t size;
- ngx_pool_t *p;
-
- if (a->nelts == a->nalloc) {
-
- /* the array is full */
-
- size = a->size * a->nalloc;
-
- p = a->pool;
-
- if ((u_char *) a->elts + size == p->d.last
- && p->d.last + a->size <= p->d.end)
- {
- /*
- * the array allocation is the last in the pool
- * and there is space for new allocation
- */
-
- p->d.last += a->size;
- a->nalloc++;
-
- } else {
- /* allocate a new array */
-
- new = ngx_palloc(p, 2 * size);
- if (new == NULL) {
- return NULL;
- }
-
- ngx_memcpy(new, a->elts, size);
- a->elts = new;
- a->nalloc *= 2;
- }
- }
-
- elt = (u_char *) a->elts + a->size * a->nelts;
- a->nelts++;
-
- return elt;
-}
-
-
-void *
-ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
-{
- void *elt, *new;
- size_t size;
- ngx_uint_t nalloc;
- ngx_pool_t *p;
-
- size = n * a->size;
-
- if (a->nelts + n > a->nalloc) {
-
- /* the array is full */
-
- p = a->pool;
-
- if ((u_char *) a->elts + a->size * a->nalloc == p->d.last
- && p->d.last + size <= p->d.end)
- {
- /*
- * the array allocation is the last in the pool
- * and there is space for new allocation
- */
-
- p->d.last += size;
- a->nalloc += n;
-
- } else {
- /* allocate a new array */
-
- nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
-
- new = ngx_palloc(p, nalloc * a->size);
- if (new == NULL) {
- return NULL;
- }
-
- ngx_memcpy(new, a->elts, a->nelts * a->size);
- a->elts = new;
- a->nalloc = nalloc;
- }
- }
-
- elt = (u_char *) a->elts + a->size * a->nelts;
- a->nelts += n;
-
- return elt;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_array.h b/usr.sbin/nginx/src/core/ngx_array.h
deleted file mode 100644
index a0f2a744021..00000000000
--- a/usr.sbin/nginx/src/core/ngx_array.h
+++ /dev/null
@@ -1,53 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_ARRAY_H_INCLUDED_
-#define _NGX_ARRAY_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef struct {
- void *elts;
- ngx_uint_t nelts;
- size_t size;
- ngx_uint_t nalloc;
- ngx_pool_t *pool;
-} ngx_array_t;
-
-
-ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);
-void ngx_array_destroy(ngx_array_t *a);
-void *ngx_array_push(ngx_array_t *a);
-void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);
-
-
-static ngx_inline ngx_int_t
-ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size)
-{
- /*
- * set "array->nelts" before "array->elts", otherwise MSVC thinks
- * that "array->nelts" may be used without having been initialized
- */
-
- array->nelts = 0;
- array->size = size;
- array->nalloc = n;
- array->pool = pool;
-
- array->elts = ngx_palloc(pool, n * size);
- if (array->elts == NULL) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-#endif /* _NGX_ARRAY_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_buf.c b/usr.sbin/nginx/src/core/ngx_buf.c
deleted file mode 100644
index 835c76ced6b..00000000000
--- a/usr.sbin/nginx/src/core/ngx_buf.c
+++ /dev/null
@@ -1,220 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-ngx_buf_t *
-ngx_create_temp_buf(ngx_pool_t *pool, size_t size)
-{
- ngx_buf_t *b;
-
- b = ngx_calloc_buf(pool);
- if (b == NULL) {
- return NULL;
- }
-
- b->start = ngx_palloc(pool, size);
- if (b->start == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_calloc_buf():
- *
- * b->file_pos = 0;
- * b->file_last = 0;
- * b->file = NULL;
- * b->shadow = NULL;
- * b->tag = 0;
- * and flags
- */
-
- b->pos = b->start;
- b->last = b->start;
- b->end = b->last + size;
- b->temporary = 1;
-
- return b;
-}
-
-
-ngx_chain_t *
-ngx_alloc_chain_link(ngx_pool_t *pool)
-{
- ngx_chain_t *cl;
-
- cl = pool->chain;
-
- if (cl) {
- pool->chain = cl->next;
- return cl;
- }
-
- cl = ngx_palloc(pool, sizeof(ngx_chain_t));
- if (cl == NULL) {
- return NULL;
- }
-
- return cl;
-}
-
-
-ngx_chain_t *
-ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs)
-{
- u_char *p;
- ngx_int_t i;
- ngx_buf_t *b;
- ngx_chain_t *chain, *cl, **ll;
-
- p = ngx_palloc(pool, bufs->num * bufs->size);
- if (p == NULL) {
- return NULL;
- }
-
- ll = &chain;
-
- for (i = 0; i < bufs->num; i++) {
-
- b = ngx_calloc_buf(pool);
- if (b == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_calloc_buf():
- *
- * b->file_pos = 0;
- * b->file_last = 0;
- * b->file = NULL;
- * b->shadow = NULL;
- * b->tag = 0;
- * and flags
- *
- */
-
- b->pos = p;
- b->last = p;
- b->temporary = 1;
-
- b->start = p;
- p += bufs->size;
- b->end = p;
-
- cl = ngx_alloc_chain_link(pool);
- if (cl == NULL) {
- return NULL;
- }
-
- cl->buf = b;
- *ll = cl;
- ll = &cl->next;
- }
-
- *ll = NULL;
-
- return chain;
-}
-
-
-ngx_int_t
-ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain, ngx_chain_t *in)
-{
- ngx_chain_t *cl, **ll;
-
- ll = chain;
-
- for (cl = *chain; cl; cl = cl->next) {
- ll = &cl->next;
- }
-
- while (in) {
- cl = ngx_alloc_chain_link(pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = in->buf;
- *ll = cl;
- ll = &cl->next;
- in = in->next;
- }
-
- *ll = NULL;
-
- return NGX_OK;
-}
-
-
-ngx_chain_t *
-ngx_chain_get_free_buf(ngx_pool_t *p, ngx_chain_t **free)
-{
- ngx_chain_t *cl;
-
- if (*free) {
- cl = *free;
- *free = cl->next;
- cl->next = NULL;
- return cl;
- }
-
- cl = ngx_alloc_chain_link(p);
- if (cl == NULL) {
- return NULL;
- }
-
- cl->buf = ngx_calloc_buf(p);
- if (cl->buf == NULL) {
- return NULL;
- }
-
- cl->next = NULL;
-
- return cl;
-}
-
-
-void
-ngx_chain_update_chains(ngx_pool_t *p, ngx_chain_t **free, ngx_chain_t **busy,
- ngx_chain_t **out, ngx_buf_tag_t tag)
-{
- ngx_chain_t *cl;
-
- if (*busy == NULL) {
- *busy = *out;
-
- } else {
- for (cl = *busy; cl->next; cl = cl->next) { /* void */ }
-
- cl->next = *out;
- }
-
- *out = NULL;
-
- while (*busy) {
- cl = *busy;
-
- if (ngx_buf_size(cl->buf) != 0) {
- break;
- }
-
- if (cl->buf->tag != tag) {
- *busy = cl->next;
- ngx_free_chain(p, cl);
- continue;
- }
-
- cl->buf->pos = cl->buf->start;
- cl->buf->last = cl->buf->start;
-
- *busy = cl->next;
- cl->next = *free;
- *free = cl;
- }
-}
diff --git a/usr.sbin/nginx/src/core/ngx_buf.h b/usr.sbin/nginx/src/core/ngx_buf.h
deleted file mode 100644
index ffc53109433..00000000000
--- a/usr.sbin/nginx/src/core/ngx_buf.h
+++ /dev/null
@@ -1,162 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_BUF_H_INCLUDED_
-#define _NGX_BUF_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef void * ngx_buf_tag_t;
-
-typedef struct ngx_buf_s ngx_buf_t;
-
-struct ngx_buf_s {
- u_char *pos;
- u_char *last;
- off_t file_pos;
- off_t file_last;
-
- u_char *start; /* start of buffer */
- u_char *end; /* end of buffer */
- ngx_buf_tag_t tag;
- ngx_file_t *file;
- ngx_buf_t *shadow;
-
-
- /* the buf's content could be changed */
- unsigned temporary:1;
-
- /*
- * the buf's content is in a memory cache or in a read only memory
- * and must not be changed
- */
- unsigned memory:1;
-
- /* the buf's content is mmap()ed and must not be changed */
- unsigned mmap:1;
-
- unsigned recycled:1;
- unsigned in_file:1;
- unsigned flush:1;
- unsigned sync:1;
- unsigned last_buf:1;
- unsigned last_in_chain:1;
-
- unsigned last_shadow:1;
- unsigned temp_file:1;
-
- /* STUB */ int num;
-};
-
-
-struct ngx_chain_s {
- ngx_buf_t *buf;
- ngx_chain_t *next;
-};
-
-
-typedef struct {
- ngx_int_t num;
- size_t size;
-} ngx_bufs_t;
-
-
-typedef struct ngx_output_chain_ctx_s ngx_output_chain_ctx_t;
-
-typedef ngx_int_t (*ngx_output_chain_filter_pt)(void *ctx, ngx_chain_t *in);
-
-#if (NGX_HAVE_FILE_AIO)
-typedef void (*ngx_output_chain_aio_pt)(ngx_output_chain_ctx_t *ctx,
- ngx_file_t *file);
-#endif
-
-struct ngx_output_chain_ctx_s {
- ngx_buf_t *buf;
- ngx_chain_t *in;
- ngx_chain_t *free;
- ngx_chain_t *busy;
-
- unsigned sendfile:1;
- unsigned directio:1;
-#if (NGX_HAVE_ALIGNED_DIRECTIO)
- unsigned unaligned:1;
-#endif
- unsigned need_in_memory:1;
- unsigned need_in_temp:1;
-#if (NGX_HAVE_FILE_AIO)
- unsigned aio:1;
-
- ngx_output_chain_aio_pt aio_handler;
-#endif
-
- off_t alignment;
-
- ngx_pool_t *pool;
- ngx_int_t allocated;
- ngx_bufs_t bufs;
- ngx_buf_tag_t tag;
-
- ngx_output_chain_filter_pt output_filter;
- void *filter_ctx;
-};
-
-
-typedef struct {
- ngx_chain_t *out;
- ngx_chain_t **last;
- ngx_connection_t *connection;
- ngx_pool_t *pool;
- off_t limit;
-} ngx_chain_writer_ctx_t;
-
-
-#define NGX_CHAIN_ERROR (ngx_chain_t *) NGX_ERROR
-
-
-#define ngx_buf_in_memory(b) (b->temporary || b->memory || b->mmap)
-#define ngx_buf_in_memory_only(b) (ngx_buf_in_memory(b) && !b->in_file)
-
-#define ngx_buf_special(b) \
- ((b->flush || b->last_buf || b->sync) \
- && !ngx_buf_in_memory(b) && !b->in_file)
-
-#define ngx_buf_sync_only(b) \
- (b->sync \
- && !ngx_buf_in_memory(b) && !b->in_file && !b->flush && !b->last_buf)
-
-#define ngx_buf_size(b) \
- (ngx_buf_in_memory(b) ? (off_t) (b->last - b->pos): \
- (b->file_last - b->file_pos))
-
-ngx_buf_t *ngx_create_temp_buf(ngx_pool_t *pool, size_t size);
-ngx_chain_t *ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs);
-
-
-#define ngx_alloc_buf(pool) ngx_palloc(pool, sizeof(ngx_buf_t))
-#define ngx_calloc_buf(pool) ngx_pcalloc(pool, sizeof(ngx_buf_t))
-
-ngx_chain_t *ngx_alloc_chain_link(ngx_pool_t *pool);
-#define ngx_free_chain(pool, cl) \
- cl->next = pool->chain; \
- pool->chain = cl
-
-
-
-ngx_int_t ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in);
-ngx_int_t ngx_chain_writer(void *ctx, ngx_chain_t *in);
-
-ngx_int_t ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain,
- ngx_chain_t *in);
-ngx_chain_t *ngx_chain_get_free_buf(ngx_pool_t *p, ngx_chain_t **free);
-void ngx_chain_update_chains(ngx_pool_t *p, ngx_chain_t **free,
- ngx_chain_t **busy, ngx_chain_t **out, ngx_buf_tag_t tag);
-
-
-#endif /* _NGX_BUF_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_conf_file.c b/usr.sbin/nginx/src/core/ngx_conf_file.c
deleted file mode 100644
index f61bfcabf99..00000000000
--- a/usr.sbin/nginx/src/core/ngx_conf_file.c
+++ /dev/null
@@ -1,1400 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-#define NGX_CONF_BUFFER 4096
-
-static ngx_int_t ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last);
-static ngx_int_t ngx_conf_read_token(ngx_conf_t *cf);
-static void ngx_conf_flush_files(ngx_cycle_t *cycle);
-
-
-static ngx_command_t ngx_conf_commands[] = {
-
- { ngx_string("include"),
- NGX_ANY_CONF|NGX_CONF_TAKE1,
- ngx_conf_include,
- 0,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-ngx_module_t ngx_conf_module = {
- NGX_MODULE_V1,
- NULL, /* module context */
- ngx_conf_commands, /* module directives */
- NGX_CONF_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- ngx_conf_flush_files, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-/* The eight fixed arguments */
-
-static ngx_uint_t argument_number[] = {
- NGX_CONF_NOARGS,
- NGX_CONF_TAKE1,
- NGX_CONF_TAKE2,
- NGX_CONF_TAKE3,
- NGX_CONF_TAKE4,
- NGX_CONF_TAKE5,
- NGX_CONF_TAKE6,
- NGX_CONF_TAKE7
-};
-
-
-char *
-ngx_conf_param(ngx_conf_t *cf)
-{
- char *rv;
- ngx_str_t *param;
- ngx_buf_t b;
- ngx_conf_file_t conf_file;
-
- param = &cf->cycle->conf_param;
-
- if (param->len == 0) {
- return NGX_CONF_OK;
- }
-
- ngx_memzero(&conf_file, sizeof(ngx_conf_file_t));
-
- ngx_memzero(&b, sizeof(ngx_buf_t));
-
- b.start = param->data;
- b.pos = param->data;
- b.last = param->data + param->len;
- b.end = b.last;
- b.temporary = 1;
-
- conf_file.file.fd = NGX_INVALID_FILE;
- conf_file.file.name.data = NULL;
- conf_file.line = 0;
-
- cf->conf_file = &conf_file;
- cf->conf_file->buffer = &b;
-
- rv = ngx_conf_parse(cf, NULL);
-
- cf->conf_file = NULL;
-
- return rv;
-}
-
-
-char *
-ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
-{
- char *rv;
- ngx_fd_t fd;
- ngx_int_t rc;
- ngx_buf_t buf;
- ngx_conf_file_t *prev, conf_file;
- enum {
- parse_file = 0,
- parse_block,
- parse_param
- } type;
-
-#if (NGX_SUPPRESS_WARN)
- fd = NGX_INVALID_FILE;
- prev = NULL;
-#endif
-
- if (filename) {
-
- /* open configuration file */
-
- fd = ngx_open_file(filename->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
- if (fd == NGX_INVALID_FILE) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
- ngx_open_file_n " \"%s\" failed",
- filename->data);
- return NGX_CONF_ERROR;
- }
-
- prev = cf->conf_file;
-
- cf->conf_file = &conf_file;
-
- if (ngx_fd_info(fd, &cf->conf_file->file.info) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno,
- ngx_fd_info_n " \"%s\" failed", filename->data);
- }
-
- cf->conf_file->buffer = &buf;
-
- buf.start = ngx_alloc(NGX_CONF_BUFFER, cf->log);
- if (buf.start == NULL) {
- goto failed;
- }
-
- buf.pos = buf.start;
- buf.last = buf.start;
- buf.end = buf.last + NGX_CONF_BUFFER;
- buf.temporary = 1;
-
- cf->conf_file->file.fd = fd;
- 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->line = 1;
-
- type = parse_file;
-
- } else if (cf->conf_file->file.fd != NGX_INVALID_FILE) {
-
- type = parse_block;
-
- } else {
- type = parse_param;
- }
-
-
- for ( ;; ) {
- rc = ngx_conf_read_token(cf);
-
- /*
- * ngx_conf_read_token() may return
- *
- * NGX_ERROR there is error
- * NGX_OK the token terminated by ";" was found
- * NGX_CONF_BLOCK_START the token terminated by "{" was found
- * NGX_CONF_BLOCK_DONE the "}" was found
- * NGX_CONF_FILE_DONE the configuration file is done
- */
-
- if (rc == NGX_ERROR) {
- goto done;
- }
-
- if (rc == NGX_CONF_BLOCK_DONE) {
-
- if (type != parse_block) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unexpected \"}\"");
- goto failed;
- }
-
- goto done;
- }
-
- if (rc == NGX_CONF_FILE_DONE) {
-
- if (type == parse_block) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unexpected end of file, expecting \"}\"");
- goto failed;
- }
-
- goto done;
- }
-
- if (rc == NGX_CONF_BLOCK_START) {
-
- if (type == parse_param) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "block directives are not supported "
- "in -g option");
- goto failed;
- }
- }
-
- /* rc == NGX_OK || rc == NGX_CONF_BLOCK_START */
-
- if (cf->handler) {
-
- /*
- * the custom handler, i.e., that is used in the http's
- * "types { ... }" directive
- */
-
- if (rc == NGX_CONF_BLOCK_START) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unexpected \"{\"");
- goto failed;
- }
-
- rv = (*cf->handler)(cf, NULL, cf->handler_conf);
- if (rv == NGX_CONF_OK) {
- continue;
- }
-
- if (rv == NGX_CONF_ERROR) {
- goto failed;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, rv);
-
- goto failed;
- }
-
-
- rc = ngx_conf_handler(cf, rc);
-
- if (rc == NGX_ERROR) {
- goto failed;
- }
- }
-
-failed:
-
- rc = NGX_ERROR;
-
-done:
-
- if (filename) {
- if (cf->conf_file->buffer->start) {
- ngx_free(cf->conf_file->buffer->start);
- }
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
- ngx_close_file_n " %s failed",
- filename->data);
- return NGX_CONF_ERROR;
- }
-
- cf->conf_file = prev;
- }
-
- if (rc == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
-{
- char *rv;
- void *conf, **confp;
- ngx_uint_t i, found;
- ngx_str_t *name;
- ngx_command_t *cmd;
-
- name = cf->args->elts;
-
- found = 0;
-
- for (i = 0; ngx_modules[i]; i++) {
-
- cmd = ngx_modules[i]->commands;
- if (cmd == NULL) {
- continue;
- }
-
- for ( /* void */ ; cmd->name.len; cmd++) {
-
- if (name->len != cmd->name.len) {
- continue;
- }
-
- if (ngx_strcmp(name->data, cmd->name.data) != 0) {
- continue;
- }
-
- found = 1;
-
- if (ngx_modules[i]->type != NGX_CONF_MODULE
- && ngx_modules[i]->type != cf->module_type)
- {
- continue;
- }
-
- /* is the directive's location right ? */
-
- if (!(cmd->type & cf->cmd_type)) {
- continue;
- }
-
- if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "directive \"%s\" is not terminated by \";\"",
- name->data);
- return NGX_ERROR;
- }
-
- if ((cmd->type & NGX_CONF_BLOCK) && last != NGX_CONF_BLOCK_START) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "directive \"%s\" has no opening \"{\"",
- name->data);
- return NGX_ERROR;
- }
-
- /* is the directive's argument count right ? */
-
- if (!(cmd->type & NGX_CONF_ANY)) {
-
- if (cmd->type & NGX_CONF_FLAG) {
-
- if (cf->args->nelts != 2) {
- goto invalid;
- }
-
- } else if (cmd->type & NGX_CONF_1MORE) {
-
- if (cf->args->nelts < 2) {
- goto invalid;
- }
-
- } else if (cmd->type & NGX_CONF_2MORE) {
-
- if (cf->args->nelts < 3) {
- goto invalid;
- }
-
- } else if (cf->args->nelts > NGX_CONF_MAX_ARGS) {
-
- goto invalid;
-
- } else if (!(cmd->type & argument_number[cf->args->nelts - 1]))
- {
- goto invalid;
- }
- }
-
- /* set up the directive's configuration context */
-
- conf = NULL;
-
- if (cmd->type & NGX_DIRECT_CONF) {
- conf = ((void **) cf->ctx)[ngx_modules[i]->index];
-
- } else if (cmd->type & NGX_MAIN_CONF) {
- conf = &(((void **) cf->ctx)[ngx_modules[i]->index]);
-
- } else if (cf->ctx) {
- confp = *(void **) ((char *) cf->ctx + cmd->conf);
-
- if (confp) {
- conf = confp[ngx_modules[i]->ctx_index];
- }
- }
-
- rv = cmd->set(cf, cmd, conf);
-
- if (rv == NGX_CONF_OK) {
- return NGX_OK;
- }
-
- if (rv == NGX_CONF_ERROR) {
- return NGX_ERROR;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%s\" directive %s", name->data, rv);
-
- return NGX_ERROR;
- }
- }
-
- if (found) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%s\" directive is not allowed here", name->data);
-
- return NGX_ERROR;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unknown directive \"%s\"", name->data);
-
- return NGX_ERROR;
-
-invalid:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid number of arguments in \"%s\" directive",
- name->data);
-
- return NGX_ERROR;
-}
-
-
-static ngx_int_t
-ngx_conf_read_token(ngx_conf_t *cf)
-{
- u_char *start, ch, *src, *dst;
- off_t file_size;
- size_t len;
- ssize_t n, size;
- ngx_uint_t found, need_space, last_space, sharp_comment, variable;
- ngx_uint_t quoted, s_quoted, d_quoted, start_line;
- ngx_str_t *word;
- ngx_buf_t *b;
-
- found = 0;
- need_space = 0;
- last_space = 1;
- sharp_comment = 0;
- variable = 0;
- quoted = 0;
- s_quoted = 0;
- d_quoted = 0;
-
- cf->args->nelts = 0;
- b = cf->conf_file->buffer;
- start = b->pos;
- start_line = cf->conf_file->line;
-
- file_size = ngx_file_size(&cf->conf_file->file.info);
-
- for ( ;; ) {
-
- if (b->pos >= b->last) {
-
- if (cf->conf_file->file.offset >= file_size) {
-
- if (cf->args->nelts > 0 || !last_space) {
-
- if (cf->conf_file->file.fd == NGX_INVALID_FILE) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unexpected end of parameter, "
- "expecting \";\"");
- return NGX_ERROR;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unexpected end of file, "
- "expecting \";\" or \"}\"");
- return NGX_ERROR;
- }
-
- return NGX_CONF_FILE_DONE;
- }
-
- len = b->pos - start;
-
- if (len == NGX_CONF_BUFFER) {
- cf->conf_file->line = start_line;
-
- if (d_quoted) {
- ch = '"';
-
- } else if (s_quoted) {
- ch = '\'';
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "too long parameter \"%*s...\" started",
- 10, start);
- return NGX_ERROR;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "too long parameter, probably "
- "missing terminating \"%c\" character", ch);
- return NGX_ERROR;
- }
-
- if (len) {
- ngx_memmove(b->start, start, len);
- }
-
- size = (ssize_t) (file_size - cf->conf_file->file.offset);
-
- if (size > b->end - (b->start + len)) {
- size = b->end - (b->start + len);
- }
-
- n = ngx_read_file(&cf->conf_file->file, b->start + len, size,
- cf->conf_file->file.offset);
-
- if (n == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- if (n != size) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- ngx_read_file_n " returned "
- "only %z bytes instead of %z",
- n, size);
- return NGX_ERROR;
- }
-
- b->pos = b->start + len;
- b->last = b->pos + n;
- start = b->start;
- }
-
- ch = *b->pos++;
-
- if (ch == LF) {
- cf->conf_file->line++;
-
- if (sharp_comment) {
- sharp_comment = 0;
- }
- }
-
- if (sharp_comment) {
- continue;
- }
-
- if (quoted) {
- quoted = 0;
- continue;
- }
-
- if (need_space) {
- if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
- last_space = 1;
- need_space = 0;
- continue;
- }
-
- if (ch == ';') {
- return NGX_OK;
- }
-
- if (ch == '{') {
- return NGX_CONF_BLOCK_START;
- }
-
- if (ch == ')') {
- last_space = 1;
- need_space = 0;
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unexpected \"%c\"", ch);
- return NGX_ERROR;
- }
- }
-
- if (last_space) {
- if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) {
- continue;
- }
-
- start = b->pos - 1;
- start_line = cf->conf_file->line;
-
- switch (ch) {
-
- case ';':
- case '{':
- if (cf->args->nelts == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unexpected \"%c\"", ch);
- return NGX_ERROR;
- }
-
- if (ch == '{') {
- return NGX_CONF_BLOCK_START;
- }
-
- return NGX_OK;
-
- case '}':
- if (cf->args->nelts != 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unexpected \"}\"");
- return NGX_ERROR;
- }
-
- return NGX_CONF_BLOCK_DONE;
-
- case '#':
- sharp_comment = 1;
- continue;
-
- case '\\':
- quoted = 1;
- last_space = 0;
- continue;
-
- case '"':
- start++;
- d_quoted = 1;
- last_space = 0;
- continue;
-
- case '\'':
- start++;
- s_quoted = 1;
- last_space = 0;
- continue;
-
- default:
- last_space = 0;
- }
-
- } else {
- if (ch == '{' && variable) {
- continue;
- }
-
- variable = 0;
-
- if (ch == '\\') {
- quoted = 1;
- continue;
- }
-
- if (ch == '$') {
- variable = 1;
- continue;
- }
-
- if (d_quoted) {
- if (ch == '"') {
- d_quoted = 0;
- need_space = 1;
- found = 1;
- }
-
- } else if (s_quoted) {
- if (ch == '\'') {
- s_quoted = 0;
- need_space = 1;
- found = 1;
- }
-
- } else if (ch == ' ' || ch == '\t' || ch == CR || ch == LF
- || ch == ';' || ch == '{')
- {
- last_space = 1;
- found = 1;
- }
-
- if (found) {
- word = ngx_array_push(cf->args);
- if (word == NULL) {
- return NGX_ERROR;
- }
-
- word->data = ngx_pnalloc(cf->pool, b->pos - start + 1);
- if (word->data == NULL) {
- return NGX_ERROR;
- }
-
- for (dst = word->data, src = start, len = 0;
- src < b->pos - 1;
- len++)
- {
- if (*src == '\\') {
- switch (src[1]) {
- case '"':
- case '\'':
- case '\\':
- src++;
- break;
-
- case 't':
- *dst++ = '\t';
- src += 2;
- continue;
-
- case 'r':
- *dst++ = '\r';
- src += 2;
- continue;
-
- case 'n':
- *dst++ = '\n';
- src += 2;
- continue;
- }
-
- }
- *dst++ = *src++;
- }
- *dst = '\0';
- word->len = len;
-
- if (ch == ';') {
- return NGX_OK;
- }
-
- if (ch == '{') {
- return NGX_CONF_BLOCK_START;
- }
-
- found = 0;
- }
- }
- }
-}
-
-
-char *
-ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *rv;
- ngx_int_t n;
- ngx_str_t *value, file, name;
- ngx_glob_t gl;
-
- value = cf->args->elts;
- file = value[1];
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
-
- if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (strpbrk((char *) file.data, "*?[") == NULL) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
-
- return ngx_conf_parse(cf, &file);
- }
-
- ngx_memzero(&gl, sizeof(ngx_glob_t));
-
- gl.pattern = file.data;
- gl.log = cf->log;
- gl.test = 1;
-
- if (ngx_open_glob(&gl) != NGX_OK) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
- ngx_open_glob_n " \"%s\" failed", file.data);
- return NGX_CONF_ERROR;
- }
-
- rv = NGX_CONF_OK;
-
- for ( ;; ) {
- n = ngx_read_glob(&gl, &name);
-
- if (n != NGX_OK) {
- break;
- }
-
- file.len = name.len++;
- file.data = ngx_pstrdup(cf->pool, &name);
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
-
- rv = ngx_conf_parse(cf, &file);
-
- if (rv != NGX_CONF_OK) {
- break;
- }
- }
-
- ngx_close_glob(&gl);
-
- return rv;
-}
-
-
-ngx_int_t
-ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix)
-{
- ngx_str_t *prefix;
-
- prefix = conf_prefix ? &cycle->conf_prefix : &cycle->prefix;
-
- return ngx_get_full_name(cycle->pool, prefix, name);
-}
-
-
-ngx_open_file_t *
-ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name)
-{
- ngx_str_t full;
- ngx_uint_t i;
- ngx_list_part_t *part;
- ngx_open_file_t *file;
-
-#if (NGX_SUPPRESS_WARN)
- ngx_str_null(&full);
-#endif
-
- if (name->len) {
- full = *name;
-
- if (ngx_conf_full_name(cycle, &full, 0) != NGX_OK) {
- return NULL;
- }
-
- part = &cycle->open_files.part;
- file = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- file = part->elts;
- i = 0;
- }
-
- if (full.len != file[i].name.len) {
- continue;
- }
-
- if (ngx_strcmp(full.data, file[i].name.data) == 0) {
- return &file[i];
- }
- }
- }
-
- file = ngx_list_push(&cycle->open_files);
- if (file == NULL) {
- return NULL;
- }
-
- if (name->len) {
- file->fd = NGX_INVALID_FILE;
- file->name = full;
-
- } else {
- file->fd = ngx_stderr;
- file->name = *name;
- }
-
- file->flush = NULL;
- file->data = NULL;
-
- return file;
-}
-
-
-static void
-ngx_conf_flush_files(ngx_cycle_t *cycle)
-{
- ngx_uint_t i;
- ngx_list_part_t *part;
- ngx_open_file_t *file;
-
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "flush files");
-
- part = &cycle->open_files.part;
- file = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- file = part->elts;
- i = 0;
- }
-
- if (file[i].flush) {
- file[i].flush(&file[i], cycle->log);
- }
- }
-}
-
-
-void ngx_cdecl
-ngx_conf_log_error(ngx_uint_t level, ngx_conf_t *cf, ngx_err_t err,
- const char *fmt, ...)
-{
- u_char errstr[NGX_MAX_CONF_ERRSTR], *p, *last;
- va_list args;
-
- last = errstr + NGX_MAX_CONF_ERRSTR;
-
- va_start(args, fmt);
- p = ngx_vslprintf(errstr, last, fmt, args);
- va_end(args);
-
- if (err) {
- p = ngx_log_errno(p, last, err);
- }
-
- if (cf->conf_file == NULL) {
- ngx_log_error(level, cf->log, 0, "%*s", p - errstr, errstr);
- return;
- }
-
- if (cf->conf_file->file.fd == NGX_INVALID_FILE) {
- ngx_log_error(level, cf->log, 0, "%*s in command line",
- p - errstr, errstr);
- return;
- }
-
- ngx_log_error(level, cf->log, 0, "%*s in %s:%ui",
- p - errstr, errstr,
- cf->conf_file->file.name.data, cf->conf_file->line);
-}
-
-
-char *
-ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_str_t *value;
- ngx_flag_t *fp;
- ngx_conf_post_t *post;
-
- fp = (ngx_flag_t *) (p + cmd->offset);
-
- if (*fp != NGX_CONF_UNSET) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- if (ngx_strcasecmp(value[1].data, (u_char *) "on") == 0) {
- *fp = 1;
-
- } else if (ngx_strcasecmp(value[1].data, (u_char *) "off") == 0) {
- *fp = 0;
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%s\" in \"%s\" directive, "
- "it must be \"on\" or \"off\"",
- value[1].data, cmd->name.data);
- return NGX_CONF_ERROR;
- }
-
- if (cmd->post) {
- post = cmd->post;
- return post->post_handler(cf, post, fp);
- }
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_str_t *field, *value;
- ngx_conf_post_t *post;
-
- field = (ngx_str_t *) (p + cmd->offset);
-
- if (field->data) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- *field = value[1];
-
- if (cmd->post) {
- post = cmd->post;
- return post->post_handler(cf, post, field);
- }
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_str_t *value, *s;
- ngx_array_t **a;
- ngx_conf_post_t *post;
-
- a = (ngx_array_t **) (p + cmd->offset);
-
- if (*a == NGX_CONF_UNSET_PTR) {
- *a = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
- if (*a == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- s = ngx_array_push(*a);
- if (s == NULL) {
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
-
- *s = value[1];
-
- if (cmd->post) {
- post = cmd->post;
- return post->post_handler(cf, post, s);
- }
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_str_t *value;
- ngx_array_t **a;
- ngx_keyval_t *kv;
- ngx_conf_post_t *post;
-
- a = (ngx_array_t **) (p + cmd->offset);
-
- if (*a == NULL) {
- *a = ngx_array_create(cf->pool, 4, sizeof(ngx_keyval_t));
- if (*a == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- kv = ngx_array_push(*a);
- if (kv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
-
- kv->key = value[1];
- kv->value = value[2];
-
- if (cmd->post) {
- post = cmd->post;
- return post->post_handler(cf, post, kv);
- }
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_int_t *np;
- ngx_str_t *value;
- ngx_conf_post_t *post;
-
-
- np = (ngx_int_t *) (p + cmd->offset);
-
- if (*np != NGX_CONF_UNSET) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
- *np = ngx_atoi(value[1].data, value[1].len);
- if (*np == NGX_ERROR) {
- return "invalid number";
- }
-
- if (cmd->post) {
- post = cmd->post;
- return post->post_handler(cf, post, np);
- }
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- size_t *sp;
- ngx_str_t *value;
- ngx_conf_post_t *post;
-
-
- sp = (size_t *) (p + cmd->offset);
- if (*sp != NGX_CONF_UNSET_SIZE) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- *sp = ngx_parse_size(&value[1]);
- if (*sp == (size_t) NGX_ERROR) {
- return "invalid value";
- }
-
- if (cmd->post) {
- post = cmd->post;
- return post->post_handler(cf, post, sp);
- }
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- off_t *op;
- ngx_str_t *value;
- ngx_conf_post_t *post;
-
-
- op = (off_t *) (p + cmd->offset);
- if (*op != NGX_CONF_UNSET) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- *op = ngx_parse_offset(&value[1]);
- if (*op == (off_t) NGX_ERROR) {
- return "invalid value";
- }
-
- if (cmd->post) {
- post = cmd->post;
- return post->post_handler(cf, post, op);
- }
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_msec_t *msp;
- ngx_str_t *value;
- ngx_conf_post_t *post;
-
-
- msp = (ngx_msec_t *) (p + cmd->offset);
- if (*msp != NGX_CONF_UNSET_MSEC) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- *msp = ngx_parse_time(&value[1], 0);
- if (*msp == (ngx_msec_t) NGX_ERROR) {
- return "invalid value";
- }
-
- if (cmd->post) {
- post = cmd->post;
- return post->post_handler(cf, post, msp);
- }
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- time_t *sp;
- ngx_str_t *value;
- ngx_conf_post_t *post;
-
-
- sp = (time_t *) (p + cmd->offset);
- if (*sp != NGX_CONF_UNSET) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- *sp = ngx_parse_time(&value[1], 1);
- if (*sp == (time_t) NGX_ERROR) {
- return "invalid value";
- }
-
- if (cmd->post) {
- post = cmd->post;
- return post->post_handler(cf, post, sp);
- }
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_str_t *value;
- ngx_bufs_t *bufs;
-
-
- bufs = (ngx_bufs_t *) (p + cmd->offset);
- if (bufs->num) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- bufs->num = ngx_atoi(value[1].data, value[1].len);
- if (bufs->num == NGX_ERROR || bufs->num == 0) {
- return "invalid value";
- }
-
- bufs->size = ngx_parse_size(&value[2]);
- if (bufs->size == (size_t) NGX_ERROR || bufs->size == 0) {
- return "invalid value";
- }
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_uint_t *np, i;
- ngx_str_t *value;
- ngx_conf_enum_t *e;
-
- np = (ngx_uint_t *) (p + cmd->offset);
-
- if (*np != NGX_CONF_UNSET_UINT) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
- e = cmd->post;
-
- for (i = 0; e[i].name.len != 0; i++) {
- if (e[i].name.len != value[1].len
- || ngx_strcasecmp(e[i].name.data, value[1].data) != 0)
- {
- continue;
- }
-
- *np = e[i].value;
-
- return NGX_CONF_OK;
- }
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "invalid value \"%s\"", value[1].data);
-
- return NGX_CONF_ERROR;
-}
-
-
-char *
-ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_uint_t *np, i, m;
- ngx_str_t *value;
- ngx_conf_bitmask_t *mask;
-
-
- np = (ngx_uint_t *) (p + cmd->offset);
- value = cf->args->elts;
- mask = cmd->post;
-
- for (i = 1; i < cf->args->nelts; i++) {
- for (m = 0; mask[m].name.len != 0; m++) {
-
- if (mask[m].name.len != value[i].len
- || ngx_strcasecmp(mask[m].name.data, value[i].data) != 0)
- {
- continue;
- }
-
- if (*np & mask[m].mask) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "duplicate value \"%s\"", value[i].data);
-
- } else {
- *np |= mask[m].mask;
- }
-
- break;
- }
-
- if (mask[m].name.len == 0) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "invalid value \"%s\"", value[i].data);
-
- return NGX_CONF_ERROR;
- }
- }
-
- return NGX_CONF_OK;
-}
-
-
-#if 0
-
-char *
-ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- return "unsupported on this platform";
-}
-
-#endif
-
-
-char *
-ngx_conf_deprecated(ngx_conf_t *cf, void *post, void *data)
-{
- ngx_conf_deprecated_t *d = post;
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "the \"%s\" directive is deprecated, "
- "use the \"%s\" directive instead",
- d->old_name, d->new_name);
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data)
-{
- ngx_conf_num_bounds_t *bounds = post;
- ngx_int_t *np = data;
-
- if (bounds->high == -1) {
- if (*np >= bounds->low) {
- return NGX_CONF_OK;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "value must be equal to or greater than %i",
- bounds->low);
-
- return NGX_CONF_ERROR;
- }
-
- if (*np >= bounds->low && *np <= bounds->high) {
- return NGX_CONF_OK;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "value must be between %i and %i",
- bounds->low, bounds->high);
-
- return NGX_CONF_ERROR;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_conf_file.h b/usr.sbin/nginx/src/core/ngx_conf_file.h
deleted file mode 100644
index d73a6c8bf55..00000000000
--- a/usr.sbin/nginx/src/core/ngx_conf_file.h
+++ /dev/null
@@ -1,340 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_CONF_FILE_H_INCLUDED_
-#define _NGX_CONF_FILE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/*
- * AAAA number of arguments
- * FF command flags
- * TT command type, i.e. HTTP "location" or "server" command
- */
-
-#define NGX_CONF_NOARGS 0x00000001
-#define NGX_CONF_TAKE1 0x00000002
-#define NGX_CONF_TAKE2 0x00000004
-#define NGX_CONF_TAKE3 0x00000008
-#define NGX_CONF_TAKE4 0x00000010
-#define NGX_CONF_TAKE5 0x00000020
-#define NGX_CONF_TAKE6 0x00000040
-#define NGX_CONF_TAKE7 0x00000080
-
-#define NGX_CONF_MAX_ARGS 8
-
-#define NGX_CONF_TAKE12 (NGX_CONF_TAKE1|NGX_CONF_TAKE2)
-#define NGX_CONF_TAKE13 (NGX_CONF_TAKE1|NGX_CONF_TAKE3)
-
-#define NGX_CONF_TAKE23 (NGX_CONF_TAKE2|NGX_CONF_TAKE3)
-
-#define NGX_CONF_TAKE123 (NGX_CONF_TAKE1|NGX_CONF_TAKE2|NGX_CONF_TAKE3)
-#define NGX_CONF_TAKE1234 (NGX_CONF_TAKE1|NGX_CONF_TAKE2|NGX_CONF_TAKE3 \
- |NGX_CONF_TAKE4)
-
-#define NGX_CONF_ARGS_NUMBER 0x000000ff
-#define NGX_CONF_BLOCK 0x00000100
-#define NGX_CONF_FLAG 0x00000200
-#define NGX_CONF_ANY 0x00000400
-#define NGX_CONF_1MORE 0x00000800
-#define NGX_CONF_2MORE 0x00001000
-#define NGX_CONF_MULTI 0x00000000 /* compatibility */
-
-#define NGX_DIRECT_CONF 0x00010000
-
-#define NGX_MAIN_CONF 0x01000000
-#define NGX_ANY_CONF 0x0F000000
-
-
-
-#define NGX_CONF_UNSET -1
-#define NGX_CONF_UNSET_UINT (ngx_uint_t) -1
-#define NGX_CONF_UNSET_PTR (void *) -1
-#define NGX_CONF_UNSET_SIZE (size_t) -1
-#define NGX_CONF_UNSET_MSEC (ngx_msec_t) -1
-
-
-#define NGX_CONF_OK NULL
-#define NGX_CONF_ERROR (void *) -1
-
-#define NGX_CONF_BLOCK_START 1
-#define NGX_CONF_BLOCK_DONE 2
-#define NGX_CONF_FILE_DONE 3
-
-#define NGX_CORE_MODULE 0x45524F43 /* "CORE" */
-#define NGX_CONF_MODULE 0x464E4F43 /* "CONF" */
-
-
-#define NGX_MAX_CONF_ERRSTR 1024
-
-
-struct ngx_command_s {
- ngx_str_t name;
- ngx_uint_t type;
- char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
- ngx_uint_t conf;
- ngx_uint_t offset;
- void *post;
-};
-
-#define ngx_null_command { ngx_null_string, 0, NULL, 0, 0, NULL }
-
-
-struct ngx_open_file_s {
- ngx_fd_t fd;
- ngx_str_t name;
-
- void (*flush)(ngx_open_file_t *file, ngx_log_t *log);
- void *data;
-};
-
-
-#define NGX_MODULE_V1 0, 0, 0, 0, 0, 0, 1
-#define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0
-
-struct ngx_module_s {
- ngx_uint_t ctx_index;
- ngx_uint_t index;
-
- ngx_uint_t spare0;
- ngx_uint_t spare1;
- ngx_uint_t spare2;
- ngx_uint_t spare3;
-
- ngx_uint_t version;
-
- void *ctx;
- ngx_command_t *commands;
- ngx_uint_t type;
-
- ngx_int_t (*init_master)(ngx_log_t *log);
-
- ngx_int_t (*init_module)(ngx_cycle_t *cycle);
-
- ngx_int_t (*init_process)(ngx_cycle_t *cycle);
- ngx_int_t (*init_thread)(ngx_cycle_t *cycle);
- void (*exit_thread)(ngx_cycle_t *cycle);
- void (*exit_process)(ngx_cycle_t *cycle);
-
- void (*exit_master)(ngx_cycle_t *cycle);
-
- uintptr_t spare_hook0;
- uintptr_t spare_hook1;
- uintptr_t spare_hook2;
- uintptr_t spare_hook3;
- uintptr_t spare_hook4;
- uintptr_t spare_hook5;
- uintptr_t spare_hook6;
- uintptr_t spare_hook7;
-};
-
-
-typedef struct {
- ngx_str_t name;
- void *(*create_conf)(ngx_cycle_t *cycle);
- char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
-} ngx_core_module_t;
-
-
-typedef struct {
- ngx_file_t file;
- ngx_buf_t *buffer;
- ngx_uint_t line;
-} ngx_conf_file_t;
-
-
-typedef char *(*ngx_conf_handler_pt)(ngx_conf_t *cf,
- ngx_command_t *dummy, void *conf);
-
-
-struct ngx_conf_s {
- char *name;
- ngx_array_t *args;
-
- ngx_cycle_t *cycle;
- ngx_pool_t *pool;
- ngx_pool_t *temp_pool;
- ngx_conf_file_t *conf_file;
- ngx_log_t *log;
-
- void *ctx;
- ngx_uint_t module_type;
- ngx_uint_t cmd_type;
-
- ngx_conf_handler_pt handler;
- char *handler_conf;
-};
-
-
-typedef char *(*ngx_conf_post_handler_pt) (ngx_conf_t *cf,
- void *data, void *conf);
-
-typedef struct {
- ngx_conf_post_handler_pt post_handler;
-} ngx_conf_post_t;
-
-
-typedef struct {
- ngx_conf_post_handler_pt post_handler;
- char *old_name;
- char *new_name;
-} ngx_conf_deprecated_t;
-
-
-typedef struct {
- ngx_conf_post_handler_pt post_handler;
- ngx_int_t low;
- ngx_int_t high;
-} ngx_conf_num_bounds_t;
-
-
-typedef struct {
- ngx_str_t name;
- ngx_uint_t value;
-} ngx_conf_enum_t;
-
-
-#define NGX_CONF_BITMASK_SET 1
-
-typedef struct {
- ngx_str_t name;
- ngx_uint_t mask;
-} ngx_conf_bitmask_t;
-
-
-
-char * ngx_conf_deprecated(ngx_conf_t *cf, void *post, void *data);
-char *ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data);
-
-
-#define ngx_get_conf(conf_ctx, module) conf_ctx[module.index]
-
-
-
-#define ngx_conf_init_value(conf, default) \
- if (conf == NGX_CONF_UNSET) { \
- conf = default; \
- }
-
-#define ngx_conf_init_ptr_value(conf, default) \
- if (conf == NGX_CONF_UNSET_PTR) { \
- conf = default; \
- }
-
-#define ngx_conf_init_uint_value(conf, default) \
- if (conf == NGX_CONF_UNSET_UINT) { \
- conf = default; \
- }
-
-#define ngx_conf_init_size_value(conf, default) \
- if (conf == NGX_CONF_UNSET_SIZE) { \
- conf = default; \
- }
-
-#define ngx_conf_init_msec_value(conf, default) \
- if (conf == NGX_CONF_UNSET_MSEC) { \
- conf = default; \
- }
-
-#define ngx_conf_merge_value(conf, prev, default) \
- if (conf == NGX_CONF_UNSET) { \
- conf = (prev == NGX_CONF_UNSET) ? default : prev; \
- }
-
-#define ngx_conf_merge_ptr_value(conf, prev, default) \
- if (conf == NGX_CONF_UNSET_PTR) { \
- conf = (prev == NGX_CONF_UNSET_PTR) ? default : prev; \
- }
-
-#define ngx_conf_merge_uint_value(conf, prev, default) \
- if (conf == NGX_CONF_UNSET_UINT) { \
- conf = (prev == NGX_CONF_UNSET_UINT) ? default : prev; \
- }
-
-#define ngx_conf_merge_msec_value(conf, prev, default) \
- if (conf == NGX_CONF_UNSET_MSEC) { \
- conf = (prev == NGX_CONF_UNSET_MSEC) ? default : prev; \
- }
-
-#define ngx_conf_merge_sec_value(conf, prev, default) \
- if (conf == NGX_CONF_UNSET) { \
- conf = (prev == NGX_CONF_UNSET) ? default : prev; \
- }
-
-#define ngx_conf_merge_size_value(conf, prev, default) \
- if (conf == NGX_CONF_UNSET_SIZE) { \
- conf = (prev == NGX_CONF_UNSET_SIZE) ? default : prev; \
- }
-
-#define ngx_conf_merge_off_value(conf, prev, default) \
- if (conf == NGX_CONF_UNSET) { \
- conf = (prev == NGX_CONF_UNSET) ? default : prev; \
- }
-
-#define ngx_conf_merge_str_value(conf, prev, default) \
- if (conf.data == NULL) { \
- if (prev.data) { \
- conf.len = prev.len; \
- conf.data = prev.data; \
- } else { \
- conf.len = sizeof(default) - 1; \
- conf.data = (u_char *) default; \
- } \
- }
-
-#define ngx_conf_merge_bufs_value(conf, prev, default_num, default_size) \
- if (conf.num == 0) { \
- if (prev.num) { \
- conf.num = prev.num; \
- conf.size = prev.size; \
- } else { \
- conf.num = default_num; \
- conf.size = default_size; \
- } \
- }
-
-#define ngx_conf_merge_bitmask_value(conf, prev, default) \
- if (conf == 0) { \
- conf = (prev == 0) ? default : prev; \
- }
-
-
-char *ngx_conf_param(ngx_conf_t *cf);
-char *ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename);
-char *ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-
-
-ngx_int_t ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name,
- ngx_uint_t conf_prefix);
-ngx_open_file_t *ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name);
-void ngx_cdecl ngx_conf_log_error(ngx_uint_t level, ngx_conf_t *cf,
- ngx_err_t err, const char *fmt, ...);
-
-
-char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-char *ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-char *ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-char *ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-char *ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-char *ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-
-
-extern ngx_uint_t ngx_max_module;
-extern ngx_module_t *ngx_modules[];
-
-
-#endif /* _NGX_CONF_FILE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_config.h b/usr.sbin/nginx/src/core/ngx_config.h
deleted file mode 100644
index 1da71f8d1a1..00000000000
--- a/usr.sbin/nginx/src/core/ngx_config.h
+++ /dev/null
@@ -1,134 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_CONFIG_H_INCLUDED_
-#define _NGX_CONFIG_H_INCLUDED_
-
-
-#include <ngx_auto_headers.h>
-
-
-#if defined __DragonFly__ && !defined __FreeBSD__
-#define __FreeBSD__ 4
-#define __FreeBSD_version 480101
-#endif
-
-
-#if (NGX_FREEBSD)
-#include <ngx_freebsd_config.h>
-
-
-#elif (NGX_LINUX)
-#include <ngx_linux_config.h>
-
-
-#elif (NGX_SOLARIS)
-#include <ngx_solaris_config.h>
-
-
-#elif (NGX_DARWIN)
-#include <ngx_darwin_config.h>
-
-
-#elif (NGX_WIN32)
-#include <ngx_win32_config.h>
-
-
-#else /* POSIX */
-#include <ngx_posix_config.h>
-
-#endif
-
-
-#ifndef NGX_HAVE_SO_SNDLOWAT
-#define NGX_HAVE_SO_SNDLOWAT 1
-#endif
-
-
-#if !(NGX_WIN32)
-
-#define ngx_signal_helper(n) SIG##n
-#define ngx_signal_value(n) ngx_signal_helper(n)
-
-#define ngx_random random
-
-/* TODO: #ifndef */
-#define NGX_SHUTDOWN_SIGNAL QUIT
-#define NGX_TERMINATE_SIGNAL TERM
-#define NGX_NOACCEPT_SIGNAL WINCH
-#define NGX_RECONFIGURE_SIGNAL HUP
-
-#if (NGX_LINUXTHREADS)
-#define NGX_REOPEN_SIGNAL INFO
-#define NGX_CHANGEBIN_SIGNAL XCPU
-#else
-#define NGX_REOPEN_SIGNAL USR1
-#define NGX_CHANGEBIN_SIGNAL USR2
-#endif
-
-#define ngx_cdecl
-#define ngx_libc_cdecl
-
-#endif
-
-typedef intptr_t ngx_int_t;
-typedef uintptr_t ngx_uint_t;
-typedef intptr_t ngx_flag_t;
-
-
-#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 */
-#endif
-
-#define ngx_align(d, a) (((d) + (a - 1)) & ~(a - 1))
-#define ngx_align_ptr(p, a) \
- (u_char *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))
-
-
-#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
-#endif
-
-#ifndef INADDR_NONE /* Solaris */
-#define INADDR_NONE ((unsigned int) -1)
-#endif
-
-#ifdef MAXHOSTNAMELEN
-#define NGX_MAXHOSTNAMELEN MAXHOSTNAMELEN
-#else
-#define NGX_MAXHOSTNAMELEN 256
-#endif
-
-
-#if ((__GNU__ == 2) && (__GNUC_MINOR__ < 8))
-#define NGX_MAX_UINT32_VALUE (uint32_t) 0xffffffffLL
-#else
-#define NGX_MAX_UINT32_VALUE (uint32_t) 0xffffffff
-#endif
-
-#define NGX_MAX_INT32_VALUE (uint32_t) 0x7fffffff
-
-
-#endif /* _NGX_CONFIG_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_connection.c b/usr.sbin/nginx/src/core/ngx_connection.c
deleted file mode 100644
index 6b6e3b3a512..00000000000
--- a/usr.sbin/nginx/src/core/ngx_connection.c
+++ /dev/null
@@ -1,1210 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-ngx_os_io_t ngx_io;
-
-
-static void ngx_drain_connections(void);
-
-
-ngx_listening_t *
-ngx_create_listening(ngx_conf_t *cf, void *sockaddr, socklen_t socklen)
-{
- size_t len;
- ngx_listening_t *ls;
- struct sockaddr *sa;
- u_char text[NGX_SOCKADDR_STRLEN];
-
- ls = ngx_array_push(&cf->cycle->listening);
- if (ls == NULL) {
- return NULL;
- }
-
- ngx_memzero(ls, sizeof(ngx_listening_t));
-
- sa = ngx_palloc(cf->pool, socklen);
- if (sa == NULL) {
- return NULL;
- }
-
- ngx_memcpy(sa, sockaddr, socklen);
-
- ls->sockaddr = sa;
- ls->socklen = socklen;
-
- len = ngx_sock_ntop(sa, socklen, text, NGX_SOCKADDR_STRLEN, 1);
- ls->addr_text.len = len;
-
- switch (ls->sockaddr->sa_family) {
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- ls->addr_text_max_len = NGX_INET6_ADDRSTRLEN;
- break;
-#endif
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- ls->addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
- len++;
- break;
-#endif
- case AF_INET:
- ls->addr_text_max_len = NGX_INET_ADDRSTRLEN;
- break;
- default:
- ls->addr_text_max_len = NGX_SOCKADDR_STRLEN;
- break;
- }
-
- ls->addr_text.data = ngx_pnalloc(cf->pool, len);
- if (ls->addr_text.data == NULL) {
- return NULL;
- }
-
- ngx_memcpy(ls->addr_text.data, text, len);
-
- ls->fd = (ngx_socket_t) -1;
- ls->type = SOCK_STREAM;
-
- ls->backlog = NGX_LISTEN_BACKLOG;
- ls->rcvbuf = -1;
- ls->sndbuf = -1;
-
-#if (NGX_HAVE_SETFIB)
- ls->setfib = -1;
-#endif
-
-#if (NGX_HAVE_TCP_FASTOPEN)
- ls->fastopen = -1;
-#endif
-
- return ls;
-}
-
-
-ngx_int_t
-ngx_set_inherited_sockets(ngx_cycle_t *cycle)
-{
- size_t len;
- ngx_uint_t i;
- ngx_listening_t *ls;
- socklen_t olen;
-#if (NGX_HAVE_DEFERRED_ACCEPT || NGX_HAVE_TCP_FASTOPEN)
- ngx_err_t err;
-#endif
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
- struct accept_filter_arg af;
-#endif
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
- int timeout;
-#endif
-
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
-
- ls[i].sockaddr = ngx_palloc(cycle->pool, NGX_SOCKADDRLEN);
- if (ls[i].sockaddr == NULL) {
- return NGX_ERROR;
- }
-
- ls[i].socklen = NGX_SOCKADDRLEN;
- if (getsockname(ls[i].fd, ls[i].sockaddr, &ls[i].socklen) == -1) {
- ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
- "getsockname() of the inherited "
- "socket #%d failed", ls[i].fd);
- ls[i].ignore = 1;
- continue;
- }
-
- switch (ls[i].sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN;
- len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- ls[i].addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
- len = NGX_UNIX_ADDRSTRLEN;
- break;
-#endif
-
- case AF_INET:
- ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN;
- len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
- break;
-
- default:
- ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_socket_errno,
- "the inherited socket #%d has "
- "an unsupported protocol family", ls[i].fd);
- ls[i].ignore = 1;
- continue;
- }
-
- ls[i].addr_text.data = ngx_pnalloc(cycle->pool, len);
- if (ls[i].addr_text.data == NULL) {
- return NGX_ERROR;
- }
-
- len = ngx_sock_ntop(ls[i].sockaddr, ls[i].socklen,
- ls[i].addr_text.data, len, 1);
- if (len == 0) {
- return NGX_ERROR;
- }
-
- ls[i].addr_text.len = len;
-
- ls[i].backlog = NGX_LISTEN_BACKLOG;
-
- olen = sizeof(int);
-
- if (getsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF, (void *) &ls[i].rcvbuf,
- &olen)
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "getsockopt(SO_RCVBUF) %V failed, ignored",
- &ls[i].addr_text);
-
- ls[i].rcvbuf = -1;
- }
-
- olen = sizeof(int);
-
- if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF, (void *) &ls[i].sndbuf,
- &olen)
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "getsockopt(SO_SNDBUF) %V failed, ignored",
- &ls[i].addr_text);
-
- ls[i].sndbuf = -1;
- }
-
-#if 0
- /* SO_SETFIB is currently a set only option */
-
-#if (NGX_HAVE_SETFIB)
-
- olen = sizeof(int);
-
- if (getsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
- (void *) &ls[i].setfib, &olen)
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "getsockopt(SO_SETFIB) %V failed, ignored",
- &ls[i].addr_text);
-
- ls[i].setfib = -1;
- }
-
-#endif
-#endif
-
-#if (NGX_HAVE_TCP_FASTOPEN)
-
- olen = sizeof(int);
-
- if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_FASTOPEN,
- (void *) &ls[i].fastopen, &olen)
- == -1)
- {
- err = ngx_socket_errno;
-
- if (err != NGX_EOPNOTSUPP && err != NGX_ENOPROTOOPT) {
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
- "getsockopt(TCP_FASTOPEN) %V failed, ignored",
- &ls[i].addr_text);
- }
-
- ls[i].fastopen = -1;
- }
-
-#endif
-
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
-
- ngx_memzero(&af, sizeof(struct accept_filter_arg));
- olen = sizeof(struct accept_filter_arg);
-
- if (getsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, &af, &olen)
- == -1)
- {
- err = ngx_socket_errno;
-
- if (err == NGX_EINVAL) {
- continue;
- }
-
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
- "getsockopt(SO_ACCEPTFILTER) for %V failed, ignored",
- &ls[i].addr_text);
- continue;
- }
-
- if (olen < sizeof(struct accept_filter_arg) || af.af_name[0] == '\0') {
- continue;
- }
-
- ls[i].accept_filter = ngx_palloc(cycle->pool, 16);
- if (ls[i].accept_filter == NULL) {
- return NGX_ERROR;
- }
-
- (void) ngx_cpystrn((u_char *) ls[i].accept_filter,
- (u_char *) af.af_name, 16);
-#endif
-
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
-
- timeout = 0;
- olen = sizeof(int);
-
- if (getsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, &olen)
- == -1)
- {
- err = ngx_socket_errno;
-
- if (err == NGX_EOPNOTSUPP) {
- continue;
- }
-
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, err,
- "getsockopt(TCP_DEFER_ACCEPT) for %V failed, ignored",
- &ls[i].addr_text);
- continue;
- }
-
- if (olen < sizeof(int) || timeout == 0) {
- continue;
- }
-
- ls[i].deferred_accept = 1;
-#endif
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_open_listening_sockets(ngx_cycle_t *cycle)
-{
- int reuseaddr;
- ngx_uint_t i, tries, failed;
- ngx_err_t err;
- ngx_log_t *log;
- ngx_socket_t s;
- ngx_listening_t *ls;
-
- reuseaddr = 1;
-#if (NGX_SUPPRESS_WARN)
- failed = 0;
-#endif
-
- log = cycle->log;
-
- /* TODO: configurable try number */
-
- for (tries = 5; tries; tries--) {
- failed = 0;
-
- /* for each listening socket */
-
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
-
- if (ls[i].ignore) {
- continue;
- }
-
- if (ls[i].fd != (ngx_socket_t) -1) {
- continue;
- }
-
- if (ls[i].inherited) {
-
- /* TODO: close on exit */
- /* TODO: nonblocking */
- /* TODO: deferred accept */
-
- continue;
- }
-
- s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type, 0);
-
- if (s == (ngx_socket_t) -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
- ngx_socket_n " %V failed", &ls[i].addr_text);
- return NGX_ERROR;
- }
-
- if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
- (const void *) &reuseaddr, sizeof(int))
- == -1)
- {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
- "setsockopt(SO_REUSEADDR) %V failed",
- &ls[i].addr_text);
-
- if (ngx_close_socket(s) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
- ngx_close_socket_n " %V failed",
- &ls[i].addr_text);
- }
-
- return NGX_ERROR;
- }
-
-#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
-
- if (ls[i].sockaddr->sa_family == AF_INET6) {
- int ipv6only;
-
- ipv6only = ls[i].ipv6only;
-
- if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
- (const void *) &ipv6only, sizeof(int))
- == -1)
- {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
- "setsockopt(IPV6_V6ONLY) %V failed, ignored",
- &ls[i].addr_text);
- }
- }
-#endif
- /* TODO: close on exit */
-
- if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) {
- if (ngx_nonblocking(s) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
- ngx_nonblocking_n " %V failed",
- &ls[i].addr_text);
-
- if (ngx_close_socket(s) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
- ngx_close_socket_n " %V failed",
- &ls[i].addr_text);
- }
-
- return NGX_ERROR;
- }
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
- "bind() %V #%d ", &ls[i].addr_text, s);
-
- if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
- err = ngx_socket_errno;
-
- if (err == NGX_EADDRINUSE && ngx_test_config) {
- continue;
- }
-
- ngx_log_error(NGX_LOG_EMERG, log, err,
- "bind() to %V failed", &ls[i].addr_text);
-
- if (ngx_close_socket(s) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
- ngx_close_socket_n " %V failed",
- &ls[i].addr_text);
- }
-
- if (err != NGX_EADDRINUSE) {
- return NGX_ERROR;
- }
-
- failed = 1;
-
- continue;
- }
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-
- if (ls[i].sockaddr->sa_family == AF_UNIX) {
- mode_t mode;
- u_char *name;
-
- name = ls[i].addr_text.data + sizeof("unix:") - 1;
- mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
-
- if (chmod((char *) name, mode) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "chmod() \"%s\" failed", name);
- }
-
- if (ngx_test_config) {
- if (ngx_delete_file(name) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- ngx_delete_file_n " %s failed", name);
- }
- }
- }
-#endif
-
- if (listen(s, ls[i].backlog) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
- "listen() to %V, backlog %d failed",
- &ls[i].addr_text, ls[i].backlog);
-
- if (ngx_close_socket(s) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
- ngx_close_socket_n " %V failed",
- &ls[i].addr_text);
- }
-
- return NGX_ERROR;
- }
-
- ls[i].listen = 1;
-
- ls[i].fd = s;
- }
-
- if (!failed) {
- break;
- }
-
- /* TODO: delay configurable */
-
- ngx_log_error(NGX_LOG_NOTICE, log, 0,
- "try again to bind() after 500ms");
-
- ngx_msleep(500);
- }
-
- if (failed) {
- ngx_log_error(NGX_LOG_EMERG, log, 0, "still could not bind()");
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-void
-ngx_configure_listening_sockets(ngx_cycle_t *cycle)
-{
- int value;
- ngx_uint_t i;
- ngx_listening_t *ls;
-
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
- struct accept_filter_arg af;
-#endif
-
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
-
- ls[i].log = *ls[i].logp;
-
- if (ls[i].rcvbuf != -1) {
- if (setsockopt(ls[i].fd, SOL_SOCKET, SO_RCVBUF,
- (const void *) &ls[i].rcvbuf, sizeof(int))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "setsockopt(SO_RCVBUF, %d) %V failed, ignored",
- ls[i].rcvbuf, &ls[i].addr_text);
- }
- }
-
- if (ls[i].sndbuf != -1) {
- if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SNDBUF,
- (const void *) &ls[i].sndbuf, sizeof(int))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "setsockopt(SO_SNDBUF, %d) %V failed, ignored",
- ls[i].sndbuf, &ls[i].addr_text);
- }
- }
-
- if (ls[i].keepalive) {
- value = (ls[i].keepalive == 1) ? 1 : 0;
-
- if (setsockopt(ls[i].fd, SOL_SOCKET, SO_KEEPALIVE,
- (const void *) &value, sizeof(int))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "setsockopt(SO_KEEPALIVE, %d) %V failed, ignored",
- value, &ls[i].addr_text);
- }
- }
-
-#if (NGX_HAVE_KEEPALIVE_TUNABLE)
-
- if (ls[i].keepidle) {
- value = ls[i].keepidle;
-
-#if (NGX_KEEPALIVE_FACTOR)
- value *= NGX_KEEPALIVE_FACTOR;
-#endif
-
- if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPIDLE,
- (const void *) &value, sizeof(int))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "setsockopt(TCP_KEEPIDLE, %d) %V failed, ignored",
- value, &ls[i].addr_text);
- }
- }
-
- if (ls[i].keepintvl) {
- value = ls[i].keepintvl;
-
-#if (NGX_KEEPALIVE_FACTOR)
- value *= NGX_KEEPALIVE_FACTOR;
-#endif
-
- if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPINTVL,
- (const void *) &value, sizeof(int))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "setsockopt(TCP_KEEPINTVL, %d) %V failed, ignored",
- value, &ls[i].addr_text);
- }
- }
-
- if (ls[i].keepcnt) {
- if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_KEEPCNT,
- (const void *) &ls[i].keepcnt, sizeof(int))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "setsockopt(TCP_KEEPCNT, %d) %V failed, ignored",
- ls[i].keepcnt, &ls[i].addr_text);
- }
- }
-
-#endif
-
-#if (NGX_HAVE_SETFIB)
- if (ls[i].setfib != -1) {
- if (setsockopt(ls[i].fd, SOL_SOCKET, SO_SETFIB,
- (const void *) &ls[i].setfib, sizeof(int))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "setsockopt(SO_SETFIB, %d) %V failed, ignored",
- ls[i].setfib, &ls[i].addr_text);
- }
- }
-#endif
-
-#if (NGX_HAVE_TCP_FASTOPEN)
- if (ls[i].fastopen != -1) {
- if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_FASTOPEN,
- (const void *) &ls[i].fastopen, sizeof(int))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "setsockopt(TCP_FASTOPEN, %d) %V failed, ignored",
- ls[i].fastopen, &ls[i].addr_text);
- }
- }
-#endif
-
-#if 0
- if (1) {
- int tcp_nodelay = 1;
-
- if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_NODELAY,
- (const void *) &tcp_nodelay, sizeof(int))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "setsockopt(TCP_NODELAY) %V failed, ignored",
- &ls[i].addr_text);
- }
- }
-#endif
-
- if (ls[i].listen) {
-
- /* change backlog via listen() */
-
- if (listen(ls[i].fd, ls[i].backlog) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "listen() to %V, backlog %d failed, ignored",
- &ls[i].addr_text, ls[i].backlog);
- }
- }
-
- /*
- * setting deferred mode should be last operation on socket,
- * because code may prematurely continue cycle on failure
- */
-
-#if (NGX_HAVE_DEFERRED_ACCEPT)
-
-#ifdef SO_ACCEPTFILTER
-
- if (ls[i].delete_deferred) {
- if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER, NULL, 0)
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "setsockopt(SO_ACCEPTFILTER, NULL) "
- "for %V failed, ignored",
- &ls[i].addr_text);
-
- if (ls[i].accept_filter) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "could not change the accept filter "
- "to \"%s\" for %V, ignored",
- ls[i].accept_filter, &ls[i].addr_text);
- }
-
- continue;
- }
-
- ls[i].deferred_accept = 0;
- }
-
- if (ls[i].add_deferred) {
- ngx_memzero(&af, sizeof(struct accept_filter_arg));
- (void) ngx_cpystrn((u_char *) af.af_name,
- (u_char *) ls[i].accept_filter, 16);
-
- if (setsockopt(ls[i].fd, SOL_SOCKET, SO_ACCEPTFILTER,
- &af, sizeof(struct accept_filter_arg))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "setsockopt(SO_ACCEPTFILTER, \"%s\") "
- "for %V failed, ignored",
- ls[i].accept_filter, &ls[i].addr_text);
- continue;
- }
-
- ls[i].deferred_accept = 1;
- }
-
-#endif
-
-#ifdef TCP_DEFER_ACCEPT
-
- if (ls[i].add_deferred || ls[i].delete_deferred) {
-
- if (ls[i].add_deferred) {
- /*
- * There is no way to find out how long a connection was
- * in queue (and a connection may bypass deferred queue at all
- * if syncookies were used), hence we use 1 second timeout
- * here.
- */
- value = 1;
-
- } else {
- value = 0;
- }
-
- if (setsockopt(ls[i].fd, IPPROTO_TCP, TCP_DEFER_ACCEPT,
- &value, sizeof(int))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno,
- "setsockopt(TCP_DEFER_ACCEPT, %d) for %V failed, "
- "ignored",
- value, &ls[i].addr_text);
-
- continue;
- }
- }
-
- if (ls[i].add_deferred) {
- ls[i].deferred_accept = 1;
- }
-
-#endif
-
-#endif /* NGX_HAVE_DEFERRED_ACCEPT */
- }
-
- return;
-}
-
-
-void
-ngx_close_listening_sockets(ngx_cycle_t *cycle)
-{
- ngx_uint_t i;
- ngx_listening_t *ls;
- ngx_connection_t *c;
-
- if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
- return;
- }
-
- ngx_accept_mutex_held = 0;
- ngx_use_accept_mutex = 0;
-
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
-
- c = ls[i].connection;
-
- if (c) {
- if (c->read->active) {
- if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
- ngx_del_conn(c, NGX_CLOSE_EVENT);
-
- } else if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
-
- /*
- * it seems that Linux-2.6.x OpenVZ sends events
- * for closed shared listening sockets unless
- * the events was explicitly deleted
- */
-
- ngx_del_event(c->read, NGX_READ_EVENT, 0);
-
- } else {
- ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
- }
- }
-
- ngx_free_connection(c);
-
- c->fd = (ngx_socket_t) -1;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
- "close listening %V #%d ", &ls[i].addr_text, ls[i].fd);
-
- if (ngx_close_socket(ls[i].fd) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
- ngx_close_socket_n " %V failed", &ls[i].addr_text);
- }
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-
- if (ls[i].sockaddr->sa_family == AF_UNIX
- && ngx_process <= NGX_PROCESS_MASTER
- && ngx_new_binary == 0)
- {
- u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1;
-
- if (ngx_delete_file(name) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
- ngx_delete_file_n " %s failed", name);
- }
- }
-
-#endif
-
- ls[i].fd = (ngx_socket_t) -1;
- }
-
- cycle->listening.nelts = 0;
-}
-
-
-ngx_connection_t *
-ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
-{
- ngx_uint_t instance;
- ngx_event_t *rev, *wev;
- ngx_connection_t *c;
-
- /* disable warning: Win32 SOCKET is u_int while UNIX socket is int */
-
- if (ngx_cycle->files && (ngx_uint_t) s >= ngx_cycle->files_n) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- "the new socket has number %d, "
- "but only %ui files are available",
- s, ngx_cycle->files_n);
- return NULL;
- }
-
- /* ngx_mutex_lock */
-
- c = ngx_cycle->free_connections;
-
- if (c == NULL) {
- ngx_drain_connections();
- c = ngx_cycle->free_connections;
- }
-
- if (c == NULL) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- "%ui worker_connections are not enough",
- ngx_cycle->connection_n);
-
- /* ngx_mutex_unlock */
-
- return NULL;
- }
-
- ngx_cycle->free_connections = c->data;
- ngx_cycle->free_connection_n--;
-
- /* ngx_mutex_unlock */
-
- if (ngx_cycle->files) {
- ngx_cycle->files[s] = c;
- }
-
- rev = c->read;
- wev = c->write;
-
- ngx_memzero(c, sizeof(ngx_connection_t));
-
- c->read = rev;
- c->write = wev;
- c->fd = s;
- c->log = log;
-
- instance = rev->instance;
-
- ngx_memzero(rev, sizeof(ngx_event_t));
- ngx_memzero(wev, sizeof(ngx_event_t));
-
- rev->instance = !instance;
- wev->instance = !instance;
-
- rev->index = NGX_INVALID_INDEX;
- wev->index = NGX_INVALID_INDEX;
-
- rev->data = c;
- wev->data = c;
-
- wev->write = 1;
-
- return c;
-}
-
-
-void
-ngx_free_connection(ngx_connection_t *c)
-{
- /* ngx_mutex_lock */
-
- c->data = ngx_cycle->free_connections;
- ngx_cycle->free_connections = c;
- ngx_cycle->free_connection_n++;
-
- /* ngx_mutex_unlock */
-
- if (ngx_cycle->files) {
- ngx_cycle->files[c->fd] = NULL;
- }
-}
-
-
-void
-ngx_close_connection(ngx_connection_t *c)
-{
- ngx_err_t err;
- ngx_uint_t log_error, level;
- ngx_socket_t fd;
-
- if (c->fd == (ngx_socket_t) -1) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
- return;
- }
-
- if (c->read->timer_set) {
- ngx_del_timer(c->read);
- }
-
- if (c->write->timer_set) {
- ngx_del_timer(c->write);
- }
-
- if (ngx_del_conn) {
- ngx_del_conn(c, NGX_CLOSE_EVENT);
-
- } else {
- if (c->read->active || c->read->disabled) {
- ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT);
- }
-
- if (c->write->active || c->write->disabled) {
- ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT);
- }
- }
-
-#if (NGX_THREADS)
-
- /*
- * we have to clean the connection information before the closing
- * because another thread may reopen the same file descriptor
- * before we clean the connection
- */
-
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- if (c->read->prev) {
- ngx_delete_posted_event(c->read);
- }
-
- if (c->write->prev) {
- ngx_delete_posted_event(c->write);
- }
-
- c->read->closed = 1;
- c->write->closed = 1;
-
- ngx_unlock(&c->lock);
- c->read->locked = 0;
- c->write->locked = 0;
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
-#else
-
- if (c->read->prev) {
- ngx_delete_posted_event(c->read);
- }
-
- if (c->write->prev) {
- ngx_delete_posted_event(c->write);
- }
-
- c->read->closed = 1;
- c->write->closed = 1;
-
-#endif
-
- ngx_reusable_connection(c, 0);
-
- log_error = c->log_error;
-
- ngx_free_connection(c);
-
- fd = c->fd;
- c->fd = (ngx_socket_t) -1;
-
- if (ngx_close_socket(fd) == -1) {
-
- err = ngx_socket_errno;
-
- if (err == NGX_ECONNRESET || err == NGX_ENOTCONN) {
-
- switch (log_error) {
-
- case NGX_ERROR_INFO:
- level = NGX_LOG_INFO;
- break;
-
- case NGX_ERROR_ERR:
- level = NGX_LOG_ERR;
- break;
-
- default:
- level = NGX_LOG_CRIT;
- }
-
- } else {
- level = NGX_LOG_CRIT;
- }
-
- /* we use ngx_cycle->log because c->log was in c->pool */
-
- ngx_log_error(level, ngx_cycle->log, err,
- ngx_close_socket_n " %d failed", fd);
- }
-}
-
-
-void
-ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable)
-{
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
- "reusable connection: %ui", reusable);
-
- if (c->reusable) {
- ngx_queue_remove(&c->queue);
-
-#if (NGX_STAT_STUB)
- (void) ngx_atomic_fetch_add(ngx_stat_waiting, -1);
-#endif
- }
-
- c->reusable = reusable;
-
- if (reusable) {
- /* need cast as ngx_cycle is volatile */
-
- ngx_queue_insert_head(
- (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue);
-
-#if (NGX_STAT_STUB)
- (void) ngx_atomic_fetch_add(ngx_stat_waiting, 1);
-#endif
- }
-}
-
-
-static void
-ngx_drain_connections(void)
-{
- ngx_int_t i;
- ngx_queue_t *q;
- ngx_connection_t *c;
-
- for (i = 0; i < 32; i++) {
- if (ngx_queue_empty(&ngx_cycle->reusable_connections_queue)) {
- break;
- }
-
- q = ngx_queue_last(&ngx_cycle->reusable_connections_queue);
- c = ngx_queue_data(q, ngx_connection_t, queue);
-
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
- "reusing connection");
-
- c->close = 1;
- c->read->handler(c->read);
- }
-}
-
-
-ngx_int_t
-ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
- ngx_uint_t port)
-{
- socklen_t len;
- ngx_uint_t addr;
- u_char sa[NGX_SOCKADDRLEN];
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- ngx_uint_t i;
- struct sockaddr_in6 *sin6;
-#endif
-
- if (c->local_socklen == 0) {
- return NGX_ERROR;
- }
-
- switch (c->local_sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
-
- for (addr = 0, i = 0; addr == 0 && i < 16; i++) {
- addr |= sin6->sin6_addr.s6_addr[i];
- }
-
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- addr = 1;
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) c->local_sockaddr;
- addr = sin->sin_addr.s_addr;
- break;
- }
-
- if (addr == 0) {
-
- len = NGX_SOCKADDRLEN;
-
- if (getsockname(c->fd, (struct sockaddr *) &sa, &len) == -1) {
- ngx_connection_error(c, ngx_socket_errno, "getsockname() failed");
- return NGX_ERROR;
- }
-
- c->local_sockaddr = ngx_palloc(c->pool, len);
- if (c->local_sockaddr == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(c->local_sockaddr, &sa, len);
-
- c->local_socklen = len;
- }
-
- if (s == NULL) {
- return NGX_OK;
- }
-
- s->len = ngx_sock_ntop(c->local_sockaddr, c->local_socklen,
- s->data, s->len, port);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
-{
- ngx_uint_t level;
-
- /* Winsock may return NGX_ECONNABORTED instead of NGX_ECONNRESET */
-
- if ((err == NGX_ECONNRESET
-#if (NGX_WIN32)
- || err == NGX_ECONNABORTED
-#endif
- ) && c->log_error == NGX_ERROR_IGNORE_ECONNRESET)
- {
- return 0;
- }
-
-#if (NGX_SOLARIS)
- if (err == NGX_EINVAL && c->log_error == NGX_ERROR_IGNORE_EINVAL) {
- return 0;
- }
-#endif
-
- if (err == 0
- || err == NGX_ECONNRESET
-#if (NGX_WIN32)
- || err == NGX_ECONNABORTED
-#else
- || err == NGX_EPIPE
-#endif
- || err == NGX_ENOTCONN
- || err == NGX_ETIMEDOUT
- || err == NGX_ECONNREFUSED
- || err == NGX_ENETDOWN
- || err == NGX_ENETUNREACH
- || err == NGX_EHOSTDOWN
- || err == NGX_EHOSTUNREACH)
- {
- switch (c->log_error) {
-
- case NGX_ERROR_IGNORE_EINVAL:
- case NGX_ERROR_IGNORE_ECONNRESET:
- case NGX_ERROR_INFO:
- level = NGX_LOG_INFO;
- break;
-
- default:
- level = NGX_LOG_ERR;
- }
-
- } else {
- level = NGX_LOG_ALERT;
- }
-
- ngx_log_error(level, c->log, err, text);
-
- return NGX_ERROR;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_connection.h b/usr.sbin/nginx/src/core/ngx_connection.h
deleted file mode 100644
index ed14e6023e7..00000000000
--- a/usr.sbin/nginx/src/core/ngx_connection.h
+++ /dev/null
@@ -1,211 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_CONNECTION_H_INCLUDED_
-#define _NGX_CONNECTION_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef struct ngx_listening_s ngx_listening_t;
-
-struct ngx_listening_s {
- ngx_socket_t fd;
-
- struct sockaddr *sockaddr;
- socklen_t socklen; /* size of sockaddr */
- size_t addr_text_max_len;
- ngx_str_t addr_text;
-
- int type;
-
- int backlog;
- int rcvbuf;
- int sndbuf;
-#if (NGX_HAVE_KEEPALIVE_TUNABLE)
- int keepidle;
- int keepintvl;
- int keepcnt;
-#endif
-
- /* handler of accepted connection */
- ngx_connection_handler_pt handler;
-
- void *servers; /* array of ngx_http_in_addr_t, for example */
-
- ngx_log_t log;
- ngx_log_t *logp;
-
- size_t pool_size;
- /* should be here because of the AcceptEx() preread */
- size_t post_accept_buffer_size;
- /* should be here because of the deferred accept */
- ngx_msec_t post_accept_timeout;
-
- ngx_listening_t *previous;
- ngx_connection_t *connection;
-
- unsigned open:1;
- unsigned remain:1;
- unsigned ignore:1;
-
- unsigned bound:1; /* already bound */
- unsigned inherited:1; /* inherited from previous process */
- unsigned nonblocking_accept:1;
- unsigned listen:1;
- unsigned nonblocking:1;
- unsigned shared:1; /* shared between threads or processes */
- unsigned addr_ntop:1;
-
-#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- unsigned ipv6only:1;
-#endif
- unsigned keepalive:2;
-
-#if (NGX_HAVE_DEFERRED_ACCEPT)
- unsigned deferred_accept:1;
- unsigned delete_deferred:1;
- unsigned add_deferred:1;
-#ifdef SO_ACCEPTFILTER
- char *accept_filter;
-#endif
-#endif
-#if (NGX_HAVE_SETFIB)
- int setfib;
-#endif
-
-#if (NGX_HAVE_TCP_FASTOPEN)
- int fastopen;
-#endif
-
-};
-
-
-typedef enum {
- NGX_ERROR_ALERT = 0,
- NGX_ERROR_ERR,
- NGX_ERROR_INFO,
- NGX_ERROR_IGNORE_ECONNRESET,
- NGX_ERROR_IGNORE_EINVAL
-} ngx_connection_log_error_e;
-
-
-typedef enum {
- NGX_TCP_NODELAY_UNSET = 0,
- NGX_TCP_NODELAY_SET,
- NGX_TCP_NODELAY_DISABLED
-} ngx_connection_tcp_nodelay_e;
-
-
-typedef enum {
- NGX_TCP_NOPUSH_UNSET = 0,
- NGX_TCP_NOPUSH_SET,
- NGX_TCP_NOPUSH_DISABLED
-} ngx_connection_tcp_nopush_e;
-
-
-#define NGX_LOWLEVEL_BUFFERED 0x0f
-#define NGX_SSL_BUFFERED 0x01
-#define NGX_SPDY_BUFFERED 0x02
-
-
-struct ngx_connection_s {
- void *data;
- ngx_event_t *read;
- ngx_event_t *write;
-
- ngx_socket_t fd;
-
- ngx_recv_pt recv;
- ngx_send_pt send;
- ngx_recv_chain_pt recv_chain;
- ngx_send_chain_pt send_chain;
-
- ngx_listening_t *listening;
-
- off_t sent;
-
- ngx_log_t *log;
-
- ngx_pool_t *pool;
-
- struct sockaddr *sockaddr;
- socklen_t socklen;
- ngx_str_t addr_text;
-
- ngx_str_t proxy_protocol_addr;
-
-#if (NGX_SSL)
- ngx_ssl_connection_t *ssl;
-#endif
-
- struct sockaddr *local_sockaddr;
- socklen_t local_socklen;
-
- ngx_buf_t *buffer;
-
- ngx_queue_t queue;
-
- ngx_atomic_uint_t number;
-
- ngx_uint_t requests;
-
- unsigned buffered:8;
-
- unsigned log_error:3; /* ngx_connection_log_error_e */
-
- unsigned unexpected_eof:1;
- unsigned timedout:1;
- unsigned error:1;
- unsigned destroyed:1;
-
- unsigned idle:1;
- unsigned reusable:1;
- unsigned close:1;
-
- unsigned sendfile:1;
- unsigned sndlowat:1;
- unsigned tcp_nodelay:2; /* ngx_connection_tcp_nodelay_e */
- unsigned tcp_nopush:2; /* ngx_connection_tcp_nopush_e */
-
- unsigned need_last_buf:1;
-
-#if (NGX_HAVE_IOCP)
- unsigned accept_context_updated:1;
-#endif
-
-#if (NGX_HAVE_AIO_SENDFILE)
- unsigned aio_sendfile:1;
- unsigned busy_count:2;
- ngx_buf_t *busy_sendfile;
-#endif
-
-#if (NGX_THREADS)
- ngx_atomic_t lock;
-#endif
-};
-
-
-ngx_listening_t *ngx_create_listening(ngx_conf_t *cf, void *sockaddr,
- socklen_t socklen);
-ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle);
-ngx_int_t ngx_open_listening_sockets(ngx_cycle_t *cycle);
-void ngx_configure_listening_sockets(ngx_cycle_t *cycle);
-void ngx_close_listening_sockets(ngx_cycle_t *cycle);
-void ngx_close_connection(ngx_connection_t *c);
-ngx_int_t ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
- ngx_uint_t port);
-ngx_int_t ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text);
-
-ngx_connection_t *ngx_get_connection(ngx_socket_t s, ngx_log_t *log);
-void ngx_free_connection(ngx_connection_t *c);
-
-void ngx_reusable_connection(ngx_connection_t *c, ngx_uint_t reusable);
-
-#endif /* _NGX_CONNECTION_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_core.h b/usr.sbin/nginx/src/core/ngx_core.h
deleted file mode 100644
index c479a59546d..00000000000
--- a/usr.sbin/nginx/src/core/ngx_core.h
+++ /dev/null
@@ -1,101 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_CORE_H_INCLUDED_
-#define _NGX_CORE_H_INCLUDED_
-
-
-typedef struct ngx_module_s ngx_module_t;
-typedef struct ngx_conf_s ngx_conf_t;
-typedef struct ngx_cycle_s ngx_cycle_t;
-typedef struct ngx_pool_s ngx_pool_t;
-typedef struct ngx_chain_s ngx_chain_t;
-typedef struct ngx_log_s ngx_log_t;
-typedef struct ngx_open_file_s ngx_open_file_t;
-typedef struct ngx_command_s ngx_command_t;
-typedef struct ngx_file_s ngx_file_t;
-typedef struct ngx_event_s ngx_event_t;
-typedef struct ngx_event_aio_s ngx_event_aio_t;
-typedef struct ngx_connection_s ngx_connection_t;
-
-typedef void (*ngx_event_handler_pt)(ngx_event_t *ev);
-typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
-
-
-#define NGX_OK 0
-#define NGX_ERROR -1
-#define NGX_AGAIN -2
-#define NGX_BUSY -3
-#define NGX_DONE -4
-#define NGX_DECLINED -5
-#define NGX_ABORT -6
-
-
-#include <ngx_errno.h>
-#include <ngx_atomic.h>
-#include <ngx_thread.h>
-#include <ngx_rbtree.h>
-#include <ngx_time.h>
-#include <ngx_socket.h>
-#include <ngx_string.h>
-#include <ngx_files.h>
-#include <ngx_shmem.h>
-#include <ngx_process.h>
-#include <ngx_user.h>
-#include <ngx_parse.h>
-#include <ngx_log.h>
-#include <ngx_alloc.h>
-#include <ngx_palloc.h>
-#include <ngx_buf.h>
-#include <ngx_queue.h>
-#include <ngx_array.h>
-#include <ngx_list.h>
-#include <ngx_hash.h>
-#include <ngx_file.h>
-#include <ngx_crc.h>
-#include <ngx_crc32.h>
-#include <ngx_murmurhash.h>
-#if (NGX_PCRE)
-#include <ngx_regex.h>
-#endif
-#include <ngx_radix_tree.h>
-#include <ngx_times.h>
-#include <ngx_shmtx.h>
-#include <ngx_slab.h>
-#include <ngx_inet.h>
-#include <ngx_cycle.h>
-#include <ngx_resolver.h>
-#if (NGX_OPENSSL)
-#include <ngx_event_openssl.h>
-#endif
-#include <ngx_process_cycle.h>
-#include <ngx_conf_file.h>
-#include <ngx_open_file_cache.h>
-#include <ngx_os.h>
-#include <ngx_connection.h>
-#include <ngx_syslog.h>
-#include <ngx_proxy_protocol.h>
-
-
-#define LF (u_char) 10
-#define CR (u_char) 13
-#define CRLF "\x0d\x0a"
-
-
-#define ngx_abs(value) (((value) >= 0) ? (value) : - (value))
-#define ngx_max(val1, val2) ((val1 < val2) ? (val2) : (val1))
-#define ngx_min(val1, val2) ((val1 > val2) ? (val2) : (val1))
-
-void ngx_cpuinfo(void);
-
-#if (NGX_HAVE_OPENAT)
-#define NGX_DISABLE_SYMLINKS_OFF 0
-#define NGX_DISABLE_SYMLINKS_ON 1
-#define NGX_DISABLE_SYMLINKS_NOTOWNER 2
-#endif
-
-#endif /* _NGX_CORE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_cpuinfo.c b/usr.sbin/nginx/src/core/ngx_cpuinfo.c
deleted file mode 100644
index 72053192ffa..00000000000
--- a/usr.sbin/nginx/src/core/ngx_cpuinfo.c
+++ /dev/null
@@ -1,139 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#if (( __i386__ || __amd64__ ) && ( __GNUC__ || __INTEL_COMPILER ))
-
-
-static ngx_inline void ngx_cpuid(uint32_t i, uint32_t *buf);
-
-
-#if ( __i386__ )
-
-static ngx_inline void
-ngx_cpuid(uint32_t i, uint32_t *buf)
-{
-
- /*
- * we could not use %ebx as output parameter if gcc builds PIC,
- * and we could not save %ebx on stack, because %esp is used,
- * when the -fomit-frame-pointer optimization is specified.
- */
-
- __asm__ (
-
- " mov %%ebx, %%esi; "
-
- " cpuid; "
- " mov %%eax, (%1); "
- " mov %%ebx, 4(%1); "
- " mov %%edx, 8(%1); "
- " mov %%ecx, 12(%1); "
-
- " mov %%esi, %%ebx; "
-
- : : "a" (i), "D" (buf) : "ecx", "edx", "esi", "memory" );
-}
-
-
-#else /* __amd64__ */
-
-
-static ngx_inline void
-ngx_cpuid(uint32_t i, uint32_t *buf)
-{
- uint32_t eax, ebx, ecx, edx;
-
- __asm__ (
-
- "cpuid"
-
- : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (i) );
-
- buf[0] = eax;
- buf[1] = ebx;
- buf[2] = edx;
- buf[3] = ecx;
-}
-
-
-#endif
-
-
-/* auto detect the L2 cache line size of modern and widespread CPUs */
-
-void
-ngx_cpuinfo(void)
-{
- u_char *vendor;
- uint32_t vbuf[5], cpu[4], model;
-
- vbuf[0] = 0;
- vbuf[1] = 0;
- vbuf[2] = 0;
- vbuf[3] = 0;
- vbuf[4] = 0;
-
- ngx_cpuid(0, vbuf);
-
- vendor = (u_char *) &vbuf[1];
-
- if (vbuf[0] == 0) {
- return;
- }
-
- ngx_cpuid(1, cpu);
-
- if (ngx_strcmp(vendor, "GenuineIntel") == 0) {
-
- switch ((cpu[0] & 0xf00) >> 8) {
-
- /* Pentium */
- case 5:
- ngx_cacheline_size = 32;
- break;
-
- /* Pentium Pro, II, III */
- case 6:
- ngx_cacheline_size = 32;
-
- model = ((cpu[0] & 0xf0000) >> 8) | (cpu[0] & 0xf0);
-
- if (model >= 0xd0) {
- /* Intel Core, Core 2, Atom */
- ngx_cacheline_size = 64;
- }
-
- break;
-
- /*
- * Pentium 4, although its cache line size is 64 bytes,
- * it prefetches up to two cache lines during memory read
- */
- case 15:
- ngx_cacheline_size = 128;
- break;
- }
-
- } else if (ngx_strcmp(vendor, "AuthenticAMD") == 0) {
- ngx_cacheline_size = 64;
- }
-}
-
-#else
-
-
-void
-ngx_cpuinfo(void)
-{
-}
-
-
-#endif
diff --git a/usr.sbin/nginx/src/core/ngx_crc.h b/usr.sbin/nginx/src/core/ngx_crc.h
deleted file mode 100644
index 35981bc15a7..00000000000
--- a/usr.sbin/nginx/src/core/ngx_crc.h
+++ /dev/null
@@ -1,39 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_CRC_H_INCLUDED_
-#define _NGX_CRC_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/* 32-bit crc16 */
-
-static ngx_inline uint32_t
-ngx_crc(u_char *data, size_t len)
-{
- uint32_t sum;
-
- for (sum = 0; len; len--) {
-
- /*
- * gcc 2.95.2 x86 and icc 7.1.006 compile
- * that operator into the single "rol" opcode,
- * msvc 6.0sp2 compiles it into four opcodes.
- */
- sum = sum >> 1 | sum << 31;
-
- sum += *data++;
- }
-
- return sum;
-}
-
-
-#endif /* _NGX_CRC_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_crc32.c b/usr.sbin/nginx/src/core/ngx_crc32.c
deleted file mode 100644
index a5b4017b87d..00000000000
--- a/usr.sbin/nginx/src/core/ngx_crc32.c
+++ /dev/null
@@ -1,129 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/*
- * The code and lookup tables are based on the algorithm
- * described at http://www.w3.org/TR/PNG/
- *
- * The 256 element lookup table takes 1024 bytes, and it may be completely
- * cached after processing about 30-60 bytes of data. So for short data
- * we use the 16 element lookup table that takes only 64 bytes and align it
- * to CPU cache line size. Of course, the small table adds code inside
- * CRC32 loop, but the cache misses overhead is bigger than overhead of
- * the additional code. For example, ngx_crc32_short() of 16 bytes of data
- * takes half as much CPU clocks than ngx_crc32_long().
- */
-
-
-static uint32_t ngx_crc32_table16[] = {
- 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
- 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
- 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
- 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
-};
-
-
-uint32_t ngx_crc32_table256[] = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
- 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
- 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
- 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
- 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
- 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
- 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
- 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
- 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
- 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
- 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
- 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
- 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
- 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
- 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
- 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
- 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
- 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
- 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
- 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
- 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
- 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
- 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
- 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
- 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
- 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
- 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
- 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
- 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
- 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
- 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
- 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
- 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
- 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
- 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
- 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
- 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
- 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
- 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
- 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
- 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
- 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
- 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
-};
-
-
-uint32_t *ngx_crc32_table_short = ngx_crc32_table16;
-
-
-ngx_int_t
-ngx_crc32_table_init(void)
-{
- void *p;
-
- if (((uintptr_t) ngx_crc32_table_short
- & ~((uintptr_t) ngx_cacheline_size - 1))
- == (uintptr_t) ngx_crc32_table_short)
- {
- return NGX_OK;
- }
-
- p = ngx_alloc(16 * sizeof(uint32_t) + ngx_cacheline_size, ngx_cycle->log);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- p = ngx_align_ptr(p, ngx_cacheline_size);
-
- ngx_memcpy(p, ngx_crc32_table16, 16 * sizeof(uint32_t));
-
- ngx_crc32_table_short = p;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_crc32.h b/usr.sbin/nginx/src/core/ngx_crc32.h
deleted file mode 100644
index f6d6865b5aa..00000000000
--- a/usr.sbin/nginx/src/core/ngx_crc32.h
+++ /dev/null
@@ -1,79 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_CRC32_H_INCLUDED_
-#define _NGX_CRC32_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-extern uint32_t *ngx_crc32_table_short;
-extern uint32_t ngx_crc32_table256[];
-
-
-static ngx_inline uint32_t
-ngx_crc32_short(u_char *p, size_t len)
-{
- u_char c;
- uint32_t crc;
-
- crc = 0xffffffff;
-
- while (len--) {
- c = *p++;
- crc = ngx_crc32_table_short[(crc ^ (c & 0xf)) & 0xf] ^ (crc >> 4);
- crc = ngx_crc32_table_short[(crc ^ (c >> 4)) & 0xf] ^ (crc >> 4);
- }
-
- return crc ^ 0xffffffff;
-}
-
-
-static ngx_inline uint32_t
-ngx_crc32_long(u_char *p, size_t len)
-{
- uint32_t crc;
-
- crc = 0xffffffff;
-
- while (len--) {
- crc = ngx_crc32_table256[(crc ^ *p++) & 0xff] ^ (crc >> 8);
- }
-
- return crc ^ 0xffffffff;
-}
-
-
-#define ngx_crc32_init(crc) \
- crc = 0xffffffff
-
-
-static ngx_inline void
-ngx_crc32_update(uint32_t *crc, u_char *p, size_t len)
-{
- uint32_t c;
-
- c = *crc;
-
- while (len--) {
- c = ngx_crc32_table256[(c ^ *p++) & 0xff] ^ (c >> 8);
- }
-
- *crc = c;
-}
-
-
-#define ngx_crc32_final(crc) \
- crc ^= 0xffffffff
-
-
-ngx_int_t ngx_crc32_table_init(void);
-
-
-#endif /* _NGX_CRC32_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_crypt.c b/usr.sbin/nginx/src/core/ngx_crypt.c
deleted file mode 100644
index e2376c6f1e1..00000000000
--- a/usr.sbin/nginx/src/core/ngx_crypt.c
+++ /dev/null
@@ -1,283 +0,0 @@
-
-/*
- * Copyright (C) Maxim Dounin
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_crypt.h>
-#include <ngx_md5.h>
-#if (NGX_HAVE_SHA1)
-#include <ngx_sha1.h>
-#endif
-
-
-#if (NGX_CRYPT)
-
-static ngx_int_t ngx_crypt_apr1(ngx_pool_t *pool, u_char *key, u_char *salt,
- u_char **encrypted);
-static ngx_int_t ngx_crypt_plain(ngx_pool_t *pool, u_char *key, u_char *salt,
- u_char **encrypted);
-
-#if (NGX_HAVE_SHA1)
-
-static ngx_int_t ngx_crypt_ssha(ngx_pool_t *pool, u_char *key, u_char *salt,
- u_char **encrypted);
-static ngx_int_t ngx_crypt_sha(ngx_pool_t *pool, u_char *key, u_char *salt,
- u_char **encrypted);
-
-#endif
-
-
-static u_char *ngx_crypt_to64(u_char *p, uint32_t v, size_t n);
-
-
-ngx_int_t
-ngx_crypt(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
-{
- if (ngx_strncmp(salt, "$apr1$", sizeof("$apr1$") - 1) == 0) {
- return ngx_crypt_apr1(pool, key, salt, encrypted);
-
- } else if (ngx_strncmp(salt, "{PLAIN}", sizeof("{PLAIN}") - 1) == 0) {
- return ngx_crypt_plain(pool, key, salt, encrypted);
-
-#if (NGX_HAVE_SHA1)
- } else if (ngx_strncmp(salt, "{SSHA}", sizeof("{SSHA}") - 1) == 0) {
- return ngx_crypt_ssha(pool, key, salt, encrypted);
-
- } else if (ngx_strncmp(salt, "{SHA}", sizeof("{SHA}") - 1) == 0) {
- return ngx_crypt_sha(pool, key, salt, encrypted);
-#endif
- }
-
- /* fallback to libc crypt() */
-
- return ngx_libc_crypt(pool, key, salt, encrypted);
-}
-
-
-static ngx_int_t
-ngx_crypt_apr1(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
-{
- ngx_int_t n;
- ngx_uint_t i;
- u_char *p, *last, final[16];
- size_t saltlen, keylen;
- ngx_md5_t md5, ctx1;
-
- /* Apache's apr1 crypt is Paul-Henning Kamp's md5 crypt with $apr1$ magic */
-
- keylen = ngx_strlen(key);
-
- /* true salt: no magic, max 8 chars, stop at first $ */
-
- salt += sizeof("$apr1$") - 1;
- last = salt + 8;
- for (p = salt; *p && *p != '$' && p < last; p++) { /* void */ }
- saltlen = p - salt;
-
- /* hash key and salt */
-
- ngx_md5_init(&md5);
- ngx_md5_update(&md5, key, keylen);
- ngx_md5_update(&md5, (u_char *) "$apr1$", sizeof("$apr1$") - 1);
- ngx_md5_update(&md5, salt, saltlen);
-
- ngx_md5_init(&ctx1);
- ngx_md5_update(&ctx1, key, keylen);
- ngx_md5_update(&ctx1, salt, saltlen);
- ngx_md5_update(&ctx1, key, keylen);
- ngx_md5_final(final, &ctx1);
-
- for (n = keylen; n > 0; n -= 16) {
- ngx_md5_update(&md5, final, n > 16 ? 16 : n);
- }
-
- ngx_memzero(final, sizeof(final));
-
- for (i = keylen; i; i >>= 1) {
- if (i & 1) {
- ngx_md5_update(&md5, final, 1);
-
- } else {
- ngx_md5_update(&md5, key, 1);
- }
- }
-
- ngx_md5_final(final, &md5);
-
- for (i = 0; i < 1000; i++) {
- ngx_md5_init(&ctx1);
-
- if (i & 1) {
- ngx_md5_update(&ctx1, key, keylen);
-
- } else {
- ngx_md5_update(&ctx1, final, 16);
- }
-
- if (i % 3) {
- ngx_md5_update(&ctx1, salt, saltlen);
- }
-
- if (i % 7) {
- ngx_md5_update(&ctx1, key, keylen);
- }
-
- if (i & 1) {
- ngx_md5_update(&ctx1, final, 16);
-
- } else {
- ngx_md5_update(&ctx1, key, keylen);
- }
-
- ngx_md5_final(final, &ctx1);
- }
-
- /* output */
-
- *encrypted = ngx_pnalloc(pool, sizeof("$apr1$") - 1 + saltlen + 1 + 22 + 1);
- if (*encrypted == NULL) {
- return NGX_ERROR;
- }
-
- p = ngx_cpymem(*encrypted, "$apr1$", sizeof("$apr1$") - 1);
- p = ngx_copy(p, salt, saltlen);
- *p++ = '$';
-
- p = ngx_crypt_to64(p, (final[ 0]<<16) | (final[ 6]<<8) | final[12], 4);
- p = ngx_crypt_to64(p, (final[ 1]<<16) | (final[ 7]<<8) | final[13], 4);
- p = ngx_crypt_to64(p, (final[ 2]<<16) | (final[ 8]<<8) | final[14], 4);
- p = ngx_crypt_to64(p, (final[ 3]<<16) | (final[ 9]<<8) | final[15], 4);
- p = ngx_crypt_to64(p, (final[ 4]<<16) | (final[10]<<8) | final[ 5], 4);
- p = ngx_crypt_to64(p, final[11], 2);
- *p = '\0';
-
- return NGX_OK;
-}
-
-
-static u_char *
-ngx_crypt_to64(u_char *p, uint32_t v, size_t n)
-{
- static u_char itoa64[] =
- "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
- while (n--) {
- *p++ = itoa64[v & 0x3f];
- v >>= 6;
- }
-
- return p;
-}
-
-
-static ngx_int_t
-ngx_crypt_plain(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
-{
- size_t len;
- u_char *p;
-
- len = ngx_strlen(key);
-
- *encrypted = ngx_pnalloc(pool, sizeof("{PLAIN}") - 1 + len + 1);
- if (*encrypted == NULL) {
- return NGX_ERROR;
- }
-
- p = ngx_cpymem(*encrypted, "{PLAIN}", sizeof("{PLAIN}") - 1);
- ngx_memcpy(p, key, len + 1);
-
- return NGX_OK;
-}
-
-
-#if (NGX_HAVE_SHA1)
-
-static ngx_int_t
-ngx_crypt_ssha(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
-{
- size_t len;
- ngx_int_t rc;
- ngx_str_t encoded, decoded;
- ngx_sha1_t sha1;
-
- /* "{SSHA}" base64(SHA1(key salt) salt) */
-
- /* decode base64 salt to find out true salt */
-
- encoded.data = salt + sizeof("{SSHA}") - 1;
- encoded.len = ngx_strlen(encoded.data);
-
- len = ngx_max(ngx_base64_decoded_length(encoded.len), 20);
-
- decoded.data = ngx_pnalloc(pool, len);
- if (decoded.data == NULL) {
- return NGX_ERROR;
- }
-
- rc = ngx_decode_base64(&decoded, &encoded);
-
- if (rc != NGX_OK || decoded.len < 20) {
- decoded.len = 20;
- }
-
- /* update SHA1 from key and salt */
-
- ngx_sha1_init(&sha1);
- ngx_sha1_update(&sha1, key, ngx_strlen(key));
- ngx_sha1_update(&sha1, decoded.data + 20, decoded.len - 20);
- ngx_sha1_final(decoded.data, &sha1);
-
- /* encode it back to base64 */
-
- len = sizeof("{SSHA}") - 1 + ngx_base64_encoded_length(decoded.len) + 1;
-
- *encrypted = ngx_pnalloc(pool, len);
- if (*encrypted == NULL) {
- return NGX_ERROR;
- }
-
- encoded.data = ngx_cpymem(*encrypted, "{SSHA}", sizeof("{SSHA}") - 1);
- ngx_encode_base64(&encoded, &decoded);
- encoded.data[encoded.len] = '\0';
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_crypt_sha(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
-{
- size_t len;
- ngx_str_t encoded, decoded;
- ngx_sha1_t sha1;
- u_char digest[20];
-
- /* "{SHA}" base64(SHA1(key)) */
-
- decoded.len = sizeof(digest);
- decoded.data = digest;
-
- ngx_sha1_init(&sha1);
- ngx_sha1_update(&sha1, key, ngx_strlen(key));
- ngx_sha1_final(digest, &sha1);
-
- len = sizeof("{SHA}") - 1 + ngx_base64_encoded_length(decoded.len) + 1;
-
- *encrypted = ngx_pnalloc(pool, len);
- if (*encrypted == NULL) {
- return NGX_ERROR;
- }
-
- encoded.data = ngx_cpymem(*encrypted, "{SHA}", sizeof("{SHA}") - 1);
- ngx_encode_base64(&encoded, &decoded);
- encoded.data[encoded.len] = '\0';
-
- return NGX_OK;
-}
-
-#endif /* NGX_HAVE_SHA1 */
-
-#endif /* NGX_CRYPT */
diff --git a/usr.sbin/nginx/src/core/ngx_crypt.h b/usr.sbin/nginx/src/core/ngx_crypt.h
deleted file mode 100644
index 386911428ac..00000000000
--- a/usr.sbin/nginx/src/core/ngx_crypt.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_CRYPT_H_INCLUDED_
-#define _NGX_CRYPT_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-ngx_int_t ngx_crypt(ngx_pool_t *pool, u_char *key, u_char *salt,
- u_char **encrypted);
-
-
-#endif /* _NGX_CRYPT_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_cycle.c b/usr.sbin/nginx/src/core/ngx_cycle.c
deleted file mode 100644
index aa42406ffe3..00000000000
--- a/usr.sbin/nginx/src/core/ngx_cycle.c
+++ /dev/null
@@ -1,1294 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-static void ngx_destroy_cycle_pools(ngx_conf_t *conf);
-static ngx_int_t ngx_init_zone_pool(ngx_cycle_t *cycle,
- ngx_shm_zone_t *shm_zone);
-static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log);
-static void ngx_clean_old_cycles(ngx_event_t *ev);
-
-
-volatile ngx_cycle_t *ngx_cycle;
-ngx_array_t ngx_old_cycles;
-
-static ngx_pool_t *ngx_temp_pool;
-static ngx_event_t ngx_cleaner_event;
-
-ngx_uint_t ngx_test_config;
-ngx_uint_t ngx_quiet_mode;
-
-#if (NGX_THREADS)
-ngx_tls_key_t ngx_core_tls_key;
-#endif
-
-
-/* STUB NAME */
-static ngx_connection_t dumb;
-/* STUB */
-
-
-ngx_cycle_t *
-ngx_init_cycle(ngx_cycle_t *old_cycle)
-{
- void *rv;
- char **senv, **env;
- ngx_uint_t i, n;
- ngx_log_t *log;
- ngx_time_t *tp;
- ngx_conf_t conf;
- ngx_pool_t *pool;
- ngx_cycle_t *cycle, **old;
- ngx_shm_zone_t *shm_zone, *oshm_zone;
- ngx_list_part_t *part, *opart;
- ngx_open_file_t *file;
- ngx_listening_t *ls, *nls;
- ngx_core_conf_t *ccf, *old_ccf;
- ngx_core_module_t *module;
- char hostname[NGX_MAXHOSTNAMELEN];
-
- ngx_timezone_update();
-
- /* force localtime update with a new timezone */
-
- tp = ngx_timeofday();
- tp->sec = 0;
-
- ngx_time_update();
-
-
- log = old_cycle->log;
-
- pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
- if (pool == NULL) {
- return NULL;
- }
- pool->log = log;
-
- cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
- if (cycle == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
- cycle->pool = pool;
- cycle->log = log;
- cycle->old_cycle = old_cycle;
-
- cycle->conf_prefix.len = old_cycle->conf_prefix.len;
- cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix);
- if (cycle->conf_prefix.data == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
- cycle->prefix.len = old_cycle->prefix.len;
- cycle->prefix.data = ngx_pstrdup(pool, &old_cycle->prefix);
- if (cycle->prefix.data == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
- cycle->conf_file.len = old_cycle->conf_file.len;
- cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1);
- if (cycle->conf_file.data == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
- ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data,
- old_cycle->conf_file.len + 1);
-
- cycle->conf_param.len = old_cycle->conf_param.len;
- cycle->conf_param.data = ngx_pstrdup(pool, &old_cycle->conf_param);
- if (cycle->conf_param.data == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
-
- n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10;
-
- cycle->paths.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *));
- if (cycle->paths.elts == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
- cycle->paths.nelts = 0;
- cycle->paths.size = sizeof(ngx_path_t *);
- cycle->paths.nalloc = n;
- cycle->paths.pool = pool;
-
-
- if (old_cycle->open_files.part.nelts) {
- n = old_cycle->open_files.part.nelts;
- for (part = old_cycle->open_files.part.next; part; part = part->next) {
- n += part->nelts;
- }
-
- } else {
- n = 20;
- }
-
- if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))
- != NGX_OK)
- {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
-
- if (old_cycle->shared_memory.part.nelts) {
- n = old_cycle->shared_memory.part.nelts;
- for (part = old_cycle->shared_memory.part.next; part; part = part->next)
- {
- n += part->nelts;
- }
-
- } else {
- n = 1;
- }
-
- if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t))
- != NGX_OK)
- {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
- n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;
-
- cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t));
- if (cycle->listening.elts == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
- cycle->listening.nelts = 0;
- cycle->listening.size = sizeof(ngx_listening_t);
- cycle->listening.nalloc = n;
- cycle->listening.pool = pool;
-
-
- ngx_queue_init(&cycle->reusable_connections_queue);
-
-
- cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
- if (cycle->conf_ctx == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
-
- if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "gethostname() failed");
- ngx_destroy_pool(pool);
- return NULL;
- }
-
- /* on Linux gethostname() silently truncates name that does not fit */
-
- hostname[NGX_MAXHOSTNAMELEN - 1] = '\0';
- cycle->hostname.len = ngx_strlen(hostname);
-
- cycle->hostname.data = ngx_pnalloc(pool, cycle->hostname.len);
- if (cycle->hostname.data == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
- ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len);
-
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_CORE_MODULE) {
- continue;
- }
-
- module = ngx_modules[i]->ctx;
-
- if (module->create_conf) {
- rv = module->create_conf(cycle);
- if (rv == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
- cycle->conf_ctx[ngx_modules[i]->index] = rv;
- }
- }
-
-
- senv = environ;
-
-
- ngx_memzero(&conf, sizeof(ngx_conf_t));
- /* STUB: init array ? */
- conf.args = ngx_array_create(pool, 10, sizeof(ngx_str_t));
- if (conf.args == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
- conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
- if (conf.temp_pool == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
-
- conf.ctx = cycle->conf_ctx;
- conf.cycle = cycle;
- conf.pool = pool;
- conf.log = log;
- conf.module_type = NGX_CORE_MODULE;
- conf.cmd_type = NGX_MAIN_CONF;
-
-#if 0
- log->log_level = NGX_LOG_DEBUG_ALL;
-#endif
-
- if (ngx_conf_param(&conf) != NGX_CONF_OK) {
- environ = senv;
- ngx_destroy_cycle_pools(&conf);
- return NULL;
- }
-
- if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
- environ = senv;
- ngx_destroy_cycle_pools(&conf);
- return NULL;
- }
-
- if (ngx_test_config && !ngx_quiet_mode) {
- ngx_log_stderr(0, "the configuration file %s syntax is ok",
- cycle->conf_file.data);
- }
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_CORE_MODULE) {
- continue;
- }
-
- module = ngx_modules[i]->ctx;
-
- if (module->init_conf) {
- if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index])
- == NGX_CONF_ERROR)
- {
- environ = senv;
- ngx_destroy_cycle_pools(&conf);
- return NULL;
- }
- }
- }
-
- if (ngx_process == NGX_PROCESS_SIGNALLER) {
- return cycle;
- }
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-
- if (ngx_test_config) {
-
- if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
- goto failed;
- }
-
- } else if (!ngx_is_init_cycle(old_cycle)) {
-
- /*
- * we do not create the pid file in the first ngx_init_cycle() call
- * because we need to write the demonized process pid
- */
-
- old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
- ngx_core_module);
- if (ccf->pid.len != old_ccf->pid.len
- || ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != 0)
- {
- /* new pid file name */
-
- if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
- goto failed;
- }
-
- ngx_delete_pidfile(old_cycle);
- }
- }
-
-
- if (ngx_test_lockfile(cycle->lock_file.data, log) != NGX_OK) {
- goto failed;
- }
-
-
- if (ngx_create_paths(cycle, ccf->user) != NGX_OK) {
- goto failed;
- }
-
-
- if (ngx_log_open_default(cycle) != NGX_OK) {
- goto failed;
- }
-
- /* open the new files */
-
- part = &cycle->open_files.part;
- file = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- file = part->elts;
- i = 0;
- }
-
- if (file[i].name.len == 0) {
- continue;
- }
-
- file[i].fd = ngx_open_file(file[i].name.data,
- NGX_FILE_APPEND,
- NGX_FILE_CREATE_OR_OPEN,
- NGX_FILE_DEFAULT_ACCESS);
-
- ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0,
- "log: %p %d \"%s\"",
- &file[i], file[i].fd, file[i].name.data);
-
- if (file[i].fd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- ngx_open_file_n " \"%s\" failed",
- file[i].name.data);
- goto failed;
- }
-
-#if !(NGX_WIN32)
- if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- "fcntl(FD_CLOEXEC) \"%s\" failed",
- file[i].name.data);
- goto failed;
- }
-#endif
- }
-
- cycle->log = &cycle->new_log;
- pool->log = &cycle->new_log;
-
-
- /* create shared memory */
-
- part = &cycle->shared_memory.part;
- shm_zone = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- shm_zone = part->elts;
- i = 0;
- }
-
- if (shm_zone[i].shm.size == 0) {
- ngx_log_error(NGX_LOG_EMERG, log, 0,
- "zero size shared memory zone \"%V\"",
- &shm_zone[i].shm.name);
- goto failed;
- }
-
- shm_zone[i].shm.log = cycle->log;
-
- opart = &old_cycle->shared_memory.part;
- oshm_zone = opart->elts;
-
- for (n = 0; /* void */ ; n++) {
-
- if (n >= opart->nelts) {
- if (opart->next == NULL) {
- break;
- }
- opart = opart->next;
- oshm_zone = opart->elts;
- n = 0;
- }
-
- if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) {
- continue;
- }
-
- if (ngx_strncmp(shm_zone[i].shm.name.data,
- oshm_zone[n].shm.name.data,
- shm_zone[i].shm.name.len)
- != 0)
- {
- continue;
- }
-
- if (shm_zone[i].tag == oshm_zone[n].tag
- && shm_zone[i].shm.size == oshm_zone[n].shm.size)
- {
- shm_zone[i].shm.addr = oshm_zone[n].shm.addr;
-
- if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data)
- != NGX_OK)
- {
- goto failed;
- }
-
- goto shm_zone_found;
- }
-
- ngx_shm_free(&oshm_zone[n].shm);
-
- break;
- }
-
- if (ngx_shm_alloc(&shm_zone[i].shm) != NGX_OK) {
- goto failed;
- }
-
- if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) {
- goto failed;
- }
-
- if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) {
- goto failed;
- }
-
- shm_zone_found:
-
- continue;
- }
-
-
- /* handle the listening sockets */
-
- if (old_cycle->listening.nelts) {
- ls = old_cycle->listening.elts;
- for (i = 0; i < old_cycle->listening.nelts; i++) {
- ls[i].remain = 0;
- }
-
- nls = cycle->listening.elts;
- for (n = 0; n < cycle->listening.nelts; n++) {
-
- for (i = 0; i < old_cycle->listening.nelts; i++) {
- if (ls[i].ignore) {
- continue;
- }
-
- if (ngx_cmp_sockaddr(nls[n].sockaddr, nls[n].socklen,
- ls[i].sockaddr, ls[i].socklen, 1)
- == NGX_OK)
- {
- nls[n].fd = ls[i].fd;
- nls[n].previous = &ls[i];
- ls[i].remain = 1;
-
- if (ls[i].backlog != nls[n].backlog) {
- nls[n].listen = 1;
- }
-
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
-
- /*
- * FreeBSD, except the most recent versions,
- * could not remove accept filter
- */
- nls[n].deferred_accept = ls[i].deferred_accept;
-
- if (ls[i].accept_filter && nls[n].accept_filter) {
- if (ngx_strcmp(ls[i].accept_filter,
- nls[n].accept_filter)
- != 0)
- {
- nls[n].delete_deferred = 1;
- nls[n].add_deferred = 1;
- }
-
- } else if (ls[i].accept_filter) {
- nls[n].delete_deferred = 1;
-
- } else if (nls[n].accept_filter) {
- nls[n].add_deferred = 1;
- }
-#endif
-
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
-
- if (ls[i].deferred_accept && !nls[n].deferred_accept) {
- nls[n].delete_deferred = 1;
-
- } else if (ls[i].deferred_accept != nls[n].deferred_accept)
- {
- nls[n].add_deferred = 1;
- }
-#endif
- break;
- }
- }
-
- if (nls[n].fd == (ngx_socket_t) -1) {
- nls[n].open = 1;
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
- if (nls[n].accept_filter) {
- nls[n].add_deferred = 1;
- }
-#endif
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
- if (nls[n].deferred_accept) {
- nls[n].add_deferred = 1;
- }
-#endif
- }
- }
-
- } else {
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
- ls[i].open = 1;
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
- if (ls[i].accept_filter) {
- ls[i].add_deferred = 1;
- }
-#endif
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
- if (ls[i].deferred_accept) {
- ls[i].add_deferred = 1;
- }
-#endif
- }
- }
-
- if (ngx_open_listening_sockets(cycle) != NGX_OK) {
- goto failed;
- }
-
- if (!ngx_test_config) {
- ngx_configure_listening_sockets(cycle);
- }
-
-
- /* commit the new cycle configuration */
-
- if (!ngx_use_stderr) {
- (void) ngx_log_redirect_stderr(cycle);
- }
-
- pool->log = cycle->log;
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->init_module) {
- if (ngx_modules[i]->init_module(cycle) != NGX_OK) {
- /* fatal */
- exit(1);
- }
- }
- }
-
-
- /* close and delete stuff that lefts from an old cycle */
-
- /* free the unnecessary shared memory */
-
- opart = &old_cycle->shared_memory.part;
- oshm_zone = opart->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= opart->nelts) {
- if (opart->next == NULL) {
- goto old_shm_zone_done;
- }
- opart = opart->next;
- oshm_zone = opart->elts;
- i = 0;
- }
-
- part = &cycle->shared_memory.part;
- shm_zone = part->elts;
-
- for (n = 0; /* void */ ; n++) {
-
- if (n >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- shm_zone = part->elts;
- n = 0;
- }
-
- if (oshm_zone[i].shm.name.len == shm_zone[n].shm.name.len
- && ngx_strncmp(oshm_zone[i].shm.name.data,
- shm_zone[n].shm.name.data,
- oshm_zone[i].shm.name.len)
- == 0)
- {
- goto live_shm_zone;
- }
- }
-
- ngx_shm_free(&oshm_zone[i].shm);
-
- live_shm_zone:
-
- continue;
- }
-
-old_shm_zone_done:
-
-
- /* close the unnecessary listening sockets */
-
- ls = old_cycle->listening.elts;
- for (i = 0; i < old_cycle->listening.nelts; i++) {
-
- if (ls[i].remain || ls[i].fd == (ngx_socket_t) -1) {
- continue;
- }
-
- if (ngx_close_socket(ls[i].fd) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
- ngx_close_socket_n " listening socket on %V failed",
- &ls[i].addr_text);
- }
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-
- if (ls[i].sockaddr->sa_family == AF_UNIX) {
- u_char *name;
-
- name = ls[i].addr_text.data + sizeof("unix:") - 1;
-
- ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
- "deleting socket %s", name);
-
- if (ngx_delete_file(name) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
- ngx_delete_file_n " %s failed", name);
- }
- }
-
-#endif
- }
-
-
- /* close the unnecessary open files */
-
- part = &old_cycle->open_files.part;
- file = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- file = part->elts;
- i = 0;
- }
-
- if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
- continue;
- }
-
- if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed",
- file[i].name.data);
- }
- }
-
- ngx_destroy_pool(conf.temp_pool);
-
- if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) {
-
- /*
- * perl_destruct() frees environ, if it is not the same as it was at
- * perl_construct() time, therefore we save the previous cycle
- * environment before ngx_conf_parse() where it will be changed.
- */
-
- env = environ;
- environ = senv;
-
- ngx_destroy_pool(old_cycle->pool);
- cycle->old_cycle = NULL;
-
- environ = env;
-
- return cycle;
- }
-
-
- if (ngx_temp_pool == NULL) {
- ngx_temp_pool = ngx_create_pool(128, cycle->log);
- if (ngx_temp_pool == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
- "could not create ngx_temp_pool");
- exit(1);
- }
-
- n = 10;
- ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool,
- n * sizeof(ngx_cycle_t *));
- if (ngx_old_cycles.elts == NULL) {
- exit(1);
- }
- ngx_old_cycles.nelts = 0;
- ngx_old_cycles.size = sizeof(ngx_cycle_t *);
- ngx_old_cycles.nalloc = n;
- ngx_old_cycles.pool = ngx_temp_pool;
-
- ngx_cleaner_event.handler = ngx_clean_old_cycles;
- ngx_cleaner_event.log = cycle->log;
- ngx_cleaner_event.data = &dumb;
- dumb.fd = (ngx_socket_t) -1;
- }
-
- ngx_temp_pool->log = cycle->log;
-
- old = ngx_array_push(&ngx_old_cycles);
- if (old == NULL) {
- exit(1);
- }
- *old = old_cycle;
-
- if (!ngx_cleaner_event.timer_set) {
- ngx_add_timer(&ngx_cleaner_event, 30000);
- ngx_cleaner_event.timer_set = 1;
- }
-
- return cycle;
-
-
-failed:
-
- if (!ngx_is_init_cycle(old_cycle)) {
- old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
- ngx_core_module);
- if (old_ccf->environment) {
- environ = old_ccf->environment;
- }
- }
-
- /* rollback the new cycle configuration */
-
- part = &cycle->open_files.part;
- file = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- file = part->elts;
- i = 0;
- }
-
- if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
- continue;
- }
-
- if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed",
- file[i].name.data);
- }
- }
-
- if (ngx_test_config) {
- ngx_destroy_cycle_pools(&conf);
- return NULL;
- }
-
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
- if (ls[i].fd == (ngx_socket_t) -1 || !ls[i].open) {
- continue;
- }
-
- if (ngx_close_socket(ls[i].fd) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
- ngx_close_socket_n " %V failed",
- &ls[i].addr_text);
- }
- }
-
- ngx_destroy_cycle_pools(&conf);
-
- return NULL;
-}
-
-
-static void
-ngx_destroy_cycle_pools(ngx_conf_t *conf)
-{
- ngx_destroy_pool(conf->temp_pool);
- ngx_destroy_pool(conf->pool);
-}
-
-
-static ngx_int_t
-ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *zn)
-{
- u_char *file;
- ngx_slab_pool_t *sp;
-
- sp = (ngx_slab_pool_t *) zn->shm.addr;
-
- if (zn->shm.exists) {
-
- if (sp == sp->addr) {
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
- "shared zone \"%V\" has no equal addresses: %p vs %p",
- &zn->shm.name, sp->addr, sp);
- return NGX_ERROR;
- }
-
- sp->end = zn->shm.addr + zn->shm.size;
- sp->min_shift = 3;
- sp->addr = zn->shm.addr;
-
-#if (NGX_HAVE_ATOMIC_OPS)
-
- file = NULL;
-
-#else
-
- file = ngx_pnalloc(cycle->pool, cycle->lock_file.len + zn->shm.name.len);
- if (file == NULL) {
- return NGX_ERROR;
- }
-
- (void) ngx_sprintf(file, "%V%V%Z", &cycle->lock_file, &zn->shm.name);
-
-#endif
-
- if (ngx_shmtx_create(&sp->mutex, &sp->lock, file) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_slab_init(sp);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
-{
- size_t len;
- ngx_uint_t create;
- ngx_file_t file;
- u_char pid[NGX_INT64_LEN + 2];
-
- if (ngx_process > NGX_PROCESS_MASTER) {
- return NGX_OK;
- }
-
- ngx_memzero(&file, sizeof(ngx_file_t));
-
- file.name = *name;
- file.log = log;
-
- create = ngx_test_config ? NGX_FILE_CREATE_OR_OPEN : NGX_FILE_TRUNCATE;
-
- file.fd = ngx_open_file(file.name.data, NGX_FILE_RDWR,
- create, NGX_FILE_DEFAULT_ACCESS);
-
- if (file.fd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- ngx_open_file_n " \"%s\" failed", file.name.data);
- return NGX_ERROR;
- }
-
- if (!ngx_test_config) {
- len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid;
-
- if (ngx_write_file(&file, pid, len, 0) == NGX_ERROR) {
- return NGX_ERROR;
- }
- }
-
- if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", file.name.data);
- }
-
- return NGX_OK;
-}
-
-
-void
-ngx_delete_pidfile(ngx_cycle_t *cycle)
-{
- u_char *name;
- ngx_core_conf_t *ccf;
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-
- name = ngx_new_binary ? ccf->oldpid.data : ccf->pid.data;
-
- if (ngx_delete_file(name) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- ngx_delete_file_n " \"%s\" failed", name);
- }
-}
-
-
-ngx_int_t
-ngx_signal_process(ngx_cycle_t *cycle, char *sig)
-{
- ssize_t n;
- ngx_int_t pid;
- ngx_file_t file;
- ngx_core_conf_t *ccf;
- u_char buf[NGX_INT64_LEN + 2];
-
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "signal process started");
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-
- ngx_memzero(&file, sizeof(ngx_file_t));
-
- file.name = ccf->pid;
- file.log = cycle->log;
-
- file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
- NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS);
-
- if (file.fd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
- ngx_open_file_n " \"%s\" failed", file.name.data);
- return 1;
- }
-
- n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0);
-
- if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", file.name.data);
- }
-
- if (n == NGX_ERROR) {
- return 1;
- }
-
- while (n-- && (buf[n] == CR || buf[n] == LF)) { /* void */ }
-
- pid = ngx_atoi(buf, ++n);
-
- if (pid == NGX_ERROR) {
- ngx_log_error(NGX_LOG_ERR, cycle->log, 0,
- "invalid PID number \"%*s\" in \"%s\"",
- n, buf, file.name.data);
- return 1;
- }
-
- return ngx_os_signal_process(cycle, sig, pid);
-
-}
-
-
-static ngx_int_t
-ngx_test_lockfile(u_char *file, ngx_log_t *log)
-{
-#if !(NGX_HAVE_ATOMIC_OPS)
- ngx_fd_t fd;
-
- fd = ngx_open_file(file, NGX_FILE_RDWR, NGX_FILE_CREATE_OR_OPEN,
- NGX_FILE_DEFAULT_ACCESS);
-
- if (fd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- ngx_open_file_n " \"%s\" failed", file);
- return NGX_ERROR;
- }
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", file);
- }
-
- if (ngx_delete_file(file) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_delete_file_n " \"%s\" failed", file);
- }
-
-#endif
-
- return NGX_OK;
-}
-
-
-void
-ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user)
-{
- ngx_fd_t fd;
- ngx_uint_t i;
- ngx_list_part_t *part;
- ngx_open_file_t *file;
-
- part = &cycle->open_files.part;
- file = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- file = part->elts;
- i = 0;
- }
-
- if ((ngx_process == NGX_PROCESS_WORKER) && ngx_chrooted) {
- ngx_strip_chroot(&file[i].name);
- }
-
- if (file[i].name.len == 0) {
- continue;
- }
-
- if (file[i].flush) {
- file[i].flush(&file[i], cycle->log);
- }
-
- fd = ngx_open_file(file[i].name.data, NGX_FILE_APPEND,
- NGX_FILE_CREATE_OR_OPEN, NGX_FILE_DEFAULT_ACCESS);
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "reopen file \"%s\", old:%d new:%d",
- file[i].name.data, file[i].fd, fd);
-
- if (fd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- ngx_open_file_n " \"%s\" failed", file[i].name.data);
- continue;
- }
-
-#if !(NGX_WIN32)
- if (user != (ngx_uid_t) NGX_CONF_UNSET_UINT) {
- ngx_file_info_t fi;
-
- if (ngx_file_info((const char *) file[i].name.data, &fi)
- == NGX_FILE_ERROR)
- {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- ngx_file_info_n " \"%s\" failed",
- file[i].name.data);
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed",
- file[i].name.data);
- }
- }
-
- if (fi.st_uid != user) {
- if (chown((const char *) file[i].name.data, user, -1) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "chown(\"%s\", %d) failed",
- file[i].name.data, user);
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed",
- file[i].name.data);
- }
- }
- }
-
- if ((fi.st_mode & (S_IRUSR|S_IWUSR)) != (S_IRUSR|S_IWUSR)) {
-
- fi.st_mode |= (S_IRUSR|S_IWUSR);
-
- if (chmod((const char *) file[i].name.data, fi.st_mode) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "chmod() \"%s\" failed", file[i].name.data);
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed",
- file[i].name.data);
- }
- }
- }
- }
-
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "fcntl(FD_CLOEXEC) \"%s\" failed",
- file[i].name.data);
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed",
- file[i].name.data);
- }
-
- continue;
- }
-#endif
-
- if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed",
- file[i].name.data);
- }
-
- file[i].fd = fd;
- }
-
- (void) ngx_log_redirect_stderr(cycle);
-}
-
-
-ngx_shm_zone_t *
-ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size, void *tag)
-{
- ngx_uint_t i;
- ngx_shm_zone_t *shm_zone;
- ngx_list_part_t *part;
-
- part = &cf->cycle->shared_memory.part;
- shm_zone = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- shm_zone = part->elts;
- i = 0;
- }
-
- if (name->len != shm_zone[i].shm.name.len) {
- continue;
- }
-
- if (ngx_strncmp(name->data, shm_zone[i].shm.name.data, name->len)
- != 0)
- {
- continue;
- }
-
- if (tag != shm_zone[i].tag) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the shared memory zone \"%V\" is "
- "already declared for a different use",
- &shm_zone[i].shm.name);
- return NULL;
- }
-
- if (size && size != shm_zone[i].shm.size) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the size %uz of shared memory zone \"%V\" "
- "conflicts with already declared size %uz",
- size, &shm_zone[i].shm.name, shm_zone[i].shm.size);
- return NULL;
- }
-
- return &shm_zone[i];
- }
-
- shm_zone = ngx_list_push(&cf->cycle->shared_memory);
-
- if (shm_zone == NULL) {
- return NULL;
- }
-
- shm_zone->data = NULL;
- shm_zone->shm.log = cf->cycle->log;
- shm_zone->shm.size = size;
- shm_zone->shm.name = *name;
- shm_zone->shm.exists = 0;
- shm_zone->init = NULL;
- shm_zone->tag = tag;
-
- return shm_zone;
-}
-
-
-static void
-ngx_clean_old_cycles(ngx_event_t *ev)
-{
- ngx_uint_t i, n, found, live;
- ngx_log_t *log;
- ngx_cycle_t **cycle;
-
- log = ngx_cycle->log;
- ngx_temp_pool->log = log;
-
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycles");
-
- live = 0;
-
- cycle = ngx_old_cycles.elts;
- for (i = 0; i < ngx_old_cycles.nelts; i++) {
-
- if (cycle[i] == NULL) {
- continue;
- }
-
- found = 0;
-
- for (n = 0; n < cycle[i]->connection_n; n++) {
- if (cycle[i]->connections[n].fd != (ngx_socket_t) -1) {
- found = 1;
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "live fd:%d", n);
-
- break;
- }
- }
-
- if (found) {
- live = 1;
- continue;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycle: %d", i);
-
- ngx_destroy_pool(cycle[i]->pool);
- cycle[i] = NULL;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "old cycles status: %d", live);
-
- if (live) {
- ngx_add_timer(ev, 30000);
-
- } else {
- ngx_destroy_pool(ngx_temp_pool);
- ngx_temp_pool = NULL;
- ngx_old_cycles.nelts = 0;
- }
-}
diff --git a/usr.sbin/nginx/src/core/ngx_cycle.h b/usr.sbin/nginx/src/core/ngx_cycle.h
deleted file mode 100644
index 21bf5ca3f25..00000000000
--- a/usr.sbin/nginx/src/core/ngx_cycle.h
+++ /dev/null
@@ -1,144 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_CYCLE_H_INCLUDED_
-#define _NGX_CYCLE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#ifndef NGX_CYCLE_POOL_SIZE
-#define NGX_CYCLE_POOL_SIZE NGX_DEFAULT_POOL_SIZE
-#endif
-
-
-#define NGX_DEBUG_POINTS_STOP 1
-#define NGX_DEBUG_POINTS_ABORT 2
-
-
-typedef struct ngx_shm_zone_s ngx_shm_zone_t;
-
-typedef ngx_int_t (*ngx_shm_zone_init_pt) (ngx_shm_zone_t *zone, void *data);
-
-struct ngx_shm_zone_s {
- void *data;
- ngx_shm_t shm;
- ngx_shm_zone_init_pt init;
- void *tag;
-};
-
-
-struct ngx_cycle_s {
- void ****conf_ctx;
- ngx_pool_t *pool;
-
- ngx_log_t *log;
- ngx_log_t new_log;
-
- ngx_uint_t log_use_stderr; /* unsigned log_use_stderr:1; */
-
- ngx_connection_t **files;
- ngx_connection_t *free_connections;
- ngx_uint_t free_connection_n;
-
- ngx_queue_t reusable_connections_queue;
-
- ngx_array_t listening;
- ngx_array_t paths;
- ngx_list_t open_files;
- ngx_list_t shared_memory;
-
- ngx_uint_t connection_n;
- ngx_uint_t files_n;
-
- ngx_connection_t *connections;
- ngx_event_t *read_events;
- ngx_event_t *write_events;
-
- ngx_cycle_t *old_cycle;
-
- ngx_str_t conf_file;
- ngx_str_t conf_param;
- ngx_str_t conf_prefix;
- ngx_str_t prefix;
- ngx_str_t lock_file;
- ngx_str_t hostname;
-};
-
-
-typedef struct {
- ngx_flag_t daemon;
- ngx_flag_t master;
-
- ngx_msec_t timer_resolution;
-
- ngx_int_t worker_processes;
- ngx_int_t debug_points;
-
- ngx_int_t rlimit_nofile;
- ngx_int_t rlimit_sigpending;
- off_t rlimit_core;
-
- int priority;
-
- ngx_uint_t cpu_affinity_n;
- uint64_t *cpu_affinity;
-
- char *username;
- ngx_uid_t user;
- ngx_gid_t group;
-
- ngx_str_t working_directory;
- ngx_str_t lock_file;
-
- ngx_str_t pid;
- ngx_str_t oldpid;
-
- ngx_array_t env;
- char **environment;
-
-#if (NGX_THREADS)
- ngx_int_t worker_threads;
- size_t thread_stack_size;
-#endif
-
-} ngx_core_conf_t;
-
-
-typedef struct {
- ngx_pool_t *pool; /* pcre's malloc() pool */
-} ngx_core_tls_t;
-
-
-#define ngx_is_init_cycle(cycle) (cycle->conf_ctx == NULL)
-
-
-ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle);
-ngx_int_t ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log);
-void ngx_delete_pidfile(ngx_cycle_t *cycle);
-ngx_int_t ngx_signal_process(ngx_cycle_t *cycle, char *sig);
-void ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user);
-char **ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last);
-ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv);
-uint64_t ngx_get_cpu_affinity(ngx_uint_t n);
-ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name,
- size_t size, void *tag);
-
-
-extern volatile ngx_cycle_t *ngx_cycle;
-extern ngx_array_t ngx_old_cycles;
-extern ngx_module_t ngx_core_module;
-extern ngx_uint_t ngx_test_config;
-extern ngx_uint_t ngx_quiet_mode;
-#if (NGX_THREADS)
-extern ngx_tls_key_t ngx_core_tls_key;
-#endif
-
-
-#endif /* _NGX_CYCLE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_file.c b/usr.sbin/nginx/src/core/ngx_file.c
deleted file mode 100644
index 4bbdc940211..00000000000
--- a/usr.sbin/nginx/src/core/ngx_file.c
+++ /dev/null
@@ -1,1101 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-static ngx_int_t ngx_test_full_name(ngx_str_t *name);
-
-
-static ngx_atomic_t temp_number = 0;
-ngx_atomic_t *ngx_temp_number = &temp_number;
-ngx_atomic_int_t ngx_random_number = 123456;
-
-
-ngx_int_t
-ngx_get_full_name(ngx_pool_t *pool, ngx_str_t *prefix, ngx_str_t *name)
-{
- size_t len;
- u_char *p, *n;
- ngx_int_t rc;
-
- rc = ngx_test_full_name(name);
-
- if (rc == NGX_OK) {
- return rc;
- }
-
- len = prefix->len;
-
-#if (NGX_WIN32)
-
- if (rc == 2) {
- len = rc;
- }
-
-#endif
-
- n = ngx_pnalloc(pool, len + name->len + 1);
- if (n == NULL) {
- return NGX_ERROR;
- }
-
- p = ngx_cpymem(n, prefix->data, len);
- ngx_cpystrn(p, name->data, name->len + 1);
-
- name->len += len;
- name->data = n;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_test_full_name(ngx_str_t *name)
-{
-#if (NGX_WIN32)
- u_char c0, c1;
-
- c0 = name->data[0];
-
- if (name->len < 2) {
- if (c0 == '/') {
- return 2;
- }
-
- return NGX_DECLINED;
- }
-
- c1 = name->data[1];
-
- if (c1 == ':') {
- c0 |= 0x20;
-
- if ((c0 >= 'a' && c0 <= 'z')) {
- return NGX_OK;
- }
-
- return NGX_DECLINED;
- }
-
- if (c1 == '/') {
- return NGX_OK;
- }
-
- if (c0 == '/') {
- return 2;
- }
-
- return NGX_DECLINED;
-
-#else
-
- if (name->data[0] == '/') {
- return NGX_OK;
- }
-
- return NGX_DECLINED;
-
-#endif
-}
-
-
-ssize_t
-ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain)
-{
- ngx_int_t rc;
-
- if (tf->file.fd == NGX_INVALID_FILE) {
- rc = ngx_create_temp_file(&tf->file, tf->path, tf->pool,
- tf->persistent, tf->clean, tf->access);
-
- if (rc == NGX_ERROR || rc == NGX_AGAIN) {
- return rc;
- }
-
- if (tf->log_level) {
- ngx_log_error(tf->log_level, tf->file.log, 0, "%s %V",
- tf->warn, &tf->file.name);
- }
- }
-
- return ngx_write_chain_to_file(&tf->file, chain, tf->offset, tf->pool);
-}
-
-
-ngx_int_t
-ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool,
- ngx_uint_t persistent, ngx_uint_t clean, ngx_uint_t access)
-{
- uint32_t n;
- ngx_err_t err;
- ngx_pool_cleanup_t *cln;
- ngx_pool_cleanup_file_t *clnf;
-
- file->name.len = path->name.len + 1 + path->len + 10;
-
- file->name.data = ngx_pnalloc(pool, file->name.len + 1);
- if (file->name.data == NULL) {
- return NGX_ERROR;
- }
-
-#if 0
- for (i = 0; i < file->name.len; i++) {
- file->name.data[i] = 'X';
- }
-#endif
-
- ngx_memcpy(file->name.data, path->name.data, path->name.len);
-
- n = (uint32_t) ngx_next_temp_number(0);
-
- cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t));
- if (cln == NULL) {
- return NGX_ERROR;
- }
-
- for ( ;; ) {
- (void) ngx_sprintf(file->name.data + path->name.len + 1 + path->len,
- "%010uD%Z", n);
-
- ngx_create_hashed_filename(path, file->name.data, file->name.len);
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
- "hashed path: %s", file->name.data);
-
- file->fd = ngx_open_tempfile(file->name.data, persistent, access);
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
- "temp fd:%d", file->fd);
-
- if (file->fd != NGX_INVALID_FILE) {
-
- cln->handler = clean ? ngx_pool_delete_file : ngx_pool_cleanup_file;
- clnf = cln->data;
-
- clnf->fd = file->fd;
- clnf->name = file->name.data;
- clnf->log = pool->log;
-
- return NGX_OK;
- }
-
- err = ngx_errno;
-
- if (err == NGX_EEXIST) {
- n = (uint32_t) ngx_next_temp_number(1);
- continue;
- }
-
- if ((path->level[0] == 0) || (err != NGX_ENOPATH)) {
- ngx_log_error(NGX_LOG_CRIT, file->log, err,
- ngx_open_tempfile_n " \"%s\" failed",
- file->name.data);
- return NGX_ERROR;
- }
-
- if (ngx_create_path(file, path) == NGX_ERROR) {
- return NGX_ERROR;
- }
- }
-}
-
-
-void
-ngx_create_hashed_filename(ngx_path_t *path, u_char *file, size_t len)
-{
- size_t i, level;
- ngx_uint_t n;
-
- i = path->name.len + 1;
-
- file[path->name.len + path->len] = '/';
-
- for (n = 0; n < 3; n++) {
- level = path->level[n];
-
- if (level == 0) {
- break;
- }
-
- len -= level;
- file[i - 1] = '/';
- ngx_memcpy(&file[i], &file[len], level);
- i += level + 1;
- }
-}
-
-
-ngx_int_t
-ngx_create_path(ngx_file_t *file, ngx_path_t *path)
-{
- size_t pos;
- ngx_err_t err;
- ngx_uint_t i;
-
- pos = path->name.len;
-
- for (i = 0; i < 3; i++) {
- if (path->level[i] == 0) {
- break;
- }
-
- pos += path->level[i] + 1;
-
- file->name.data[pos] = '\0';
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
- "temp file: \"%s\"", file->name.data);
-
- if (ngx_create_dir(file->name.data, 0700) == NGX_FILE_ERROR) {
- err = ngx_errno;
- if (err != NGX_EEXIST) {
- ngx_log_error(NGX_LOG_CRIT, file->log, err,
- ngx_create_dir_n " \"%s\" failed",
- file->name.data);
- return NGX_ERROR;
- }
- }
-
- file->name.data[pos] = '/';
- }
-
- return NGX_OK;
-}
-
-
-ngx_err_t
-ngx_create_full_path(u_char *dir, ngx_uint_t access)
-{
- u_char *p, ch;
- ngx_err_t err;
-
- err = 0;
-
-#if (NGX_WIN32)
- p = dir + 3;
-#else
- p = dir + 1;
-#endif
-
- for ( /* void */ ; *p; p++) {
- ch = *p;
-
- if (ch != '/') {
- continue;
- }
-
- *p = '\0';
-
- if (ngx_create_dir(dir, access) == NGX_FILE_ERROR) {
- err = ngx_errno;
-
- switch (err) {
- case NGX_EEXIST:
- err = 0;
- case NGX_EACCES:
- break;
-
- default:
- return err;
- }
- }
-
- *p = '/';
- }
-
- return err;
-}
-
-
-ngx_atomic_uint_t
-ngx_next_temp_number(ngx_uint_t collision)
-{
- ngx_atomic_uint_t n, add;
-
- add = collision ? ngx_random_number : 1;
-
- n = ngx_atomic_fetch_add(ngx_temp_number, add);
-
- return n + add;
-}
-
-
-char *
-ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ssize_t level;
- ngx_str_t *value;
- ngx_uint_t i, n;
- ngx_path_t *path, **slot;
-
- slot = (ngx_path_t **) (p + cmd->offset);
-
- if (*slot) {
- return "is duplicate";
- }
-
- path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));
- if (path == NULL) {
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
-
- path->name = value[1];
-
- if (path->name.data[path->name.len - 1] == '/') {
- path->name.len--;
- }
-
- if (ngx_conf_full_name(cf->cycle, &path->name, 0) != NGX_OK) {
- return NULL;
- }
-
- path->conf_file = cf->conf_file->file.name.data;
- path->line = cf->conf_file->line;
-
- for (i = 0, n = 2; n < cf->args->nelts; i++, n++) {
- level = ngx_atoi(value[n].data, value[n].len);
- if (level == NGX_ERROR || level == 0) {
- return "invalid value";
- }
-
- path->level[i] = level;
- path->len += level + 1;
- }
-
- while (i < 3) {
- path->level[i++] = 0;
- }
-
- *slot = path;
-
- if (ngx_add_path(cf, slot) == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_conf_merge_path_value(ngx_conf_t *cf, ngx_path_t **path, ngx_path_t *prev,
- ngx_path_init_t *init)
-{
- if (*path) {
- return NGX_CONF_OK;
- }
-
- if (prev) {
- *path = prev;
- return NGX_CONF_OK;
- }
-
- *path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));
- if (*path == NULL) {
- return NGX_CONF_ERROR;
- }
-
- (*path)->name = init->name;
-
- if (ngx_conf_full_name(cf->cycle, &(*path)->name, 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- (*path)->level[0] = init->level[0];
- (*path)->level[1] = init->level[1];
- (*path)->level[2] = init->level[2];
-
- (*path)->len = init->level[0] + (init->level[0] ? 1 : 0)
- + init->level[1] + (init->level[1] ? 1 : 0)
- + init->level[2] + (init->level[2] ? 1 : 0);
-
- if (ngx_add_path(cf, path) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-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)
-{
- ngx_uint_t i, n;
- ngx_path_t *path, **p;
-
- path = *slot;
-
- p = cf->cycle->paths.elts;
- for (i = 0; i < cf->cycle->paths.nelts; i++) {
- if (p[i]->name.len == path->name.len
- && ngx_strcmp(p[i]->name.data, path->name.data) == 0)
- {
- if (p[i]->data != path->data) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the same path name \"%V\" "
- "used in %s:%ui and",
- &p[i]->name, p[i]->conf_file, p[i]->line);
- return NGX_ERROR;
- }
-
- for (n = 0; n < 3; n++) {
- if (p[i]->level[n] != path->level[n]) {
- if (path->conf_file == NULL) {
- if (p[i]->conf_file == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "the default path name \"%V\" has "
- "the same name as another default path, "
- "but the different levels, you need to "
- "redefine one of them in http section",
- &p[i]->name);
- return NGX_ERROR;
- }
-
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "the path name \"%V\" in %s:%ui has "
- "the same name as default path, but "
- "the different levels, you need to "
- "define default path in http section",
- &p[i]->name, p[i]->conf_file, p[i]->line);
- return NGX_ERROR;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the same path name \"%V\" in %s:%ui "
- "has the different levels than",
- &p[i]->name, p[i]->conf_file, p[i]->line);
- return NGX_ERROR;
- }
-
- if (p[i]->level[n] == 0) {
- break;
- }
- }
-
- *slot = p[i];
-
- return NGX_OK;
- }
- }
-
- p = ngx_array_push(&cf->cycle->paths);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- *p = path;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_create_paths(ngx_cycle_t *cycle, ngx_uid_t user)
-{
- u_char *prefix;
- ngx_err_t err;
- ngx_uint_t i;
- ngx_path_t **path;
-
- path = cycle->paths.elts;
- for (i = 0; i < cycle->paths.nelts; i++) {
-
- if (ngx_chrooted) {
- if (ngx_prefix)
- prefix = ngx_prefix;
- else
- prefix = NGX_PREFIX;
- if (chdir(prefix) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "chdir(\"%s\") failed", prefix);
- return NGX_ERROR;
- }
- ngx_strip_chroot(&path[i]->name);
- path[i]->name.data++;
- path[i]->name.len--;
- }
-
- if (ngx_create_dir(path[i]->name.data, 0700) == NGX_FILE_ERROR) {
- err = ngx_errno;
- if (err != NGX_EEXIST) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, err,
- ngx_create_dir_n " \"%s\" failed",
- path[i]->name.data);
- return NGX_ERROR;
- }
- }
-
- if (user == (ngx_uid_t) NGX_CONF_UNSET_UINT) {
- continue;
- }
-
-#if !(NGX_WIN32)
- {
- ngx_file_info_t fi;
-
- if (ngx_file_info((const char *) path[i]->name.data, &fi)
- == NGX_FILE_ERROR)
- {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- ngx_file_info_n " \"%s\" failed", path[i]->name.data);
- return NGX_ERROR;
- }
-
- if (fi.st_uid != user) {
- if (chown((const char *) path[i]->name.data, user, -1) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "chown(\"%s\", %d) failed",
- path[i]->name.data, user);
- return NGX_ERROR;
- }
- }
-
- if ((fi.st_mode & (S_IRUSR|S_IWUSR|S_IXUSR))
- != (S_IRUSR|S_IWUSR|S_IXUSR))
- {
- fi.st_mode |= (S_IRUSR|S_IWUSR|S_IXUSR);
-
- if (chmod((const char *) path[i]->name.data, fi.st_mode) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "chmod() \"%s\" failed", path[i]->name.data);
- return NGX_ERROR;
- }
- }
- }
-#endif
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext)
-{
- u_char *name;
- ngx_err_t err;
- ngx_copy_file_t cf;
-
-#if !(NGX_WIN32)
-
- if (ext->access) {
- if (ngx_change_file_access(src->data, ext->access) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,
- ngx_change_file_access_n " \"%s\" failed", src->data);
- err = 0;
- goto failed;
- }
- }
-
-#endif
-
- if (ext->time != -1) {
- if (ngx_set_file_time(src->data, ext->fd, ext->time) != NGX_OK) {
- ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,
- ngx_set_file_time_n " \"%s\" failed", src->data);
- err = 0;
- goto failed;
- }
- }
-
- if (ngx_rename_file(src->data, to->data) != NGX_FILE_ERROR) {
- return NGX_OK;
- }
-
- err = ngx_errno;
-
- if (err == NGX_ENOPATH) {
-
- if (!ext->create_path) {
- goto failed;
- }
-
- err = ngx_create_full_path(to->data, ngx_dir_access(ext->path_access));
-
- if (err) {
- ngx_log_error(NGX_LOG_CRIT, ext->log, err,
- ngx_create_dir_n " \"%s\" failed", to->data);
- err = 0;
- goto failed;
- }
-
- if (ngx_rename_file(src->data, to->data) != NGX_FILE_ERROR) {
- return NGX_OK;
- }
-
- err = ngx_errno;
- }
-
-#if (NGX_WIN32)
-
- if (err == NGX_EEXIST) {
- err = ngx_win32_rename_file(src, to, ext->log);
-
- if (err == 0) {
- return NGX_OK;
- }
- }
-
-#endif
-
- if (err == NGX_EXDEV) {
-
- cf.size = -1;
- cf.buf_size = 0;
- cf.access = ext->access;
- cf.time = ext->time;
- cf.log = ext->log;
-
- name = ngx_alloc(to->len + 1 + 10 + 1, ext->log);
- if (name == NULL) {
- return NGX_ERROR;
- }
-
- (void) ngx_sprintf(name, "%*s.%010uD%Z", to->len, to->data,
- (uint32_t) ngx_next_temp_number(0));
-
- if (ngx_copy_file(src->data, name, &cf) == NGX_OK) {
-
- if (ngx_rename_file(name, to->data) != NGX_FILE_ERROR) {
- ngx_free(name);
-
- if (ngx_delete_file(src->data) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,
- ngx_delete_file_n " \"%s\" failed",
- src->data);
- return NGX_ERROR;
- }
-
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,
- ngx_rename_file_n " \"%s\" to \"%s\" failed",
- name, to->data);
-
- if (ngx_delete_file(name) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,
- ngx_delete_file_n " \"%s\" failed", name);
-
- }
- }
-
- ngx_free(name);
-
- err = 0;
- }
-
-failed:
-
- if (ext->delete_file) {
- if (ngx_delete_file(src->data) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,
- ngx_delete_file_n " \"%s\" failed", src->data);
- }
- }
-
- if (err) {
- ngx_log_error(NGX_LOG_CRIT, ext->log, err,
- ngx_rename_file_n " \"%s\" to \"%s\" failed",
- src->data, to->data);
- }
-
- return NGX_ERROR;
-}
-
-
-ngx_int_t
-ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
-{
- char *buf;
- off_t size;
- size_t len;
- ssize_t n;
- ngx_fd_t fd, nfd;
- ngx_int_t rc;
- ngx_file_info_t fi;
-
- rc = NGX_ERROR;
- buf = NULL;
- nfd = NGX_INVALID_FILE;
-
- fd = ngx_open_file(from, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
-
- if (fd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_CRIT, cf->log, ngx_errno,
- ngx_open_file_n " \"%s\" failed", from);
- goto failed;
- }
-
- if (cf->size != -1) {
- size = cf->size;
-
- } else {
- if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
- ngx_fd_info_n " \"%s\" failed", from);
-
- goto failed;
- }
-
- size = ngx_file_size(&fi);
- }
-
- len = cf->buf_size ? cf->buf_size : 65536;
-
- if ((off_t) len > size) {
- len = (size_t) size;
- }
-
- buf = ngx_alloc(len, cf->log);
- if (buf == NULL) {
- goto failed;
- }
-
- nfd = ngx_open_file(to, NGX_FILE_WRONLY, NGX_FILE_CREATE_OR_OPEN,
- cf->access);
-
- if (nfd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_CRIT, cf->log, ngx_errno,
- ngx_open_file_n " \"%s\" failed", to);
- goto failed;
- }
-
- while (size > 0) {
-
- if ((off_t) len > size) {
- len = (size_t) size;
- }
-
- n = ngx_read_fd(fd, buf, len);
-
- if (n == -1) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
- ngx_read_fd_n " \"%s\" failed", from);
- goto failed;
- }
-
- if ((size_t) n != len) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
- ngx_read_fd_n " has read only %z of %uz from %s",
- n, size, from);
- goto failed;
- }
-
- n = ngx_write_fd(nfd, buf, len);
-
- if (n == -1) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
- ngx_write_fd_n " \"%s\" failed", to);
- goto failed;
- }
-
- if ((size_t) n != len) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
- ngx_write_fd_n " has written only %z of %uz to %s",
- n, size, to);
- goto failed;
- }
-
- size -= n;
- }
-
- if (cf->time != -1) {
- if (ngx_set_file_time(to, nfd, cf->time) != NGX_OK) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
- ngx_set_file_time_n " \"%s\" failed", to);
- goto failed;
- }
- }
-
- rc = NGX_OK;
-
-failed:
-
- if (nfd != NGX_INVALID_FILE) {
- if (ngx_close_file(nfd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", to);
- }
- }
-
- if (fd != NGX_INVALID_FILE) {
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", from);
- }
- }
-
- if (buf) {
- ngx_free(buf);
- }
-
- return rc;
-}
-
-
-/*
- * ctx->init_handler() - see ctx->alloc
- * ctx->file_handler() - file handler
- * ctx->pre_tree_handler() - handler is called before entering directory
- * ctx->post_tree_handler() - handler is called after leaving directory
- * ctx->spec_handler() - special (socket, FIFO, etc.) file handler
- *
- * ctx->data - some data structure, it may be the same on all levels, or
- * reallocated if ctx->alloc is nonzero
- *
- * ctx->alloc - a size of data structure that is allocated at every level
- * and is initialized by ctx->init_handler()
- *
- * ctx->log - a log
- *
- * on fatal (memory) error handler must return NGX_ABORT to stop walking tree
- */
-
-ngx_int_t
-ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t *tree)
-{
- void *data, *prev;
- u_char *p, *name;
- size_t len;
- ngx_int_t rc;
- ngx_err_t err;
- ngx_str_t file, buf;
- ngx_dir_t dir;
-
- ngx_str_null(&buf);
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
- "walk tree \"%V\"", tree);
-
- if (ngx_open_dir(tree, &dir) == NGX_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
- ngx_open_dir_n " \"%s\" failed", tree->data);
- return NGX_ERROR;
- }
-
- prev = ctx->data;
-
- if (ctx->alloc) {
- data = ngx_alloc(ctx->alloc, ctx->log);
- if (data == NULL) {
- goto failed;
- }
-
- if (ctx->init_handler(data, prev) == NGX_ABORT) {
- goto failed;
- }
-
- ctx->data = data;
-
- } else {
- data = NULL;
- }
-
- for ( ;; ) {
-
- ngx_set_errno(0);
-
- if (ngx_read_dir(&dir) == NGX_ERROR) {
- err = ngx_errno;
-
- if (err == NGX_ENOMOREFILES) {
- rc = NGX_OK;
-
- } else {
- ngx_log_error(NGX_LOG_CRIT, ctx->log, err,
- ngx_read_dir_n " \"%s\" failed", tree->data);
- rc = NGX_ERROR;
- }
-
- goto done;
- }
-
- len = ngx_de_namelen(&dir);
- name = ngx_de_name(&dir);
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->log, 0,
- "tree name %uz:\"%s\"", len, name);
-
- if (len == 1 && name[0] == '.') {
- continue;
- }
-
- if (len == 2 && name[0] == '.' && name[1] == '.') {
- continue;
- }
-
- file.len = tree->len + 1 + len;
-
- if (file.len + NGX_DIR_MASK_LEN > buf.len) {
-
- if (buf.len) {
- ngx_free(buf.data);
- }
-
- buf.len = tree->len + 1 + len + NGX_DIR_MASK_LEN;
-
- buf.data = ngx_alloc(buf.len + 1, ctx->log);
- if (buf.data == NULL) {
- goto failed;
- }
- }
-
- p = ngx_cpymem(buf.data, tree->data, tree->len);
- *p++ = '/';
- ngx_memcpy(p, name, len + 1);
-
- file.data = buf.data;
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
- "tree path \"%s\"", file.data);
-
- if (!dir.valid_info) {
- if (ngx_de_info(file.data, &dir) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
- ngx_de_info_n " \"%s\" failed", file.data);
- continue;
- }
- }
-
- if (ngx_de_is_file(&dir)) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
- "tree file \"%s\"", file.data);
-
- ctx->size = ngx_de_size(&dir);
- ctx->fs_size = ngx_de_fs_size(&dir);
- ctx->access = ngx_de_access(&dir);
- ctx->mtime = ngx_de_mtime(&dir);
-
- if (ctx->file_handler(ctx, &file) == NGX_ABORT) {
- goto failed;
- }
-
- } else if (ngx_de_is_dir(&dir)) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
- "tree enter dir \"%s\"", file.data);
-
- ctx->access = ngx_de_access(&dir);
- ctx->mtime = ngx_de_mtime(&dir);
-
- if (ctx->pre_tree_handler(ctx, &file) == NGX_ABORT) {
- goto failed;
- }
-
- if (ngx_walk_tree(ctx, &file) == NGX_ABORT) {
- goto failed;
- }
-
- ctx->access = ngx_de_access(&dir);
- ctx->mtime = ngx_de_mtime(&dir);
-
- if (ctx->post_tree_handler(ctx, &file) == NGX_ABORT) {
- goto failed;
- }
-
- } else {
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
- "tree special \"%s\"", file.data);
-
- if (ctx->spec_handler(ctx, &file) == NGX_ABORT) {
- goto failed;
- }
- }
- }
-
-failed:
-
- rc = NGX_ABORT;
-
-done:
-
- if (buf.len) {
- ngx_free(buf.data);
- }
-
- if (data) {
- ngx_free(data);
- ctx->data = prev;
- }
-
- if (ngx_close_dir(&dir) == NGX_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
- ngx_close_dir_n " \"%s\" failed", tree->data);
- }
-
- return rc;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_file.h b/usr.sbin/nginx/src/core/ngx_file.h
deleted file mode 100644
index 3ea6c28c863..00000000000
--- a/usr.sbin/nginx/src/core/ngx_file.h
+++ /dev/null
@@ -1,154 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_FILE_H_INCLUDED_
-#define _NGX_FILE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-struct ngx_file_s {
- ngx_fd_t fd;
- ngx_str_t name;
- ngx_file_info_t info;
-
- off_t offset;
- off_t sys_offset;
-
- ngx_log_t *log;
-
-#if (NGX_HAVE_FILE_AIO)
- ngx_event_aio_t *aio;
-#endif
-
- unsigned valid_info:1;
- unsigned directio:1;
-};
-
-
-#define NGX_MAX_PATH_LEVEL 3
-
-
-typedef time_t (*ngx_path_manager_pt) (void *data);
-typedef void (*ngx_path_loader_pt) (void *data);
-
-
-typedef struct {
- ngx_str_t name;
- size_t len;
- size_t level[3];
-
- ngx_path_manager_pt manager;
- ngx_path_loader_pt loader;
- void *data;
-
- u_char *conf_file;
- ngx_uint_t line;
-} ngx_path_t;
-
-
-typedef struct {
- ngx_str_t name;
- size_t level[3];
-} ngx_path_init_t;
-
-
-typedef struct {
- ngx_file_t file;
- off_t offset;
- ngx_path_t *path;
- ngx_pool_t *pool;
- char *warn;
-
- ngx_uint_t access;
-
- unsigned log_level:8;
- unsigned persistent:1;
- unsigned clean:1;
-} ngx_temp_file_t;
-
-
-typedef struct {
- ngx_uint_t access;
- ngx_uint_t path_access;
- time_t time;
- ngx_fd_t fd;
-
- unsigned create_path:1;
- unsigned delete_file:1;
-
- ngx_log_t *log;
-} ngx_ext_rename_file_t;
-
-
-typedef struct {
- off_t size;
- size_t buf_size;
-
- ngx_uint_t access;
- time_t time;
-
- ngx_log_t *log;
-} ngx_copy_file_t;
-
-
-typedef struct ngx_tree_ctx_s ngx_tree_ctx_t;
-
-typedef ngx_int_t (*ngx_tree_init_handler_pt) (void *ctx, void *prev);
-typedef ngx_int_t (*ngx_tree_handler_pt) (ngx_tree_ctx_t *ctx, ngx_str_t *name);
-
-struct ngx_tree_ctx_s {
- off_t size;
- off_t fs_size;
- ngx_uint_t access;
- time_t mtime;
-
- ngx_tree_init_handler_pt init_handler;
- ngx_tree_handler_pt file_handler;
- ngx_tree_handler_pt pre_tree_handler;
- ngx_tree_handler_pt post_tree_handler;
- ngx_tree_handler_pt spec_handler;
-
- void *data;
- size_t alloc;
-
- ngx_log_t *log;
-};
-
-
-ngx_int_t ngx_get_full_name(ngx_pool_t *pool, ngx_str_t *prefix,
- ngx_str_t *name);
-
-ssize_t ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain);
-ngx_int_t ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path,
- ngx_pool_t *pool, ngx_uint_t persistent, ngx_uint_t clean,
- ngx_uint_t access);
-void ngx_create_hashed_filename(ngx_path_t *path, u_char *file, size_t len);
-ngx_int_t ngx_create_path(ngx_file_t *file, ngx_path_t *path);
-ngx_err_t ngx_create_full_path(u_char *dir, ngx_uint_t access);
-ngx_int_t ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot);
-ngx_int_t ngx_create_paths(ngx_cycle_t *cycle, ngx_uid_t user);
-ngx_int_t ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to,
- ngx_ext_rename_file_t *ext);
-ngx_int_t ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf);
-ngx_int_t ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t *tree);
-
-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_merge_path_value(ngx_conf_t *cf, ngx_path_t **path,
- ngx_path_t *prev, ngx_path_init_t *init);
-char *ngx_conf_set_access_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-
-
-extern ngx_atomic_t *ngx_temp_number;
-extern ngx_atomic_int_t ngx_random_number;
-
-
-#endif /* _NGX_FILE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_hash.c b/usr.sbin/nginx/src/core/ngx_hash.c
deleted file mode 100644
index c7bfed70979..00000000000
--- a/usr.sbin/nginx/src/core/ngx_hash.c
+++ /dev/null
@@ -1,975 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-void *
-ngx_hash_find(ngx_hash_t *hash, ngx_uint_t key, u_char *name, size_t len)
-{
- ngx_uint_t i;
- ngx_hash_elt_t *elt;
-
-#if 0
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "hf:\"%*s\"", len, name);
-#endif
-
- elt = hash->buckets[key % hash->size];
-
- if (elt == NULL) {
- return NULL;
- }
-
- while (elt->value) {
- if (len != (size_t) elt->len) {
- goto next;
- }
-
- for (i = 0; i < len; i++) {
- if (name[i] != elt->name[i]) {
- goto next;
- }
- }
-
- return elt->value;
-
- next:
-
- elt = (ngx_hash_elt_t *) ngx_align_ptr(&elt->name[0] + elt->len,
- sizeof(void *));
- continue;
- }
-
- return NULL;
-}
-
-
-void *
-ngx_hash_find_wc_head(ngx_hash_wildcard_t *hwc, u_char *name, size_t len)
-{
- void *value;
- ngx_uint_t i, n, key;
-
-#if 0
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wch:\"%*s\"", len, name);
-#endif
-
- n = len;
-
- while (n) {
- if (name[n - 1] == '.') {
- break;
- }
-
- n--;
- }
-
- key = 0;
-
- for (i = n; i < len; i++) {
- key = ngx_hash(key, name[i]);
- }
-
-#if 0
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "key:\"%ui\"", key);
-#endif
-
- value = ngx_hash_find(&hwc->hash, key, &name[n], len - n);
-
-#if 0
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "value:\"%p\"", value);
-#endif
-
- if (value) {
-
- /*
- * the 2 low bits of value have the special meaning:
- * 00 - value is data pointer for both "example.com"
- * and "*.example.com";
- * 01 - value is data pointer for "*.example.com" only;
- * 10 - value is pointer to wildcard hash allowing
- * both "example.com" and "*.example.com";
- * 11 - value is pointer to wildcard hash allowing
- * "*.example.com" only.
- */
-
- if ((uintptr_t) value & 2) {
-
- if (n == 0) {
-
- /* "example.com" */
-
- if ((uintptr_t) value & 1) {
- return NULL;
- }
-
- hwc = (ngx_hash_wildcard_t *)
- ((uintptr_t) value & (uintptr_t) ~3);
- return hwc->value;
- }
-
- hwc = (ngx_hash_wildcard_t *) ((uintptr_t) value & (uintptr_t) ~3);
-
- value = ngx_hash_find_wc_head(hwc, name, n - 1);
-
- if (value) {
- return value;
- }
-
- return hwc->value;
- }
-
- if ((uintptr_t) value & 1) {
-
- if (n == 0) {
-
- /* "example.com" */
-
- return NULL;
- }
-
- return (void *) ((uintptr_t) value & (uintptr_t) ~3);
- }
-
- return value;
- }
-
- return hwc->value;
-}
-
-
-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_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "wct:\"%*s\"", len, name);
-#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 0
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "value:\"%p\"", value);
-#endif
-
- if (value) {
-
- /*
- * the 2 low bits of value have the special meaning:
- * 00 - value is data pointer;
- * 11 - value is pointer to wildcard hash allowing "example.*".
- */
-
- if ((uintptr_t) value & 2) {
-
- 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 (len == 0) {
- return NULL;
- }
-
- 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 + 2, sizeof(void *)))
-
-ngx_int_t
-ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
-{
- u_char *elts;
- size_t len;
- u_short *test;
- ngx_uint_t i, n, key, size, start, bucket_size;
- ngx_hash_elt_t *elt, **buckets;
-
- for (n = 0; n < nelts; n++) {
- if (hinit->bucket_size < NGX_HASH_ELT_SIZE(&names[n]) + sizeof(void *))
- {
- ngx_log_error(NGX_LOG_EMERG, hinit->pool->log, 0,
- "could not build the %s, you should "
- "increase %s_bucket_size: %i",
- hinit->name, hinit->name, hinit->bucket_size);
- return NGX_ERROR;
- }
- }
-
- test = ngx_alloc(hinit->max_size * sizeof(u_short), hinit->pool->log);
- if (test == NULL) {
- return NGX_ERROR;
- }
-
- bucket_size = hinit->bucket_size - sizeof(void *);
-
- start = nelts / (bucket_size / (2 * sizeof(void *)));
- start = start ? start : 1;
-
- if (hinit->max_size > 10000 && nelts && hinit->max_size / nelts < 100) {
- start = hinit->max_size - 1000;
- }
-
- for (size = start; size <= hinit->max_size; size++) {
-
- ngx_memzero(test, size * sizeof(u_short));
-
- for (n = 0; n < nelts; n++) {
- if (names[n].key.data == NULL) {
- continue;
- }
-
- key = names[n].key_hash % size;
- test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n]));
-
-#if 0
- ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
- "%ui: %ui %ui \"%V\"",
- size, key, test[key], &names[n].key);
-#endif
-
- if (test[key] > (u_short) bucket_size) {
- goto next;
- }
- }
-
- goto found;
-
- next:
-
- continue;
- }
-
- ngx_log_error(NGX_LOG_WARN, hinit->pool->log, 0,
- "could not build optimal %s, you should increase "
- "either %s_max_size: %i or %s_bucket_size: %i; "
- "ignoring %s_bucket_size",
- hinit->name, hinit->name, hinit->max_size,
- hinit->name, hinit->bucket_size, hinit->name);
-
-found:
-
- for (i = 0; i < size; i++) {
- test[i] = sizeof(void *);
- }
-
- for (n = 0; n < nelts; n++) {
- if (names[n].key.data == NULL) {
- continue;
- }
-
- key = names[n].key_hash % size;
- test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n]));
- }
-
- len = 0;
-
- for (i = 0; i < size; i++) {
- if (test[i] == sizeof(void *)) {
- continue;
- }
-
- test[i] = (u_short) (ngx_align(test[i], ngx_cacheline_size));
-
- len += test[i];
- }
-
- if (hinit->hash == NULL) {
- hinit->hash = ngx_pcalloc(hinit->pool, sizeof(ngx_hash_wildcard_t)
- + size * sizeof(ngx_hash_elt_t *));
- if (hinit->hash == NULL) {
- ngx_free(test);
- return NGX_ERROR;
- }
-
- buckets = (ngx_hash_elt_t **)
- ((u_char *) hinit->hash + sizeof(ngx_hash_wildcard_t));
-
- } else {
- buckets = ngx_pcalloc(hinit->pool, size * sizeof(ngx_hash_elt_t *));
- if (buckets == NULL) {
- ngx_free(test);
- return NGX_ERROR;
- }
- }
-
- elts = ngx_palloc(hinit->pool, len + ngx_cacheline_size);
- if (elts == NULL) {
- ngx_free(test);
- return NGX_ERROR;
- }
-
- elts = ngx_align_ptr(elts, ngx_cacheline_size);
-
- for (i = 0; i < size; i++) {
- if (test[i] == sizeof(void *)) {
- continue;
- }
-
- buckets[i] = (ngx_hash_elt_t *) elts;
- elts += test[i];
-
- }
-
- for (i = 0; i < size; i++) {
- test[i] = 0;
- }
-
- for (n = 0; n < nelts; n++) {
- if (names[n].key.data == NULL) {
- continue;
- }
-
- key = names[n].key_hash % size;
- elt = (ngx_hash_elt_t *) ((u_char *) buckets[key] + test[key]);
-
- elt->value = names[n].value;
- elt->len = (u_short) names[n].key.len;
-
- ngx_strlow(elt->name, names[n].key.data, names[n].key.len);
-
- test[key] = (u_short) (test[key] + NGX_HASH_ELT_SIZE(&names[n]));
- }
-
- for (i = 0; i < size; i++) {
- if (buckets[i] == NULL) {
- continue;
- }
-
- elt = (ngx_hash_elt_t *) ((u_char *) buckets[i] + test[i]);
-
- elt->value = NULL;
- }
-
- ngx_free(test);
-
- hinit->hash->buckets = buckets;
- hinit->hash->size = size;
-
-#if 0
-
- for (i = 0; i < size; i++) {
- ngx_str_t val;
- ngx_uint_t key;
-
- elt = buckets[i];
-
- if (elt == NULL) {
- ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
- "%ui: NULL", i);
- continue;
- }
-
- while (elt->value) {
- val.len = elt->len;
- val.data = &elt->name[0];
-
- key = hinit->key(val.data, val.len);
-
- ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
- "%ui: %p \"%V\" %ui", i, elt, &val, key);
-
- elt = (ngx_hash_elt_t *) ngx_align_ptr(&elt->name[0] + elt->len,
- sizeof(void *));
- }
- }
-
-#endif
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
- ngx_uint_t nelts)
-{
- size_t len, dot_len;
- ngx_uint_t i, n, dot;
- ngx_array_t curr_names, next_names;
- ngx_hash_key_t *name, *next_name;
- ngx_hash_init_t h;
- ngx_hash_wildcard_t *wdc;
-
- if (ngx_array_init(&curr_names, hinit->temp_pool, nelts,
- sizeof(ngx_hash_key_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&next_names, hinit->temp_pool, nelts,
- sizeof(ngx_hash_key_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- for (n = 0; n < nelts; n = i) {
-
-#if 0
- ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
- "wc0: \"%V\"", &names[n].key);
-#endif
-
- dot = 0;
-
- for (len = 0; len < names[n].key.len; len++) {
- if (names[n].key.data[len] == '.') {
- dot = 1;
- break;
- }
- }
-
- name = ngx_array_push(&curr_names);
- if (name == NULL) {
- return NGX_ERROR;
- }
-
- name->key.len = len;
- name->key.data = names[n].key.data;
- name->key_hash = hinit->key(name->key.data, name->key.len);
- name->value = names[n].value;
-
-#if 0
- ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
- "wc1: \"%V\" %ui", &name->key, dot);
-#endif
-
- dot_len = len + 1;
-
- if (dot) {
- len++;
- }
-
- next_names.nelts = 0;
-
- if (names[n].key.len != len) {
- next_name = ngx_array_push(&next_names);
- if (next_name == NULL) {
- return NGX_ERROR;
- }
-
- next_name->key.len = names[n].key.len - len;
- next_name->key.data = names[n].key.data + len;
- next_name->key_hash = 0;
- next_name->value = names[n].value;
-
-#if 0
- ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
- "wc2: \"%V\"", &next_name->key);
-#endif
- }
-
- for (i = n + 1; i < nelts; i++) {
- if (ngx_strncmp(names[n].key.data, names[i].key.data, len) != 0) {
- break;
- }
-
- if (!dot
- && names[i].key.len > len
- && names[i].key.data[len] != '.')
- {
- break;
- }
-
- next_name = ngx_array_push(&next_names);
- if (next_name == NULL) {
- return NGX_ERROR;
- }
-
- next_name->key.len = names[i].key.len - dot_len;
- next_name->key.data = names[i].key.data + dot_len;
- next_name->key_hash = 0;
- next_name->value = names[i].value;
-
-#if 0
- ngx_log_error(NGX_LOG_ALERT, hinit->pool->log, 0,
- "wc3: \"%V\"", &next_name->key);
-#endif
- }
-
- if (next_names.nelts) {
-
- h = *hinit;
- h.hash = NULL;
-
- if (ngx_hash_wildcard_init(&h, (ngx_hash_key_t *) next_names.elts,
- next_names.nelts)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- wdc = (ngx_hash_wildcard_t *) h.hash;
-
- if (names[n].key.len == len) {
- wdc->value = names[n].value;
- }
-
- name->value = (void *) ((uintptr_t) wdc | (dot ? 3 : 2));
-
- } else if (dot) {
- name->value = (void *) ((uintptr_t) name->value | 1);
- }
- }
-
- if (ngx_hash_init(hinit, (ngx_hash_key_t *) curr_names.elts,
- curr_names.nelts)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-ngx_uint_t
-ngx_hash_key(u_char *data, size_t len)
-{
- ngx_uint_t i, key;
-
- key = 0;
-
- for (i = 0; i < len; i++) {
- key = ngx_hash(key, data[i]);
- }
-
- return key;
-}
-
-
-ngx_uint_t
-ngx_hash_key_lc(u_char *data, size_t len)
-{
- ngx_uint_t i, key;
-
- key = 0;
-
- for (i = 0; i < len; i++) {
- key = ngx_hash(key, ngx_tolower(data[i]));
- }
-
- return key;
-}
-
-
-ngx_uint_t
-ngx_hash_strlow(u_char *dst, u_char *src, size_t n)
-{
- ngx_uint_t key;
-
- key = 0;
-
- while (n--) {
- *dst = ngx_tolower(*src);
- key = ngx_hash(key, *dst);
- dst++;
- src++;
- }
-
- return key;
-}
-
-
-ngx_int_t
-ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type)
-{
- ngx_uint_t asize;
-
- if (type == NGX_HASH_SMALL) {
- asize = 4;
- ha->hsize = 107;
-
- } else {
- asize = NGX_HASH_LARGE_ASIZE;
- ha->hsize = NGX_HASH_LARGE_HSIZE;
- }
-
- if (ngx_array_init(&ha->keys, ha->temp_pool, asize, sizeof(ngx_hash_key_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- 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)
- {
- return NGX_ERROR;
- }
-
- ha->keys_hash = ngx_pcalloc(ha->temp_pool, sizeof(ngx_array_t) * ha->hsize);
- if (ha->keys_hash == NULL) {
- return NGX_ERROR;
- }
-
- 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;
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-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 *p;
- ngx_str_t *name;
- ngx_uint_t i, k, n, skip, last;
- ngx_array_t *keys, *hwc;
- ngx_hash_key_t *hk;
-
- last = key->len;
-
- if (flags & NGX_HASH_WILDCARD_KEY) {
-
- /*
- * supported wildcards:
- * "*.example.com", ".example.com", and "www.example.*"
- */
-
- n = 0;
-
- for (i = 0; i < key->len; i++) {
-
- if (key->data[i] == '*') {
- if (++n > 1) {
- return NGX_DECLINED;
- }
- }
-
- if (key->data[i] == '.' && key->data[i + 1] == '.') {
- return NGX_DECLINED;
- }
- }
-
- if (key->len > 1 && key->data[0] == '.') {
- skip = 1;
- goto wildcard;
- }
-
- 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 = ngx_hash_strlow(&key->data[skip], &key->data[skip], last - skip);
-
- 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 (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 = last - 1;
- name->data = ngx_pnalloc(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"
- */
-
- p = ngx_pnalloc(ha->temp_pool, last);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- len = 0;
- n = 0;
-
- for (i = last - 1; i; i--) {
- if (key->data[i] == '.') {
- ngx_memcpy(&p[n], &key->data[i + 1], len);
- n += len;
- p[n++] = '.';
- len = 0;
- continue;
- }
-
- len++;
- }
-
- if (len) {
- ngx_memcpy(&p[n], &key->data[1], len);
- n += len;
- }
-
- p[n] = '\0';
-
- hwc = &ha->dns_wc_head;
- keys = &ha->dns_wc_head_hash[k];
-
- } else {
-
- /* convert "www.example.*" to "www.example\0" */
-
- last++;
-
- p = ngx_pnalloc(ha->temp_pool, last);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- ngx_cpystrn(p, key->data, last);
-
- hwc = &ha->dns_wc_tail;
- keys = &ha->dns_wc_tail_hash[k];
- }
-
-
- /* 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_pnalloc(ha->temp_pool, name->len);
- if (name->data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(name->data, key->data + skip, name->len);
-
-
- /* add to wildcard hash */
-
- 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;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_hash.h b/usr.sbin/nginx/src/core/ngx_hash.h
deleted file mode 100644
index abc3cbe5d93..00000000000
--- a/usr.sbin/nginx/src/core/ngx_hash.h
+++ /dev/null
@@ -1,122 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HASH_H_INCLUDED_
-#define _NGX_HASH_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef struct {
- void *value;
- u_short len;
- u_char name[1];
-} ngx_hash_elt_t;
-
-
-typedef struct {
- ngx_hash_elt_t **buckets;
- ngx_uint_t size;
-} ngx_hash_t;
-
-
-typedef struct {
- ngx_hash_t hash;
- void *value;
-} ngx_hash_wildcard_t;
-
-
-typedef struct {
- ngx_str_t key;
- ngx_uint_t key_hash;
- void *value;
-} ngx_hash_key_t;
-
-
-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;
-
- ngx_uint_t max_size;
- ngx_uint_t bucket_size;
-
- char *name;
- ngx_pool_t *pool;
- ngx_pool_t *temp_pool;
-} ngx_hash_init_t;
-
-
-#define NGX_HASH_SMALL 1
-#define NGX_HASH_LARGE 2
-
-#define NGX_HASH_LARGE_ASIZE 16384
-#define NGX_HASH_LARGE_HSIZE 10007
-
-#define NGX_HASH_WILDCARD_KEY 1
-#define NGX_HASH_READONLY_KEY 2
-
-
-typedef struct {
- ngx_uint_t hsize;
-
- ngx_pool_t *pool;
- ngx_pool_t *temp_pool;
-
- ngx_array_t keys;
- ngx_array_t *keys_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;
-
-
-typedef struct {
- ngx_uint_t hash;
- ngx_str_t key;
- ngx_str_t value;
- u_char *lowcase_key;
-} ngx_table_elt_t;
-
-
-void *ngx_hash_find(ngx_hash_t *hash, ngx_uint_t key, 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);
-ngx_int_t ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
- ngx_uint_t nelts);
-
-#define ngx_hash(key, c) ((ngx_uint_t) key * 31 + c)
-ngx_uint_t ngx_hash_key(u_char *data, size_t len);
-ngx_uint_t ngx_hash_key_lc(u_char *data, size_t len);
-ngx_uint_t ngx_hash_strlow(u_char *dst, u_char *src, size_t n);
-
-
-ngx_int_t ngx_hash_keys_array_init(ngx_hash_keys_arrays_t *ha, ngx_uint_t type);
-ngx_int_t ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key,
- void *value, ngx_uint_t flags);
-
-
-#endif /* _NGX_HASH_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_inet.c b/usr.sbin/nginx/src/core/ngx_inet.c
deleted file mode 100644
index 26c5bc4b0bb..00000000000
--- a/usr.sbin/nginx/src/core/ngx_inet.c
+++ /dev/null
@@ -1,1271 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-static ngx_int_t ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u);
-static ngx_int_t ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u);
-static ngx_int_t ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u);
-
-
-in_addr_t
-ngx_inet_addr(u_char *text, size_t len)
-{
- u_char *p, c;
- in_addr_t addr;
- ngx_uint_t octet, n;
-
- addr = 0;
- octet = 0;
- n = 0;
-
- for (p = text; p < text + len; p++) {
-
- c = *p;
-
- if (c >= '0' && c <= '9') {
- octet = octet * 10 + (c - '0');
- continue;
- }
-
- if (c == '.' && octet < 256) {
- addr = (addr << 8) + octet;
- octet = 0;
- n++;
- continue;
- }
-
- return INADDR_NONE;
- }
-
- if (n == 3 && octet < 256) {
- addr = (addr << 8) + octet;
- return htonl(addr);
- }
-
- return INADDR_NONE;
-}
-
-
-#if (NGX_HAVE_INET6)
-
-ngx_int_t
-ngx_inet6_addr(u_char *p, size_t len, u_char *addr)
-{
- u_char c, *zero, *digit, *s, *d;
- size_t len4;
- ngx_uint_t n, nibbles, word;
-
- if (len == 0) {
- return NGX_ERROR;
- }
-
- zero = NULL;
- digit = NULL;
- len4 = 0;
- nibbles = 0;
- word = 0;
- n = 8;
-
- if (p[0] == ':') {
- p++;
- len--;
- }
-
- for (/* void */; len; len--) {
- c = *p++;
-
- if (c == ':') {
- if (nibbles) {
- digit = p;
- len4 = len;
- *addr++ = (u_char) (word >> 8);
- *addr++ = (u_char) (word & 0xff);
-
- if (--n) {
- nibbles = 0;
- word = 0;
- continue;
- }
-
- } else {
- if (zero == NULL) {
- digit = p;
- len4 = len;
- zero = addr;
- continue;
- }
- }
-
- return NGX_ERROR;
- }
-
- if (c == '.' && nibbles) {
- if (n < 2 || digit == NULL) {
- return NGX_ERROR;
- }
-
- word = ngx_inet_addr(digit, len4 - 1);
- if (word == INADDR_NONE) {
- return NGX_ERROR;
- }
-
- word = ntohl(word);
- *addr++ = (u_char) ((word >> 24) & 0xff);
- *addr++ = (u_char) ((word >> 16) & 0xff);
- n--;
- break;
- }
-
- if (++nibbles > 4) {
- return NGX_ERROR;
- }
-
- if (c >= '0' && c <= '9') {
- word = word * 16 + (c - '0');
- continue;
- }
-
- c |= 0x20;
-
- if (c >= 'a' && c <= 'f') {
- word = word * 16 + (c - 'a') + 10;
- continue;
- }
-
- return NGX_ERROR;
- }
-
- if (nibbles == 0 && zero == NULL) {
- return NGX_ERROR;
- }
-
- *addr++ = (u_char) (word >> 8);
- *addr++ = (u_char) (word & 0xff);
-
- if (--n) {
- if (zero) {
- n *= 2;
- s = addr - 1;
- d = s + n;
- while (s >= zero) {
- *d-- = *s--;
- }
- ngx_memzero(zero, n);
- return NGX_OK;
- }
-
- } else {
- if (zero == NULL) {
- return NGX_OK;
- }
- }
-
- return NGX_ERROR;
-}
-
-#endif
-
-
-size_t
-ngx_sock_ntop(struct sockaddr *sa, socklen_t socklen, u_char *text, size_t len,
- ngx_uint_t port)
-{
- u_char *p;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- size_t n;
- struct sockaddr_in6 *sin6;
-#endif
-#if (NGX_HAVE_UNIX_DOMAIN)
- struct sockaddr_un *saun;
-#endif
-
- switch (sa->sa_family) {
-
- case AF_INET:
-
- sin = (struct sockaddr_in *) sa;
- p = (u_char *) &sin->sin_addr;
-
- if (port) {
- p = ngx_snprintf(text, len, "%ud.%ud.%ud.%ud:%d",
- p[0], p[1], p[2], p[3], ntohs(sin->sin_port));
- } else {
- p = ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
- p[0], p[1], p[2], p[3]);
- }
-
- return (p - text);
-
-#if (NGX_HAVE_INET6)
-
- case AF_INET6:
-
- sin6 = (struct sockaddr_in6 *) sa;
-
- n = 0;
-
- if (port) {
- text[n++] = '[';
- }
-
- n = ngx_inet6_ntop(sin6->sin6_addr.s6_addr, &text[n], len);
-
- if (port) {
- n = ngx_sprintf(&text[1 + n], "]:%d",
- ntohs(sin6->sin6_port)) - text;
- }
-
- return n;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-
- case AF_UNIX:
- saun = (struct sockaddr_un *) sa;
-
- /* on Linux sockaddr might not include sun_path at all */
-
- if (socklen <= (socklen_t) offsetof(struct sockaddr_un, sun_path)) {
- p = ngx_snprintf(text, len, "unix:%Z");
-
- } else {
- p = ngx_snprintf(text, len, "unix:%s%Z", saun->sun_path);
- }
-
- /* we do not include trailing zero in address length */
-
- return (p - text - 1);
-
-#endif
-
- default:
- return 0;
- }
-}
-
-
-size_t
-ngx_inet_ntop(int family, void *addr, u_char *text, size_t len)
-{
- u_char *p;
-
- switch (family) {
-
- case AF_INET:
-
- p = addr;
-
- return ngx_snprintf(text, len, "%ud.%ud.%ud.%ud",
- p[0], p[1], p[2], p[3])
- - text;
-
-#if (NGX_HAVE_INET6)
-
- case AF_INET6:
- return ngx_inet6_ntop(addr, text, len);
-
-#endif
-
- default:
- return 0;
- }
-}
-
-
-#if (NGX_HAVE_INET6)
-
-size_t
-ngx_inet6_ntop(u_char *p, u_char *text, size_t len)
-{
- u_char *dst;
- size_t max, n;
- ngx_uint_t i, zero, last;
-
- if (len < NGX_INET6_ADDRSTRLEN) {
- return 0;
- }
-
- zero = (ngx_uint_t) -1;
- last = (ngx_uint_t) -1;
- max = 1;
- n = 0;
-
- for (i = 0; i < 16; i += 2) {
-
- if (p[i] || p[i + 1]) {
-
- if (max < n) {
- zero = last;
- max = n;
- }
-
- n = 0;
- continue;
- }
-
- if (n++ == 0) {
- last = i;
- }
- }
-
- if (max < n) {
- zero = last;
- max = n;
- }
-
- dst = text;
- n = 16;
-
- if (zero == 0) {
-
- if ((max == 5 && p[10] == 0xff && p[11] == 0xff)
- || (max == 6)
- || (max == 7 && p[14] != 0 && p[15] != 1))
- {
- n = 12;
- }
-
- *dst++ = ':';
- }
-
- for (i = 0; i < n; i += 2) {
-
- if (i == zero) {
- *dst++ = ':';
- i += (max - 1) * 2;
- continue;
- }
-
- dst = ngx_sprintf(dst, "%uxi", p[i] * 256 + p[i + 1]);
-
- if (i < 14) {
- *dst++ = ':';
- }
- }
-
- if (n == 12) {
- dst = ngx_sprintf(dst, "%ud.%ud.%ud.%ud", p[12], p[13], p[14], p[15]);
- }
-
- return dst - text;
-}
-
-#endif
-
-
-ngx_int_t
-ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr)
-{
- u_char *addr, *mask, *last;
- size_t len;
- ngx_int_t shift;
-#if (NGX_HAVE_INET6)
- ngx_int_t rc;
- ngx_uint_t s, i;
-#endif
-
- addr = text->data;
- last = addr + text->len;
-
- mask = ngx_strlchr(addr, last, '/');
- len = (mask ? mask : last) - addr;
-
- cidr->u.in.addr = ngx_inet_addr(addr, len);
-
- if (cidr->u.in.addr != INADDR_NONE) {
- cidr->family = AF_INET;
-
- if (mask == NULL) {
- cidr->u.in.mask = 0xffffffff;
- return NGX_OK;
- }
-
-#if (NGX_HAVE_INET6)
- } else if (ngx_inet6_addr(addr, len, cidr->u.in6.addr.s6_addr) == NGX_OK) {
- cidr->family = AF_INET6;
-
- if (mask == NULL) {
- ngx_memset(cidr->u.in6.mask.s6_addr, 0xff, 16);
- return NGX_OK;
- }
-
-#endif
- } else {
- return NGX_ERROR;
- }
-
- mask++;
-
- shift = ngx_atoi(mask, last - mask);
- if (shift == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- switch (cidr->family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- if (shift > 128) {
- return NGX_ERROR;
- }
-
- addr = cidr->u.in6.addr.s6_addr;
- mask = cidr->u.in6.mask.s6_addr;
- rc = NGX_OK;
-
- for (i = 0; i < 16; i++) {
-
- s = (shift > 8) ? 8 : shift;
- shift -= s;
-
- mask[i] = (u_char) (0xffu << (8 - s));
-
- if (addr[i] != (addr[i] & mask[i])) {
- rc = NGX_DONE;
- addr[i] &= mask[i];
- }
- }
-
- return rc;
-#endif
-
- default: /* AF_INET */
- if (shift > 32) {
- return NGX_ERROR;
- }
-
- if (shift) {
- cidr->u.in.mask = htonl((uint32_t) (0xffffffffu << (32 - shift)));
-
- } else {
- /* x86 compilers use a shl instruction that shifts by modulo 32 */
- cidr->u.in.mask = 0;
- }
-
- if (cidr->u.in.addr == (cidr->u.in.addr & cidr->u.in.mask)) {
- return NGX_OK;
- }
-
- cidr->u.in.addr &= cidr->u.in.mask;
-
- return NGX_DONE;
- }
-}
-
-
-ngx_int_t
-ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len)
-{
- in_addr_t inaddr;
- ngx_uint_t family;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct in6_addr inaddr6;
- struct sockaddr_in6 *sin6;
-
- /*
- * prevent MSVC8 warning:
- * potentially uninitialized local variable 'inaddr6' used
- */
- ngx_memzero(&inaddr6, sizeof(struct in6_addr));
-#endif
-
- inaddr = ngx_inet_addr(text, len);
-
- if (inaddr != INADDR_NONE) {
- family = AF_INET;
- len = sizeof(struct sockaddr_in);
-
-#if (NGX_HAVE_INET6)
- } else if (ngx_inet6_addr(text, len, inaddr6.s6_addr) == NGX_OK) {
- family = AF_INET6;
- len = sizeof(struct sockaddr_in6);
-
-#endif
- } else {
- return NGX_DECLINED;
- }
-
- addr->sockaddr = ngx_pcalloc(pool, len);
- if (addr->sockaddr == NULL) {
- return NGX_ERROR;
- }
-
- addr->sockaddr->sa_family = (u_char) family;
- addr->socklen = len;
-
- switch (family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) addr->sockaddr;
- ngx_memcpy(sin6->sin6_addr.s6_addr, inaddr6.s6_addr, 16);
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) addr->sockaddr;
- sin->sin_addr.s_addr = inaddr;
- break;
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u)
-{
- u_char *p;
-
- p = u->url.data;
-
- if (ngx_strncasecmp(p, (u_char *) "unix:", 5) == 0) {
- return ngx_parse_unix_domain_url(pool, u);
- }
-
- if (p[0] == '[') {
- return ngx_parse_inet6_url(pool, u);
- }
-
- return ngx_parse_inet_url(pool, u);
-}
-
-
-static ngx_int_t
-ngx_parse_unix_domain_url(ngx_pool_t *pool, ngx_url_t *u)
-{
-#if (NGX_HAVE_UNIX_DOMAIN)
- u_char *path, *uri, *last;
- size_t len;
- struct sockaddr_un *saun;
-
- len = u->url.len;
- path = u->url.data;
-
- path += 5;
- len -= 5;
-
- if (u->uri_part) {
-
- last = path + len;
- uri = ngx_strlchr(path, last, ':');
-
- if (uri) {
- len = uri - path;
- uri++;
- u->uri.len = last - uri;
- u->uri.data = uri;
- }
- }
-
- if (len == 0) {
- u->err = "no path in the unix domain socket";
- return NGX_ERROR;
- }
-
- u->host.len = len++;
- u->host.data = path;
-
- if (len > sizeof(saun->sun_path)) {
- u->err = "too long path in the unix domain socket";
- return NGX_ERROR;
- }
-
- u->socklen = sizeof(struct sockaddr_un);
- saun = (struct sockaddr_un *) &u->sockaddr;
- saun->sun_family = AF_UNIX;
- (void) ngx_cpystrn((u_char *) saun->sun_path, path, len);
-
- u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- return NGX_ERROR;
- }
-
- saun = ngx_pcalloc(pool, sizeof(struct sockaddr_un));
- if (saun == NULL) {
- return NGX_ERROR;
- }
-
- u->family = AF_UNIX;
- u->naddrs = 1;
-
- saun->sun_family = AF_UNIX;
- (void) ngx_cpystrn((u_char *) saun->sun_path, path, len);
-
- u->addrs[0].sockaddr = (struct sockaddr *) saun;
- u->addrs[0].socklen = sizeof(struct sockaddr_un);
- u->addrs[0].name.len = len + 4;
- u->addrs[0].name.data = u->url.data;
-
- return NGX_OK;
-
-#else
-
- u->err = "the unix domain sockets are not supported on this platform";
-
- return NGX_ERROR;
-
-#endif
-}
-
-
-static ngx_int_t
-ngx_parse_inet_url(ngx_pool_t *pool, ngx_url_t *u)
-{
- u_char *p, *host, *port, *last, *uri, *args;
- size_t len;
- ngx_int_t n;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
-
- u->socklen = sizeof(struct sockaddr_in);
- sin = (struct sockaddr_in *) &u->sockaddr;
- sin->sin_family = AF_INET;
-
- u->family = AF_INET;
-
- host = u->url.data;
-
- last = host + u->url.len;
-
- port = ngx_strlchr(host, last, ':');
-
- uri = ngx_strlchr(host, last, '/');
-
- args = ngx_strlchr(host, last, '?');
-
- if (args) {
- if (uri == NULL || args < uri) {
- uri = args;
- }
- }
-
- if (uri) {
- if (u->listen || !u->uri_part) {
- u->err = "invalid host";
- return NGX_ERROR;
- }
-
- u->uri.len = last - uri;
- u->uri.data = uri;
-
- last = uri;
-
- if (uri < port) {
- port = NULL;
- }
- }
-
- if (port) {
- port++;
-
- len = last - port;
-
- n = ngx_atoi(port, len);
-
- if (n < 1 || n > 65535) {
- u->err = "invalid port";
- return NGX_ERROR;
- }
-
- u->port = (in_port_t) n;
- sin->sin_port = htons((in_port_t) n);
-
- u->port_text.len = len;
- u->port_text.data = port;
-
- last = port - 1;
-
- } else {
- if (uri == NULL) {
-
- if (u->listen) {
-
- /* test value as port only */
-
- n = ngx_atoi(host, last - host);
-
- if (n != NGX_ERROR) {
-
- if (n < 1 || n > 65535) {
- u->err = "invalid port";
- return NGX_ERROR;
- }
-
- u->port = (in_port_t) n;
- sin->sin_port = htons((in_port_t) n);
-
- u->port_text.len = last - host;
- u->port_text.data = host;
-
- u->wildcard = 1;
-
- return NGX_OK;
- }
- }
- }
-
- u->no_port = 1;
- u->port = u->default_port;
- sin->sin_port = htons(u->default_port);
- }
-
- len = last - host;
-
- if (len == 0) {
- u->err = "no host";
- return NGX_ERROR;
- }
-
- u->host.len = len;
- u->host.data = host;
-
- if (u->listen && len == 1 && *host == '*') {
- sin->sin_addr.s_addr = INADDR_ANY;
- u->wildcard = 1;
- return NGX_OK;
- }
-
- sin->sin_addr.s_addr = ngx_inet_addr(host, len);
-
- if (sin->sin_addr.s_addr != INADDR_NONE) {
-
- if (sin->sin_addr.s_addr == INADDR_ANY) {
- u->wildcard = 1;
- }
-
- u->naddrs = 1;
-
- u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- return NGX_ERROR;
- }
-
- sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(sin, u->sockaddr, sizeof(struct sockaddr_in));
-
- u->addrs[0].sockaddr = (struct sockaddr *) sin;
- u->addrs[0].socklen = sizeof(struct sockaddr_in);
-
- p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
- &u->host, u->port) - p;
- u->addrs[0].name.data = p;
-
- return NGX_OK;
- }
-
- if (u->no_resolve) {
- return NGX_OK;
- }
-
- if (ngx_inet_resolve_host(pool, u) != NGX_OK) {
- return NGX_ERROR;
- }
-
- u->family = u->addrs[0].sockaddr->sa_family;
- u->socklen = u->addrs[0].socklen;
- ngx_memcpy(u->sockaddr, u->addrs[0].sockaddr, u->addrs[0].socklen);
-
- switch (u->family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) &u->sockaddr;
-
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
- u->wildcard = 1;
- }
-
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) &u->sockaddr;
-
- if (sin->sin_addr.s_addr == INADDR_ANY) {
- u->wildcard = 1;
- }
-
- break;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_parse_inet6_url(ngx_pool_t *pool, ngx_url_t *u)
-{
-#if (NGX_HAVE_INET6)
- u_char *p, *host, *port, *last, *uri;
- size_t len;
- ngx_int_t n;
- struct sockaddr_in6 *sin6;
-
- u->socklen = sizeof(struct sockaddr_in6);
- sin6 = (struct sockaddr_in6 *) &u->sockaddr;
- sin6->sin6_family = AF_INET6;
-
- host = u->url.data + 1;
-
- last = u->url.data + u->url.len;
-
- p = ngx_strlchr(host, last, ']');
-
- if (p == NULL) {
- u->err = "invalid host";
- return NGX_ERROR;
- }
-
- if (last - p) {
-
- port = p + 1;
-
- uri = ngx_strlchr(port, last, '/');
-
- if (uri) {
- if (u->listen || !u->uri_part) {
- u->err = "invalid host";
- return NGX_ERROR;
- }
-
- u->uri.len = last - uri;
- u->uri.data = uri;
-
- last = uri;
- }
-
- if (*port == ':') {
- port++;
-
- len = last - port;
-
- n = ngx_atoi(port, len);
-
- if (n < 1 || n > 65535) {
- u->err = "invalid port";
- return NGX_ERROR;
- }
-
- u->port = (in_port_t) n;
- sin6->sin6_port = htons((in_port_t) n);
-
- u->port_text.len = len;
- u->port_text.data = port;
-
- } else {
- u->no_port = 1;
- u->port = u->default_port;
- sin6->sin6_port = htons(u->default_port);
- }
- }
-
- len = p - host;
-
- if (len == 0) {
- u->err = "no host";
- return NGX_ERROR;
- }
-
- u->host.len = len + 2;
- u->host.data = host - 1;
-
- if (ngx_inet6_addr(host, len, sin6->sin6_addr.s6_addr) != NGX_OK) {
- u->err = "invalid IPv6 address";
- return NGX_ERROR;
- }
-
- if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
- u->wildcard = 1;
- }
-
- u->family = AF_INET6;
- u->naddrs = 1;
-
- u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- return NGX_ERROR;
- }
-
- sin6 = ngx_pcalloc(pool, sizeof(struct sockaddr_in6));
- if (sin6 == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(sin6, u->sockaddr, sizeof(struct sockaddr_in6));
-
- u->addrs[0].sockaddr = (struct sockaddr *) sin6;
- u->addrs[0].socklen = sizeof(struct sockaddr_in6);
-
- p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
- &u->host, u->port) - p;
- u->addrs[0].name.data = p;
-
- return NGX_OK;
-
-#else
-
- u->err = "the INET6 sockets are not supported on this platform";
-
- return NGX_ERROR;
-
-#endif
-}
-
-
-#if (NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6)
-
-ngx_int_t
-ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
-{
- u_char *p, *host;
- size_t len;
- in_port_t port;
- ngx_uint_t i;
- struct addrinfo hints, *res, *rp;
- struct sockaddr_in *sin;
- struct sockaddr_in6 *sin6;
-
- port = htons(u->port);
-
- 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);
-
- ngx_memzero(&hints, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-#ifdef AI_ADDRCONFIG
- hints.ai_flags = AI_ADDRCONFIG;
-#endif
-
- if (getaddrinfo((char *) host, NULL, &hints, &res) != 0) {
- u->err = "host not found";
- ngx_free(host);
- return NGX_ERROR;
- }
-
- ngx_free(host);
-
- for (i = 0, rp = res; rp != NULL; rp = rp->ai_next) {
-
- switch (rp->ai_family) {
-
- case AF_INET:
- case AF_INET6:
- break;
-
- default:
- continue;
- }
-
- i++;
- }
-
- if (i == 0) {
- u->err = "host not found";
- goto failed;
- }
-
- /* MP: ngx_shared_palloc() */
-
- u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- goto failed;
- }
-
- u->naddrs = i;
-
- i = 0;
-
- /* AF_INET addresses first */
-
- for (rp = res; rp != NULL; rp = rp->ai_next) {
-
- if (rp->ai_family != AF_INET) {
- continue;
- }
-
- sin = ngx_pcalloc(pool, rp->ai_addrlen);
- if (sin == NULL) {
- goto failed;
- }
-
- ngx_memcpy(sin, rp->ai_addr, rp->ai_addrlen);
-
- sin->sin_port = port;
-
- u->addrs[i].sockaddr = (struct sockaddr *) sin;
- u->addrs[i].socklen = rp->ai_addrlen;
-
- len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
-
- p = ngx_pnalloc(pool, len);
- if (p == NULL) {
- goto failed;
- }
-
- len = ngx_sock_ntop((struct sockaddr *) sin, rp->ai_addrlen, p, len, 1);
-
- u->addrs[i].name.len = len;
- u->addrs[i].name.data = p;
-
- i++;
- }
-
- for (rp = res; rp != NULL; rp = rp->ai_next) {
-
- if (rp->ai_family != AF_INET6) {
- continue;
- }
-
- sin6 = ngx_pcalloc(pool, rp->ai_addrlen);
- if (sin6 == NULL) {
- goto failed;
- }
-
- ngx_memcpy(sin6, rp->ai_addr, rp->ai_addrlen);
-
- sin6->sin6_port = port;
-
- u->addrs[i].sockaddr = (struct sockaddr *) sin6;
- u->addrs[i].socklen = rp->ai_addrlen;
-
- len = NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
-
- p = ngx_pnalloc(pool, len);
- if (p == NULL) {
- goto failed;
- }
-
- len = ngx_sock_ntop((struct sockaddr *) sin6, rp->ai_addrlen, p,
- len, 1);
-
- u->addrs[i].name.len = len;
- u->addrs[i].name.data = p;
-
- i++;
- }
-
- freeaddrinfo(res);
- return NGX_OK;
-
-failed:
-
- freeaddrinfo(res);
- return NGX_ERROR;
-}
-
-#else /* !NGX_HAVE_GETADDRINFO || !NGX_HAVE_INET6 */
-
-ngx_int_t
-ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
-{
- u_char *p, *host;
- size_t len;
- in_port_t port;
- in_addr_t in_addr;
- ngx_uint_t i;
- struct hostent *h;
- struct sockaddr_in *sin;
-
- /* AF_INET only */
-
- port = htons(u->port);
-
- in_addr = ngx_inet_addr(u->host.data, u->host.len);
-
- if (in_addr == INADDR_NONE) {
- 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);
-
- h = gethostbyname((char *) host);
-
- ngx_free(host);
-
- if (h == NULL || h->h_addr_list[0] == NULL) {
- u->err = "host not found";
- return NGX_ERROR;
- }
-
- for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
-
- /* MP: ngx_shared_palloc() */
-
- u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- return NGX_ERROR;
- }
-
- u->naddrs = i;
-
- for (i = 0; i < u->naddrs; i++) {
-
- sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
- return NGX_ERROR;
- }
-
- sin->sin_family = AF_INET;
- sin->sin_port = port;
- sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
-
- u->addrs[i].sockaddr = (struct sockaddr *) sin;
- u->addrs[i].socklen = sizeof(struct sockaddr_in);
-
- len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
-
- p = ngx_pnalloc(pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- len = ngx_sock_ntop((struct sockaddr *) sin,
- sizeof(struct sockaddr_in), p, len, 1);
-
- u->addrs[i].name.len = len;
- u->addrs[i].name.data = p;
- }
-
- } else {
-
- /* MP: ngx_shared_palloc() */
-
- u->addrs = ngx_pcalloc(pool, sizeof(ngx_addr_t));
- if (u->addrs == NULL) {
- return NGX_ERROR;
- }
-
- sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
- if (sin == NULL) {
- return NGX_ERROR;
- }
-
- u->naddrs = 1;
-
- sin->sin_family = AF_INET;
- sin->sin_port = port;
- sin->sin_addr.s_addr = in_addr;
-
- u->addrs[0].sockaddr = (struct sockaddr *) sin;
- u->addrs[0].socklen = sizeof(struct sockaddr_in);
-
- p = ngx_pnalloc(pool, u->host.len + sizeof(":65535") - 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- u->addrs[0].name.len = ngx_sprintf(p, "%V:%d",
- &u->host, ntohs(port)) - p;
- u->addrs[0].name.data = p;
- }
-
- return NGX_OK;
-}
-
-#endif /* NGX_HAVE_GETADDRINFO && NGX_HAVE_INET6 */
-
-
-ngx_int_t
-ngx_cmp_sockaddr(struct sockaddr *sa1, socklen_t slen1,
- struct sockaddr *sa2, socklen_t slen2, ngx_uint_t cmp_port)
-{
- struct sockaddr_in *sin1, *sin2;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin61, *sin62;
-#endif
-#if (NGX_HAVE_UNIX_DOMAIN)
- struct sockaddr_un *saun1, *saun2;
-#endif
-
- if (sa1->sa_family != sa2->sa_family) {
- return NGX_DECLINED;
- }
-
- switch (sa1->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
-
- sin61 = (struct sockaddr_in6 *) sa1;
- sin62 = (struct sockaddr_in6 *) sa2;
-
- if (cmp_port && sin61->sin6_port != sin62->sin6_port) {
- return NGX_DECLINED;
- }
-
- if (ngx_memcmp(&sin61->sin6_addr, &sin62->sin6_addr, 16) != 0) {
- return NGX_DECLINED;
- }
-
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
-
- /* TODO length */
-
- saun1 = (struct sockaddr_un *) sa1;
- saun2 = (struct sockaddr_un *) sa2;
-
- if (ngx_memcmp(&saun1->sun_path, &saun2->sun_path,
- sizeof(saun1->sun_path))
- != 0)
- {
- return NGX_DECLINED;
- }
-
- break;
-#endif
-
- default: /* AF_INET */
-
- sin1 = (struct sockaddr_in *) sa1;
- sin2 = (struct sockaddr_in *) sa2;
-
- if (cmp_port && sin1->sin_port != sin2->sin_port) {
- return NGX_DECLINED;
- }
-
- if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
- return NGX_DECLINED;
- }
-
- break;
- }
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_inet.h b/usr.sbin/nginx/src/core/ngx_inet.h
deleted file mode 100644
index 05557509d65..00000000000
--- a/usr.sbin/nginx/src/core/ngx_inet.h
+++ /dev/null
@@ -1,122 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_INET_H_INCLUDED_
-#define _NGX_INET_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/*
- * TODO: autoconfigure NGX_SOCKADDRLEN and NGX_SOCKADDR_STRLEN as
- * sizeof(struct sockaddr_storage)
- * sizeof(struct sockaddr_un)
- * sizeof(struct sockaddr_in6)
- * sizeof(struct sockaddr_in)
- */
-
-#define NGX_INET_ADDRSTRLEN (sizeof("255.255.255.255") - 1)
-#define NGX_INET6_ADDRSTRLEN \
- (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") - 1)
-#define NGX_UNIX_ADDRSTRLEN \
- (sizeof(struct sockaddr_un) - offsetof(struct sockaddr_un, sun_path))
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-#define NGX_SOCKADDR_STRLEN (sizeof("unix:") - 1 + NGX_UNIX_ADDRSTRLEN)
-#else
-#define NGX_SOCKADDR_STRLEN (NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1)
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-#define NGX_SOCKADDRLEN sizeof(struct sockaddr_un)
-#else
-#define NGX_SOCKADDRLEN 512
-#endif
-
-
-typedef struct {
- in_addr_t addr;
- in_addr_t mask;
-} ngx_in_cidr_t;
-
-
-#if (NGX_HAVE_INET6)
-
-typedef struct {
- struct in6_addr addr;
- struct in6_addr mask;
-} ngx_in6_cidr_t;
-
-#endif
-
-
-typedef struct {
- ngx_uint_t family;
- union {
- ngx_in_cidr_t in;
-#if (NGX_HAVE_INET6)
- ngx_in6_cidr_t in6;
-#endif
- } u;
-} ngx_cidr_t;
-
-
-typedef struct {
- struct sockaddr *sockaddr;
- socklen_t socklen;
- ngx_str_t name;
-} ngx_addr_t;
-
-
-typedef struct {
- ngx_str_t url;
- ngx_str_t host;
- ngx_str_t port_text;
- ngx_str_t uri;
-
- in_port_t port;
- in_port_t default_port;
- int family;
-
- unsigned listen:1;
- unsigned uri_part:1;
- unsigned no_resolve:1;
- unsigned one_addr:1; /* compatibility */
-
- unsigned no_port:1;
- unsigned wildcard:1;
-
- socklen_t socklen;
- u_char sockaddr[NGX_SOCKADDRLEN];
-
- ngx_addr_t *addrs;
- ngx_uint_t naddrs;
-
- char *err;
-} ngx_url_t;
-
-
-in_addr_t ngx_inet_addr(u_char *text, size_t len);
-#if (NGX_HAVE_INET6)
-ngx_int_t ngx_inet6_addr(u_char *p, size_t len, u_char *addr);
-size_t ngx_inet6_ntop(u_char *p, u_char *text, size_t len);
-#endif
-size_t ngx_sock_ntop(struct sockaddr *sa, socklen_t socklen, u_char *text,
- size_t len, ngx_uint_t port);
-size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
-ngx_int_t ngx_ptocidr(ngx_str_t *text, ngx_cidr_t *cidr);
-ngx_int_t ngx_parse_addr(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text,
- size_t len);
-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);
-ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, socklen_t slen1,
- struct sockaddr *sa2, socklen_t slen2, ngx_uint_t cmp_port);
-
-
-#endif /* _NGX_INET_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_list.c b/usr.sbin/nginx/src/core/ngx_list.c
deleted file mode 100644
index d0eb15930a8..00000000000
--- a/usr.sbin/nginx/src/core/ngx_list.c
+++ /dev/null
@@ -1,63 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-ngx_list_t *
-ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size)
-{
- ngx_list_t *list;
-
- list = ngx_palloc(pool, sizeof(ngx_list_t));
- if (list == NULL) {
- return NULL;
- }
-
- if (ngx_list_init(list, pool, n, size) != NGX_OK) {
- return NULL;
- }
-
- return list;
-}
-
-
-void *
-ngx_list_push(ngx_list_t *l)
-{
- void *elt;
- ngx_list_part_t *last;
-
- last = l->last;
-
- if (last->nelts == l->nalloc) {
-
- /* the last part is full, allocate a new list part */
-
- last = ngx_palloc(l->pool, sizeof(ngx_list_part_t));
- if (last == NULL) {
- return NULL;
- }
-
- last->elts = ngx_palloc(l->pool, l->nalloc * l->size);
- if (last->elts == NULL) {
- return NULL;
- }
-
- last->nelts = 0;
- last->next = NULL;
-
- l->last->next = last;
- l->last = last;
- }
-
- elt = (char *) last->elts + l->size * last->nelts;
- last->nelts++;
-
- return elt;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_list.h b/usr.sbin/nginx/src/core/ngx_list.h
deleted file mode 100644
index e0fe6436b13..00000000000
--- a/usr.sbin/nginx/src/core/ngx_list.h
+++ /dev/null
@@ -1,83 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_LIST_H_INCLUDED_
-#define _NGX_LIST_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef struct ngx_list_part_s ngx_list_part_t;
-
-struct ngx_list_part_s {
- void *elts;
- ngx_uint_t nelts;
- ngx_list_part_t *next;
-};
-
-
-typedef struct {
- ngx_list_part_t *last;
- ngx_list_part_t part;
- size_t size;
- ngx_uint_t nalloc;
- ngx_pool_t *pool;
-} ngx_list_t;
-
-
-ngx_list_t *ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size);
-
-static ngx_inline ngx_int_t
-ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size)
-{
- list->part.elts = ngx_palloc(pool, n * size);
- if (list->part.elts == NULL) {
- return NGX_ERROR;
- }
-
- list->part.nelts = 0;
- list->part.next = NULL;
- list->last = &list->part;
- list->size = size;
- list->nalloc = n;
- list->pool = pool;
-
- return NGX_OK;
-}
-
-
-/*
- *
- * the iteration through the list:
- *
- * part = &list.part;
- * data = part->elts;
- *
- * for (i = 0 ;; i++) {
- *
- * if (i >= part->nelts) {
- * if (part->next == NULL) {
- * break;
- * }
- *
- * part = part->next;
- * data = part->elts;
- * i = 0;
- * }
- *
- * ... data[i] ...
- *
- * }
- */
-
-
-void *ngx_list_push(ngx_list_t *list);
-
-
-#endif /* _NGX_LIST_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_log.c b/usr.sbin/nginx/src/core/ngx_log.c
deleted file mode 100644
index 375d52f65d4..00000000000
--- a/usr.sbin/nginx/src/core/ngx_log.c
+++ /dev/null
@@ -1,619 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-static char *ngx_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static char *ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log);
-static void ngx_log_insert(ngx_log_t *log, ngx_log_t *new_log);
-
-
-static ngx_command_t ngx_errlog_commands[] = {
-
- {ngx_string("error_log"),
- NGX_MAIN_CONF|NGX_CONF_1MORE,
- ngx_error_log,
- 0,
- 0,
- NULL},
-
- ngx_null_command
-};
-
-
-static ngx_core_module_t ngx_errlog_module_ctx = {
- ngx_string("errlog"),
- NULL,
- NULL
-};
-
-
-ngx_module_t ngx_errlog_module = {
- NGX_MODULE_V1,
- &ngx_errlog_module_ctx, /* module context */
- ngx_errlog_commands, /* module directives */
- NGX_CORE_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_log_t ngx_log;
-static ngx_open_file_t ngx_log_file;
-ngx_uint_t ngx_use_stderr = 1;
-
-
-static ngx_str_t err_levels[] = {
- ngx_null_string,
- ngx_string("emerg"),
- ngx_string("alert"),
- ngx_string("crit"),
- ngx_string("error"),
- ngx_string("warn"),
- ngx_string("notice"),
- ngx_string("info"),
- ngx_string("debug")
-};
-
-static const char *debug_levels[] = {
- "debug_core", "debug_alloc", "debug_mutex", "debug_event",
- "debug_http", "debug_mail", "debug_mysql"
-};
-
-
-#if (NGX_HAVE_VARIADIC_MACROS)
-
-void
-ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
- const char *fmt, ...)
-
-#else
-
-void
-ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
- const char *fmt, va_list args)
-
-#endif
-{
-#if (NGX_HAVE_VARIADIC_MACROS)
- va_list args;
-#endif
- u_char *p, *last, *msg;
- u_char errstr[NGX_MAX_ERROR_STR];
- ngx_uint_t wrote_stderr, debug_connection;
-
- last = errstr + NGX_MAX_ERROR_STR;
-
- ngx_memcpy(errstr, ngx_cached_err_log_time.data,
- ngx_cached_err_log_time.len);
-
- p = errstr + ngx_cached_err_log_time.len;
-
- p = ngx_slprintf(p, last, " [%V] ", &err_levels[level]);
-
- /* pid#tid */
- p = ngx_slprintf(p, last, "%P#" NGX_TID_T_FMT ": ",
- ngx_log_pid, ngx_log_tid);
-
- if (log->connection) {
- p = ngx_slprintf(p, last, "*%uA ", log->connection);
- }
-
- msg = p;
-
-#if (NGX_HAVE_VARIADIC_MACROS)
-
- va_start(args, fmt);
- p = ngx_vslprintf(p, last, fmt, args);
- va_end(args);
-
-#else
-
- p = ngx_vslprintf(p, last, fmt, args);
-
-#endif
-
- if (err) {
- p = ngx_log_errno(p, last, err);
- }
-
- if (level != NGX_LOG_DEBUG && log->handler) {
- p = log->handler(log, p, last - p);
- }
-
- if (p > last - NGX_LINEFEED_SIZE) {
- p = last - NGX_LINEFEED_SIZE;
- }
-
- ngx_linefeed(p);
-
- wrote_stderr = 0;
- debug_connection = (log->log_level & NGX_LOG_DEBUG_CONNECTION) != 0;
-
- while (log) {
-
- if (log->log_level < level && !debug_connection) {
- break;
- }
-
- if (log->writer) {
- log->writer(log, level, errstr, p - errstr);
- log = log->next;
- continue;
- }
-
- (void) ngx_write_fd(log->file->fd, errstr, p - errstr);
-
- if (log->file->fd == ngx_stderr) {
- wrote_stderr = 1;
- }
-
- log = log->next;
- }
-
- if (!ngx_use_stderr
- || level > NGX_LOG_WARN
- || wrote_stderr)
- {
- return;
- }
-
- msg -= (7 + err_levels[level].len + 3);
-
- (void) ngx_sprintf(msg, "nginx: [%V] ", &err_levels[level]);
-
- (void) ngx_write_console(ngx_stderr, msg, p - msg);
-}
-
-
-#if !(NGX_HAVE_VARIADIC_MACROS)
-
-void ngx_cdecl
-ngx_log_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
- const char *fmt, ...)
-{
- va_list args;
-
- if (log->log_level >= level) {
- va_start(args, fmt);
- ngx_log_error_core(level, log, err, fmt, args);
- va_end(args);
- }
-}
-
-
-void ngx_cdecl
-ngx_log_debug_core(ngx_log_t *log, ngx_err_t err, const char *fmt, ...)
-{
- va_list args;
-
- va_start(args, fmt);
- ngx_log_error_core(NGX_LOG_DEBUG, log, err, fmt, args);
- va_end(args);
-}
-
-#endif
-
-
-void ngx_cdecl
-ngx_log_abort(ngx_err_t err, const char *fmt, ...)
-{
- u_char *p;
- va_list args;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
-
- va_start(args, fmt);
- p = ngx_vsnprintf(errstr, sizeof(errstr) - 1, fmt, args);
- va_end(args);
-
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err,
- "%*s", p - errstr, errstr);
-}
-
-
-void ngx_cdecl
-ngx_log_stderr(ngx_err_t err, const char *fmt, ...)
-{
- u_char *p, *last;
- va_list args;
- u_char errstr[NGX_MAX_ERROR_STR];
-
- last = errstr + NGX_MAX_ERROR_STR;
- p = errstr + 7;
-
- ngx_memcpy(errstr, "nginx: ", 7);
-
- va_start(args, fmt);
- p = ngx_vslprintf(p, last, fmt, args);
- va_end(args);
-
- if (err) {
- p = ngx_log_errno(p, last, err);
- }
-
- if (p > last - NGX_LINEFEED_SIZE) {
- p = last - NGX_LINEFEED_SIZE;
- }
-
- ngx_linefeed(p);
-
- (void) ngx_write_console(ngx_stderr, errstr, p - errstr);
-}
-
-
-u_char *
-ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err)
-{
- if (buf > last - 50) {
-
- /* leave a space for an error code */
-
- buf = last - 50;
- *buf++ = '.';
- *buf++ = '.';
- *buf++ = '.';
- }
-
-#if (NGX_WIN32)
- buf = ngx_slprintf(buf, last, ((unsigned) err < 0x80000000)
- ? " (%d: " : " (%Xd: ", err);
-#else
- buf = ngx_slprintf(buf, last, " (%d: ", err);
-#endif
-
- buf = ngx_strerror(err, buf, last - buf);
-
- if (buf < last) {
- *buf++ = ')';
- }
-
- return buf;
-}
-
-
-ngx_log_t *
-ngx_log_init(u_char *prefix)
-{
- u_char *p, *name;
- size_t nlen, plen;
-
- ngx_log.file = &ngx_log_file;
- ngx_log.log_level = NGX_LOG_NOTICE;
-
- name = (u_char *) NGX_ERROR_LOG_PATH;
-
- /*
- * we use ngx_strlen() here since BCC warns about
- * condition is always false and unreachable code
- */
-
- nlen = ngx_strlen(name);
-
- if (nlen == 0) {
- ngx_log_file.fd = ngx_stderr;
- return &ngx_log;
- }
-
- p = NULL;
-
-#if (NGX_WIN32)
- if (name[1] != ':') {
-#else
- if (name[0] != '/') {
-#endif
-
- if (prefix) {
- plen = ngx_strlen(prefix);
-
- } else {
-#ifdef NGX_PREFIX
- prefix = (u_char *) NGX_PREFIX;
- plen = ngx_strlen(prefix);
-#else
- plen = 0;
-#endif
- }
-
- if (plen) {
- name = malloc(plen + nlen + 2);
- if (name == NULL) {
- return NULL;
- }
-
- p = ngx_cpymem(name, prefix, plen);
-
- if (!ngx_path_separator(*(p - 1))) {
- *p++ = '/';
- }
-
- ngx_cpystrn(p, (u_char *) NGX_ERROR_LOG_PATH, nlen + 1);
-
- p = name;
- }
- }
-
- ngx_log_file.fd = ngx_open_file(name, NGX_FILE_APPEND,
- NGX_FILE_CREATE_OR_OPEN,
- NGX_FILE_DEFAULT_ACCESS);
-
- if (ngx_log_file.fd == NGX_INVALID_FILE) {
- ngx_log_stderr(ngx_errno,
- "[alert] could not open error log file: "
- ngx_open_file_n " \"%s\" failed", name);
-#if (NGX_WIN32)
- ngx_event_log(ngx_errno,
- "could not open error log file: "
- ngx_open_file_n " \"%s\" failed", name);
-#endif
-
- ngx_log_file.fd = ngx_stderr;
- }
-
- if (p) {
- ngx_free(p);
- }
-
- return &ngx_log;
-}
-
-
-ngx_int_t
-ngx_log_open_default(ngx_cycle_t *cycle)
-{
- ngx_log_t *log;
- static ngx_str_t error_log = ngx_string(NGX_ERROR_LOG_PATH);
-
- if (ngx_log_get_file_log(&cycle->new_log) != NULL) {
- return NGX_OK;
- }
-
- if (cycle->new_log.log_level != 0) {
- /* there are some error logs, but no files */
-
- log = ngx_pcalloc(cycle->pool, sizeof(ngx_log_t));
- if (log == NULL) {
- return NGX_ERROR;
- }
-
- log->log_level = NGX_LOG_ERR;
- ngx_log_insert(&cycle->new_log, log);
-
- } else {
- /* no error logs at all */
- log = &cycle->new_log;
- log->log_level = NGX_LOG_ERR;
- }
-
- log->file = ngx_conf_open_file(cycle, &error_log);
- if (log->file == NULL) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_log_redirect_stderr(ngx_cycle_t *cycle)
-{
- ngx_fd_t fd;
-
- if (cycle->log_use_stderr) {
- return NGX_OK;
- }
-
- /* file log always exists when we are called */
- fd = ngx_log_get_file_log(cycle->log)->file->fd;
-
- if (fd != ngx_stderr) {
- if (ngx_set_stderr(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- ngx_set_stderr_n " failed");
-
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
-}
-
-
-ngx_log_t *
-ngx_log_get_file_log(ngx_log_t *head)
-{
- ngx_log_t *log;
-
- for (log = head; log; log = log->next) {
- if (log->file != NULL) {
- return log;
- }
- }
-
- return NULL;
-}
-
-
-static char *
-ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log)
-{
- ngx_uint_t i, n, d, found;
- ngx_str_t *value;
-
- if (cf->args->nelts == 2) {
- log->log_level = NGX_LOG_ERR;
- return NGX_CONF_OK;
- }
-
- value = cf->args->elts;
-
- for (i = 2; i < cf->args->nelts; i++) {
- found = 0;
-
- for (n = 1; n <= NGX_LOG_DEBUG; n++) {
- if (ngx_strcmp(value[i].data, err_levels[n].data) == 0) {
-
- if (log->log_level != 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate log level \"%V\"",
- &value[i]);
- return NGX_CONF_ERROR;
- }
-
- log->log_level = n;
- found = 1;
- break;
- }
- }
-
- for (n = 0, d = NGX_LOG_DEBUG_FIRST; d <= NGX_LOG_DEBUG_LAST; d <<= 1) {
- if (ngx_strcmp(value[i].data, debug_levels[n++]) == 0) {
- if (log->log_level & ~NGX_LOG_DEBUG_ALL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid log level \"%V\"",
- &value[i]);
- return NGX_CONF_ERROR;
- }
-
- log->log_level |= d;
- found = 1;
- break;
- }
- }
-
-
- if (!found) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid log level \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
- }
-
- if (log->log_level == NGX_LOG_DEBUG) {
- log->log_level = NGX_LOG_DEBUG_ALL;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_log_t *dummy;
-
- dummy = &cf->cycle->new_log;
-
- return ngx_log_set_log(cf, &dummy);
-}
-
-
-char *
-ngx_log_set_log(ngx_conf_t *cf, ngx_log_t **head)
-{
- ngx_log_t *new_log;
- ngx_str_t *value, name;
- ngx_syslog_peer_t *peer;
-
- if (*head != NULL && (*head)->log_level == 0) {
- new_log = *head;
-
- } else {
-
- new_log = ngx_pcalloc(cf->pool, sizeof(ngx_log_t));
- if (new_log == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (*head == NULL) {
- *head = new_log;
- }
- }
-
- value = cf->args->elts;
-
- if (ngx_strcmp(value[1].data, "stderr") == 0) {
- ngx_str_null(&name);
- cf->cycle->log_use_stderr = 1;
-
- new_log->file = ngx_conf_open_file(cf->cycle, &name);
- if (new_log->file == NULL) {
- return NGX_CONF_ERROR;
- }
-
-
- } else if (ngx_strncmp(value[1].data, "syslog:", 7) == 0) {
- peer = ngx_pcalloc(cf->pool, sizeof(ngx_syslog_peer_t));
- if (peer == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (ngx_syslog_process_conf(cf, peer) != NGX_CONF_OK) {
- return NGX_CONF_ERROR;
- }
-
- new_log->writer = ngx_syslog_writer;
- new_log->wdata = peer;
-
- } else {
- new_log->file = ngx_conf_open_file(cf->cycle, &value[1]);
- if (new_log->file == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- if (ngx_log_set_levels(cf, new_log) != NGX_CONF_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (*head != new_log) {
- ngx_log_insert(*head, new_log);
- }
-
- return NGX_CONF_OK;
-}
-
-
-static void
-ngx_log_insert(ngx_log_t *log, ngx_log_t *new_log)
-{
- ngx_log_t tmp;
-
- if (new_log->log_level > log->log_level) {
-
- /*
- * list head address is permanent, insert new log after
- * head and swap its contents with head
- */
-
- tmp = *log;
- *log = *new_log;
- *new_log = tmp;
-
- log->next = new_log;
- return;
- }
-
- while (log->next) {
- if (new_log->log_level > log->next->log_level) {
- new_log->next = log->next;
- log->next = new_log;
- return;
- }
-
- log = log->next;
- }
-
- log->next = new_log;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_log.h b/usr.sbin/nginx/src/core/ngx_log.h
deleted file mode 100644
index c1a52c44f0b..00000000000
--- a/usr.sbin/nginx/src/core/ngx_log.h
+++ /dev/null
@@ -1,259 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_LOG_H_INCLUDED_
-#define _NGX_LOG_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#define NGX_LOG_STDERR 0
-#define NGX_LOG_EMERG 1
-#define NGX_LOG_ALERT 2
-#define NGX_LOG_CRIT 3
-#define NGX_LOG_ERR 4
-#define NGX_LOG_WARN 5
-#define NGX_LOG_NOTICE 6
-#define NGX_LOG_INFO 7
-#define NGX_LOG_DEBUG 8
-
-#define NGX_LOG_DEBUG_CORE 0x010
-#define NGX_LOG_DEBUG_ALLOC 0x020
-#define NGX_LOG_DEBUG_MUTEX 0x040
-#define NGX_LOG_DEBUG_EVENT 0x080
-#define NGX_LOG_DEBUG_HTTP 0x100
-#define NGX_LOG_DEBUG_MAIL 0x200
-#define NGX_LOG_DEBUG_MYSQL 0x400
-
-/*
- * do not forget to update debug_levels[] in src/core/ngx_log.c
- * after the adding a new debug level
- */
-
-#define NGX_LOG_DEBUG_FIRST NGX_LOG_DEBUG_CORE
-#define NGX_LOG_DEBUG_LAST NGX_LOG_DEBUG_MYSQL
-#define NGX_LOG_DEBUG_CONNECTION 0x80000000
-#define NGX_LOG_DEBUG_ALL 0x7ffffff0
-
-
-typedef u_char *(*ngx_log_handler_pt) (ngx_log_t *log, u_char *buf, size_t len);
-typedef void (*ngx_log_writer_pt) (ngx_log_t *log, ngx_uint_t level,
- u_char *buf, size_t len);
-
-
-struct ngx_log_s {
- ngx_uint_t log_level;
- ngx_open_file_t *file;
-
- ngx_atomic_uint_t connection;
-
- ngx_log_handler_pt handler;
- void *data;
-
- ngx_log_writer_pt writer;
- void *wdata;
-
- /*
- * we declare "action" as "char *" because the actions are usually
- * the static strings and in the "u_char *" case we have to override
- * their types all the time
- */
-
- char *action;
-
- ngx_log_t *next;
-};
-
-
-#define NGX_MAX_ERROR_STR 2048
-
-
-/*********************************/
-
-#if (NGX_HAVE_C99_VARIADIC_MACROS)
-
-#define NGX_HAVE_VARIADIC_MACROS 1
-
-#define ngx_log_error(level, log, ...) \
- if ((log)->log_level >= level) ngx_log_error_core(level, log, __VA_ARGS__)
-
-void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
- const char *fmt, ...);
-
-#define ngx_log_debug(level, log, ...) \
- if ((log)->log_level & level) \
- ngx_log_error_core(NGX_LOG_DEBUG, log, __VA_ARGS__)
-
-/*********************************/
-
-#elif (NGX_HAVE_GCC_VARIADIC_MACROS)
-
-#define NGX_HAVE_VARIADIC_MACROS 1
-
-#define ngx_log_error(level, log, args...) \
- if ((log)->log_level >= level) ngx_log_error_core(level, log, args)
-
-void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
- const char *fmt, ...);
-
-#define ngx_log_debug(level, log, args...) \
- if ((log)->log_level & level) \
- ngx_log_error_core(NGX_LOG_DEBUG, log, args)
-
-/*********************************/
-
-#else /* NO VARIADIC MACROS */
-
-#define NGX_HAVE_VARIADIC_MACROS 0
-
-void ngx_cdecl ngx_log_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
- const char *fmt, ...);
-void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
- const char *fmt, va_list args);
-void ngx_cdecl ngx_log_debug_core(ngx_log_t *log, ngx_err_t err,
- const char *fmt, ...);
-
-
-#endif /* VARIADIC MACROS */
-
-
-/*********************************/
-
-#if (NGX_DEBUG)
-
-#if (NGX_HAVE_VARIADIC_MACROS)
-
-#define ngx_log_debug0(level, log, err, fmt) \
- ngx_log_debug(level, log, err, fmt)
-
-#define ngx_log_debug1(level, log, err, fmt, arg1) \
- ngx_log_debug(level, log, err, fmt, arg1)
-
-#define ngx_log_debug2(level, log, err, fmt, arg1, arg2) \
- ngx_log_debug(level, log, err, fmt, arg1, arg2)
-
-#define ngx_log_debug3(level, log, err, fmt, arg1, arg2, arg3) \
- ngx_log_debug(level, log, err, fmt, arg1, arg2, arg3)
-
-#define ngx_log_debug4(level, log, err, fmt, arg1, arg2, arg3, arg4) \
- ngx_log_debug(level, log, err, fmt, arg1, arg2, arg3, arg4)
-
-#define ngx_log_debug5(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5) \
- ngx_log_debug(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5)
-
-#define ngx_log_debug6(level, log, err, fmt, \
- arg1, arg2, arg3, arg4, arg5, arg6) \
- ngx_log_debug(level, log, err, fmt, \
- arg1, arg2, arg3, arg4, arg5, arg6)
-
-#define ngx_log_debug7(level, log, err, fmt, \
- arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
- ngx_log_debug(level, log, err, fmt, \
- arg1, arg2, arg3, arg4, arg5, arg6, arg7)
-
-#define ngx_log_debug8(level, log, err, fmt, \
- arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
- ngx_log_debug(level, log, err, fmt, \
- arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
-
-
-#else /* NO VARIADIC MACROS */
-
-#define ngx_log_debug0(level, log, err, fmt) \
- if ((log)->log_level & level) \
- ngx_log_debug_core(log, err, fmt)
-
-#define ngx_log_debug1(level, log, err, fmt, arg1) \
- if ((log)->log_level & level) \
- ngx_log_debug_core(log, err, fmt, arg1)
-
-#define ngx_log_debug2(level, log, err, fmt, arg1, arg2) \
- if ((log)->log_level & level) \
- ngx_log_debug_core(log, err, fmt, arg1, arg2)
-
-#define ngx_log_debug3(level, log, err, fmt, arg1, arg2, arg3) \
- if ((log)->log_level & level) \
- ngx_log_debug_core(log, err, fmt, arg1, arg2, arg3)
-
-#define ngx_log_debug4(level, log, err, fmt, arg1, arg2, arg3, arg4) \
- if ((log)->log_level & level) \
- ngx_log_debug_core(log, err, fmt, arg1, arg2, arg3, arg4)
-
-#define ngx_log_debug5(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5) \
- if ((log)->log_level & level) \
- ngx_log_debug_core(log, err, fmt, arg1, arg2, arg3, arg4, arg5)
-
-#define ngx_log_debug6(level, log, err, fmt, \
- arg1, arg2, arg3, arg4, arg5, arg6) \
- if ((log)->log_level & level) \
- ngx_log_debug_core(log, err, fmt, arg1, arg2, arg3, arg4, arg5, arg6)
-
-#define ngx_log_debug7(level, log, err, fmt, \
- arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
- if ((log)->log_level & level) \
- ngx_log_debug_core(log, err, fmt, \
- arg1, arg2, arg3, arg4, arg5, arg6, arg7)
-
-#define ngx_log_debug8(level, log, err, fmt, \
- arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
- if ((log)->log_level & level) \
- ngx_log_debug_core(log, err, fmt, \
- arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
-
-#endif
-
-#else /* NO NGX_DEBUG */
-
-#define ngx_log_debug0(level, log, err, fmt)
-#define ngx_log_debug1(level, log, err, fmt, arg1)
-#define ngx_log_debug2(level, log, err, fmt, arg1, arg2)
-#define ngx_log_debug3(level, log, err, fmt, arg1, arg2, arg3)
-#define ngx_log_debug4(level, log, err, fmt, arg1, arg2, arg3, arg4)
-#define ngx_log_debug5(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5)
-#define ngx_log_debug6(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5, arg6)
-#define ngx_log_debug7(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5, \
- arg6, arg7)
-#define ngx_log_debug8(level, log, err, fmt, arg1, arg2, arg3, arg4, arg5, \
- arg6, arg7, arg8)
-
-#endif
-
-/*********************************/
-
-ngx_log_t *ngx_log_init(u_char *prefix);
-void ngx_cdecl ngx_log_abort(ngx_err_t err, const char *fmt, ...);
-void ngx_cdecl ngx_log_stderr(ngx_err_t err, const char *fmt, ...);
-u_char *ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err);
-ngx_int_t ngx_log_open_default(ngx_cycle_t *cycle);
-ngx_int_t ngx_log_redirect_stderr(ngx_cycle_t *cycle);
-ngx_log_t *ngx_log_get_file_log(ngx_log_t *head);
-char *ngx_log_set_log(ngx_conf_t *cf, ngx_log_t **head);
-
-
-/*
- * ngx_write_stderr() cannot be implemented as macro, since
- * MSVC does not allow to use #ifdef inside macro parameters.
- *
- * ngx_write_fd() is used instead of ngx_write_console(), since
- * CharToOemBuff() inside ngx_write_console() cannot be used with
- * read only buffer as destination and CharToOemBuff() is not needed
- * for ngx_write_stderr() anyway.
- */
-static ngx_inline void
-ngx_write_stderr(char *text)
-{
- (void) ngx_write_fd(ngx_stderr, text, strlen(text));
-}
-
-
-extern ngx_module_t ngx_errlog_module;
-extern ngx_uint_t ngx_use_stderr;
-
-
-#endif /* _NGX_LOG_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_md5.c b/usr.sbin/nginx/src/core/ngx_md5.c
deleted file mode 100644
index 440c75bca6f..00000000000
--- a/usr.sbin/nginx/src/core/ngx_md5.c
+++ /dev/null
@@ -1,289 +0,0 @@
-
-/*
- * An internal implementation, based on Alexander Peslyak's
- * public domain implementation:
- * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
- * It is not expected to be optimal and is used only
- * if no MD5 implementation was found in system.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_md5.h>
-
-
-#if !(NGX_HAVE_MD5)
-
-static const u_char *ngx_md5_body(ngx_md5_t *ctx, const u_char *data,
- size_t size);
-
-
-void
-ngx_md5_init(ngx_md5_t *ctx)
-{
- ctx->a = 0x67452301;
- ctx->b = 0xefcdab89;
- ctx->c = 0x98badcfe;
- ctx->d = 0x10325476;
-
- ctx->bytes = 0;
-}
-
-
-void
-ngx_md5_update(ngx_md5_t *ctx, const void *data, size_t size)
-{
- size_t used, free;
-
- used = (size_t) (ctx->bytes & 0x3f);
- ctx->bytes += size;
-
- if (used) {
- free = 64 - used;
-
- if (size < free) {
- ngx_memcpy(&ctx->buffer[used], data, size);
- return;
- }
-
- ngx_memcpy(&ctx->buffer[used], data, free);
- data = (u_char *) data + free;
- size -= free;
- (void) ngx_md5_body(ctx, ctx->buffer, 64);
- }
-
- if (size >= 64) {
- data = ngx_md5_body(ctx, data, size & ~(size_t) 0x3f);
- size &= 0x3f;
- }
-
- ngx_memcpy(ctx->buffer, data, size);
-}
-
-
-void
-ngx_md5_final(u_char result[16], ngx_md5_t *ctx)
-{
- size_t used, free;
-
- used = (size_t) (ctx->bytes & 0x3f);
-
- ctx->buffer[used++] = 0x80;
-
- free = 64 - used;
-
- if (free < 8) {
- ngx_memzero(&ctx->buffer[used], free);
- (void) ngx_md5_body(ctx, ctx->buffer, 64);
- used = 0;
- free = 64;
- }
-
- ngx_memzero(&ctx->buffer[used], free - 8);
-
- ctx->bytes <<= 3;
- ctx->buffer[56] = (u_char) ctx->bytes;
- ctx->buffer[57] = (u_char) (ctx->bytes >> 8);
- ctx->buffer[58] = (u_char) (ctx->bytes >> 16);
- ctx->buffer[59] = (u_char) (ctx->bytes >> 24);
- ctx->buffer[60] = (u_char) (ctx->bytes >> 32);
- ctx->buffer[61] = (u_char) (ctx->bytes >> 40);
- ctx->buffer[62] = (u_char) (ctx->bytes >> 48);
- ctx->buffer[63] = (u_char) (ctx->bytes >> 56);
-
- (void) ngx_md5_body(ctx, ctx->buffer, 64);
-
- result[0] = (u_char) ctx->a;
- result[1] = (u_char) (ctx->a >> 8);
- result[2] = (u_char) (ctx->a >> 16);
- result[3] = (u_char) (ctx->a >> 24);
- result[4] = (u_char) ctx->b;
- result[5] = (u_char) (ctx->b >> 8);
- result[6] = (u_char) (ctx->b >> 16);
- result[7] = (u_char) (ctx->b >> 24);
- result[8] = (u_char) ctx->c;
- result[9] = (u_char) (ctx->c >> 8);
- result[10] = (u_char) (ctx->c >> 16);
- result[11] = (u_char) (ctx->c >> 24);
- result[12] = (u_char) ctx->d;
- result[13] = (u_char) (ctx->d >> 8);
- result[14] = (u_char) (ctx->d >> 16);
- result[15] = (u_char) (ctx->d >> 24);
-
- ngx_memzero(ctx, sizeof(*ctx));
-}
-
-
-/*
- * The basic MD5 functions.
- *
- * F and G are optimized compared to their RFC 1321 definitions for
- * architectures that lack an AND-NOT instruction, just like in
- * Colin Plumb's implementation.
- */
-
-#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
-#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-
-/*
- * The MD5 transformation for all four rounds.
- */
-
-#define STEP(f, a, b, c, d, x, t, s) \
- (a) += f((b), (c), (d)) + (x) + (t); \
- (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
- (a) += (b)
-
-/*
- * SET() reads 4 input bytes in little-endian byte order and stores them
- * in a properly aligned word in host byte order.
- *
- * The check for little-endian architectures that tolerate unaligned
- * memory accesses is just an optimization. Nothing will break if it
- * does not work.
- */
-
-#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED)
-
-#define SET(n) (*(uint32_t *) &p[n * 4])
-#define GET(n) (*(uint32_t *) &p[n * 4])
-
-#else
-
-#define SET(n) \
- (block[n] = \
- (uint32_t) p[n * 4] | \
- ((uint32_t) p[n * 4 + 1] << 8) | \
- ((uint32_t) p[n * 4 + 2] << 16) | \
- ((uint32_t) p[n * 4 + 3] << 24))
-
-#define GET(n) block[n]
-
-#endif
-
-
-/*
- * This processes one or more 64-byte data blocks, but does not update
- * the bit counters. There are no alignment requirements.
- */
-
-static const u_char *
-ngx_md5_body(ngx_md5_t *ctx, const u_char *data, size_t size)
-{
- uint32_t a, b, c, d;
- uint32_t saved_a, saved_b, saved_c, saved_d;
- const u_char *p;
-#if !(NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED)
- uint32_t block[16];
-#endif
-
- p = data;
-
- a = ctx->a;
- b = ctx->b;
- c = ctx->c;
- d = ctx->d;
-
- do {
- saved_a = a;
- saved_b = b;
- saved_c = c;
- saved_d = d;
-
- /* Round 1 */
-
- STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7);
- STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12);
- STEP(F, c, d, a, b, SET(2), 0x242070db, 17);
- STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22);
- STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7);
- STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12);
- STEP(F, c, d, a, b, SET(6), 0xa8304613, 17);
- STEP(F, b, c, d, a, SET(7), 0xfd469501, 22);
- STEP(F, a, b, c, d, SET(8), 0x698098d8, 7);
- STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12);
- STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17);
- STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22);
- STEP(F, a, b, c, d, SET(12), 0x6b901122, 7);
- STEP(F, d, a, b, c, SET(13), 0xfd987193, 12);
- STEP(F, c, d, a, b, SET(14), 0xa679438e, 17);
- STEP(F, b, c, d, a, SET(15), 0x49b40821, 22);
-
- /* Round 2 */
-
- STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5);
- STEP(G, d, a, b, c, GET(6), 0xc040b340, 9);
- STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14);
- STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20);
- STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5);
- STEP(G, d, a, b, c, GET(10), 0x02441453, 9);
- STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14);
- STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20);
- STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5);
- STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9);
- STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14);
- STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20);
- STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5);
- STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9);
- STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14);
- STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20);
-
- /* Round 3 */
-
- STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4);
- STEP(H, d, a, b, c, GET(8), 0x8771f681, 11);
- STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16);
- STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23);
- STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4);
- STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11);
- STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16);
- STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23);
- STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4);
- STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11);
- STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16);
- STEP(H, b, c, d, a, GET(6), 0x04881d05, 23);
- STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4);
- STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11);
- STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16);
- STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23);
-
- /* Round 4 */
-
- STEP(I, a, b, c, d, GET(0), 0xf4292244, 6);
- STEP(I, d, a, b, c, GET(7), 0x432aff97, 10);
- STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15);
- STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21);
- STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6);
- STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10);
- STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15);
- STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21);
- STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6);
- STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10);
- STEP(I, c, d, a, b, GET(6), 0xa3014314, 15);
- STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21);
- STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6);
- STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10);
- STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15);
- STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21);
-
- a += saved_a;
- b += saved_b;
- c += saved_c;
- d += saved_d;
-
- p += 64;
-
- } while (size -= 64);
-
- ctx->a = a;
- ctx->b = b;
- ctx->c = c;
- ctx->d = d;
-
- return p;
-}
-
-#endif
diff --git a/usr.sbin/nginx/src/core/ngx_md5.h b/usr.sbin/nginx/src/core/ngx_md5.h
deleted file mode 100644
index 18d09d6d59a..00000000000
--- a/usr.sbin/nginx/src/core/ngx_md5.h
+++ /dev/null
@@ -1,60 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_MD5_H_INCLUDED_
-#define _NGX_MD5_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#if (NGX_HAVE_MD5)
-
-#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
-
-
-#else /* !NGX_HAVE_MD5 */
-
-
-typedef struct {
- uint64_t bytes;
- uint32_t a, b, c, d;
- u_char buffer[64];
-} ngx_md5_t;
-
-
-void ngx_md5_init(ngx_md5_t *ctx);
-void ngx_md5_update(ngx_md5_t *ctx, const void *data, size_t size);
-void ngx_md5_final(u_char result[16], ngx_md5_t *ctx);
-
-
-#endif
-
-#endif /* _NGX_MD5_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_murmurhash.c b/usr.sbin/nginx/src/core/ngx_murmurhash.c
deleted file mode 100644
index c31e0e03500..00000000000
--- a/usr.sbin/nginx/src/core/ngx_murmurhash.c
+++ /dev/null
@@ -1,50 +0,0 @@
-
-/*
- * Copyright (C) Austin Appleby
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-uint32_t
-ngx_murmur_hash2(u_char *data, size_t len)
-{
- uint32_t h, k;
-
- h = 0 ^ len;
-
- while (len >= 4) {
- k = data[0];
- k |= data[1] << 8;
- k |= data[2] << 16;
- k |= data[3] << 24;
-
- k *= 0x5bd1e995;
- k ^= k >> 24;
- k *= 0x5bd1e995;
-
- h *= 0x5bd1e995;
- h ^= k;
-
- data += 4;
- len -= 4;
- }
-
- switch (len) {
- case 3:
- h ^= data[2] << 16;
- case 2:
- h ^= data[1] << 8;
- case 1:
- h ^= data[0];
- h *= 0x5bd1e995;
- }
-
- h ^= h >> 13;
- h *= 0x5bd1e995;
- h ^= h >> 15;
-
- return h;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_murmurhash.h b/usr.sbin/nginx/src/core/ngx_murmurhash.h
deleted file mode 100644
index 54e867d303a..00000000000
--- a/usr.sbin/nginx/src/core/ngx_murmurhash.h
+++ /dev/null
@@ -1,19 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_MURMURHASH_H_INCLUDED_
-#define _NGX_MURMURHASH_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-uint32_t ngx_murmur_hash2(u_char *data, size_t len);
-
-
-#endif /* _NGX_MURMURHASH_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_open_file_cache.c b/usr.sbin/nginx/src/core/ngx_open_file_cache.c
deleted file mode 100644
index 4df2134b2bd..00000000000
--- a/usr.sbin/nginx/src/core/ngx_open_file_cache.c
+++ /dev/null
@@ -1,1253 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-/*
- * open file cache caches
- * open file handles with stat() info;
- * directories stat() info;
- * files and directories errors: not found, access denied, etc.
- */
-
-
-#define NGX_MIN_READ_AHEAD (128 * 1024)
-
-
-static void ngx_open_file_cache_cleanup(void *data);
-#if (NGX_HAVE_OPENAT)
-static ngx_fd_t ngx_openat_file_owner(ngx_fd_t at_fd, const u_char *name,
- ngx_int_t mode, ngx_int_t create, ngx_int_t access, ngx_log_t *log);
-#if (NGX_HAVE_O_PATH)
-static ngx_int_t ngx_file_o_path_info(ngx_fd_t fd, ngx_file_info_t *fi,
- ngx_log_t *log);
-#endif
-#endif
-static ngx_fd_t ngx_open_file_wrapper(ngx_str_t *name,
- ngx_open_file_info_t *of, ngx_int_t mode, ngx_int_t create,
- ngx_int_t access, ngx_log_t *log);
-static ngx_int_t ngx_file_info_wrapper(ngx_str_t *name,
- ngx_open_file_info_t *of, ngx_file_info_t *fi, ngx_log_t *log);
-static ngx_int_t ngx_open_and_stat_file(ngx_str_t *name,
- ngx_open_file_info_t *of, ngx_log_t *log);
-static void ngx_open_file_add_event(ngx_open_file_cache_t *cache,
- ngx_cached_open_file_t *file, ngx_open_file_info_t *of, ngx_log_t *log);
-static void ngx_open_file_cleanup(void *data);
-static void ngx_close_cached_file(ngx_open_file_cache_t *cache,
- ngx_cached_open_file_t *file, ngx_uint_t min_uses, ngx_log_t *log);
-static void ngx_open_file_del_event(ngx_cached_open_file_t *file);
-static void ngx_expire_old_cached_files(ngx_open_file_cache_t *cache,
- ngx_uint_t n, ngx_log_t *log);
-static void ngx_open_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
-static ngx_cached_open_file_t *
- ngx_open_file_lookup(ngx_open_file_cache_t *cache, ngx_str_t *name,
- uint32_t hash);
-static void ngx_open_file_cache_remove(ngx_event_t *ev);
-
-
-ngx_open_file_cache_t *
-ngx_open_file_cache_init(ngx_pool_t *pool, ngx_uint_t max, time_t inactive)
-{
- ngx_pool_cleanup_t *cln;
- ngx_open_file_cache_t *cache;
-
- cache = ngx_palloc(pool, sizeof(ngx_open_file_cache_t));
- if (cache == NULL) {
- return NULL;
- }
-
- ngx_rbtree_init(&cache->rbtree, &cache->sentinel,
- ngx_open_file_cache_rbtree_insert_value);
-
- ngx_queue_init(&cache->expire_queue);
-
- cache->current = 0;
- cache->max = max;
- cache->inactive = inactive;
-
- cln = ngx_pool_cleanup_add(pool, 0);
- if (cln == NULL) {
- return NULL;
- }
-
- cln->handler = ngx_open_file_cache_cleanup;
- cln->data = cache;
-
- return cache;
-}
-
-
-static void
-ngx_open_file_cache_cleanup(void *data)
-{
- ngx_open_file_cache_t *cache = data;
-
- ngx_queue_t *q;
- ngx_cached_open_file_t *file;
-
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
- "open file cache cleanup");
-
- for ( ;; ) {
-
- if (ngx_queue_empty(&cache->expire_queue)) {
- break;
- }
-
- q = ngx_queue_last(&cache->expire_queue);
-
- file = ngx_queue_data(q, ngx_cached_open_file_t, queue);
-
- ngx_queue_remove(q);
-
- ngx_rbtree_delete(&cache->rbtree, &file->node);
-
- cache->current--;
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
- "delete cached open file: %s", file->name);
-
- if (!file->err && !file->is_dir) {
- file->close = 1;
- file->count = 0;
- ngx_close_cached_file(cache, file, 0, ngx_cycle->log);
-
- } else {
- ngx_free(file->name);
- ngx_free(file);
- }
- }
-
- if (cache->current) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
- "%ui items still leave in open file cache",
- cache->current);
- }
-
- if (cache->rbtree.root != cache->rbtree.sentinel) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
- "rbtree still is not empty in open file cache");
-
- }
-}
-
-
-ngx_int_t
-ngx_open_cached_file(ngx_open_file_cache_t *cache, ngx_str_t *name,
- ngx_open_file_info_t *of, ngx_pool_t *pool)
-{
- time_t now;
- uint32_t hash;
- ngx_int_t rc;
- ngx_file_info_t fi;
- ngx_pool_cleanup_t *cln;
- ngx_cached_open_file_t *file;
- ngx_pool_cleanup_file_t *clnf;
- ngx_open_file_cache_cleanup_t *ofcln;
-
- of->fd = NGX_INVALID_FILE;
- of->err = 0;
-
- if (cache == NULL) {
-
- if (of->test_only) {
-
- if (ngx_file_info_wrapper(name, of, &fi, pool->log)
- == NGX_FILE_ERROR)
- {
- return NGX_ERROR;
- }
-
- of->uniq = ngx_file_uniq(&fi);
- of->mtime = ngx_file_mtime(&fi);
- of->size = ngx_file_size(&fi);
- of->fs_size = ngx_file_fs_size(&fi);
- of->is_dir = ngx_is_dir(&fi);
- of->is_file = ngx_is_file(&fi);
- of->is_link = ngx_is_link(&fi);
- of->is_exec = ngx_is_exec(&fi);
-
- return NGX_OK;
- }
-
- cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t));
- if (cln == NULL) {
- return NGX_ERROR;
- }
-
- rc = ngx_open_and_stat_file(name, of, pool->log);
-
- if (rc == NGX_OK && !of->is_dir) {
- cln->handler = ngx_pool_cleanup_file;
- clnf = cln->data;
-
- clnf->fd = of->fd;
- clnf->name = name->data;
- clnf->log = pool->log;
- }
-
- return rc;
- }
-
- cln = ngx_pool_cleanup_add(pool, sizeof(ngx_open_file_cache_cleanup_t));
- if (cln == NULL) {
- return NGX_ERROR;
- }
-
- now = ngx_time();
-
- hash = ngx_crc32_long(name->data, name->len);
-
- file = ngx_open_file_lookup(cache, name, hash);
-
- if (file) {
-
- file->uses++;
-
- ngx_queue_remove(&file->queue);
-
- if (file->fd == NGX_INVALID_FILE && file->err == 0 && !file->is_dir) {
-
- /* file was not used often enough to keep open */
-
- rc = ngx_open_and_stat_file(name, of, pool->log);
-
- if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
- goto failed;
- }
-
- goto add_event;
- }
-
- if (file->use_event
- || (file->event == NULL
- && (of->uniq == 0 || of->uniq == file->uniq)
- && now - file->created < of->valid
-#if (NGX_HAVE_OPENAT)
- && of->disable_symlinks == file->disable_symlinks
- && of->disable_symlinks_from == file->disable_symlinks_from
-#endif
- ))
- {
- if (file->err == 0) {
-
- of->fd = file->fd;
- of->uniq = file->uniq;
- of->mtime = file->mtime;
- of->size = file->size;
-
- of->is_dir = file->is_dir;
- of->is_file = file->is_file;
- of->is_link = file->is_link;
- of->is_exec = file->is_exec;
- of->is_directio = file->is_directio;
-
- if (!file->is_dir) {
- file->count++;
- ngx_open_file_add_event(cache, file, of, pool->log);
- }
-
- } else {
- of->err = file->err;
-#if (NGX_HAVE_OPENAT)
- of->failed = file->disable_symlinks ? ngx_openat_file_n
- : ngx_open_file_n;
-#else
- of->failed = ngx_open_file_n;
-#endif
- }
-
- goto found;
- }
-
- ngx_log_debug4(NGX_LOG_DEBUG_CORE, pool->log, 0,
- "retest open file: %s, fd:%d, c:%d, e:%d",
- file->name, file->fd, file->count, file->err);
-
- if (file->is_dir) {
-
- /*
- * chances that directory became file are very small
- * so test_dir flag allows to use a single syscall
- * in ngx_file_info() instead of three syscalls
- */
-
- of->test_dir = 1;
- }
-
- of->fd = file->fd;
- of->uniq = file->uniq;
-
- rc = ngx_open_and_stat_file(name, of, pool->log);
-
- if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
- goto failed;
- }
-
- if (of->is_dir) {
-
- if (file->is_dir || file->err) {
- goto update;
- }
-
- /* file became directory */
-
- } else if (of->err == 0) { /* file */
-
- if (file->is_dir || file->err) {
- goto add_event;
- }
-
- if (of->uniq == file->uniq) {
-
- if (file->event) {
- file->use_event = 1;
- }
-
- of->is_directio = file->is_directio;
-
- goto update;
- }
-
- /* file was changed */
-
- } else { /* error to cache */
-
- if (file->err || file->is_dir) {
- goto update;
- }
-
- /* file was removed, etc. */
- }
-
- if (file->count == 0) {
-
- ngx_open_file_del_event(file);
-
- if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
- ngx_close_file_n " \"%V\" failed", name);
- }
-
- goto add_event;
- }
-
- ngx_rbtree_delete(&cache->rbtree, &file->node);
-
- cache->current--;
-
- file->close = 1;
-
- goto create;
- }
-
- /* not found */
-
- rc = ngx_open_and_stat_file(name, of, pool->log);
-
- if (rc != NGX_OK && (of->err == 0 || !of->errors)) {
- goto failed;
- }
-
-create:
-
- if (cache->current >= cache->max) {
- ngx_expire_old_cached_files(cache, 0, pool->log);
- }
-
- file = ngx_alloc(sizeof(ngx_cached_open_file_t), pool->log);
-
- if (file == NULL) {
- goto failed;
- }
-
- file->name = ngx_alloc(name->len + 1, pool->log);
-
- if (file->name == NULL) {
- ngx_free(file);
- file = NULL;
- goto failed;
- }
-
- ngx_cpystrn(file->name, name->data, name->len + 1);
-
- file->node.key = hash;
-
- ngx_rbtree_insert(&cache->rbtree, &file->node);
-
- cache->current++;
-
- file->uses = 1;
- file->count = 0;
- file->use_event = 0;
- file->event = NULL;
-
-add_event:
-
- ngx_open_file_add_event(cache, file, of, pool->log);
-
-update:
-
- file->fd = of->fd;
- file->err = of->err;
-#if (NGX_HAVE_OPENAT)
- file->disable_symlinks = of->disable_symlinks;
- file->disable_symlinks_from = of->disable_symlinks_from;
-#endif
-
- if (of->err == 0) {
- file->uniq = of->uniq;
- file->mtime = of->mtime;
- file->size = of->size;
-
- file->close = 0;
-
- file->is_dir = of->is_dir;
- file->is_file = of->is_file;
- file->is_link = of->is_link;
- file->is_exec = of->is_exec;
- file->is_directio = of->is_directio;
-
- if (!of->is_dir) {
- file->count++;
- }
- }
-
- file->created = now;
-
-found:
-
- file->accessed = now;
-
- ngx_queue_insert_head(&cache->expire_queue, &file->queue);
-
- ngx_log_debug5(NGX_LOG_DEBUG_CORE, pool->log, 0,
- "cached open file: %s, fd:%d, c:%d, e:%d, u:%d",
- file->name, file->fd, file->count, file->err, file->uses);
-
- if (of->err == 0) {
-
- if (!of->is_dir) {
- cln->handler = ngx_open_file_cleanup;
- ofcln = cln->data;
-
- ofcln->cache = cache;
- ofcln->file = file;
- ofcln->min_uses = of->min_uses;
- ofcln->log = pool->log;
- }
-
- return NGX_OK;
- }
-
- return NGX_ERROR;
-
-failed:
-
- if (file) {
- ngx_rbtree_delete(&cache->rbtree, &file->node);
-
- cache->current--;
-
- if (file->count == 0) {
-
- if (file->fd != NGX_INVALID_FILE) {
- if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed",
- file->name);
- }
- }
-
- ngx_free(file->name);
- ngx_free(file);
-
- } else {
- file->close = 1;
- }
- }
-
- if (of->fd != NGX_INVALID_FILE) {
- if (ngx_close_file(of->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, pool->log, ngx_errno,
- ngx_close_file_n " \"%V\" failed", name);
- }
- }
-
- return NGX_ERROR;
-}
-
-
-#if (NGX_HAVE_OPENAT)
-
-static ngx_fd_t
-ngx_openat_file_owner(ngx_fd_t at_fd, const u_char *name,
- ngx_int_t mode, ngx_int_t create, ngx_int_t access, ngx_log_t *log)
-{
- ngx_fd_t fd;
- ngx_err_t err;
- ngx_file_info_t fi, atfi;
-
- /*
- * To allow symlinks with the same owner, use openat() (followed
- * by fstat()) and fstatat(AT_SYMLINK_NOFOLLOW), and then compare
- * uids between fstat() and fstatat().
- *
- * As there is a race between openat() and fstatat() we don't
- * know if openat() in fact opened symlink or not. Therefore,
- * we have to compare uids even if fstatat() reports the opened
- * component isn't a symlink (as we don't know whether it was
- * symlink during openat() or not).
- */
-
- fd = ngx_openat_file(at_fd, name, mode, create, access);
-
- if (fd == NGX_INVALID_FILE) {
- return NGX_INVALID_FILE;
- }
-
- if (ngx_file_at_info(at_fd, name, &atfi, AT_SYMLINK_NOFOLLOW)
- == NGX_FILE_ERROR)
- {
- err = ngx_errno;
- goto failed;
- }
-
-#if (NGX_HAVE_O_PATH)
- if (ngx_file_o_path_info(fd, &fi, log) == NGX_ERROR) {
- err = ngx_errno;
- goto failed;
- }
-#else
- if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
- err = ngx_errno;
- goto failed;
- }
-#endif
-
- if (fi.st_uid != atfi.st_uid) {
- err = NGX_ELOOP;
- goto failed;
- }
-
- return fd;
-
-failed:
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%V\" failed", name);
- }
-
- ngx_set_errno(err);
-
- return NGX_INVALID_FILE;
-}
-
-
-#if (NGX_HAVE_O_PATH)
-
-static ngx_int_t
-ngx_file_o_path_info(ngx_fd_t fd, ngx_file_info_t *fi, ngx_log_t *log)
-{
- static ngx_uint_t use_fstat = 1;
-
- /*
- * In Linux 2.6.39 the O_PATH flag was introduced that allows to obtain
- * a descriptor without actually opening file or directory. It requires
- * less permissions for path components, but till Linux 3.6 fstat() returns
- * EBADF on such descriptors, and fstatat() with the AT_EMPTY_PATH flag
- * should be used instead.
- *
- * Three scenarios are handled in this function:
- *
- * 1) The kernel is newer than 3.6 or fstat() with O_PATH support was
- * backported by vendor. Then fstat() is used.
- *
- * 2) The kernel is newer than 2.6.39 but older than 3.6. In this case
- * the first call of fstat() returns EBADF and we fallback to fstatat()
- * with AT_EMPTY_PATH which was introduced at the same time as O_PATH.
- *
- * 3) The kernel is older than 2.6.39 but nginx was build with O_PATH
- * support. Since descriptors are opened with O_PATH|O_RDONLY flags
- * and O_PATH is ignored by the kernel then the O_RDONLY flag is
- * actually used. In this case fstat() just works.
- */
-
- if (use_fstat) {
- if (ngx_fd_info(fd, fi) != NGX_FILE_ERROR) {
- return NGX_OK;
- }
-
- if (ngx_errno != NGX_EBADF) {
- return NGX_ERROR;
- }
-
- ngx_log_error(NGX_LOG_NOTICE, log, 0,
- "fstat(O_PATH) failed with EBADF, "
- "switching to fstatat(AT_EMPTY_PATH)");
-
- use_fstat = 0;
- }
-
- if (ngx_file_at_info(fd, "", fi, AT_EMPTY_PATH) != NGX_FILE_ERROR) {
- return NGX_OK;
- }
-
- return NGX_ERROR;
-}
-
-#endif
-
-#endif /* NGX_HAVE_OPENAT */
-
-
-static ngx_fd_t
-ngx_open_file_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,
- ngx_int_t mode, ngx_int_t create, ngx_int_t access, ngx_log_t *log)
-{
- ngx_fd_t fd;
-
-#if !(NGX_HAVE_OPENAT)
-
- fd = ngx_open_file(name->data, mode, create, access);
-
- if (fd == NGX_INVALID_FILE) {
- of->err = ngx_errno;
- of->failed = ngx_open_file_n;
- return NGX_INVALID_FILE;
- }
-
- return fd;
-
-#else
-
- u_char *p, *cp, *end;
- ngx_fd_t at_fd;
- ngx_str_t at_name;
-
- if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
- fd = ngx_open_file(name->data, mode, create, access);
-
- if (fd == NGX_INVALID_FILE) {
- of->err = ngx_errno;
- of->failed = ngx_open_file_n;
- return NGX_INVALID_FILE;
- }
-
- return fd;
- }
-
- p = name->data;
- end = p + name->len;
-
- at_name = *name;
-
- if (of->disable_symlinks_from) {
-
- cp = p + of->disable_symlinks_from;
-
- *cp = '\0';
-
- at_fd = ngx_open_file(p, NGX_FILE_SEARCH|NGX_FILE_NONBLOCK,
- NGX_FILE_OPEN, 0);
-
- *cp = '/';
-
- if (at_fd == NGX_INVALID_FILE) {
- of->err = ngx_errno;
- of->failed = ngx_open_file_n;
- return NGX_INVALID_FILE;
- }
-
- at_name.len = of->disable_symlinks_from;
- p = cp + 1;
-
- } else if (*p == '/') {
-
- at_fd = ngx_open_file("/",
- NGX_FILE_SEARCH|NGX_FILE_NONBLOCK,
- NGX_FILE_OPEN, 0);
-
- if (at_fd == NGX_INVALID_FILE) {
- of->err = ngx_errno;
- of->failed = ngx_openat_file_n;
- return NGX_INVALID_FILE;
- }
-
- at_name.len = 1;
- p++;
-
- } else {
- at_fd = NGX_AT_FDCWD;
- }
-
- for ( ;; ) {
- cp = ngx_strlchr(p, end, '/');
- if (cp == NULL) {
- break;
- }
-
- if (cp == p) {
- p++;
- continue;
- }
-
- *cp = '\0';
-
- if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER) {
- fd = ngx_openat_file_owner(at_fd, p,
- NGX_FILE_SEARCH|NGX_FILE_NONBLOCK,
- NGX_FILE_OPEN, 0, log);
-
- } else {
- fd = ngx_openat_file(at_fd, p,
- NGX_FILE_SEARCH|NGX_FILE_NONBLOCK|NGX_FILE_NOFOLLOW,
- NGX_FILE_OPEN, 0);
- }
-
- *cp = '/';
-
- if (fd == NGX_INVALID_FILE) {
- of->err = ngx_errno;
- of->failed = ngx_openat_file_n;
- goto failed;
- }
-
- if (at_fd != NGX_AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%V\" failed", &at_name);
- }
-
- p = cp + 1;
- at_fd = fd;
- at_name.len = cp - at_name.data;
- }
-
- if (p == end) {
-
- /*
- * If pathname ends with a trailing slash, assume the last path
- * component is a directory and reopen it with requested flags;
- * if not, fail with ENOTDIR as per POSIX.
- *
- * We cannot rely on O_DIRECTORY in the loop above to check
- * that the last path component is a directory because
- * O_DIRECTORY doesn't work on FreeBSD 8. Fortunately, by
- * reopening a directory, we don't depend on it at all.
- */
-
- fd = ngx_openat_file(at_fd, ".", mode, create, access);
- goto done;
- }
-
- if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_NOTOWNER
- && !(create & (NGX_FILE_CREATE_OR_OPEN|NGX_FILE_TRUNCATE)))
- {
- fd = ngx_openat_file_owner(at_fd, p, mode, create, access, log);
-
- } else {
- fd = ngx_openat_file(at_fd, p, mode|NGX_FILE_NOFOLLOW, create, access);
- }
-
-done:
-
- if (fd == NGX_INVALID_FILE) {
- of->err = ngx_errno;
- of->failed = ngx_openat_file_n;
- }
-
-failed:
-
- if (at_fd != NGX_AT_FDCWD && ngx_close_file(at_fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%V\" failed", &at_name);
- }
-
- return fd;
-#endif
-}
-
-
-static ngx_int_t
-ngx_file_info_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,
- ngx_file_info_t *fi, ngx_log_t *log)
-{
- ngx_int_t rc;
-
-#if !(NGX_HAVE_OPENAT)
-
- rc = ngx_file_info(name->data, fi);
-
- if (rc == NGX_FILE_ERROR) {
- of->err = ngx_errno;
- of->failed = ngx_file_info_n;
- return NGX_FILE_ERROR;
- }
-
- return rc;
-
-#else
-
- ngx_fd_t fd;
-
- if (of->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
-
- rc = ngx_file_info(name->data, fi);
-
- if (rc == NGX_FILE_ERROR) {
- of->err = ngx_errno;
- of->failed = ngx_file_info_n;
- return NGX_FILE_ERROR;
- }
-
- return rc;
- }
-
- fd = ngx_open_file_wrapper(name, of, NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
- NGX_FILE_OPEN, 0, log);
-
- if (fd == NGX_INVALID_FILE) {
- return NGX_FILE_ERROR;
- }
-
- rc = ngx_fd_info(fd, fi);
-
- if (rc == NGX_FILE_ERROR) {
- of->err = ngx_errno;
- of->failed = ngx_fd_info_n;
- }
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%V\" failed", name);
- }
-
- return rc;
-#endif
-}
-
-
-static ngx_int_t
-ngx_open_and_stat_file(ngx_str_t *name, ngx_open_file_info_t *of,
- ngx_log_t *log)
-{
- ngx_fd_t fd;
- ngx_file_info_t fi;
-
- if (of->fd != NGX_INVALID_FILE) {
-
- if (ngx_file_info_wrapper(name, of, &fi, log) == NGX_FILE_ERROR) {
- of->fd = NGX_INVALID_FILE;
- return NGX_ERROR;
- }
-
- if (of->uniq == ngx_file_uniq(&fi)) {
- goto done;
- }
-
- } else if (of->test_dir) {
-
- if (ngx_file_info_wrapper(name, of, &fi, log) == NGX_FILE_ERROR) {
- of->fd = NGX_INVALID_FILE;
- return NGX_ERROR;
- }
-
- if (ngx_is_dir(&fi)) {
- goto done;
- }
- }
-
- if (!of->log) {
-
- /*
- * Use non-blocking open() not to hang on FIFO files, etc.
- * This flag has no effect on a regular files.
- */
-
- fd = ngx_open_file_wrapper(name, of, NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
- NGX_FILE_OPEN, 0, log);
-
- } else {
- fd = ngx_open_file_wrapper(name, of, NGX_FILE_APPEND,
- NGX_FILE_CREATE_OR_OPEN,
- NGX_FILE_DEFAULT_ACCESS, log);
- }
-
- if (fd == NGX_INVALID_FILE) {
- of->fd = NGX_INVALID_FILE;
- return NGX_ERROR;
- }
-
- if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
- ngx_fd_info_n " \"%V\" failed", name);
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%V\" failed", name);
- }
-
- of->fd = NGX_INVALID_FILE;
-
- return NGX_ERROR;
- }
-
- if (ngx_is_dir(&fi)) {
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%V\" failed", name);
- }
-
- of->fd = NGX_INVALID_FILE;
-
- } else {
- of->fd = fd;
-
- if (of->read_ahead && ngx_file_size(&fi) > NGX_MIN_READ_AHEAD) {
- if (ngx_read_ahead(fd, of->read_ahead) == NGX_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_read_ahead_n " \"%V\" failed", name);
- }
- }
-
- if (of->directio <= ngx_file_size(&fi)) {
- if (ngx_directio_on(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_directio_on_n " \"%V\" failed", name);
-
- } else {
- of->is_directio = 1;
- }
- }
- }
-
-done:
-
- of->uniq = ngx_file_uniq(&fi);
- of->mtime = ngx_file_mtime(&fi);
- of->size = ngx_file_size(&fi);
- of->fs_size = ngx_file_fs_size(&fi);
- of->is_dir = ngx_is_dir(&fi);
- of->is_file = ngx_is_file(&fi);
- of->is_link = ngx_is_link(&fi);
- of->is_exec = ngx_is_exec(&fi);
-
- return NGX_OK;
-}
-
-
-/*
- * we ignore any possible event setting error and
- * fallback to usual periodic file retests
- */
-
-static void
-ngx_open_file_add_event(ngx_open_file_cache_t *cache,
- ngx_cached_open_file_t *file, ngx_open_file_info_t *of, ngx_log_t *log)
-{
- ngx_open_file_cache_event_t *fev;
-
- if (!(ngx_event_flags & NGX_USE_VNODE_EVENT)
- || !of->events
- || file->event
- || of->fd == NGX_INVALID_FILE
- || file->uses < of->min_uses)
- {
- return;
- }
-
- file->use_event = 0;
-
- file->event = ngx_calloc(sizeof(ngx_event_t), log);
- if (file->event== NULL) {
- return;
- }
-
- fev = ngx_alloc(sizeof(ngx_open_file_cache_event_t), log);
- if (fev == NULL) {
- ngx_free(file->event);
- file->event = NULL;
- return;
- }
-
- fev->fd = of->fd;
- fev->file = file;
- fev->cache = cache;
-
- file->event->handler = ngx_open_file_cache_remove;
- file->event->data = fev;
-
- /*
- * although vnode event may be called while ngx_cycle->poll
- * destruction, however, cleanup procedures are run before any
- * memory freeing and events will be canceled.
- */
-
- file->event->log = ngx_cycle->log;
-
- if (ngx_add_event(file->event, NGX_VNODE_EVENT, NGX_ONESHOT_EVENT)
- != NGX_OK)
- {
- ngx_free(file->event->data);
- ngx_free(file->event);
- file->event = NULL;
- return;
- }
-
- /*
- * we do not set file->use_event here because there may be a race
- * condition: a file may be deleted between opening the file and
- * adding event, so we rely upon event notification only after
- * one file revalidation on next file access
- */
-
- return;
-}
-
-
-static void
-ngx_open_file_cleanup(void *data)
-{
- ngx_open_file_cache_cleanup_t *c = data;
-
- c->file->count--;
-
- ngx_close_cached_file(c->cache, c->file, c->min_uses, c->log);
-
- /* drop one or two expired open files */
- ngx_expire_old_cached_files(c->cache, 1, c->log);
-}
-
-
-static void
-ngx_close_cached_file(ngx_open_file_cache_t *cache,
- ngx_cached_open_file_t *file, ngx_uint_t min_uses, ngx_log_t *log)
-{
- ngx_log_debug5(NGX_LOG_DEBUG_CORE, log, 0,
- "close cached open file: %s, fd:%d, c:%d, u:%d, %d",
- file->name, file->fd, file->count, file->uses, file->close);
-
- if (!file->close) {
-
- file->accessed = ngx_time();
-
- ngx_queue_remove(&file->queue);
-
- ngx_queue_insert_head(&cache->expire_queue, &file->queue);
-
- if (file->uses >= min_uses || file->count) {
- return;
- }
- }
-
- ngx_open_file_del_event(file);
-
- if (file->count) {
- return;
- }
-
- if (file->fd != NGX_INVALID_FILE) {
-
- if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", file->name);
- }
-
- file->fd = NGX_INVALID_FILE;
- }
-
- if (!file->close) {
- return;
- }
-
- ngx_free(file->name);
- ngx_free(file);
-}
-
-
-static void
-ngx_open_file_del_event(ngx_cached_open_file_t *file)
-{
- if (file->event == NULL) {
- return;
- }
-
- (void) ngx_del_event(file->event, NGX_VNODE_EVENT,
- file->count ? NGX_FLUSH_EVENT : NGX_CLOSE_EVENT);
-
- ngx_free(file->event->data);
- ngx_free(file->event);
- file->event = NULL;
- file->use_event = 0;
-}
-
-
-static void
-ngx_expire_old_cached_files(ngx_open_file_cache_t *cache, ngx_uint_t n,
- ngx_log_t *log)
-{
- time_t now;
- ngx_queue_t *q;
- ngx_cached_open_file_t *file;
-
- now = ngx_time();
-
- /*
- * n == 1 deletes one or two inactive files
- * n == 0 deletes least recently used file by force
- * and one or two inactive files
- */
-
- while (n < 3) {
-
- if (ngx_queue_empty(&cache->expire_queue)) {
- return;
- }
-
- q = ngx_queue_last(&cache->expire_queue);
-
- file = ngx_queue_data(q, ngx_cached_open_file_t, queue);
-
- if (n++ != 0 && now - file->accessed <= cache->inactive) {
- return;
- }
-
- ngx_queue_remove(q);
-
- ngx_rbtree_delete(&cache->rbtree, &file->node);
-
- cache->current--;
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
- "expire cached open file: %s", file->name);
-
- if (!file->err && !file->is_dir) {
- file->close = 1;
- ngx_close_cached_file(cache, file, 0, log);
-
- } else {
- ngx_free(file->name);
- ngx_free(file);
- }
- }
-}
-
-
-static void
-ngx_open_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
-{
- ngx_rbtree_node_t **p;
- ngx_cached_open_file_t *file, *file_temp;
-
- for ( ;; ) {
-
- if (node->key < temp->key) {
-
- p = &temp->left;
-
- } else if (node->key > temp->key) {
-
- p = &temp->right;
-
- } else { /* node->key == temp->key */
-
- file = (ngx_cached_open_file_t *) node;
- file_temp = (ngx_cached_open_file_t *) temp;
-
- p = (ngx_strcmp(file->name, file_temp->name) < 0)
- ? &temp->left : &temp->right;
- }
-
- if (*p == sentinel) {
- break;
- }
-
- temp = *p;
- }
-
- *p = node;
- node->parent = temp;
- node->left = sentinel;
- node->right = sentinel;
- ngx_rbt_red(node);
-}
-
-
-static ngx_cached_open_file_t *
-ngx_open_file_lookup(ngx_open_file_cache_t *cache, ngx_str_t *name,
- uint32_t hash)
-{
- ngx_int_t rc;
- ngx_rbtree_node_t *node, *sentinel;
- ngx_cached_open_file_t *file;
-
- node = cache->rbtree.root;
- sentinel = cache->rbtree.sentinel;
-
- while (node != sentinel) {
-
- if (hash < node->key) {
- node = node->left;
- continue;
- }
-
- if (hash > node->key) {
- node = node->right;
- continue;
- }
-
- /* hash == node->key */
-
- file = (ngx_cached_open_file_t *) node;
-
- rc = ngx_strcmp(name->data, file->name);
-
- if (rc == 0) {
- return file;
- }
-
- node = (rc < 0) ? node->left : node->right;
- }
-
- return NULL;
-}
-
-
-static void
-ngx_open_file_cache_remove(ngx_event_t *ev)
-{
- ngx_cached_open_file_t *file;
- ngx_open_file_cache_event_t *fev;
-
- fev = ev->data;
- file = fev->file;
-
- ngx_queue_remove(&file->queue);
-
- ngx_rbtree_delete(&fev->cache->rbtree, &file->node);
-
- fev->cache->current--;
-
- /* NGX_ONESHOT_EVENT was already deleted */
- file->event = NULL;
- file->use_event = 0;
-
- file->close = 1;
-
- ngx_close_cached_file(fev->cache, file, 0, ev->log);
-
- /* free memory only when fev->cache and fev->file are already not needed */
-
- ngx_free(ev->data);
- ngx_free(ev);
-}
diff --git a/usr.sbin/nginx/src/core/ngx_open_file_cache.h b/usr.sbin/nginx/src/core/ngx_open_file_cache.h
deleted file mode 100644
index d119c1296f4..00000000000
--- a/usr.sbin/nginx/src/core/ngx_open_file_cache.h
+++ /dev/null
@@ -1,129 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#ifndef _NGX_OPEN_FILE_CACHE_H_INCLUDED_
-#define _NGX_OPEN_FILE_CACHE_H_INCLUDED_
-
-
-#define NGX_OPEN_FILE_DIRECTIO_OFF NGX_MAX_OFF_T_VALUE
-
-
-typedef struct {
- ngx_fd_t fd;
- ngx_file_uniq_t uniq;
- time_t mtime;
- off_t size;
- off_t fs_size;
- off_t directio;
- size_t read_ahead;
-
- ngx_err_t err;
- char *failed;
-
- time_t valid;
-
- ngx_uint_t min_uses;
-
-#if (NGX_HAVE_OPENAT)
- size_t disable_symlinks_from;
- unsigned disable_symlinks:2;
-#endif
-
- unsigned test_dir:1;
- unsigned test_only:1;
- unsigned log:1;
- unsigned errors:1;
- unsigned events:1;
-
- unsigned is_dir:1;
- unsigned is_file:1;
- unsigned is_link:1;
- unsigned is_exec:1;
- unsigned is_directio:1;
-} ngx_open_file_info_t;
-
-
-typedef struct ngx_cached_open_file_s ngx_cached_open_file_t;
-
-struct ngx_cached_open_file_s {
- ngx_rbtree_node_t node;
- ngx_queue_t queue;
-
- u_char *name;
- time_t created;
- time_t accessed;
-
- ngx_fd_t fd;
- ngx_file_uniq_t uniq;
- time_t mtime;
- off_t size;
- ngx_err_t err;
-
- uint32_t uses;
-
-#if (NGX_HAVE_OPENAT)
- size_t disable_symlinks_from;
- unsigned disable_symlinks:2;
-#endif
-
- unsigned count:24;
- unsigned close:1;
- unsigned use_event:1;
-
- unsigned is_dir:1;
- unsigned is_file:1;
- unsigned is_link:1;
- unsigned is_exec:1;
- unsigned is_directio:1;
-
- ngx_event_t *event;
-};
-
-
-typedef struct {
- ngx_rbtree_t rbtree;
- ngx_rbtree_node_t sentinel;
- ngx_queue_t expire_queue;
-
- ngx_uint_t current;
- ngx_uint_t max;
- time_t inactive;
-} ngx_open_file_cache_t;
-
-
-typedef struct {
- ngx_open_file_cache_t *cache;
- ngx_cached_open_file_t *file;
- ngx_uint_t min_uses;
- ngx_log_t *log;
-} ngx_open_file_cache_cleanup_t;
-
-
-typedef struct {
-
- /* ngx_connection_t stub to allow use c->fd as event ident */
- void *data;
- ngx_event_t *read;
- ngx_event_t *write;
- ngx_fd_t fd;
-
- ngx_cached_open_file_t *file;
- ngx_open_file_cache_t *cache;
-} ngx_open_file_cache_event_t;
-
-
-ngx_open_file_cache_t *ngx_open_file_cache_init(ngx_pool_t *pool,
- ngx_uint_t max, time_t inactive);
-ngx_int_t ngx_open_cached_file(ngx_open_file_cache_t *cache, ngx_str_t *name,
- ngx_open_file_info_t *of, ngx_pool_t *pool);
-
-
-#endif /* _NGX_OPEN_FILE_CACHE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_output_chain.c b/usr.sbin/nginx/src/core/ngx_output_chain.c
deleted file mode 100644
index 3cb60ea73dd..00000000000
--- a/usr.sbin/nginx/src/core/ngx_output_chain.c
+++ /dev/null
@@ -1,674 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#if 0
-#define NGX_SENDFILE_LIMIT 4096
-#endif
-
-/*
- * When DIRECTIO is enabled FreeBSD, Solaris, and MacOSX read directly
- * to an application memory from a device if parameters are aligned
- * to device sector boundary (512 bytes). They fallback to usual read
- * operation if the parameters are not aligned.
- * Linux allows DIRECTIO only if the parameters are aligned to a filesystem
- * sector boundary, otherwise it returns EINVAL. The sector size is
- * usually 512 bytes, however, on XFS it may be 4096 bytes.
- */
-
-#define NGX_NONE 1
-
-
-static ngx_inline ngx_int_t
- ngx_output_chain_as_is(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf);
-static ngx_int_t ngx_output_chain_add_copy(ngx_pool_t *pool,
- ngx_chain_t **chain, ngx_chain_t *in);
-static ngx_int_t ngx_output_chain_align_file_buf(ngx_output_chain_ctx_t *ctx,
- off_t bsize);
-static ngx_int_t ngx_output_chain_get_buf(ngx_output_chain_ctx_t *ctx,
- off_t bsize);
-static ngx_int_t ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx);
-
-
-ngx_int_t
-ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
-{
- off_t bsize;
- ngx_int_t rc, last;
- ngx_chain_t *cl, *out, **last_out;
-
- if (ctx->in == NULL && ctx->busy == NULL) {
-
- /*
- * the short path for the case when the ctx->in and ctx->busy chains
- * are empty, the incoming chain is empty too or has the single buf
- * that does not require the copy
- */
-
- if (in == NULL) {
- return ctx->output_filter(ctx->filter_ctx, in);
- }
-
- if (in->next == NULL
-#if (NGX_SENDFILE_LIMIT)
- && !(in->buf->in_file && in->buf->file_last > NGX_SENDFILE_LIMIT)
-#endif
- && ngx_output_chain_as_is(ctx, in->buf))
- {
- return ctx->output_filter(ctx->filter_ctx, in);
- }
- }
-
- /* add the incoming buf to the chain ctx->in */
-
- if (in) {
- if (ngx_output_chain_add_copy(ctx->pool, &ctx->in, in) == NGX_ERROR) {
- return NGX_ERROR;
- }
- }
-
- out = NULL;
- last_out = &out;
- last = NGX_NONE;
-
- for ( ;; ) {
-
-#if (NGX_HAVE_FILE_AIO)
- if (ctx->aio) {
- return NGX_AGAIN;
- }
-#endif
-
- while (ctx->in) {
-
- /*
- * cycle while there are the ctx->in bufs
- * and there are the free output bufs to copy in
- */
-
- bsize = ngx_buf_size(ctx->in->buf);
-
- if (bsize == 0 && !ngx_buf_special(ctx->in->buf)) {
-
- ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
- "zero size buf in output "
- "t:%d r:%d f:%d %p %p-%p %p %O-%O",
- ctx->in->buf->temporary,
- ctx->in->buf->recycled,
- ctx->in->buf->in_file,
- ctx->in->buf->start,
- ctx->in->buf->pos,
- ctx->in->buf->last,
- ctx->in->buf->file,
- ctx->in->buf->file_pos,
- ctx->in->buf->file_last);
-
- ngx_debug_point();
-
- ctx->in = ctx->in->next;
-
- continue;
- }
-
- if (ngx_output_chain_as_is(ctx, ctx->in->buf)) {
-
- /* move the chain link to the output chain */
-
- cl = ctx->in;
- ctx->in = cl->next;
-
- *last_out = cl;
- last_out = &cl->next;
- cl->next = NULL;
-
- continue;
- }
-
- if (ctx->buf == NULL) {
-
- rc = ngx_output_chain_align_file_buf(ctx, bsize);
-
- if (rc == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- if (rc != NGX_OK) {
-
- if (ctx->free) {
-
- /* get the free buf */
-
- cl = ctx->free;
- ctx->buf = cl->buf;
- ctx->free = cl->next;
-
- ngx_free_chain(ctx->pool, cl);
-
- } else if (out || ctx->allocated == ctx->bufs.num) {
-
- break;
-
- } else if (ngx_output_chain_get_buf(ctx, bsize) != NGX_OK) {
- return NGX_ERROR;
- }
- }
- }
-
- rc = ngx_output_chain_copy_buf(ctx);
-
- if (rc == NGX_ERROR) {
- return rc;
- }
-
- if (rc == NGX_AGAIN) {
- if (out) {
- break;
- }
-
- return rc;
- }
-
- /* delete the completed buf from the ctx->in chain */
-
- if (ngx_buf_size(ctx->in->buf) == 0) {
- ctx->in = ctx->in->next;
- }
-
- cl = ngx_alloc_chain_link(ctx->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = ctx->buf;
- cl->next = NULL;
- *last_out = cl;
- last_out = &cl->next;
- ctx->buf = NULL;
- }
-
- if (out == NULL && last != NGX_NONE) {
-
- if (ctx->in) {
- return NGX_AGAIN;
- }
-
- return last;
- }
-
- last = ctx->output_filter(ctx->filter_ctx, out);
-
- if (last == NGX_ERROR || last == NGX_DONE) {
- return last;
- }
-
- ngx_chain_update_chains(ctx->pool, &ctx->free, &ctx->busy, &out,
- ctx->tag);
- last_out = &out;
- }
-}
-
-
-static ngx_inline ngx_int_t
-ngx_output_chain_as_is(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf)
-{
- ngx_uint_t sendfile;
-
- if (ngx_buf_special(buf)) {
- return 1;
- }
-
- if (buf->in_file && buf->file->directio) {
- return 0;
- }
-
- sendfile = ctx->sendfile;
-
-#if (NGX_SENDFILE_LIMIT)
-
- if (buf->in_file && buf->file_pos >= NGX_SENDFILE_LIMIT) {
- sendfile = 0;
- }
-
-#endif
-
- if (!sendfile) {
-
- if (!ngx_buf_in_memory(buf)) {
- return 0;
- }
-
- buf->in_file = 0;
- }
-
- if (ctx->need_in_memory && !ngx_buf_in_memory(buf)) {
- return 0;
- }
-
- if (ctx->need_in_temp && (buf->memory || buf->mmap)) {
- return 0;
- }
-
- return 1;
-}
-
-
-static ngx_int_t
-ngx_output_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain,
- ngx_chain_t *in)
-{
- ngx_chain_t *cl, **ll;
-#if (NGX_SENDFILE_LIMIT)
- ngx_buf_t *b, *buf;
-#endif
-
- ll = chain;
-
- for (cl = *chain; cl; cl = cl->next) {
- ll = &cl->next;
- }
-
- while (in) {
-
- cl = ngx_alloc_chain_link(pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
-#if (NGX_SENDFILE_LIMIT)
-
- buf = in->buf;
-
- if (buf->in_file
- && buf->file_pos < NGX_SENDFILE_LIMIT
- && buf->file_last > NGX_SENDFILE_LIMIT)
- {
- /* split a file buf on two bufs by the sendfile limit */
-
- b = ngx_calloc_buf(pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(b, buf, sizeof(ngx_buf_t));
-
- if (ngx_buf_in_memory(buf)) {
- buf->pos += (ssize_t) (NGX_SENDFILE_LIMIT - buf->file_pos);
- b->last = buf->pos;
- }
-
- buf->file_pos = NGX_SENDFILE_LIMIT;
- b->file_last = NGX_SENDFILE_LIMIT;
-
- cl->buf = b;
-
- } else {
- cl->buf = buf;
- in = in->next;
- }
-
-#else
- cl->buf = in->buf;
- in = in->next;
-
-#endif
-
- cl->next = NULL;
- *ll = cl;
- ll = &cl->next;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_output_chain_align_file_buf(ngx_output_chain_ctx_t *ctx, off_t bsize)
-{
- size_t size;
- ngx_buf_t *in;
-
- in = ctx->in->buf;
-
- if (in->file == NULL || !in->file->directio) {
- return NGX_DECLINED;
- }
-
- ctx->directio = 1;
-
- size = (size_t) (in->file_pos - (in->file_pos & ~(ctx->alignment - 1)));
-
- if (size == 0) {
-
- if (bsize >= (off_t) ctx->bufs.size) {
- return NGX_DECLINED;
- }
-
- size = (size_t) bsize;
-
- } else {
- size = (size_t) ctx->alignment - size;
-
- if ((off_t) size > bsize) {
- size = (size_t) bsize;
- }
- }
-
- ctx->buf = ngx_create_temp_buf(ctx->pool, size);
- if (ctx->buf == NULL) {
- return NGX_ERROR;
- }
-
- /*
- * we do not set ctx->buf->tag, because we do not want
- * to reuse the buf via ctx->free list
- */
-
-#if (NGX_HAVE_ALIGNED_DIRECTIO)
- ctx->unaligned = 1;
-#endif
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_output_chain_get_buf(ngx_output_chain_ctx_t *ctx, off_t bsize)
-{
- size_t size;
- ngx_buf_t *b, *in;
- ngx_uint_t recycled;
-
- in = ctx->in->buf;
- size = ctx->bufs.size;
- recycled = 1;
-
- if (in->last_in_chain) {
-
- if (bsize < (off_t) size) {
-
- /*
- * allocate a small temp buf for a small last buf
- * or its small last part
- */
-
- size = (size_t) bsize;
- recycled = 0;
-
- } else if (!ctx->directio
- && ctx->bufs.num == 1
- && (bsize < (off_t) (size + size / 4)))
- {
- /*
- * allocate a temp buf that equals to a last buf,
- * if there is no directio, the last buf size is lesser
- * than 1.25 of bufs.size and the temp buf is single
- */
-
- size = (size_t) bsize;
- recycled = 0;
- }
- }
-
- b = ngx_calloc_buf(ctx->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- if (ctx->directio) {
-
- /*
- * allocate block aligned to a disk sector size to enable
- * userland buffer direct usage conjunctly with directio
- */
-
- b->start = ngx_pmemalign(ctx->pool, size, (size_t) ctx->alignment);
- if (b->start == NULL) {
- return NGX_ERROR;
- }
-
- } else {
- b->start = ngx_palloc(ctx->pool, size);
- if (b->start == NULL) {
- return NGX_ERROR;
- }
- }
-
- b->pos = b->start;
- b->last = b->start;
- b->end = b->last + size;
- b->temporary = 1;
- b->tag = ctx->tag;
- b->recycled = recycled;
-
- ctx->buf = b;
- ctx->allocated++;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
-{
- off_t size;
- ssize_t n;
- ngx_buf_t *src, *dst;
- ngx_uint_t sendfile;
-
- src = ctx->in->buf;
- dst = ctx->buf;
-
- size = ngx_buf_size(src);
- size = ngx_min(size, dst->end - dst->pos);
-
- sendfile = ctx->sendfile & !ctx->directio;
-
-#if (NGX_SENDFILE_LIMIT)
-
- if (src->in_file && src->file_pos >= NGX_SENDFILE_LIMIT) {
- sendfile = 0;
- }
-
-#endif
-
- if (ngx_buf_in_memory(src)) {
- ngx_memcpy(dst->pos, src->pos, (size_t) size);
- src->pos += (size_t) size;
- dst->last += (size_t) size;
-
- if (src->in_file) {
-
- if (sendfile) {
- dst->in_file = 1;
- dst->file = src->file;
- dst->file_pos = src->file_pos;
- dst->file_last = src->file_pos + size;
-
- } else {
- dst->in_file = 0;
- }
-
- src->file_pos += size;
-
- } else {
- dst->in_file = 0;
- }
-
- if (src->pos == src->last) {
- dst->flush = src->flush;
- dst->last_buf = src->last_buf;
- dst->last_in_chain = src->last_in_chain;
- }
-
- } else {
-
-#if (NGX_HAVE_ALIGNED_DIRECTIO)
-
- if (ctx->unaligned) {
- if (ngx_directio_off(src->file->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno,
- ngx_directio_off_n " \"%s\" failed",
- src->file->name.data);
- }
- }
-
-#endif
-
-#if (NGX_HAVE_FILE_AIO)
-
- if (ctx->aio_handler) {
- n = ngx_file_aio_read(src->file, dst->pos, (size_t) size,
- src->file_pos, ctx->pool);
- if (n == NGX_AGAIN) {
- ctx->aio_handler(ctx, src->file);
- return NGX_AGAIN;
- }
-
- } else {
- n = ngx_read_file(src->file, dst->pos, (size_t) size,
- src->file_pos);
- }
-#else
-
- n = ngx_read_file(src->file, dst->pos, (size_t) size, src->file_pos);
-
-#endif
-
-#if (NGX_HAVE_ALIGNED_DIRECTIO)
-
- if (ctx->unaligned) {
- ngx_err_t err;
-
- err = ngx_errno;
-
- if (ngx_directio_on(src->file->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno,
- ngx_directio_on_n " \"%s\" failed",
- src->file->name.data);
- }
-
- ngx_set_errno(err);
-
- ctx->unaligned = 0;
- }
-
-#endif
-
- if (n == NGX_ERROR) {
- return (ngx_int_t) n;
- }
-
- if (n != size) {
- ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
- ngx_read_file_n " read only %z of %O from \"%s\"",
- n, size, src->file->name.data);
- return NGX_ERROR;
- }
-
- dst->last += n;
-
- if (sendfile) {
- dst->in_file = 1;
- dst->file = src->file;
- dst->file_pos = src->file_pos;
- dst->file_last = src->file_pos + n;
-
- } else {
- dst->in_file = 0;
- }
-
- src->file_pos += n;
-
- if (src->file_pos == src->file_last) {
- dst->flush = src->flush;
- dst->last_buf = src->last_buf;
- dst->last_in_chain = src->last_in_chain;
- }
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_chain_writer(void *data, ngx_chain_t *in)
-{
- ngx_chain_writer_ctx_t *ctx = data;
-
- off_t size;
- ngx_chain_t *cl;
- ngx_connection_t *c;
-
- c = ctx->connection;
-
- for (size = 0; in; in = in->next) {
-
-#if 1
- if (ngx_buf_size(in->buf) == 0 && !ngx_buf_special(in->buf)) {
- ngx_debug_point();
- }
-#endif
-
- size += ngx_buf_size(in->buf);
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, c->log, 0,
- "chain writer buf fl:%d s:%uO",
- in->buf->flush, ngx_buf_size(in->buf));
-
- cl = ngx_alloc_chain_link(ctx->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = in->buf;
- cl->next = NULL;
- *ctx->last = cl;
- ctx->last = &cl->next;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
- "chain writer in: %p", ctx->out);
-
- for (cl = ctx->out; cl; cl = cl->next) {
-
-#if 1
- if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) {
- ngx_debug_point();
- }
-
-#endif
-
- size += ngx_buf_size(cl->buf);
- }
-
- if (size == 0 && !c->buffered) {
- return NGX_OK;
- }
-
- ctx->out = c->send_chain(c, ctx->out, ctx->limit);
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
- "chain writer out: %p", ctx->out);
-
- if (ctx->out == NGX_CHAIN_ERROR) {
- return NGX_ERROR;
- }
-
- if (ctx->out == NULL) {
- ctx->last = &ctx->out;
-
- if (!c->buffered) {
- return NGX_OK;
- }
- }
-
- return NGX_AGAIN;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_palloc.c b/usr.sbin/nginx/src/core/ngx_palloc.c
deleted file mode 100644
index 1f70f9eee29..00000000000
--- a/usr.sbin/nginx/src/core/ngx_palloc.c
+++ /dev/null
@@ -1,436 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
-static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
-
-
-ngx_pool_t *
-ngx_create_pool(size_t size, ngx_log_t *log)
-{
- ngx_pool_t *p;
-
- p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
- if (p == NULL) {
- return NULL;
- }
-
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
- p->d.end = (u_char *) p + size;
- p->d.next = NULL;
- p->d.failed = 0;
-
- size = size - sizeof(ngx_pool_t);
- p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
-
- p->current = p;
- p->chain = NULL;
- p->large = NULL;
- p->cleanup = NULL;
- p->log = log;
-
- return p;
-}
-
-
-void
-ngx_destroy_pool(ngx_pool_t *pool)
-{
- ngx_pool_t *p, *n;
- ngx_pool_large_t *l;
- ngx_pool_cleanup_t *c;
-
- for (c = pool->cleanup; c; c = c->next) {
- if (c->handler) {
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
- "run cleanup: %p", c);
- c->handler(c->data);
- }
- }
-
- for (l = pool->large; l; l = l->next) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
-
- if (l->alloc) {
- ngx_free(l->alloc);
- }
- }
-
-#if (NGX_DEBUG)
-
- /*
- * we could allocate the pool->log from this pool
- * so we cannot use this log while free()ing the pool
- */
-
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
- ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
- "free: %p, unused: %uz", p, p->d.end - p->d.last);
-
- if (n == NULL) {
- break;
- }
- }
-
-#endif
-
- for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
- ngx_free(p);
-
- if (n == NULL) {
- break;
- }
- }
-}
-
-
-void
-ngx_reset_pool(ngx_pool_t *pool)
-{
- ngx_pool_t *p;
- ngx_pool_large_t *l;
-
- for (l = pool->large; l; l = l->next) {
- if (l->alloc) {
- ngx_free(l->alloc);
- }
- }
-
- for (p = pool; p; p = p->d.next) {
- p->d.last = (u_char *) p + sizeof(ngx_pool_t);
- p->d.failed = 0;
- }
-
- pool->current = pool;
- pool->chain = NULL;
- pool->large = NULL;
-}
-
-
-void *
-ngx_palloc(ngx_pool_t *pool, size_t size)
-{
- u_char *m;
- ngx_pool_t *p;
-
- if (size <= pool->max) {
-
- p = pool->current;
-
- do {
- m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);
-
- if ((size_t) (p->d.end - m) >= size) {
- p->d.last = m + size;
-
- return m;
- }
-
- p = p->d.next;
-
- } while (p);
-
- return ngx_palloc_block(pool, size);
- }
-
- return ngx_palloc_large(pool, size);
-}
-
-
-void *
-ngx_pnalloc(ngx_pool_t *pool, size_t size)
-{
- u_char *m;
- ngx_pool_t *p;
-
- if (size <= pool->max) {
-
- p = pool->current;
-
- do {
- m = p->d.last;
-
- if ((size_t) (p->d.end - m) >= size) {
- p->d.last = m + size;
-
- return m;
- }
-
- p = p->d.next;
-
- } while (p);
-
- return ngx_palloc_block(pool, size);
- }
-
- return ngx_palloc_large(pool, size);
-}
-
-
-static void *
-ngx_palloc_block(ngx_pool_t *pool, size_t size)
-{
- u_char *m;
- size_t psize;
- ngx_pool_t *p, *new, *current;
-
- psize = (size_t) (pool->d.end - (u_char *) pool);
-
- m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
- if (m == NULL) {
- return NULL;
- }
-
- new = (ngx_pool_t *) m;
-
- new->d.end = m + psize;
- new->d.next = NULL;
- new->d.failed = 0;
-
- m += sizeof(ngx_pool_data_t);
- m = ngx_align_ptr(m, NGX_ALIGNMENT);
- new->d.last = m + size;
-
- current = pool->current;
-
- for (p = current; p->d.next; p = p->d.next) {
- if (p->d.failed++ > 4) {
- current = p->d.next;
- }
- }
-
- p->d.next = new;
-
- pool->current = current ? current : new;
-
- return m;
-}
-
-
-static void *
-ngx_palloc_large(ngx_pool_t *pool, size_t size)
-{
- void *p;
- ngx_uint_t n;
- ngx_pool_large_t *large;
-
- p = ngx_alloc(size, pool->log);
- if (p == NULL) {
- return NULL;
- }
-
- n = 0;
-
- for (large = pool->large; large; large = large->next) {
- if (large->alloc == NULL) {
- large->alloc = p;
- return p;
- }
-
- if (n++ > 3) {
- break;
- }
- }
-
- large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
- if (large == NULL) {
- ngx_free(p);
- return NULL;
- }
-
- large->alloc = p;
- large->next = pool->large;
- pool->large = large;
-
- return p;
-}
-
-
-void *
-ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
-{
- void *p;
- ngx_pool_large_t *large;
-
- p = ngx_memalign(alignment, size, pool->log);
- if (p == NULL) {
- return NULL;
- }
-
- large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
- if (large == NULL) {
- ngx_free(p);
- return NULL;
- }
-
- large->alloc = p;
- large->next = pool->large;
- pool->large = large;
-
- return p;
-}
-
-
-ngx_int_t
-ngx_pfree(ngx_pool_t *pool, void *p)
-{
- ngx_pool_large_t *l;
-
- for (l = pool->large; l; l = l->next) {
- if (p == l->alloc) {
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
- "free: %p", l->alloc);
- ngx_free(l->alloc);
- l->alloc = NULL;
-
- return NGX_OK;
- }
- }
-
- return NGX_DECLINED;
-}
-
-
-void *
-ngx_pcalloc(ngx_pool_t *pool, size_t size)
-{
- void *p;
-
- p = ngx_palloc(pool, size);
- if (p) {
- ngx_memzero(p, size);
- }
-
- return p;
-}
-
-
-ngx_pool_cleanup_t *
-ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)
-{
- ngx_pool_cleanup_t *c;
-
- c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));
- if (c == NULL) {
- return NULL;
- }
-
- if (size) {
- c->data = ngx_palloc(p, size);
- if (c->data == NULL) {
- return NULL;
- }
-
- } else {
- c->data = NULL;
- }
-
- c->handler = NULL;
- c->next = p->cleanup;
-
- p->cleanup = c;
-
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c);
-
- return c;
-}
-
-
-void
-ngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd)
-{
- ngx_pool_cleanup_t *c;
- ngx_pool_cleanup_file_t *cf;
-
- for (c = p->cleanup; c; c = c->next) {
- if (c->handler == ngx_pool_cleanup_file) {
-
- cf = c->data;
-
- if (cf->fd == fd) {
- c->handler(cf);
- c->handler = NULL;
- return;
- }
- }
- }
-}
-
-
-void
-ngx_pool_cleanup_file(void *data)
-{
- ngx_pool_cleanup_file_t *c = data;
-
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d",
- c->fd);
-
- if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", c->name);
- }
-}
-
-
-void
-ngx_pool_delete_file(void *data)
-{
- ngx_pool_cleanup_file_t *c = data;
-
- ngx_err_t err;
-
- ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d %s",
- c->fd, c->name);
-
- if (ngx_delete_file(c->name) == NGX_FILE_ERROR) {
- err = ngx_errno;
-
- if (err != NGX_ENOENT) {
- ngx_log_error(NGX_LOG_CRIT, c->log, err,
- ngx_delete_file_n " \"%s\" failed", c->name);
- }
- }
-
- if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", c->name);
- }
-}
-
-
-#if 0
-
-static void *
-ngx_get_cached_block(size_t size)
-{
- void *p;
- ngx_cached_block_slot_t *slot;
-
- if (ngx_cycle->cache == NULL) {
- return NULL;
- }
-
- slot = &ngx_cycle->cache[(size + ngx_pagesize - 1) / ngx_pagesize];
-
- slot->tries++;
-
- if (slot->number) {
- p = slot->block;
- slot->block = slot->block->next;
- slot->number--;
- return p;
- }
-
- return NULL;
-}
-
-#endif
diff --git a/usr.sbin/nginx/src/core/ngx_palloc.h b/usr.sbin/nginx/src/core/ngx_palloc.h
deleted file mode 100644
index d6528291053..00000000000
--- a/usr.sbin/nginx/src/core/ngx_palloc.h
+++ /dev/null
@@ -1,95 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_PALLOC_H_INCLUDED_
-#define _NGX_PALLOC_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/*
- * NGX_MAX_ALLOC_FROM_POOL should be (ngx_pagesize - 1), i.e. 4095 on x86.
- * On Windows NT it decreases a number of locked pages in a kernel.
- */
-#define NGX_MAX_ALLOC_FROM_POOL (ngx_pagesize - 1)
-
-#define NGX_DEFAULT_POOL_SIZE (16 * 1024)
-
-#define NGX_POOL_ALIGNMENT 16
-#define NGX_MIN_POOL_SIZE \
- ngx_align((sizeof(ngx_pool_t) + 2 * sizeof(ngx_pool_large_t)), \
- NGX_POOL_ALIGNMENT)
-
-
-typedef void (*ngx_pool_cleanup_pt)(void *data);
-
-typedef struct ngx_pool_cleanup_s ngx_pool_cleanup_t;
-
-struct ngx_pool_cleanup_s {
- ngx_pool_cleanup_pt handler;
- void *data;
- ngx_pool_cleanup_t *next;
-};
-
-
-typedef struct ngx_pool_large_s ngx_pool_large_t;
-
-struct ngx_pool_large_s {
- ngx_pool_large_t *next;
- void *alloc;
-};
-
-
-typedef struct {
- u_char *last;
- u_char *end;
- ngx_pool_t *next;
- ngx_uint_t failed;
-} ngx_pool_data_t;
-
-
-struct ngx_pool_s {
- ngx_pool_data_t d;
- size_t max;
- ngx_pool_t *current;
- ngx_chain_t *chain;
- ngx_pool_large_t *large;
- ngx_pool_cleanup_t *cleanup;
- ngx_log_t *log;
-};
-
-
-typedef struct {
- ngx_fd_t fd;
- u_char *name;
- ngx_log_t *log;
-} ngx_pool_cleanup_file_t;
-
-
-void *ngx_alloc(size_t size, ngx_log_t *log);
-void *ngx_calloc(size_t size, ngx_log_t *log);
-
-ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log);
-void ngx_destroy_pool(ngx_pool_t *pool);
-void ngx_reset_pool(ngx_pool_t *pool);
-
-void *ngx_palloc(ngx_pool_t *pool, size_t size);
-void *ngx_pnalloc(ngx_pool_t *pool, size_t size);
-void *ngx_pcalloc(ngx_pool_t *pool, size_t size);
-void *ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment);
-ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p);
-
-
-ngx_pool_cleanup_t *ngx_pool_cleanup_add(ngx_pool_t *p, size_t size);
-void ngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd);
-void ngx_pool_cleanup_file(void *data);
-void ngx_pool_delete_file(void *data);
-
-
-#endif /* _NGX_PALLOC_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_parse.c b/usr.sbin/nginx/src/core/ngx_parse.c
deleted file mode 100644
index da24f4c7543..00000000000
--- a/usr.sbin/nginx/src/core/ngx_parse.c
+++ /dev/null
@@ -1,249 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-ssize_t
-ngx_parse_size(ngx_str_t *line)
-{
- u_char unit;
- size_t len;
- ssize_t size;
- ngx_int_t scale;
-
- len = line->len;
- unit = line->data[len - 1];
-
- switch (unit) {
- case 'K':
- case 'k':
- len--;
- scale = 1024;
- break;
-
- case 'M':
- case 'm':
- len--;
- scale = 1024 * 1024;
- break;
-
- default:
- scale = 1;
- }
-
- size = ngx_atosz(line->data, len);
- if (size == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- size *= scale;
-
- return size;
-}
-
-
-off_t
-ngx_parse_offset(ngx_str_t *line)
-{
- u_char unit;
- off_t offset;
- size_t len;
- ngx_int_t scale;
-
- len = line->len;
- unit = line->data[len - 1];
-
- switch (unit) {
- case 'K':
- case 'k':
- len--;
- scale = 1024;
- break;
-
- case 'M':
- case 'm':
- len--;
- scale = 1024 * 1024;
- break;
-
- case 'G':
- case 'g':
- len--;
- scale = 1024 * 1024 * 1024;
- break;
-
- default:
- scale = 1;
- }
-
- offset = ngx_atoof(line->data, len);
- if (offset == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- offset *= scale;
-
- return offset;
-}
-
-
-ngx_int_t
-ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
-{
- u_char *p, *last;
- ngx_int_t value, total, scale;
- ngx_uint_t max, valid;
- enum {
- st_start = 0,
- st_year,
- st_month,
- st_week,
- st_day,
- st_hour,
- st_min,
- st_sec,
- st_msec,
- st_last
- } step;
-
- valid = 0;
- value = 0;
- total = 0;
- step = is_sec ? st_start : st_month;
- scale = is_sec ? 1 : 1000;
-
- p = line->data;
- last = p + line->len;
-
- while (p < last) {
-
- if (*p >= '0' && *p <= '9') {
- value = value * 10 + (*p++ - '0');
- valid = 1;
- continue;
- }
-
- switch (*p++) {
-
- case 'y':
- if (step > st_start) {
- return NGX_ERROR;
- }
- step = st_year;
- max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 365);
- scale = 60 * 60 * 24 * 365;
- break;
-
- case 'M':
- if (step >= st_month) {
- return NGX_ERROR;
- }
- step = st_month;
- max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 30);
- scale = 60 * 60 * 24 * 30;
- break;
-
- case 'w':
- if (step >= st_week) {
- return NGX_ERROR;
- }
- step = st_week;
- max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 7);
- scale = 60 * 60 * 24 * 7;
- break;
-
- case 'd':
- if (step >= st_day) {
- return NGX_ERROR;
- }
- step = st_day;
- max = NGX_MAX_INT32_VALUE / (60 * 60 * 24);
- scale = 60 * 60 * 24;
- break;
-
- case 'h':
- if (step >= st_hour) {
- return NGX_ERROR;
- }
- step = st_hour;
- max = NGX_MAX_INT32_VALUE / (60 * 60);
- scale = 60 * 60;
- break;
-
- case 'm':
- if (*p == 's') {
- if (is_sec || step >= st_msec) {
- return NGX_ERROR;
- }
- p++;
- step = st_msec;
- max = NGX_MAX_INT32_VALUE;
- scale = 1;
- break;
- }
-
- if (step >= st_min) {
- return NGX_ERROR;
- }
- step = st_min;
- max = NGX_MAX_INT32_VALUE / 60;
- scale = 60;
- break;
-
- case 's':
- if (step >= st_sec) {
- return NGX_ERROR;
- }
- step = st_sec;
- max = NGX_MAX_INT32_VALUE;
- scale = 1;
- break;
-
- case ' ':
- if (step >= st_sec) {
- return NGX_ERROR;
- }
- step = st_last;
- max = NGX_MAX_INT32_VALUE;
- scale = 1;
- break;
-
- default:
- return NGX_ERROR;
- }
-
- if (step != st_msec && !is_sec) {
- scale *= 1000;
- max /= 1000;
- }
-
- if ((ngx_uint_t) value > max) {
- return NGX_ERROR;
- }
-
- total += value * scale;
-
- if ((ngx_uint_t) total > NGX_MAX_INT32_VALUE) {
- return NGX_ERROR;
- }
-
- value = 0;
- scale = is_sec ? 1 : 1000;
-
- while (p < last && *p == ' ') {
- p++;
- }
- }
-
- if (valid) {
- return total + value * scale;
- }
-
- return NGX_ERROR;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_parse.h b/usr.sbin/nginx/src/core/ngx_parse.h
deleted file mode 100644
index ec093b5a2be..00000000000
--- a/usr.sbin/nginx/src/core/ngx_parse.h
+++ /dev/null
@@ -1,21 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_PARSE_H_INCLUDED_
-#define _NGX_PARSE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-ssize_t ngx_parse_size(ngx_str_t *line);
-off_t ngx_parse_offset(ngx_str_t *line);
-ngx_int_t ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec);
-
-
-#endif /* _NGX_PARSE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_proxy_protocol.c b/usr.sbin/nginx/src/core/ngx_proxy_protocol.c
deleted file mode 100644
index 59ef010fc06..00000000000
--- a/usr.sbin/nginx/src/core/ngx_proxy_protocol.c
+++ /dev/null
@@ -1,91 +0,0 @@
-
-/*
- * Copyright (C) Roman Arutyunyan
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-u_char *
-ngx_proxy_protocol_parse(ngx_connection_t *c, u_char *buf, u_char *last)
-{
- size_t len;
- u_char ch, *p, *addr;
-
- p = buf;
- len = last - buf;
-
- if (len < 8 || ngx_strncmp(p, "PROXY ", 6) != 0) {
- goto invalid;
- }
-
- p += 6;
- len -= 6;
-
- if (len >= 7 && ngx_strncmp(p, "UNKNOWN", 7) == 0) {
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0,
- "PROXY protocol unknown protocol");
- p += 7;
- goto skip;
- }
-
- if (len < 5 || ngx_strncmp(p, "TCP", 3) != 0
- || (p[3] != '4' && p[3] != '6') || p[4] != ' ')
- {
- goto invalid;
- }
-
- p += 5;
- addr = p;
-
- for ( ;; ) {
- if (p == last) {
- goto invalid;
- }
-
- ch = *p++;
-
- if (ch == ' ') {
- break;
- }
-
- if (ch != ':' && ch != '.'
- && (ch < 'a' || ch > 'f')
- && (ch < 'A' || ch > 'F')
- && (ch < '0' || ch > '9'))
- {
- goto invalid;
- }
- }
-
- len = p - addr - 1;
- c->proxy_protocol_addr.data = ngx_pnalloc(c->pool, len);
-
- if (c->proxy_protocol_addr.data == NULL) {
- return NULL;
- }
-
- ngx_memcpy(c->proxy_protocol_addr.data, addr, len);
- c->proxy_protocol_addr.len = len;
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0,
- "PROXY protocol address: \"%V\"", &c->proxy_protocol_addr);
-
-skip:
-
- for ( /* void */ ; p < last - 1; p++) {
- if (p[0] == CR && p[1] == LF) {
- return p + 2;
- }
- }
-
-invalid:
-
- ngx_log_error(NGX_LOG_ERR, c->log, 0,
- "broken header: \"%*s\"", (size_t) (last - buf), buf);
-
- return NULL;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_proxy_protocol.h b/usr.sbin/nginx/src/core/ngx_proxy_protocol.h
deleted file mode 100644
index 4f3912512f1..00000000000
--- a/usr.sbin/nginx/src/core/ngx_proxy_protocol.h
+++ /dev/null
@@ -1,23 +0,0 @@
-
-/*
- * Copyright (C) Roman Arutyunyan
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_PROXY_PROTOCOL_H_INCLUDED_
-#define _NGX_PROXY_PROTOCOL_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#define NGX_PROXY_PROTOCOL_MAX_HEADER 107
-
-
-u_char *ngx_proxy_protocol_parse(ngx_connection_t *c, u_char *buf,
- u_char *last);
-
-
-#endif /* _NGX_PROXY_PROTOCOL_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_queue.c b/usr.sbin/nginx/src/core/ngx_queue.c
deleted file mode 100644
index 3cacaf3a883..00000000000
--- a/usr.sbin/nginx/src/core/ngx_queue.c
+++ /dev/null
@@ -1,80 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/*
- * find the middle queue element if the queue has odd number of elements
- * or the first element of the queue's second part otherwise
- */
-
-ngx_queue_t *
-ngx_queue_middle(ngx_queue_t *queue)
-{
- ngx_queue_t *middle, *next;
-
- middle = ngx_queue_head(queue);
-
- if (middle == ngx_queue_last(queue)) {
- return middle;
- }
-
- next = ngx_queue_head(queue);
-
- for ( ;; ) {
- middle = ngx_queue_next(middle);
-
- next = ngx_queue_next(next);
-
- if (next == ngx_queue_last(queue)) {
- return middle;
- }
-
- next = ngx_queue_next(next);
-
- if (next == ngx_queue_last(queue)) {
- return middle;
- }
- }
-}
-
-
-/* the stable insertion sort */
-
-void
-ngx_queue_sort(ngx_queue_t *queue,
- ngx_int_t (*cmp)(const ngx_queue_t *, const ngx_queue_t *))
-{
- ngx_queue_t *q, *prev, *next;
-
- q = ngx_queue_head(queue);
-
- if (q == ngx_queue_last(queue)) {
- return;
- }
-
- for (q = ngx_queue_next(q); q != ngx_queue_sentinel(queue); q = next) {
-
- prev = ngx_queue_prev(q);
- next = ngx_queue_next(q);
-
- ngx_queue_remove(q);
-
- do {
- if (cmp(prev, q) <= 0) {
- break;
- }
-
- prev = ngx_queue_prev(prev);
-
- } while (prev != ngx_queue_sentinel(queue));
-
- ngx_queue_insert_after(prev, q);
- }
-}
diff --git a/usr.sbin/nginx/src/core/ngx_queue.h b/usr.sbin/nginx/src/core/ngx_queue.h
deleted file mode 100644
index 038bf121138..00000000000
--- a/usr.sbin/nginx/src/core/ngx_queue.h
+++ /dev/null
@@ -1,112 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#ifndef _NGX_QUEUE_H_INCLUDED_
-#define _NGX_QUEUE_H_INCLUDED_
-
-
-typedef struct ngx_queue_s ngx_queue_t;
-
-struct ngx_queue_s {
- ngx_queue_t *prev;
- ngx_queue_t *next;
-};
-
-
-#define ngx_queue_init(q) \
- (q)->prev = q; \
- (q)->next = q
-
-
-#define ngx_queue_empty(h) \
- (h == (h)->prev)
-
-
-#define ngx_queue_insert_head(h, x) \
- (x)->next = (h)->next; \
- (x)->next->prev = x; \
- (x)->prev = h; \
- (h)->next = x
-
-
-#define ngx_queue_insert_after ngx_queue_insert_head
-
-
-#define ngx_queue_insert_tail(h, x) \
- (x)->prev = (h)->prev; \
- (x)->prev->next = x; \
- (x)->next = h; \
- (h)->prev = x
-
-
-#define ngx_queue_head(h) \
- (h)->next
-
-
-#define ngx_queue_last(h) \
- (h)->prev
-
-
-#define ngx_queue_sentinel(h) \
- (h)
-
-
-#define ngx_queue_next(q) \
- (q)->next
-
-
-#define ngx_queue_prev(q) \
- (q)->prev
-
-
-#if (NGX_DEBUG)
-
-#define ngx_queue_remove(x) \
- (x)->next->prev = (x)->prev; \
- (x)->prev->next = (x)->next; \
- (x)->prev = NULL; \
- (x)->next = NULL
-
-#else
-
-#define ngx_queue_remove(x) \
- (x)->next->prev = (x)->prev; \
- (x)->prev->next = (x)->next
-
-#endif
-
-
-#define ngx_queue_split(h, q, n) \
- (n)->prev = (h)->prev; \
- (n)->prev->next = n; \
- (n)->next = q; \
- (h)->prev = (q)->prev; \
- (h)->prev->next = h; \
- (q)->prev = n;
-
-
-#define ngx_queue_add(h, n) \
- (h)->prev->next = (n)->next; \
- (n)->next->prev = (h)->prev; \
- (h)->prev = (n)->prev; \
- (h)->prev->next = h;
-
-
-#define ngx_queue_data(q, type, link) \
- (type *) ((u_char *) q - offsetof(type, link))
-
-
-ngx_queue_t *ngx_queue_middle(ngx_queue_t *queue);
-void ngx_queue_sort(ngx_queue_t *queue,
- ngx_int_t (*cmp)(const ngx_queue_t *, const ngx_queue_t *));
-
-
-#endif /* _NGX_QUEUE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_radix_tree.c b/usr.sbin/nginx/src/core/ngx_radix_tree.c
deleted file mode 100644
index c1d873749b8..00000000000
--- a/usr.sbin/nginx/src/core/ngx_radix_tree.c
+++ /dev/null
@@ -1,488 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-static ngx_radix_node_t *ngx_radix_alloc(ngx_radix_tree_t *tree);
-
-
-ngx_radix_tree_t *
-ngx_radix_tree_create(ngx_pool_t *pool, ngx_int_t preallocate)
-{
- uint32_t key, mask, inc;
- ngx_radix_tree_t *tree;
-
- tree = ngx_palloc(pool, sizeof(ngx_radix_tree_t));
- if (tree == NULL) {
- return NULL;
- }
-
- tree->pool = pool;
- tree->free = NULL;
- tree->start = NULL;
- tree->size = 0;
-
- tree->root = ngx_radix_alloc(tree);
- if (tree->root == NULL) {
- return NULL;
- }
-
- tree->root->right = NULL;
- tree->root->left = NULL;
- tree->root->parent = NULL;
- tree->root->value = NGX_RADIX_NO_VALUE;
-
- if (preallocate == 0) {
- return tree;
- }
-
- /*
- * Preallocation of first nodes : 0, 1, 00, 01, 10, 11, 000, 001, etc.
- * increases TLB hits even if for first lookup iterations.
- * On 32-bit platforms the 7 preallocated bits takes continuous 4K,
- * 8 - 8K, 9 - 16K, etc. On 64-bit platforms the 6 preallocated bits
- * takes continuous 4K, 7 - 8K, 8 - 16K, etc. There is no sense to
- * to preallocate more than one page, because further preallocation
- * distributes the only bit per page. Instead, a random insertion
- * may distribute several bits per page.
- *
- * Thus, by default we preallocate maximum
- * 6 bits on amd64 (64-bit platform and 4K pages)
- * 7 bits on i386 (32-bit platform and 4K pages)
- * 7 bits on sparc64 in 64-bit mode (8K pages)
- * 8 bits on sparc64 in 32-bit mode (8K pages)
- */
-
- if (preallocate == -1) {
- switch (ngx_pagesize / sizeof(ngx_radix_node_t)) {
-
- /* amd64 */
- case 128:
- preallocate = 6;
- break;
-
- /* i386, sparc64 */
- case 256:
- preallocate = 7;
- break;
-
- /* sparc64 in 32-bit mode */
- default:
- preallocate = 8;
- }
- }
-
- mask = 0;
- inc = 0x80000000;
-
- while (preallocate--) {
-
- key = 0;
- mask >>= 1;
- mask |= 0x80000000;
-
- do {
- if (ngx_radix32tree_insert(tree, key, mask, NGX_RADIX_NO_VALUE)
- != NGX_OK)
- {
- return NULL;
- }
-
- key += inc;
-
- } while (key);
-
- inc >>= 1;
- }
-
- return tree;
-}
-
-
-ngx_int_t
-ngx_radix32tree_insert(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask,
- uintptr_t value)
-{
- uint32_t bit;
- ngx_radix_node_t *node, *next;
-
- bit = 0x80000000;
-
- node = tree->root;
- next = tree->root;
-
- while (bit & mask) {
- if (key & bit) {
- next = node->right;
-
- } else {
- next = node->left;
- }
-
- if (next == NULL) {
- break;
- }
-
- bit >>= 1;
- node = next;
- }
-
- if (next) {
- if (node->value != NGX_RADIX_NO_VALUE) {
- return NGX_BUSY;
- }
-
- node->value = value;
- return NGX_OK;
- }
-
- while (bit & mask) {
- next = ngx_radix_alloc(tree);
- if (next == NULL) {
- return NGX_ERROR;
- }
-
- next->right = NULL;
- next->left = NULL;
- next->parent = node;
- next->value = NGX_RADIX_NO_VALUE;
-
- if (key & bit) {
- node->right = next;
-
- } else {
- node->left = next;
- }
-
- bit >>= 1;
- node = next;
- }
-
- node->value = value;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_radix32tree_delete(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask)
-{
- uint32_t bit;
- ngx_radix_node_t *node;
-
- bit = 0x80000000;
- node = tree->root;
-
- while (node && (bit & mask)) {
- if (key & bit) {
- node = node->right;
-
- } else {
- node = node->left;
- }
-
- bit >>= 1;
- }
-
- if (node == NULL) {
- return NGX_ERROR;
- }
-
- if (node->right || node->left) {
- if (node->value != NGX_RADIX_NO_VALUE) {
- node->value = NGX_RADIX_NO_VALUE;
- return NGX_OK;
- }
-
- return NGX_ERROR;
- }
-
- for ( ;; ) {
- if (node->parent->right == node) {
- node->parent->right = NULL;
-
- } else {
- node->parent->left = NULL;
- }
-
- node->right = tree->free;
- tree->free = node;
-
- node = node->parent;
-
- if (node->right || node->left) {
- break;
- }
-
- if (node->value != NGX_RADIX_NO_VALUE) {
- break;
- }
-
- if (node->parent == NULL) {
- break;
- }
- }
-
- return NGX_OK;
-}
-
-
-uintptr_t
-ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key)
-{
- uint32_t bit;
- uintptr_t value;
- ngx_radix_node_t *node;
-
- bit = 0x80000000;
- value = NGX_RADIX_NO_VALUE;
- node = tree->root;
-
- while (node) {
- if (node->value != NGX_RADIX_NO_VALUE) {
- value = node->value;
- }
-
- if (key & bit) {
- node = node->right;
-
- } else {
- node = node->left;
- }
-
- bit >>= 1;
- }
-
- return value;
-}
-
-
-#if (NGX_HAVE_INET6)
-
-ngx_int_t
-ngx_radix128tree_insert(ngx_radix_tree_t *tree, u_char *key, u_char *mask,
- uintptr_t value)
-{
- u_char bit;
- ngx_uint_t i;
- ngx_radix_node_t *node, *next;
-
- i = 0;
- bit = 0x80;
-
- node = tree->root;
- next = tree->root;
-
- while (bit & mask[i]) {
- if (key[i] & bit) {
- next = node->right;
-
- } else {
- next = node->left;
- }
-
- if (next == NULL) {
- break;
- }
-
- bit >>= 1;
- node = next;
-
- if (bit == 0) {
- if (++i == 16) {
- break;
- }
-
- bit = 0x80;
- }
- }
-
- if (next) {
- if (node->value != NGX_RADIX_NO_VALUE) {
- return NGX_BUSY;
- }
-
- node->value = value;
- return NGX_OK;
- }
-
- while (bit & mask[i]) {
- next = ngx_radix_alloc(tree);
- if (next == NULL) {
- return NGX_ERROR;
- }
-
- next->right = NULL;
- next->left = NULL;
- next->parent = node;
- next->value = NGX_RADIX_NO_VALUE;
-
- if (key[i] & bit) {
- node->right = next;
-
- } else {
- node->left = next;
- }
-
- bit >>= 1;
- node = next;
-
- if (bit == 0) {
- if (++i == 16) {
- break;
- }
-
- bit = 0x80;
- }
- }
-
- node->value = value;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_radix128tree_delete(ngx_radix_tree_t *tree, u_char *key, u_char *mask)
-{
- u_char bit;
- ngx_uint_t i;
- ngx_radix_node_t *node;
-
- i = 0;
- bit = 0x80;
- node = tree->root;
-
- while (node && (bit & mask[i])) {
- if (key[i] & bit) {
- node = node->right;
-
- } else {
- node = node->left;
- }
-
- bit >>= 1;
-
- if (bit == 0) {
- if (++i == 16) {
- break;
- }
-
- bit = 0x80;
- }
- }
-
- if (node == NULL) {
- return NGX_ERROR;
- }
-
- if (node->right || node->left) {
- if (node->value != NGX_RADIX_NO_VALUE) {
- node->value = NGX_RADIX_NO_VALUE;
- return NGX_OK;
- }
-
- return NGX_ERROR;
- }
-
- for ( ;; ) {
- if (node->parent->right == node) {
- node->parent->right = NULL;
-
- } else {
- node->parent->left = NULL;
- }
-
- node->right = tree->free;
- tree->free = node;
-
- node = node->parent;
-
- if (node->right || node->left) {
- break;
- }
-
- if (node->value != NGX_RADIX_NO_VALUE) {
- break;
- }
-
- if (node->parent == NULL) {
- break;
- }
- }
-
- return NGX_OK;
-}
-
-
-uintptr_t
-ngx_radix128tree_find(ngx_radix_tree_t *tree, u_char *key)
-{
- u_char bit;
- uintptr_t value;
- ngx_uint_t i;
- ngx_radix_node_t *node;
-
- i = 0;
- bit = 0x80;
- value = NGX_RADIX_NO_VALUE;
- node = tree->root;
-
- while (node) {
- if (node->value != NGX_RADIX_NO_VALUE) {
- value = node->value;
- }
-
- if (key[i] & bit) {
- node = node->right;
-
- } else {
- node = node->left;
- }
-
- bit >>= 1;
-
- if (bit == 0) {
- i++;
- bit = 0x80;
- }
- }
-
- return value;
-}
-
-#endif
-
-
-static ngx_radix_node_t *
-ngx_radix_alloc(ngx_radix_tree_t *tree)
-{
- ngx_radix_node_t *p;
-
- if (tree->free) {
- p = tree->free;
- tree->free = tree->free->right;
- return p;
- }
-
- if (tree->size < sizeof(ngx_radix_node_t)) {
- tree->start = ngx_pmemalign(tree->pool, ngx_pagesize, ngx_pagesize);
- if (tree->start == NULL) {
- return NULL;
- }
-
- tree->size = ngx_pagesize;
- }
-
- p = (ngx_radix_node_t *) tree->start;
- tree->start += sizeof(ngx_radix_node_t);
- tree->size -= sizeof(ngx_radix_node_t);
-
- return p;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_radix_tree.h b/usr.sbin/nginx/src/core/ngx_radix_tree.h
deleted file mode 100644
index 4fe06e01474..00000000000
--- a/usr.sbin/nginx/src/core/ngx_radix_tree.h
+++ /dev/null
@@ -1,55 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_RADIX_TREE_H_INCLUDED_
-#define _NGX_RADIX_TREE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#define NGX_RADIX_NO_VALUE (uintptr_t) -1
-
-typedef struct ngx_radix_node_s ngx_radix_node_t;
-
-struct ngx_radix_node_s {
- ngx_radix_node_t *right;
- ngx_radix_node_t *left;
- ngx_radix_node_t *parent;
- uintptr_t value;
-};
-
-
-typedef struct {
- ngx_radix_node_t *root;
- ngx_pool_t *pool;
- ngx_radix_node_t *free;
- char *start;
- size_t size;
-} ngx_radix_tree_t;
-
-
-ngx_radix_tree_t *ngx_radix_tree_create(ngx_pool_t *pool,
- ngx_int_t preallocate);
-
-ngx_int_t ngx_radix32tree_insert(ngx_radix_tree_t *tree,
- uint32_t key, uint32_t mask, uintptr_t value);
-ngx_int_t ngx_radix32tree_delete(ngx_radix_tree_t *tree,
- uint32_t key, uint32_t mask);
-uintptr_t ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key);
-
-#if (NGX_HAVE_INET6)
-ngx_int_t ngx_radix128tree_insert(ngx_radix_tree_t *tree,
- u_char *key, u_char *mask, uintptr_t value);
-ngx_int_t ngx_radix128tree_delete(ngx_radix_tree_t *tree,
- u_char *key, u_char *mask);
-uintptr_t ngx_radix128tree_find(ngx_radix_tree_t *tree, u_char *key);
-#endif
-
-
-#endif /* _NGX_RADIX_TREE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_rbtree.c b/usr.sbin/nginx/src/core/ngx_rbtree.c
deleted file mode 100644
index 914ca7e884b..00000000000
--- a/usr.sbin/nginx/src/core/ngx_rbtree.c
+++ /dev/null
@@ -1,382 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/*
- * The red-black tree code is based on the algorithm described in
- * the "Introduction to Algorithms" by Cormen, Leiserson and Rivest.
- */
-
-
-static ngx_inline void ngx_rbtree_left_rotate(ngx_rbtree_node_t **root,
- ngx_rbtree_node_t *sentinel, ngx_rbtree_node_t *node);
-static ngx_inline void ngx_rbtree_right_rotate(ngx_rbtree_node_t **root,
- ngx_rbtree_node_t *sentinel, ngx_rbtree_node_t *node);
-
-
-void
-ngx_rbtree_insert(ngx_thread_volatile ngx_rbtree_t *tree,
- ngx_rbtree_node_t *node)
-{
- ngx_rbtree_node_t **root, *temp, *sentinel;
-
- /* a binary tree insert */
-
- root = (ngx_rbtree_node_t **) &tree->root;
- sentinel = tree->sentinel;
-
- if (*root == sentinel) {
- node->parent = NULL;
- node->left = sentinel;
- node->right = sentinel;
- ngx_rbt_black(node);
- *root = node;
-
- return;
- }
-
- tree->insert(*root, node, sentinel);
-
- /* re-balance tree */
-
- while (node != *root && ngx_rbt_is_red(node->parent)) {
-
- if (node->parent == node->parent->parent->left) {
- temp = node->parent->parent->right;
-
- if (ngx_rbt_is_red(temp)) {
- ngx_rbt_black(node->parent);
- ngx_rbt_black(temp);
- ngx_rbt_red(node->parent->parent);
- node = node->parent->parent;
-
- } else {
- if (node == node->parent->right) {
- node = node->parent;
- ngx_rbtree_left_rotate(root, sentinel, node);
- }
-
- ngx_rbt_black(node->parent);
- ngx_rbt_red(node->parent->parent);
- ngx_rbtree_right_rotate(root, sentinel, node->parent->parent);
- }
-
- } else {
- temp = node->parent->parent->left;
-
- if (ngx_rbt_is_red(temp)) {
- ngx_rbt_black(node->parent);
- ngx_rbt_black(temp);
- ngx_rbt_red(node->parent->parent);
- node = node->parent->parent;
-
- } else {
- if (node == node->parent->left) {
- node = node->parent;
- ngx_rbtree_right_rotate(root, sentinel, node);
- }
-
- ngx_rbt_black(node->parent);
- ngx_rbt_red(node->parent->parent);
- ngx_rbtree_left_rotate(root, sentinel, node->parent->parent);
- }
- }
- }
-
- ngx_rbt_black(*root);
-}
-
-
-void
-ngx_rbtree_insert_value(ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node,
- ngx_rbtree_node_t *sentinel)
-{
- ngx_rbtree_node_t **p;
-
- for ( ;; ) {
-
- p = (node->key < temp->key) ? &temp->left : &temp->right;
-
- if (*p == sentinel) {
- break;
- }
-
- temp = *p;
- }
-
- *p = node;
- node->parent = temp;
- node->left = sentinel;
- node->right = sentinel;
- ngx_rbt_red(node);
-}
-
-
-void
-ngx_rbtree_insert_timer_value(ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node,
- ngx_rbtree_node_t *sentinel)
-{
- ngx_rbtree_node_t **p;
-
- for ( ;; ) {
-
- /*
- * Timer values
- * 1) are spread in small range, usually several minutes,
- * 2) and overflow each 49 days, if milliseconds are stored in 32 bits.
- * The comparison takes into account that overflow.
- */
-
- /* node->key < temp->key */
-
- p = ((ngx_rbtree_key_int_t) (node->key - temp->key) < 0)
- ? &temp->left : &temp->right;
-
- if (*p == sentinel) {
- break;
- }
-
- temp = *p;
- }
-
- *p = node;
- node->parent = temp;
- node->left = sentinel;
- node->right = sentinel;
- ngx_rbt_red(node);
-}
-
-
-void
-ngx_rbtree_delete(ngx_thread_volatile ngx_rbtree_t *tree,
- ngx_rbtree_node_t *node)
-{
- ngx_uint_t red;
- ngx_rbtree_node_t **root, *sentinel, *subst, *temp, *w;
-
- /* a binary tree delete */
-
- root = (ngx_rbtree_node_t **) &tree->root;
- sentinel = tree->sentinel;
-
- if (node->left == sentinel) {
- temp = node->right;
- subst = node;
-
- } else if (node->right == sentinel) {
- temp = node->left;
- subst = node;
-
- } else {
- subst = ngx_rbtree_min(node->right, sentinel);
-
- if (subst->left != sentinel) {
- temp = subst->left;
- } else {
- temp = subst->right;
- }
- }
-
- if (subst == *root) {
- *root = temp;
- ngx_rbt_black(temp);
-
- /* DEBUG stuff */
- node->left = NULL;
- node->right = NULL;
- node->parent = NULL;
- node->key = 0;
-
- return;
- }
-
- red = ngx_rbt_is_red(subst);
-
- if (subst == subst->parent->left) {
- subst->parent->left = temp;
-
- } else {
- subst->parent->right = temp;
- }
-
- if (subst == node) {
-
- temp->parent = subst->parent;
-
- } else {
-
- if (subst->parent == node) {
- temp->parent = subst;
-
- } else {
- temp->parent = subst->parent;
- }
-
- subst->left = node->left;
- subst->right = node->right;
- subst->parent = node->parent;
- ngx_rbt_copy_color(subst, node);
-
- if (node == *root) {
- *root = subst;
-
- } else {
- if (node == node->parent->left) {
- node->parent->left = subst;
- } else {
- node->parent->right = subst;
- }
- }
-
- if (subst->left != sentinel) {
- subst->left->parent = subst;
- }
-
- if (subst->right != sentinel) {
- subst->right->parent = subst;
- }
- }
-
- /* DEBUG stuff */
- node->left = NULL;
- node->right = NULL;
- node->parent = NULL;
- node->key = 0;
-
- if (red) {
- return;
- }
-
- /* a delete fixup */
-
- while (temp != *root && ngx_rbt_is_black(temp)) {
-
- if (temp == temp->parent->left) {
- w = temp->parent->right;
-
- if (ngx_rbt_is_red(w)) {
- ngx_rbt_black(w);
- ngx_rbt_red(temp->parent);
- ngx_rbtree_left_rotate(root, sentinel, temp->parent);
- w = temp->parent->right;
- }
-
- if (ngx_rbt_is_black(w->left) && ngx_rbt_is_black(w->right)) {
- ngx_rbt_red(w);
- temp = temp->parent;
-
- } else {
- if (ngx_rbt_is_black(w->right)) {
- ngx_rbt_black(w->left);
- ngx_rbt_red(w);
- ngx_rbtree_right_rotate(root, sentinel, w);
- w = temp->parent->right;
- }
-
- ngx_rbt_copy_color(w, temp->parent);
- ngx_rbt_black(temp->parent);
- ngx_rbt_black(w->right);
- ngx_rbtree_left_rotate(root, sentinel, temp->parent);
- temp = *root;
- }
-
- } else {
- w = temp->parent->left;
-
- if (ngx_rbt_is_red(w)) {
- ngx_rbt_black(w);
- ngx_rbt_red(temp->parent);
- ngx_rbtree_right_rotate(root, sentinel, temp->parent);
- w = temp->parent->left;
- }
-
- if (ngx_rbt_is_black(w->left) && ngx_rbt_is_black(w->right)) {
- ngx_rbt_red(w);
- temp = temp->parent;
-
- } else {
- if (ngx_rbt_is_black(w->left)) {
- ngx_rbt_black(w->right);
- ngx_rbt_red(w);
- ngx_rbtree_left_rotate(root, sentinel, w);
- w = temp->parent->left;
- }
-
- ngx_rbt_copy_color(w, temp->parent);
- ngx_rbt_black(temp->parent);
- ngx_rbt_black(w->left);
- ngx_rbtree_right_rotate(root, sentinel, temp->parent);
- temp = *root;
- }
- }
- }
-
- ngx_rbt_black(temp);
-}
-
-
-static ngx_inline void
-ngx_rbtree_left_rotate(ngx_rbtree_node_t **root, ngx_rbtree_node_t *sentinel,
- ngx_rbtree_node_t *node)
-{
- ngx_rbtree_node_t *temp;
-
- temp = node->right;
- node->right = temp->left;
-
- if (temp->left != sentinel) {
- temp->left->parent = node;
- }
-
- temp->parent = node->parent;
-
- if (node == *root) {
- *root = temp;
-
- } else if (node == node->parent->left) {
- node->parent->left = temp;
-
- } else {
- node->parent->right = temp;
- }
-
- temp->left = node;
- node->parent = temp;
-}
-
-
-static ngx_inline void
-ngx_rbtree_right_rotate(ngx_rbtree_node_t **root, ngx_rbtree_node_t *sentinel,
- ngx_rbtree_node_t *node)
-{
- ngx_rbtree_node_t *temp;
-
- temp = node->left;
- node->left = temp->right;
-
- if (temp->right != sentinel) {
- temp->right->parent = node;
- }
-
- temp->parent = node->parent;
-
- if (node == *root) {
- *root = temp;
-
- } else if (node == node->parent->right) {
- node->parent->right = temp;
-
- } else {
- node->parent->left = temp;
- }
-
- temp->right = node;
- node->parent = temp;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_rbtree.h b/usr.sbin/nginx/src/core/ngx_rbtree.h
deleted file mode 100644
index 6e47a5bbbaa..00000000000
--- a/usr.sbin/nginx/src/core/ngx_rbtree.h
+++ /dev/null
@@ -1,84 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_RBTREE_H_INCLUDED_
-#define _NGX_RBTREE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef ngx_uint_t ngx_rbtree_key_t;
-typedef ngx_int_t ngx_rbtree_key_int_t;
-
-
-typedef struct ngx_rbtree_node_s ngx_rbtree_node_t;
-
-struct ngx_rbtree_node_s {
- ngx_rbtree_key_t key;
- ngx_rbtree_node_t *left;
- ngx_rbtree_node_t *right;
- ngx_rbtree_node_t *parent;
- u_char color;
- u_char data;
-};
-
-
-typedef struct ngx_rbtree_s ngx_rbtree_t;
-
-typedef void (*ngx_rbtree_insert_pt) (ngx_rbtree_node_t *root,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
-
-struct ngx_rbtree_s {
- ngx_rbtree_node_t *root;
- ngx_rbtree_node_t *sentinel;
- ngx_rbtree_insert_pt insert;
-};
-
-
-#define ngx_rbtree_init(tree, s, i) \
- ngx_rbtree_sentinel_init(s); \
- (tree)->root = s; \
- (tree)->sentinel = s; \
- (tree)->insert = i
-
-
-void ngx_rbtree_insert(ngx_thread_volatile ngx_rbtree_t *tree,
- ngx_rbtree_node_t *node);
-void ngx_rbtree_delete(ngx_thread_volatile ngx_rbtree_t *tree,
- ngx_rbtree_node_t *node);
-void ngx_rbtree_insert_value(ngx_rbtree_node_t *root, ngx_rbtree_node_t *node,
- ngx_rbtree_node_t *sentinel);
-void ngx_rbtree_insert_timer_value(ngx_rbtree_node_t *root,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
-
-
-#define ngx_rbt_red(node) ((node)->color = 1)
-#define ngx_rbt_black(node) ((node)->color = 0)
-#define ngx_rbt_is_red(node) ((node)->color)
-#define ngx_rbt_is_black(node) (!ngx_rbt_is_red(node))
-#define ngx_rbt_copy_color(n1, n2) (n1->color = n2->color)
-
-
-/* a sentinel must be black */
-
-#define ngx_rbtree_sentinel_init(node) ngx_rbt_black(node)
-
-
-static ngx_inline ngx_rbtree_node_t *
-ngx_rbtree_min(ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
-{
- while (node->left != sentinel) {
- node = node->left;
- }
-
- return node;
-}
-
-
-#endif /* _NGX_RBTREE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_regex.c b/usr.sbin/nginx/src/core/ngx_regex.c
deleted file mode 100644
index 3771aab8ee7..00000000000
--- a/usr.sbin/nginx/src/core/ngx_regex.c
+++ /dev/null
@@ -1,464 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef struct {
- ngx_flag_t pcre_jit;
-} ngx_regex_conf_t;
-
-
-static void * ngx_libc_cdecl ngx_regex_malloc(size_t size);
-static void ngx_libc_cdecl ngx_regex_free(void *p);
-#if (NGX_HAVE_PCRE_JIT)
-static void ngx_pcre_free_studies(void *data);
-#endif
-
-static ngx_int_t ngx_regex_module_init(ngx_cycle_t *cycle);
-
-static void *ngx_regex_create_conf(ngx_cycle_t *cycle);
-static char *ngx_regex_init_conf(ngx_cycle_t *cycle, void *conf);
-
-static char *ngx_regex_pcre_jit(ngx_conf_t *cf, void *post, void *data);
-static ngx_conf_post_t ngx_regex_pcre_jit_post = { ngx_regex_pcre_jit };
-
-
-static ngx_command_t ngx_regex_commands[] = {
-
- { ngx_string("pcre_jit"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_flag_slot,
- 0,
- offsetof(ngx_regex_conf_t, pcre_jit),
- &ngx_regex_pcre_jit_post },
-
- ngx_null_command
-};
-
-
-static ngx_core_module_t ngx_regex_module_ctx = {
- ngx_string("regex"),
- ngx_regex_create_conf,
- ngx_regex_init_conf
-};
-
-
-ngx_module_t ngx_regex_module = {
- NGX_MODULE_V1,
- &ngx_regex_module_ctx, /* module context */
- ngx_regex_commands, /* module directives */
- NGX_CORE_MODULE, /* module type */
- NULL, /* init master */
- ngx_regex_module_init, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_pool_t *ngx_pcre_pool;
-static ngx_list_t *ngx_pcre_studies;
-
-
-void
-ngx_regex_init(void)
-{
- pcre_malloc = ngx_regex_malloc;
- pcre_free = ngx_regex_free;
-}
-
-
-static ngx_inline void
-ngx_regex_malloc_init(ngx_pool_t *pool)
-{
-#if (NGX_THREADS)
- ngx_core_tls_t *tls;
-
- if (ngx_threaded) {
- tls = ngx_thread_get_tls(ngx_core_tls_key);
- tls->pool = pool;
- return;
- }
-
-#endif
-
- ngx_pcre_pool = pool;
-}
-
-
-static ngx_inline void
-ngx_regex_malloc_done(void)
-{
-#if (NGX_THREADS)
- ngx_core_tls_t *tls;
-
- if (ngx_threaded) {
- tls = ngx_thread_get_tls(ngx_core_tls_key);
- tls->pool = NULL;
- return;
- }
-
-#endif
-
- ngx_pcre_pool = NULL;
-}
-
-
-ngx_int_t
-ngx_regex_compile(ngx_regex_compile_t *rc)
-{
- int n, erroff;
- char *p;
- pcre *re;
- const char *errstr;
- ngx_regex_elt_t *elt;
-
- ngx_regex_malloc_init(rc->pool);
-
- re = pcre_compile((const char *) rc->pattern.data, (int) rc->options,
- &errstr, &erroff, NULL);
-
- /* ensure that there is no current pool */
- ngx_regex_malloc_done();
-
- if (re == NULL) {
- if ((size_t) erroff == rc->pattern.len) {
- rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
- "pcre_compile() failed: %s in \"%V\"",
- errstr, &rc->pattern)
- - rc->err.data;
-
- } else {
- rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
- "pcre_compile() failed: %s in \"%V\" at \"%s\"",
- errstr, &rc->pattern, rc->pattern.data + erroff)
- - rc->err.data;
- }
-
- return NGX_ERROR;
- }
-
- rc->regex = ngx_pcalloc(rc->pool, sizeof(ngx_regex_t));
- if (rc->regex == NULL) {
- return NGX_ERROR;
- }
-
- rc->regex->code = re;
-
- /* do not study at runtime */
-
- if (ngx_pcre_studies != NULL) {
- elt = ngx_list_push(ngx_pcre_studies);
- if (elt == NULL) {
- return NGX_ERROR;
- }
-
- elt->regex = rc->regex;
- elt->name = rc->pattern.data;
- }
-
- n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures);
- if (n < 0) {
- p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d";
- goto failed;
- }
-
- if (rc->captures == 0) {
- return NGX_OK;
- }
-
- n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &rc->named_captures);
- if (n < 0) {
- p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMECOUNT) failed: %d";
- goto failed;
- }
-
- if (rc->named_captures == 0) {
- return NGX_OK;
- }
-
- n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &rc->name_size);
- if (n < 0) {
- p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMEENTRYSIZE) failed: %d";
- goto failed;
- }
-
- n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &rc->names);
- if (n < 0) {
- p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMETABLE) failed: %d";
- goto failed;
- }
-
- return NGX_OK;
-
-failed:
-
- rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n)
- - rc->err.data;
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log)
-{
- ngx_int_t n;
- ngx_uint_t i;
- ngx_regex_elt_t *re;
-
- re = a->elts;
-
- for (i = 0; i < a->nelts; i++) {
-
- n = ngx_regex_exec(re[i].regex, s, NULL, 0);
-
- if (n == NGX_REGEX_NO_MATCHED) {
- continue;
- }
-
- if (n < 0) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- ngx_regex_exec_n " failed: %i on \"%V\" using \"%s\"",
- n, s, re[i].name);
- return NGX_ERROR;
- }
-
- /* match */
-
- return NGX_OK;
- }
-
- return NGX_DECLINED;
-}
-
-
-static void * ngx_libc_cdecl
-ngx_regex_malloc(size_t size)
-{
- ngx_pool_t *pool;
-#if (NGX_THREADS)
- ngx_core_tls_t *tls;
-
- if (ngx_threaded) {
- tls = ngx_thread_get_tls(ngx_core_tls_key);
- pool = tls->pool;
-
- } else {
- pool = ngx_pcre_pool;
- }
-
-#else
-
- pool = ngx_pcre_pool;
-
-#endif
-
- if (pool) {
- return ngx_palloc(pool, size);
- }
-
- return NULL;
-}
-
-
-static void ngx_libc_cdecl
-ngx_regex_free(void *p)
-{
- return;
-}
-
-
-#if (NGX_HAVE_PCRE_JIT)
-
-static void
-ngx_pcre_free_studies(void *data)
-{
- ngx_list_t *studies = data;
-
- ngx_uint_t i;
- ngx_list_part_t *part;
- ngx_regex_elt_t *elts;
-
- part = &studies->part;
- elts = part->elts;
-
- for (i = 0 ; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- elts = part->elts;
- i = 0;
- }
-
- if (elts[i].regex->extra != NULL) {
- pcre_free_study(elts[i].regex->extra);
- }
- }
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_regex_module_init(ngx_cycle_t *cycle)
-{
- int opt;
- const char *errstr;
- ngx_uint_t i;
- ngx_list_part_t *part;
- ngx_regex_elt_t *elts;
-
- opt = 0;
-
-#if (NGX_HAVE_PCRE_JIT)
- {
- ngx_regex_conf_t *rcf;
- ngx_pool_cleanup_t *cln;
-
- rcf = (ngx_regex_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_regex_module);
-
- if (rcf->pcre_jit) {
- opt = PCRE_STUDY_JIT_COMPILE;
-
- /*
- * The PCRE JIT compiler uses mmap for its executable codes, so we
- * have to explicitly call the pcre_free_study() function to free
- * this memory.
- */
-
- cln = ngx_pool_cleanup_add(cycle->pool, 0);
- if (cln == NULL) {
- return NGX_ERROR;
- }
-
- cln->handler = ngx_pcre_free_studies;
- cln->data = ngx_pcre_studies;
- }
- }
-#endif
-
- ngx_regex_malloc_init(cycle->pool);
-
- part = &ngx_pcre_studies->part;
- elts = part->elts;
-
- for (i = 0 ; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- elts = part->elts;
- i = 0;
- }
-
- elts[i].regex->extra = pcre_study(elts[i].regex->code, opt, &errstr);
-
- if (errstr != NULL) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "pcre_study() failed: %s in \"%s\"",
- errstr, elts[i].name);
- }
-
-#if (NGX_HAVE_PCRE_JIT)
- if (opt & PCRE_STUDY_JIT_COMPILE) {
- int jit, n;
-
- jit = 0;
- n = pcre_fullinfo(elts[i].regex->code, elts[i].regex->extra,
- PCRE_INFO_JIT, &jit);
-
- if (n != 0 || jit != 1) {
- ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
- "JIT compiler does not support pattern: \"%s\"",
- elts[i].name);
- }
- }
-#endif
- }
-
- ngx_regex_malloc_done();
-
- ngx_pcre_studies = NULL;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_regex_create_conf(ngx_cycle_t *cycle)
-{
- ngx_regex_conf_t *rcf;
-
- rcf = ngx_pcalloc(cycle->pool, sizeof(ngx_regex_conf_t));
- if (rcf == NULL) {
- return NULL;
- }
-
- rcf->pcre_jit = NGX_CONF_UNSET;
-
- ngx_pcre_studies = ngx_list_create(cycle->pool, 8, sizeof(ngx_regex_elt_t));
- if (ngx_pcre_studies == NULL) {
- return NULL;
- }
-
- return rcf;
-}
-
-
-static char *
-ngx_regex_init_conf(ngx_cycle_t *cycle, void *conf)
-{
- ngx_regex_conf_t *rcf = conf;
-
- ngx_conf_init_value(rcf->pcre_jit, 0);
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_regex_pcre_jit(ngx_conf_t *cf, void *post, void *data)
-{
- ngx_flag_t *fp = data;
-
- if (*fp == 0) {
- return NGX_CONF_OK;
- }
-
-#if (NGX_HAVE_PCRE_JIT)
- {
- int jit, r;
-
- jit = 0;
- r = pcre_config(PCRE_CONFIG_JIT, &jit);
-
- if (r != 0 || jit != 1) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "PCRE library does not support JIT");
- *fp = 0;
- }
- }
-#else
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "nginx was built without PCRE JIT support");
- *fp = 0;
-#endif
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_regex.h b/usr.sbin/nginx/src/core/ngx_regex.h
deleted file mode 100644
index 680486c816f..00000000000
--- a/usr.sbin/nginx/src/core/ngx_regex.h
+++ /dev/null
@@ -1,60 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_REGEX_H_INCLUDED_
-#define _NGX_REGEX_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-#include <pcre.h>
-
-
-#define NGX_REGEX_NO_MATCHED PCRE_ERROR_NOMATCH /* -1 */
-
-#define NGX_REGEX_CASELESS PCRE_CASELESS
-
-
-typedef struct {
- pcre *code;
- pcre_extra *extra;
-} ngx_regex_t;
-
-
-typedef struct {
- ngx_str_t pattern;
- ngx_pool_t *pool;
- ngx_int_t options;
-
- ngx_regex_t *regex;
- int captures;
- int named_captures;
- int name_size;
- u_char *names;
- ngx_str_t err;
-} ngx_regex_compile_t;
-
-
-typedef struct {
- ngx_regex_t *regex;
- u_char *name;
-} ngx_regex_elt_t;
-
-
-void ngx_regex_init(void);
-ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc);
-
-#define ngx_regex_exec(re, s, captures, size) \
- pcre_exec(re->code, re->extra, (const char *) (s)->data, (s)->len, 0, 0, \
- captures, size)
-#define ngx_regex_exec_n "pcre_exec()"
-
-ngx_int_t ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log);
-
-
-#endif /* _NGX_REGEX_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_resolver.c b/usr.sbin/nginx/src/core/ngx_resolver.c
deleted file mode 100644
index 645738ce531..00000000000
--- a/usr.sbin/nginx/src/core/ngx_resolver.c
+++ /dev/null
@@ -1,3108 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#define NGX_RESOLVER_UDP_SIZE 4096
-
-
-typedef struct {
- u_char ident_hi;
- u_char ident_lo;
- u_char flags_hi;
- u_char flags_lo;
- u_char nqs_hi;
- u_char nqs_lo;
- u_char nan_hi;
- u_char nan_lo;
- u_char nns_hi;
- u_char nns_lo;
- u_char nar_hi;
- u_char nar_lo;
-} ngx_resolver_hdr_t;
-
-
-typedef struct {
- u_char type_hi;
- u_char type_lo;
- u_char class_hi;
- u_char class_lo;
-} ngx_resolver_qs_t;
-
-
-typedef struct {
- u_char type_hi;
- u_char type_lo;
- u_char class_hi;
- u_char class_lo;
- u_char ttl[4];
- u_char len_hi;
- u_char len_lo;
-} ngx_resolver_an_t;
-
-
-ngx_int_t ngx_udp_connect(ngx_udp_connection_t *uc);
-
-
-static void ngx_resolver_cleanup(void *data);
-static void ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree);
-static ngx_int_t ngx_resolve_name_locked(ngx_resolver_t *r,
- ngx_resolver_ctx_t *ctx);
-static void ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree,
- ngx_queue_t *queue);
-static ngx_int_t ngx_resolver_send_query(ngx_resolver_t *r,
- ngx_resolver_node_t *rn);
-static ngx_int_t ngx_resolver_create_name_query(ngx_resolver_node_t *rn,
- ngx_resolver_ctx_t *ctx);
-static ngx_int_t ngx_resolver_create_addr_query(ngx_resolver_node_t *rn,
- ngx_resolver_ctx_t *ctx);
-static void ngx_resolver_resend_handler(ngx_event_t *ev);
-static time_t ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree,
- ngx_queue_t *queue);
-static void ngx_resolver_read_response(ngx_event_t *rev);
-static void ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf,
- size_t n);
-static void ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n,
- ngx_uint_t ident, ngx_uint_t code, ngx_uint_t qtype,
- ngx_uint_t nan, ngx_uint_t ans);
-static void ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
- ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan);
-static ngx_resolver_node_t *ngx_resolver_lookup_name(ngx_resolver_t *r,
- ngx_str_t *name, uint32_t hash);
-static ngx_resolver_node_t *ngx_resolver_lookup_addr(ngx_resolver_t *r,
- in_addr_t addr);
-static void ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
-static ngx_int_t ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name,
- u_char *buf, u_char *src, u_char *last);
-static void ngx_resolver_timeout_handler(ngx_event_t *ev);
-static void ngx_resolver_free_node(ngx_resolver_t *r, ngx_resolver_node_t *rn);
-static void *ngx_resolver_alloc(ngx_resolver_t *r, size_t size);
-static void *ngx_resolver_calloc(ngx_resolver_t *r, size_t size);
-static void ngx_resolver_free(ngx_resolver_t *r, void *p);
-static void ngx_resolver_free_locked(ngx_resolver_t *r, void *p);
-static void *ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size);
-static ngx_addr_t *ngx_resolver_export(ngx_resolver_t *r,
- ngx_resolver_node_t *rn, ngx_uint_t rotate);
-static u_char *ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len);
-
-#if (NGX_HAVE_INET6)
-static void ngx_resolver_rbtree_insert_addr6_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
-static ngx_resolver_node_t *ngx_resolver_lookup_addr6(ngx_resolver_t *r,
- struct in6_addr *addr, uint32_t hash);
-#endif
-
-
-ngx_resolver_t *
-ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names, ngx_uint_t n)
-{
- ngx_str_t s;
- ngx_url_t u;
- ngx_uint_t i, j;
- ngx_resolver_t *r;
- ngx_pool_cleanup_t *cln;
- ngx_udp_connection_t *uc;
-
- cln = ngx_pool_cleanup_add(cf->pool, 0);
- if (cln == NULL) {
- return NULL;
- }
-
- cln->handler = ngx_resolver_cleanup;
-
- r = ngx_calloc(sizeof(ngx_resolver_t), cf->log);
- if (r == NULL) {
- return NULL;
- }
-
- cln->data = r;
-
- r->event = ngx_calloc(sizeof(ngx_event_t), cf->log);
- if (r->event == NULL) {
- return NULL;
- }
-
- ngx_rbtree_init(&r->name_rbtree, &r->name_sentinel,
- ngx_resolver_rbtree_insert_value);
-
- ngx_rbtree_init(&r->addr_rbtree, &r->addr_sentinel,
- ngx_rbtree_insert_value);
-
- ngx_queue_init(&r->name_resend_queue);
- ngx_queue_init(&r->addr_resend_queue);
-
- ngx_queue_init(&r->name_expire_queue);
- ngx_queue_init(&r->addr_expire_queue);
-
-#if (NGX_HAVE_INET6)
- r->ipv6 = 1;
-
- ngx_rbtree_init(&r->addr6_rbtree, &r->addr6_sentinel,
- ngx_resolver_rbtree_insert_addr6_value);
-
- ngx_queue_init(&r->addr6_resend_queue);
-
- ngx_queue_init(&r->addr6_expire_queue);
-#endif
-
- r->event->handler = ngx_resolver_resend_handler;
- r->event->data = r;
- r->event->log = &cf->cycle->new_log;
- r->ident = -1;
-
- r->resend_timeout = 5;
- r->expire = 30;
- r->valid = 0;
-
- r->log = &cf->cycle->new_log;
- r->log_level = NGX_LOG_ERR;
-
- if (n) {
- if (ngx_array_init(&r->udp_connections, cf->pool, n,
- sizeof(ngx_udp_connection_t))
- != NGX_OK)
- {
- return NULL;
- }
- }
-
- for (i = 0; i < n; i++) {
- if (ngx_strncmp(names[i].data, "valid=", 6) == 0) {
- s.len = names[i].len - 6;
- s.data = names[i].data + 6;
-
- r->valid = ngx_parse_time(&s, 1);
-
- if (r->valid == (time_t) NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter: %V", &names[i]);
- return NULL;
- }
-
- continue;
- }
-
-#if (NGX_HAVE_INET6)
- if (ngx_strncmp(names[i].data, "ipv6=", 5) == 0) {
-
- if (ngx_strcmp(&names[i].data[5], "on") == 0) {
- r->ipv6 = 1;
-
- } else if (ngx_strcmp(&names[i].data[5], "off") == 0) {
- r->ipv6 = 0;
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter: %V", &names[i]);
- return NULL;
- }
-
- continue;
- }
-#endif
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- u.url = names[i];
- u.default_port = 53;
-
- if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
- if (u.err) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "%s in resolver \"%V\"",
- u.err, &u.url);
- }
-
- return NULL;
- }
-
- uc = ngx_array_push_n(&r->udp_connections, u.naddrs);
- if (uc == NULL) {
- return NULL;
- }
-
- ngx_memzero(uc, u.naddrs * sizeof(ngx_udp_connection_t));
-
- for (j = 0; j < u.naddrs; j++) {
- uc[j].sockaddr = u.addrs[j].sockaddr;
- uc[j].socklen = u.addrs[j].socklen;
- uc[j].server = u.addrs[j].name;
- }
- }
-
- return r;
-}
-
-
-static void
-ngx_resolver_cleanup(void *data)
-{
- ngx_resolver_t *r = data;
-
- ngx_uint_t i;
- ngx_udp_connection_t *uc;
-
- if (r) {
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
- "cleanup resolver");
-
- ngx_resolver_cleanup_tree(r, &r->name_rbtree);
-
- ngx_resolver_cleanup_tree(r, &r->addr_rbtree);
-
-#if (NGX_HAVE_INET6)
- ngx_resolver_cleanup_tree(r, &r->addr6_rbtree);
-#endif
-
- if (r->event) {
- ngx_free(r->event);
- }
-
-
- uc = r->udp_connections.elts;
-
- for (i = 0; i < r->udp_connections.nelts; i++) {
- if (uc[i].connection) {
- ngx_close_connection(uc[i].connection);
- }
- }
-
- ngx_free(r);
- }
-}
-
-
-static void
-ngx_resolver_cleanup_tree(ngx_resolver_t *r, ngx_rbtree_t *tree)
-{
- ngx_resolver_ctx_t *ctx, *next;
- ngx_resolver_node_t *rn;
-
- while (tree->root != tree->sentinel) {
-
- rn = (ngx_resolver_node_t *) ngx_rbtree_min(tree->root, tree->sentinel);
-
- ngx_queue_remove(&rn->queue);
-
- for (ctx = rn->waiting; ctx; ctx = next) {
- next = ctx->next;
-
- if (ctx->event) {
- ngx_resolver_free(r, ctx->event);
- }
-
- ngx_resolver_free(r, ctx);
- }
-
- ngx_rbtree_delete(tree, &rn->node);
-
- ngx_resolver_free_node(r, rn);
- }
-}
-
-
-ngx_resolver_ctx_t *
-ngx_resolve_start(ngx_resolver_t *r, ngx_resolver_ctx_t *temp)
-{
- in_addr_t addr;
- ngx_resolver_ctx_t *ctx;
-
- if (temp) {
- addr = ngx_inet_addr(temp->name.data, temp->name.len);
-
- if (addr != INADDR_NONE) {
- temp->resolver = r;
- temp->state = NGX_OK;
- temp->naddrs = 1;
- temp->addrs = &temp->addr;
- temp->addr.sockaddr = (struct sockaddr *) &temp->sin;
- temp->addr.socklen = sizeof(struct sockaddr_in);
- ngx_memzero(&temp->sin, sizeof(struct sockaddr_in));
- temp->sin.sin_family = AF_INET;
- temp->sin.sin_addr.s_addr = addr;
- temp->quick = 1;
-
- return temp;
- }
- }
-
- if (r->udp_connections.nelts == 0) {
- return NGX_NO_RESOLVER;
- }
-
- ctx = ngx_resolver_calloc(r, sizeof(ngx_resolver_ctx_t));
-
- if (ctx) {
- ctx->resolver = r;
- }
-
- return ctx;
-}
-
-
-ngx_int_t
-ngx_resolve_name(ngx_resolver_ctx_t *ctx)
-{
- ngx_int_t rc;
- ngx_resolver_t *r;
-
- r = ctx->resolver;
-
- if (ctx->name.len > 0 && ctx->name.data[ctx->name.len - 1] == '.') {
- ctx->name.len--;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolve: \"%V\"", &ctx->name);
-
- if (ctx->quick) {
- ctx->handler(ctx);
- return NGX_OK;
- }
-
- /* lock name mutex */
-
- rc = ngx_resolve_name_locked(r, ctx);
-
- if (rc == NGX_OK) {
- return NGX_OK;
- }
-
- /* unlock name mutex */
-
- if (rc == NGX_AGAIN) {
- return NGX_OK;
- }
-
- /* NGX_ERROR */
-
- if (ctx->event) {
- ngx_resolver_free(r, ctx->event);
- }
-
- ngx_resolver_free(r, ctx);
-
- return NGX_ERROR;
-}
-
-
-void
-ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
-{
- uint32_t hash;
- ngx_resolver_t *r;
- ngx_resolver_ctx_t *w, **p;
- ngx_resolver_node_t *rn;
-
- r = ctx->resolver;
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolve name done: %i", ctx->state);
-
- if (ctx->quick) {
- return;
- }
-
- if (ctx->event && ctx->event->timer_set) {
- ngx_del_timer(ctx->event);
- }
-
- /* lock name mutex */
-
- if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
-
- hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
-
- rn = ngx_resolver_lookup_name(r, &ctx->name, hash);
-
- if (rn) {
- p = &rn->waiting;
- w = rn->waiting;
-
- while (w) {
- if (w == ctx) {
- *p = w->next;
-
- goto done;
- }
-
- p = &w->next;
- w = w->next;
- }
- }
-
- ngx_log_error(NGX_LOG_ALERT, r->log, 0,
- "could not cancel %V resolving", &ctx->name);
- }
-
-done:
-
- ngx_resolver_expire(r, &r->name_rbtree, &r->name_expire_queue);
-
- /* unlock name mutex */
-
- /* lock alloc mutex */
-
- if (ctx->event) {
- ngx_resolver_free_locked(r, ctx->event);
- }
-
- ngx_resolver_free_locked(r, ctx);
-
- /* unlock alloc mutex */
-}
-
-
-static ngx_int_t
-ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
-{
- uint32_t hash;
- ngx_int_t rc;
- ngx_uint_t naddrs;
- ngx_addr_t *addrs;
- ngx_resolver_ctx_t *next;
- ngx_resolver_node_t *rn;
-
- ngx_strlow(ctx->name.data, ctx->name.data, ctx->name.len);
-
- hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
-
- rn = ngx_resolver_lookup_name(r, &ctx->name, hash);
-
- if (rn) {
-
- if (rn->valid >= ngx_time()) {
-
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolve cached");
-
- ngx_queue_remove(&rn->queue);
-
- rn->expire = ngx_time() + r->expire;
-
- ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
-
- naddrs = (rn->naddrs == (u_short) -1) ? 0 : rn->naddrs;
-#if (NGX_HAVE_INET6)
- naddrs += (rn->naddrs6 == (u_short) -1) ? 0 : rn->naddrs6;
-#endif
-
- if (naddrs) {
-
- if (naddrs == 1 && rn->naddrs == 1) {
- addrs = NULL;
-
- } else {
- addrs = ngx_resolver_export(r, rn, 1);
- if (addrs == NULL) {
- return NGX_ERROR;
- }
- }
-
- ctx->next = rn->waiting;
- rn->waiting = NULL;
-
- /* unlock name mutex */
-
- do {
- ctx->state = NGX_OK;
- ctx->naddrs = naddrs;
-
- if (addrs == NULL) {
- ctx->addrs = &ctx->addr;
- ctx->addr.sockaddr = (struct sockaddr *) &ctx->sin;
- ctx->addr.socklen = sizeof(struct sockaddr_in);
- ngx_memzero(&ctx->sin, sizeof(struct sockaddr_in));
- ctx->sin.sin_family = AF_INET;
- ctx->sin.sin_addr.s_addr = rn->u.addr;
-
- } else {
- ctx->addrs = addrs;
- }
-
- next = ctx->next;
-
- ctx->handler(ctx);
-
- ctx = next;
- } while (ctx);
-
- if (addrs != NULL) {
- ngx_resolver_free(r, addrs->sockaddr);
- ngx_resolver_free(r, addrs);
- }
-
- return NGX_OK;
- }
-
- /* NGX_RESOLVE_CNAME */
-
- if (ctx->recursion++ < NGX_RESOLVER_MAX_RECURSION) {
-
- ctx->name.len = rn->cnlen;
- ctx->name.data = rn->u.cname;
-
- return ngx_resolve_name_locked(r, ctx);
- }
-
- ctx->next = rn->waiting;
- rn->waiting = NULL;
-
- /* unlock name mutex */
-
- do {
- ctx->state = NGX_RESOLVE_NXDOMAIN;
- next = ctx->next;
-
- ctx->handler(ctx);
-
- ctx = next;
- } while (ctx);
-
- return NGX_OK;
- }
-
- if (rn->waiting) {
-
- ctx->next = rn->waiting;
- rn->waiting = ctx;
- ctx->state = NGX_AGAIN;
-
- return NGX_AGAIN;
- }
-
- ngx_queue_remove(&rn->queue);
-
- /* lock alloc mutex */
-
- if (rn->query) {
- ngx_resolver_free_locked(r, rn->query);
- rn->query = NULL;
-#if (NGX_HAVE_INET6)
- rn->query6 = NULL;
-#endif
- }
-
- if (rn->cnlen) {
- ngx_resolver_free_locked(r, rn->u.cname);
- }
-
- if (rn->naddrs > 1 && rn->naddrs != (u_short) -1) {
- ngx_resolver_free_locked(r, rn->u.addrs);
- }
-
-#if (NGX_HAVE_INET6)
- if (rn->naddrs6 > 1 && rn->naddrs6 != (u_short) -1) {
- ngx_resolver_free_locked(r, rn->u6.addrs6);
- }
-#endif
-
- /* unlock alloc mutex */
-
- } else {
-
- rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t));
- if (rn == NULL) {
- return NGX_ERROR;
- }
-
- rn->name = ngx_resolver_dup(r, ctx->name.data, ctx->name.len);
- if (rn->name == NULL) {
- ngx_resolver_free(r, rn);
- return NGX_ERROR;
- }
-
- rn->node.key = hash;
- rn->nlen = (u_short) ctx->name.len;
- rn->query = NULL;
-#if (NGX_HAVE_INET6)
- rn->query6 = NULL;
-#endif
-
- ngx_rbtree_insert(&r->name_rbtree, &rn->node);
- }
-
- rc = ngx_resolver_create_name_query(rn, ctx);
-
- if (rc == NGX_ERROR) {
- goto failed;
- }
-
- if (rc == NGX_DECLINED) {
- ngx_rbtree_delete(&r->name_rbtree, &rn->node);
-
- ngx_resolver_free(r, rn->query);
- ngx_resolver_free(r, rn->name);
- ngx_resolver_free(r, rn);
-
- ctx->state = NGX_RESOLVE_NXDOMAIN;
- ctx->handler(ctx);
-
- return NGX_OK;
- }
-
- rn->naddrs = (u_short) -1;
-#if (NGX_HAVE_INET6)
- rn->naddrs6 = r->ipv6 ? (u_short) -1 : 0;
-#endif
-
- if (ngx_resolver_send_query(r, rn) != NGX_OK) {
- goto failed;
- }
-
- if (ctx->event == NULL) {
- ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
- if (ctx->event == NULL) {
- goto failed;
- }
-
- ctx->event->handler = ngx_resolver_timeout_handler;
- ctx->event->data = ctx;
- ctx->event->log = r->log;
- ctx->ident = -1;
-
- ngx_add_timer(ctx->event, ctx->timeout);
- }
-
- if (ngx_queue_empty(&r->name_resend_queue)) {
- ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000));
- }
-
- rn->expire = ngx_time() + r->resend_timeout;
-
- ngx_queue_insert_head(&r->name_resend_queue, &rn->queue);
-
- rn->code = 0;
- rn->cnlen = 0;
- rn->valid = 0;
- rn->ttl = NGX_MAX_UINT32_VALUE;
- rn->waiting = ctx;
-
- ctx->state = NGX_AGAIN;
-
- return NGX_AGAIN;
-
-failed:
-
- ngx_rbtree_delete(&r->name_rbtree, &rn->node);
-
- if (rn->query) {
- ngx_resolver_free(r, rn->query);
- }
-
- ngx_resolver_free(r, rn->name);
-
- ngx_resolver_free(r, rn);
-
- return NGX_ERROR;
-}
-
-
-ngx_int_t
-ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
-{
- u_char *name;
- in_addr_t addr;
- ngx_queue_t *resend_queue, *expire_queue;
- ngx_rbtree_t *tree;
- ngx_resolver_t *r;
- struct sockaddr_in *sin;
- ngx_resolver_node_t *rn;
-#if (NGX_HAVE_INET6)
- uint32_t hash;
- struct sockaddr_in6 *sin6;
-#endif
-
-#if (NGX_SUPPRESS_WARN)
- addr = 0;
-#if (NGX_HAVE_INET6)
- hash = 0;
- sin6 = NULL;
-#endif
-#endif
-
- r = ctx->resolver;
-
- switch (ctx->addr.sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) ctx->addr.sockaddr;
- hash = ngx_crc32_short(sin6->sin6_addr.s6_addr, 16);
-
- /* lock addr mutex */
-
- rn = ngx_resolver_lookup_addr6(r, &sin6->sin6_addr, hash);
-
- tree = &r->addr6_rbtree;
- resend_queue = &r->addr6_resend_queue;
- expire_queue = &r->addr6_expire_queue;
-
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) ctx->addr.sockaddr;
- addr = ntohl(sin->sin_addr.s_addr);
-
- /* lock addr mutex */
-
- rn = ngx_resolver_lookup_addr(r, addr);
-
- tree = &r->addr_rbtree;
- resend_queue = &r->addr_resend_queue;
- expire_queue = &r->addr_expire_queue;
- }
-
- if (rn) {
-
- if (rn->valid >= ngx_time()) {
-
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolve cached");
-
- ngx_queue_remove(&rn->queue);
-
- rn->expire = ngx_time() + r->expire;
-
- ngx_queue_insert_head(expire_queue, &rn->queue);
-
- name = ngx_resolver_dup(r, rn->name, rn->nlen);
- if (name == NULL) {
- goto failed;
- }
-
- ctx->name.len = rn->nlen;
- ctx->name.data = name;
-
- /* unlock addr mutex */
-
- ctx->state = NGX_OK;
-
- ctx->handler(ctx);
-
- ngx_resolver_free(r, name);
-
- return NGX_OK;
- }
-
- if (rn->waiting) {
-
- ctx->next = rn->waiting;
- rn->waiting = ctx;
- ctx->state = NGX_AGAIN;
-
- /* unlock addr mutex */
-
- return NGX_OK;
- }
-
- ngx_queue_remove(&rn->queue);
-
- ngx_resolver_free(r, rn->query);
- rn->query = NULL;
-#if (NGX_HAVE_INET6)
- rn->query6 = NULL;
-#endif
-
- } else {
- rn = ngx_resolver_alloc(r, sizeof(ngx_resolver_node_t));
- if (rn == NULL) {
- goto failed;
- }
-
- switch (ctx->addr.sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- rn->addr6 = sin6->sin6_addr;
- rn->node.key = hash;
- break;
-#endif
-
- default: /* AF_INET */
- rn->node.key = addr;
- }
-
- rn->query = NULL;
-#if (NGX_HAVE_INET6)
- rn->query6 = NULL;
-#endif
-
- ngx_rbtree_insert(tree, &rn->node);
- }
-
- if (ngx_resolver_create_addr_query(rn, ctx) != NGX_OK) {
- goto failed;
- }
-
- rn->naddrs = (u_short) -1;
-#if (NGX_HAVE_INET6)
- rn->naddrs6 = (u_short) -1;
-#endif
-
- if (ngx_resolver_send_query(r, rn) != NGX_OK) {
- goto failed;
- }
-
- ctx->event = ngx_resolver_calloc(r, sizeof(ngx_event_t));
- if (ctx->event == NULL) {
- goto failed;
- }
-
- ctx->event->handler = ngx_resolver_timeout_handler;
- ctx->event->data = ctx;
- ctx->event->log = r->log;
- ctx->ident = -1;
-
- ngx_add_timer(ctx->event, ctx->timeout);
-
- if (ngx_queue_empty(resend_queue)) {
- ngx_add_timer(r->event, (ngx_msec_t) (r->resend_timeout * 1000));
- }
-
- rn->expire = ngx_time() + r->resend_timeout;
-
- ngx_queue_insert_head(resend_queue, &rn->queue);
-
- rn->code = 0;
- rn->cnlen = 0;
- rn->name = NULL;
- rn->nlen = 0;
- rn->valid = 0;
- rn->ttl = NGX_MAX_UINT32_VALUE;
- rn->waiting = ctx;
-
- /* unlock addr mutex */
-
- ctx->state = NGX_AGAIN;
-
- return NGX_OK;
-
-failed:
-
- if (rn) {
- ngx_rbtree_delete(tree, &rn->node);
-
- if (rn->query) {
- ngx_resolver_free(r, rn->query);
- }
-
- ngx_resolver_free(r, rn);
- }
-
- /* unlock addr mutex */
-
- if (ctx->event) {
- ngx_resolver_free(r, ctx->event);
- }
-
- ngx_resolver_free(r, ctx);
-
- return NGX_ERROR;
-}
-
-
-void
-ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
-{
- in_addr_t addr;
- ngx_queue_t *expire_queue;
- ngx_rbtree_t *tree;
- ngx_resolver_t *r;
- ngx_resolver_ctx_t *w, **p;
- struct sockaddr_in *sin;
- ngx_resolver_node_t *rn;
-#if (NGX_HAVE_INET6)
- uint32_t hash;
- struct sockaddr_in6 *sin6;
-#endif
-
- r = ctx->resolver;
-
- switch (ctx->addr.sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- tree = &r->addr6_rbtree;
- expire_queue = &r->addr6_expire_queue;
- break;
-#endif
-
- default: /* AF_INET */
- tree = &r->addr_rbtree;
- expire_queue = &r->addr_expire_queue;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolve addr done: %i", ctx->state);
-
- if (ctx->event && ctx->event->timer_set) {
- ngx_del_timer(ctx->event);
- }
-
- /* lock addr mutex */
-
- if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
-
- switch (ctx->addr.sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) ctx->addr.sockaddr;
- hash = ngx_crc32_short(sin6->sin6_addr.s6_addr, 16);
- rn = ngx_resolver_lookup_addr6(r, &sin6->sin6_addr, hash);
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) ctx->addr.sockaddr;
- addr = ntohl(sin->sin_addr.s_addr);
- rn = ngx_resolver_lookup_addr(r, addr);
- }
-
- if (rn) {
- p = &rn->waiting;
- w = rn->waiting;
-
- while (w) {
- if (w == ctx) {
- *p = w->next;
-
- goto done;
- }
-
- p = &w->next;
- w = w->next;
- }
- }
-
- {
- u_char text[NGX_SOCKADDR_STRLEN];
- ngx_str_t addrtext;
-
- addrtext.data = text;
- addrtext.len = ngx_sock_ntop(ctx->addr.sockaddr, ctx->addr.socklen,
- text, NGX_SOCKADDR_STRLEN, 0);
-
- ngx_log_error(NGX_LOG_ALERT, r->log, 0,
- "could not cancel %V resolving", &addrtext);
- }
- }
-
-done:
-
- ngx_resolver_expire(r, tree, expire_queue);
-
- /* unlock addr mutex */
-
- /* lock alloc mutex */
-
- if (ctx->event) {
- ngx_resolver_free_locked(r, ctx->event);
- }
-
- ngx_resolver_free_locked(r, ctx);
-
- /* unlock alloc mutex */
-}
-
-
-static void
-ngx_resolver_expire(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue)
-{
- time_t now;
- ngx_uint_t i;
- ngx_queue_t *q;
- ngx_resolver_node_t *rn;
-
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver expire");
-
- now = ngx_time();
-
- for (i = 0; i < 2; i++) {
- if (ngx_queue_empty(queue)) {
- return;
- }
-
- q = ngx_queue_last(queue);
-
- rn = ngx_queue_data(q, ngx_resolver_node_t, queue);
-
- if (now <= rn->expire) {
- return;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver expire \"%*s\"", (size_t) rn->nlen, rn->name);
-
- ngx_queue_remove(q);
-
- ngx_rbtree_delete(tree, &rn->node);
-
- ngx_resolver_free_node(r, rn);
- }
-}
-
-
-static ngx_int_t
-ngx_resolver_send_query(ngx_resolver_t *r, ngx_resolver_node_t *rn)
-{
- ssize_t n;
- ngx_udp_connection_t *uc;
-
- uc = r->udp_connections.elts;
-
- uc = &uc[r->last_connection++];
- if (r->last_connection == r->udp_connections.nelts) {
- r->last_connection = 0;
- }
-
- if (uc->connection == NULL) {
-
- uc->log = *r->log;
- uc->log.handler = ngx_resolver_log_error;
- uc->log.data = uc;
- uc->log.action = "resolving";
-
- if (ngx_udp_connect(uc) != NGX_OK) {
- return NGX_ERROR;
- }
-
- uc->connection->data = r;
- uc->connection->read->handler = ngx_resolver_read_response;
- uc->connection->read->resolver = 1;
- }
-
- if (rn->naddrs == (u_short) -1) {
- n = ngx_send(uc->connection, rn->query, rn->qlen);
-
- if (n == -1) {
- return NGX_ERROR;
- }
-
- if ((size_t) n != (size_t) rn->qlen) {
- ngx_log_error(NGX_LOG_CRIT, &uc->log, 0, "send() incomplete");
- return NGX_ERROR;
- }
- }
-
-#if (NGX_HAVE_INET6)
- if (rn->query6 && rn->naddrs6 == (u_short) -1) {
- n = ngx_send(uc->connection, rn->query6, rn->qlen);
-
- if (n == -1) {
- return NGX_ERROR;
- }
-
- if ((size_t) n != (size_t) rn->qlen) {
- ngx_log_error(NGX_LOG_CRIT, &uc->log, 0, "send() incomplete");
- return NGX_ERROR;
- }
- }
-#endif
-
- return NGX_OK;
-}
-
-
-static void
-ngx_resolver_resend_handler(ngx_event_t *ev)
-{
- time_t timer, atimer, ntimer;
-#if (NGX_HAVE_INET6)
- time_t a6timer;
-#endif
- ngx_resolver_t *r;
-
- r = ev->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver resend handler");
-
- /* lock name mutex */
-
- ntimer = ngx_resolver_resend(r, &r->name_rbtree, &r->name_resend_queue);
-
- /* unlock name mutex */
-
- /* lock addr mutex */
-
- atimer = ngx_resolver_resend(r, &r->addr_rbtree, &r->addr_resend_queue);
-
- /* unlock addr mutex */
-
-#if (NGX_HAVE_INET6)
-
- /* lock addr6 mutex */
-
- a6timer = ngx_resolver_resend(r, &r->addr6_rbtree, &r->addr6_resend_queue);
-
- /* unlock addr6 mutex */
-
-#endif
-
- timer = ntimer;
-
- if (timer == 0) {
- timer = atimer;
-
- } else if (atimer) {
- timer = ngx_min(timer, atimer);
- }
-
-#if (NGX_HAVE_INET6)
-
- if (timer == 0) {
- timer = a6timer;
-
- } else if (a6timer) {
- timer = ngx_min(timer, a6timer);
- }
-
-#endif
-
- if (timer) {
- ngx_add_timer(r->event, (ngx_msec_t) (timer * 1000));
- }
-}
-
-
-static time_t
-ngx_resolver_resend(ngx_resolver_t *r, ngx_rbtree_t *tree, ngx_queue_t *queue)
-{
- time_t now;
- ngx_queue_t *q;
- ngx_resolver_node_t *rn;
-
- now = ngx_time();
-
- for ( ;; ) {
- if (ngx_queue_empty(queue)) {
- return 0;
- }
-
- q = ngx_queue_last(queue);
-
- rn = ngx_queue_data(q, ngx_resolver_node_t, queue);
-
- if (now < rn->expire) {
- return rn->expire - now;
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver resend \"%*s\" %p",
- (size_t) rn->nlen, rn->name, rn->waiting);
-
- ngx_queue_remove(q);
-
- if (rn->waiting) {
-
- (void) ngx_resolver_send_query(r, rn);
-
- rn->expire = now + r->resend_timeout;
-
- ngx_queue_insert_head(queue, q);
-
- continue;
- }
-
- ngx_rbtree_delete(tree, &rn->node);
-
- ngx_resolver_free_node(r, rn);
- }
-}
-
-
-static void
-ngx_resolver_read_response(ngx_event_t *rev)
-{
- ssize_t n;
- ngx_connection_t *c;
- u_char buf[NGX_RESOLVER_UDP_SIZE];
-
- c = rev->data;
-
- do {
- n = ngx_udp_recv(c, buf, NGX_RESOLVER_UDP_SIZE);
-
- if (n < 0) {
- return;
- }
-
- ngx_resolver_process_response(c->data, buf, n);
-
- } while (rev->ready);
-}
-
-
-static void
-ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
-{
- char *err;
- ngx_uint_t i, times, ident, qident, flags, code, nqs, nan,
- qtype, qclass;
-#if (NGX_HAVE_INET6)
- ngx_uint_t qident6;
-#endif
- ngx_queue_t *q;
- ngx_resolver_qs_t *qs;
- ngx_resolver_hdr_t *response;
- ngx_resolver_node_t *rn;
-
- if (n < sizeof(ngx_resolver_hdr_t)) {
- goto short_response;
- }
-
- response = (ngx_resolver_hdr_t *) buf;
-
- ident = (response->ident_hi << 8) + response->ident_lo;
- flags = (response->flags_hi << 8) + response->flags_lo;
- nqs = (response->nqs_hi << 8) + response->nqs_lo;
- nan = (response->nan_hi << 8) + response->nan_lo;
-
- ngx_log_debug6(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver DNS response %ui fl:%04Xui %ui/%ui/%ud/%ud",
- ident, flags, nqs, nan,
- (response->nns_hi << 8) + response->nns_lo,
- (response->nar_hi << 8) + response->nar_lo);
-
- /* response to a standard query */
- if ((flags & 0xf870) != 0x8000) {
- ngx_log_error(r->log_level, r->log, 0,
- "invalid DNS response %ui fl:%04Xui", ident, flags);
- return;
- }
-
- code = flags & 0xf;
-
- if (code == NGX_RESOLVE_FORMERR) {
-
- times = 0;
-
- for (q = ngx_queue_head(&r->name_resend_queue);
- q != ngx_queue_sentinel(&r->name_resend_queue) || times++ < 100;
- q = ngx_queue_next(q))
- {
- rn = ngx_queue_data(q, ngx_resolver_node_t, queue);
- qident = (rn->query[0] << 8) + rn->query[1];
-
- if (qident == ident) {
- goto dns_error_name;
- }
-
-#if (NGX_HAVE_INET6)
- if (rn->query6) {
- qident6 = (rn->query6[0] << 8) + rn->query6[1];
-
- if (qident6 == ident) {
- goto dns_error_name;
- }
- }
-#endif
- }
-
- goto dns_error;
- }
-
- if (code > NGX_RESOLVE_REFUSED) {
- goto dns_error;
- }
-
- if (nqs != 1) {
- err = "invalid number of questions in DNS response";
- goto done;
- }
-
- i = sizeof(ngx_resolver_hdr_t);
-
- while (i < (ngx_uint_t) n) {
- if (buf[i] == '\0') {
- goto found;
- }
-
- i += 1 + buf[i];
- }
-
- goto short_response;
-
-found:
-
- if (i++ == sizeof(ngx_resolver_hdr_t)) {
- err = "zero-length domain name in DNS response";
- goto done;
- }
-
- if (i + sizeof(ngx_resolver_qs_t) + nan * (2 + sizeof(ngx_resolver_an_t))
- > (ngx_uint_t) n)
- {
- goto short_response;
- }
-
- qs = (ngx_resolver_qs_t *) &buf[i];
-
- qtype = (qs->type_hi << 8) + qs->type_lo;
- qclass = (qs->class_hi << 8) + qs->class_lo;
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver DNS response qt:%ui cl:%ui", qtype, qclass);
-
- if (qclass != 1) {
- ngx_log_error(r->log_level, r->log, 0,
- "unknown query class %ui in DNS response", qclass);
- return;
- }
-
- switch (qtype) {
-
- case NGX_RESOLVE_A:
-#if (NGX_HAVE_INET6)
- case NGX_RESOLVE_AAAA:
-#endif
-
- ngx_resolver_process_a(r, buf, n, ident, code, qtype, nan,
- i + sizeof(ngx_resolver_qs_t));
-
- break;
-
- case NGX_RESOLVE_PTR:
-
- ngx_resolver_process_ptr(r, buf, n, ident, code, nan);
-
- break;
-
- default:
- ngx_log_error(r->log_level, r->log, 0,
- "unknown query type %ui in DNS response", qtype);
- return;
- }
-
- return;
-
-short_response:
-
- err = "short DNS response";
-
-done:
-
- ngx_log_error(r->log_level, r->log, 0, err);
-
- return;
-
-dns_error_name:
-
- ngx_log_error(r->log_level, r->log, 0,
- "DNS error (%ui: %s), query id:%ui, name:\"%*s\"",
- code, ngx_resolver_strerror(code), ident,
- rn->nlen, rn->name);
- return;
-
-dns_error:
-
- ngx_log_error(r->log_level, r->log, 0,
- "DNS error (%ui: %s), query id:%ui",
- code, ngx_resolver_strerror(code), ident);
- return;
-}
-
-
-static void
-ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
- ngx_uint_t ident, ngx_uint_t code, ngx_uint_t qtype,
- ngx_uint_t nan, ngx_uint_t ans)
-{
- char *err;
- u_char *cname;
- size_t len;
- int32_t ttl;
- uint32_t hash;
- in_addr_t *addr;
- ngx_str_t name;
- ngx_addr_t *addrs;
- ngx_uint_t type, class, qident, naddrs, a, i, n, start;
-#if (NGX_HAVE_INET6)
- struct in6_addr *addr6;
-#endif
- ngx_resolver_an_t *an;
- ngx_resolver_ctx_t *ctx, *next;
- ngx_resolver_node_t *rn;
-
- if (ngx_resolver_copy(r, &name, buf,
- buf + sizeof(ngx_resolver_hdr_t), buf + last)
- != NGX_OK)
- {
- return;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver qs:%V", &name);
-
- hash = ngx_crc32_short(name.data, name.len);
-
- /* lock name mutex */
-
- rn = ngx_resolver_lookup_name(r, &name, hash);
-
- if (rn == NULL) {
- ngx_log_error(r->log_level, r->log, 0,
- "unexpected response for %V", &name);
- ngx_resolver_free(r, name.data);
- goto failed;
- }
-
- switch (qtype) {
-
-#if (NGX_HAVE_INET6)
- case NGX_RESOLVE_AAAA:
-
- if (rn->query6 == NULL || rn->naddrs6 != (u_short) -1) {
- ngx_log_error(r->log_level, r->log, 0,
- "unexpected response for %V", &name);
- ngx_resolver_free(r, name.data);
- goto failed;
- }
-
- rn->naddrs6 = 0;
- qident = (rn->query6[0] << 8) + rn->query6[1];
-
- break;
-#endif
-
- default: /* NGX_RESOLVE_A */
-
- if (rn->query == NULL || rn->naddrs != (u_short) -1) {
- ngx_log_error(r->log_level, r->log, 0,
- "unexpected response for %V", &name);
- ngx_resolver_free(r, name.data);
- goto failed;
- }
-
- rn->naddrs = 0;
- qident = (rn->query[0] << 8) + rn->query[1];
- }
-
- if (ident != qident) {
- ngx_log_error(r->log_level, r->log, 0,
- "wrong ident %ui response for %V, expect %ui",
- ident, &name, qident);
- ngx_resolver_free(r, name.data);
- goto failed;
- }
-
- ngx_resolver_free(r, name.data);
-
- if (code == 0 && rn->code) {
- code = rn->code;
- }
-
- if (code == 0 && nan == 0) {
-
-#if (NGX_HAVE_INET6)
- switch (qtype) {
-
- case NGX_RESOLVE_AAAA:
-
- if (rn->naddrs == (u_short) -1) {
- goto next;
- }
-
- if (rn->naddrs) {
- goto export;
- }
-
- break;
-
- default: /* NGX_RESOLVE_A */
-
- if (rn->naddrs6 == (u_short) -1) {
- goto next;
- }
-
- if (rn->naddrs6) {
- goto export;
- }
- }
-#endif
-
- code = NGX_RESOLVE_NXDOMAIN;
- }
-
- if (code) {
-
-#if (NGX_HAVE_INET6)
- switch (qtype) {
-
- case NGX_RESOLVE_AAAA:
-
- if (rn->naddrs == (u_short) -1) {
- rn->code = (u_char) code;
- goto next;
- }
-
- break;
-
- default: /* NGX_RESOLVE_A */
-
- if (rn->naddrs6 == (u_short) -1) {
- rn->code = (u_char) code;
- goto next;
- }
- }
-#endif
-
- next = rn->waiting;
- rn->waiting = NULL;
-
- ngx_queue_remove(&rn->queue);
-
- ngx_rbtree_delete(&r->name_rbtree, &rn->node);
-
- ngx_resolver_free_node(r, rn);
-
- /* unlock name mutex */
-
- while (next) {
- ctx = next;
- ctx->state = code;
- next = ctx->next;
-
- ctx->handler(ctx);
- }
-
- return;
- }
-
- i = ans;
- naddrs = 0;
- cname = NULL;
-
- for (a = 0; a < nan; a++) {
-
- start = i;
-
- while (i < last) {
-
- if (buf[i] & 0xc0) {
- i += 2;
- goto found;
- }
-
- if (buf[i] == 0) {
- i++;
- goto test_length;
- }
-
- i += 1 + buf[i];
- }
-
- goto short_response;
-
- test_length:
-
- if (i - start < 2) {
- err = "invalid name in DNS response";
- goto invalid;
- }
-
- found:
-
- if (i + sizeof(ngx_resolver_an_t) >= last) {
- goto short_response;
- }
-
- an = (ngx_resolver_an_t *) &buf[i];
-
- type = (an->type_hi << 8) + an->type_lo;
- class = (an->class_hi << 8) + an->class_lo;
- len = (an->len_hi << 8) + an->len_lo;
- ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16)
- + (an->ttl[2] << 8) + (an->ttl[3]);
-
- if (class != 1) {
- ngx_log_error(r->log_level, r->log, 0,
- "unexpected RR class %ui", class);
- goto failed;
- }
-
- if (ttl < 0) {
- ttl = 0;
- }
-
- rn->ttl = ngx_min(rn->ttl, (uint32_t) ttl);
-
- i += sizeof(ngx_resolver_an_t);
-
- switch (type) {
-
- case NGX_RESOLVE_A:
-
- if (qtype != NGX_RESOLVE_A) {
- err = "unexpected A record in DNS response";
- goto invalid;
- }
-
- if (len != 4) {
- err = "invalid A record in DNS response";
- goto invalid;
- }
-
- if (i + 4 > last) {
- goto short_response;
- }
-
- naddrs++;
-
- break;
-
-#if (NGX_HAVE_INET6)
- case NGX_RESOLVE_AAAA:
-
- if (qtype != NGX_RESOLVE_AAAA) {
- err = "unexpected AAAA record in DNS response";
- goto invalid;
- }
-
- if (len != 16) {
- err = "invalid AAAA record in DNS response";
- goto invalid;
- }
-
- if (i + 16 > last) {
- goto short_response;
- }
-
- naddrs++;
-
- break;
-#endif
-
- case NGX_RESOLVE_CNAME:
-
- cname = &buf[i];
-
- break;
-
- case NGX_RESOLVE_DNAME:
-
- break;
-
- default:
-
- ngx_log_error(r->log_level, r->log, 0,
- "unexpected RR type %ui", type);
- }
-
- i += len;
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver naddrs:%ui cname:%p ttl:%uD",
- naddrs, cname, rn->ttl);
-
- if (naddrs) {
-
- switch (qtype) {
-
-#if (NGX_HAVE_INET6)
- case NGX_RESOLVE_AAAA:
-
- if (naddrs == 1) {
- addr6 = &rn->u6.addr6;
- rn->naddrs6 = 1;
-
- } else {
- addr6 = ngx_resolver_alloc(r, naddrs * sizeof(struct in6_addr));
- if (addr6 == NULL) {
- goto failed;
- }
-
- rn->u6.addrs6 = addr6;
- rn->naddrs6 = (u_short) naddrs;
- }
-
-#if (NGX_SUPPRESS_WARN)
- addr = NULL;
-#endif
-
- break;
-#endif
-
- default: /* NGX_RESOLVE_A */
-
- if (naddrs == 1) {
- addr = &rn->u.addr;
- rn->naddrs = 1;
-
- } else {
- addr = ngx_resolver_alloc(r, naddrs * sizeof(in_addr_t));
- if (addr == NULL) {
- goto failed;
- }
-
- rn->u.addrs = addr;
- rn->naddrs = (u_short) naddrs;
- }
-
-#if (NGX_HAVE_INET6 && NGX_SUPPRESS_WARN)
- addr6 = NULL;
-#endif
- }
-
- n = 0;
- i = ans;
-
- for (a = 0; a < nan; a++) {
-
- for ( ;; ) {
-
- if (buf[i] & 0xc0) {
- i += 2;
- break;
- }
-
- if (buf[i] == 0) {
- i++;
- break;
- }
-
- i += 1 + buf[i];
- }
-
- an = (ngx_resolver_an_t *) &buf[i];
-
- type = (an->type_hi << 8) + an->type_lo;
- len = (an->len_hi << 8) + an->len_lo;
-
- i += sizeof(ngx_resolver_an_t);
-
- if (type == NGX_RESOLVE_A) {
-
- addr[n] = htonl((buf[i] << 24) + (buf[i + 1] << 16)
- + (buf[i + 2] << 8) + (buf[i + 3]));
-
- if (++n == naddrs) {
-
-#if (NGX_HAVE_INET6)
- if (rn->naddrs6 == (u_short) -1) {
- goto next;
- }
-#endif
-
- break;
- }
- }
-
-#if (NGX_HAVE_INET6)
- else if (type == NGX_RESOLVE_AAAA) {
-
- ngx_memcpy(addr6[n].s6_addr, &buf[i], 16);
-
- if (++n == naddrs) {
-
- if (rn->naddrs == (u_short) -1) {
- goto next;
- }
-
- break;
- }
- }
-#endif
-
- i += len;
- }
- }
-
- if (rn->naddrs != (u_short) -1
-#if (NGX_HAVE_INET6)
- && rn->naddrs6 != (u_short) -1
-#endif
- && rn->naddrs
-#if (NGX_HAVE_INET6)
- + rn->naddrs6
-#endif
- > 0)
- {
-
-#if (NGX_HAVE_INET6)
- export:
-#endif
-
- naddrs = rn->naddrs;
-#if (NGX_HAVE_INET6)
- naddrs += rn->naddrs6;
-#endif
-
- if (naddrs == 1 && rn->naddrs == 1) {
- addrs = NULL;
-
- } else {
- addrs = ngx_resolver_export(r, rn, 0);
- if (addrs == NULL) {
- goto failed;
- }
- }
-
- ngx_queue_remove(&rn->queue);
-
- rn->valid = ngx_time() + (r->valid ? r->valid : (time_t) rn->ttl);
- rn->expire = ngx_time() + r->expire;
-
- ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
-
- next = rn->waiting;
- rn->waiting = NULL;
-
- /* unlock name mutex */
-
- while (next) {
- ctx = next;
- ctx->state = NGX_OK;
- ctx->naddrs = naddrs;
-
- if (addrs == NULL) {
- ctx->addrs = &ctx->addr;
- ctx->addr.sockaddr = (struct sockaddr *) &ctx->sin;
- ctx->addr.socklen = sizeof(struct sockaddr_in);
- ngx_memzero(&ctx->sin, sizeof(struct sockaddr_in));
- ctx->sin.sin_family = AF_INET;
- ctx->sin.sin_addr.s_addr = rn->u.addr;
-
- } else {
- ctx->addrs = addrs;
- }
-
- next = ctx->next;
-
- ctx->handler(ctx);
- }
-
- if (addrs != NULL) {
- ngx_resolver_free(r, addrs->sockaddr);
- ngx_resolver_free(r, addrs);
- }
-
- ngx_resolver_free(r, rn->query);
- rn->query = NULL;
-#if (NGX_HAVE_INET6)
- rn->query6 = NULL;
-#endif
-
- return;
- }
-
- if (cname) {
-
- /* CNAME only */
-
- if (rn->naddrs == (u_short) -1
-#if (NGX_HAVE_INET6)
- || rn->naddrs6 == (u_short) -1
-#endif
- )
- {
- goto next;
- }
-
- if (ngx_resolver_copy(r, &name, buf, cname, buf + last) != NGX_OK) {
- goto failed;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver cname:\"%V\"", &name);
-
- ngx_queue_remove(&rn->queue);
-
- rn->cnlen = (u_short) name.len;
- rn->u.cname = name.data;
-
- rn->valid = ngx_time() + (r->valid ? r->valid : (time_t) rn->ttl);
- rn->expire = ngx_time() + r->expire;
-
- ngx_queue_insert_head(&r->name_expire_queue, &rn->queue);
-
- ctx = rn->waiting;
- rn->waiting = NULL;
-
- if (ctx) {
- ctx->name = name;
-
- (void) ngx_resolve_name_locked(r, ctx);
- }
-
- ngx_resolver_free(r, rn->query);
- rn->query = NULL;
-#if (NGX_HAVE_INET6)
- rn->query6 = NULL;
-#endif
-
- /* unlock name mutex */
-
- return;
- }
-
- ngx_log_error(r->log_level, r->log, 0,
- "no A or CNAME types in DNS response");
- return;
-
-short_response:
-
- err = "short DNS response";
-
-invalid:
-
- /* unlock name mutex */
-
- ngx_log_error(r->log_level, r->log, 0, err);
-
- return;
-
-failed:
-
-next:
-
- /* unlock name mutex */
-
- return;
-}
-
-
-static void
-ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n,
- ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan)
-{
- char *err;
- size_t len;
- u_char text[NGX_SOCKADDR_STRLEN];
- in_addr_t addr;
- int32_t ttl;
- ngx_int_t octet;
- ngx_str_t name;
- ngx_uint_t i, mask, qident, class;
- ngx_queue_t *expire_queue;
- ngx_rbtree_t *tree;
- ngx_resolver_an_t *an;
- ngx_resolver_ctx_t *ctx, *next;
- ngx_resolver_node_t *rn;
-#if (NGX_HAVE_INET6)
- uint32_t hash;
- ngx_int_t digit;
- struct in6_addr addr6;
-#endif
-
- if (ngx_resolver_copy(r, NULL, buf,
- buf + sizeof(ngx_resolver_hdr_t), buf + n)
- != NGX_OK)
- {
- return;
- }
-
- /* AF_INET */
-
- addr = 0;
- i = sizeof(ngx_resolver_hdr_t);
-
- for (mask = 0; mask < 32; mask += 8) {
- len = buf[i++];
-
- octet = ngx_atoi(&buf[i], len);
- if (octet == NGX_ERROR || octet > 255) {
- goto invalid_in_addr_arpa;
- }
-
- addr += octet << mask;
- i += len;
- }
-
- if (ngx_strcasecmp(&buf[i], (u_char *) "\7in-addr\4arpa") == 0) {
- i += sizeof("\7in-addr\4arpa");
-
- /* lock addr mutex */
-
- rn = ngx_resolver_lookup_addr(r, addr);
-
- tree = &r->addr_rbtree;
- expire_queue = &r->addr_expire_queue;
-
- addr = htonl(addr);
- name.len = ngx_inet_ntop(AF_INET, &addr, text, NGX_SOCKADDR_STRLEN);
- name.data = text;
-
- goto valid;
- }
-
-invalid_in_addr_arpa:
-
-#if (NGX_HAVE_INET6)
-
- i = sizeof(ngx_resolver_hdr_t);
-
- for (octet = 15; octet >= 0; octet--) {
- if (buf[i++] != '\1') {
- goto invalid_ip6_arpa;
- }
-
- digit = ngx_hextoi(&buf[i++], 1);
- if (digit == NGX_ERROR) {
- goto invalid_ip6_arpa;
- }
-
- addr6.s6_addr[octet] = (u_char) digit;
-
- if (buf[i++] != '\1') {
- goto invalid_ip6_arpa;
- }
-
- digit = ngx_hextoi(&buf[i++], 1);
- if (digit == NGX_ERROR) {
- goto invalid_ip6_arpa;
- }
-
- addr6.s6_addr[octet] += (u_char) (digit * 16);
- }
-
- if (ngx_strcasecmp(&buf[i], (u_char *) "\3ip6\4arpa") == 0) {
- i += sizeof("\3ip6\4arpa");
-
- /* lock addr mutex */
-
- hash = ngx_crc32_short(addr6.s6_addr, 16);
- rn = ngx_resolver_lookup_addr6(r, &addr6, hash);
-
- tree = &r->addr6_rbtree;
- expire_queue = &r->addr6_expire_queue;
-
- name.len = ngx_inet6_ntop(addr6.s6_addr, text, NGX_SOCKADDR_STRLEN);
- name.data = text;
-
- goto valid;
- }
-
-invalid_ip6_arpa:
-#endif
-
- ngx_log_error(r->log_level, r->log, 0,
- "invalid in-addr.arpa or ip6.arpa name in DNS response");
- return;
-
-valid:
-
- if (rn == NULL || rn->query == NULL) {
- ngx_log_error(r->log_level, r->log, 0,
- "unexpected response for %V", &name);
- goto failed;
- }
-
- qident = (rn->query[0] << 8) + rn->query[1];
-
- if (ident != qident) {
- ngx_log_error(r->log_level, r->log, 0,
- "wrong ident %ui response for %V, expect %ui",
- ident, &name, qident);
- goto failed;
- }
-
- if (code == 0 && nan == 0) {
- code = NGX_RESOLVE_NXDOMAIN;
- }
-
- if (code) {
- next = rn->waiting;
- rn->waiting = NULL;
-
- ngx_queue_remove(&rn->queue);
-
- ngx_rbtree_delete(tree, &rn->node);
-
- ngx_resolver_free_node(r, rn);
-
- /* unlock addr mutex */
-
- while (next) {
- ctx = next;
- ctx->state = code;
- next = ctx->next;
-
- ctx->handler(ctx);
- }
-
- return;
- }
-
- i += sizeof(ngx_resolver_qs_t);
-
- if (i + 2 + sizeof(ngx_resolver_an_t) >= n) {
- goto short_response;
- }
-
- /* compression pointer to *.arpa */
-
- if (buf[i] != 0xc0 || buf[i + 1] != sizeof(ngx_resolver_hdr_t)) {
- err = "invalid in-addr.arpa or ip6.arpa name in DNS response";
- goto invalid;
- }
-
- an = (ngx_resolver_an_t *) &buf[i + 2];
-
- class = (an->class_hi << 8) + an->class_lo;
- len = (an->len_hi << 8) + an->len_lo;
- ttl = (an->ttl[0] << 24) + (an->ttl[1] << 16)
- + (an->ttl[2] << 8) + (an->ttl[3]);
-
- if (class != 1) {
- ngx_log_error(r->log_level, r->log, 0,
- "unexpected RR class %ui", class);
- goto failed;
- }
-
- if (ttl < 0) {
- ttl = 0;
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_CORE, r->log, 0,
- "resolver qt:%ui cl:%ui len:%uz",
- (an->type_hi << 8) + an->type_lo,
- class, len);
-
- i += 2 + sizeof(ngx_resolver_an_t);
-
- if (i + len > n) {
- goto short_response;
- }
-
- if (ngx_resolver_copy(r, &name, buf, buf + i, buf + n) != NGX_OK) {
- goto failed;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver an:%V", &name);
-
- if (name.len != (size_t) rn->nlen
- || ngx_strncmp(name.data, rn->name, name.len) != 0)
- {
- if (rn->nlen) {
- ngx_resolver_free(r, rn->name);
- }
-
- rn->nlen = (u_short) name.len;
- rn->name = name.data;
-
- name.data = ngx_resolver_dup(r, rn->name, name.len);
- if (name.data == NULL) {
- goto failed;
- }
- }
-
- ngx_queue_remove(&rn->queue);
-
- rn->valid = ngx_time() + (r->valid ? r->valid : ttl);
- rn->expire = ngx_time() + r->expire;
-
- ngx_queue_insert_head(expire_queue, &rn->queue);
-
- next = rn->waiting;
- rn->waiting = NULL;
-
- /* unlock addr mutex */
-
- while (next) {
- ctx = next;
- ctx->state = NGX_OK;
- ctx->name = name;
- next = ctx->next;
-
- ctx->handler(ctx);
- }
-
- ngx_resolver_free(r, name.data);
-
- return;
-
-short_response:
-
- err = "short DNS response";
-
-invalid:
-
- /* unlock addr mutex */
-
- ngx_log_error(r->log_level, r->log, 0, err);
-
- return;
-
-failed:
-
- /* unlock addr mutex */
-
- return;
-}
-
-
-static ngx_resolver_node_t *
-ngx_resolver_lookup_name(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash)
-{
- ngx_int_t rc;
- ngx_rbtree_node_t *node, *sentinel;
- ngx_resolver_node_t *rn;
-
- node = r->name_rbtree.root;
- sentinel = r->name_rbtree.sentinel;
-
- while (node != sentinel) {
-
- if (hash < node->key) {
- node = node->left;
- continue;
- }
-
- if (hash > node->key) {
- node = node->right;
- continue;
- }
-
- /* hash == node->key */
-
- rn = (ngx_resolver_node_t *) node;
-
- rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen);
-
- if (rc == 0) {
- return rn;
- }
-
- node = (rc < 0) ? node->left : node->right;
- }
-
- /* not found */
-
- return NULL;
-}
-
-
-static ngx_resolver_node_t *
-ngx_resolver_lookup_addr(ngx_resolver_t *r, in_addr_t addr)
-{
- ngx_rbtree_node_t *node, *sentinel;
-
- node = r->addr_rbtree.root;
- sentinel = r->addr_rbtree.sentinel;
-
- while (node != sentinel) {
-
- if (addr < node->key) {
- node = node->left;
- continue;
- }
-
- if (addr > node->key) {
- node = node->right;
- continue;
- }
-
- /* addr == node->key */
-
- return (ngx_resolver_node_t *) node;
- }
-
- /* not found */
-
- return NULL;
-}
-
-
-#if (NGX_HAVE_INET6)
-
-static ngx_resolver_node_t *
-ngx_resolver_lookup_addr6(ngx_resolver_t *r, struct in6_addr *addr,
- uint32_t hash)
-{
- ngx_int_t rc;
- ngx_rbtree_node_t *node, *sentinel;
- ngx_resolver_node_t *rn;
-
- node = r->addr6_rbtree.root;
- sentinel = r->addr6_rbtree.sentinel;
-
- while (node != sentinel) {
-
- if (hash < node->key) {
- node = node->left;
- continue;
- }
-
- if (hash > node->key) {
- node = node->right;
- continue;
- }
-
- /* hash == node->key */
-
- rn = (ngx_resolver_node_t *) node;
-
- rc = ngx_memcmp(addr, &rn->addr6, 16);
-
- if (rc == 0) {
- return rn;
- }
-
- node = (rc < 0) ? node->left : node->right;
- }
-
- /* not found */
-
- return NULL;
-}
-
-#endif
-
-
-static void
-ngx_resolver_rbtree_insert_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
-{
- ngx_rbtree_node_t **p;
- ngx_resolver_node_t *rn, *rn_temp;
-
- for ( ;; ) {
-
- if (node->key < temp->key) {
-
- p = &temp->left;
-
- } else if (node->key > temp->key) {
-
- p = &temp->right;
-
- } else { /* node->key == temp->key */
-
- rn = (ngx_resolver_node_t *) node;
- rn_temp = (ngx_resolver_node_t *) temp;
-
- p = (ngx_memn2cmp(rn->name, rn_temp->name, rn->nlen, rn_temp->nlen)
- < 0) ? &temp->left : &temp->right;
- }
-
- if (*p == sentinel) {
- break;
- }
-
- temp = *p;
- }
-
- *p = node;
- node->parent = temp;
- node->left = sentinel;
- node->right = sentinel;
- ngx_rbt_red(node);
-}
-
-
-#if (NGX_HAVE_INET6)
-
-static void
-ngx_resolver_rbtree_insert_addr6_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
-{
- ngx_rbtree_node_t **p;
- ngx_resolver_node_t *rn, *rn_temp;
-
- for ( ;; ) {
-
- if (node->key < temp->key) {
-
- p = &temp->left;
-
- } else if (node->key > temp->key) {
-
- p = &temp->right;
-
- } else { /* node->key == temp->key */
-
- rn = (ngx_resolver_node_t *) node;
- rn_temp = (ngx_resolver_node_t *) temp;
-
- p = (ngx_memcmp(&rn->addr6, &rn_temp->addr6, 16)
- < 0) ? &temp->left : &temp->right;
- }
-
- if (*p == sentinel) {
- break;
- }
-
- temp = *p;
- }
-
- *p = node;
- node->parent = temp;
- node->left = sentinel;
- node->right = sentinel;
- ngx_rbt_red(node);
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
-{
- u_char *p, *s;
- size_t len, nlen;
- ngx_uint_t ident;
-#if (NGX_HAVE_INET6)
- ngx_resolver_t *r;
-#endif
- ngx_resolver_qs_t *qs;
- ngx_resolver_hdr_t *query;
-
- nlen = ctx->name.len ? (1 + ctx->name.len + 1) : 1;
-
- len = sizeof(ngx_resolver_hdr_t) + nlen + sizeof(ngx_resolver_qs_t);
-
-#if (NGX_HAVE_INET6)
- r = ctx->resolver;
-
- p = ngx_resolver_alloc(ctx->resolver, r->ipv6 ? len * 2 : len);
-#else
- p = ngx_resolver_alloc(ctx->resolver, len);
-#endif
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- rn->qlen = (u_short) len;
- rn->query = p;
-
-#if (NGX_HAVE_INET6)
- if (r->ipv6) {
- rn->query6 = p + len;
- }
-#endif
-
- query = (ngx_resolver_hdr_t *) p;
-
- ident = ngx_random();
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0,
- "resolve: \"%V\" A %i", &ctx->name, ident & 0xffff);
-
- query->ident_hi = (u_char) ((ident >> 8) & 0xff);
- query->ident_lo = (u_char) (ident & 0xff);
-
- /* recursion query */
- query->flags_hi = 1; query->flags_lo = 0;
-
- /* one question */
- query->nqs_hi = 0; query->nqs_lo = 1;
- query->nan_hi = 0; query->nan_lo = 0;
- query->nns_hi = 0; query->nns_lo = 0;
- query->nar_hi = 0; query->nar_lo = 0;
-
- p += sizeof(ngx_resolver_hdr_t) + nlen;
-
- qs = (ngx_resolver_qs_t *) p;
-
- /* query type */
- qs->type_hi = 0; qs->type_lo = NGX_RESOLVE_A;
-
- /* IN query class */
- qs->class_hi = 0; qs->class_lo = 1;
-
- /* convert "www.example.com" to "\3www\7example\3com\0" */
-
- len = 0;
- p--;
- *p-- = '\0';
-
- if (ctx->name.len == 0) {
- return NGX_DECLINED;
- }
-
- for (s = ctx->name.data + ctx->name.len - 1; s >= ctx->name.data; s--) {
- if (*s != '.') {
- *p = *s;
- len++;
-
- } else {
- if (len == 0 || len > 255) {
- return NGX_DECLINED;
- }
-
- *p = (u_char) len;
- len = 0;
- }
-
- p--;
- }
-
- if (len == 0 || len > 255) {
- return NGX_DECLINED;
- }
-
- *p = (u_char) len;
-
-#if (NGX_HAVE_INET6)
- if (!r->ipv6) {
- return NGX_OK;
- }
-
- p = rn->query6;
-
- ngx_memcpy(p, rn->query, rn->qlen);
-
- query = (ngx_resolver_hdr_t *) p;
-
- ident = ngx_random();
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->resolver->log, 0,
- "resolve: \"%V\" AAAA %i", &ctx->name, ident & 0xffff);
-
- query->ident_hi = (u_char) ((ident >> 8) & 0xff);
- query->ident_lo = (u_char) (ident & 0xff);
-
- p += sizeof(ngx_resolver_hdr_t) + nlen;
-
- qs = (ngx_resolver_qs_t *) p;
-
- qs->type_lo = NGX_RESOLVE_AAAA;
-#endif
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_resolver_create_addr_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
-{
- u_char *p, *d;
- size_t len;
- in_addr_t addr;
- ngx_int_t n;
- ngx_uint_t ident;
- ngx_resolver_hdr_t *query;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
-
- switch (ctx->addr.sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- len = sizeof(ngx_resolver_hdr_t)
- + 64 + sizeof(".ip6.arpa.") - 1
- + sizeof(ngx_resolver_qs_t);
-
- break;
-#endif
-
- default: /* AF_INET */
- len = sizeof(ngx_resolver_hdr_t)
- + sizeof(".255.255.255.255.in-addr.arpa.") - 1
- + sizeof(ngx_resolver_qs_t);
- }
-
- p = ngx_resolver_alloc(ctx->resolver, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- rn->query = p;
- query = (ngx_resolver_hdr_t *) p;
-
- ident = ngx_random();
-
- query->ident_hi = (u_char) ((ident >> 8) & 0xff);
- query->ident_lo = (u_char) (ident & 0xff);
-
- /* recursion query */
- query->flags_hi = 1; query->flags_lo = 0;
-
- /* one question */
- query->nqs_hi = 0; query->nqs_lo = 1;
- query->nan_hi = 0; query->nan_lo = 0;
- query->nns_hi = 0; query->nns_lo = 0;
- query->nar_hi = 0; query->nar_lo = 0;
-
- p += sizeof(ngx_resolver_hdr_t);
-
- switch (ctx->addr.sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) ctx->addr.sockaddr;
-
- for (n = 15; n >= 0; n--) {
- p = ngx_sprintf(p, "\1%xd\1%xd",
- sin6->sin6_addr.s6_addr[n] & 0xf,
- (sin6->sin6_addr.s6_addr[n] >> 4) & 0xf);
- }
-
- p = ngx_cpymem(p, "\3ip6\4arpa\0", 10);
-
- break;
-#endif
-
- default: /* AF_INET */
-
- sin = (struct sockaddr_in *) ctx->addr.sockaddr;
- addr = ntohl(sin->sin_addr.s_addr);
-
- for (n = 0; n < 32; n += 8) {
- d = ngx_sprintf(&p[1], "%ud", (addr >> n) & 0xff);
- *p = (u_char) (d - &p[1]);
- p = d;
- }
-
- p = ngx_cpymem(p, "\7in-addr\4arpa\0", 14);
- }
-
- /* query type "PTR", IN query class */
- p = ngx_cpymem(p, "\0\14\0\1", 4);
-
- rn->qlen = (u_short) (p - rn->query);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name, u_char *buf, u_char *src,
- u_char *last)
-{
- char *err;
- u_char *p, *dst;
- ssize_t len;
- ngx_uint_t i, n;
-
- p = src;
- len = -1;
-
- /*
- * compression pointers allow to create endless loop, so we set limit;
- * 128 pointers should be enough to store 255-byte name
- */
-
- for (i = 0; i < 128; i++) {
- n = *p++;
-
- if (n == 0) {
- goto done;
- }
-
- if (n & 0xc0) {
- n = ((n & 0x3f) << 8) + *p;
- p = &buf[n];
-
- } else {
- len += 1 + n;
- p = &p[n];
- }
-
- if (p >= last) {
- err = "name is out of response";
- goto invalid;
- }
- }
-
- err = "compression pointers loop";
-
-invalid:
-
- ngx_log_error(r->log_level, r->log, 0, err);
-
- return NGX_ERROR;
-
-done:
-
- if (name == NULL) {
- return NGX_OK;
- }
-
- if (len == -1) {
- name->len = 0;
- name->data = NULL;
- return NGX_OK;
- }
-
- dst = ngx_resolver_alloc(r, len);
- if (dst == NULL) {
- return NGX_ERROR;
- }
-
- name->data = dst;
-
- n = *src++;
-
- for ( ;; ) {
- if (n & 0xc0) {
- n = ((n & 0x3f) << 8) + *src;
- src = &buf[n];
-
- n = *src++;
-
- } else {
- ngx_strlow(dst, src, n);
- dst += n;
- src += n;
-
- n = *src++;
-
- if (n != 0) {
- *dst++ = '.';
- }
- }
-
- if (n == 0) {
- name->len = dst - name->data;
- return NGX_OK;
- }
- }
-}
-
-
-static void
-ngx_resolver_timeout_handler(ngx_event_t *ev)
-{
- ngx_resolver_ctx_t *ctx;
-
- ctx = ev->data;
-
- ctx->state = NGX_RESOLVE_TIMEDOUT;
-
- ctx->handler(ctx);
-}
-
-
-static void
-ngx_resolver_free_node(ngx_resolver_t *r, ngx_resolver_node_t *rn)
-{
- /* lock alloc mutex */
-
- if (rn->query) {
- ngx_resolver_free_locked(r, rn->query);
- }
-
- if (rn->name) {
- ngx_resolver_free_locked(r, rn->name);
- }
-
- if (rn->cnlen) {
- ngx_resolver_free_locked(r, rn->u.cname);
- }
-
- if (rn->naddrs > 1 && rn->naddrs != (u_short) -1) {
- ngx_resolver_free_locked(r, rn->u.addrs);
- }
-
-#if (NGX_HAVE_INET6)
- if (rn->naddrs6 > 1 && rn->naddrs6 != (u_short) -1) {
- ngx_resolver_free_locked(r, rn->u6.addrs6);
- }
-#endif
-
- ngx_resolver_free_locked(r, rn);
-
- /* unlock alloc mutex */
-}
-
-
-static void *
-ngx_resolver_alloc(ngx_resolver_t *r, size_t size)
-{
- u_char *p;
-
- /* lock alloc mutex */
-
- p = ngx_alloc(size, r->log);
-
- /* unlock alloc mutex */
-
- return p;
-}
-
-
-static void *
-ngx_resolver_calloc(ngx_resolver_t *r, size_t size)
-{
- u_char *p;
-
- p = ngx_resolver_alloc(r, size);
-
- if (p) {
- ngx_memzero(p, size);
- }
-
- return p;
-}
-
-
-static void
-ngx_resolver_free(ngx_resolver_t *r, void *p)
-{
- /* lock alloc mutex */
-
- ngx_free(p);
-
- /* unlock alloc mutex */
-}
-
-
-static void
-ngx_resolver_free_locked(ngx_resolver_t *r, void *p)
-{
- ngx_free(p);
-}
-
-
-static void *
-ngx_resolver_dup(ngx_resolver_t *r, void *src, size_t size)
-{
- void *dst;
-
- dst = ngx_resolver_alloc(r, size);
-
- if (dst == NULL) {
- return dst;
- }
-
- ngx_memcpy(dst, src, size);
-
- return dst;
-}
-
-
-static ngx_addr_t *
-ngx_resolver_export(ngx_resolver_t *r, ngx_resolver_node_t *rn,
- ngx_uint_t rotate)
-{
- ngx_addr_t *dst;
- ngx_uint_t d, i, j, n;
- u_char (*sockaddr)[NGX_SOCKADDRLEN];
- in_addr_t *addr;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct in6_addr *addr6;
- struct sockaddr_in6 *sin6;
-#endif
-
- n = rn->naddrs;
-#if (NGX_HAVE_INET6)
- n += rn->naddrs6;
-#endif
-
- dst = ngx_resolver_calloc(r, n * sizeof(ngx_addr_t));
- if (dst == NULL) {
- return NULL;
- }
-
- sockaddr = ngx_resolver_calloc(r, n * NGX_SOCKADDRLEN);
- if (sockaddr == NULL) {
- ngx_resolver_free(r, dst);
- return NULL;
- }
-
- i = 0;
- d = rotate ? ngx_random() % n : 0;
-
- if (rn->naddrs) {
- j = rotate ? ngx_random() % rn->naddrs : 0;
-
- addr = (rn->naddrs == 1) ? &rn->u.addr : rn->u.addrs;
-
- do {
- sin = (struct sockaddr_in *) sockaddr[d];
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = addr[j++];
- dst[d].sockaddr = (struct sockaddr *) sin;
- dst[d++].socklen = sizeof(struct sockaddr_in);
-
- if (d == n) {
- d = 0;
- }
-
- if (j == rn->naddrs) {
- j = 0;
- }
- } while (++i < rn->naddrs);
- }
-
-#if (NGX_HAVE_INET6)
- if (rn->naddrs6) {
- j = rotate ? ngx_random() % rn->naddrs6 : 0;
-
- addr6 = (rn->naddrs6 == 1) ? &rn->u6.addr6 : rn->u6.addrs6;
-
- do {
- sin6 = (struct sockaddr_in6 *) sockaddr[d];
- sin6->sin6_family = AF_INET6;
- ngx_memcpy(sin6->sin6_addr.s6_addr, addr6[j++].s6_addr, 16);
- dst[d].sockaddr = (struct sockaddr *) sin6;
- dst[d++].socklen = sizeof(struct sockaddr_in6);
-
- if (d == n) {
- d = 0;
- }
-
- if (j == rn->naddrs6) {
- j = 0;
- }
- } while (++i < n);
- }
-#endif
-
- return dst;
-}
-
-
-char *
-ngx_resolver_strerror(ngx_int_t err)
-{
- static char *errors[] = {
- "Format error", /* FORMERR */
- "Server failure", /* SERVFAIL */
- "Host not found", /* NXDOMAIN */
- "Unimplemented", /* NOTIMP */
- "Operation refused" /* REFUSED */
- };
-
- if (err > 0 && err < 6) {
- return errors[err - 1];
- }
-
- if (err == NGX_RESOLVE_TIMEDOUT) {
- return "Operation timed out";
- }
-
- return "Unknown error";
-}
-
-
-static u_char *
-ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len)
-{
- u_char *p;
- ngx_udp_connection_t *uc;
-
- p = buf;
-
- if (log->action) {
- p = ngx_snprintf(buf, len, " while %s", log->action);
- len -= p - buf;
- }
-
- uc = log->data;
-
- if (uc) {
- p = ngx_snprintf(p, len, ", resolver: %V", &uc->server);
- }
-
- return p;
-}
-
-
-ngx_int_t
-ngx_udp_connect(ngx_udp_connection_t *uc)
-{
- int rc;
- ngx_int_t event;
- ngx_event_t *rev, *wev;
- ngx_socket_t s;
- ngx_connection_t *c;
-
- s = ngx_socket(uc->sockaddr->sa_family, SOCK_DGRAM, 0);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &uc->log, 0, "UDP socket %d", s);
-
- if (s == (ngx_socket_t) -1) {
- ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno,
- ngx_socket_n " failed");
- return NGX_ERROR;
- }
-
- c = ngx_get_connection(s, &uc->log);
-
- if (c == NULL) {
- if (ngx_close_socket(s) == -1) {
- ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno,
- ngx_close_socket_n "failed");
- }
-
- return NGX_ERROR;
- }
-
- if (ngx_nonblocking(s) == -1) {
- ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno,
- ngx_nonblocking_n " failed");
-
- goto failed;
- }
-
- rev = c->read;
- wev = c->write;
-
- rev->log = &uc->log;
- wev->log = &uc->log;
-
- uc->connection = c;
-
- c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
-
-#if (NGX_THREADS)
-
- /* TODO: lock event when call completion handler */
-
- rev->lock = &c->lock;
- wev->lock = &c->lock;
- rev->own_lock = &c->lock;
- wev->own_lock = &c->lock;
-
-#endif
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, &uc->log, 0,
- "connect to %V, fd:%d #%uA", &uc->server, s, c->number);
-
- rc = connect(s, uc->sockaddr, uc->socklen);
-
- /* TODO: aio, iocp */
-
- if (rc == -1) {
- ngx_log_error(NGX_LOG_CRIT, &uc->log, ngx_socket_errno,
- "connect() failed");
-
- goto failed;
- }
-
- /* UDP sockets are always ready to write */
- wev->ready = 1;
-
- if (ngx_add_event) {
-
- event = (ngx_event_flags & NGX_USE_CLEAR_EVENT) ?
- /* kqueue, epoll */ NGX_CLEAR_EVENT:
- /* select, poll, /dev/poll */ NGX_LEVEL_EVENT;
- /* eventport event type has no meaning: oneshot only */
-
- if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
- goto failed;
- }
-
- } else {
- /* rtsig */
-
- if (ngx_add_conn(c) == NGX_ERROR) {
- goto failed;
- }
- }
-
- return NGX_OK;
-
-failed:
-
- ngx_close_connection(c);
- uc->connection = NULL;
-
- return NGX_ERROR;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_resolver.h b/usr.sbin/nginx/src/core/ngx_resolver.h
deleted file mode 100644
index 264c8c42b98..00000000000
--- a/usr.sbin/nginx/src/core/ngx_resolver.h
+++ /dev/null
@@ -1,178 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#ifndef _NGX_RESOLVER_H_INCLUDED_
-#define _NGX_RESOLVER_H_INCLUDED_
-
-
-#define NGX_RESOLVE_A 1
-#define NGX_RESOLVE_CNAME 5
-#define NGX_RESOLVE_PTR 12
-#define NGX_RESOLVE_MX 15
-#define NGX_RESOLVE_TXT 16
-#if (NGX_HAVE_INET6)
-#define NGX_RESOLVE_AAAA 28
-#endif
-#define NGX_RESOLVE_DNAME 39
-
-#define NGX_RESOLVE_FORMERR 1
-#define NGX_RESOLVE_SERVFAIL 2
-#define NGX_RESOLVE_NXDOMAIN 3
-#define NGX_RESOLVE_NOTIMP 4
-#define NGX_RESOLVE_REFUSED 5
-#define NGX_RESOLVE_TIMEDOUT NGX_ETIMEDOUT
-
-
-#define NGX_NO_RESOLVER (void *) -1
-
-#define NGX_RESOLVER_MAX_RECURSION 50
-
-
-typedef struct {
- ngx_connection_t *connection;
- struct sockaddr *sockaddr;
- socklen_t socklen;
- ngx_str_t server;
- ngx_log_t log;
-} ngx_udp_connection_t;
-
-
-typedef struct ngx_resolver_ctx_s ngx_resolver_ctx_t;
-
-typedef void (*ngx_resolver_handler_pt)(ngx_resolver_ctx_t *ctx);
-
-
-typedef struct {
- ngx_rbtree_node_t node;
- ngx_queue_t queue;
-
- /* PTR: resolved name, A: name to resolve */
- u_char *name;
-
-#if (NGX_HAVE_INET6)
- /* PTR: IPv6 address to resolve (IPv4 address is in rbtree node key) */
- struct in6_addr addr6;
-#endif
-
- u_short nlen;
- u_short qlen;
-
- u_char *query;
-#if (NGX_HAVE_INET6)
- u_char *query6;
-#endif
-
- union {
- in_addr_t addr;
- in_addr_t *addrs;
- u_char *cname;
- } u;
-
- u_char code;
- u_short naddrs;
- u_short cnlen;
-
-#if (NGX_HAVE_INET6)
- union {
- struct in6_addr addr6;
- struct in6_addr *addrs6;
- } u6;
-
- u_short naddrs6;
-#endif
-
- time_t expire;
- time_t valid;
- uint32_t ttl;
-
- ngx_resolver_ctx_t *waiting;
-} ngx_resolver_node_t;
-
-
-typedef struct {
- /* has to be pointer because of "incomplete type" */
- ngx_event_t *event;
- void *dummy;
- ngx_log_t *log;
-
- /* ident must be after 3 pointers */
- ngx_int_t ident;
-
- /* simple round robin DNS peers balancer */
- ngx_array_t udp_connections;
- ngx_uint_t last_connection;
-
- ngx_rbtree_t name_rbtree;
- ngx_rbtree_node_t name_sentinel;
-
- ngx_rbtree_t addr_rbtree;
- ngx_rbtree_node_t addr_sentinel;
-
- ngx_queue_t name_resend_queue;
- ngx_queue_t addr_resend_queue;
-
- ngx_queue_t name_expire_queue;
- ngx_queue_t addr_expire_queue;
-
-#if (NGX_HAVE_INET6)
- ngx_uint_t ipv6; /* unsigned ipv6:1; */
- ngx_rbtree_t addr6_rbtree;
- ngx_rbtree_node_t addr6_sentinel;
- ngx_queue_t addr6_resend_queue;
- ngx_queue_t addr6_expire_queue;
-#endif
-
- time_t resend_timeout;
- time_t expire;
- time_t valid;
-
- ngx_uint_t log_level;
-} ngx_resolver_t;
-
-
-struct ngx_resolver_ctx_s {
- ngx_resolver_ctx_t *next;
- ngx_resolver_t *resolver;
- ngx_udp_connection_t *udp_connection;
-
- /* ident must be after 3 pointers */
- ngx_int_t ident;
-
- ngx_int_t state;
- ngx_str_t name;
-
- ngx_uint_t naddrs;
- ngx_addr_t *addrs;
- ngx_addr_t addr;
- struct sockaddr_in sin;
-
- ngx_resolver_handler_pt handler;
- void *data;
- ngx_msec_t timeout;
-
- ngx_uint_t quick; /* unsigned quick:1; */
- ngx_uint_t recursion;
- ngx_event_t *event;
-};
-
-
-ngx_resolver_t *ngx_resolver_create(ngx_conf_t *cf, ngx_str_t *names,
- ngx_uint_t n);
-ngx_resolver_ctx_t *ngx_resolve_start(ngx_resolver_t *r,
- ngx_resolver_ctx_t *temp);
-ngx_int_t ngx_resolve_name(ngx_resolver_ctx_t *ctx);
-void ngx_resolve_name_done(ngx_resolver_ctx_t *ctx);
-ngx_int_t ngx_resolve_addr(ngx_resolver_ctx_t *ctx);
-void ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx);
-char *ngx_resolver_strerror(ngx_int_t err);
-
-
-#endif /* _NGX_RESOLVER_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_sha1.h b/usr.sbin/nginx/src/core/ngx_sha1.h
deleted file mode 100644
index 81c909e2f3d..00000000000
--- a/usr.sbin/nginx/src/core/ngx_sha1.h
+++ /dev/null
@@ -1,31 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#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_ */
diff --git a/usr.sbin/nginx/src/core/ngx_shmtx.c b/usr.sbin/nginx/src/core/ngx_shmtx.c
deleted file mode 100644
index a62999f3393..00000000000
--- a/usr.sbin/nginx/src/core/ngx_shmtx.c
+++ /dev/null
@@ -1,309 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#if (NGX_HAVE_ATOMIC_OPS)
-
-
-static void ngx_shmtx_wakeup(ngx_shmtx_t *mtx);
-
-
-ngx_int_t
-ngx_shmtx_create(ngx_shmtx_t *mtx, ngx_shmtx_sh_t *addr, u_char *name)
-{
- mtx->lock = &addr->lock;
-
- if (mtx->spin == (ngx_uint_t) -1) {
- return NGX_OK;
- }
-
- mtx->spin = 2048;
-
-#if (NGX_HAVE_POSIX_SEM)
-
- mtx->wait = &addr->wait;
-
- if (sem_init(&mtx->sem, 1, 0) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
- "sem_init() failed");
- } else {
- mtx->semaphore = 1;
- }
-
-#endif
-
- return NGX_OK;
-}
-
-
-void
-ngx_shmtx_destroy(ngx_shmtx_t *mtx)
-{
-#if (NGX_HAVE_POSIX_SEM)
-
- if (mtx->semaphore) {
- if (sem_destroy(&mtx->sem) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
- "sem_destroy() failed");
- }
- }
-
-#endif
-}
-
-
-ngx_uint_t
-ngx_shmtx_trylock(ngx_shmtx_t *mtx)
-{
- return (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid));
-}
-
-
-void
-ngx_shmtx_lock(ngx_shmtx_t *mtx)
-{
- ngx_uint_t i, n;
-
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "shmtx lock");
-
- for ( ;; ) {
-
- if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) {
- return;
- }
-
- if (ngx_ncpu > 1) {
-
- for (n = 1; n < mtx->spin; n <<= 1) {
-
- for (i = 0; i < n; i++) {
- ngx_cpu_pause();
- }
-
- if (*mtx->lock == 0
- && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid))
- {
- return;
- }
- }
- }
-
-#if (NGX_HAVE_POSIX_SEM)
-
- if (mtx->semaphore) {
- (void) ngx_atomic_fetch_add(mtx->wait, 1);
-
- if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) {
- return;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
- "shmtx wait %uA", *mtx->wait);
-
- while (sem_wait(&mtx->sem) == -1) {
- ngx_err_t err;
-
- err = ngx_errno;
-
- if (err != NGX_EINTR) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err,
- "sem_wait() failed while waiting on shmtx");
- break;
- }
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
- "shmtx awoke");
-
- continue;
- }
-
-#endif
-
- ngx_sched_yield();
- }
-}
-
-
-void
-ngx_shmtx_unlock(ngx_shmtx_t *mtx)
-{
- if (mtx->spin != (ngx_uint_t) -1) {
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "shmtx unlock");
- }
-
- if (ngx_atomic_cmp_set(mtx->lock, ngx_pid, 0)) {
- ngx_shmtx_wakeup(mtx);
- }
-}
-
-
-ngx_uint_t
-ngx_shmtx_force_unlock(ngx_shmtx_t *mtx, ngx_pid_t pid)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
- "shmtx forced unlock");
-
- if (ngx_atomic_cmp_set(mtx->lock, pid, 0)) {
- ngx_shmtx_wakeup(mtx);
- return 1;
- }
-
- return 0;
-}
-
-
-static void
-ngx_shmtx_wakeup(ngx_shmtx_t *mtx)
-{
-#if (NGX_HAVE_POSIX_SEM)
- ngx_atomic_uint_t wait;
-
- if (!mtx->semaphore) {
- return;
- }
-
- for ( ;; ) {
-
- wait = *mtx->wait;
-
- if (wait == 0) {
- return;
- }
-
- if (ngx_atomic_cmp_set(mtx->wait, wait, wait - 1)) {
- break;
- }
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
- "shmtx wake %uA", wait);
-
- if (sem_post(&mtx->sem) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
- "sem_post() failed while wake shmtx");
- }
-
-#endif
-}
-
-
-#else
-
-
-ngx_int_t
-ngx_shmtx_create(ngx_shmtx_t *mtx, ngx_shmtx_sh_t *addr, u_char *name)
-{
- if (mtx->name) {
-
- if (ngx_strcmp(name, mtx->name) == 0) {
- mtx->name = name;
- return NGX_OK;
- }
-
- ngx_shmtx_destroy(mtx);
- }
-
- mtx->fd = ngx_open_file(name, NGX_FILE_RDWR, NGX_FILE_CREATE_OR_OPEN,
- NGX_FILE_DEFAULT_ACCESS);
-
- if (mtx->fd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno,
- ngx_open_file_n " \"%s\" failed", name);
- return NGX_ERROR;
- }
-
- if (ngx_delete_file(name) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
- ngx_delete_file_n " \"%s\" failed", name);
- }
-
- mtx->name = name;
-
- return NGX_OK;
-}
-
-
-void
-ngx_shmtx_destroy(ngx_shmtx_t *mtx)
-{
- if (ngx_close_file(mtx->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", mtx->name);
- }
-}
-
-
-ngx_uint_t
-ngx_shmtx_trylock(ngx_shmtx_t *mtx)
-{
- ngx_err_t err;
-
- err = ngx_trylock_fd(mtx->fd);
-
- if (err == 0) {
- return 1;
- }
-
- if (err == NGX_EAGAIN) {
- return 0;
- }
-
-#if __osf__ /* Tru64 UNIX */
-
- if (err == NGX_EACCESS) {
- return 0;
- }
-
-#endif
-
- ngx_log_abort(err, ngx_trylock_fd_n " %s failed", mtx->name);
-
- return 0;
-}
-
-
-void
-ngx_shmtx_lock(ngx_shmtx_t *mtx)
-{
- ngx_err_t err;
-
- err = ngx_lock_fd(mtx->fd);
-
- if (err == 0) {
- return;
- }
-
- ngx_log_abort(err, ngx_lock_fd_n " %s failed", mtx->name);
-}
-
-
-void
-ngx_shmtx_unlock(ngx_shmtx_t *mtx)
-{
- ngx_err_t err;
-
- err = ngx_unlock_fd(mtx->fd);
-
- if (err == 0) {
- return;
- }
-
- ngx_log_abort(err, ngx_unlock_fd_n " %s failed", mtx->name);
-}
-
-
-ngx_uint_t
-ngx_shmtx_force_unlock(ngx_shmtx_t *mtx, ngx_pid_t pid)
-{
- return 0;
-}
-
-#endif
diff --git a/usr.sbin/nginx/src/core/ngx_shmtx.h b/usr.sbin/nginx/src/core/ngx_shmtx.h
deleted file mode 100644
index 91e11bebbf4..00000000000
--- a/usr.sbin/nginx/src/core/ngx_shmtx.h
+++ /dev/null
@@ -1,49 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_SHMTX_H_INCLUDED_
-#define _NGX_SHMTX_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef struct {
- ngx_atomic_t lock;
-#if (NGX_HAVE_POSIX_SEM)
- ngx_atomic_t wait;
-#endif
-} ngx_shmtx_sh_t;
-
-
-typedef struct {
-#if (NGX_HAVE_ATOMIC_OPS)
- ngx_atomic_t *lock;
-#if (NGX_HAVE_POSIX_SEM)
- ngx_atomic_t *wait;
- ngx_uint_t semaphore;
- sem_t sem;
-#endif
-#else
- ngx_fd_t fd;
- u_char *name;
-#endif
- ngx_uint_t spin;
-} ngx_shmtx_t;
-
-
-ngx_int_t ngx_shmtx_create(ngx_shmtx_t *mtx, ngx_shmtx_sh_t *addr,
- u_char *name);
-void ngx_shmtx_destroy(ngx_shmtx_t *mtx);
-ngx_uint_t ngx_shmtx_trylock(ngx_shmtx_t *mtx);
-void ngx_shmtx_lock(ngx_shmtx_t *mtx);
-void ngx_shmtx_unlock(ngx_shmtx_t *mtx);
-ngx_uint_t ngx_shmtx_force_unlock(ngx_shmtx_t *mtx, ngx_pid_t pid);
-
-
-#endif /* _NGX_SHMTX_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_slab.c b/usr.sbin/nginx/src/core/ngx_slab.c
deleted file mode 100644
index be7927ce067..00000000000
--- a/usr.sbin/nginx/src/core/ngx_slab.c
+++ /dev/null
@@ -1,702 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#define NGX_SLAB_PAGE_MASK 3
-#define NGX_SLAB_PAGE 0
-#define NGX_SLAB_BIG 1
-#define NGX_SLAB_EXACT 2
-#define NGX_SLAB_SMALL 3
-
-#if (NGX_PTR_SIZE == 4)
-
-#define NGX_SLAB_PAGE_FREE 0
-#define NGX_SLAB_PAGE_BUSY 0xffffffff
-#define NGX_SLAB_PAGE_START 0x80000000
-
-#define NGX_SLAB_SHIFT_MASK 0x0000000f
-#define NGX_SLAB_MAP_MASK 0xffff0000
-#define NGX_SLAB_MAP_SHIFT 16
-
-#define NGX_SLAB_BUSY 0xffffffff
-
-#else /* (NGX_PTR_SIZE == 8) */
-
-#define NGX_SLAB_PAGE_FREE 0
-#define NGX_SLAB_PAGE_BUSY 0xffffffffffffffff
-#define NGX_SLAB_PAGE_START 0x8000000000000000
-
-#define NGX_SLAB_SHIFT_MASK 0x000000000000000f
-#define NGX_SLAB_MAP_MASK 0xffffffff00000000
-#define NGX_SLAB_MAP_SHIFT 32
-
-#define NGX_SLAB_BUSY 0xffffffffffffffff
-
-#endif
-
-
-#if (NGX_DEBUG_MALLOC)
-
-#define ngx_slab_junk(p, size) ngx_memset(p, 0xA5, size)
-
-#elif (NGX_HAVE_DEBUG_MALLOC)
-
-#define ngx_slab_junk(p, size) \
- if (ngx_debug_malloc) ngx_memset(p, 0xA5, size)
-
-#else
-
-#define ngx_slab_junk(p, size)
-
-#endif
-
-static ngx_slab_page_t *ngx_slab_alloc_pages(ngx_slab_pool_t *pool,
- ngx_uint_t pages);
-static void ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
- ngx_uint_t pages);
-static void ngx_slab_error(ngx_slab_pool_t *pool, ngx_uint_t level,
- char *text);
-
-
-static ngx_uint_t ngx_slab_max_size;
-static ngx_uint_t ngx_slab_exact_size;
-static ngx_uint_t ngx_slab_exact_shift;
-
-
-void
-ngx_slab_init(ngx_slab_pool_t *pool)
-{
- u_char *p;
- size_t size;
- ngx_int_t m;
- ngx_uint_t i, n, pages;
- ngx_slab_page_t *slots;
-
- /* STUB */
- if (ngx_slab_max_size == 0) {
- ngx_slab_max_size = ngx_pagesize / 2;
- ngx_slab_exact_size = ngx_pagesize / (8 * sizeof(uintptr_t));
- for (n = ngx_slab_exact_size; n >>= 1; ngx_slab_exact_shift++) {
- /* void */
- }
- }
- /**/
-
- pool->min_size = 1 << pool->min_shift;
-
- p = (u_char *) pool + sizeof(ngx_slab_pool_t);
- size = pool->end - p;
-
- ngx_slab_junk(p, size);
-
- slots = (ngx_slab_page_t *) p;
- n = ngx_pagesize_shift - pool->min_shift;
-
- for (i = 0; i < n; i++) {
- slots[i].slab = 0;
- slots[i].next = &slots[i];
- slots[i].prev = 0;
- }
-
- p += n * sizeof(ngx_slab_page_t);
-
- pages = (ngx_uint_t) (size / (ngx_pagesize + sizeof(ngx_slab_page_t)));
-
- ngx_memzero(p, pages * sizeof(ngx_slab_page_t));
-
- pool->pages = (ngx_slab_page_t *) p;
-
- pool->free.prev = 0;
- pool->free.next = (ngx_slab_page_t *) p;
-
- pool->pages->slab = pages;
- pool->pages->next = &pool->free;
- pool->pages->prev = (uintptr_t) &pool->free;
-
- pool->start = (u_char *)
- ngx_align_ptr((uintptr_t) p + pages * sizeof(ngx_slab_page_t),
- ngx_pagesize);
-
- m = pages - (pool->end - pool->start) / ngx_pagesize;
- if (m > 0) {
- pages -= m;
- pool->pages->slab = pages;
- }
-
- pool->log_nomem = 1;
- pool->log_ctx = &pool->zero;
- pool->zero = '\0';
-}
-
-
-void *
-ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size)
-{
- void *p;
-
- ngx_shmtx_lock(&pool->mutex);
-
- p = ngx_slab_alloc_locked(pool, size);
-
- ngx_shmtx_unlock(&pool->mutex);
-
- return p;
-}
-
-
-void *
-ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size)
-{
- size_t s;
- uintptr_t p, n, m, mask, *bitmap;
- ngx_uint_t i, slot, shift, map;
- ngx_slab_page_t *page, *prev, *slots;
-
- if (size >= ngx_slab_max_size) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
- "slab alloc: %uz", size);
-
- page = ngx_slab_alloc_pages(pool, (size >> ngx_pagesize_shift)
- + ((size % ngx_pagesize) ? 1 : 0));
- if (page) {
- p = (page - pool->pages) << ngx_pagesize_shift;
- p += (uintptr_t) pool->start;
-
- } else {
- p = 0;
- }
-
- goto done;
- }
-
- if (size > pool->min_size) {
- shift = 1;
- for (s = size - 1; s >>= 1; shift++) { /* void */ }
- slot = shift - pool->min_shift;
-
- } else {
- size = pool->min_size;
- shift = pool->min_shift;
- slot = 0;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0,
- "slab alloc: %uz slot: %ui", size, slot);
-
- slots = (ngx_slab_page_t *) ((u_char *) pool + sizeof(ngx_slab_pool_t));
- page = slots[slot].next;
-
- if (page->next != page) {
-
- if (shift < ngx_slab_exact_shift) {
-
- do {
- p = (page - pool->pages) << ngx_pagesize_shift;
- bitmap = (uintptr_t *) (pool->start + p);
-
- map = (1 << (ngx_pagesize_shift - shift))
- / (sizeof(uintptr_t) * 8);
-
- for (n = 0; n < map; n++) {
-
- if (bitmap[n] != NGX_SLAB_BUSY) {
-
- for (m = 1, i = 0; m; m <<= 1, i++) {
- if ((bitmap[n] & m)) {
- continue;
- }
-
- bitmap[n] |= m;
-
- i = ((n * sizeof(uintptr_t) * 8) << shift)
- + (i << shift);
-
- if (bitmap[n] == NGX_SLAB_BUSY) {
- for (n = n + 1; n < map; n++) {
- if (bitmap[n] != NGX_SLAB_BUSY) {
- p = (uintptr_t) bitmap + i;
-
- goto done;
- }
- }
-
- prev = (ngx_slab_page_t *)
- (page->prev & ~NGX_SLAB_PAGE_MASK);
- prev->next = page->next;
- page->next->prev = page->prev;
-
- page->next = NULL;
- page->prev = NGX_SLAB_SMALL;
- }
-
- p = (uintptr_t) bitmap + i;
-
- goto done;
- }
- }
- }
-
- page = page->next;
-
- } while (page);
-
- } else if (shift == ngx_slab_exact_shift) {
-
- do {
- if (page->slab != NGX_SLAB_BUSY) {
-
- for (m = 1, i = 0; m; m <<= 1, i++) {
- if ((page->slab & m)) {
- continue;
- }
-
- page->slab |= m;
-
- if (page->slab == NGX_SLAB_BUSY) {
- prev = (ngx_slab_page_t *)
- (page->prev & ~NGX_SLAB_PAGE_MASK);
- prev->next = page->next;
- page->next->prev = page->prev;
-
- page->next = NULL;
- page->prev = NGX_SLAB_EXACT;
- }
-
- p = (page - pool->pages) << ngx_pagesize_shift;
- p += i << shift;
- p += (uintptr_t) pool->start;
-
- goto done;
- }
- }
-
- page = page->next;
-
- } while (page);
-
- } else { /* shift > ngx_slab_exact_shift */
-
- n = ngx_pagesize_shift - (page->slab & NGX_SLAB_SHIFT_MASK);
- n = 1 << n;
- n = ((uintptr_t) 1 << n) - 1;
- mask = n << NGX_SLAB_MAP_SHIFT;
-
- do {
- if ((page->slab & NGX_SLAB_MAP_MASK) != mask) {
-
- for (m = (uintptr_t) 1 << NGX_SLAB_MAP_SHIFT, i = 0;
- m & mask;
- m <<= 1, i++)
- {
- if ((page->slab & m)) {
- continue;
- }
-
- page->slab |= m;
-
- if ((page->slab & NGX_SLAB_MAP_MASK) == mask) {
- prev = (ngx_slab_page_t *)
- (page->prev & ~NGX_SLAB_PAGE_MASK);
- prev->next = page->next;
- page->next->prev = page->prev;
-
- page->next = NULL;
- page->prev = NGX_SLAB_BIG;
- }
-
- p = (page - pool->pages) << ngx_pagesize_shift;
- p += i << shift;
- p += (uintptr_t) pool->start;
-
- goto done;
- }
- }
-
- page = page->next;
-
- } while (page);
- }
- }
-
- page = ngx_slab_alloc_pages(pool, 1);
-
- if (page) {
- if (shift < ngx_slab_exact_shift) {
- p = (page - pool->pages) << ngx_pagesize_shift;
- bitmap = (uintptr_t *) (pool->start + p);
-
- s = 1 << shift;
- n = (1 << (ngx_pagesize_shift - shift)) / 8 / s;
-
- if (n == 0) {
- n = 1;
- }
-
- bitmap[0] = (2 << n) - 1;
-
- map = (1 << (ngx_pagesize_shift - shift)) / (sizeof(uintptr_t) * 8);
-
- for (i = 1; i < map; i++) {
- bitmap[i] = 0;
- }
-
- page->slab = shift;
- page->next = &slots[slot];
- page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_SMALL;
-
- slots[slot].next = page;
-
- p = ((page - pool->pages) << ngx_pagesize_shift) + s * n;
- p += (uintptr_t) pool->start;
-
- goto done;
-
- } else if (shift == ngx_slab_exact_shift) {
-
- page->slab = 1;
- page->next = &slots[slot];
- page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT;
-
- slots[slot].next = page;
-
- p = (page - pool->pages) << ngx_pagesize_shift;
- p += (uintptr_t) pool->start;
-
- goto done;
-
- } else { /* shift > ngx_slab_exact_shift */
-
- page->slab = ((uintptr_t) 1 << NGX_SLAB_MAP_SHIFT) | shift;
- page->next = &slots[slot];
- page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG;
-
- slots[slot].next = page;
-
- p = (page - pool->pages) << ngx_pagesize_shift;
- p += (uintptr_t) pool->start;
-
- goto done;
- }
- }
-
- p = 0;
-
-done:
-
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab alloc: %p", p);
-
- return (void *) p;
-}
-
-
-void
-ngx_slab_free(ngx_slab_pool_t *pool, void *p)
-{
- ngx_shmtx_lock(&pool->mutex);
-
- ngx_slab_free_locked(pool, p);
-
- ngx_shmtx_unlock(&pool->mutex);
-}
-
-
-void
-ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
-{
- size_t size;
- uintptr_t slab, m, *bitmap;
- ngx_uint_t n, type, slot, shift, map;
- ngx_slab_page_t *slots, *page;
-
- ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, ngx_cycle->log, 0, "slab free: %p", p);
-
- if ((u_char *) p < pool->start || (u_char *) p > pool->end) {
- ngx_slab_error(pool, NGX_LOG_ALERT, "ngx_slab_free(): outside of pool");
- goto fail;
- }
-
- n = ((u_char *) p - pool->start) >> ngx_pagesize_shift;
- page = &pool->pages[n];
- slab = page->slab;
- type = page->prev & NGX_SLAB_PAGE_MASK;
-
- switch (type) {
-
- case NGX_SLAB_SMALL:
-
- shift = slab & NGX_SLAB_SHIFT_MASK;
- size = 1 << shift;
-
- if ((uintptr_t) p & (size - 1)) {
- goto wrong_chunk;
- }
-
- n = ((uintptr_t) p & (ngx_pagesize - 1)) >> shift;
- m = (uintptr_t) 1 << (n & (sizeof(uintptr_t) * 8 - 1));
- n /= (sizeof(uintptr_t) * 8);
- bitmap = (uintptr_t *)
- ((uintptr_t) p & ~((uintptr_t) ngx_pagesize - 1));
-
- if (bitmap[n] & m) {
-
- if (page->next == NULL) {
- slots = (ngx_slab_page_t *)
- ((u_char *) pool + sizeof(ngx_slab_pool_t));
- slot = shift - pool->min_shift;
-
- page->next = slots[slot].next;
- slots[slot].next = page;
-
- page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_SMALL;
- page->next->prev = (uintptr_t) page | NGX_SLAB_SMALL;
- }
-
- bitmap[n] &= ~m;
-
- n = (1 << (ngx_pagesize_shift - shift)) / 8 / (1 << shift);
-
- if (n == 0) {
- n = 1;
- }
-
- if (bitmap[0] & ~(((uintptr_t) 1 << n) - 1)) {
- goto done;
- }
-
- map = (1 << (ngx_pagesize_shift - shift)) / (sizeof(uintptr_t) * 8);
-
- for (n = 1; n < map; n++) {
- if (bitmap[n]) {
- goto done;
- }
- }
-
- ngx_slab_free_pages(pool, page, 1);
-
- goto done;
- }
-
- goto chunk_already_free;
-
- case NGX_SLAB_EXACT:
-
- m = (uintptr_t) 1 <<
- (((uintptr_t) p & (ngx_pagesize - 1)) >> ngx_slab_exact_shift);
- size = ngx_slab_exact_size;
-
- if ((uintptr_t) p & (size - 1)) {
- goto wrong_chunk;
- }
-
- if (slab & m) {
- if (slab == NGX_SLAB_BUSY) {
- slots = (ngx_slab_page_t *)
- ((u_char *) pool + sizeof(ngx_slab_pool_t));
- slot = ngx_slab_exact_shift - pool->min_shift;
-
- page->next = slots[slot].next;
- slots[slot].next = page;
-
- page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_EXACT;
- page->next->prev = (uintptr_t) page | NGX_SLAB_EXACT;
- }
-
- page->slab &= ~m;
-
- if (page->slab) {
- goto done;
- }
-
- ngx_slab_free_pages(pool, page, 1);
-
- goto done;
- }
-
- goto chunk_already_free;
-
- case NGX_SLAB_BIG:
-
- shift = slab & NGX_SLAB_SHIFT_MASK;
- size = 1 << shift;
-
- if ((uintptr_t) p & (size - 1)) {
- goto wrong_chunk;
- }
-
- m = (uintptr_t) 1 << ((((uintptr_t) p & (ngx_pagesize - 1)) >> shift)
- + NGX_SLAB_MAP_SHIFT);
-
- if (slab & m) {
-
- if (page->next == NULL) {
- slots = (ngx_slab_page_t *)
- ((u_char *) pool + sizeof(ngx_slab_pool_t));
- slot = shift - pool->min_shift;
-
- page->next = slots[slot].next;
- slots[slot].next = page;
-
- page->prev = (uintptr_t) &slots[slot] | NGX_SLAB_BIG;
- page->next->prev = (uintptr_t) page | NGX_SLAB_BIG;
- }
-
- page->slab &= ~m;
-
- if (page->slab & NGX_SLAB_MAP_MASK) {
- goto done;
- }
-
- ngx_slab_free_pages(pool, page, 1);
-
- goto done;
- }
-
- goto chunk_already_free;
-
- case NGX_SLAB_PAGE:
-
- if ((uintptr_t) p & (ngx_pagesize - 1)) {
- goto wrong_chunk;
- }
-
- if (slab == NGX_SLAB_PAGE_FREE) {
- ngx_slab_error(pool, NGX_LOG_ALERT,
- "ngx_slab_free(): page is already free");
- goto fail;
- }
-
- if (slab == NGX_SLAB_PAGE_BUSY) {
- ngx_slab_error(pool, NGX_LOG_ALERT,
- "ngx_slab_free(): pointer to wrong page");
- goto fail;
- }
-
- n = ((u_char *) p - pool->start) >> ngx_pagesize_shift;
- size = slab & ~NGX_SLAB_PAGE_START;
-
- ngx_slab_free_pages(pool, &pool->pages[n], size);
-
- ngx_slab_junk(p, size << ngx_pagesize_shift);
-
- return;
- }
-
- /* not reached */
-
- return;
-
-done:
-
- ngx_slab_junk(p, size);
-
- return;
-
-wrong_chunk:
-
- ngx_slab_error(pool, NGX_LOG_ALERT,
- "ngx_slab_free(): pointer to wrong chunk");
-
- goto fail;
-
-chunk_already_free:
-
- ngx_slab_error(pool, NGX_LOG_ALERT,
- "ngx_slab_free(): chunk is already free");
-
-fail:
-
- return;
-}
-
-
-static ngx_slab_page_t *
-ngx_slab_alloc_pages(ngx_slab_pool_t *pool, ngx_uint_t pages)
-{
- ngx_slab_page_t *page, *p;
-
- for (page = pool->free.next; page != &pool->free; page = page->next) {
-
- if (page->slab >= pages) {
-
- if (page->slab > pages) {
- page[pages].slab = page->slab - pages;
- page[pages].next = page->next;
- page[pages].prev = page->prev;
-
- p = (ngx_slab_page_t *) page->prev;
- p->next = &page[pages];
- page->next->prev = (uintptr_t) &page[pages];
-
- } else {
- p = (ngx_slab_page_t *) page->prev;
- p->next = page->next;
- page->next->prev = page->prev;
- }
-
- page->slab = pages | NGX_SLAB_PAGE_START;
- page->next = NULL;
- page->prev = NGX_SLAB_PAGE;
-
- if (--pages == 0) {
- return page;
- }
-
- for (p = page + 1; pages; pages--) {
- p->slab = NGX_SLAB_PAGE_BUSY;
- p->next = NULL;
- p->prev = NGX_SLAB_PAGE;
- p++;
- }
-
- return page;
- }
- }
-
- if (pool->log_nomem) {
- ngx_slab_error(pool, NGX_LOG_CRIT,
- "ngx_slab_alloc() failed: no memory");
- }
-
- return NULL;
-}
-
-
-static void
-ngx_slab_free_pages(ngx_slab_pool_t *pool, ngx_slab_page_t *page,
- ngx_uint_t pages)
-{
- ngx_slab_page_t *prev;
-
- page->slab = pages--;
-
- if (pages) {
- ngx_memzero(&page[1], pages * sizeof(ngx_slab_page_t));
- }
-
- if (page->next) {
- prev = (ngx_slab_page_t *) (page->prev & ~NGX_SLAB_PAGE_MASK);
- prev->next = page->next;
- page->next->prev = page->prev;
- }
-
- page->prev = (uintptr_t) &pool->free;
- page->next = pool->free.next;
-
- page->next->prev = (uintptr_t) page;
-
- pool->free.next = page;
-}
-
-
-static void
-ngx_slab_error(ngx_slab_pool_t *pool, ngx_uint_t level, char *text)
-{
- ngx_log_error(level, ngx_cycle->log, 0, "%s%s", text, pool->log_ctx);
-}
diff --git a/usr.sbin/nginx/src/core/ngx_slab.h b/usr.sbin/nginx/src/core/ngx_slab.h
deleted file mode 100644
index 5735e3bb3b9..00000000000
--- a/usr.sbin/nginx/src/core/ngx_slab.h
+++ /dev/null
@@ -1,56 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_SLAB_H_INCLUDED_
-#define _NGX_SLAB_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef struct ngx_slab_page_s ngx_slab_page_t;
-
-struct ngx_slab_page_s {
- uintptr_t slab;
- ngx_slab_page_t *next;
- uintptr_t prev;
-};
-
-
-typedef struct {
- ngx_shmtx_sh_t lock;
-
- size_t min_size;
- size_t min_shift;
-
- ngx_slab_page_t *pages;
- ngx_slab_page_t free;
-
- u_char *start;
- u_char *end;
-
- ngx_shmtx_t mutex;
-
- u_char *log_ctx;
- u_char zero;
-
- unsigned log_nomem:1;
-
- void *data;
- void *addr;
-} ngx_slab_pool_t;
-
-
-void ngx_slab_init(ngx_slab_pool_t *pool);
-void *ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size);
-void *ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size);
-void ngx_slab_free(ngx_slab_pool_t *pool, void *p);
-void ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p);
-
-
-#endif /* _NGX_SLAB_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_spinlock.c b/usr.sbin/nginx/src/core/ngx_spinlock.c
deleted file mode 100644
index 9c93afaf1b1..00000000000
--- a/usr.sbin/nginx/src/core/ngx_spinlock.c
+++ /dev/null
@@ -1,53 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-void
-ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin)
-{
-
-#if (NGX_HAVE_ATOMIC_OPS)
-
- ngx_uint_t i, n;
-
- for ( ;; ) {
-
- if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
- return;
- }
-
- if (ngx_ncpu > 1) {
-
- for (n = 1; n < spin; n <<= 1) {
-
- for (i = 0; i < n; i++) {
- ngx_cpu_pause();
- }
-
- if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
- return;
- }
- }
- }
-
- ngx_sched_yield();
- }
-
-#else
-
-#if (NGX_THREADS)
-
-#error ngx_spinlock() or ngx_atomic_cmp_set() are not defined !
-
-#endif
-
-#endif
-
-}
diff --git a/usr.sbin/nginx/src/core/ngx_string.c b/usr.sbin/nginx/src/core/ngx_string.c
deleted file mode 100644
index a4cfcdc7a5e..00000000000
--- a/usr.sbin/nginx/src/core/ngx_string.c
+++ /dev/null
@@ -1,1929 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-static u_char *ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64,
- u_char zero, ngx_uint_t hexadecimal, ngx_uint_t width);
-static void ngx_encode_base64_internal(ngx_str_t *dst, ngx_str_t *src,
- const u_char *basis, ngx_uint_t padding);
-static ngx_int_t ngx_decode_base64_internal(ngx_str_t *dst, ngx_str_t *src,
- const u_char *basis);
-
-
-void
-ngx_strlow(u_char *dst, u_char *src, size_t n)
-{
- while (n) {
- *dst = ngx_tolower(*src);
- dst++;
- src++;
- n--;
- }
-}
-
-
-u_char *
-ngx_cpystrn(u_char *dst, u_char *src, size_t n)
-{
- if (n == 0) {
- return dst;
- }
-
- while (--n) {
- *dst = *src;
-
- if (*dst == '\0') {
- return dst;
- }
-
- dst++;
- src++;
- }
-
- *dst = '\0';
-
- return dst;
-}
-
-
-u_char *
-ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src)
-{
- u_char *dst;
-
- dst = ngx_pnalloc(pool, src->len);
- if (dst == NULL) {
- return NULL;
- }
-
- ngx_memcpy(dst, src->data, src->len);
-
- return dst;
-}
-
-
-/*
- * supported formats:
- * %[0][width][x][X]O off_t
- * %[0][width]T time_t
- * %[0][width][u][x|X]z ssize_t/size_t
- * %[0][width][u][x|X]d int/u_int
- * %[0][width][u][x|X]l long
- * %[0][width|m][u][x|X]i ngx_int_t/ngx_uint_t
- * %[0][width][u][x|X]D int32_t/uint32_t
- * %[0][width][u][x|X]L int64_t/uint64_t
- * %[0][width|m][u][x|X]A ngx_atomic_int_t/ngx_atomic_uint_t
- * %[0][width][.width]f double, max valid number fits to %18.15f
- * %P ngx_pid_t
- * %M ngx_msec_t
- * %r rlim_t
- * %p void *
- * %V ngx_str_t *
- * %v ngx_variable_value_t *
- * %s null-terminated string
- * %*s length and string
- * %Z '\0'
- * %N '\n'
- * %c char
- * %% %
- *
- * reserved:
- * %t ptrdiff_t
- * %S null-terminated wchar string
- * %C wchar
- */
-
-
-u_char * ngx_cdecl
-ngx_sprintf(u_char *buf, const char *fmt, ...)
-{
- u_char *p;
- va_list args;
-
- va_start(args, fmt);
- p = ngx_vslprintf(buf, (void *) -1, fmt, args);
- va_end(args);
-
- return p;
-}
-
-
-u_char * ngx_cdecl
-ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...)
-{
- u_char *p;
- va_list args;
-
- va_start(args, fmt);
- p = ngx_vslprintf(buf, buf + max, fmt, args);
- va_end(args);
-
- return p;
-}
-
-
-u_char * ngx_cdecl
-ngx_slprintf(u_char *buf, u_char *last, const char *fmt, ...)
-{
- u_char *p;
- va_list args;
-
- va_start(args, fmt);
- p = ngx_vslprintf(buf, last, fmt, args);
- va_end(args);
-
- return p;
-}
-
-
-u_char *
-ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args)
-{
- u_char *p, zero;
- int d;
- double f;
- size_t len, slen;
- int64_t i64;
- uint64_t ui64, frac;
- ngx_msec_t ms;
- ngx_uint_t width, sign, hex, max_width, frac_width, scale, n;
- ngx_str_t *v;
- ngx_variable_value_t *vv;
-
- while (*fmt && buf < last) {
-
- /*
- * "buf < last" means that we could copy at least one character:
- * the plain character, "%%", "%c", and minus without the checking
- */
-
- if (*fmt == '%') {
-
- i64 = 0;
- ui64 = 0;
-
- zero = (u_char) ((*++fmt == '0') ? '0' : ' ');
- width = 0;
- sign = 1;
- hex = 0;
- max_width = 0;
- frac_width = 0;
- slen = (size_t) -1;
-
- while (*fmt >= '0' && *fmt <= '9') {
- width = width * 10 + *fmt++ - '0';
- }
-
-
- for ( ;; ) {
- switch (*fmt) {
-
- case 'u':
- sign = 0;
- fmt++;
- continue;
-
- case 'm':
- max_width = 1;
- fmt++;
- continue;
-
- case 'X':
- hex = 2;
- sign = 0;
- fmt++;
- continue;
-
- case 'x':
- hex = 1;
- sign = 0;
- fmt++;
- continue;
-
- case '.':
- fmt++;
-
- while (*fmt >= '0' && *fmt <= '9') {
- frac_width = frac_width * 10 + *fmt++ - '0';
- }
-
- break;
-
- case '*':
- slen = va_arg(args, size_t);
- fmt++;
- continue;
-
- default:
- break;
- }
-
- break;
- }
-
-
- switch (*fmt) {
-
- case 'V':
- v = va_arg(args, ngx_str_t *);
-
- len = ngx_min(((size_t) (last - buf)), v->len);
- buf = ngx_cpymem(buf, v->data, len);
- fmt++;
-
- continue;
-
- case 'v':
- vv = va_arg(args, ngx_variable_value_t *);
-
- len = ngx_min(((size_t) (last - buf)), vv->len);
- buf = ngx_cpymem(buf, vv->data, len);
- fmt++;
-
- continue;
-
- case 's':
- p = va_arg(args, u_char *);
-
- if (slen == (size_t) -1) {
- while (*p && buf < last) {
- *buf++ = *p++;
- }
-
- } else {
- len = ngx_min(((size_t) (last - buf)), slen);
- buf = ngx_cpymem(buf, p, len);
- }
-
- fmt++;
-
- continue;
-
- case 'O':
- i64 = (int64_t) va_arg(args, off_t);
- sign = 1;
- break;
-
- case 'P':
- i64 = (int64_t) va_arg(args, ngx_pid_t);
- sign = 1;
- break;
-
- case 'T':
- i64 = (int64_t) va_arg(args, time_t);
- sign = 1;
- break;
-
- case 'M':
- ms = (ngx_msec_t) va_arg(args, ngx_msec_t);
- if ((ngx_msec_int_t) ms == -1) {
- sign = 1;
- i64 = -1;
- } else {
- sign = 0;
- ui64 = (uint64_t) ms;
- }
- break;
-
- case 'z':
- if (sign) {
- i64 = (int64_t) va_arg(args, ssize_t);
- } else {
- ui64 = (uint64_t) va_arg(args, size_t);
- }
- break;
-
- case 'i':
- if (sign) {
- i64 = (int64_t) va_arg(args, ngx_int_t);
- } else {
- ui64 = (uint64_t) va_arg(args, ngx_uint_t);
- }
-
- if (max_width) {
- width = NGX_INT_T_LEN;
- }
-
- break;
-
- case 'd':
- if (sign) {
- i64 = (int64_t) va_arg(args, int);
- } else {
- ui64 = (uint64_t) va_arg(args, u_int);
- }
- break;
-
- case 'l':
- if (sign) {
- i64 = (int64_t) va_arg(args, long);
- } else {
- ui64 = (uint64_t) va_arg(args, u_long);
- }
- break;
-
- case 'D':
- if (sign) {
- i64 = (int64_t) va_arg(args, int32_t);
- } else {
- ui64 = (uint64_t) va_arg(args, uint32_t);
- }
- break;
-
- case 'L':
- if (sign) {
- i64 = va_arg(args, int64_t);
- } else {
- ui64 = va_arg(args, uint64_t);
- }
- break;
-
- case 'A':
- if (sign) {
- i64 = (int64_t) va_arg(args, ngx_atomic_int_t);
- } else {
- ui64 = (uint64_t) va_arg(args, ngx_atomic_uint_t);
- }
-
- if (max_width) {
- width = NGX_ATOMIC_T_LEN;
- }
-
- break;
-
- case 'f':
- f = va_arg(args, double);
-
- if (f < 0) {
- *buf++ = '-';
- f = -f;
- }
-
- ui64 = (int64_t) f;
- frac = 0;
-
- if (frac_width) {
-
- scale = 1;
- for (n = frac_width; n; n--) {
- scale *= 10;
- }
-
- frac = (uint64_t) ((f - (double) ui64) * scale + 0.5);
-
- if (frac == scale) {
- ui64++;
- frac = 0;
- }
- }
-
- buf = ngx_sprintf_num(buf, last, ui64, zero, 0, width);
-
- if (frac_width) {
- if (buf < last) {
- *buf++ = '.';
- }
-
- buf = ngx_sprintf_num(buf, last, frac, '0', 0, frac_width);
- }
-
- fmt++;
-
- continue;
-
-#if !(NGX_WIN32)
- case 'r':
- i64 = (int64_t) va_arg(args, rlim_t);
- sign = 1;
- break;
-#endif
-
- case 'p':
- ui64 = (uintptr_t) va_arg(args, void *);
- hex = 2;
- sign = 0;
- zero = '0';
- width = NGX_PTR_SIZE * 2;
- break;
-
- case 'c':
- d = va_arg(args, int);
- *buf++ = (u_char) (d & 0xff);
- fmt++;
-
- continue;
-
- case 'Z':
- *buf++ = '\0';
- fmt++;
-
- continue;
-
- case 'N':
-#if (NGX_WIN32)
- *buf++ = CR;
-#endif
- *buf++ = LF;
- fmt++;
-
- continue;
-
- case '%':
- *buf++ = '%';
- fmt++;
-
- continue;
-
- default:
- *buf++ = *fmt++;
-
- continue;
- }
-
- if (sign) {
- if (i64 < 0) {
- *buf++ = '-';
- ui64 = (uint64_t) -i64;
-
- } else {
- ui64 = (uint64_t) i64;
- }
- }
-
- buf = ngx_sprintf_num(buf, last, ui64, zero, hex, width);
-
- fmt++;
-
- } else {
- *buf++ = *fmt++;
- }
- }
-
- return buf;
-}
-
-
-static u_char *
-ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64, u_char zero,
- ngx_uint_t hexadecimal, ngx_uint_t width)
-{
- u_char *p, temp[NGX_INT64_LEN + 1];
- /*
- * we need temp[NGX_INT64_LEN] only,
- * but icc issues the warning
- */
- size_t len;
- uint32_t ui32;
- static u_char hex[] = "0123456789abcdef";
- static u_char HEX[] = "0123456789ABCDEF";
-
- p = temp + NGX_INT64_LEN;
-
- if (hexadecimal == 0) {
-
- if (ui64 <= (uint64_t) NGX_MAX_UINT32_VALUE) {
-
- /*
- * To divide 64-bit numbers and to find remainders
- * on the x86 platform gcc and icc call the libc functions
- * [u]divdi3() and [u]moddi3(), they call another function
- * in its turn. On FreeBSD it is the qdivrem() function,
- * its source code is about 170 lines of the code.
- * The glibc counterpart is about 150 lines of the code.
- *
- * For 32-bit numbers and some divisors gcc and icc use
- * a inlined multiplication and shifts. For example,
- * unsigned "i32 / 10" is compiled to
- *
- * (i32 * 0xCCCCCCCD) >> 35
- */
-
- ui32 = (uint32_t) ui64;
-
- do {
- *--p = (u_char) (ui32 % 10 + '0');
- } while (ui32 /= 10);
-
- } else {
- do {
- *--p = (u_char) (ui64 % 10 + '0');
- } while (ui64 /= 10);
- }
-
- } else if (hexadecimal == 1) {
-
- do {
-
- /* the "(uint32_t)" cast disables the BCC's warning */
- *--p = hex[(uint32_t) (ui64 & 0xf)];
-
- } while (ui64 >>= 4);
-
- } else { /* hexadecimal == 2 */
-
- do {
-
- /* the "(uint32_t)" cast disables the BCC's warning */
- *--p = HEX[(uint32_t) (ui64 & 0xf)];
-
- } while (ui64 >>= 4);
- }
-
- /* zero or space padding */
-
- len = (temp + NGX_INT64_LEN) - p;
-
- while (len++ < width && buf < last) {
- *buf++ = zero;
- }
-
- /* number safe copy */
-
- len = (temp + NGX_INT64_LEN) - p;
-
- if (buf + len > last) {
- len = last - buf;
- }
-
- return ngx_cpymem(buf, p, len);
-}
-
-
-/*
- * 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.
- */
-
-ngx_int_t
-ngx_strcasecmp(u_char *s1, u_char *s2)
-{
- ngx_uint_t c1, c2;
-
- for ( ;; ) {
- c1 = (ngx_uint_t) *s1++;
- c2 = (ngx_uint_t) *s2++;
-
- c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
- c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
-
- if (c1 == c2) {
-
- if (c1) {
- continue;
- }
-
- return 0;
- }
-
- return c1 - c2;
- }
-}
-
-
-ngx_int_t
-ngx_strncasecmp(u_char *s1, u_char *s2, size_t n)
-{
- ngx_uint_t c1, c2;
-
- while (n) {
- c1 = (ngx_uint_t) *s1++;
- c2 = (ngx_uint_t) *s2++;
-
- c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
- c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
-
- if (c1 == c2) {
-
- if (c1) {
- n--;
- continue;
- }
-
- return 0;
- }
-
- return c1 - c2;
- }
-
- return 0;
-}
-
-
-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_strlcasestrn() is intended to search for static substring
- * with known length in string until the argument last. The argument n
- * must be length of the second substring - 1.
- */
-
-u_char *
-ngx_strlcasestrn(u_char *s1, u_char *last, u_char *s2, size_t n)
-{
- ngx_uint_t c1, c2;
-
- c2 = (ngx_uint_t) *s2++;
- c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
- last -= n;
-
- do {
- do {
- if (s1 >= last) {
- return NULL;
- }
-
- c1 = (ngx_uint_t) *s1++;
-
- c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
-
- } while (c1 != c2);
-
- } while (ngx_strncasecmp(s1, s2, n) != 0);
-
- return --s1;
-}
-
-
-ngx_int_t
-ngx_rstrncmp(u_char *s1, u_char *s2, size_t n)
-{
- if (n == 0) {
- return 0;
- }
-
- n--;
-
- for ( ;; ) {
- if (s1[n] != s2[n]) {
- return s1[n] - s2[n];
- }
-
- if (n == 0) {
- return 0;
- }
-
- n--;
- }
-}
-
-
-ngx_int_t
-ngx_rstrncasecmp(u_char *s1, u_char *s2, size_t n)
-{
- u_char c1, c2;
-
- if (n == 0) {
- return 0;
- }
-
- n--;
-
- for ( ;; ) {
- c1 = s1[n];
- if (c1 >= 'a' && c1 <= 'z') {
- c1 -= 'a' - 'A';
- }
-
- c2 = s2[n];
- if (c2 >= 'a' && c2 <= 'z') {
- c2 -= 'a' - 'A';
- }
-
- if (c1 != c2) {
- return c1 - c2;
- }
-
- if (n == 0) {
- return 0;
- }
-
- n--;
- }
-}
-
-
-ngx_int_t
-ngx_memn2cmp(u_char *s1, u_char *s2, size_t n1, size_t n2)
-{
- size_t n;
- ngx_int_t m, z;
-
- if (n1 <= n2) {
- n = n1;
- z = -1;
-
- } else {
- n = n2;
- z = 1;
- }
-
- m = ngx_memcmp(s1, s2, n);
-
- if (m || n1 == n2) {
- return m;
- }
-
- return z;
-}
-
-
-ngx_int_t
-ngx_dns_strcmp(u_char *s1, u_char *s2)
-{
- ngx_uint_t c1, c2;
-
- for ( ;; ) {
- c1 = (ngx_uint_t) *s1++;
- c2 = (ngx_uint_t) *s2++;
-
- c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
- c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
-
- if (c1 == c2) {
-
- if (c1) {
- continue;
- }
-
- return 0;
- }
-
- /* in ASCII '.' > '-', but we need '.' to be the lowest character */
-
- c1 = (c1 == '.') ? ' ' : c1;
- c2 = (c2 == '.') ? ' ' : c2;
-
- return c1 - c2;
- }
-}
-
-
-ngx_int_t
-ngx_filename_cmp(u_char *s1, u_char *s2, size_t n)
-{
- ngx_uint_t c1, c2;
-
- while (n) {
- c1 = (ngx_uint_t) *s1++;
- c2 = (ngx_uint_t) *s2++;
-
-#if (NGX_HAVE_CASELESS_FILESYSTEM)
- c1 = tolower(c1);
- c2 = tolower(c2);
-#endif
-
- if (c1 == c2) {
-
- if (c1) {
- n--;
- continue;
- }
-
- return 0;
- }
-
- /* we need '/' to be the lowest character */
-
- if (c1 == 0 || c2 == 0) {
- return c1 - c2;
- }
-
- c1 = (c1 == '/') ? 0 : c1;
- c2 = (c2 == '/') ? 0 : c2;
-
- return c1 - c2;
- }
-
- return 0;
-}
-
-
-ngx_int_t
-ngx_atoi(u_char *line, size_t n)
-{
- ngx_int_t value;
-
- if (n == 0) {
- return NGX_ERROR;
- }
-
- for (value = 0; n--; line++) {
- if (*line < '0' || *line > '9') {
- return NGX_ERROR;
- }
-
- value = value * 10 + (*line - '0');
- }
-
- if (value < 0) {
- return NGX_ERROR;
-
- } else {
- return value;
- }
-}
-
-
-/* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050 */
-
-ngx_int_t
-ngx_atofp(u_char *line, size_t n, size_t point)
-{
- ngx_int_t value;
- ngx_uint_t dot;
-
- if (n == 0) {
- return NGX_ERROR;
- }
-
- dot = 0;
-
- for (value = 0; n--; line++) {
-
- if (point == 0) {
- return NGX_ERROR;
- }
-
- if (*line == '.') {
- if (dot) {
- return NGX_ERROR;
- }
-
- dot = 1;
- continue;
- }
-
- if (*line < '0' || *line > '9') {
- return NGX_ERROR;
- }
-
- value = value * 10 + (*line - '0');
- point -= dot;
- }
-
- while (point--) {
- value = value * 10;
- }
-
- if (value < 0) {
- return NGX_ERROR;
-
- } else {
- return value;
- }
-}
-
-
-ssize_t
-ngx_atosz(u_char *line, size_t n)
-{
- ssize_t value;
-
- if (n == 0) {
- return NGX_ERROR;
- }
-
- for (value = 0; n--; line++) {
- if (*line < '0' || *line > '9') {
- return NGX_ERROR;
- }
-
- value = value * 10 + (*line - '0');
- }
-
- if (value < 0) {
- return NGX_ERROR;
-
- } else {
- return value;
- }
-}
-
-
-off_t
-ngx_atoof(u_char *line, size_t n)
-{
- off_t value;
-
- if (n == 0) {
- return NGX_ERROR;
- }
-
- for (value = 0; n--; line++) {
- if (*line < '0' || *line > '9') {
- return NGX_ERROR;
- }
-
- value = value * 10 + (*line - '0');
- }
-
- if (value < 0) {
- return NGX_ERROR;
-
- } else {
- return value;
- }
-}
-
-
-time_t
-ngx_atotm(u_char *line, size_t n)
-{
- time_t value;
-
- if (n == 0) {
- return NGX_ERROR;
- }
-
- for (value = 0; n--; line++) {
- if (*line < '0' || *line > '9') {
- return NGX_ERROR;
- }
-
- value = value * 10 + (*line - '0');
- }
-
- if (value < 0) {
- return NGX_ERROR;
-
- } else {
- return value;
- }
-}
-
-
-ngx_int_t
-ngx_hextoi(u_char *line, size_t n)
-{
- u_char c, ch;
- ngx_int_t value;
-
- if (n == 0) {
- return NGX_ERROR;
- }
-
- for (value = 0; n--; line++) {
- ch = *line;
-
- if (ch >= '0' && ch <= '9') {
- value = value * 16 + (ch - '0');
- continue;
- }
-
- c = (u_char) (ch | 0x20);
-
- if (c >= 'a' && c <= 'f') {
- value = value * 16 + (c - 'a' + 10);
- continue;
- }
-
- return NGX_ERROR;
- }
-
- if (value < 0) {
- return NGX_ERROR;
-
- } else {
- return value;
- }
-}
-
-
-u_char *
-ngx_hex_dump(u_char *dst, u_char *src, size_t len)
-{
- static u_char hex[] = "0123456789abcdef";
-
- while (len--) {
- *dst++ = hex[*src >> 4];
- *dst++ = hex[*src++ & 0xf];
- }
-
- return dst;
-}
-
-
-void
-ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src)
-{
- static u_char basis64[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
- ngx_encode_base64_internal(dst, src, basis64, 1);
-}
-
-
-void
-ngx_encode_base64url(ngx_str_t *dst, ngx_str_t *src)
-{
- static u_char basis64[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
-
- ngx_encode_base64_internal(dst, src, basis64, 0);
-}
-
-
-static void
-ngx_encode_base64_internal(ngx_str_t *dst, ngx_str_t *src, const u_char *basis,
- ngx_uint_t padding)
-{
- u_char *d, *s;
- size_t len;
-
- len = src->len;
- s = src->data;
- d = dst->data;
-
- while (len > 2) {
- *d++ = basis[(s[0] >> 2) & 0x3f];
- *d++ = basis[((s[0] & 3) << 4) | (s[1] >> 4)];
- *d++ = basis[((s[1] & 0x0f) << 2) | (s[2] >> 6)];
- *d++ = basis[s[2] & 0x3f];
-
- s += 3;
- len -= 3;
- }
-
- if (len) {
- *d++ = basis[(s[0] >> 2) & 0x3f];
-
- if (len == 1) {
- *d++ = basis[(s[0] & 3) << 4];
- if (padding) {
- *d++ = '=';
- }
-
- } else {
- *d++ = basis[((s[0] & 3) << 4) | (s[1] >> 4)];
- *d++ = basis[(s[1] & 0x0f) << 2];
- }
-
- if (padding) {
- *d++ = '=';
- }
- }
-
- dst->len = d - dst->data;
-}
-
-
-ngx_int_t
-ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src)
-{
- static u_char basis64[] = {
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 62, 77, 77, 77, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 77, 77, 77, 77, 77, 77,
- 77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 77, 77, 77, 77, 77,
- 77, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 77, 77, 77, 77, 77,
-
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77
- };
-
- return ngx_decode_base64_internal(dst, src, basis64);
-}
-
-
-ngx_int_t
-ngx_decode_base64url(ngx_str_t *dst, ngx_str_t *src)
-{
- static u_char basis64[] = {
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 62, 77, 77,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 77, 77, 77, 77, 77, 77,
- 77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 77, 77, 77, 77, 63,
- 77, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 77, 77, 77, 77, 77,
-
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77
- };
-
- return ngx_decode_base64_internal(dst, src, basis64);
-}
-
-
-static ngx_int_t
-ngx_decode_base64_internal(ngx_str_t *dst, ngx_str_t *src, const u_char *basis)
-{
- size_t len;
- u_char *d, *s;
-
- for (len = 0; len < src->len; len++) {
- if (src->data[len] == '=') {
- break;
- }
-
- if (basis[src->data[len]] == 77) {
- return NGX_ERROR;
- }
- }
-
- if (len % 4 == 1) {
- return NGX_ERROR;
- }
-
- s = src->data;
- d = dst->data;
-
- while (len > 3) {
- *d++ = (u_char) (basis[s[0]] << 2 | basis[s[1]] >> 4);
- *d++ = (u_char) (basis[s[1]] << 4 | basis[s[2]] >> 2);
- *d++ = (u_char) (basis[s[2]] << 6 | basis[s[3]]);
-
- s += 4;
- len -= 4;
- }
-
- if (len > 1) {
- *d++ = (u_char) (basis[s[0]] << 2 | basis[s[1]] >> 4);
- }
-
- if (len > 2) {
- *d++ = (u_char) (basis[s[1]] << 4 | basis[s[2]] >> 2);
- }
-
- dst->len = d - dst->data;
-
- return NGX_OK;
-}
-
-
-/*
- * ngx_utf8_decode() decodes two and more bytes UTF sequences only
- * the return values:
- * 0x80 - 0x10ffff valid character
- * 0x110000 - 0xfffffffd invalid sequence
- * 0xfffffffe incomplete sequence
- * 0xffffffff error
- */
-
-uint32_t
-ngx_utf8_decode(u_char **p, size_t n)
-{
- size_t len;
- uint32_t u, i, valid;
-
- u = **p;
-
- if (u >= 0xf0) {
-
- u &= 0x07;
- valid = 0xffff;
- len = 3;
-
- } else if (u >= 0xe0) {
-
- u &= 0x0f;
- valid = 0x7ff;
- len = 2;
-
- } else if (u >= 0xc2) {
-
- u &= 0x1f;
- valid = 0x7f;
- len = 1;
-
- } else {
- (*p)++;
- return 0xffffffff;
- }
-
- if (n - 1 < len) {
- return 0xfffffffe;
- }
-
- (*p)++;
-
- while (len) {
- i = *(*p)++;
-
- if (i < 0x80) {
- return 0xffffffff;
- }
-
- u = (u << 6) | (i & 0x3f);
-
- len--;
- }
-
- if (u > valid) {
- return u;
- }
-
- return 0xffffffff;
-}
-
-
-size_t
-ngx_utf8_length(u_char *p, size_t n)
-{
- u_char c, *last;
- size_t len;
-
- last = p + n;
-
- for (len = 0; p < last; len++) {
-
- c = *p;
-
- if (c < 0x80) {
- p++;
- continue;
- }
-
- if (ngx_utf8_decode(&p, n) > 0x10ffff) {
- /* invalid UTF-8 */
- return n;
- }
- }
-
- return len;
-}
-
-
-u_char *
-ngx_utf8_cpystrn(u_char *dst, u_char *src, size_t n, size_t len)
-{
- u_char c, *next;
-
- if (n == 0) {
- return dst;
- }
-
- while (--n) {
-
- c = *src;
- *dst = c;
-
- if (c < 0x80) {
-
- if (c != '\0') {
- dst++;
- src++;
- len--;
-
- continue;
- }
-
- return dst;
- }
-
- next = src;
-
- if (ngx_utf8_decode(&next, len) > 0x10ffff) {
- /* invalid UTF-8 */
- break;
- }
-
- while (src < next) {
- *dst++ = *src++;
- len--;
- }
- }
-
- *dst = '\0';
-
- return dst;
-}
-
-
-uintptr_t
-ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
-{
- ngx_uint_t n;
- uint32_t *escape;
- static u_char hex[] = "0123456789abcdef";
-
- /* " ", "#", "%", "?", %00-%1F, %7F-%FF */
-
- static uint32_t uri[] = {
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
-
- /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
- 0x80000029, /* 1000 0000 0000 0000 0000 0000 0010 1001 */
-
- /* _^]\ [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, %7F-%FF */
-
- static uint32_t args[] = {
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
-
- /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
- 0x88000869, /* 1000 1000 0000 0000 0000 1000 0110 1001 */
-
- /* _^]\ [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 */
- };
-
- /* not ALPHA, DIGIT, "-", ".", "_", "~" */
-
- static uint32_t uri_component[] = {
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
-
- /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
- 0xfc009fff, /* 1111 1100 0000 0000 1001 1111 1111 1111 */
-
- /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
- 0x78000001, /* 0111 1000 0000 0000 0000 0000 0000 0001 */
-
- /* ~}| {zyx wvut srqp onml kjih gfed cba` */
- 0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */
-
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- };
-
- /* " ", "#", """, "%", "'", %00-%1F, %7F-%FF */
-
- static uint32_t html[] = {
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
-
- /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
- 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 */
-
- /* ~}| {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, %7F-%FF */
-
- 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, uri_component, html, refresh, memcached, memcached };
-
-
- escape = map[type];
-
- if (dst == NULL) {
-
- /* find the number of the characters to be escaped */
-
- n = 0;
-
- while (size) {
- if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
- n++;
- }
- src++;
- size--;
- }
-
- return (uintptr_t) n;
- }
-
- while (size) {
- if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
- *dst++ = '%';
- *dst++ = hex[*src >> 4];
- *dst++ = hex[*src & 0xf];
- src++;
-
- } else {
- *dst++ = *src++;
- }
- size--;
- }
-
- return (uintptr_t) dst;
-}
-
-
-void
-ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type)
-{
- u_char *d, *s, ch, c, decoded;
- enum {
- sw_usual = 0,
- sw_quoted,
- sw_quoted_second
- } state;
-
- d = *dst;
- s = *src;
-
- state = 0;
- decoded = 0;
-
- while (size--) {
-
- ch = *s++;
-
- switch (state) {
- case sw_usual:
- if (ch == '?'
- && (type & (NGX_UNESCAPE_URI|NGX_UNESCAPE_REDIRECT)))
- {
- *d++ = ch;
- goto done;
- }
-
- if (ch == '%') {
- state = sw_quoted;
- break;
- }
-
- *d++ = ch;
- break;
-
- case sw_quoted:
-
- if (ch >= '0' && ch <= '9') {
- decoded = (u_char) (ch - '0');
- state = sw_quoted_second;
- break;
- }
-
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'f') {
- decoded = (u_char) (c - 'a' + 10);
- state = sw_quoted_second;
- break;
- }
-
- /* the invalid quoted character */
-
- state = sw_usual;
-
- *d++ = ch;
-
- break;
-
- case sw_quoted_second:
-
- state = sw_usual;
-
- if (ch >= '0' && ch <= '9') {
- ch = (u_char) ((decoded << 4) + ch - '0');
-
- if (type & NGX_UNESCAPE_REDIRECT) {
- if (ch > '%' && ch < 0x7f) {
- *d++ = ch;
- break;
- }
-
- *d++ = '%'; *d++ = *(s - 2); *d++ = *(s - 1);
-
- break;
- }
-
- *d++ = ch;
-
- break;
- }
-
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'f') {
- ch = (u_char) ((decoded << 4) + c - 'a' + 10);
-
- 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;
- }
-
- if (ch > '%' && ch < 0x7f) {
- *d++ = ch;
- break;
- }
-
- *d++ = '%'; *d++ = *(s - 2); *d++ = *(s - 1);
- break;
- }
-
- *d++ = ch;
-
- break;
- }
-
- /* the invalid quoted character */
-
- break;
- }
- }
-
-done:
-
- *dst = d;
- *src = s;
-}
-
-
-uintptr_t
-ngx_escape_html(u_char *dst, u_char *src, size_t size)
-{
- u_char ch;
- ngx_uint_t len;
-
- if (dst == NULL) {
-
- len = 0;
-
- while (size) {
- switch (*src++) {
-
- case '<':
- len += sizeof("&lt;") - 2;
- break;
-
- case '>':
- len += sizeof("&gt;") - 2;
- break;
-
- case '&':
- len += sizeof("&amp;") - 2;
- break;
-
- case '"':
- len += sizeof("&quot;") - 2;
- break;
-
- default:
- break;
- }
- size--;
- }
-
- return (uintptr_t) len;
- }
-
- while (size) {
- 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;
-
- case '"':
- *dst++ = '&'; *dst++ = 'q'; *dst++ = 'u'; *dst++ = 'o';
- *dst++ = 't'; *dst++ = ';';
- break;
-
- default:
- *dst++ = ch;
- break;
- }
- size--;
- }
-
- return (uintptr_t) dst;
-}
-
-
-void
-ngx_str_rbtree_insert_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
-{
- ngx_str_node_t *n, *t;
- ngx_rbtree_node_t **p;
-
- for ( ;; ) {
-
- n = (ngx_str_node_t *) node;
- t = (ngx_str_node_t *) temp;
-
- if (node->key != temp->key) {
-
- p = (node->key < temp->key) ? &temp->left : &temp->right;
-
- } else if (n->str.len != t->str.len) {
-
- p = (n->str.len < t->str.len) ? &temp->left : &temp->right;
-
- } else {
- p = (ngx_memcmp(n->str.data, t->str.data, n->str.len) < 0)
- ? &temp->left : &temp->right;
- }
-
- if (*p == sentinel) {
- break;
- }
-
- temp = *p;
- }
-
- *p = node;
- node->parent = temp;
- node->left = sentinel;
- node->right = sentinel;
- ngx_rbt_red(node);
-}
-
-
-ngx_str_node_t *
-ngx_str_rbtree_lookup(ngx_rbtree_t *rbtree, ngx_str_t *val, uint32_t hash)
-{
- ngx_int_t rc;
- ngx_str_node_t *n;
- ngx_rbtree_node_t *node, *sentinel;
-
- node = rbtree->root;
- sentinel = rbtree->sentinel;
-
- while (node != sentinel) {
-
- n = (ngx_str_node_t *) node;
-
- if (hash != node->key) {
- node = (hash < node->key) ? node->left : node->right;
- continue;
- }
-
- if (val->len != n->str.len) {
- node = (val->len < n->str.len) ? node->left : node->right;
- continue;
- }
-
- rc = ngx_memcmp(val->data, n->str.data, val->len);
-
- if (rc < 0) {
- node = node->left;
- continue;
- }
-
- if (rc > 0) {
- node = node->right;
- continue;
- }
-
- return n;
- }
-
- return NULL;
-}
-
-
-/* ngx_sort() is implemented as insertion sort because we need stable sort */
-
-void
-ngx_sort(void *base, size_t n, size_t size,
- ngx_int_t (*cmp)(const void *, const void *))
-{
- u_char *p1, *p2, *p;
-
- p = ngx_alloc(size, ngx_cycle->log);
- if (p == NULL) {
- return;
- }
-
- for (p1 = (u_char *) base + size;
- p1 < (u_char *) base + n * size;
- p1 += size)
- {
- ngx_memcpy(p, p1, size);
-
- for (p2 = p1;
- p2 > (u_char *) base && cmp(p2 - size, p) > 0;
- p2 -= size)
- {
- ngx_memcpy(p2, p2 - size, size);
- }
-
- ngx_memcpy(p2, p, size);
- }
-
- ngx_free(p);
-}
-
-
-#if (NGX_MEMCPY_LIMIT)
-
-void *
-ngx_memcpy(void *dst, const void *src, size_t n)
-{
- if (n > NGX_MEMCPY_LIMIT) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "memcpy %uz bytes", n);
- ngx_debug_point();
- }
-
- return memcpy(dst, src, n);
-}
-
-#endif
-
-void
-ngx_strip_chroot(ngx_str_t *path)
-{
- int plen;
- u_char *prefix;
-
- if (ngx_prefix)
- prefix = ngx_prefix;
- else
- prefix = NGX_PREFIX;
-
- if (prefix[strlen(prefix) - 1] == '/')
- plen = strlen(prefix) - 1;
- else
- plen = strlen(prefix);
-
- if (!ngx_strncmp(path->data, prefix, strlen(prefix))) {
- char *x, *buf = malloc(path->len);
- x = ngx_cpystrn(buf, path->data + plen, path->len);
- path->len = (x - buf);
- path->data = buf;
- }
-}
diff --git a/usr.sbin/nginx/src/core/ngx_string.h b/usr.sbin/nginx/src/core/ngx_string.h
deleted file mode 100644
index dc0be5b5532..00000000000
--- a/usr.sbin/nginx/src/core/ngx_string.h
+++ /dev/null
@@ -1,234 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_STRING_H_INCLUDED_
-#define _NGX_STRING_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef struct {
- size_t len;
- u_char *data;
-} ngx_str_t;
-
-
-typedef struct {
- ngx_str_t key;
- ngx_str_t value;
-} ngx_keyval_t;
-
-
-typedef struct {
- unsigned len:28;
-
- unsigned valid:1;
- unsigned no_cacheable:1;
- unsigned not_found:1;
- unsigned escape:1;
-
- u_char *data;
-} ngx_variable_value_t;
-
-
-#define ngx_string(str) { sizeof(str) - 1, (u_char *) str }
-#define ngx_null_string { 0, NULL }
-#define ngx_str_set(str, text) \
- (str)->len = sizeof(text) - 1; (str)->data = (u_char *) text
-#define ngx_str_null(str) (str)->len = 0; (str)->data = NULL
-
-
-#define ngx_tolower(c) (u_char) ((c >= 'A' && c <= 'Z') ? (c | 0x20) : c)
-#define ngx_toupper(c) (u_char) ((c >= 'a' && c <= 'z') ? (c & ~0x20) : c)
-
-void ngx_strlow(u_char *dst, u_char *src, size_t n);
-
-
-#define ngx_strncmp(s1, s2, n) strncmp((const char *) s1, (const char *) s2, n)
-
-
-/* msvc and icc7 compile strcmp() to inline loop */
-#define ngx_strcmp(s1, s2) strcmp((const char *) s1, (const char *) s2)
-
-
-#define ngx_strstr(s1, s2) strstr((const char *) s1, (const char *) s2)
-#define ngx_strlen(s) strlen((const char *) s)
-
-#define ngx_strchr(s1, c) strchr((const char *) s1, (int) c)
-
-static ngx_inline u_char *
-ngx_strlchr(u_char *p, u_char *last, u_char c)
-{
- while (p < last) {
-
- if (*p == c) {
- return p;
- }
-
- p++;
- }
-
- return NULL;
-}
-
-
-/*
- * msvc and icc7 compile memset() to the inline "rep stos"
- * while ZeroMemory() and bzero() are the calls.
- * icc7 may also inline several mov's of a zeroed register for small blocks.
- */
-#define ngx_memzero(buf, n) (void) memset(buf, 0, n)
-#define ngx_memset(buf, c, n) (void) memset(buf, c, n)
-
-
-#if (NGX_MEMCPY_LIMIT)
-
-void *ngx_memcpy(void *dst, const void *src, size_t n);
-#define ngx_cpymem(dst, src, n) (((u_char *) ngx_memcpy(dst, src, n)) + (n))
-
-#else
-
-/*
- * gcc3, msvc, and icc7 compile memcpy() to the inline "rep movs".
- * gcc3 compiles memcpy(d, s, 4) to the inline "mov"es.
- * icc8 compile memcpy(d, s, 4) to the inline "mov"es or XMM moves.
- */
-#define ngx_memcpy(dst, src, n) (void) memcpy(dst, src, n)
-#define ngx_cpymem(dst, src, n) (((u_char *) memcpy(dst, src, n)) + (n))
-
-#endif
-
-
-#if ( __INTEL_COMPILER >= 800 )
-
-/*
- * the simple inline cycle copies the variable length strings up to 16
- * bytes faster than icc8 autodetecting _intel_fast_memcpy()
- */
-
-static ngx_inline u_char *
-ngx_copy(u_char *dst, u_char *src, size_t len)
-{
- if (len < 17) {
-
- while (len) {
- *dst++ = *src++;
- len--;
- }
-
- return dst;
-
- } else {
- return ngx_cpymem(dst, src, len);
- }
-}
-
-#else
-
-#define ngx_copy ngx_cpymem
-
-#endif
-
-
-#define ngx_memmove(dst, src, n) (void) memmove(dst, src, n)
-#define ngx_movemem(dst, src, n) (((u_char *) memmove(dst, src, n)) + (n))
-
-
-/* msvc and icc7 compile memcmp() to the inline loop */
-#define ngx_memcmp(s1, s2, n) memcmp((const char *) s1, (const char *) s2, n)
-
-
-u_char *ngx_cpystrn(u_char *dst, u_char *src, size_t n);
-u_char *ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src);
-u_char * ngx_cdecl ngx_sprintf(u_char *buf, const char *fmt, ...);
-u_char * ngx_cdecl ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...);
-u_char * ngx_cdecl ngx_slprintf(u_char *buf, u_char *last, const char *fmt,
- ...);
-u_char *ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args);
-#define ngx_vsnprintf(buf, max, fmt, args) \
- ngx_vslprintf(buf, buf + (max), fmt, 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);
-u_char *ngx_strlcasestrn(u_char *s1, u_char *last, u_char *s2, size_t n);
-
-ngx_int_t ngx_rstrncmp(u_char *s1, u_char *s2, size_t n);
-ngx_int_t ngx_rstrncasecmp(u_char *s1, u_char *s2, size_t n);
-ngx_int_t ngx_memn2cmp(u_char *s1, u_char *s2, size_t n1, size_t n2);
-ngx_int_t ngx_dns_strcmp(u_char *s1, u_char *s2);
-ngx_int_t ngx_filename_cmp(u_char *s1, u_char *s2, size_t n);
-
-ngx_int_t ngx_atoi(u_char *line, size_t n);
-ngx_int_t ngx_atofp(u_char *line, size_t n, size_t point);
-ssize_t ngx_atosz(u_char *line, size_t n);
-off_t ngx_atoof(u_char *line, size_t n);
-time_t ngx_atotm(u_char *line, size_t n);
-ngx_int_t ngx_hextoi(u_char *line, size_t n);
-
-u_char *ngx_hex_dump(u_char *dst, u_char *src, size_t len);
-
-
-#define ngx_base64_encoded_length(len) (((len + 2) / 3) * 4)
-#define ngx_base64_decoded_length(len) (((len + 3) / 4) * 3)
-
-void ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src);
-void ngx_encode_base64url(ngx_str_t *dst, ngx_str_t *src);
-ngx_int_t ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src);
-ngx_int_t ngx_decode_base64url(ngx_str_t *dst, ngx_str_t *src);
-
-uint32_t ngx_utf8_decode(u_char **p, size_t n);
-size_t ngx_utf8_length(u_char *p, size_t n);
-u_char *ngx_utf8_cpystrn(u_char *dst, u_char *src, size_t n, size_t len);
-
-
-#define NGX_ESCAPE_URI 0
-#define NGX_ESCAPE_ARGS 1
-#define NGX_ESCAPE_URI_COMPONENT 2
-#define NGX_ESCAPE_HTML 3
-#define NGX_ESCAPE_REFRESH 4
-#define NGX_ESCAPE_MEMCACHED 5
-#define NGX_ESCAPE_MAIL_AUTH 6
-
-#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);
-
-
-typedef struct {
- ngx_rbtree_node_t node;
- ngx_str_t str;
-} ngx_str_node_t;
-
-
-void ngx_str_rbtree_insert_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
-ngx_str_node_t *ngx_str_rbtree_lookup(ngx_rbtree_t *rbtree, ngx_str_t *name,
- uint32_t hash);
-
-
-void ngx_sort(void *base, size_t n, size_t size,
- ngx_int_t (*cmp)(const void *, const void *));
-#define ngx_qsort qsort
-
-
-#define ngx_value_helper(n) #n
-#define ngx_value(n) ngx_value_helper(n)
-
-void ngx_strip_chroot(ngx_str_t *root);
-
-#endif /* _NGX_STRING_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_syslog.c b/usr.sbin/nginx/src/core/ngx_syslog.c
deleted file mode 100644
index 7c5de38b6cb..00000000000
--- a/usr.sbin/nginx/src/core/ngx_syslog.c
+++ /dev/null
@@ -1,342 +0,0 @@
-
-/*
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#define NGX_SYSLOG_MAX_STR \
- NGX_MAX_ERROR_STR + sizeof("<255>Jan 01 00:00:00 ") - 1 \
- + (NGX_MAXHOSTNAMELEN - 1) + 1 /* space */ \
- + 32 /* tag */ + 2 /* colon, space */
-
-
-static char *ngx_syslog_parse_args(ngx_conf_t *cf, ngx_syslog_peer_t *peer);
-static ngx_int_t ngx_syslog_init_peer(ngx_syslog_peer_t *peer);
-static void ngx_syslog_cleanup(void *data);
-
-
-static char *facilities[] = {
- "kern", "user", "mail", "daemon", "auth", "intern", "lpr", "news", "uucp",
- "clock", "authpriv", "ftp", "ntp", "audit", "alert", "cron", "local0",
- "local1", "local2", "local3", "local4", "local5", "local6", "local7",
- NULL
-};
-
-/* note 'error/warn' like in nginx.conf, not 'err/warning' */
-static char *severities[] = {
- "emerg", "alert", "crit", "error", "warn", "notice", "info", "debug", NULL
-};
-
-static ngx_log_t ngx_syslog_dummy_log;
-static ngx_event_t ngx_syslog_dummy_event;
-
-
-char *
-ngx_syslog_process_conf(ngx_conf_t *cf, ngx_syslog_peer_t *peer)
-{
- peer->pool = cf->pool;
- peer->facility = NGX_CONF_UNSET_UINT;
- peer->severity = NGX_CONF_UNSET_UINT;
-
- if (ngx_syslog_parse_args(cf, peer) != NGX_CONF_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (peer->server.sockaddr == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "no syslog server specified");
- return NGX_CONF_ERROR;
- }
-
- if (peer->facility == NGX_CONF_UNSET_UINT) {
- peer->facility = 23; /* local7 */
- }
-
- if (peer->severity == NGX_CONF_UNSET_UINT) {
- peer->severity = 6; /* info */
- }
-
- if (peer->tag.data == NULL) {
- ngx_str_set(&peer->tag, "nginx");
- }
-
- peer->conn.fd = (ngx_socket_t) -1;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_syslog_parse_args(ngx_conf_t *cf, ngx_syslog_peer_t *peer)
-{
- u_char *p, *comma, c;
- size_t len;
- ngx_str_t *value;
- ngx_url_t u;
- ngx_uint_t i;
-
- value = cf->args->elts;
-
- p = value[1].data + sizeof("syslog:") - 1;
-
- for ( ;; ) {
- comma = (u_char *) ngx_strchr(p, ',');
-
- if (comma != NULL) {
- len = comma - p;
- *comma = '\0';
-
- } else {
- len = value[1].data + value[1].len - p;
- }
-
- if (ngx_strncmp(p, "server=", 7) == 0) {
-
- if (peer->server.sockaddr != NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate syslog \"server\"");
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- u.url.data = p + 7;
- u.url.len = len - 7;
- u.default_port = 514;
-
- if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
- if (u.err) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "%s in syslog server \"%V\"",
- u.err, &u.url);
- }
-
- return NGX_CONF_ERROR;
- }
-
- peer->server = u.addrs[0];
-
- } else if (ngx_strncmp(p, "facility=", 9) == 0) {
-
- if (peer->facility != NGX_CONF_UNSET_UINT) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate syslog \"facility\"");
- return NGX_CONF_ERROR;
- }
-
- for (i = 0; facilities[i] != NULL; i++) {
-
- if (ngx_strcmp(p + 9, facilities[i]) == 0) {
- peer->facility = i;
- goto next;
- }
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unknown syslog facility \"%s\"", p + 9);
- return NGX_CONF_ERROR;
-
- } else if (ngx_strncmp(p, "severity=", 9) == 0) {
-
- if (peer->severity != NGX_CONF_UNSET_UINT) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate syslog \"severity\"");
- return NGX_CONF_ERROR;
- }
-
- for (i = 0; severities[i] != NULL; i++) {
-
- if (ngx_strcmp(p + 9, severities[i]) == 0) {
- peer->severity = i;
- goto next;
- }
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unknown syslog severity \"%s\"", p + 9);
- return NGX_CONF_ERROR;
-
- } else if (ngx_strncmp(p, "tag=", 4) == 0) {
-
- if (peer->tag.data != NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate syslog \"tag\"");
- return NGX_CONF_ERROR;
- }
-
- /*
- * RFC 3164: the TAG is a string of ABNF alphanumeric characters
- * that MUST NOT exceed 32 characters.
- */
- if (len - 4 > 32) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "syslog tag length exceeds 32");
- return NGX_CONF_ERROR;
- }
-
- for (i = 4; i < len; i++) {
- c = ngx_tolower(p[i]);
-
- if (c < '0' || (c > '9' && c < 'a') || c > 'z') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "syslog \"tag\" only allows "
- "alphanumeric characters");
- return NGX_CONF_ERROR;
- }
- }
-
- peer->tag.data = p + 4;
- peer->tag.len = len - 4;
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unknown syslog parameter \"%s\"", p);
- return NGX_CONF_ERROR;
- }
-
- next:
-
- if (comma == NULL) {
- break;
- }
-
- p = comma + 1;
- }
-
- return NGX_CONF_OK;
-}
-
-
-u_char *
-ngx_syslog_add_header(ngx_syslog_peer_t *peer, u_char *buf)
-{
- ngx_uint_t pri;
-
- pri = peer->facility * 8 + peer->severity;
-
- return ngx_sprintf(buf, "<%ui>%V %V %V: ", pri, &ngx_cached_syslog_time,
- &ngx_cycle->hostname, &peer->tag);
-}
-
-
-void
-ngx_syslog_writer(ngx_log_t *log, ngx_uint_t level, u_char *buf,
- size_t len)
-{
- u_char *p, msg[NGX_SYSLOG_MAX_STR];
- ngx_uint_t head_len;
- ngx_syslog_peer_t *peer;
-
- peer = log->wdata;
-
- if (peer->processing) {
- return;
- }
-
- peer->processing = 1;
- peer->severity = level - 1;
-
- p = ngx_syslog_add_header(peer, msg);
- head_len = p - msg;
-
- len -= NGX_LINEFEED_SIZE;
-
- if (len > NGX_SYSLOG_MAX_STR - head_len) {
- len = NGX_SYSLOG_MAX_STR - head_len;
- }
-
- p = ngx_snprintf(p, len, "%s", buf);
-
- (void) ngx_syslog_send(peer, msg, p - msg);
-
- peer->processing = 0;
-}
-
-
-ssize_t
-ngx_syslog_send(ngx_syslog_peer_t *peer, u_char *buf, size_t len)
-{
- if (peer->conn.fd == (ngx_socket_t) -1) {
- if (ngx_syslog_init_peer(peer) != NGX_OK) {
- return NGX_ERROR;
- }
- }
-
- if (ngx_send) {
- return ngx_send(&peer->conn, buf, len);
-
- } else {
- /* event module has not yet set ngx_io */
- return ngx_os_io.send(&peer->conn, buf, len);
- }
-}
-
-
-static ngx_int_t
-ngx_syslog_init_peer(ngx_syslog_peer_t *peer)
-{
- ngx_socket_t fd;
- ngx_pool_cleanup_t *cln;
-
- peer->conn.read = &ngx_syslog_dummy_event;
- peer->conn.write = &ngx_syslog_dummy_event;
- peer->conn.log = &ngx_syslog_dummy_log;
-
- ngx_syslog_dummy_event.log = &ngx_syslog_dummy_log;
-
- fd = ngx_socket(peer->server.sockaddr->sa_family, SOCK_DGRAM, 0);
- if (fd == (ngx_socket_t) -1) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
- ngx_socket_n " failed");
- return NGX_ERROR;
- }
-
- if (ngx_nonblocking(fd) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
- ngx_nonblocking_n " failed");
- goto failed;
- }
-
- if (connect(fd, peer->server.sockaddr, peer->server.socklen) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
- "connect() failed");
- goto failed;
- }
-
- cln = ngx_pool_cleanup_add(peer->pool, 0);
- if (cln == NULL) {
- goto failed;
- }
-
- cln->data = peer;
- cln->handler = ngx_syslog_cleanup;
-
- peer->conn.fd = fd;
- return NGX_OK;
-
-failed:
-
- if (ngx_close_socket(fd) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
- ngx_close_socket_n " failed");
- }
-
- return NGX_ERROR;
-}
-
-
-static void
-ngx_syslog_cleanup(void *data)
-{
- ngx_syslog_peer_t *peer = data;
-
- if (ngx_close_socket(peer->conn.fd) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
- ngx_close_socket_n " failed");
- }
-}
diff --git a/usr.sbin/nginx/src/core/ngx_syslog.h b/usr.sbin/nginx/src/core/ngx_syslog.h
deleted file mode 100644
index 92d47d5f5fd..00000000000
--- a/usr.sbin/nginx/src/core/ngx_syslog.h
+++ /dev/null
@@ -1,30 +0,0 @@
-
-/*
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_SYSLOG_H_INCLUDED_
-#define _NGX_SYSLOG_H_INCLUDED_
-
-
-typedef struct {
- ngx_pool_t *pool;
- ngx_uint_t facility;
- ngx_uint_t severity;
- ngx_str_t tag;
-
- ngx_addr_t server;
- ngx_connection_t conn;
- ngx_uint_t processing; /* unsigned processing:1; */
-} ngx_syslog_peer_t;
-
-
-char *ngx_syslog_process_conf(ngx_conf_t *cf, ngx_syslog_peer_t *peer);
-u_char *ngx_syslog_add_header(ngx_syslog_peer_t *peer, u_char *buf);
-void ngx_syslog_writer(ngx_log_t *log, ngx_uint_t level, u_char *buf,
- size_t len);
-ssize_t ngx_syslog_send(ngx_syslog_peer_t *peer, u_char *buf, size_t len);
-
-
-#endif /* _NGX_SYSLOG_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/core/ngx_times.c b/usr.sbin/nginx/src/core/ngx_times.c
deleted file mode 100644
index 595c1224d0e..00000000000
--- a/usr.sbin/nginx/src/core/ngx_times.c
+++ /dev/null
@@ -1,428 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/*
- * The time may be updated by signal handler or by several threads.
- * The time update operations are rare and require to hold the ngx_time_lock.
- * The time read operations are frequent, so they are lock-free and get time
- * values and strings from the current slot. Thus thread may get the corrupted
- * values only if it is preempted while copying and then it is not scheduled
- * to run more than NGX_TIME_SLOTS seconds.
- */
-
-#define NGX_TIME_SLOTS 64
-
-static ngx_uint_t slot;
-static ngx_atomic_t ngx_time_lock;
-
-volatile ngx_msec_t ngx_current_msec;
-volatile ngx_time_t *ngx_cached_time;
-volatile ngx_str_t ngx_cached_err_log_time;
-volatile ngx_str_t ngx_cached_http_time;
-volatile ngx_str_t ngx_cached_http_log_time;
-volatile ngx_str_t ngx_cached_http_log_iso8601;
-volatile ngx_str_t ngx_cached_syslog_time;
-
-#if !(NGX_WIN32)
-
-/*
- * localtime() and localtime_r() are not Async-Signal-Safe functions, therefore,
- * they must not be called by a signal handler, so we use the cached
- * GMT offset value. Fortunately the value is changed only two times a year.
- */
-
-static ngx_int_t cached_gmtoff;
-#endif
-
-static ngx_time_t cached_time[NGX_TIME_SLOTS];
-static u_char cached_err_log_time[NGX_TIME_SLOTS]
- [sizeof("1970/09/28 12:00:00")];
-static u_char cached_http_time[NGX_TIME_SLOTS]
- [sizeof("Mon, 28 Sep 1970 06:00:00 GMT")];
-static u_char cached_http_log_time[NGX_TIME_SLOTS]
- [sizeof("28/Sep/1970:12:00:00 +0600")];
-static u_char cached_http_log_iso8601[NGX_TIME_SLOTS]
- [sizeof("1970-09-28T12:00:00+06:00")];
-static u_char cached_syslog_time[NGX_TIME_SLOTS]
- [sizeof("Sep 28 12:00:00")];
-
-
-static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
-static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
-void
-ngx_time_init(void)
-{
- ngx_cached_err_log_time.len = sizeof("1970/09/28 12:00:00") - 1;
- ngx_cached_http_time.len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1;
- ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1;
- ngx_cached_http_log_iso8601.len = sizeof("1970-09-28T12:00:00+06:00") - 1;
- ngx_cached_syslog_time.len = sizeof("Sep 28 12:00:00") - 1;
-
- ngx_cached_time = &cached_time[0];
-
- ngx_time_update();
-}
-
-
-void
-ngx_time_update(void)
-{
- u_char *p0, *p1, *p2, *p3, *p4;
- ngx_tm_t tm, gmt;
- time_t sec;
- ngx_uint_t msec;
- ngx_time_t *tp;
- struct timeval tv;
-
- if (!ngx_trylock(&ngx_time_lock)) {
- return;
- }
-
- ngx_gettimeofday(&tv);
-
- sec = tv.tv_sec;
- msec = tv.tv_usec / 1000;
-
- ngx_current_msec = (ngx_msec_t) sec * 1000 + msec;
-
- tp = &cached_time[slot];
-
- if (tp->sec == sec) {
- tp->msec = msec;
- ngx_unlock(&ngx_time_lock);
- return;
- }
-
- if (slot == NGX_TIME_SLOTS - 1) {
- slot = 0;
- } else {
- slot++;
- }
-
- tp = &cached_time[slot];
-
- tp->sec = sec;
- tp->msec = msec;
-
- ngx_gmtime(sec, &gmt);
-
-
- p0 = &cached_http_time[slot][0];
-
- (void) ngx_sprintf(p0, "%s, %02d %s %4d %02d:%02d:%02d GMT",
- week[gmt.ngx_tm_wday], gmt.ngx_tm_mday,
- months[gmt.ngx_tm_mon - 1], gmt.ngx_tm_year,
- gmt.ngx_tm_hour, gmt.ngx_tm_min, gmt.ngx_tm_sec);
-
-#if (NGX_HAVE_GETTIMEZONE)
-
- tp->gmtoff = ngx_gettimezone();
- ngx_gmtime(sec + tp->gmtoff * 60, &tm);
-
-#elif (NGX_HAVE_GMTOFF)
-
- ngx_localtime(sec, &tm);
- cached_gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);
- tp->gmtoff = cached_gmtoff;
-
-#else
-
- ngx_localtime(sec, &tm);
- cached_gmtoff = ngx_timezone(tm.ngx_tm_isdst);
- tp->gmtoff = cached_gmtoff;
-
-#endif
-
-
- p1 = &cached_err_log_time[slot][0];
-
- (void) ngx_sprintf(p1, "%4d/%02d/%02d %02d:%02d:%02d",
- tm.ngx_tm_year, tm.ngx_tm_mon,
- tm.ngx_tm_mday, tm.ngx_tm_hour,
- tm.ngx_tm_min, tm.ngx_tm_sec);
-
-
- p2 = &cached_http_log_time[slot][0];
-
- (void) ngx_sprintf(p2, "%02d/%s/%d:%02d:%02d:%02d %c%02d%02d",
- tm.ngx_tm_mday, months[tm.ngx_tm_mon - 1],
- tm.ngx_tm_year, tm.ngx_tm_hour,
- tm.ngx_tm_min, tm.ngx_tm_sec,
- tp->gmtoff < 0 ? '-' : '+',
- ngx_abs(tp->gmtoff / 60), ngx_abs(tp->gmtoff % 60));
-
- p3 = &cached_http_log_iso8601[slot][0];
-
- (void) ngx_sprintf(p3, "%4d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
- tm.ngx_tm_year, tm.ngx_tm_mon,
- tm.ngx_tm_mday, tm.ngx_tm_hour,
- tm.ngx_tm_min, tm.ngx_tm_sec,
- tp->gmtoff < 0 ? '-' : '+',
- ngx_abs(tp->gmtoff / 60), ngx_abs(tp->gmtoff % 60));
-
- p4 = &cached_syslog_time[slot][0];
-
- (void) ngx_sprintf(p4, "%s %2d %02d:%02d:%02d",
- months[tm.ngx_tm_mon - 1], tm.ngx_tm_mday,
- tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec);
-
- ngx_memory_barrier();
-
- ngx_cached_time = tp;
- ngx_cached_http_time.data = p0;
- ngx_cached_err_log_time.data = p1;
- ngx_cached_http_log_time.data = p2;
- ngx_cached_http_log_iso8601.data = p3;
- ngx_cached_syslog_time.data = p4;
-
- ngx_unlock(&ngx_time_lock);
-}
-
-
-#if !(NGX_WIN32)
-
-void
-ngx_time_sigsafe_update(void)
-{
- u_char *p, *p2;
- ngx_tm_t tm;
- time_t sec;
- ngx_time_t *tp;
- struct timeval tv;
-
- if (!ngx_trylock(&ngx_time_lock)) {
- return;
- }
-
- ngx_gettimeofday(&tv);
-
- sec = tv.tv_sec;
-
- tp = &cached_time[slot];
-
- if (tp->sec == sec) {
- ngx_unlock(&ngx_time_lock);
- return;
- }
-
- if (slot == NGX_TIME_SLOTS - 1) {
- slot = 0;
- } else {
- slot++;
- }
-
- tp = &cached_time[slot];
-
- tp->sec = 0;
-
- ngx_gmtime(sec + cached_gmtoff * 60, &tm);
-
- p = &cached_err_log_time[slot][0];
-
- (void) ngx_sprintf(p, "%4d/%02d/%02d %02d:%02d:%02d",
- tm.ngx_tm_year, tm.ngx_tm_mon,
- tm.ngx_tm_mday, tm.ngx_tm_hour,
- tm.ngx_tm_min, tm.ngx_tm_sec);
-
- p2 = &cached_syslog_time[slot][0];
-
- (void) ngx_sprintf(p2, "%s %2d %02d:%02d:%02d",
- months[tm.ngx_tm_mon - 1], tm.ngx_tm_mday,
- tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec);
-
- ngx_memory_barrier();
-
- ngx_cached_err_log_time.data = p;
- ngx_cached_syslog_time.data = p2;
-
- ngx_unlock(&ngx_time_lock);
-}
-
-#endif
-
-
-u_char *
-ngx_http_time(u_char *buf, time_t t)
-{
- ngx_tm_t tm;
-
- ngx_gmtime(t, &tm);
-
- return ngx_sprintf(buf, "%s, %02d %s %4d %02d:%02d:%02d GMT",
- week[tm.ngx_tm_wday],
- tm.ngx_tm_mday,
- months[tm.ngx_tm_mon - 1],
- tm.ngx_tm_year,
- tm.ngx_tm_hour,
- tm.ngx_tm_min,
- tm.ngx_tm_sec);
-}
-
-
-u_char *
-ngx_http_cookie_time(u_char *buf, time_t t)
-{
- ngx_tm_t tm;
-
- ngx_gmtime(t, &tm);
-
- /*
- * Netscape 3.x does not understand 4-digit years at all and
- * 2-digit years more than "37"
- */
-
- return ngx_sprintf(buf,
- (tm.ngx_tm_year > 2037) ?
- "%s, %02d-%s-%d %02d:%02d:%02d GMT":
- "%s, %02d-%s-%02d %02d:%02d:%02d GMT",
- week[tm.ngx_tm_wday],
- tm.ngx_tm_mday,
- months[tm.ngx_tm_mon - 1],
- (tm.ngx_tm_year > 2037) ? tm.ngx_tm_year:
- tm.ngx_tm_year % 100,
- tm.ngx_tm_hour,
- tm.ngx_tm_min,
- tm.ngx_tm_sec);
-}
-
-
-void
-ngx_gmtime(time_t t, ngx_tm_t *tp)
-{
- ngx_int_t yday;
- ngx_uint_t n, sec, min, hour, mday, mon, year, wday, days, leap;
-
- /* the calculation is valid for positive time_t only */
-
- n = (ngx_uint_t) t;
-
- days = n / 86400;
-
- /* January 1, 1970 was Thursday */
-
- wday = (4 + days) % 7;
-
- n %= 86400;
- hour = n / 3600;
- n %= 3600;
- min = n / 60;
- sec = n % 60;
-
- /*
- * the algorithm based on Gauss' formula,
- * see src/http/ngx_http_parse_time.c
- */
-
- /* days since March 1, 1 BC */
- days = days - (31 + 28) + 719527;
-
- /*
- * The "days" should be adjusted to 1 only, however, some March 1st's go
- * to previous year, so we adjust them to 2. This causes also shift of the
- * last February days to next year, but we catch the case when "yday"
- * becomes negative.
- */
-
- year = (days + 2) * 400 / (365 * 400 + 100 - 4 + 1);
-
- yday = days - (365 * year + year / 4 - year / 100 + year / 400);
-
- if (yday < 0) {
- leap = (year % 4 == 0) && (year % 100 || (year % 400 == 0));
- yday = 365 + leap + yday;
- year--;
- }
-
- /*
- * The empirical formula that maps "yday" to month.
- * There are at least 10 variants, some of them are:
- * mon = (yday + 31) * 15 / 459
- * mon = (yday + 31) * 17 / 520
- * mon = (yday + 31) * 20 / 612
- */
-
- mon = (yday + 31) * 10 / 306;
-
- /* the Gauss' formula that evaluates days before the month */
-
- mday = yday - (367 * mon / 12 - 30) + 1;
-
- if (yday >= 306) {
-
- year++;
- mon -= 10;
-
- /*
- * there is no "yday" in Win32 SYSTEMTIME
- *
- * yday -= 306;
- */
-
- } else {
-
- mon += 2;
-
- /*
- * there is no "yday" in Win32 SYSTEMTIME
- *
- * yday += 31 + 28 + leap;
- */
- }
-
- tp->ngx_tm_sec = (ngx_tm_sec_t) sec;
- tp->ngx_tm_min = (ngx_tm_min_t) min;
- tp->ngx_tm_hour = (ngx_tm_hour_t) hour;
- tp->ngx_tm_mday = (ngx_tm_mday_t) mday;
- tp->ngx_tm_mon = (ngx_tm_mon_t) mon;
- tp->ngx_tm_year = (ngx_tm_year_t) year;
- tp->ngx_tm_wday = (ngx_tm_wday_t) wday;
-}
-
-
-time_t
-ngx_next_time(time_t when)
-{
- time_t now, next;
- struct tm tm;
-
- now = ngx_time();
-
- ngx_libc_localtime(now, &tm);
-
- tm.tm_hour = (int) (when / 3600);
- when %= 3600;
- tm.tm_min = (int) (when / 60);
- tm.tm_sec = (int) (when % 60);
-
- next = mktime(&tm);
-
- if (next == -1) {
- return -1;
- }
-
- if (next - now > 0) {
- return next;
- }
-
- tm.tm_mday++;
-
- /* mktime() should normalize a date (Jan 32, etc) */
-
- next = mktime(&tm);
-
- if (next != -1) {
- return next;
- }
-
- return -1;
-}
diff --git a/usr.sbin/nginx/src/core/ngx_times.h b/usr.sbin/nginx/src/core/ngx_times.h
deleted file mode 100644
index 94aedcdc94c..00000000000
--- a/usr.sbin/nginx/src/core/ngx_times.h
+++ /dev/null
@@ -1,52 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_TIMES_H_INCLUDED_
-#define _NGX_TIMES_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef struct {
- time_t sec;
- ngx_uint_t msec;
- ngx_int_t gmtoff;
-} ngx_time_t;
-
-
-void ngx_time_init(void);
-void ngx_time_update(void);
-void ngx_time_sigsafe_update(void);
-u_char *ngx_http_time(u_char *buf, time_t t);
-u_char *ngx_http_cookie_time(u_char *buf, time_t t);
-void ngx_gmtime(time_t t, ngx_tm_t *tp);
-
-time_t ngx_next_time(time_t when);
-#define ngx_next_time_n "mktime()"
-
-
-extern volatile ngx_time_t *ngx_cached_time;
-
-#define ngx_time() ngx_cached_time->sec
-#define ngx_timeofday() (ngx_time_t *) ngx_cached_time
-
-extern volatile ngx_str_t ngx_cached_err_log_time;
-extern volatile ngx_str_t ngx_cached_http_time;
-extern volatile ngx_str_t ngx_cached_http_log_time;
-extern volatile ngx_str_t ngx_cached_http_log_iso8601;
-extern volatile ngx_str_t ngx_cached_syslog_time;
-
-/*
- * milliseconds elapsed since epoch and truncated to ngx_msec_t,
- * used in event timers
- */
-extern volatile ngx_msec_t ngx_current_msec;
-
-
-#endif /* _NGX_TIMES_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/event/modules/ngx_aio_module.c b/usr.sbin/nginx/src/event/modules/ngx_aio_module.c
deleted file mode 100644
index c881319d179..00000000000
--- a/usr.sbin/nginx/src/event/modules/ngx_aio_module.c
+++ /dev/null
@@ -1,171 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-extern ngx_event_module_t ngx_kqueue_module_ctx;
-
-
-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, 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);
-
-
-ngx_os_io_t ngx_os_aio = {
- ngx_aio_read,
- ngx_aio_read_chain,
- NULL,
- ngx_aio_write,
- ngx_aio_write_chain,
- 0
-};
-
-
-static ngx_str_t aio_name = ngx_string("aio");
-
-ngx_event_module_t ngx_aio_module_ctx = {
- &aio_name,
- NULL, /* create configuration */
- NULL, /* init configuration */
-
- {
- ngx_aio_add_event, /* add an event */
- ngx_aio_del_event, /* delete an event */
- NULL, /* enable an event */
- NULL, /* disable an event */
- NULL, /* add an connection */
- ngx_aio_del_connection, /* delete an connection */
- NULL, /* process the changes */
- ngx_aio_process_events, /* process the events */
- ngx_aio_init, /* init the events */
- ngx_aio_done /* done the events */
- }
-
-};
-
-ngx_module_t ngx_aio_module = {
- NGX_MODULE_V1,
- &ngx_aio_module_ctx, /* module context */
- NULL, /* module directives */
- NGX_EVENT_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-#if (NGX_HAVE_KQUEUE)
-
-static ngx_int_t
-ngx_aio_init(ngx_cycle_t *cycle, ngx_msec_t timer)
-{
- if (ngx_kqueue_module_ctx.actions.init(cycle, timer) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- ngx_io = ngx_os_aio;
-
- ngx_event_flags = NGX_USE_AIO_EVENT;
- ngx_event_actions = ngx_aio_module_ctx.actions;
-
-
- return NGX_OK;
-}
-
-
-static void
-ngx_aio_done(ngx_cycle_t *cycle)
-{
- ngx_kqueue_module_ctx.actions.done(cycle);
-}
-
-
-/* the event adding and deleting are needed for the listening sockets */
-
-static ngx_int_t
-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, 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, ngx_uint_t flags)
-{
- int rc;
-
- if (c->read->active == 0 && c->write->active == 0) {
- return NGX_OK;
- }
-
- if (flags & NGX_CLOSE_EVENT) {
- return NGX_OK;
- }
-
- rc = aio_cancel(c->fd, NULL);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "aio_cancel: %d", rc);
-
- if (rc == AIO_CANCELED) {
- c->read->active = 0;
- c->write->active = 0;
- return NGX_OK;
- }
-
- if (rc == AIO_ALLDONE) {
- c->read->active = 0;
- c->write->active = 0;
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "aio_cancel() returned AIO_ALLDONE");
- return NGX_OK;
- }
-
- if (rc == -1) {
- ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
- "aio_cancel() failed");
- return NGX_ERROR;
- }
-
- if (rc == AIO_NOTCANCELED) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "aio_cancel() returned AIO_NOTCANCELED");
-
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_aio_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
-{
- return ngx_kqueue_module_ctx.actions.process_events(cycle, timer, flags);
-}
-
-#endif /* NGX_HAVE_KQUEUE */
diff --git a/usr.sbin/nginx/src/event/modules/ngx_devpoll_module.c b/usr.sbin/nginx/src/event/modules/ngx_devpoll_module.c
deleted file mode 100644
index 0506103e616..00000000000
--- a/usr.sbin/nginx/src/event/modules/ngx_devpoll_module.c
+++ /dev/null
@@ -1,575 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#if (NGX_TEST_BUILD_DEVPOLL)
-
-/* Solaris declarations */
-
-#define POLLREMOVE 0x0800
-#define DP_POLL 0xD001
-#define DP_ISPOLLED 0xD002
-
-struct dvpoll {
- struct pollfd *dp_fds;
- int dp_nfds;
- int dp_timeout;
-};
-
-#endif
-
-
-typedef struct {
- 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, 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);
-
-static void *ngx_devpoll_create_conf(ngx_cycle_t *cycle);
-static char *ngx_devpoll_init_conf(ngx_cycle_t *cycle, void *conf);
-
-static int dp = -1;
-static struct pollfd *change_list, *event_list;
-static ngx_uint_t nchanges, max_changes, nevents;
-
-static ngx_event_t **change_index;
-
-
-static ngx_str_t devpoll_name = ngx_string("/dev/poll");
-
-static ngx_command_t ngx_devpoll_commands[] = {
-
- { ngx_string("devpoll_changes"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_devpoll_conf_t, changes),
- NULL },
-
- { ngx_string("devpoll_events"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_devpoll_conf_t, events),
- NULL },
-
- ngx_null_command
-};
-
-
-ngx_event_module_t ngx_devpoll_module_ctx = {
- &devpoll_name,
- ngx_devpoll_create_conf, /* create configuration */
- ngx_devpoll_init_conf, /* init configuration */
-
- {
- ngx_devpoll_add_event, /* add an event */
- ngx_devpoll_del_event, /* delete an event */
- ngx_devpoll_add_event, /* enable an event */
- ngx_devpoll_del_event, /* disable an event */
- NULL, /* add an connection */
- NULL, /* delete an connection */
- NULL, /* process the changes */
- ngx_devpoll_process_events, /* process the events */
- ngx_devpoll_init, /* init the events */
- ngx_devpoll_done, /* done the events */
- }
-
-};
-
-ngx_module_t ngx_devpoll_module = {
- NGX_MODULE_V1,
- &ngx_devpoll_module_ctx, /* module context */
- ngx_devpoll_commands, /* module directives */
- NGX_EVENT_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_devpoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
-{
- size_t n;
- ngx_devpoll_conf_t *dpcf;
-
- dpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_devpoll_module);
-
- if (dp == -1) {
- dp = open("/dev/poll", O_RDWR);
-
- if (dp == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "open(/dev/poll) failed");
- return NGX_ERROR;
- }
- }
-
- if (max_changes < dpcf->changes) {
- if (nchanges) {
- n = nchanges * sizeof(struct pollfd);
- if (write(dp, change_list, n) != (ssize_t) n) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "write(/dev/poll) failed");
- return NGX_ERROR;
- }
-
- nchanges = 0;
- }
-
- if (change_list) {
- ngx_free(change_list);
- }
-
- change_list = ngx_alloc(sizeof(struct pollfd) * dpcf->changes,
- cycle->log);
- if (change_list == NULL) {
- return NGX_ERROR;
- }
-
- if (change_index) {
- ngx_free(change_index);
- }
-
- change_index = ngx_alloc(sizeof(ngx_event_t *) * dpcf->changes,
- cycle->log);
- if (change_index == NULL) {
- return NGX_ERROR;
- }
- }
-
- max_changes = dpcf->changes;
-
- if (nevents < dpcf->events) {
- if (event_list) {
- ngx_free(event_list);
- }
-
- event_list = ngx_alloc(sizeof(struct pollfd) * dpcf->events,
- cycle->log);
- if (event_list == NULL) {
- return NGX_ERROR;
- }
- }
-
- nevents = dpcf->events;
-
- ngx_io = ngx_os_io;
-
- ngx_event_actions = ngx_devpoll_module_ctx.actions;
-
- ngx_event_flags = NGX_USE_LEVEL_EVENT|NGX_USE_FD_EVENT;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_devpoll_done(ngx_cycle_t *cycle)
-{
- if (close(dp) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "close(/dev/poll) failed");
- }
-
- dp = -1;
-
- ngx_free(change_list);
- ngx_free(event_list);
- ngx_free(change_index);
-
- change_list = NULL;
- event_list = NULL;
- change_index = NULL;
- max_changes = 0;
- nchanges = 0;
- nevents = 0;
-}
-
-
-static ngx_int_t
-ngx_devpoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
-{
-#if (NGX_DEBUG)
- ngx_connection_t *c;
-#endif
-
-#if (NGX_READ_EVENT != POLLIN)
- event = (event == NGX_READ_EVENT) ? POLLIN : POLLOUT;
-#endif
-
-#if (NGX_DEBUG)
- c = ev->data;
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "devpoll add event: fd:%d ev:%04Xi", c->fd, event);
-#endif
-
- ev->active = 1;
-
- return ngx_devpoll_set_event(ev, event, 0);
-}
-
-
-static ngx_int_t
-ngx_devpoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
-{
- ngx_event_t *e;
- ngx_connection_t *c;
-
- c = ev->data;
-
-#if (NGX_READ_EVENT != POLLIN)
- event = (event == NGX_READ_EVENT) ? POLLIN : POLLOUT;
-#endif
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "devpoll del event: fd:%d ev:%04Xi", c->fd, event);
-
- if (ngx_devpoll_set_event(ev, POLLREMOVE, flags) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- 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 pair event if it exists */
-
- if (event == POLLIN) {
- e = c->write;
- event = POLLOUT;
-
- } else {
- e = c->read;
- event = POLLIN;
- }
-
- if (e && e->active) {
- return ngx_devpoll_set_event(e, event, 0);
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_devpoll_set_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
-{
- size_t n;
- ngx_connection_t *c;
-
- c = ev->data;
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "devpoll fd:%d ev:%04Xi fl:%04Xi", c->fd, event, flags);
-
- if (nchanges >= max_changes) {
- ngx_log_error(NGX_LOG_WARN, ev->log, 0,
- "/dev/pool change list is filled up");
-
- n = nchanges * sizeof(struct pollfd);
- if (write(dp, change_list, n) != (ssize_t) n) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
- "write(/dev/poll) failed");
- return NGX_ERROR;
- }
-
- nchanges = 0;
- }
-
- change_list[nchanges].fd = c->fd;
- change_list[nchanges].events = (short) event;
- change_list[nchanges].revents = 0;
-
- change_index[nchanges] = ev;
- ev->index = nchanges;
-
- nchanges++;
-
- if (flags & NGX_CLOSE_EVENT) {
- n = nchanges * sizeof(struct pollfd);
- if (write(dp, change_list, n) != (ssize_t) n) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
- "write(/dev/poll) failed");
- return NGX_ERROR;
- }
-
- nchanges = 0;
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
- ngx_uint_t flags)
-{
- int events, revents, rc;
- size_t n;
- ngx_fd_t fd;
- ngx_err_t err;
- ngx_int_t i;
- ngx_uint_t level, instance;
- ngx_event_t *rev, *wev, **queue;
- ngx_connection_t *c;
- struct pollfd pfd;
- struct dvpoll dvp;
-
- /* NGX_TIMER_INFINITE == INFTIM */
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "devpoll timer: %M", timer);
-
- if (nchanges) {
- n = nchanges * sizeof(struct pollfd);
- if (write(dp, change_list, n) != (ssize_t) n) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "write(/dev/poll) failed");
- return NGX_ERROR;
- }
-
- nchanges = 0;
- }
-
- dvp.dp_fds = event_list;
- dvp.dp_nfds = (int) nevents;
- dvp.dp_timeout = timer;
- events = ioctl(dp, DP_POLL, &dvp);
-
- err = (events == -1) ? ngx_errno : 0;
-
- if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
- ngx_time_update();
- }
-
- if (err) {
- if (err == NGX_EINTR) {
-
- if (ngx_event_timer_alarm) {
- ngx_event_timer_alarm = 0;
- return NGX_OK;
- }
-
- level = NGX_LOG_INFO;
-
- } else {
- level = NGX_LOG_ALERT;
- }
-
- ngx_log_error(level, cycle->log, err, "ioctl(DP_POLL) failed");
- return NGX_ERROR;
- }
-
- if (events == 0) {
- if (timer != NGX_TIMER_INFINITE) {
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "ioctl(DP_POLL) returned no events without timeout");
- return NGX_ERROR;
- }
-
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- for (i = 0; i < events; i++) {
-
- 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 %04Xd",
- 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;
- }
-
- continue;
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "devpoll: fd:%d, ev:%04Xd, rev:%04Xd",
- 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",
- 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",
- fd, event_list[i].events, revents);
- }
-
- if ((revents & (POLLERR|POLLHUP|POLLNVAL))
- && (revents & (POLLIN|POLLOUT)) == 0)
- {
- /*
- * if the error events were returned without POLLIN or POLLOUT,
- * then add these flags to handle the events at least in one
- * active handler
- */
-
- revents |= POLLIN|POLLOUT;
- }
-
- rev = c->read;
-
- if ((revents & POLLIN) && rev->active) {
-
- if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
- rev->posted_ready = 1;
-
- } else {
- rev->ready = 1;
- }
-
- if (flags & NGX_POST_EVENTS) {
- queue = (ngx_event_t **) (rev->accept ?
- &ngx_posted_accept_events : &ngx_posted_events);
-
- ngx_locked_post_event(rev, queue);
-
- } else {
- instance = rev->instance;
-
- rev->handler(rev);
-
- if (c->fd == -1 || rev->instance != instance) {
- continue;
- }
- }
- }
-
- wev = c->write;
-
- if ((revents & POLLOUT) && wev->active) {
-
- if (flags & NGX_POST_THREAD_EVENTS) {
- wev->posted_ready = 1;
-
- } else {
- wev->ready = 1;
- }
-
- if (flags & NGX_POST_EVENTS) {
- ngx_locked_post_event(wev, &ngx_posted_events);
-
- } else {
- wev->handler(wev);
- }
- }
- }
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_devpoll_create_conf(ngx_cycle_t *cycle)
-{
- ngx_devpoll_conf_t *dpcf;
-
- dpcf = ngx_palloc(cycle->pool, sizeof(ngx_devpoll_conf_t));
- if (dpcf == NULL) {
- return NULL;
- }
-
- dpcf->changes = NGX_CONF_UNSET;
- dpcf->events = NGX_CONF_UNSET;
-
- return dpcf;
-}
-
-
-static char *
-ngx_devpoll_init_conf(ngx_cycle_t *cycle, void *conf)
-{
- ngx_devpoll_conf_t *dpcf = conf;
-
- ngx_conf_init_uint_value(dpcf->changes, 32);
- ngx_conf_init_uint_value(dpcf->events, 32);
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/event/modules/ngx_epoll_module.c b/usr.sbin/nginx/src/event/modules/ngx_epoll_module.c
deleted file mode 100644
index f5f66317943..00000000000
--- a/usr.sbin/nginx/src/event/modules/ngx_epoll_module.c
+++ /dev/null
@@ -1,845 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#if (NGX_TEST_BUILD_EPOLL)
-
-/* epoll declarations */
-
-#define EPOLLIN 0x001
-#define EPOLLPRI 0x002
-#define EPOLLOUT 0x004
-#define EPOLLRDNORM 0x040
-#define EPOLLRDBAND 0x080
-#define EPOLLWRNORM 0x100
-#define EPOLLWRBAND 0x200
-#define EPOLLMSG 0x400
-#define EPOLLERR 0x008
-#define EPOLLHUP 0x010
-
-#define EPOLLRDHUP 0x2000
-
-#define EPOLLET 0x80000000
-#define EPOLLONESHOT 0x40000000
-
-#define EPOLL_CTL_ADD 1
-#define EPOLL_CTL_DEL 2
-#define EPOLL_CTL_MOD 3
-
-typedef union epoll_data {
- void *ptr;
- int fd;
- uint32_t u32;
- uint64_t u64;
-} epoll_data_t;
-
-struct epoll_event {
- uint32_t events;
- epoll_data_t data;
-};
-
-
-int epoll_create(int size);
-
-int epoll_create(int size)
-{
- return -1;
-}
-
-
-int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
-
-int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
-{
- return -1;
-}
-
-
-int epoll_wait(int epfd, struct epoll_event *events, int nevents, int timeout);
-
-int epoll_wait(int epfd, struct epoll_event *events, int nevents, int timeout)
-{
- return -1;
-}
-
-#if (NGX_HAVE_FILE_AIO)
-
-#define SYS_io_setup 245
-#define SYS_io_destroy 246
-#define SYS_io_getevents 247
-#define SYS_eventfd 323
-
-typedef u_int aio_context_t;
-
-struct io_event {
- uint64_t data; /* the data field from the iocb */
- uint64_t obj; /* what iocb this event came from */
- int64_t res; /* result code for this event */
- int64_t res2; /* secondary result */
-};
-
-
-#endif
-#endif
-
-
-typedef struct {
- ngx_uint_t events;
- ngx_uint_t aio_requests;
-} 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, 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,
- ngx_uint_t flags);
-static ngx_int_t ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
- ngx_uint_t flags);
-
-#if (NGX_HAVE_FILE_AIO)
-static void ngx_epoll_eventfd_handler(ngx_event_t *ev);
-#endif
-
-static void *ngx_epoll_create_conf(ngx_cycle_t *cycle);
-static char *ngx_epoll_init_conf(ngx_cycle_t *cycle, void *conf);
-
-static int ep = -1;
-static struct epoll_event *event_list;
-static ngx_uint_t nevents;
-
-#if (NGX_HAVE_FILE_AIO)
-
-int ngx_eventfd = -1;
-aio_context_t ngx_aio_ctx = 0;
-
-static ngx_event_t ngx_eventfd_event;
-static ngx_connection_t ngx_eventfd_conn;
-
-#endif
-
-static ngx_str_t epoll_name = ngx_string("epoll");
-
-static ngx_command_t ngx_epoll_commands[] = {
-
- { ngx_string("epoll_events"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_epoll_conf_t, events),
- NULL },
-
- { ngx_string("worker_aio_requests"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_epoll_conf_t, aio_requests),
- NULL },
-
- ngx_null_command
-};
-
-
-ngx_event_module_t ngx_epoll_module_ctx = {
- &epoll_name,
- ngx_epoll_create_conf, /* create configuration */
- ngx_epoll_init_conf, /* init configuration */
-
- {
- ngx_epoll_add_event, /* add an event */
- ngx_epoll_del_event, /* delete an event */
- ngx_epoll_add_event, /* enable an event */
- ngx_epoll_del_event, /* disable an event */
- ngx_epoll_add_connection, /* add an connection */
- ngx_epoll_del_connection, /* delete an connection */
- NULL, /* process the changes */
- ngx_epoll_process_events, /* process the events */
- ngx_epoll_init, /* init the events */
- ngx_epoll_done, /* done the events */
- }
-};
-
-ngx_module_t ngx_epoll_module = {
- NGX_MODULE_V1,
- &ngx_epoll_module_ctx, /* module context */
- ngx_epoll_commands, /* module directives */
- NGX_EVENT_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-#if (NGX_HAVE_FILE_AIO)
-
-/*
- * We call io_setup(), io_destroy() io_submit(), and io_getevents() directly
- * as syscalls instead of libaio usage, because the library header file
- * supports eventfd() since 0.3.107 version only.
- *
- * Also we do not use eventfd() in glibc, because glibc supports it
- * since 2.8 version and glibc maps two syscalls eventfd() and eventfd2()
- * into single eventfd() function with different number of parameters.
- */
-
-static int
-io_setup(u_int nr_reqs, aio_context_t *ctx)
-{
- return syscall(SYS_io_setup, nr_reqs, ctx);
-}
-
-
-static int
-io_destroy(aio_context_t ctx)
-{
- return syscall(SYS_io_destroy, ctx);
-}
-
-
-static int
-io_getevents(aio_context_t ctx, long min_nr, long nr, struct io_event *events,
- struct timespec *tmo)
-{
- return syscall(SYS_io_getevents, ctx, min_nr, nr, events, tmo);
-}
-
-
-static void
-ngx_epoll_aio_init(ngx_cycle_t *cycle, ngx_epoll_conf_t *epcf)
-{
- int n;
- struct epoll_event ee;
-
- ngx_eventfd = syscall(SYS_eventfd, 0);
-
- if (ngx_eventfd == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "eventfd() failed");
- ngx_file_aio = 0;
- return;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "eventfd: %d", ngx_eventfd);
-
- n = 1;
-
- if (ioctl(ngx_eventfd, FIONBIO, &n) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "ioctl(eventfd, FIONBIO) failed");
- goto failed;
- }
-
- if (io_setup(epcf->aio_requests, &ngx_aio_ctx) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "io_setup() failed");
- goto failed;
- }
-
- ngx_eventfd_event.data = &ngx_eventfd_conn;
- ngx_eventfd_event.handler = ngx_epoll_eventfd_handler;
- ngx_eventfd_event.log = cycle->log;
- ngx_eventfd_event.active = 1;
- ngx_eventfd_conn.fd = ngx_eventfd;
- ngx_eventfd_conn.read = &ngx_eventfd_event;
- ngx_eventfd_conn.log = cycle->log;
-
- ee.events = EPOLLIN|EPOLLET;
- ee.data.ptr = &ngx_eventfd_conn;
-
- if (epoll_ctl(ep, EPOLL_CTL_ADD, ngx_eventfd, &ee) != -1) {
- return;
- }
-
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "epoll_ctl(EPOLL_CTL_ADD, eventfd) failed");
-
- if (io_destroy(ngx_aio_ctx) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "io_destroy() failed");
- }
-
-failed:
-
- if (close(ngx_eventfd) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "eventfd close() failed");
- }
-
- ngx_eventfd = -1;
- ngx_aio_ctx = 0;
- ngx_file_aio = 0;
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
-{
- ngx_epoll_conf_t *epcf;
-
- epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_epoll_module);
-
- if (ep == -1) {
- ep = epoll_create(cycle->connection_n / 2);
-
- if (ep == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "epoll_create() failed");
- return NGX_ERROR;
- }
-
-#if (NGX_HAVE_FILE_AIO)
-
- ngx_epoll_aio_init(cycle, epcf);
-
-#endif
- }
-
- if (nevents < epcf->events) {
- if (event_list) {
- ngx_free(event_list);
- }
-
- event_list = ngx_alloc(sizeof(struct epoll_event) * epcf->events,
- cycle->log);
- if (event_list == NULL) {
- return NGX_ERROR;
- }
- }
-
- nevents = epcf->events;
-
- ngx_io = ngx_os_io;
-
- ngx_event_actions = ngx_epoll_module_ctx.actions;
-
-#if (NGX_HAVE_CLEAR_EVENT)
- ngx_event_flags = NGX_USE_CLEAR_EVENT
-#else
- ngx_event_flags = NGX_USE_LEVEL_EVENT
-#endif
- |NGX_USE_GREEDY_EVENT
- |NGX_USE_EPOLL_EVENT;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_epoll_done(ngx_cycle_t *cycle)
-{
- if (close(ep) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "epoll close() failed");
- }
-
- ep = -1;
-
-#if (NGX_HAVE_FILE_AIO)
-
- if (ngx_eventfd != -1) {
-
- if (io_destroy(ngx_aio_ctx) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "io_destroy() failed");
- }
-
- if (close(ngx_eventfd) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "eventfd close() failed");
- }
-
- ngx_eventfd = -1;
- }
-
- ngx_aio_ctx = 0;
-
-#endif
-
- ngx_free(event_list);
-
- event_list = NULL;
- nevents = 0;
-}
-
-
-static ngx_int_t
-ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
-{
- int op;
- uint32_t events, prev;
- ngx_event_t *e;
- ngx_connection_t *c;
- struct epoll_event ee;
-
- c = ev->data;
-
- events = (uint32_t) event;
-
- if (event == NGX_READ_EVENT) {
- e = c->write;
- prev = EPOLLOUT;
-#if (NGX_READ_EVENT != EPOLLIN|EPOLLRDHUP)
- events = EPOLLIN|EPOLLRDHUP;
-#endif
-
- } else {
- e = c->read;
- prev = EPOLLIN|EPOLLRDHUP;
-#if (NGX_WRITE_EVENT != EPOLLOUT)
- events = EPOLLOUT;
-#endif
- }
-
- if (e->active) {
- op = EPOLL_CTL_MOD;
- events |= prev;
-
- } else {
- op = EPOLL_CTL_ADD;
- }
-
- 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,
- "epoll add event: fd:%d op:%d ev:%08XD",
- c->fd, op, ee.events);
-
- if (epoll_ctl(ep, op, c->fd, &ee) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
- "epoll_ctl(%d, %d) failed", op, c->fd);
- return NGX_ERROR;
- }
-
- ev->active = 1;
-#if 0
- ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0;
-#endif
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_epoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
-{
- int op;
- uint32_t prev;
- ngx_event_t *e;
- ngx_connection_t *c;
- struct epoll_event ee;
-
- /*
- * when the file descriptor is closed, the epoll automatically deletes
- * it from its queue, so we do not need to delete explicitly the event
- * before the closing the file descriptor
- */
-
- if (flags & NGX_CLOSE_EVENT) {
- ev->active = 0;
- return NGX_OK;
- }
-
- c = ev->data;
-
- if (event == NGX_READ_EVENT) {
- e = c->write;
- prev = EPOLLOUT;
-
- } else {
- e = c->read;
- prev = EPOLLIN|EPOLLRDHUP;
- }
-
- if (e->active) {
- op = EPOLL_CTL_MOD;
- ee.events = prev | (uint32_t) flags;
- ee.data.ptr = (void *) ((uintptr_t) c | ev->instance);
-
- } else {
- op = EPOLL_CTL_DEL;
- ee.events = 0;
- ee.data.ptr = NULL;
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "epoll del event: fd:%d op:%d ev:%08XD",
- c->fd, op, ee.events);
-
- if (epoll_ctl(ep, op, c->fd, &ee) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
- "epoll_ctl(%d, %d) failed", op, c->fd);
- return NGX_ERROR;
- }
-
- ev->active = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_epoll_add_connection(ngx_connection_t *c)
-{
- struct epoll_event ee;
-
- ee.events = EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP;
- ee.data.ptr = (void *) ((uintptr_t) c | c->read->instance);
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "epoll add connection: fd:%d ev:%08XD", c->fd, ee.events);
-
- if (epoll_ctl(ep, EPOLL_CTL_ADD, c->fd, &ee) == -1) {
- ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
- "epoll_ctl(EPOLL_CTL_ADD, %d) failed", c->fd);
- return NGX_ERROR;
- }
-
- c->read->active = 1;
- c->write->active = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_epoll_del_connection(ngx_connection_t *c, ngx_uint_t flags)
-{
- int op;
- struct epoll_event ee;
-
- /*
- * when the file descriptor is closed the epoll automatically deletes
- * it from its queue so we do not need to delete explicitly the event
- * before the closing the file descriptor
- */
-
- if (flags & NGX_CLOSE_EVENT) {
- c->read->active = 0;
- c->write->active = 0;
- return NGX_OK;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "epoll del connection: fd:%d", c->fd);
-
- op = EPOLL_CTL_DEL;
- ee.events = 0;
- ee.data.ptr = NULL;
-
- if (epoll_ctl(ep, op, c->fd, &ee) == -1) {
- ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
- "epoll_ctl(%d, %d) failed", op, c->fd);
- return NGX_ERROR;
- }
-
- c->read->active = 0;
- c->write->active = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
-{
- int events;
- uint32_t revents;
- ngx_int_t instance, i;
- ngx_uint_t level;
- ngx_err_t err;
- ngx_event_t *rev, *wev, **queue;
- ngx_connection_t *c;
-
- /* NGX_TIMER_INFINITE == INFTIM */
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "epoll timer: %M", timer);
-
- events = epoll_wait(ep, event_list, (int) nevents, timer);
-
- err = (events == -1) ? ngx_errno : 0;
-
- if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
- ngx_time_update();
- }
-
- if (err) {
- if (err == NGX_EINTR) {
-
- if (ngx_event_timer_alarm) {
- ngx_event_timer_alarm = 0;
- return NGX_OK;
- }
-
- level = NGX_LOG_INFO;
-
- } else {
- level = NGX_LOG_ALERT;
- }
-
- ngx_log_error(level, cycle->log, err, "epoll_wait() failed");
- return NGX_ERROR;
- }
-
- if (events == 0) {
- if (timer != NGX_TIMER_INFINITE) {
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "epoll_wait() returned no events without timeout");
- return NGX_ERROR;
- }
-
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- for (i = 0; i < events; i++) {
- c = event_list[i].data.ptr;
-
- instance = (uintptr_t) c & 1;
- c = (ngx_connection_t *) ((uintptr_t) c & (uintptr_t) ~1);
-
- rev = c->read;
-
- if (c->fd == -1 || rev->instance != instance) {
-
- /*
- * the stale event from a file descriptor
- * that was just closed in this iteration
- */
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "epoll: stale event %p", c);
- continue;
- }
-
- revents = event_list[i].events;
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "epoll: fd:%d ev:%04XD d:%p",
- c->fd, revents, event_list[i].data.ptr);
-
- if (revents & (EPOLLERR|EPOLLHUP)) {
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "epoll_wait() error on fd:%d ev:%04XD",
- c->fd, revents);
- }
-
-#if 0
- if (revents & ~(EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP)) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "strange epoll_wait() events fd:%d ev:%04XD",
- c->fd, revents);
- }
-#endif
-
- if ((revents & (EPOLLERR|EPOLLHUP))
- && (revents & (EPOLLIN|EPOLLOUT)) == 0)
- {
- /*
- * if the error events were returned without EPOLLIN or EPOLLOUT,
- * then add these flags to handle the events at least in one
- * active handler
- */
-
- revents |= EPOLLIN|EPOLLOUT;
- }
-
- if ((revents & EPOLLIN) && rev->active) {
-
-#if (NGX_HAVE_EPOLLRDHUP)
- if (revents & EPOLLRDHUP) {
- rev->pending_eof = 1;
- }
-#endif
-
- if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
- rev->posted_ready = 1;
-
- } else {
- rev->ready = 1;
- }
-
- if (flags & NGX_POST_EVENTS) {
- queue = (ngx_event_t **) (rev->accept ?
- &ngx_posted_accept_events : &ngx_posted_events);
-
- ngx_locked_post_event(rev, queue);
-
- } else {
- rev->handler(rev);
- }
- }
-
- wev = c->write;
-
- if ((revents & EPOLLOUT) && wev->active) {
-
- if (c->fd == -1 || wev->instance != instance) {
-
- /*
- * the stale event from a file descriptor
- * that was just closed in this iteration
- */
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "epoll: stale event %p", c);
- continue;
- }
-
- if (flags & NGX_POST_THREAD_EVENTS) {
- wev->posted_ready = 1;
-
- } else {
- wev->ready = 1;
- }
-
- if (flags & NGX_POST_EVENTS) {
- ngx_locked_post_event(wev, &ngx_posted_events);
-
- } else {
- wev->handler(wev);
- }
- }
- }
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- return NGX_OK;
-}
-
-
-#if (NGX_HAVE_FILE_AIO)
-
-static void
-ngx_epoll_eventfd_handler(ngx_event_t *ev)
-{
- int n, events;
- long i;
- uint64_t ready;
- ngx_err_t err;
- ngx_event_t *e;
- ngx_event_aio_t *aio;
- struct io_event event[64];
- struct timespec ts;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "eventfd handler");
-
- n = read(ngx_eventfd, &ready, 8);
-
- err = ngx_errno;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0, "eventfd: %d", n);
-
- if (n != 8) {
- if (n == -1) {
- if (err == NGX_EAGAIN) {
- return;
- }
-
- ngx_log_error(NGX_LOG_ALERT, ev->log, err, "read(eventfd) failed");
- return;
- }
-
- ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
- "read(eventfd) returned only %d bytes", n);
- return;
- }
-
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
-
- while (ready) {
-
- events = io_getevents(ngx_aio_ctx, 1, 64, event, &ts);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "io_getevents: %l", events);
-
- if (events > 0) {
- ready -= events;
-
- for (i = 0; i < events; i++) {
-
- ngx_log_debug4(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "io_event: %uXL %uXL %L %L",
- event[i].data, event[i].obj,
- event[i].res, event[i].res2);
-
- e = (ngx_event_t *) (uintptr_t) event[i].data;
-
- e->complete = 1;
- e->active = 0;
- e->ready = 1;
-
- aio = e->data;
- aio->res = event[i].res;
-
- ngx_post_event(e, &ngx_posted_events);
- }
-
- continue;
- }
-
- if (events == 0) {
- return;
- }
-
- /* events == -1 */
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
- "io_getevents() failed");
- return;
- }
-}
-
-#endif
-
-
-static void *
-ngx_epoll_create_conf(ngx_cycle_t *cycle)
-{
- ngx_epoll_conf_t *epcf;
-
- epcf = ngx_palloc(cycle->pool, sizeof(ngx_epoll_conf_t));
- if (epcf == NULL) {
- return NULL;
- }
-
- epcf->events = NGX_CONF_UNSET;
- epcf->aio_requests = NGX_CONF_UNSET;
-
- return epcf;
-}
-
-
-static char *
-ngx_epoll_init_conf(ngx_cycle_t *cycle, void *conf)
-{
- ngx_epoll_conf_t *epcf = conf;
-
- ngx_conf_init_uint_value(epcf->events, 512);
- ngx_conf_init_uint_value(epcf->aio_requests, 32);
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/event/modules/ngx_eventport_module.c b/usr.sbin/nginx/src/event/modules/ngx_eventport_module.c
deleted file mode 100644
index 5f9cf4e35fb..00000000000
--- a/usr.sbin/nginx/src/event/modules/ngx_eventport_module.c
+++ /dev/null
@@ -1,633 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#if (NGX_TEST_BUILD_EVENTPORT)
-
-#define ushort_t u_short
-#define uint_t u_int
-
-#ifndef CLOCK_REALTIME
-#define CLOCK_REALTIME 0
-typedef int clockid_t;
-typedef void * timer_t;
-#endif
-
-/* Solaris declarations */
-
-#define PORT_SOURCE_AIO 1
-#define PORT_SOURCE_TIMER 2
-#define PORT_SOURCE_USER 3
-#define PORT_SOURCE_FD 4
-#define PORT_SOURCE_ALERT 5
-#define PORT_SOURCE_MQ 6
-
-#ifndef ETIME
-#define ETIME 64
-#endif
-
-#define SIGEV_PORT 4
-
-typedef struct {
- int portev_events; /* event data is source specific */
- ushort_t portev_source; /* event source */
- ushort_t portev_pad; /* port internal use */
- uintptr_t portev_object; /* source specific object */
- void *portev_user; /* user cookie */
-} port_event_t;
-
-typedef struct port_notify {
- int portnfy_port; /* bind request(s) to port */
- void *portnfy_user; /* user defined */
-} port_notify_t;
-
-#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);
-
-int port_create(void)
-{
- return -1;
-}
-
-
-int port_associate(int port, int source, uintptr_t object, int events,
- void *user);
-
-int port_associate(int port, int source, uintptr_t object, int events,
- void *user)
-{
- return -1;
-}
-
-
-int port_dissociate(int port, int source, uintptr_t object);
-
-int port_dissociate(int port, int source, uintptr_t object)
-{
- return -1;
-}
-
-
-int port_getn(int port, port_event_t list[], uint_t max, uint_t *nget,
- struct timespec *timeout);
-
-int port_getn(int port, port_event_t list[], uint_t max, uint_t *nget,
- struct timespec *timeout)
-{
- return -1;
-}
-
-
-int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid);
-
-int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid)
-{
- return -1;
-}
-
-
-int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
- struct itimerspec *ovalue);
-
-int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
- struct itimerspec *ovalue)
-{
- return -1;
-}
-
-
-int timer_delete(timer_t timerid);
-
-int timer_delete(timer_t timerid)
-{
- return -1;
-}
-
-#endif
-
-
-typedef struct {
- 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, 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);
-
-static void *ngx_eventport_create_conf(ngx_cycle_t *cycle);
-static char *ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf);
-
-static int ep = -1;
-static port_event_t *event_list;
-static ngx_uint_t nevents;
-static timer_t event_timer = (timer_t) -1;
-
-static ngx_str_t eventport_name = ngx_string("eventport");
-
-
-static ngx_command_t ngx_eventport_commands[] = {
-
- { ngx_string("eventport_events"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_eventport_conf_t, events),
- NULL },
-
- ngx_null_command
-};
-
-
-ngx_event_module_t ngx_eventport_module_ctx = {
- &eventport_name,
- ngx_eventport_create_conf, /* create configuration */
- ngx_eventport_init_conf, /* init configuration */
-
- {
- ngx_eventport_add_event, /* add an event */
- ngx_eventport_del_event, /* delete an event */
- ngx_eventport_add_event, /* enable an event */
- ngx_eventport_del_event, /* disable an event */
- NULL, /* add an connection */
- NULL, /* delete an connection */
- NULL, /* process the changes */
- ngx_eventport_process_events, /* process the events */
- ngx_eventport_init, /* init the events */
- ngx_eventport_done, /* done the events */
- }
-
-};
-
-ngx_module_t ngx_eventport_module = {
- NGX_MODULE_V1,
- &ngx_eventport_module_ctx, /* module context */
- ngx_eventport_commands, /* module directives */
- NGX_EVENT_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_eventport_init(ngx_cycle_t *cycle, ngx_msec_t timer)
-{
- port_notify_t pn;
- struct itimerspec its;
- struct sigevent sev;
- ngx_eventport_conf_t *epcf;
-
- epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_eventport_module);
-
- if (ep == -1) {
- ep = port_create();
-
- if (ep == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "port_create() failed");
- return NGX_ERROR;
- }
- }
-
- if (nevents < epcf->events) {
- if (event_list) {
- ngx_free(event_list);
- }
-
- event_list = ngx_alloc(sizeof(port_event_t) * epcf->events,
- cycle->log);
- if (event_list == NULL) {
- return NGX_ERROR;
- }
- }
-
- ngx_event_flags = NGX_USE_EVENTPORT_EVENT;
-
- if (timer) {
- ngx_memzero(&pn, sizeof(port_notify_t));
- pn.portnfy_port = ep;
-
- ngx_memzero(&sev, sizeof(struct sigevent));
- sev.sigev_notify = SIGEV_PORT;
-#if !(NGX_TEST_BUILD_EVENTPORT)
- sev.sigev_value.sival_ptr = &pn;
-#endif
-
- if (timer_create(CLOCK_REALTIME, &sev, &event_timer) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "timer_create() failed");
- return NGX_ERROR;
- }
-
- its.it_interval.tv_sec = timer / 1000;
- its.it_interval.tv_nsec = (timer % 1000) * 1000000;
- its.it_value.tv_sec = timer / 1000;
- its.it_value.tv_nsec = (timer % 1000) * 1000000;
-
- if (timer_settime(event_timer, 0, &its, NULL) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "timer_settime() failed");
- return NGX_ERROR;
- }
-
- ngx_event_flags |= NGX_USE_TIMER_EVENT;
- }
-
- nevents = epcf->events;
-
- ngx_io = ngx_os_io;
-
- ngx_event_actions = ngx_eventport_module_ctx.actions;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_eventport_done(ngx_cycle_t *cycle)
-{
- 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 = (timer_t) -1;
- }
-
- if (close(ep) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "close() event port failed");
- }
-
- ep = -1;
-
- ngx_free(event_list);
-
- event_list = NULL;
- nevents = 0;
-}
-
-
-static ngx_int_t
-ngx_eventport_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
-{
- ngx_int_t events, prev;
- ngx_event_t *e;
- ngx_connection_t *c;
-
- c = ev->data;
-
- events = event;
-
- if (event == NGX_READ_EVENT) {
- e = c->write;
- prev = POLLOUT;
-#if (NGX_READ_EVENT != POLLIN)
- events = POLLIN;
-#endif
-
- } else {
- e = c->read;
- prev = POLLIN;
-#if (NGX_WRITE_EVENT != POLLOUT)
- events = POLLOUT;
-#endif
- }
-
- if (e->oneshot) {
- events |= prev;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "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))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
- "port_associate() failed");
- return NGX_ERROR;
- }
-
- ev->active = 1;
- ev->oneshot = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_eventport_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
-{
- ngx_event_t *e;
- ngx_connection_t *c;
-
- /*
- * when the file descriptor is closed, the event port automatically
- * dissociates it from the port, so we do not need to dissociate explicitly
- * the event before the closing the file descriptor
- */
-
- if (flags & NGX_CLOSE_EVENT) {
- ev->active = 0;
- ev->oneshot = 0;
- return NGX_OK;
- }
-
- c = ev->data;
-
- if (event == NGX_READ_EVENT) {
- e = c->write;
- event = POLLOUT;
-
- } else {
- e = c->read;
- event = POLLIN;
- }
-
- if (e->oneshot) {
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "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))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
- "port_associate() failed");
- return NGX_ERROR;
- }
-
- } else {
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "eventport del event: fd:%d", c->fd);
-
- if (port_dissociate(ep, PORT_SOURCE_FD, c->fd) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
- "port_dissociate() failed");
- return NGX_ERROR;
- }
- }
-
- ev->active = 0;
- ev->oneshot = 0;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
- ngx_uint_t flags)
-{
- int n, revents;
- u_int events;
- ngx_err_t err;
- ngx_int_t instance;
- ngx_uint_t i, level;
- ngx_event_t *ev, *rev, *wev, **queue;
- ngx_connection_t *c;
- struct timespec ts, *tp;
-
- if (timer == NGX_TIMER_INFINITE) {
- tp = NULL;
-
- } else {
- ts.tv_sec = timer / 1000;
- ts.tv_nsec = (timer % 1000) * 1000000;
- tp = &ts;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "eventport timer: %M", timer);
-
- events = 1;
-
- n = port_getn(ep, event_list, (u_int) nevents, &events, tp);
-
- err = ngx_errno;
-
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update();
- }
-
- if (n == -1) {
- if (err == ETIME) {
- if (timer != NGX_TIMER_INFINITE) {
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "port_getn() returned no events without timeout");
- return NGX_ERROR;
- }
-
- level = (err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT;
- ngx_log_error(level, cycle->log, err, "port_getn() failed");
- return NGX_ERROR;
- }
-
- if (events == 0) {
- if (timer != NGX_TIMER_INFINITE) {
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "port_getn() returned no events without timeout");
- return NGX_ERROR;
- }
-
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- for (i = 0; i < events; i++) {
-
- if (event_list[i].portev_source == PORT_SOURCE_TIMER) {
- ngx_time_update();
- continue;
- }
-
- ev = event_list[i].portev_user;
-
- switch (event_list[i].portev_source) {
-
- case PORT_SOURCE_FD:
-
- instance = (uintptr_t) ev & 1;
- ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1);
-
- if (ev->closed || ev->instance != instance) {
-
- /*
- * the stale event from a file descriptor
- * that was just closed in this iteration
- */
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "eventport: stale event %p", ev);
- continue;
- }
-
- revents = event_list[i].portev_events;
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "eventport: fd:%d, ev:%04Xd",
- event_list[i].portev_object, revents);
-
- if (revents & (POLLERR|POLLHUP|POLLNVAL)) {
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "port_getn() error fd:%d ev:%04Xd",
- event_list[i].portev_object, revents);
- }
-
- if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "strange port_getn() events fd:%d ev:%04Xd",
- event_list[i].portev_object, revents);
- }
-
- if ((revents & (POLLERR|POLLHUP|POLLNVAL))
- && (revents & (POLLIN|POLLOUT)) == 0)
- {
- /*
- * if the error events were returned without POLLIN or POLLOUT,
- * then add these flags to handle the events at least in one
- * active handler
- */
-
- revents |= POLLIN|POLLOUT;
- }
-
- c = ev->data;
- rev = c->read;
- wev = c->write;
-
- rev->active = 0;
- wev->active = 0;
-
- if (revents & POLLIN) {
-
- if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
- rev->posted_ready = 1;
-
- } else {
- rev->ready = 1;
- }
-
- if (flags & NGX_POST_EVENTS) {
- queue = (ngx_event_t **) (rev->accept ?
- &ngx_posted_accept_events : &ngx_posted_events);
-
- ngx_locked_post_event(rev, queue);
-
- } else {
- rev->handler(rev);
-
- if (ev->closed || ev->instance != instance) {
- continue;
- }
- }
-
- if (rev->accept) {
- if (ngx_use_accept_mutex) {
- ngx_accept_events = 1;
- continue;
- }
-
- if (port_associate(ep, PORT_SOURCE_FD, c->fd, POLLIN,
- (void *) ((uintptr_t) ev | ev->instance))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
- "port_associate() failed");
- return NGX_ERROR;
- }
- }
- }
-
- if (revents & POLLOUT) {
-
- if (flags & NGX_POST_THREAD_EVENTS) {
- wev->posted_ready = 1;
-
- } else {
- wev->ready = 1;
- }
-
- if (flags & NGX_POST_EVENTS) {
- ngx_locked_post_event(wev, &ngx_posted_events);
-
- } else {
- wev->handler(wev);
- }
- }
-
- continue;
-
- default:
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "unexpected even_port object %d",
- event_list[i].portev_object);
- continue;
- }
- }
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_eventport_create_conf(ngx_cycle_t *cycle)
-{
- ngx_eventport_conf_t *epcf;
-
- epcf = ngx_palloc(cycle->pool, sizeof(ngx_eventport_conf_t));
- if (epcf == NULL) {
- return NULL;
- }
-
- epcf->events = NGX_CONF_UNSET;
-
- return epcf;
-}
-
-
-static char *
-ngx_eventport_init_conf(ngx_cycle_t *cycle, void *conf)
-{
- ngx_eventport_conf_t *epcf = conf;
-
- ngx_conf_init_uint_value(epcf->events, 32);
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/event/modules/ngx_kqueue_module.c b/usr.sbin/nginx/src/event/modules/ngx_kqueue_module.c
deleted file mode 100644
index 30e456c4da0..00000000000
--- a/usr.sbin/nginx/src/event/modules/ngx_kqueue_module.c
+++ /dev/null
@@ -1,785 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-typedef struct {
- 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, 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);
-static ngx_inline void ngx_kqueue_dump_event(ngx_log_t *log,
- struct kevent *kev);
-
-static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle);
-static char *ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf);
-
-
-int ngx_kqueue = -1;
-
-/*
- * The "change_list" should be declared as ngx_thread_volatile.
- * However, the use of the change_list is localized in kqueue functions and
- * is protected by the mutex so even the "icc -ipo" should not build the code
- * with the race condition. Thus we avoid the declaration to make a more
- * readable code.
- */
-
-static struct kevent *change_list, *change_list0, *change_list1;
-static struct kevent *event_list;
-static ngx_uint_t max_changes, nchanges, nevents;
-
-#if (NGX_THREADS)
-static ngx_mutex_t *list_mutex;
-static ngx_mutex_t *kevent_mutex;
-#endif
-
-
-
-static ngx_str_t kqueue_name = ngx_string("kqueue");
-
-static ngx_command_t ngx_kqueue_commands[] = {
-
- { ngx_string("kqueue_changes"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_kqueue_conf_t, changes),
- NULL },
-
- { ngx_string("kqueue_events"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_kqueue_conf_t, events),
- NULL },
-
- ngx_null_command
-};
-
-
-ngx_event_module_t ngx_kqueue_module_ctx = {
- &kqueue_name,
- ngx_kqueue_create_conf, /* create configuration */
- ngx_kqueue_init_conf, /* init configuration */
-
- {
- ngx_kqueue_add_event, /* add an event */
- ngx_kqueue_del_event, /* delete an event */
- ngx_kqueue_add_event, /* enable an event */
- ngx_kqueue_del_event, /* disable an event */
- NULL, /* add an connection */
- NULL, /* delete an connection */
- ngx_kqueue_process_changes, /* process the changes */
- ngx_kqueue_process_events, /* process the events */
- ngx_kqueue_init, /* init the events */
- ngx_kqueue_done /* done the events */
- }
-
-};
-
-ngx_module_t ngx_kqueue_module = {
- NGX_MODULE_V1,
- &ngx_kqueue_module_ctx, /* module context */
- ngx_kqueue_commands, /* module directives */
- NGX_EVENT_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer)
-{
- ngx_kqueue_conf_t *kcf;
- struct timespec ts;
-#if (NGX_HAVE_TIMER_EVENT)
- struct kevent kev;
-#endif
-
- kcf = ngx_event_get_conf(cycle->conf_ctx, ngx_kqueue_module);
-
- if (ngx_kqueue == -1) {
- ngx_kqueue = kqueue();
-
- if (ngx_kqueue == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "kqueue() failed");
- return NGX_ERROR;
- }
-
-#if (NGX_THREADS)
-
- list_mutex = ngx_mutex_init(cycle->log, 0);
- if (list_mutex == NULL) {
- return NGX_ERROR;
- }
-
- kevent_mutex = ngx_mutex_init(cycle->log, 0);
- if (kevent_mutex == NULL) {
- return NGX_ERROR;
- }
-
-#endif
- }
-
- if (max_changes < kcf->changes) {
- if (nchanges) {
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
-
- 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;
- }
- nchanges = 0;
- }
-
- if (change_list0) {
- ngx_free(change_list0);
- }
-
- change_list0 = ngx_alloc(kcf->changes * sizeof(struct kevent),
- cycle->log);
- if (change_list0 == NULL) {
- return NGX_ERROR;
- }
-
- if (change_list1) {
- ngx_free(change_list1);
- }
-
- change_list1 = ngx_alloc(kcf->changes * sizeof(struct kevent),
- cycle->log);
- if (change_list1 == NULL) {
- return NGX_ERROR;
- }
-
- change_list = change_list0;
- }
-
- max_changes = kcf->changes;
-
- if (nevents < kcf->events) {
- if (event_list) {
- ngx_free(event_list);
- }
-
- event_list = ngx_alloc(kcf->events * sizeof(struct kevent), cycle->log);
- if (event_list == NULL) {
- return NGX_ERROR;
- }
- }
-
- ngx_event_flags = NGX_USE_ONESHOT_EVENT
- |NGX_USE_KQUEUE_EVENT
- |NGX_USE_VNODE_EVENT;
-
-#if (NGX_HAVE_TIMER_EVENT)
-
- if (timer) {
- kev.ident = 0;
- kev.filter = EVFILT_TIMER;
- kev.flags = EV_ADD|EV_ENABLE;
- kev.fflags = 0;
- kev.data = timer;
- kev.udata = 0;
-
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
-
- if (kevent(ngx_kqueue, &kev, 1, NULL, 0, &ts) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "kevent(EVFILT_TIMER) failed");
- return NGX_ERROR;
- }
-
- ngx_event_flags |= NGX_USE_TIMER_EVENT;
- }
-
-#endif
-
-#if (NGX_HAVE_CLEAR_EVENT)
- ngx_event_flags |= NGX_USE_CLEAR_EVENT;
-#else
- ngx_event_flags |= NGX_USE_LEVEL_EVENT;
-#endif
-
-#if (NGX_HAVE_LOWAT_EVENT)
- ngx_event_flags |= NGX_USE_LOWAT_EVENT;
-#endif
-
- nevents = kcf->events;
-
- ngx_io = ngx_os_io;
-
- ngx_event_actions = ngx_kqueue_module_ctx.actions;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_kqueue_done(ngx_cycle_t *cycle)
-{
- if (close(ngx_kqueue) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "kqueue close() failed");
- }
-
- ngx_kqueue = -1;
-
-#if (NGX_THREADS)
- ngx_mutex_destroy(kevent_mutex);
- ngx_mutex_destroy(list_mutex);
-#endif
-
- ngx_free(change_list1);
- ngx_free(change_list0);
- ngx_free(event_list);
-
- change_list1 = NULL;
- change_list0 = NULL;
- change_list = NULL;
- event_list = NULL;
- max_changes = 0;
- nchanges = 0;
- nevents = 0;
-}
-
-
-static ngx_int_t
-ngx_kqueue_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
-{
- ngx_int_t rc;
-#if 0
- ngx_event_t *e;
- ngx_connection_t *c;
-#endif
-
- ev->active = 1;
- ev->disabled = 0;
- ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1 : 0;
-
- ngx_mutex_lock(list_mutex);
-
-#if 0
-
- if (ev->index < nchanges
- && ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1)
- == (uintptr_t) ev)
- {
- if (change_list[ev->index].flags == EV_DISABLE) {
-
- /*
- * if the EV_DISABLE is still not passed to a kernel
- * we will not pass it
- */
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "kevent activated: %d: ft:%i",
- ngx_event_ident(ev->data), event);
-
- if (ev->index < --nchanges) {
- e = (ngx_event_t *)
- ((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1);
- change_list[ev->index] = change_list[nchanges];
- e->index = ev->index;
- }
-
- ngx_mutex_unlock(list_mutex);
-
- return NGX_OK;
- }
-
- c = ev->data;
-
- ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
- "previous event on #%d were not passed in kernel", c->fd);
-
- ngx_mutex_unlock(list_mutex);
-
- return NGX_ERROR;
- }
-
-#endif
-
- rc = ngx_kqueue_set_event(ev, event, EV_ADD|EV_ENABLE|flags);
-
- ngx_mutex_unlock(list_mutex);
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_kqueue_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
-{
- ngx_int_t rc;
- ngx_event_t *e;
-
- ev->active = 0;
- ev->disabled = 0;
-
- ngx_mutex_lock(list_mutex);
-
- 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:%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 < nchanges) {
- e = (ngx_event_t *)
- ((uintptr_t) change_list[nchanges].udata & (uintptr_t) ~1);
- change_list[ev->index] = change_list[nchanges];
- e->index = ev->index;
- }
-
- ngx_mutex_unlock(list_mutex);
-
- return NGX_OK;
- }
-
- /*
- * when the file descriptor is closed the kqueue automatically deletes
- * its filters so we do not need to delete explicitly the event
- * before the closing the file descriptor.
- */
-
- if (flags & NGX_CLOSE_EVENT) {
- ngx_mutex_unlock(list_mutex);
- return NGX_OK;
- }
-
- if (flags & NGX_DISABLE_EVENT) {
- ev->disabled = 1;
-
- } else {
- flags |= EV_DELETE;
- }
-
- rc = ngx_kqueue_set_event(ev, event, flags);
-
- ngx_mutex_unlock(list_mutex);
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_kqueue_set_event(ngx_event_t *ev, ngx_int_t filter, ngx_uint_t flags)
-{
- struct kevent *kev;
- struct timespec ts;
- ngx_connection_t *c;
-
- c = ev->data;
-
- 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) {
- ngx_log_error(NGX_LOG_WARN, ev->log, 0,
- "kqueue change list is filled up");
-
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
-
- 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;
- }
-
- nchanges = 0;
- }
-
- kev = &change_list[nchanges];
-
- kev->ident = c->fd;
- kev->filter = (short) filter;
- kev->flags = (u_short) flags;
- kev->udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ev | ev->instance);
-
- if (filter == EVFILT_VNODE) {
- kev->fflags = NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND
- |NOTE_ATTRIB|NOTE_RENAME
-#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
- || __FreeBSD_version >= 500018
- |NOTE_REVOKE
-#endif
- ;
- kev->data = 0;
-
- } else {
-#if (NGX_HAVE_LOWAT_EVENT)
- if (flags & NGX_LOWAT_EVENT) {
- kev->fflags = NOTE_LOWAT;
- kev->data = ev->available;
-
- } else {
- kev->fflags = 0;
- kev->data = 0;
- }
-#else
- kev->fflags = 0;
- kev->data = 0;
-#endif
- }
-
- ev->index = nchanges;
- nchanges++;
-
- if (flags & NGX_FLUSH_EVENT) {
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "kevent flush");
-
- 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;
- }
-
- nchanges = 0;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
- ngx_uint_t flags)
-{
- int events, n;
- ngx_int_t i, instance;
- ngx_uint_t level;
- ngx_err_t err;
- ngx_event_t *ev, **queue;
- struct timespec ts, *tp;
-
- if (ngx_threaded) {
- if (ngx_kqueue_process_changes(cycle, 0) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- n = 0;
-
- } else {
- n = (int) nchanges;
- nchanges = 0;
- }
-
- if (timer == NGX_TIMER_INFINITE) {
- tp = NULL;
-
- } else {
-
- ts.tv_sec = timer / 1000;
- ts.tv_nsec = (timer % 1000) * 1000000;
-
- /*
- * 64-bit Darwin kernel has the bug: kernel level ts.tv_nsec is
- * the int32_t while user level ts.tv_nsec is the long (64-bit),
- * so on the big endian PowerPC all nanoseconds are lost.
- */
-
-#if (NGX_DARWIN_KEVENT_BUG)
- ts.tv_nsec <<= 32;
-#endif
-
- tp = &ts;
- }
-
- 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, (int) nevents, tp);
-
- err = (events == -1) ? ngx_errno : 0;
-
- if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
- ngx_time_update();
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "kevent events: %d", events);
-
- if (err) {
- if (err == NGX_EINTR) {
-
- if (ngx_event_timer_alarm) {
- ngx_event_timer_alarm = 0;
- return NGX_OK;
- }
-
- level = NGX_LOG_INFO;
-
- } else {
- level = NGX_LOG_ALERT;
- }
-
- ngx_log_error(level, cycle->log, err, "kevent() failed");
- return NGX_ERROR;
- }
-
- if (events == 0) {
- if (timer != NGX_TIMER_INFINITE) {
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "kevent() returned no events without timeout");
- return NGX_ERROR;
- }
-
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- for (i = 0; i < events; i++) {
-
- ngx_kqueue_dump_event(cycle->log, &event_list[i]);
-
- if (event_list[i].flags & EV_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, event_list[i].data,
- "kevent() error on %d filter:%d flags:%04Xd",
- event_list[i].ident, event_list[i].filter,
- event_list[i].flags);
- continue;
- }
-
-#if (NGX_HAVE_TIMER_EVENT)
-
- if (event_list[i].filter == EVFILT_TIMER) {
- ngx_time_update();
- continue;
- }
-
-#endif
-
- ev = (ngx_event_t *) event_list[i].udata;
-
- switch (event_list[i].filter) {
-
- case EVFILT_READ:
- case EVFILT_WRITE:
-
- instance = (uintptr_t) ev & 1;
- ev = (ngx_event_t *) ((uintptr_t) ev & (uintptr_t) ~1);
-
- if (ev->closed || ev->instance != instance) {
-
- /*
- * the stale event from a file descriptor
- * that was just closed in this iteration
- */
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "kevent: stale event %p", ev);
- continue;
- }
-
- if (ev->log && (ev->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
- ngx_kqueue_dump_event(ev->log, &event_list[i]);
- }
-
- if (ev->oneshot) {
- ev->active = 0;
- }
-
-#if (NGX_THREADS)
-
- if ((flags & NGX_POST_THREAD_EVENTS) && !ev->accept) {
- ev->posted_ready = 1;
- ev->posted_available = event_list[i].data;
-
- if (event_list[i].flags & EV_EOF) {
- ev->posted_eof = 1;
- ev->posted_errno = event_list[i].fflags;
- }
-
- ngx_locked_post_event(ev, &ngx_posted_events);
-
- continue;
- }
-
-#endif
-
- ev->available = event_list[i].data;
-
- if (event_list[i].flags & EV_EOF) {
- ev->pending_eof = 1;
- ev->kq_errno = event_list[i].fflags;
- }
-
- ev->ready = 1;
-
- break;
-
- case EVFILT_VNODE:
- ev->kq_vnode = 1;
-
- break;
-
- case EVFILT_AIO:
- ev->complete = 1;
- ev->ready = 1;
-
- break;
-
- default:
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "unexpected kevent() filter %d",
- event_list[i].filter);
- continue;
- }
-
- if (flags & NGX_POST_EVENTS) {
- queue = (ngx_event_t **) (ev->accept ? &ngx_posted_accept_events:
- &ngx_posted_events);
- ngx_locked_post_event(ev, queue);
-
- continue;
- }
-
- ev->handler(ev);
- }
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_kqueue_process_changes(ngx_cycle_t *cycle, ngx_uint_t try)
-{
- int n;
- ngx_int_t rc;
- ngx_err_t err;
- struct timespec ts;
- struct kevent *changes;
-
- ngx_mutex_lock(kevent_mutex);
-
- ngx_mutex_lock(list_mutex);
-
- if (nchanges == 0) {
- ngx_mutex_unlock(list_mutex);
- ngx_mutex_unlock(kevent_mutex);
- return NGX_OK;
- }
-
- changes = change_list;
- if (change_list == change_list0) {
- change_list = change_list1;
- } else {
- change_list = change_list0;
- }
-
- n = (int) nchanges;
- nchanges = 0;
-
- ngx_mutex_unlock(list_mutex);
-
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "kevent changes: %d", n);
-
- if (kevent(ngx_kqueue, changes, n, NULL, 0, &ts) == -1) {
- err = ngx_errno;
- ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
- cycle->log, err, "kevent() failed");
- rc = NGX_ERROR;
-
- } else {
- rc = NGX_OK;
- }
-
- ngx_mutex_unlock(kevent_mutex);
-
- return rc;
-}
-
-
-static ngx_inline void
-ngx_kqueue_dump_event(ngx_log_t *log, struct kevent *kev)
-{
- ngx_log_debug6(NGX_LOG_DEBUG_EVENT, log, 0,
- (kev->ident > 0x8000000 && kev->ident != (unsigned) -1) ?
- "kevent: %p: ft:%d fl:%04Xd ff:%08Xd d:%d ud:%p":
- "kevent: %d: ft:%d fl:%04Xd ff:%08Xd d:%d ud:%p",
- kev->ident, kev->filter,
- kev->flags, kev->fflags,
- kev->data, kev->udata);
-}
-
-
-static void *
-ngx_kqueue_create_conf(ngx_cycle_t *cycle)
-{
- ngx_kqueue_conf_t *kcf;
-
- kcf = ngx_palloc(cycle->pool, sizeof(ngx_kqueue_conf_t));
- if (kcf == NULL) {
- return NULL;
- }
-
- kcf->changes = NGX_CONF_UNSET;
- kcf->events = NGX_CONF_UNSET;
-
- return kcf;
-}
-
-
-static char *
-ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf)
-{
- ngx_kqueue_conf_t *kcf = conf;
-
- ngx_conf_init_uint_value(kcf->changes, 512);
- ngx_conf_init_uint_value(kcf->events, 512);
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/event/modules/ngx_poll_module.c b/usr.sbin/nginx/src/event/modules/ngx_poll_module.c
deleted file mode 100644
index 4d4521845a8..00000000000
--- a/usr.sbin/nginx/src/event/modules/ngx_poll_module.c
+++ /dev/null
@@ -1,443 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-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, 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 ngx_int_t nevents;
-
-
-static ngx_str_t poll_name = ngx_string("poll");
-
-ngx_event_module_t ngx_poll_module_ctx = {
- &poll_name,
- NULL, /* create configuration */
- ngx_poll_init_conf, /* init configuration */
-
- {
- ngx_poll_add_event, /* add an event */
- ngx_poll_del_event, /* delete an event */
- ngx_poll_add_event, /* enable an event */
- ngx_poll_del_event, /* disable an event */
- NULL, /* add an connection */
- NULL, /* delete an connection */
- NULL, /* process the changes */
- ngx_poll_process_events, /* process the events */
- ngx_poll_init, /* init the events */
- ngx_poll_done /* done the events */
- }
-
-};
-
-ngx_module_t ngx_poll_module = {
- NGX_MODULE_V1,
- &ngx_poll_module_ctx, /* module context */
- NULL, /* module directives */
- NGX_EVENT_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-
-static ngx_int_t
-ngx_poll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
-{
- struct pollfd *list;
-
- if (event_list == NULL) {
- nevents = 0;
- }
-
- if (ngx_process >= NGX_PROCESS_WORKER
- || cycle->old_cycle == NULL
- || cycle->old_cycle->connection_n < cycle->connection_n)
- {
- list = ngx_alloc(sizeof(struct pollfd) * cycle->connection_n,
- cycle->log);
- if (list == NULL) {
- return NGX_ERROR;
- }
-
- if (event_list) {
- ngx_memcpy(list, event_list, sizeof(ngx_event_t *) * nevents);
- ngx_free(event_list);
- }
-
- event_list = list;
- }
-
- ngx_io = ngx_os_io;
-
- ngx_event_actions = ngx_poll_module_ctx.actions;
-
- ngx_event_flags = NGX_USE_LEVEL_EVENT|NGX_USE_FD_EVENT;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_poll_done(ngx_cycle_t *cycle)
-{
- ngx_free(event_list);
-
- event_list = NULL;
-}
-
-
-static ngx_int_t
-ngx_poll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
-{
- ngx_event_t *e;
- ngx_connection_t *c;
-
- c = ev->data;
-
- ev->active = 1;
-
- if (ev->index != NGX_INVALID_INDEX) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
- "poll event fd:%d ev:%i is already set", c->fd, event);
- return NGX_OK;
- }
-
- if (event == NGX_READ_EVENT) {
- e = c->write;
-#if (NGX_READ_EVENT != POLLIN)
- event = POLLIN;
-#endif
-
- } else {
- e = c->read;
-#if (NGX_WRITE_EVENT != POLLOUT)
- event = POLLOUT;
-#endif
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "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 = (short) event;
- event_list[nevents].revents = 0;
-
- ev->index = nevents;
- nevents++;
-
- } else {
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "poll add index: %i", e->index);
-
- event_list[e->index].events |= (short) event;
- ev->index = e->index;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_poll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
-{
- ngx_event_t *e;
- ngx_connection_t *c;
-
- c = ev->data;
-
- ev->active = 0;
-
- if (ev->index == NGX_INVALID_INDEX) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
- "poll event fd:%d ev:%i is already deleted",
- c->fd, event);
- return NGX_OK;
- }
-
- if (event == NGX_READ_EVENT) {
- e = c->write;
-#if (NGX_READ_EVENT != POLLIN)
- event = POLLIN;
-#endif
-
- } else {
- e = c->read;
-#if (NGX_WRITE_EVENT != POLLOUT)
- event = POLLOUT;
-#endif
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "poll del event: fd:%d ev:%i", c->fd, event);
-
- if (e == NULL || e->index == NGX_INVALID_INDEX) {
- nevents--;
-
- if (ev->index < (ngx_uint_t) nevents) {
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "index: copy event %ui to %i", nevents, ev->index);
-
- event_list[ev->index] = event_list[nevents];
-
- c = ngx_cycle->files[event_list[nevents].fd];
-
- if (c->fd == -1) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
- "unexpected last event");
-
- } else {
- if (c->read->index == (ngx_uint_t) nevents) {
- c->read->index = ev->index;
- }
-
- if (c->write->index == (ngx_uint_t) nevents) {
- c->write->index = ev->index;
- }
- }
- }
-
- } else {
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "poll del index: %i", e->index);
-
- event_list[e->index].events &= (short) ~event;
- }
-
- ev->index = NGX_INVALID_INDEX;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
-{
- int ready, revents;
- ngx_err_t err;
- ngx_int_t i, nready;
- ngx_uint_t found, level;
- ngx_event_t *ev, **queue;
- ngx_connection_t *c;
-
- /* NGX_TIMER_INFINITE == INFTIM */
-
-#if (NGX_DEBUG0)
- if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) {
- for (i = 0; i < nevents; i++) {
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "poll: %d: fd:%d ev:%04Xd",
- i, event_list[i].fd, event_list[i].events);
- }
- }
-#endif
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "poll timer: %M", timer);
-
- ready = poll(event_list, (u_int) nevents, (int) timer);
-
- err = (ready == -1) ? ngx_errno : 0;
-
- if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
- ngx_time_update();
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "poll ready %d of %d", ready, nevents);
-
- if (err) {
- if (err == NGX_EINTR) {
-
- if (ngx_event_timer_alarm) {
- ngx_event_timer_alarm = 0;
- return NGX_OK;
- }
-
- level = NGX_LOG_INFO;
-
- } else {
- level = NGX_LOG_ALERT;
- }
-
- ngx_log_error(level, cycle->log, err, "poll() failed");
- return NGX_ERROR;
- }
-
- if (ready == 0) {
- if (timer != NGX_TIMER_INFINITE) {
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "poll() returned no events without timeout");
- return NGX_ERROR;
- }
-
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- nready = 0;
-
- for (i = 0; i < nevents && ready; i++) {
-
- revents = event_list[i].revents;
-
-#if 1
- ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "poll: %d: fd:%d ev:%04Xd rev:%04Xd",
- i, event_list[i].fd, event_list[i].events, revents);
-#else
- if (revents) {
- ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "poll: %d: fd:%d ev:%04Xd rev:%04Xd",
- i, event_list[i].fd, event_list[i].events, revents);
- }
-#endif
-
- if (revents & POLLNVAL) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "poll() error fd:%d ev:%04Xd rev:%04Xd",
- event_list[i].fd, event_list[i].events, revents);
- }
-
- if (revents & ~(POLLIN|POLLOUT|POLLERR|POLLHUP|POLLNVAL)) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "strange poll() events fd:%d ev:%04Xd rev:%04Xd",
- event_list[i].fd, event_list[i].events, revents);
- }
-
- if (event_list[i].fd == -1) {
- /*
- * the disabled event, a workaround for our possible bug,
- * see the comment below
- */
- continue;
- }
-
- c = ngx_cycle->files[event_list[i].fd];
-
- if (c->fd == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unexpected event");
-
- /*
- * it is certainly our fault and it should be investigated,
- * in the meantime we disable this event to avoid a CPU spinning
- */
-
- if (i == nevents - 1) {
- nevents--;
- } else {
- event_list[i].fd = -1;
- }
-
- continue;
- }
-
- if ((revents & (POLLERR|POLLHUP|POLLNVAL))
- && (revents & (POLLIN|POLLOUT)) == 0)
- {
- /*
- * if the error events were returned without POLLIN or POLLOUT,
- * then add these flags to handle the events at least in one
- * active handler
- */
-
- revents |= POLLIN|POLLOUT;
- }
-
- found = 0;
-
- if ((revents & POLLIN) && c->read->active) {
- found = 1;
-
- ev = c->read;
-
- if ((flags & NGX_POST_THREAD_EVENTS) && !ev->accept) {
- ev->posted_ready = 1;
-
- } else {
- ev->ready = 1;
- }
-
- queue = (ngx_event_t **) (ev->accept ? &ngx_posted_accept_events:
- &ngx_posted_events);
- ngx_locked_post_event(ev, queue);
- }
-
- if ((revents & POLLOUT) && c->write->active) {
- found = 1;
- ev = c->write;
-
- if (flags & NGX_POST_THREAD_EVENTS) {
- ev->posted_ready = 1;
-
- } else {
- ev->ready = 1;
- }
-
- ngx_locked_post_event(ev, &ngx_posted_events);
- }
-
- if (found) {
- ready--;
- continue;
- }
- }
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- if (ready != 0) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "poll ready != events");
- }
-
- return nready;
-}
-
-
-static char *
-ngx_poll_init_conf(ngx_cycle_t *cycle, void *conf)
-{
- ngx_event_conf_t *ecf;
-
- ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
-
- if (ecf->use != ngx_poll_module.ctx_index) {
- return NGX_CONF_OK;
- }
-
-#if (NGX_THREADS)
-
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
- "poll() is not supported in the threaded mode");
- return NGX_CONF_ERROR;
-
-#else
-
- return NGX_CONF_OK;
-
-#endif
-}
diff --git a/usr.sbin/nginx/src/event/modules/ngx_rtsig_module.c b/usr.sbin/nginx/src/event/modules/ngx_rtsig_module.c
deleted file mode 100644
index b36230c7650..00000000000
--- a/usr.sbin/nginx/src/event/modules/ngx_rtsig_module.c
+++ /dev/null
@@ -1,747 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#if (NGX_TEST_BUILD_RTSIG)
-
-#if (NGX_DARWIN)
-
-#define SIGRTMIN 33
-#define si_fd __pad[0]
-
-#else
-
-#ifdef SIGRTMIN
-#define si_fd _reason.__spare__.__spare2__[0]
-#else
-#define SIGRTMIN 33
-#define si_fd __spare__[0]
-#endif
-
-#endif
-
-#define F_SETSIG 10
-#define KERN_RTSIGNR 30
-#define KERN_RTSIGMAX 31
-
-int sigtimedwait(const sigset_t *set, siginfo_t *info,
- const struct timespec *timeout);
-
-int sigtimedwait(const sigset_t *set, siginfo_t *info,
- const struct timespec *timeout)
-{
- return -1;
-}
-
-int ngx_linux_rtsig_max;
-
-#endif
-
-
-typedef struct {
- ngx_uint_t signo;
- ngx_uint_t overflow_events;
- ngx_uint_t overflow_test;
- ngx_uint_t overflow_threshold;
-} ngx_rtsig_conf_t;
-
-
-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,
- 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,
- ngx_msec_t timer, ngx_uint_t flags);
-
-static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle);
-static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf);
-static char *ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf,
- void *post, void *data);
-
-
-static sigset_t set;
-static ngx_uint_t overflow, overflow_current;
-static struct pollfd *overflow_list;
-
-
-static ngx_str_t rtsig_name = ngx_string("rtsig");
-
-static ngx_conf_num_bounds_t ngx_overflow_threshold_bounds = {
- ngx_check_ngx_overflow_threshold_bounds, 2, 10
-};
-
-
-static ngx_command_t ngx_rtsig_commands[] = {
-
- { ngx_string("rtsig_signo"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_rtsig_conf_t, signo),
- NULL },
-
- { ngx_string("rtsig_overflow_events"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_rtsig_conf_t, overflow_events),
- NULL },
-
- { ngx_string("rtsig_overflow_test"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_rtsig_conf_t, overflow_test),
- NULL },
-
- { ngx_string("rtsig_overflow_threshold"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- 0,
- offsetof(ngx_rtsig_conf_t, overflow_threshold),
- &ngx_overflow_threshold_bounds },
-
- ngx_null_command
-};
-
-
-ngx_event_module_t ngx_rtsig_module_ctx = {
- &rtsig_name,
- ngx_rtsig_create_conf, /* create configuration */
- ngx_rtsig_init_conf, /* init configuration */
-
- {
- NULL, /* add an event */
- NULL, /* delete an event */
- NULL, /* enable an event */
- NULL, /* disable an event */
- ngx_rtsig_add_connection, /* add an connection */
- ngx_rtsig_del_connection, /* delete an connection */
- NULL, /* process the changes */
- ngx_rtsig_process_events, /* process the events */
- ngx_rtsig_init, /* init the events */
- ngx_rtsig_done, /* done the events */
- }
-
-};
-
-ngx_module_t ngx_rtsig_module = {
- NGX_MODULE_V1,
- &ngx_rtsig_module_ctx, /* module context */
- ngx_rtsig_commands, /* module directives */
- NGX_EVENT_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer)
-{
- ngx_rtsig_conf_t *rtscf;
-
- rtscf = ngx_event_get_conf(cycle->conf_ctx, ngx_rtsig_module);
-
- sigemptyset(&set);
- sigaddset(&set, (int) rtscf->signo);
- sigaddset(&set, (int) rtscf->signo + 1);
- sigaddset(&set, SIGIO);
- sigaddset(&set, SIGALRM);
-
- if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "sigprocmask() failed");
- return NGX_ERROR;
- }
-
- if (overflow_list) {
- ngx_free(overflow_list);
- }
-
- overflow_list = ngx_alloc(sizeof(struct pollfd) * rtscf->overflow_events,
- cycle->log);
- if (overflow_list == NULL) {
- return NGX_ERROR;
- }
-
- ngx_io = ngx_os_io;
-
- ngx_event_actions = ngx_rtsig_module_ctx.actions;
-
- ngx_event_flags = NGX_USE_RTSIG_EVENT
- |NGX_USE_GREEDY_EVENT
- |NGX_USE_FD_EVENT;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_rtsig_done(ngx_cycle_t *cycle)
-{
- ngx_free(overflow_list);
-
- overflow_list = NULL;
-}
-
-
-static ngx_int_t
-ngx_rtsig_add_connection(ngx_connection_t *c)
-{
- ngx_uint_t signo;
- ngx_rtsig_conf_t *rtscf;
-
- if (c->read->accept && c->read->disabled) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "rtsig enable connection: fd:%d", c->fd);
-
- if (fcntl(c->fd, F_SETOWN, ngx_pid) == -1) {
- ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
- "fcntl(F_SETOWN) failed");
- return NGX_ERROR;
- }
-
- c->read->active = 1;
- c->read->disabled = 0;
- }
-
- rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
-
- signo = rtscf->signo + c->read->instance;
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "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,
- "fcntl(O_RDWR|O_NONBLOCK|O_ASYNC) failed");
- return NGX_ERROR;
- }
-
- 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;
- }
-
- if (fcntl(c->fd, F_SETOWN, ngx_pid) == -1) {
- ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
- "fcntl(F_SETOWN) failed");
- return NGX_ERROR;
- }
-
-#if (NGX_HAVE_ONESIGFD)
- if (fcntl(c->fd, F_SETAUXFL, O_ONESIGFD) == -1) {
- ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
- "fcntl(F_SETAUXFL) failed");
- return NGX_ERROR;
- }
-#endif
-
- c->read->active = 1;
- c->write->active = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-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);
-
- if ((flags & NGX_DISABLE_EVENT) && c->read->accept) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "rtsig disable connection: fd:%d", c->fd);
-
- c->read->active = 0;
- c->read->disabled = 1;
- return NGX_OK;
- }
-
- if (flags & NGX_CLOSE_EVENT) {
- c->read->active = 0;
- c->write->active = 0;
- return NGX_OK;
- }
-
- if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK) == -1) {
- ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
- "fcntl(O_RDWR|O_NONBLOCK) failed");
- return NGX_ERROR;
- }
-
- c->read->active = 0;
- c->write->active = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
-{
- int signo;
- ngx_int_t instance;
- ngx_err_t err;
- siginfo_t si;
- ngx_event_t *rev, *wev, **queue;
- struct timespec ts, *tp;
- struct sigaction sa;
- ngx_connection_t *c;
- ngx_rtsig_conf_t *rtscf;
-
- if (timer == NGX_TIMER_INFINITE) {
- tp = NULL;
-
- } else {
- ts.tv_sec = timer / 1000;
- ts.tv_nsec = (timer % 1000) * 1000000;
- tp = &ts;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "rtsig timer: %M", timer);
-
- /* Linux's sigwaitinfo() is sigtimedwait() with the NULL timeout pointer */
-
- signo = sigtimedwait(&set, &si, tp);
-
- if (signo == -1) {
- err = ngx_errno;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, err,
- "rtsig signo:%d", signo);
-
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update();
- }
-
- if (err == NGX_EAGAIN) {
-
- /* timeout */
-
- if (timer != NGX_TIMER_INFINITE) {
- return NGX_AGAIN;
- }
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
- "sigtimedwait() returned EAGAIN without timeout");
- return NGX_ERROR;
- }
-
- ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
- cycle->log, err, "sigtimedwait() failed");
- return NGX_ERROR;
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "rtsig signo:%d fd:%d band:%04Xd",
- signo, si.si_fd, si.si_band);
-
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update();
- }
-
- rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
-
- if (signo == (int) rtscf->signo || signo == (int) rtscf->signo + 1) {
-
- if (overflow && (ngx_uint_t) si.si_fd > overflow_current) {
- return NGX_OK;
- }
-
- c = ngx_cycle->files[si.si_fd];
-
- if (c == NULL) {
-
- /* the stale event */
-
- return NGX_OK;
- }
-
- instance = signo - (int) rtscf->signo;
-
- rev = c->read;
-
- if (rev->instance != instance) {
-
- /*
- * the stale event from a file descriptor
- * that was just closed in this iteration
- */
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "rtsig: stale event %p", c);
-
- return NGX_OK;
- }
-
- if ((si.si_band & (POLLIN|POLLHUP|POLLERR)) && rev->active) {
-
- rev->ready = 1;
-
- if (flags & NGX_POST_EVENTS) {
- queue = (ngx_event_t **) (rev->accept ?
- &ngx_posted_accept_events : &ngx_posted_events);
-
- ngx_locked_post_event(rev, queue);
-
- } else {
- rev->handler(rev);
- }
- }
-
- wev = c->write;
-
- if ((si.si_band & (POLLOUT|POLLHUP|POLLERR)) && wev->active) {
-
- wev->ready = 1;
-
- if (flags & NGX_POST_EVENTS) {
- ngx_locked_post_event(wev, &ngx_posted_events);
-
- } else {
- wev->handler(wev);
- }
- }
-
- return NGX_OK;
-
- } else if (signo == SIGALRM) {
-
- ngx_time_update();
-
- return NGX_OK;
-
- } else if (signo == SIGIO) {
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "rt signal queue overflowed");
-
- /* flush the RT signal queue */
-
- ngx_memzero(&sa, sizeof(struct sigaction));
- sa.sa_handler = SIG_DFL;
- sigemptyset(&sa.sa_mask);
-
- if (sigaction(rtscf->signo, &sa, NULL) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "sigaction(%d, SIG_DFL) failed", rtscf->signo);
- }
-
- if (sigaction(rtscf->signo + 1, &sa, NULL) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "sigaction(%d, SIG_DFL) failed", rtscf->signo + 1);
- }
-
- overflow = 1;
- overflow_current = 0;
- ngx_event_actions.process_events = ngx_rtsig_process_overflow;
-
- return NGX_ERROR;
-
- }
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "sigtimedwait() returned unexpected signal: %d", signo);
-
- return NGX_ERROR;
-}
-
-
-static ngx_int_t
-ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
- ngx_uint_t flags)
-{
- int name[2], rtsig_max, rtsig_nr, events, ready;
- size_t len;
- 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;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "rtsig process overflow");
-
- rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
-
- tested = 0;
-
- for ( ;; ) {
-
- n = 0;
- while (n < rtscf->overflow_events) {
-
- if (overflow_current == cycle->connection_n) {
- break;
- }
-
- c = cycle->files[overflow_current++];
-
- if (c == NULL || c->fd == -1) {
- continue;
- }
-
- events = 0;
-
- if (c->read->active && c->read->handler) {
- events |= POLLIN;
- }
-
- if (c->write->active && c->write->handler) {
- events |= POLLOUT;
- }
-
- if (events == 0) {
- continue;
- }
-
- overflow_list[n].fd = c->fd;
- overflow_list[n].events = events;
- overflow_list[n].revents = 0;
- n++;
- }
-
- if (n == 0) {
- break;
- }
-
- for ( ;; ) {
- ready = poll(overflow_list, n, 0);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "rtsig overflow poll:%d", ready);
-
- if (ready == -1) {
- err = ngx_errno;
- ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
- cycle->log, 0,
- "poll() failed while the overflow recover");
-
- if (err == NGX_EINTR) {
- continue;
- }
- }
-
- break;
- }
-
- if (ready <= 0) {
- continue;
- }
-
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- for (i = 0; i < n; i++) {
- c = cycle->files[overflow_list[i].fd];
-
- if (c == NULL) {
- continue;
- }
-
- rev = c->read;
-
- if (rev->active
- && !rev->closed
- && rev->handler
- && (overflow_list[i].revents
- & (POLLIN|POLLERR|POLLHUP|POLLNVAL)))
- {
- tested++;
-
- if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
- rev->posted_ready = 1;
-
- } else {
- rev->ready = 1;
- }
-
- if (flags & NGX_POST_EVENTS) {
- queue = (ngx_event_t **) (rev->accept ?
- &ngx_posted_accept_events : &ngx_posted_events);
-
- ngx_locked_post_event(rev, queue);
-
- } else {
- rev->handler(rev);
- }
- }
-
- wev = c->write;
-
- if (wev->active
- && !wev->closed
- && wev->handler
- && (overflow_list[i].revents
- & (POLLOUT|POLLERR|POLLHUP|POLLNVAL)))
- {
- tested++;
-
- if (flags & NGX_POST_THREAD_EVENTS) {
- wev->posted_ready = 1;
-
- } else {
- wev->ready = 1;
- }
-
- if (flags & NGX_POST_EVENTS) {
- ngx_locked_post_event(wev, &ngx_posted_events);
-
- } else {
- wev->handler(wev);
- }
- }
- }
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- if (tested >= rtscf->overflow_test) {
-
- if (ngx_linux_rtsig_max) {
-
- /*
- * Check the current rt queue length to prevent
- * the new overflow.
- *
- * learn the "/proc/sys/kernel/rtsig-max" value because
- * it can be changed since the last checking
- */
-
- name[0] = CTL_KERN;
- name[1] = KERN_RTSIGMAX;
- len = sizeof(rtsig_max);
-
- if (sysctl(name, 2, &rtsig_max, &len, NULL, 0) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, errno,
- "sysctl(KERN_RTSIGMAX) failed");
- return NGX_ERROR;
- }
-
- /* name[0] = CTL_KERN; */
- name[1] = KERN_RTSIGNR;
- len = sizeof(rtsig_nr);
-
- if (sysctl(name, 2, &rtsig_nr, &len, NULL, 0) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, errno,
- "sysctl(KERN_RTSIGNR) failed");
- return NGX_ERROR;
- }
-
- /*
- * drain the rt signal queue if the /"proc/sys/kernel/rtsig-nr"
- * is bigger than
- * "/proc/sys/kernel/rtsig-max" / "rtsig_overflow_threshold"
- */
-
- 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);
- while (ngx_rtsig_process_events(cycle, 0, flags) == NGX_OK)
- {
- /* void */
- }
- }
-
- } else {
-
- /*
- * Linux has not KERN_RTSIGMAX since 2.6.6-mm2
- * so drain the rt signal queue unconditionally
- */
-
- while (ngx_rtsig_process_events(cycle, 0, flags) == NGX_OK) {
- /* void */
- }
- }
-
- tested = 0;
- }
- }
-
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update();
- }
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "rt signal queue overflow recovered");
-
- overflow = 0;
- ngx_event_actions.process_events = ngx_rtsig_process_events;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_rtsig_create_conf(ngx_cycle_t *cycle)
-{
- ngx_rtsig_conf_t *rtscf;
-
- rtscf = ngx_palloc(cycle->pool, sizeof(ngx_rtsig_conf_t));
- if (rtscf == NULL) {
- return NULL;
- }
-
- rtscf->signo = NGX_CONF_UNSET;
- rtscf->overflow_events = NGX_CONF_UNSET;
- rtscf->overflow_test = NGX_CONF_UNSET;
- rtscf->overflow_threshold = NGX_CONF_UNSET;
-
- return rtscf;
-}
-
-
-static char *
-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_uint_value(rtscf->signo, SIGRTMIN + 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)
-{
- if (ngx_linux_rtsig_max) {
- return ngx_conf_check_num_bounds(cf, post, data);
- }
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "\"rtsig_overflow_threshold\" is not supported "
- "since Linux 2.6.6-mm2, ignored");
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/event/modules/ngx_select_module.c b/usr.sbin/nginx/src/event/modules/ngx_select_module.c
deleted file mode 100644
index 51690558e91..00000000000
--- a/usr.sbin/nginx/src/event/modules/ngx_select_module.c
+++ /dev/null
@@ -1,435 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-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, 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 void ngx_select_repair_fd_sets(ngx_cycle_t *cycle);
-static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf);
-
-
-static fd_set master_read_fd_set;
-static fd_set master_write_fd_set;
-static fd_set work_read_fd_set;
-static fd_set work_write_fd_set;
-
-static ngx_int_t max_fd;
-static ngx_uint_t nevents;
-
-static ngx_event_t **event_index;
-
-
-static ngx_str_t select_name = ngx_string("select");
-
-ngx_event_module_t ngx_select_module_ctx = {
- &select_name,
- NULL, /* create configuration */
- ngx_select_init_conf, /* init configuration */
-
- {
- ngx_select_add_event, /* add an event */
- ngx_select_del_event, /* delete an event */
- ngx_select_add_event, /* enable an event */
- ngx_select_del_event, /* disable an event */
- NULL, /* add an connection */
- NULL, /* delete an connection */
- NULL, /* process the changes */
- ngx_select_process_events, /* process the events */
- ngx_select_init, /* init the events */
- ngx_select_done /* done the events */
- }
-
-};
-
-ngx_module_t ngx_select_module = {
- NGX_MODULE_V1,
- &ngx_select_module_ctx, /* module context */
- NULL, /* module directives */
- NGX_EVENT_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer)
-{
- ngx_event_t **index;
-
- if (event_index == NULL) {
- FD_ZERO(&master_read_fd_set);
- FD_ZERO(&master_write_fd_set);
- nevents = 0;
- }
-
- if (ngx_process >= NGX_PROCESS_WORKER
- || cycle->old_cycle == NULL
- || cycle->old_cycle->connection_n < cycle->connection_n)
- {
- index = ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n,
- cycle->log);
- if (index == NULL) {
- return NGX_ERROR;
- }
-
- if (event_index) {
- ngx_memcpy(index, event_index, sizeof(ngx_event_t *) * nevents);
- ngx_free(event_index);
- }
-
- event_index = index;
- }
-
- ngx_io = ngx_os_io;
-
- ngx_event_actions = ngx_select_module_ctx.actions;
-
- ngx_event_flags = NGX_USE_LEVEL_EVENT;
-
- max_fd = -1;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_select_done(ngx_cycle_t *cycle)
-{
- ngx_free(event_index);
-
- event_index = NULL;
-}
-
-
-static ngx_int_t
-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:%i", c->fd, event);
-
- if (ev->index != NGX_INVALID_INDEX) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
- "select event fd:%d ev:%i is already set", c->fd, event);
- return NGX_OK;
- }
-
- if ((event == NGX_READ_EVENT && ev->write)
- || (event == NGX_WRITE_EVENT && !ev->write))
- {
- ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
- "invalid select %s event fd:%d ev:%i",
- ev->write ? "write" : "read", c->fd, event);
- return NGX_ERROR;
- }
-
- if (event == NGX_READ_EVENT) {
- FD_SET(c->fd, &master_read_fd_set);
-
- } else if (event == NGX_WRITE_EVENT) {
- FD_SET(c->fd, &master_write_fd_set);
- }
-
- if (max_fd != -1 && max_fd < c->fd) {
- max_fd = c->fd;
- }
-
- ev->active = 1;
-
- event_index[nevents] = ev;
- ev->index = nevents;
- nevents++;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_select_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
-{
- ngx_event_t *e;
- ngx_connection_t *c;
-
- c = ev->data;
-
- ev->active = 0;
-
- if (ev->index == NGX_INVALID_INDEX) {
- return NGX_OK;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "select del event fd:%d ev:%i", c->fd, event);
-
- if (event == NGX_READ_EVENT) {
- FD_CLR(c->fd, &master_read_fd_set);
-
- } else if (event == NGX_WRITE_EVENT) {
- FD_CLR(c->fd, &master_write_fd_set);
- }
-
- if (max_fd == c->fd) {
- max_fd = -1;
- }
-
- if (ev->index < --nevents) {
- e = event_index[nevents];
- event_index[ev->index] = e;
- e->index = ev->index;
- }
-
- ev->index = NGX_INVALID_INDEX;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
- ngx_uint_t flags)
-{
- int ready, nready;
- ngx_err_t err;
- ngx_uint_t i, found;
- ngx_event_t *ev, **queue;
- struct timeval tv, *tp;
- ngx_connection_t *c;
-
- if (max_fd == -1) {
- for (i = 0; i < nevents; i++) {
- c = event_index[i]->data;
- if (max_fd < c->fd) {
- max_fd = c->fd;
- }
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "change max_fd: %d", max_fd);
- }
-
-#if (NGX_DEBUG)
- if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) {
- for (i = 0; i < nevents; i++) {
- ev = event_index[i];
- c = ev->data;
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "select event: fd:%d wr:%d", c->fd, ev->write);
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "max_fd: %d", max_fd);
- }
-#endif
-
- if (timer == NGX_TIMER_INFINITE) {
- tp = NULL;
-
- } else {
- tv.tv_sec = (long) (timer / 1000);
- tv.tv_usec = (long) ((timer % 1000) * 1000);
- tp = &tv;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "select timer: %M", timer);
-
- work_read_fd_set = master_read_fd_set;
- work_write_fd_set = master_write_fd_set;
-
- ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, NULL, tp);
-
- err = (ready == -1) ? ngx_errno : 0;
-
- if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
- ngx_time_update();
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "select ready %d", ready);
-
- if (err) {
- ngx_uint_t level;
-
- if (err == NGX_EINTR) {
-
- if (ngx_event_timer_alarm) {
- ngx_event_timer_alarm = 0;
- return NGX_OK;
- }
-
- level = NGX_LOG_INFO;
-
- } else {
- level = NGX_LOG_ALERT;
- }
-
- ngx_log_error(level, cycle->log, err, "select() failed");
-
- if (err == NGX_EBADF) {
- ngx_select_repair_fd_sets(cycle);
- }
-
- return NGX_ERROR;
- }
-
- if (ready == 0) {
- if (timer != NGX_TIMER_INFINITE) {
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "select() returned no events without timeout");
- return NGX_ERROR;
- }
-
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- nready = 0;
-
- for (i = 0; i < nevents; i++) {
- ev = event_index[i];
- c = ev->data;
- found = 0;
-
- if (ev->write) {
- if (FD_ISSET(c->fd, &work_write_fd_set)) {
- found = 1;
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "select write %d", c->fd);
- }
-
- } else {
- if (FD_ISSET(c->fd, &work_read_fd_set)) {
- found = 1;
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "select read %d", c->fd);
- }
- }
-
- if (found) {
- ev->ready = 1;
-
- queue = (ngx_event_t **) (ev->accept ? &ngx_posted_accept_events:
- &ngx_posted_events);
- ngx_locked_post_event(ev, queue);
-
- nready++;
- }
- }
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- if (ready != nready) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "select ready != events: %d:%d", ready, nready);
-
- ngx_select_repair_fd_sets(cycle);
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_select_repair_fd_sets(ngx_cycle_t *cycle)
-{
- int n;
- socklen_t len;
- ngx_err_t err;
- ngx_socket_t s;
-
- for (s = 0; s <= max_fd; s++) {
-
- if (FD_ISSET(s, &master_read_fd_set) == 0) {
- continue;
- }
-
- len = sizeof(int);
-
- if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) {
- err = ngx_socket_errno;
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
- "invalid descriptor #%d in read fd_set", s);
-
- FD_CLR(s, &master_read_fd_set);
- }
- }
-
- for (s = 0; s <= max_fd; s++) {
-
- if (FD_ISSET(s, &master_write_fd_set) == 0) {
- continue;
- }
-
- len = sizeof(int);
-
- if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) {
- err = ngx_socket_errno;
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
- "invalid descriptor #%d in write fd_set", s);
-
- FD_CLR(s, &master_write_fd_set);
- }
- }
-
- max_fd = -1;
-}
-
-
-static char *
-ngx_select_init_conf(ngx_cycle_t *cycle, void *conf)
-{
- ngx_event_conf_t *ecf;
-
- ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
-
- if (ecf->use != ngx_select_module.ctx_index) {
- return NGX_CONF_OK;
- }
-
- /* disable warning: the default FD_SETSIZE is 1024U in FreeBSD 5.x */
-
- if (cycle->connection_n > FD_SETSIZE) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
- "the maximum number of files "
- "supported by select() is %ud", FD_SETSIZE);
- return NGX_CONF_ERROR;
- }
-
-#if (NGX_THREADS)
-
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
- "select() is not supported in the threaded mode");
- return NGX_CONF_ERROR;
-
-#else
-
- return NGX_CONF_OK;
-
-#endif
-}
diff --git a/usr.sbin/nginx/src/event/modules/ngx_win32_select_module.c b/usr.sbin/nginx/src/event/modules/ngx_win32_select_module.c
deleted file mode 100644
index eb5382d4e0b..00000000000
--- a/usr.sbin/nginx/src/event/modules/ngx_win32_select_module.c
+++ /dev/null
@@ -1,400 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-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, 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 void ngx_select_repair_fd_sets(ngx_cycle_t *cycle);
-static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf);
-
-
-static fd_set master_read_fd_set;
-static fd_set master_write_fd_set;
-static fd_set work_read_fd_set;
-static fd_set work_write_fd_set;
-
-static ngx_uint_t max_read;
-static ngx_uint_t max_write;
-static ngx_uint_t nevents;
-
-static ngx_event_t **event_index;
-
-
-static ngx_str_t select_name = ngx_string("select");
-
-ngx_event_module_t ngx_select_module_ctx = {
- &select_name,
- NULL, /* create configuration */
- ngx_select_init_conf, /* init configuration */
-
- {
- ngx_select_add_event, /* add an event */
- ngx_select_del_event, /* delete an event */
- ngx_select_add_event, /* enable an event */
- ngx_select_del_event, /* disable an event */
- NULL, /* add an connection */
- NULL, /* delete an connection */
- NULL, /* process the changes */
- ngx_select_process_events, /* process the events */
- ngx_select_init, /* init the events */
- ngx_select_done /* done the events */
- }
-
-};
-
-ngx_module_t ngx_select_module = {
- NGX_MODULE_V1,
- &ngx_select_module_ctx, /* module context */
- NULL, /* module directives */
- NGX_EVENT_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer)
-{
- ngx_event_t **index;
-
- if (event_index == NULL) {
- FD_ZERO(&master_read_fd_set);
- FD_ZERO(&master_write_fd_set);
- nevents = 0;
- }
-
- if (ngx_process >= NGX_PROCESS_WORKER
- || cycle->old_cycle == NULL
- || cycle->old_cycle->connection_n < cycle->connection_n)
- {
- index = ngx_alloc(sizeof(ngx_event_t *) * 2 * cycle->connection_n,
- cycle->log);
- if (index == NULL) {
- return NGX_ERROR;
- }
-
- if (event_index) {
- ngx_memcpy(index, event_index, sizeof(ngx_event_t *) * nevents);
- ngx_free(event_index);
- }
-
- event_index = index;
- }
-
- ngx_io = ngx_os_io;
-
- ngx_event_actions = ngx_select_module_ctx.actions;
-
- ngx_event_flags = NGX_USE_LEVEL_EVENT;
-
- max_read = 0;
- max_write = 0;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_select_done(ngx_cycle_t *cycle)
-{
- ngx_free(event_index);
-
- event_index = NULL;
-}
-
-
-static ngx_int_t
-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:%i", c->fd, event);
-
- if (ev->index != NGX_INVALID_INDEX) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
- "select event fd:%d ev:%i is already set", c->fd, event);
- return NGX_OK;
- }
-
- if ((event == NGX_READ_EVENT && ev->write)
- || (event == NGX_WRITE_EVENT && !ev->write))
- {
- ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
- "invalid select %s event fd:%d ev:%i",
- ev->write ? "write" : "read", c->fd, event);
- return NGX_ERROR;
- }
-
- if ((event == NGX_READ_EVENT && max_read >= FD_SETSIZE)
- || (event == NGX_WRITE_EVENT && max_write >= FD_SETSIZE))
- {
- ngx_log_error(NGX_LOG_ERR, ev->log, 0,
- "maximum number of descriptors "
- "supported by select() is %d", FD_SETSIZE);
- return NGX_ERROR;
- }
-
- if (event == NGX_READ_EVENT) {
- FD_SET(c->fd, &master_read_fd_set);
- max_read++;
-
- } else if (event == NGX_WRITE_EVENT) {
- FD_SET(c->fd, &master_write_fd_set);
- max_write++;
- }
-
- ev->active = 1;
-
- event_index[nevents] = ev;
- ev->index = nevents;
- nevents++;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_select_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
-{
- ngx_event_t *e;
- ngx_connection_t *c;
-
- c = ev->data;
-
- ev->active = 0;
-
- if (ev->index == NGX_INVALID_INDEX) {
- return NGX_OK;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "select del event fd:%d ev:%i", c->fd, event);
-
- if (event == NGX_READ_EVENT) {
- FD_CLR(c->fd, &master_read_fd_set);
- max_read--;
-
- } else if (event == NGX_WRITE_EVENT) {
- FD_CLR(c->fd, &master_write_fd_set);
- max_write--;
- }
-
- if (ev->index < --nevents) {
- e = event_index[nevents];
- event_index[ev->index] = e;
- e->index = ev->index;
- }
-
- ev->index = NGX_INVALID_INDEX;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
- ngx_uint_t flags)
-{
- int ready, nready;
- ngx_err_t err;
- ngx_uint_t i, found;
- ngx_event_t *ev, **queue;
- struct timeval tv, *tp;
- ngx_connection_t *c;
-
-#if (NGX_DEBUG)
- if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) {
- for (i = 0; i < nevents; i++) {
- ev = event_index[i];
- c = ev->data;
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "select event: fd:%d wr:%d", c->fd, ev->write);
- }
- }
-#endif
-
- if (timer == NGX_TIMER_INFINITE) {
- tp = NULL;
-
- } else {
- tv.tv_sec = (long) (timer / 1000);
- tv.tv_usec = (long) ((timer % 1000) * 1000);
- tp = &tv;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "select timer: %M", timer);
-
- work_read_fd_set = master_read_fd_set;
- work_write_fd_set = master_write_fd_set;
-
- if (max_read || max_write) {
- ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp);
-
- } else {
-
- /*
- * Winsock select() requires that at least one descriptor set must be
- * be non-null, and any non-null descriptor set must contain at least
- * one handle to a socket. Otherwise select() returns WSAEINVAL.
- */
-
- ngx_msleep(timer);
-
- ready = 0;
- }
-
- err = (ready == -1) ? ngx_socket_errno : 0;
-
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update();
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "select ready %d", ready);
-
- if (err) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, err, "select() failed");
-
- if (err == WSAENOTSOCK) {
- ngx_select_repair_fd_sets(cycle);
- }
-
- return NGX_ERROR;
- }
-
- if (ready == 0) {
- if (timer != NGX_TIMER_INFINITE) {
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "select() returned no events without timeout");
- return NGX_ERROR;
- }
-
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- nready = 0;
-
- for (i = 0; i < nevents; i++) {
- ev = event_index[i];
- c = ev->data;
- found = 0;
-
- if (ev->write) {
- if (FD_ISSET(c->fd, &work_write_fd_set)) {
- found = 1;
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "select write %d", c->fd);
- }
-
- } else {
- if (FD_ISSET(c->fd, &work_read_fd_set)) {
- found = 1;
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "select read %d", c->fd);
- }
- }
-
- if (found) {
- ev->ready = 1;
-
- queue = (ngx_event_t **) (ev->accept ? &ngx_posted_accept_events:
- &ngx_posted_events);
- ngx_locked_post_event(ev, queue);
-
- nready++;
- }
- }
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- if (ready != nready) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "select ready != events: %d:%d", ready, nready);
-
- ngx_select_repair_fd_sets(cycle);
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_select_repair_fd_sets(ngx_cycle_t *cycle)
-{
- int n;
- u_int i;
- socklen_t len;
- ngx_err_t err;
- ngx_socket_t s;
-
- for (i = 0; i < master_read_fd_set.fd_count; i++) {
-
- s = master_read_fd_set.fd_array[i];
- len = sizeof(int);
-
- if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &n, &len) == -1) {
- err = ngx_socket_errno;
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
- "invalid descriptor #%d in read fd_set", s);
-
- FD_CLR(s, &master_read_fd_set);
- }
- }
-
- for (i = 0; i < master_write_fd_set.fd_count; i++) {
-
- s = master_write_fd_set.fd_array[i];
- len = sizeof(int);
-
- if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &n, &len) == -1) {
- err = ngx_socket_errno;
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
- "invalid descriptor #%d in write fd_set", s);
-
- FD_CLR(s, &master_write_fd_set);
- }
- }
-}
-
-
-static char *
-ngx_select_init_conf(ngx_cycle_t *cycle, void *conf)
-{
- ngx_event_conf_t *ecf;
-
- ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
-
- if (ecf->use != ngx_select_module.ctx_index) {
- return NGX_CONF_OK;
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/event/ngx_event.c b/usr.sbin/nginx/src/event/ngx_event.c
deleted file mode 100644
index e2857f0c05c..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event.c
+++ /dev/null
@@ -1,1339 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#define DEFAULT_CONNECTIONS 512
-
-
-extern ngx_module_t ngx_kqueue_module;
-extern ngx_module_t ngx_eventport_module;
-extern ngx_module_t ngx_devpoll_module;
-extern ngx_module_t ngx_epoll_module;
-extern ngx_module_t ngx_rtsig_module;
-extern ngx_module_t ngx_select_module;
-
-
-static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf);
-static ngx_int_t ngx_event_module_init(ngx_cycle_t *cycle);
-static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle);
-static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-
-static char *ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static char *ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-static void *ngx_event_core_create_conf(ngx_cycle_t *cycle);
-static char *ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf);
-
-
-static ngx_uint_t ngx_timer_resolution;
-sig_atomic_t ngx_event_timer_alarm;
-
-static ngx_uint_t ngx_event_max_module;
-
-ngx_uint_t ngx_event_flags;
-ngx_event_actions_t ngx_event_actions;
-
-
-static ngx_atomic_t connection_counter = 1;
-ngx_atomic_t *ngx_connection_counter = &connection_counter;
-
-
-ngx_atomic_t *ngx_accept_mutex_ptr;
-ngx_shmtx_t ngx_accept_mutex;
-ngx_uint_t ngx_use_accept_mutex;
-ngx_uint_t ngx_accept_events;
-ngx_uint_t ngx_accept_mutex_held;
-ngx_msec_t ngx_accept_mutex_delay;
-ngx_int_t ngx_accept_disabled;
-
-
-#if (NGX_STAT_STUB)
-
-ngx_atomic_t ngx_stat_accepted0;
-ngx_atomic_t *ngx_stat_accepted = &ngx_stat_accepted0;
-ngx_atomic_t ngx_stat_handled0;
-ngx_atomic_t *ngx_stat_handled = &ngx_stat_handled0;
-ngx_atomic_t ngx_stat_requests0;
-ngx_atomic_t *ngx_stat_requests = &ngx_stat_requests0;
-ngx_atomic_t ngx_stat_active0;
-ngx_atomic_t *ngx_stat_active = &ngx_stat_active0;
-ngx_atomic_t ngx_stat_reading0;
-ngx_atomic_t *ngx_stat_reading = &ngx_stat_reading0;
-ngx_atomic_t ngx_stat_writing0;
-ngx_atomic_t *ngx_stat_writing = &ngx_stat_writing0;
-ngx_atomic_t ngx_stat_waiting0;
-ngx_atomic_t *ngx_stat_waiting = &ngx_stat_waiting0;
-
-#endif
-
-
-
-static ngx_command_t ngx_events_commands[] = {
-
- { ngx_string("events"),
- NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
- ngx_events_block,
- 0,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_core_module_t ngx_events_module_ctx = {
- ngx_string("events"),
- NULL,
- ngx_event_init_conf
-};
-
-
-ngx_module_t ngx_events_module = {
- NGX_MODULE_V1,
- &ngx_events_module_ctx, /* module context */
- ngx_events_commands, /* module directives */
- NGX_CORE_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_str_t event_core_name = ngx_string("event_core");
-
-
-static ngx_command_t ngx_event_core_commands[] = {
-
- { ngx_string("worker_connections"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_event_connections,
- 0,
- 0,
- NULL },
-
- { ngx_string("connections"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_event_connections,
- 0,
- 0,
- NULL },
-
- { ngx_string("use"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_event_use,
- 0,
- 0,
- NULL },
-
- { ngx_string("multi_accept"),
- NGX_EVENT_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- 0,
- offsetof(ngx_event_conf_t, multi_accept),
- NULL },
-
- { ngx_string("accept_mutex"),
- NGX_EVENT_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- 0,
- offsetof(ngx_event_conf_t, accept_mutex),
- NULL },
-
- { ngx_string("accept_mutex_delay"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- 0,
- offsetof(ngx_event_conf_t, accept_mutex_delay),
- NULL },
-
- { ngx_string("debug_connection"),
- NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_event_debug_connection,
- 0,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-ngx_event_module_t ngx_event_core_module_ctx = {
- &event_core_name,
- ngx_event_core_create_conf, /* create configuration */
- ngx_event_core_init_conf, /* init configuration */
-
- { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-
-ngx_module_t ngx_event_core_module = {
- NGX_MODULE_V1,
- &ngx_event_core_module_ctx, /* module context */
- ngx_event_core_commands, /* module directives */
- NGX_EVENT_MODULE, /* module type */
- NULL, /* init master */
- ngx_event_module_init, /* init module */
- ngx_event_process_init, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-void
-ngx_process_events_and_timers(ngx_cycle_t *cycle)
-{
- ngx_uint_t flags;
- ngx_msec_t timer, delta;
-
- if (ngx_timer_resolution) {
- timer = NGX_TIMER_INFINITE;
- flags = 0;
-
- } else {
- timer = ngx_event_find_timer();
- flags = NGX_UPDATE_TIME;
-
-#if (NGX_THREADS)
-
- if (timer == NGX_TIMER_INFINITE || timer > 500) {
- timer = 500;
- }
-
-#endif
- }
-
- if (ngx_use_accept_mutex) {
- if (ngx_accept_disabled > 0) {
- ngx_accept_disabled--;
-
- } else {
- if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
- return;
- }
-
- if (ngx_accept_mutex_held) {
- flags |= NGX_POST_EVENTS;
-
- } else {
- if (timer == NGX_TIMER_INFINITE
- || timer > ngx_accept_mutex_delay)
- {
- timer = ngx_accept_mutex_delay;
- }
- }
- }
- }
-
- delta = ngx_current_msec;
-
- (void) ngx_process_events(cycle, timer, flags);
-
- delta = ngx_current_msec - delta;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "timer delta: %M", delta);
-
- if (ngx_posted_accept_events) {
- ngx_event_process_posted(cycle, &ngx_posted_accept_events);
- }
-
- if (ngx_accept_mutex_held) {
- ngx_shmtx_unlock(&ngx_accept_mutex);
- }
-
- if (delta) {
- ngx_event_expire_timers();
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "posted events %p", ngx_posted_events);
-
- if (ngx_posted_events) {
- if (ngx_threaded) {
- ngx_wakeup_worker_thread(cycle);
-
- } else {
- ngx_event_process_posted(cycle, &ngx_posted_events);
- }
- }
-}
-
-
-ngx_int_t
-ngx_handle_read_event(ngx_event_t *rev, ngx_uint_t flags)
-{
- if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
-
- /* kqueue, epoll */
-
- if (!rev->active && !rev->ready) {
- if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT)
- == NGX_ERROR)
- {
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
-
- } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
-
- /* select, poll, /dev/poll */
-
- if (!rev->active && !rev->ready) {
- if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT)
- == NGX_ERROR)
- {
- return NGX_ERROR;
- }
-
- return NGX_OK;
- }
-
- if (rev->active && (rev->ready || (flags & NGX_CLOSE_EVENT))) {
- if (ngx_del_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT | flags)
- == NGX_ERROR)
- {
- return NGX_ERROR;
- }
-
- return NGX_OK;
- }
-
- } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
-
- /* event ports */
-
- if (!rev->active && !rev->ready) {
- if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
- }
-
- if (rev->oneshot && !rev->ready) {
- if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
- }
- }
-
- /* aio, iocp, rtsig */
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_handle_write_event(ngx_event_t *wev, size_t lowat)
-{
- ngx_connection_t *c;
-
- if (lowat) {
- c = wev->data;
-
- if (ngx_send_lowat(c, lowat) == NGX_ERROR) {
- return NGX_ERROR;
- }
- }
-
- if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
-
- /* kqueue, epoll */
-
- if (!wev->active && !wev->ready) {
- if (ngx_add_event(wev, NGX_WRITE_EVENT,
- NGX_CLEAR_EVENT | (lowat ? NGX_LOWAT_EVENT : 0))
- == NGX_ERROR)
- {
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
-
- } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
-
- /* select, poll, /dev/poll */
-
- if (!wev->active && !wev->ready) {
- if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
- == NGX_ERROR)
- {
- return NGX_ERROR;
- }
-
- return NGX_OK;
- }
-
- if (wev->active && wev->ready) {
- if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
- == NGX_ERROR)
- {
- return NGX_ERROR;
- }
-
- return NGX_OK;
- }
-
- } else if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
-
- /* event ports */
-
- if (!wev->active && !wev->ready) {
- if (ngx_add_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
- }
-
- if (wev->oneshot && wev->ready) {
- if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
- }
- }
-
- /* aio, iocp, rtsig */
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
-{
- if (ngx_get_conf(cycle->conf_ctx, ngx_events_module) == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
- "no \"events\" section in configuration");
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_event_module_init(ngx_cycle_t *cycle)
-{
- void ***cf;
- u_char *shared;
- size_t size, cl;
- ngx_shm_t shm;
- ngx_time_t *tp;
- ngx_core_conf_t *ccf;
- ngx_event_conf_t *ecf;
-
- cf = ngx_get_conf(cycle->conf_ctx, ngx_events_module);
- ecf = (*cf)[ngx_event_core_module.ctx_index];
-
- if (!ngx_test_config && ngx_process <= NGX_PROCESS_MASTER) {
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
- "using the \"%s\" event method", ecf->name);
- }
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-
- ngx_timer_resolution = ccf->timer_resolution;
-
-#if !(NGX_WIN32)
- {
- ngx_int_t limit;
- struct rlimit rlmt;
-
- if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "getrlimit(RLIMIT_NOFILE) failed, ignored");
-
- } else {
- if (ecf->connections > (ngx_uint_t) rlmt.rlim_cur
- && (ccf->rlimit_nofile == NGX_CONF_UNSET
- || ecf->connections > (ngx_uint_t) ccf->rlimit_nofile))
- {
- limit = (ccf->rlimit_nofile == NGX_CONF_UNSET) ?
- (ngx_int_t) rlmt.rlim_cur : ccf->rlimit_nofile;
-
- ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
- "%ui worker_connections exceed "
- "open file resource limit: %i",
- ecf->connections, limit);
- }
- }
- }
-#endif /* !(NGX_WIN32) */
-
-
- if (ccf->master == 0) {
- return NGX_OK;
- }
-
- if (ngx_accept_mutex_ptr) {
- return NGX_OK;
- }
-
-
- /* cl should be equal to or greater than cache line size */
-
- cl = 128;
-
- size = cl /* ngx_accept_mutex */
- + cl /* ngx_connection_counter */
- + cl; /* ngx_temp_number */
-
-#if (NGX_STAT_STUB)
-
- size += cl /* ngx_stat_accepted */
- + cl /* ngx_stat_handled */
- + cl /* ngx_stat_requests */
- + cl /* ngx_stat_active */
- + cl /* ngx_stat_reading */
- + cl /* ngx_stat_writing */
- + cl; /* ngx_stat_waiting */
-
-#endif
-
- shm.size = size;
- shm.name.len = sizeof("nginx_shared_zone");
- shm.name.data = (u_char *) "nginx_shared_zone";
- shm.log = cycle->log;
-
- if (ngx_shm_alloc(&shm) != NGX_OK) {
- return NGX_ERROR;
- }
-
- shared = shm.addr;
-
- ngx_accept_mutex_ptr = (ngx_atomic_t *) shared;
- ngx_accept_mutex.spin = (ngx_uint_t) -1;
-
- if (ngx_shmtx_create(&ngx_accept_mutex, (ngx_shmtx_sh_t *) shared,
- cycle->lock_file.data)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl);
-
- (void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1);
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "counter: %p, %d",
- ngx_connection_counter, *ngx_connection_counter);
-
- ngx_temp_number = (ngx_atomic_t *) (shared + 2 * cl);
-
- tp = ngx_timeofday();
-
- ngx_random_number = (tp->msec << 16) + ngx_pid;
-
-#if (NGX_STAT_STUB)
-
- ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * cl);
- ngx_stat_handled = (ngx_atomic_t *) (shared + 4 * cl);
- ngx_stat_requests = (ngx_atomic_t *) (shared + 5 * cl);
- ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl);
- ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl);
- ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl);
- ngx_stat_waiting = (ngx_atomic_t *) (shared + 9 * cl);
-
-#endif
-
- return NGX_OK;
-}
-
-
-#if !(NGX_WIN32)
-
-static void
-ngx_timer_signal_handler(int signo)
-{
- ngx_event_timer_alarm = 1;
-
-#if 1
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal");
-#endif
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_event_process_init(ngx_cycle_t *cycle)
-{
- ngx_uint_t m, i;
- ngx_event_t *rev, *wev;
- ngx_listening_t *ls;
- ngx_connection_t *c, *next, *old;
- ngx_core_conf_t *ccf;
- ngx_event_conf_t *ecf;
- ngx_event_module_t *module;
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
- ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
-
- if (ccf->master && ccf->worker_processes > 1 && ecf->accept_mutex) {
- ngx_use_accept_mutex = 1;
- ngx_accept_mutex_held = 0;
- ngx_accept_mutex_delay = ecf->accept_mutex_delay;
-
- } else {
- ngx_use_accept_mutex = 0;
- }
-
-#if (NGX_WIN32)
-
- /*
- * disable accept mutex on win32 as it may cause deadlock if
- * grabbed by a process which can't accept connections
- */
-
- ngx_use_accept_mutex = 0;
-
-#endif
-
-#if (NGX_THREADS)
- ngx_posted_events_mutex = ngx_mutex_init(cycle->log, 0);
- if (ngx_posted_events_mutex == NULL) {
- return NGX_ERROR;
- }
-#endif
-
- if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
- continue;
- }
-
- if (ngx_modules[m]->ctx_index != ecf->use) {
- continue;
- }
-
- module = ngx_modules[m]->ctx;
-
- if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
- /* fatal */
- exit(2);
- }
-
- break;
- }
-
-#if !(NGX_WIN32)
-
- if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) {
- struct sigaction sa;
- struct itimerval itv;
-
- ngx_memzero(&sa, sizeof(struct sigaction));
- sa.sa_handler = ngx_timer_signal_handler;
- sigemptyset(&sa.sa_mask);
-
- if (sigaction(SIGALRM, &sa, NULL) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "sigaction(SIGALRM) failed");
- return NGX_ERROR;
- }
-
- itv.it_interval.tv_sec = ngx_timer_resolution / 1000;
- itv.it_interval.tv_usec = (ngx_timer_resolution % 1000) * 1000;
- itv.it_value.tv_sec = ngx_timer_resolution / 1000;
- itv.it_value.tv_usec = (ngx_timer_resolution % 1000 ) * 1000;
-
- if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "setitimer() failed");
- }
- }
-
- if (ngx_event_flags & NGX_USE_FD_EVENT) {
- struct rlimit rlmt;
-
- if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "getrlimit(RLIMIT_NOFILE) failed");
- return NGX_ERROR;
- }
-
- cycle->files_n = (ngx_uint_t) rlmt.rlim_cur;
-
- cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n,
- cycle->log);
- if (cycle->files == NULL) {
- return NGX_ERROR;
- }
- }
-
-#endif
-
- cycle->connections =
- ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);
- if (cycle->connections == NULL) {
- return NGX_ERROR;
- }
-
- c = cycle->connections;
-
- cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
- cycle->log);
- if (cycle->read_events == NULL) {
- return NGX_ERROR;
- }
-
- rev = cycle->read_events;
- for (i = 0; i < cycle->connection_n; i++) {
- rev[i].closed = 1;
- rev[i].instance = 1;
-#if (NGX_THREADS)
- rev[i].lock = &c[i].lock;
- rev[i].own_lock = &c[i].lock;
-#endif
- }
-
- cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
- cycle->log);
- if (cycle->write_events == NULL) {
- return NGX_ERROR;
- }
-
- wev = cycle->write_events;
- for (i = 0; i < cycle->connection_n; i++) {
- wev[i].closed = 1;
-#if (NGX_THREADS)
- wev[i].lock = &c[i].lock;
- wev[i].own_lock = &c[i].lock;
-#endif
- }
-
- i = cycle->connection_n;
- next = NULL;
-
- do {
- i--;
-
- c[i].data = next;
- c[i].read = &cycle->read_events[i];
- c[i].write = &cycle->write_events[i];
- c[i].fd = (ngx_socket_t) -1;
-
- next = &c[i];
-
-#if (NGX_THREADS)
- c[i].lock = 0;
-#endif
- } while (i);
-
- cycle->free_connections = next;
- cycle->free_connection_n = cycle->connection_n;
-
- /* for each listening socket */
-
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
-
- c = ngx_get_connection(ls[i].fd, cycle->log);
-
- if (c == NULL) {
- return NGX_ERROR;
- }
-
- c->log = &ls[i].log;
-
- c->listening = &ls[i];
- ls[i].connection = c;
-
- rev = c->read;
-
- rev->log = c->log;
- rev->accept = 1;
-
-#if (NGX_HAVE_DEFERRED_ACCEPT)
- rev->deferred_accept = ls[i].deferred_accept;
-#endif
-
- if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
- if (ls[i].previous) {
-
- /*
- * delete the old accept events that were bound to
- * the old cycle read events array
- */
-
- old = ls[i].previous->connection;
-
- if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT)
- == NGX_ERROR)
- {
- return NGX_ERROR;
- }
-
- old->fd = (ngx_socket_t) -1;
- }
- }
-
-#if (NGX_WIN32)
-
- if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
- ngx_iocp_conf_t *iocpcf;
-
- rev->handler = ngx_event_acceptex;
-
- if (ngx_use_accept_mutex) {
- continue;
- }
-
- if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- ls[i].log.handler = ngx_acceptex_log_error;
-
- iocpcf = ngx_event_get_conf(cycle->conf_ctx, ngx_iocp_module);
- if (ngx_event_post_acceptex(&ls[i], iocpcf->post_acceptex)
- == NGX_ERROR)
- {
- return NGX_ERROR;
- }
-
- } else {
- rev->handler = ngx_event_accept;
-
- if (ngx_use_accept_mutex) {
- continue;
- }
-
- if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
- return NGX_ERROR;
- }
- }
-
-#else
-
- rev->handler = ngx_event_accept;
-
- if (ngx_use_accept_mutex) {
- continue;
- }
-
- if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
- if (ngx_add_conn(c) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- } else {
- if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
- return NGX_ERROR;
- }
- }
-
-#endif
-
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_send_lowat(ngx_connection_t *c, size_t lowat)
-{
- int sndlowat;
-
-#if (NGX_HAVE_LOWAT_EVENT)
-
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
- c->write->available = lowat;
- return NGX_OK;
- }
-
-#endif
-
- if (lowat == 0 || c->sndlowat) {
- return NGX_OK;
- }
-
- sndlowat = (int) lowat;
-
- if (setsockopt(c->fd, SOL_SOCKET, SO_SNDLOWAT,
- (const void *) &sndlowat, sizeof(int))
- == -1)
- {
- ngx_connection_error(c, ngx_socket_errno,
- "setsockopt(SO_SNDLOWAT) failed");
- return NGX_ERROR;
- }
-
- c->sndlowat = 1;
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *rv;
- void ***ctx;
- ngx_uint_t i;
- ngx_conf_t pcf;
- ngx_event_module_t *m;
-
- if (*(void **) conf) {
- return "is duplicate";
- }
-
- /* count the number of the event modules and set up their indices */
-
- ngx_event_max_module = 0;
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
- continue;
- }
-
- ngx_modules[i]->ctx_index = ngx_event_max_module++;
- }
-
- ctx = ngx_pcalloc(cf->pool, sizeof(void *));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *));
- if (*ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *(void **) conf = ctx;
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
- continue;
- }
-
- m = ngx_modules[i]->ctx;
-
- if (m->create_conf) {
- (*ctx)[ngx_modules[i]->ctx_index] = m->create_conf(cf->cycle);
- if ((*ctx)[ngx_modules[i]->ctx_index] == NULL) {
- return NGX_CONF_ERROR;
- }
- }
- }
-
- pcf = *cf;
- cf->ctx = ctx;
- cf->module_type = NGX_EVENT_MODULE;
- cf->cmd_type = NGX_EVENT_CONF;
-
- rv = ngx_conf_parse(cf, NULL);
-
- *cf = pcf;
-
- if (rv != NGX_CONF_OK)
- return rv;
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
- continue;
- }
-
- m = ngx_modules[i]->ctx;
-
- if (m->init_conf) {
- rv = m->init_conf(cf->cycle, (*ctx)[ngx_modules[i]->ctx_index]);
- if (rv != NGX_CONF_OK) {
- return rv;
- }
- }
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_event_connections(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_event_conf_t *ecf = conf;
-
- ngx_str_t *value;
-
- if (ecf->connections != NGX_CONF_UNSET_UINT) {
- return "is duplicate";
- }
-
- if (ngx_strcmp(cmd->name.data, "connections") == 0) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "the \"connections\" directive is deprecated, "
- "use the \"worker_connections\" directive instead");
- }
-
- value = cf->args->elts;
- ecf->connections = ngx_atoi(value[1].data, value[1].len);
- if (ecf->connections == (ngx_uint_t) NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid number \"%V\"", &value[1]);
-
- return NGX_CONF_ERROR;
- }
-
- cf->cycle->connection_n = ecf->connections;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_event_conf_t *ecf = conf;
-
- ngx_int_t m;
- ngx_str_t *value;
- ngx_event_conf_t *old_ecf;
- ngx_event_module_t *module;
-
- if (ecf->use != NGX_CONF_UNSET_UINT) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- if (cf->cycle->old_cycle->conf_ctx) {
- old_ecf = ngx_event_get_conf(cf->cycle->old_cycle->conf_ctx,
- ngx_event_core_module);
- } else {
- old_ecf = NULL;
- }
-
-
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_EVENT_MODULE) {
- continue;
- }
-
- module = ngx_modules[m]->ctx;
- if (module->name->len == value[1].len) {
- if (ngx_strcmp(module->name->data, value[1].data) == 0) {
- ecf->use = ngx_modules[m]->ctx_index;
- ecf->name = module->name->data;
-
- if (ngx_process == NGX_PROCESS_SINGLE
- && old_ecf
- && old_ecf->use != ecf->use)
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "when the server runs without a master process "
- "the \"%V\" event type must be the same as "
- "in previous configuration - \"%s\" "
- "and it cannot be changed on the fly, "
- "to change it you need to stop server "
- "and start it again",
- &value[1], old_ecf->name);
-
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
- }
- }
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid event type \"%V\"", &value[1]);
-
- return NGX_CONF_ERROR;
-}
-
-
-static char *
-ngx_event_debug_connection(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
-#if (NGX_DEBUG)
- ngx_event_conf_t *ecf = conf;
-
- ngx_int_t rc;
- ngx_str_t *value;
- ngx_url_t u;
- ngx_cidr_t c, *cidr;
- ngx_uint_t i;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
-
- value = cf->args->elts;
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-
- if (ngx_strcmp(value[1].data, "unix:") == 0) {
- cidr = ngx_array_push(&ecf->debug_connection);
- if (cidr == NULL) {
- return NGX_CONF_ERROR;
- }
-
- cidr->family = AF_UNIX;
- return NGX_CONF_OK;
- }
-
-#endif
-
- rc = ngx_ptocidr(&value[1], &c);
-
- if (rc != NGX_ERROR) {
- if (rc == NGX_DONE) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "low address bits of %V are meaningless",
- &value[1]);
- }
-
- cidr = ngx_array_push(&ecf->debug_connection);
- if (cidr == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *cidr = c;
-
- return NGX_CONF_OK;
- }
-
- ngx_memzero(&u, sizeof(ngx_url_t));
- u.host = value[1];
-
- if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
- if (u.err) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "%s in debug_connection \"%V\"",
- u.err, &u.host);
- }
-
- return NGX_CONF_ERROR;
- }
-
- cidr = ngx_array_push_n(&ecf->debug_connection, u.naddrs);
- if (cidr == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t));
-
- for (i = 0; i < u.naddrs; i++) {
- cidr[i].family = u.addrs[i].sockaddr->sa_family;
-
- switch (cidr[i].family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr;
- cidr[i].u.in6.addr = sin6->sin6_addr;
- ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16);
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) u.addrs[i].sockaddr;
- cidr[i].u.in.addr = sin->sin_addr.s_addr;
- cidr[i].u.in.mask = 0xffffffff;
- break;
- }
- }
-
-#else
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "\"debug_connection\" is ignored, you need to rebuild "
- "nginx using --with-debug option to enable it");
-
-#endif
-
- return NGX_CONF_OK;
-}
-
-
-static void *
-ngx_event_core_create_conf(ngx_cycle_t *cycle)
-{
- ngx_event_conf_t *ecf;
-
- ecf = ngx_palloc(cycle->pool, sizeof(ngx_event_conf_t));
- if (ecf == NULL) {
- return NULL;
- }
-
- ecf->connections = NGX_CONF_UNSET_UINT;
- ecf->use = NGX_CONF_UNSET_UINT;
- ecf->multi_accept = NGX_CONF_UNSET;
- ecf->accept_mutex = NGX_CONF_UNSET;
- ecf->accept_mutex_delay = NGX_CONF_UNSET_MSEC;
- ecf->name = (void *) NGX_CONF_UNSET;
-
-#if (NGX_DEBUG)
-
- if (ngx_array_init(&ecf->debug_connection, cycle->pool, 4,
- sizeof(ngx_cidr_t)) == NGX_ERROR)
- {
- return NULL;
- }
-
-#endif
-
- return ecf;
-}
-
-
-static char *
-ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf)
-{
- ngx_event_conf_t *ecf = conf;
-
-#if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
- int fd;
-#endif
-#if (NGX_HAVE_RTSIG)
- ngx_uint_t rtsig;
- ngx_core_conf_t *ccf;
-#endif
- ngx_int_t i;
- ngx_module_t *module;
- ngx_event_module_t *event_module;
-
- module = NULL;
-
-#if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)
-
- fd = epoll_create(100);
-
- if (fd != -1) {
- (void) close(fd);
- module = &ngx_epoll_module;
-
- } else if (ngx_errno != NGX_ENOSYS) {
- module = &ngx_epoll_module;
- }
-
-#endif
-
-#if (NGX_HAVE_RTSIG)
-
- if (module == NULL) {
- module = &ngx_rtsig_module;
- rtsig = 1;
-
- } else {
- rtsig = 0;
- }
-
-#endif
-
-#if (NGX_HAVE_DEVPOLL)
-
- module = &ngx_devpoll_module;
-
-#endif
-
-#if (NGX_HAVE_KQUEUE)
-
- module = &ngx_kqueue_module;
-
-#endif
-
-#if (NGX_HAVE_SELECT)
-
- if (module == NULL) {
- module = &ngx_select_module;
- }
-
-#endif
-
- if (module == NULL) {
- for (i = 0; ngx_modules[i]; i++) {
-
- if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
- continue;
- }
-
- event_module = ngx_modules[i]->ctx;
-
- if (ngx_strcmp(event_module->name->data, event_core_name.data) == 0)
- {
- continue;
- }
-
- module = ngx_modules[i];
- break;
- }
- }
-
- if (module == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "no events module found");
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_init_uint_value(ecf->connections, DEFAULT_CONNECTIONS);
- cycle->connection_n = ecf->connections;
-
- ngx_conf_init_uint_value(ecf->use, module->ctx_index);
-
- event_module = module->ctx;
- ngx_conf_init_ptr_value(ecf->name, event_module->name->data);
-
- ngx_conf_init_value(ecf->multi_accept, 0);
- ngx_conf_init_value(ecf->accept_mutex, 1);
- ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);
-
-
-#if (NGX_HAVE_RTSIG)
-
- if (!rtsig) {
- return NGX_CONF_OK;
- }
-
- if (ecf->accept_mutex) {
- return NGX_CONF_OK;
- }
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-
- if (ccf->worker_processes == 0) {
- return NGX_CONF_OK;
- }
-
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
- "the \"rtsig\" method requires \"accept_mutex\" to be on");
-
- return NGX_CONF_ERROR;
-
-#else
-
- return NGX_CONF_OK;
-
-#endif
-}
diff --git a/usr.sbin/nginx/src/event/ngx_event.h b/usr.sbin/nginx/src/event/ngx_event.h
deleted file mode 100644
index 530c9486c51..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event.h
+++ /dev/null
@@ -1,569 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_EVENT_H_INCLUDED_
-#define _NGX_EVENT_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#define NGX_INVALID_INDEX 0xd0d0d0d0
-
-
-#if (NGX_HAVE_IOCP)
-
-typedef struct {
- WSAOVERLAPPED ovlp;
- ngx_event_t *event;
- int error;
-} ngx_event_ovlp_t;
-
-#endif
-
-
-typedef struct {
- ngx_uint_t lock;
-
- ngx_event_t *events;
- ngx_event_t *last;
-} ngx_event_mutex_t;
-
-
-struct ngx_event_s {
- void *data;
-
- unsigned write:1;
-
- unsigned accept:1;
-
- /* used to detect the stale events in kqueue, rtsig, and epoll */
- unsigned instance:1;
-
- /*
- * the event was passed or would be passed to a kernel;
- * in aio mode - operation was posted.
- */
- unsigned active:1;
-
- unsigned disabled:1;
-
- /* the ready event; in aio mode 0 means that no operation can be posted */
- unsigned ready:1;
-
- unsigned oneshot:1;
-
- /* aio operation is complete */
- unsigned complete:1;
-
- unsigned eof:1;
- unsigned error:1;
-
- unsigned timedout:1;
- unsigned timer_set:1;
-
- unsigned delayed:1;
-
- unsigned deferred_accept:1;
-
- /* the pending eof reported by kqueue, epoll or in aio chain operation */
- unsigned pending_eof:1;
-
-#if !(NGX_THREADS)
- unsigned posted_ready:1;
-#endif
-
-#if (NGX_WIN32)
- /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was successful */
- unsigned accept_context_updated:1;
-#endif
-
-#if (NGX_HAVE_KQUEUE)
- unsigned kq_vnode:1;
-
- /* the pending errno reported by kqueue */
- int kq_errno;
-#endif
-
- /*
- * kqueue only:
- * accept: number of sockets that wait to be accepted
- * read: bytes to read when event is ready
- * or lowat when event is set with NGX_LOWAT_EVENT flag
- * write: available space in buffer when event is ready
- * or lowat when event is set with NGX_LOWAT_EVENT flag
- *
- * iocp: TODO
- *
- * otherwise:
- * accept: 1 if accept many, 0 otherwise
- */
-
-#if (NGX_HAVE_KQUEUE) || (NGX_HAVE_IOCP)
- int available;
-#else
- unsigned available:1;
-#endif
-
- ngx_event_handler_pt handler;
-
-
-#if (NGX_HAVE_AIO)
-
-#if (NGX_HAVE_IOCP)
- ngx_event_ovlp_t ovlp;
-#else
- struct aiocb aiocb;
-#endif
-
-#endif
-
- ngx_uint_t index;
-
- ngx_log_t *log;
-
- ngx_rbtree_node_t timer;
-
- unsigned closed:1;
-
- /* to test on worker exit */
- unsigned channel:1;
- unsigned resolver:1;
-
-#if (NGX_THREADS)
-
- unsigned locked:1;
-
- unsigned posted_ready:1;
- unsigned posted_timedout:1;
- unsigned posted_eof:1;
-
-#if (NGX_HAVE_KQUEUE)
- /* the pending errno reported by kqueue */
- int posted_errno;
-#endif
-
-#if (NGX_HAVE_KQUEUE) || (NGX_HAVE_IOCP)
- int posted_available;
-#else
- unsigned posted_available:1;
-#endif
-
- ngx_atomic_t *lock;
- ngx_atomic_t *own_lock;
-
-#endif
-
- /* the links of the posted queue */
- ngx_event_t *next;
- ngx_event_t **prev;
-
-
-#if 0
-
- /* the threads support */
-
- /*
- * the event thread context, we store it here
- * if $(CC) does not understand __thread declaration
- * and pthread_getspecific() is too costly
- */
-
- void *thr_ctx;
-
-#if (NGX_EVENT_T_PADDING)
-
- /* event should not cross cache line in SMP */
-
- uint32_t padding[NGX_EVENT_T_PADDING];
-#endif
-#endif
-};
-
-
-#if (NGX_HAVE_FILE_AIO)
-
-struct ngx_event_aio_s {
- void *data;
- ngx_event_handler_pt handler;
- ngx_file_t *file;
-
- ngx_fd_t fd;
-
-#if (NGX_HAVE_EVENTFD)
- int64_t res;
-#if (NGX_TEST_BUILD_EPOLL)
- ngx_err_t err;
- size_t nbytes;
-#endif
-#else
- ngx_err_t err;
- size_t nbytes;
-#endif
-
-#if (NGX_HAVE_AIO_SENDFILE)
- off_t last_offset;
-#endif
-
- ngx_aiocb_t aiocb;
- ngx_event_t event;
-};
-
-#endif
-
-
-typedef struct {
- 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, 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, 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,
- ngx_uint_t flags);
-
- ngx_int_t (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);
- void (*done)(ngx_cycle_t *cycle);
-} ngx_event_actions_t;
-
-
-extern ngx_event_actions_t ngx_event_actions;
-
-
-/*
- * The event filter requires to read/write the whole data:
- * select, poll, /dev/poll, kqueue, epoll.
- */
-#define NGX_USE_LEVEL_EVENT 0x00000001
-
-/*
- * The event filter is deleted after a notification without an additional
- * syscall: kqueue, epoll.
- */
-#define NGX_USE_ONESHOT_EVENT 0x00000002
-
-/*
- * The event filter notifies only the changes and an initial level:
- * kqueue, epoll.
- */
-#define NGX_USE_CLEAR_EVENT 0x00000004
-
-/*
- * The event filter has kqueue features: the eof flag, errno,
- * available data, etc.
- */
-#define NGX_USE_KQUEUE_EVENT 0x00000008
-
-/*
- * The event filter supports low water mark: kqueue's NOTE_LOWAT.
- * kqueue in FreeBSD 4.1-4.2 has no NOTE_LOWAT so we need a separate flag.
- */
-#define NGX_USE_LOWAT_EVENT 0x00000010
-
-/*
- * The event filter requires to do i/o operation until EAGAIN: epoll, rtsig.
- */
-#define NGX_USE_GREEDY_EVENT 0x00000020
-
-/*
- * The event filter is epoll.
- */
-#define NGX_USE_EPOLL_EVENT 0x00000040
-
-/*
- * No need to add or delete the event filters: rtsig.
- */
-#define NGX_USE_RTSIG_EVENT 0x00000080
-
-/*
- * No need to add or delete the event filters: overlapped, aio_read,
- * aioread, io_submit.
- */
-#define NGX_USE_AIO_EVENT 0x00000100
-
-/*
- * Need to add socket or handle only once: i/o completion port.
- * It also requires NGX_HAVE_AIO and NGX_USE_AIO_EVENT to be set.
- */
-#define NGX_USE_IOCP_EVENT 0x00000200
-
-/*
- * The event filter has no opaque data and requires file descriptors table:
- * 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, NetBSD 2.0, and MacOSX 10.4, Solaris 10's event ports.
- */
-#define NGX_USE_TIMER_EVENT 0x00000800
-
-/*
- * All event filters on file descriptor are deleted after a notification:
- * Solaris 10's event ports.
- */
-#define NGX_USE_EVENTPORT_EVENT 0x00001000
-
-/*
- * The event filter support vnode notifications: kqueue.
- */
-#define NGX_USE_VNODE_EVENT 0x00002000
-
-
-/*
- * 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
-
-/*
- * event must be passed to kernel right now, do not wait until batch processing.
- */
-#define NGX_FLUSH_EVENT 4
-
-
-/* these flags have a meaning only for kqueue */
-#define NGX_LOWAT_EVENT 0
-#define NGX_VNODE_EVENT 0
-
-
-#if (NGX_HAVE_EPOLL) && !(NGX_HAVE_EPOLLRDHUP)
-#define EPOLLRDHUP 0
-#endif
-
-
-#if (NGX_HAVE_KQUEUE)
-
-#define NGX_READ_EVENT EVFILT_READ
-#define NGX_WRITE_EVENT EVFILT_WRITE
-
-#undef NGX_VNODE_EVENT
-#define NGX_VNODE_EVENT EVFILT_VNODE
-
-/*
- * NGX_CLOSE_EVENT, NGX_LOWAT_EVENT, and NGX_FLUSH_EVENT are the module flags
- * and they must not go into a kernel so we need to choose the value
- * that must not interfere with any existent and future kqueue flags.
- * kqueue has such values - EV_FLAG1, EV_EOF, and EV_ERROR:
- * they are reserved and cleared on a kernel entrance.
- */
-#undef NGX_CLOSE_EVENT
-#define NGX_CLOSE_EVENT EV_EOF
-
-#undef NGX_LOWAT_EVENT
-#define NGX_LOWAT_EVENT EV_FLAG1
-
-#undef NGX_FLUSH_EVENT
-#define NGX_FLUSH_EVENT EV_ERROR
-
-#define NGX_LEVEL_EVENT 0
-#define NGX_ONESHOT_EVENT EV_ONESHOT
-#define NGX_CLEAR_EVENT EV_CLEAR
-
-#undef NGX_DISABLE_EVENT
-#define NGX_DISABLE_EVENT EV_DISABLE
-
-
-#elif (NGX_HAVE_DEVPOLL || NGX_HAVE_EVENTPORT)
-
-#define NGX_READ_EVENT POLLIN
-#define NGX_WRITE_EVENT POLLOUT
-
-#define NGX_LEVEL_EVENT 0
-#define NGX_ONESHOT_EVENT 1
-
-
-#elif (NGX_HAVE_EPOLL)
-
-#define NGX_READ_EVENT (EPOLLIN|EPOLLRDHUP)
-#define NGX_WRITE_EVENT EPOLLOUT
-
-#define NGX_LEVEL_EVENT 0
-#define NGX_CLEAR_EVENT EPOLLET
-#define NGX_ONESHOT_EVENT 0x70000000
-#if 0
-#define NGX_ONESHOT_EVENT EPOLLONESHOT
-#endif
-
-
-#elif (NGX_HAVE_POLL)
-
-#define NGX_READ_EVENT POLLIN
-#define NGX_WRITE_EVENT POLLOUT
-
-#define NGX_LEVEL_EVENT 0
-#define NGX_ONESHOT_EVENT 1
-
-
-#else /* select */
-
-#define NGX_READ_EVENT 0
-#define NGX_WRITE_EVENT 1
-
-#define NGX_LEVEL_EVENT 0
-#define NGX_ONESHOT_EVENT 1
-
-#endif /* NGX_HAVE_KQUEUE */
-
-
-#if (NGX_HAVE_IOCP)
-#define NGX_IOCP_ACCEPT 0
-#define NGX_IOCP_IO 1
-#define NGX_IOCP_CONNECT 2
-#endif
-
-
-#ifndef NGX_CLEAR_EVENT
-#define NGX_CLEAR_EVENT 0 /* dummy declaration */
-#endif
-
-
-#define ngx_process_changes ngx_event_actions.process_changes
-#define ngx_process_events ngx_event_actions.process_events
-#define ngx_done_events ngx_event_actions.done
-
-#define ngx_add_event ngx_event_actions.add
-#define ngx_del_event ngx_event_actions.del
-#define ngx_add_conn ngx_event_actions.add_conn
-#define ngx_del_conn ngx_event_actions.del_conn
-
-#define ngx_add_timer ngx_event_add_timer
-#define ngx_del_timer ngx_event_del_timer
-
-
-extern ngx_os_io_t ngx_io;
-
-#define ngx_recv ngx_io.recv
-#define ngx_recv_chain ngx_io.recv_chain
-#define ngx_udp_recv ngx_io.udp_recv
-#define ngx_send ngx_io.send
-#define ngx_send_chain ngx_io.send_chain
-
-
-#define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */
-#define NGX_EVENT_CONF 0x02000000
-
-
-typedef struct {
- ngx_uint_t connections;
- ngx_uint_t use;
-
- ngx_flag_t multi_accept;
- ngx_flag_t accept_mutex;
-
- ngx_msec_t accept_mutex_delay;
-
- u_char *name;
-
-#if (NGX_DEBUG)
- ngx_array_t debug_connection;
-#endif
-} ngx_event_conf_t;
-
-
-typedef struct {
- ngx_str_t *name;
-
- void *(*create_conf)(ngx_cycle_t *cycle);
- char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
-
- ngx_event_actions_t actions;
-} ngx_event_module_t;
-
-
-extern ngx_atomic_t *ngx_connection_counter;
-
-extern ngx_atomic_t *ngx_accept_mutex_ptr;
-extern ngx_shmtx_t ngx_accept_mutex;
-extern ngx_uint_t ngx_use_accept_mutex;
-extern ngx_uint_t ngx_accept_events;
-extern ngx_uint_t ngx_accept_mutex_held;
-extern ngx_msec_t ngx_accept_mutex_delay;
-extern ngx_int_t ngx_accept_disabled;
-
-
-#if (NGX_STAT_STUB)
-
-extern ngx_atomic_t *ngx_stat_accepted;
-extern ngx_atomic_t *ngx_stat_handled;
-extern ngx_atomic_t *ngx_stat_requests;
-extern ngx_atomic_t *ngx_stat_active;
-extern ngx_atomic_t *ngx_stat_reading;
-extern ngx_atomic_t *ngx_stat_writing;
-extern ngx_atomic_t *ngx_stat_waiting;
-
-#endif
-
-
-#define NGX_UPDATE_TIME 1
-#define NGX_POST_EVENTS 2
-#define NGX_POST_THREAD_EVENTS 4
-
-
-extern sig_atomic_t ngx_event_timer_alarm;
-extern ngx_uint_t ngx_event_flags;
-extern ngx_module_t ngx_events_module;
-extern ngx_module_t ngx_event_core_module;
-
-
-#define ngx_event_get_conf(conf_ctx, module) \
- (*(ngx_get_conf(conf_ctx, ngx_events_module))) [module.ctx_index];
-
-
-
-void ngx_event_accept(ngx_event_t *ev);
-ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle);
-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, ngx_uint_t flags);
-ngx_int_t ngx_handle_write_event(ngx_event_t *wev, size_t lowat);
-
-
-#if (NGX_WIN32)
-void ngx_event_acceptex(ngx_event_t *ev);
-ngx_int_t ngx_event_post_acceptex(ngx_listening_t *ls, ngx_uint_t n);
-u_char *ngx_acceptex_log_error(ngx_log_t *log, u_char *buf, size_t len);
-#endif
-
-
-ngx_int_t ngx_send_lowat(ngx_connection_t *c, size_t lowat);
-
-
-/* used in ngx_log_debugX() */
-#define ngx_event_ident(p) ((ngx_connection_t *) (p))->fd
-
-
-#include <ngx_event_timer.h>
-#include <ngx_event_posted.h>
-#include <ngx_event_busy_lock.h>
-
-#if (NGX_WIN32)
-#include <ngx_iocp_module.h>
-#endif
-
-
-#endif /* _NGX_EVENT_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/event/ngx_event_accept.c b/usr.sbin/nginx/src/event/ngx_event_accept.c
deleted file mode 100644
index bf67ecee062..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_accept.c
+++ /dev/null
@@ -1,507 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-static ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle);
-static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle);
-static void ngx_close_accepted_connection(ngx_connection_t *c);
-
-
-void
-ngx_event_accept(ngx_event_t *ev)
-{
- socklen_t socklen;
- ngx_err_t err;
- ngx_log_t *log;
- ngx_uint_t level;
- ngx_socket_t s;
- ngx_event_t *rev, *wev;
- ngx_listening_t *ls;
- ngx_connection_t *c, *lc;
- ngx_event_conf_t *ecf;
- u_char sa[NGX_SOCKADDRLEN];
-#if (NGX_HAVE_ACCEPT4)
- static ngx_uint_t use_accept4 = 1;
-#endif
-
- if (ev->timedout) {
- if (ngx_enable_accept_events((ngx_cycle_t *) ngx_cycle) != NGX_OK) {
- return;
- }
-
- ev->timedout = 0;
- }
-
- ecf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_event_core_module);
-
- if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
- ev->available = 1;
-
- } else if (!(ngx_event_flags & NGX_USE_KQUEUE_EVENT)) {
- ev->available = ecf->multi_accept;
- }
-
- lc = ev->data;
- ls = lc->listening;
- ev->ready = 0;
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "accept on %V, ready: %d", &ls->addr_text, ev->available);
-
- do {
- socklen = NGX_SOCKADDRLEN;
-
-#if (NGX_HAVE_ACCEPT4)
- if (use_accept4) {
- s = accept4(lc->fd, (struct sockaddr *) sa, &socklen,
- SOCK_NONBLOCK);
- } else {
- s = accept(lc->fd, (struct sockaddr *) sa, &socklen);
- }
-#else
- s = accept(lc->fd, (struct sockaddr *) sa, &socklen);
-#endif
-
- if (s == (ngx_socket_t) -1) {
- err = ngx_socket_errno;
-
- if (err == NGX_EAGAIN) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, err,
- "accept() not ready");
- return;
- }
-
- level = NGX_LOG_ALERT;
-
- if (err == NGX_ECONNABORTED) {
- level = NGX_LOG_ERR;
-
- } else if (err == NGX_EMFILE || err == NGX_ENFILE) {
- level = NGX_LOG_CRIT;
- }
-
-#if (NGX_HAVE_ACCEPT4)
- ngx_log_error(level, ev->log, err,
- use_accept4 ? "accept4() failed" : "accept() failed");
-
- if (use_accept4 && err == NGX_ENOSYS) {
- use_accept4 = 0;
- ngx_inherited_nonblocking = 0;
- continue;
- }
-#else
- ngx_log_error(level, ev->log, err, "accept() failed");
-#endif
-
- if (err == NGX_ECONNABORTED) {
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
- ev->available--;
- }
-
- if (ev->available) {
- continue;
- }
- }
-
- if (err == NGX_EMFILE || err == NGX_ENFILE) {
- if (ngx_disable_accept_events((ngx_cycle_t *) ngx_cycle)
- != NGX_OK)
- {
- return;
- }
-
- if (ngx_use_accept_mutex) {
- if (ngx_accept_mutex_held) {
- ngx_shmtx_unlock(&ngx_accept_mutex);
- ngx_accept_mutex_held = 0;
- }
-
- ngx_accept_disabled = 1;
-
- } else {
- ngx_add_timer(ev, ecf->accept_mutex_delay);
- }
- }
-
- return;
- }
-
-#if (NGX_STAT_STUB)
- (void) ngx_atomic_fetch_add(ngx_stat_accepted, 1);
-#endif
-
- ngx_accept_disabled = ngx_cycle->connection_n / 8
- - ngx_cycle->free_connection_n;
-
- c = ngx_get_connection(s, ev->log);
-
- if (c == NULL) {
- if (ngx_close_socket(s) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
- ngx_close_socket_n " failed");
- }
-
- return;
- }
-
-#if (NGX_STAT_STUB)
- (void) ngx_atomic_fetch_add(ngx_stat_active, 1);
-#endif
-
- c->pool = ngx_create_pool(ls->pool_size, ev->log);
- if (c->pool == NULL) {
- ngx_close_accepted_connection(c);
- return;
- }
-
- c->sockaddr = ngx_palloc(c->pool, socklen);
- if (c->sockaddr == NULL) {
- ngx_close_accepted_connection(c);
- return;
- }
-
- ngx_memcpy(c->sockaddr, sa, socklen);
-
- log = ngx_palloc(c->pool, sizeof(ngx_log_t));
- if (log == NULL) {
- ngx_close_accepted_connection(c);
- return;
- }
-
- /* set a blocking mode for aio and non-blocking mode for others */
-
- if (ngx_inherited_nonblocking) {
- if (ngx_event_flags & NGX_USE_AIO_EVENT) {
- if (ngx_blocking(s) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
- ngx_blocking_n " failed");
- ngx_close_accepted_connection(c);
- return;
- }
- }
-
- } else {
- if (!(ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_RTSIG_EVENT))) {
- if (ngx_nonblocking(s) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
- ngx_nonblocking_n " failed");
- ngx_close_accepted_connection(c);
- return;
- }
- }
- }
-
- *log = ls->log;
-
- c->recv = ngx_recv;
- c->send = ngx_send;
- c->recv_chain = ngx_recv_chain;
- c->send_chain = ngx_send_chain;
-
- c->log = log;
- c->pool->log = log;
-
- c->socklen = socklen;
- c->listening = ls;
- c->local_sockaddr = ls->sockaddr;
- c->local_socklen = ls->socklen;
-
- c->unexpected_eof = 1;
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- if (c->sockaddr->sa_family == AF_UNIX) {
- c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
- c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
-#if (NGX_SOLARIS)
- /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */
- c->sendfile = 0;
-#endif
- }
-#endif
-
- rev = c->read;
- wev = c->write;
-
- wev->ready = 1;
-
- if (ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_RTSIG_EVENT)) {
- /* rtsig, aio, iocp */
- rev->ready = 1;
- }
-
- if (ev->deferred_accept) {
- rev->ready = 1;
-#if (NGX_HAVE_KQUEUE)
- rev->available = 1;
-#endif
- }
-
- rev->log = log;
- wev->log = log;
-
- /*
- * TODO: MT: - ngx_atomic_fetch_add()
- * or protection by critical section or light mutex
- *
- * TODO: MP: - allocated in a shared memory
- * - ngx_atomic_fetch_add()
- * or protection by critical section or light mutex
- */
-
- c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
-
-#if (NGX_STAT_STUB)
- (void) ngx_atomic_fetch_add(ngx_stat_handled, 1);
-#endif
-
-#if (NGX_THREADS)
- rev->lock = &c->lock;
- wev->lock = &c->lock;
- rev->own_lock = &c->lock;
- wev->own_lock = &c->lock;
-#endif
-
- if (ls->addr_ntop) {
- c->addr_text.data = ngx_pnalloc(c->pool, ls->addr_text_max_len);
- if (c->addr_text.data == NULL) {
- ngx_close_accepted_connection(c);
- return;
- }
-
- c->addr_text.len = ngx_sock_ntop(c->sockaddr, c->socklen,
- c->addr_text.data,
- ls->addr_text_max_len, 0);
- if (c->addr_text.len == 0) {
- ngx_close_accepted_connection(c);
- return;
- }
- }
-
-#if (NGX_DEBUG)
- {
-
- struct sockaddr_in *sin;
- ngx_cidr_t *cidr;
- ngx_uint_t i;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
- ngx_uint_t n;
-#endif
-
- cidr = ecf->debug_connection.elts;
- for (i = 0; i < ecf->debug_connection.nelts; i++) {
- if (cidr[i].family != (ngx_uint_t) c->sockaddr->sa_family) {
- goto next;
- }
-
- switch (cidr[i].family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) c->sockaddr;
- for (n = 0; n < 16; n++) {
- if ((sin6->sin6_addr.s6_addr[n]
- & cidr[i].u.in6.mask.s6_addr[n])
- != cidr[i].u.in6.addr.s6_addr[n])
- {
- goto next;
- }
- }
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) c->sockaddr;
- if ((sin->sin_addr.s_addr & cidr[i].u.in.mask)
- != cidr[i].u.in.addr)
- {
- goto next;
- }
- break;
- }
-
- log->log_level = NGX_LOG_DEBUG_CONNECTION|NGX_LOG_DEBUG_ALL;
- break;
-
- next:
- continue;
- }
-
- }
-#endif
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, log, 0,
- "*%uA accept: %V fd:%d", c->number, &c->addr_text, s);
-
- if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
- if (ngx_add_conn(c) == NGX_ERROR) {
- ngx_close_accepted_connection(c);
- return;
- }
- }
-
- log->data = NULL;
- log->handler = NULL;
-
- ls->handler(c);
-
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
- ev->available--;
- }
-
- } while (ev->available);
-}
-
-
-ngx_int_t
-ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
-{
- if (ngx_shmtx_trylock(&ngx_accept_mutex)) {
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "accept mutex locked");
-
- if (ngx_accept_mutex_held
- && ngx_accept_events == 0
- && !(ngx_event_flags & NGX_USE_RTSIG_EVENT))
- {
- return NGX_OK;
- }
-
- if (ngx_enable_accept_events(cycle) == NGX_ERROR) {
- ngx_shmtx_unlock(&ngx_accept_mutex);
- return NGX_ERROR;
- }
-
- ngx_accept_events = 0;
- ngx_accept_mutex_held = 1;
-
- return NGX_OK;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "accept mutex lock failed: %ui", ngx_accept_mutex_held);
-
- if (ngx_accept_mutex_held) {
- if (ngx_disable_accept_events(cycle) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- ngx_accept_mutex_held = 0;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_enable_accept_events(ngx_cycle_t *cycle)
-{
- ngx_uint_t i;
- ngx_listening_t *ls;
- ngx_connection_t *c;
-
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
-
- c = ls[i].connection;
-
- if (c->read->active) {
- continue;
- }
-
- if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
-
- if (ngx_add_conn(c) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- } else {
- if (ngx_add_event(c->read, NGX_READ_EVENT, 0) == NGX_ERROR) {
- return NGX_ERROR;
- }
- }
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_disable_accept_events(ngx_cycle_t *cycle)
-{
- ngx_uint_t i;
- ngx_listening_t *ls;
- ngx_connection_t *c;
-
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
-
- c = ls[i].connection;
-
- if (!c->read->active) {
- continue;
- }
-
- if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
- if (ngx_del_conn(c, NGX_DISABLE_EVENT) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- } else {
- if (ngx_del_event(c->read, NGX_READ_EVENT, NGX_DISABLE_EVENT)
- == NGX_ERROR)
- {
- return NGX_ERROR;
- }
- }
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_close_accepted_connection(ngx_connection_t *c)
-{
- ngx_socket_t fd;
-
- ngx_free_connection(c);
-
- fd = c->fd;
- c->fd = (ngx_socket_t) -1;
-
- if (ngx_close_socket(fd) == -1) {
- ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno,
- ngx_close_socket_n " failed");
- }
-
- if (c->pool) {
- ngx_destroy_pool(c->pool);
- }
-
-#if (NGX_STAT_STUB)
- (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
-#endif
-}
-
-
-u_char *
-ngx_accept_log_error(ngx_log_t *log, u_char *buf, size_t len)
-{
- return ngx_snprintf(buf, len, " while accepting new connection on %V",
- log->data);
-}
diff --git a/usr.sbin/nginx/src/event/ngx_event_busy_lock.c b/usr.sbin/nginx/src/event/ngx_event_busy_lock.c
deleted file mode 100644
index fdac0da8fd2..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_busy_lock.c
+++ /dev/null
@@ -1,286 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-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);
-
-
-/*
- * NGX_OK: the busy lock is held
- * NGX_AGAIN: the all busy locks are held but we will wait the specified time
- * NGX_BUSY: ctx->timer == 0: there are many the busy locks
- * ctx->timer != 0: there are many the waiting locks
- */
-
-ngx_int_t
-ngx_event_busy_lock(ngx_event_busy_lock_t *bl, ngx_event_busy_lock_ctx_t *ctx)
-{
- ngx_int_t rc;
-
- ngx_mutex_lock(bl->mutex);
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->event->log, 0,
- "event busy lock: b:%d mb:%d",
- bl->busy, bl->max_busy);
-
- if (bl->busy < bl->max_busy) {
- bl->busy++;
-
- rc = NGX_OK;
-
- } else if (ctx->timer && bl->waiting < bl->max_waiting) {
- bl->waiting++;
- ngx_add_timer(ctx->event, ctx->timer);
- ctx->event->handler = ngx_event_busy_lock_handler;
-
- if (bl->events) {
- bl->last->next = ctx;
-
- } else {
- bl->events = ctx;
- }
-
- bl->last = ctx;
-
- rc = NGX_AGAIN;
-
- } else {
- rc = NGX_BUSY;
- }
-
- ngx_mutex_unlock(bl->mutex);
-
- return rc;
-}
-
-
-ngx_int_t
-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_cacheable(bl, ctx);
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->event->log, 0,
- "event busy lock: %d w:%d mw:%d",
- rc, bl->waiting, bl->max_waiting);
-
- /*
- * NGX_OK: no the same request, there is free slot and we locked it
- * NGX_BUSY: no the same request and there is no free slot
- * NGX_AGAIN: the same request is processing
- */
-
- if (rc == NGX_AGAIN) {
-
- if (ctx->timer && bl->waiting < bl->max_waiting) {
- bl->waiting++;
- ngx_add_timer(ctx->event, ctx->timer);
- ctx->event->handler = ngx_event_busy_lock_handler;
-
- if (bl->events == NULL) {
- bl->events = ctx;
- } else {
- bl->last->next = ctx;
- }
- bl->last = ctx;
-
- } else {
- rc = NGX_BUSY;
- }
- }
-
- ngx_mutex_unlock(bl->mutex);
-
- return rc;
-}
-
-
-void
-ngx_event_busy_unlock(ngx_event_busy_lock_t *bl,
- ngx_event_busy_lock_ctx_t *ctx)
-{
- ngx_event_t *ev;
- ngx_event_busy_lock_ctx_t *wakeup;
-
- ngx_mutex_lock(bl->mutex);
-
- if (bl->events) {
- wakeup = bl->events;
- bl->events = bl->events->next;
-
- } else {
- wakeup = NULL;
- bl->busy--;
- }
-
- /*
- * MP: all ctx's and their queue must be in shared memory,
- * each ctx has pid to wake up
- */
-
- if (wakeup == NULL) {
- ngx_mutex_unlock(bl->mutex);
- return;
- }
-
- if (ctx->md5) {
- for (wakeup = bl->events; wakeup; wakeup = wakeup->next) {
- if (wakeup->md5 == NULL || wakeup->slot != ctx->slot) {
- continue;
- }
-
- wakeup->handler = ngx_event_busy_lock_posted_handler;
- wakeup->cache_updated = 1;
-
- ev = wakeup->event;
-
- ngx_post_event(ev, &ngx_posted_events);
- }
-
- ngx_mutex_unlock(bl->mutex);
-
- } else {
- bl->waiting--;
-
- ngx_mutex_unlock(bl->mutex);
-
- wakeup->handler = ngx_event_busy_lock_posted_handler;
- wakeup->locked = 1;
-
- ev = wakeup->event;
-
- if (ev->timer_set) {
- ngx_del_timer(ev);
- }
-
- ngx_post_event(ev, &ngx_posted_events);
- }
-}
-
-
-void
-ngx_event_busy_lock_cancel(ngx_event_busy_lock_t *bl,
- ngx_event_busy_lock_ctx_t *ctx)
-{
- ngx_event_busy_lock_ctx_t *c, *p;
-
- ngx_mutex_lock(bl->mutex);
-
- bl->waiting--;
-
- if (ctx == bl->events) {
- bl->events = ctx->next;
-
- } else {
- p = bl->events;
- for (c = bl->events->next; c; c = c->next) {
- if (c == ctx) {
- p->next = ctx->next;
- break;
- }
- p = c;
- }
- }
-
- ngx_mutex_unlock(bl->mutex);
-}
-
-
-static ngx_int_t
-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, cacheable, mask;
-
- bit = 0;
- cacheable = 0;
- free = -1;
-
-#if (NGX_SUPPRESS_WARN)
- mask = 0;
-#endif
-
- for (i = 0; i < bl->max_busy; i++) {
-
- if ((bit & 7) == 0) {
- mask = bl->md5_mask[i / 8];
- }
-
- if (mask & 1) {
- if (ngx_memcmp(&bl->md5[i * 16], ctx->md5, 16) == 0) {
- ctx->waiting = 1;
- ctx->slot = i;
- return NGX_AGAIN;
- }
- cacheable++;
-
- } else if (free == -1) {
- free = i;
- }
-
- if (cacheable == bl->cacheable) {
- if (free == -1 && cacheable < bl->max_busy) {
- free = i + 1;
- }
-
- break;
- }
-
- mask >>= 1;
- bit++;
- }
-
- if (free == -1) {
- return NGX_BUSY;
- }
-
-#if 0
- if (bl->busy == bl->max_busy) {
- return NGX_BUSY;
- }
-#endif
-
- ngx_memcpy(&bl->md5[free * 16], ctx->md5, 16);
- bl->md5_mask[free / 8] |= 1 << (free & 7);
- ctx->slot = free;
-
- bl->cacheable++;
- bl->busy++;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_event_busy_lock_handler(ngx_event_t *ev)
-{
- ev->handler = ngx_event_busy_lock_posted_handler;
-
- ngx_post_event(ev, &ngx_posted_events);
-}
-
-
-static void
-ngx_event_busy_lock_posted_handler(ngx_event_t *ev)
-{
- ngx_event_busy_lock_ctx_t *ctx;
-
- ctx = ev->data;
- ctx->handler(ev);
-}
diff --git a/usr.sbin/nginx/src/event/ngx_event_busy_lock.h b/usr.sbin/nginx/src/event/ngx_event_busy_lock.h
deleted file mode 100644
index 254c233e776..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_busy_lock.h
+++ /dev/null
@@ -1,65 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_EVENT_BUSY_LOCK_H_INCLUDED_
-#define _NGX_EVENT_BUSY_LOCK_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-typedef struct ngx_event_busy_lock_ctx_s ngx_event_busy_lock_ctx_t;
-
-struct ngx_event_busy_lock_ctx_s {
- ngx_event_t *event;
- ngx_event_handler_pt handler;
- void *data;
- ngx_msec_t timer;
-
- unsigned locked:1;
- unsigned waiting:1;
- unsigned cache_updated:1;
-
- char *md5;
- ngx_int_t slot;
-
- ngx_event_busy_lock_ctx_t *next;
-};
-
-
-typedef struct {
- u_char *md5_mask;
- char *md5;
- ngx_uint_t cacheable;
-
- ngx_uint_t busy;
- ngx_uint_t max_busy;
-
- ngx_uint_t waiting;
- ngx_uint_t max_waiting;
-
- ngx_event_busy_lock_ctx_t *events;
- ngx_event_busy_lock_ctx_t *last;
-
-#if (NGX_THREADS)
- ngx_mutex_t *mutex;
-#endif
-} ngx_event_busy_lock_t;
-
-
-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_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);
-void ngx_event_busy_lock_cancel(ngx_event_busy_lock_t *bl,
- ngx_event_busy_lock_ctx_t *ctx);
-
-
-#endif /* _NGX_EVENT_BUSY_LOCK_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/event/ngx_event_connect.c b/usr.sbin/nginx/src/event/ngx_event_connect.c
deleted file mode 100644
index 5fcabcfd1fa..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_connect.c
+++ /dev/null
@@ -1,258 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_event_connect.h>
-
-
-ngx_int_t
-ngx_event_connect_peer(ngx_peer_connection_t *pc)
-{
- int rc;
- ngx_int_t event;
- ngx_err_t err;
- ngx_uint_t level;
- ngx_socket_t s;
- ngx_event_t *rev, *wev;
- ngx_connection_t *c;
-
- rc = pc->get(pc, pc->data);
- if (rc != NGX_OK) {
- return rc;
- }
-
- s = ngx_socket(pc->sockaddr->sa_family, SOCK_STREAM, 0);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0, "socket %d", s);
-
- if (s == (ngx_socket_t) -1) {
- ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
- ngx_socket_n " failed");
- return NGX_ERROR;
- }
-
-
- c = ngx_get_connection(s, pc->log);
-
- if (c == NULL) {
- if (ngx_close_socket(s) == -1) {
- ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
- ngx_close_socket_n "failed");
- }
-
- return NGX_ERROR;
- }
-
- if (pc->rcvbuf) {
- if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
- (const void *) &pc->rcvbuf, sizeof(int)) == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
- "setsockopt(SO_RCVBUF) failed");
- goto failed;
- }
- }
-
- if (ngx_nonblocking(s) == -1) {
- ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
- ngx_nonblocking_n " failed");
-
- goto failed;
- }
-
- if (pc->local) {
- if (bind(s, pc->local->sockaddr, pc->local->socklen) == -1) {
- ngx_log_error(NGX_LOG_CRIT, pc->log, ngx_socket_errno,
- "bind(%V) failed", &pc->local->name);
-
- goto failed;
- }
- }
-
- c->recv = ngx_recv;
- c->send = ngx_send;
- 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_UNIX) {
- c->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
- c->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
-
-#if (NGX_SOLARIS)
- /* Solaris's sendfilev() supports AF_NCA, AF_INET, and AF_INET6 */
- c->sendfile = 0;
-#endif
- }
-
- rev = c->read;
- wev = c->write;
-
- rev->log = pc->log;
- wev->log = pc->log;
-
- pc->connection = c;
-
- c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
-
-#if (NGX_THREADS)
-
- /* TODO: lock event when call completion handler */
-
- rev->lock = pc->lock;
- wev->lock = pc->lock;
- rev->own_lock = &c->lock;
- wev->own_lock = &c->lock;
-
-#endif
-
- if (ngx_add_conn) {
- if (ngx_add_conn(c) == NGX_ERROR) {
- goto failed;
- }
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, pc->log, 0,
- "connect to %V, fd:%d #%uA", pc->name, s, c->number);
-
- rc = connect(s, pc->sockaddr, pc->socklen);
-
- if (rc == -1) {
- err = ngx_socket_errno;
-
-
- if (err != NGX_EINPROGRESS
-#if (NGX_WIN32)
- /* Winsock returns WSAEWOULDBLOCK (NGX_EAGAIN) */
- && err != NGX_EAGAIN
-#endif
- )
- {
- if (err == NGX_ECONNREFUSED
-#if (NGX_LINUX)
- /*
- * Linux returns EAGAIN instead of ECONNREFUSED
- * for unix sockets if listen queue is full
- */
- || err == NGX_EAGAIN
-#endif
- || err == NGX_ECONNRESET
- || err == NGX_ENETDOWN
- || err == NGX_ENETUNREACH
- || err == NGX_EHOSTDOWN
- || err == NGX_EHOSTUNREACH)
- {
- level = NGX_LOG_ERR;
-
- } else {
- level = NGX_LOG_CRIT;
- }
-
- ngx_log_error(level, c->log, err, "connect() to %V failed",
- pc->name);
-
- ngx_close_connection(c);
- pc->connection = NULL;
-
- return NGX_DECLINED;
- }
- }
-
- if (ngx_add_conn) {
- if (rc == -1) {
-
- /* NGX_EINPROGRESS */
-
- return NGX_AGAIN;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected");
-
- wev->ready = 1;
-
- return NGX_OK;
- }
-
- if (ngx_event_flags & NGX_USE_AIO_EVENT) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, ngx_socket_errno,
- "connect(): %d", rc);
-
- /* aio, iocp */
-
- if (ngx_blocking(s) == -1) {
- ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
- ngx_blocking_n " failed");
- goto failed;
- }
-
- /*
- * FreeBSD's aio allows to post an operation on non-connected socket.
- * NT does not support it.
- *
- * TODO: check in Win32, etc. As workaround we can use NGX_ONESHOT_EVENT
- */
-
- rev->ready = 1;
- wev->ready = 1;
-
- return NGX_OK;
- }
-
- if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
-
- /* kqueue */
-
- event = NGX_CLEAR_EVENT;
-
- } else {
-
- /* select, poll, /dev/poll */
-
- event = NGX_LEVEL_EVENT;
- }
-
- if (ngx_add_event(rev, NGX_READ_EVENT, event) != NGX_OK) {
- goto failed;
- }
-
- if (rc == -1) {
-
- /* NGX_EINPROGRESS */
-
- if (ngx_add_event(wev, NGX_WRITE_EVENT, event) != NGX_OK) {
- goto failed;
- }
-
- return NGX_AGAIN;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pc->log, 0, "connected");
-
- wev->ready = 1;
-
- return NGX_OK;
-
-failed:
-
- ngx_close_connection(c);
- pc->connection = NULL;
-
- return NGX_ERROR;
-}
-
-
-ngx_int_t
-ngx_event_get_peer(ngx_peer_connection_t *pc, void *data)
-{
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/event/ngx_event_connect.h b/usr.sbin/nginx/src/event/ngx_event_connect.h
deleted file mode 100644
index 951c24f411c..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_connect.h
+++ /dev/null
@@ -1,76 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_EVENT_CONNECT_H_INCLUDED_
-#define _NGX_EVENT_CONNECT_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#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);
-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;
-
- struct sockaddr *sockaddr;
- socklen_t socklen;
- ngx_str_t *name;
-
- ngx_uint_t tries;
-
- ngx_event_get_peer_pt get;
- ngx_event_free_peer_pt free;
- void *data;
-
-#if (NGX_SSL)
- ngx_event_set_peer_session_pt set_session;
- ngx_event_save_peer_session_pt save_session;
-#endif
-
-#if (NGX_THREADS)
- ngx_atomic_t *lock;
-#endif
-
- ngx_addr_t *local;
-
- int rcvbuf;
-
- ngx_log_t *log;
-
- unsigned cached:1;
-
- /* ngx_connection_log_error_e */
- unsigned log_error:2;
-};
-
-
-ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc);
-ngx_int_t ngx_event_get_peer(ngx_peer_connection_t *pc, void *data);
-
-
-#endif /* _NGX_EVENT_CONNECT_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/event/ngx_event_mutex.c b/usr.sbin/nginx/src/event/ngx_event_mutex.c
deleted file mode 100644
index 2bdfd5b4ecc..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_mutex.c
+++ /dev/null
@@ -1,70 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-ngx_int_t ngx_event_mutex_timedlock(ngx_event_mutex_t *m, ngx_msec_t timer,
- ngx_event_t *ev)
-{
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "lock event mutex %p lock:%XD", m, m->lock);
-
- if (m->lock) {
-
- if (m->events == NULL) {
- m->events = ev;
-
- } else {
- m->last->next = ev;
- }
-
- m->last = ev;
- ev->next = NULL;
-
-#if (NGX_THREADS0)
- ev->light = 1;
-#endif
-
- ngx_add_timer(ev, timer);
-
- return NGX_AGAIN;
- }
-
- m->lock = 1;
-
- return NGX_OK;
-}
-
-
-ngx_int_t ngx_event_mutex_unlock(ngx_event_mutex_t *m, ngx_log_t *log)
-{
- ngx_event_t *ev;
-
- if (m->lock == 0) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- "tring to unlock the free event mutex %p", m);
- return NGX_ERROR;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, log, 0,
- "unlock event mutex %p, next event: %p", m, m->events);
-
- m->lock = 0;
-
- if (m->events) {
- ev = m->events;
- m->events = ev->next;
-
- ev->next = (ngx_event_t *) ngx_posted_events;
- ngx_posted_events = ev;
- }
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/event/ngx_event_openssl.c b/usr.sbin/nginx/src/event/ngx_event_openssl.c
deleted file mode 100644
index 6290a57fe0c..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_openssl.c
+++ /dev/null
@@ -1,2852 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-typedef struct {
- ngx_uint_t engine; /* unsigned engine:1; */
-} ngx_openssl_conf_t;
-
-
-static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
-static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where,
- int ret);
-static void ngx_ssl_handshake_handler(ngx_event_t *ev);
-static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);
-static void ngx_ssl_write_handler(ngx_event_t *wev);
-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);
-
-ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
-static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn,
- ngx_ssl_session_t *sess);
-static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn,
- u_char *id, int len, int *copy);
-static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess);
-static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
- ngx_slab_pool_t *shpool, ngx_uint_t n);
-static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
-
-#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
-static int ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
- unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx,
- HMAC_CTX *hctx, int enc);
-#endif
-
-static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
-static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static void ngx_openssl_exit(ngx_cycle_t *cycle);
-
-
-static ngx_command_t ngx_openssl_commands[] = {
-
- { ngx_string("ssl_engine"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_openssl_engine,
- 0,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_core_module_t ngx_openssl_module_ctx = {
- ngx_string("openssl"),
- ngx_openssl_create_conf,
- NULL
-};
-
-
-ngx_module_t ngx_openssl_module = {
- NGX_MODULE_V1,
- &ngx_openssl_module_ctx, /* module context */
- ngx_openssl_commands, /* module directives */
- NGX_CORE_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- ngx_openssl_exit, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-int ngx_ssl_connection_index;
-int ngx_ssl_server_conf_index;
-int ngx_ssl_session_cache_index;
-int ngx_ssl_session_ticket_keys_index;
-int ngx_ssl_certificate_index;
-int ngx_ssl_stapling_index;
-
-
-ngx_int_t
-ngx_ssl_init(ngx_log_t *log)
-{
- OPENSSL_config(NULL);
-
- SSL_library_init();
- SSL_load_error_strings();
-
- OpenSSL_add_all_algorithms();
-
-#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
-#ifndef SSL_OP_NO_COMPRESSION
- {
- /*
- * Disable gzip compression in OpenSSL prior to 1.0.0 version,
- * this saves about 522K per connection.
- */
- int n;
- STACK_OF(SSL_COMP) *ssl_comp_methods;
-
- ssl_comp_methods = SSL_COMP_get_compression_methods();
- n = sk_SSL_COMP_num(ssl_comp_methods);
-
- while (n--) {
- (void) sk_SSL_COMP_pop(ssl_comp_methods);
- }
- }
-#endif
-#endif
-
- ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
-
- if (ngx_ssl_connection_index == -1) {
- ngx_ssl_error(NGX_LOG_ALERT, log, 0, "SSL_get_ex_new_index() failed");
- return NGX_ERROR;
- }
-
- ngx_ssl_server_conf_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
- NULL);
- if (ngx_ssl_server_conf_index == -1) {
- ngx_ssl_error(NGX_LOG_ALERT, log, 0,
- "SSL_CTX_get_ex_new_index() failed");
- return NGX_ERROR;
- }
-
- ngx_ssl_session_cache_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
- NULL);
- if (ngx_ssl_session_cache_index == -1) {
- ngx_ssl_error(NGX_LOG_ALERT, log, 0,
- "SSL_CTX_get_ex_new_index() failed");
- return NGX_ERROR;
- }
-
- ngx_ssl_session_ticket_keys_index = SSL_CTX_get_ex_new_index(0, NULL, NULL,
- NULL, NULL);
- if (ngx_ssl_session_ticket_keys_index == -1) {
- ngx_ssl_error(NGX_LOG_ALERT, log, 0,
- "SSL_CTX_get_ex_new_index() failed");
- return NGX_ERROR;
- }
-
- ngx_ssl_certificate_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
- NULL);
- if (ngx_ssl_certificate_index == -1) {
- ngx_ssl_error(NGX_LOG_ALERT, log, 0,
- "SSL_CTX_get_ex_new_index() failed");
- return NGX_ERROR;
- }
-
- ngx_ssl_stapling_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
- NULL);
- if (ngx_ssl_stapling_index == -1) {
- ngx_ssl_error(NGX_LOG_ALERT, log, 0,
- "SSL_CTX_get_ex_new_index() failed");
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
-{
- ssl->ctx = SSL_CTX_new(SSLv23_method());
-
- if (ssl->ctx == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_new() failed");
- return NGX_ERROR;
- }
-
- if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_server_conf_index, data) == 0) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_CTX_set_ex_data() failed");
- return NGX_ERROR;
- }
-
- ssl->buffer_size = NGX_SSL_BUFSIZE;
-
- /* client side options */
-
- SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_SESS_ID_BUG);
- SSL_CTX_set_options(ssl->ctx, SSL_OP_NETSCAPE_CHALLENGE_BUG);
-
- /* server side options */
-
- SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG);
- SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER);
-
-#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
- /* this option allow a potential SSL 2.0 rollback (CAN-2005-2969) */
- SSL_CTX_set_options(ssl->ctx, SSL_OP_MSIE_SSLV2_RSA_PADDING);
-#endif
-
- SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLEAY_080_CLIENT_DH_BUG);
- SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_D5_BUG);
- SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_BLOCK_PADDING_BUG);
-
- SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_DH_USE);
-
- if (!(protocols & NGX_SSL_SSLv2)) {
- SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_SSLv2);
- }
- if (!(protocols & NGX_SSL_SSLv3)) {
- SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_SSLv3);
- }
- if (!(protocols & NGX_SSL_TLSv1)) {
- SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1);
- }
-#ifdef SSL_OP_NO_TLSv1_1
- if (!(protocols & NGX_SSL_TLSv1_1)) {
- SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_1);
- }
-#endif
-#ifdef SSL_OP_NO_TLSv1_2
- if (!(protocols & NGX_SSL_TLSv1_2)) {
- SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_2);
- }
-#endif
-
-#ifdef SSL_OP_NO_COMPRESSION
- SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION);
-#endif
-
-#ifdef SSL_MODE_RELEASE_BUFFERS
- SSL_CTX_set_mode(ssl->ctx, SSL_MODE_RELEASE_BUFFERS);
-#endif
-
- SSL_CTX_set_read_ahead(ssl->ctx, 1);
-
- SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
- ngx_str_t *key)
-{
- BIO *bio;
- X509 *x509;
- u_long n;
-
- if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
- return NGX_ERROR;
- }
-
- /*
- * we can't use SSL_CTX_use_certificate_chain_file() as it doesn't
- * allow to access certificate later from SSL_CTX, so we reimplement
- * it here
- */
-
- bio = BIO_new_file((char *) cert->data, "r");
- if (bio == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "BIO_new_file(\"%s\") failed", cert->data);
- return NGX_ERROR;
- }
-
- x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
- if (x509 == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "PEM_read_bio_X509_AUX(\"%s\") failed", cert->data);
- BIO_free(bio);
- return NGX_ERROR;
- }
-
- if (SSL_CTX_use_certificate(ssl->ctx, x509) == 0) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_CTX_use_certificate(\"%s\") failed", cert->data);
- X509_free(x509);
- BIO_free(bio);
- return NGX_ERROR;
- }
-
- if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, x509)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_CTX_set_ex_data() failed");
- X509_free(x509);
- BIO_free(bio);
- return NGX_ERROR;
- }
-
- X509_free(x509);
-
- /* read rest of the chain */
-
- for ( ;; ) {
-
- x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
- if (x509 == NULL) {
- n = ERR_peek_last_error();
-
- if (ERR_GET_LIB(n) == ERR_LIB_PEM
- && ERR_GET_REASON(n) == PEM_R_NO_START_LINE)
- {
- /* end of file */
- ERR_clear_error();
- break;
- }
-
- /* some real error */
-
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "PEM_read_bio_X509(\"%s\") failed", cert->data);
- BIO_free(bio);
- return NGX_ERROR;
- }
-
- if (SSL_CTX_add_extra_chain_cert(ssl->ctx, x509) == 0) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_CTX_add_extra_chain_cert(\"%s\") failed",
- cert->data);
- X509_free(x509);
- BIO_free(bio);
- return NGX_ERROR;
- }
- }
-
- BIO_free(bio);
-
- if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (SSL_CTX_use_PrivateKey_file(ssl->ctx, (char *) key->data,
- SSL_FILETYPE_PEM)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_CTX_use_PrivateKey_file(\"%s\") failed", key->data);
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
- ngx_int_t depth)
-{
- STACK_OF(X509_NAME) *list;
-
- SSL_CTX_set_verify(ssl->ctx, SSL_VERIFY_PEER, ngx_ssl_verify_callback);
-
- SSL_CTX_set_verify_depth(ssl->ctx, depth);
-
- if (cert->len == 0) {
- return NGX_OK;
- }
-
- if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_CTX_load_verify_locations(\"%s\") failed",
- cert->data);
- return NGX_ERROR;
- }
-
- /*
- * SSL_CTX_load_verify_locations() may leave errors in the error queue
- * while returning success
- */
-
- ERR_clear_error();
-
- list = SSL_load_client_CA_file((char *) cert->data);
-
- if (list == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_load_client_CA_file(\"%s\") failed", cert->data);
- return NGX_ERROR;
- }
-
- /*
- * before 0.9.7h and 0.9.8 SSL_load_client_CA_file()
- * always leaved an error in the error queue
- */
-
- ERR_clear_error();
-
- SSL_CTX_set_client_CA_list(ssl->ctx, list);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
- ngx_int_t depth)
-{
- SSL_CTX_set_verify_depth(ssl->ctx, depth);
-
- if (cert->len == 0) {
- return NGX_OK;
- }
-
- if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_CTX_load_verify_locations(\"%s\") failed",
- cert->data);
- return NGX_ERROR;
- }
-
- /*
- * SSL_CTX_load_verify_locations() may leave errors in the error queue
- * while returning success
- */
-
- ERR_clear_error();
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl)
-{
- X509_STORE *store;
- X509_LOOKUP *lookup;
-
- if (crl->len == 0) {
- return NGX_OK;
- }
-
- if (ngx_conf_full_name(cf->cycle, crl, 1) != NGX_OK) {
- return NGX_ERROR;
- }
-
- store = SSL_CTX_get_cert_store(ssl->ctx);
-
- if (store == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_CTX_get_cert_store() failed");
- return NGX_ERROR;
- }
-
- lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
-
- if (lookup == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "X509_STORE_add_lookup() failed");
- return NGX_ERROR;
- }
-
- if (X509_LOOKUP_load_file(lookup, (char *) crl->data, X509_FILETYPE_PEM)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "X509_LOOKUP_load_file(\"%s\") failed", crl->data);
- return NGX_ERROR;
- }
-
- X509_STORE_set_flags(store,
- X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
-
- return NGX_OK;
-}
-
-
-static int
-ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
-{
-#if (NGX_DEBUG)
- char *subject, *issuer;
- int err, depth;
- X509 *cert;
- X509_NAME *sname, *iname;
- ngx_connection_t *c;
- ngx_ssl_conn_t *ssl_conn;
-
- ssl_conn = X509_STORE_CTX_get_ex_data(x509_store,
- SSL_get_ex_data_X509_STORE_CTX_idx());
-
- c = ngx_ssl_get_connection(ssl_conn);
-
- cert = X509_STORE_CTX_get_current_cert(x509_store);
- err = X509_STORE_CTX_get_error(x509_store);
- depth = X509_STORE_CTX_get_error_depth(x509_store);
-
- sname = X509_get_subject_name(cert);
- subject = sname ? X509_NAME_oneline(sname, NULL, 0) : "(none)";
-
- iname = X509_get_issuer_name(cert);
- issuer = iname ? X509_NAME_oneline(iname, NULL, 0) : "(none)";
-
- ngx_log_debug5(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "verify:%d, error:%d, depth:%d, "
- "subject:\"%s\",issuer: \"%s\"",
- ok, err, depth, subject, issuer);
-
- if (sname) {
- OPENSSL_free(subject);
- }
-
- if (iname) {
- OPENSSL_free(issuer);
- }
-#endif
-
- return 1;
-}
-
-
-static void
-ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
-{
- BIO *rbio, *wbio;
- ngx_connection_t *c;
-
- if (where & SSL_CB_HANDSHAKE_START) {
- c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
-
- if (c->ssl->handshaked) {
- c->ssl->renegotiation = 1;
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL renegotiation");
- }
- }
-
- if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
- c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
-
- if (!c->ssl->handshake_buffer_set) {
- /*
- * By default OpenSSL uses 4k buffer during a handshake,
- * which is too low for long certificate chains and might
- * result in extra round-trips.
- *
- * To adjust a buffer size we detect that buffering was added
- * to write side of the connection by comparing rbio and wbio.
- * If they are different, we assume that it's due to buffering
- * added to wbio, and set buffer size.
- */
-
- rbio = SSL_get_rbio((ngx_ssl_conn_t *) ssl_conn);
- wbio = SSL_get_wbio((ngx_ssl_conn_t *) ssl_conn);
-
- if (rbio != wbio) {
- (void) BIO_set_write_buffer_size(wbio, NGX_SSL_BUFSIZE);
- c->ssl->handshake_buffer_set = 1;
- }
- }
- }
-}
-
-
-RSA *
-ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export,
- int key_length)
-{
- static RSA *key;
-
- if (key_length == 512) {
- if (key == NULL) {
- key = RSA_generate_key(512, RSA_F4, NULL, NULL);
- }
- }
-
- return key;
-}
-
-
-ngx_int_t
-ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
-{
- DH *dh;
- BIO *bio;
-
- /*
- * -----BEGIN DH PARAMETERS-----
- * MIGHAoGBALu8LcrYRnSQfEP89YDpz9vZWKP1aLQtSwju1OsPs1BMbAMCducQgAxc
- * y7qokiYUxb7spWWl/fHSh6K8BJvmd4Bg6RqSp1fjBI9osHb302zI8pul34HcLKcl
- * 7OZicMyaUDXYzs7vnqAnSmOrHlj6/UmI0PZdFGdX2gcd8EXP4WubAgEC
- * -----END DH PARAMETERS-----
- */
-
- static unsigned char dh1024_p[] = {
- 0xBB, 0xBC, 0x2D, 0xCA, 0xD8, 0x46, 0x74, 0x90, 0x7C, 0x43, 0xFC, 0xF5,
- 0x80, 0xE9, 0xCF, 0xDB, 0xD9, 0x58, 0xA3, 0xF5, 0x68, 0xB4, 0x2D, 0x4B,
- 0x08, 0xEE, 0xD4, 0xEB, 0x0F, 0xB3, 0x50, 0x4C, 0x6C, 0x03, 0x02, 0x76,
- 0xE7, 0x10, 0x80, 0x0C, 0x5C, 0xCB, 0xBA, 0xA8, 0x92, 0x26, 0x14, 0xC5,
- 0xBE, 0xEC, 0xA5, 0x65, 0xA5, 0xFD, 0xF1, 0xD2, 0x87, 0xA2, 0xBC, 0x04,
- 0x9B, 0xE6, 0x77, 0x80, 0x60, 0xE9, 0x1A, 0x92, 0xA7, 0x57, 0xE3, 0x04,
- 0x8F, 0x68, 0xB0, 0x76, 0xF7, 0xD3, 0x6C, 0xC8, 0xF2, 0x9B, 0xA5, 0xDF,
- 0x81, 0xDC, 0x2C, 0xA7, 0x25, 0xEC, 0xE6, 0x62, 0x70, 0xCC, 0x9A, 0x50,
- 0x35, 0xD8, 0xCE, 0xCE, 0xEF, 0x9E, 0xA0, 0x27, 0x4A, 0x63, 0xAB, 0x1E,
- 0x58, 0xFA, 0xFD, 0x49, 0x88, 0xD0, 0xF6, 0x5D, 0x14, 0x67, 0x57, 0xDA,
- 0x07, 0x1D, 0xF0, 0x45, 0xCF, 0xE1, 0x6B, 0x9B
- };
-
- static unsigned char dh1024_g[] = { 0x02 };
-
-
- if (file->len == 0) {
-
- dh = DH_new();
- if (dh == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "DH_new() failed");
- return NGX_ERROR;
- }
-
- dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
- dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
-
- if (dh->p == NULL || dh->g == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "BN_bin2bn() failed");
- DH_free(dh);
- return NGX_ERROR;
- }
-
- SSL_CTX_set_tmp_dh(ssl->ctx, dh);
-
- DH_free(dh);
-
- return NGX_OK;
- }
-
- if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) {
- return NGX_ERROR;
- }
-
- bio = BIO_new_file((char *) file->data, "r");
- if (bio == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "BIO_new_file(\"%s\") failed", file->data);
- return NGX_ERROR;
- }
-
- dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
- if (dh == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "PEM_read_bio_DHparams(\"%s\") failed", file->data);
- BIO_free(bio);
- return NGX_ERROR;
- }
-
- SSL_CTX_set_tmp_dh(ssl->ctx, dh);
-
- DH_free(dh);
- BIO_free(bio);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
-{
-#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
-#ifndef OPENSSL_NO_ECDH
- int nid;
- EC_KEY *ecdh;
-
- /*
- * Elliptic-Curve Diffie-Hellman parameters are either "named curves"
- * from RFC 4492 section 5.1.1, or explicitly described curves over
- * binary fields. OpenSSL only supports the "named curves", which provide
- * maximum interoperability.
- */
-
- nid = OBJ_sn2nid((const char *) name->data);
- if (nid == 0) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "Unknown curve name \"%s\"", name->data);
- return NGX_ERROR;
- }
-
- ecdh = EC_KEY_new_by_curve_name(nid);
- if (ecdh == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "Unable to create curve \"%s\"", name->data);
- return NGX_ERROR;
- }
-
- SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE);
-
- SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh);
-
- EC_KEY_free(ecdh);
-#endif
-#endif
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)
-{
- ngx_ssl_connection_t *sc;
-
- sc = ngx_pcalloc(c->pool, sizeof(ngx_ssl_connection_t));
- if (sc == NULL) {
- return NGX_ERROR;
- }
-
- sc->buffer = ((flags & NGX_SSL_BUFFER) != 0);
- sc->buffer_size = ssl->buffer_size;
-
- sc->connection = SSL_new(ssl->ctx);
-
- if (sc->connection == NULL) {
- ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed");
- return NGX_ERROR;
- }
-
- if (SSL_set_fd(sc->connection, c->fd) == 0) {
- ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed");
- return NGX_ERROR;
- }
-
- if (flags & NGX_SSL_CLIENT) {
- SSL_set_connect_state(sc->connection);
-
- } else {
- SSL_set_accept_state(sc->connection);
- }
-
- if (SSL_set_ex_data(sc->connection, ngx_ssl_connection_index, c) == 0) {
- ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_ex_data() failed");
- return NGX_ERROR;
- }
-
- c->ssl = sc;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session)
-{
- if (session) {
- if (SSL_set_session(c->ssl->connection, session) == 0) {
- ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_session() failed");
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-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);
-
- if (n == 1) {
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
-#if (NGX_DEBUG)
- {
- char buf[129], *s, *d;
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
- const
-#endif
- SSL_CIPHER *cipher;
-
- cipher = SSL_get_current_cipher(c->ssl->connection);
-
- if (cipher) {
- SSL_CIPHER_description(cipher, &buf[1], 128);
-
- for (s = &buf[1], d = buf; *s; s++) {
- if (*s == ' ' && *d == ' ') {
- continue;
- }
-
- if (*s == LF || *s == CR) {
- continue;
- }
-
- *++d = *s;
- }
-
- if (*d != ' ') {
- d++;
- }
-
- *d = '\0';
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "SSL: %s, cipher: \"%s\"",
- SSL_get_version(c->ssl->connection), &buf[1]);
-
- if (SSL_session_reused(c->ssl->connection)) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "SSL reused session");
- }
-
- } else {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "SSL no shared ciphers");
- }
- }
-#endif
-
- c->ssl->handshaked = 1;
-
- c->recv = ngx_ssl_recv;
- c->send = ngx_ssl_write;
- c->recv_chain = ngx_ssl_recv_chain;
- c->send_chain = ngx_ssl_send_chain;
-
- /* initial handshake done, disable renegotiation (CVE-2009-3555) */
- if (c->ssl->connection->s3) {
- c->ssl->connection->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;
- }
-
- return NGX_OK;
- }
-
- sslerr = SSL_get_error(c->ssl->connection, n);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
-
- if (sslerr == SSL_ERROR_WANT_READ) {
- c->read->ready = 0;
- c->read->handler = ngx_ssl_handshake_handler;
- c->write->handler = ngx_ssl_handshake_handler;
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return NGX_AGAIN;
- }
-
- if (sslerr == SSL_ERROR_WANT_WRITE) {
- c->write->ready = 0;
- c->read->handler = ngx_ssl_handshake_handler;
- c->write->handler = ngx_ssl_handshake_handler;
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return NGX_AGAIN;
- }
-
- err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
-
- c->ssl->no_wait_shutdown = 1;
- c->ssl->no_send_shutdown = 1;
- c->read->eof = 1;
-
- if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
- ngx_log_error(NGX_LOG_INFO, c->log, err,
- "peer closed connection in SSL handshake");
-
- return NGX_ERROR;
- }
-
- c->read->error = 1;
-
- ngx_ssl_connection_error(c, sslerr, err, "SSL_do_handshake() failed");
-
- return NGX_ERROR;
-}
-
-
-static void
-ngx_ssl_handshake_handler(ngx_event_t *ev)
-{
- ngx_connection_t *c;
-
- c = ev->data;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "SSL handshake handler: %d", ev->write);
-
- if (ev->timedout) {
- c->ssl->handler(c);
- return;
- }
-
- if (ngx_ssl_handshake(c) == NGX_AGAIN) {
- return;
- }
-
- c->ssl->handler(c);
-}
-
-
-ssize_t
-ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl)
-{
- u_char *last;
- ssize_t n, bytes;
- ngx_buf_t *b;
-
- bytes = 0;
-
- b = cl->buf;
- last = b->last;
-
- for ( ;; ) {
-
- n = ngx_ssl_recv(c, last, b->end - last);
-
- if (n > 0) {
- last += n;
- bytes += n;
-
- if (last == b->end) {
- cl = cl->next;
-
- if (cl == NULL) {
- return bytes;
- }
-
- b = cl->buf;
- last = b->last;
- }
-
- continue;
- }
-
- if (bytes) {
-
- if (n == 0 || n == NGX_ERROR) {
- c->read->ready = 1;
- }
-
- return bytes;
- }
-
- return n;
- }
-}
-
-
-ssize_t
-ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
-{
- int n, bytes;
-
- if (c->ssl->last == NGX_ERROR) {
- c->read->error = 1;
- return NGX_ERROR;
- }
-
- if (c->ssl->last == NGX_DONE) {
- c->read->ready = 0;
- c->read->eof = 1;
- return 0;
- }
-
- 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
- */
-
- for ( ;; ) {
-
- n = SSL_read(c->ssl->connection, buf, size);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n);
-
- if (n > 0) {
- bytes += n;
- }
-
- c->ssl->last = ngx_ssl_handle_recv(c, n);
-
- if (c->ssl->last == NGX_OK) {
-
- size -= n;
-
- if (size == 0) {
- c->read->ready = 1;
- return bytes;
- }
-
- buf += n;
-
- continue;
- }
-
- if (bytes) {
- if (c->ssl->last != NGX_AGAIN) {
- c->read->ready = 1;
- }
-
- return bytes;
- }
-
- switch (c->ssl->last) {
-
- case NGX_DONE:
- c->read->ready = 0;
- c->read->eof = 1;
- return 0;
-
- case NGX_ERROR:
- c->read->error = 1;
-
- /* fall through */
-
- case NGX_AGAIN:
- return c->ssl->last;
- }
- }
-}
-
-
-static ngx_int_t
-ngx_ssl_handle_recv(ngx_connection_t *c, int n)
-{
- int sslerr;
- ngx_err_t err;
-
- if (c->ssl->renegotiation) {
- /*
- * disable renegotiation (CVE-2009-3555):
- * OpenSSL (at least up to 0.9.8l) does not handle disabled
- * renegotiation gracefully, so drop connection here
- */
-
- ngx_log_error(NGX_LOG_NOTICE, c->log, 0, "SSL renegotiation disabled");
-
- while (ERR_peek_error()) {
- ngx_ssl_error(NGX_LOG_DEBUG, c->log, 0,
- "ignoring stale global SSL error");
- }
-
- ERR_clear_error();
-
- c->ssl->no_wait_shutdown = 1;
- c->ssl->no_send_shutdown = 1;
-
- return NGX_ERROR;
- }
-
- if (n > 0) {
-
- if (c->ssl->saved_write_handler) {
-
- c->write->handler = c->ssl->saved_write_handler;
- c->ssl->saved_write_handler = NULL;
- c->write->ready = 1;
-
- if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_post_event(c->write, &ngx_posted_events);
- }
-
- return NGX_OK;
- }
-
- sslerr = SSL_get_error(c->ssl->connection, n);
-
- err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
-
- if (sslerr == SSL_ERROR_WANT_READ) {
- c->read->ready = 0;
- return NGX_AGAIN;
- }
-
- if (sslerr == SSL_ERROR_WANT_WRITE) {
-
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "peer started SSL renegotiation");
-
- c->write->ready = 0;
-
- if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- /*
- * we do not set the timer because there is already the read event timer
- */
-
- if (c->ssl->saved_write_handler == NULL) {
- c->ssl->saved_write_handler = c->write->handler;
- c->write->handler = ngx_ssl_write_handler;
- }
-
- return NGX_AGAIN;
- }
-
- c->ssl->no_wait_shutdown = 1;
- c->ssl->no_send_shutdown = 1;
-
- if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "peer shutdown SSL cleanly");
- return NGX_DONE;
- }
-
- ngx_ssl_connection_error(c, sslerr, err, "SSL_read() failed");
-
- return NGX_ERROR;
-}
-
-
-static void
-ngx_ssl_write_handler(ngx_event_t *wev)
-{
- ngx_connection_t *c;
-
- c = wev->data;
-
- c->read->handler(c->read);
-}
-
-
-/*
- * OpenSSL has no SSL_writev() so we copy several bufs into our 16K buffer
- * before the SSL_write() call to decrease a SSL overhead.
- *
- * Besides for protocols such as HTTP it is possible to always buffer
- * the output to decrease a SSL overhead some more.
- */
-
-ngx_chain_t *
-ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
-{
- int n;
- ngx_uint_t flush;
- ssize_t send, size;
- ngx_buf_t *buf;
-
- if (!c->ssl->buffer) {
-
- while (in) {
- if (ngx_buf_special(in->buf)) {
- in = in->next;
- continue;
- }
-
- n = ngx_ssl_write(c, in->buf->pos, in->buf->last - in->buf->pos);
-
- if (n == NGX_ERROR) {
- return NGX_CHAIN_ERROR;
- }
-
- if (n == NGX_AGAIN) {
- return in;
- }
-
- in->buf->pos += n;
- c->sent += n;
-
- if (in->buf->pos == in->buf->last) {
- in = in->next;
- }
- }
-
- return in;
- }
-
-
- /* the maximum limit size is the maximum int32_t value - the page size */
-
- if (limit == 0 || limit > (off_t) (NGX_MAX_INT32_VALUE - ngx_pagesize)) {
- limit = NGX_MAX_INT32_VALUE - ngx_pagesize;
- }
-
- buf = c->ssl->buf;
-
- if (buf == NULL) {
- buf = ngx_create_temp_buf(c->pool, c->ssl->buffer_size);
- if (buf == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- c->ssl->buf = buf;
- }
-
- if (buf->start == NULL) {
- buf->start = ngx_palloc(c->pool, c->ssl->buffer_size);
- if (buf->start == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- buf->pos = buf->start;
- buf->last = buf->start;
- buf->end = buf->start + c->ssl->buffer_size;
- }
-
- send = buf->last - buf->pos;
- flush = (in == NULL) ? 1 : buf->flush;
-
- for ( ;; ) {
-
- while (in && buf->last < buf->end && send < limit) {
- if (in->buf->last_buf || in->buf->flush) {
- flush = 1;
- }
-
- if (ngx_buf_special(in->buf)) {
- in = in->next;
- continue;
- }
-
- size = in->buf->last - in->buf->pos;
-
- if (size > buf->end - buf->last) {
- size = buf->end - buf->last;
- }
-
- if (send + size > limit) {
- size = (ssize_t) (limit - send);
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "SSL buf copy: %d", size);
-
- ngx_memcpy(buf->last, in->buf->pos, size);
-
- buf->last += size;
- in->buf->pos += size;
- send += size;
-
- if (in->buf->pos == in->buf->last) {
- in = in->next;
- }
- }
-
- if (!flush && send < limit && buf->last < buf->end) {
- break;
- }
-
- size = buf->last - buf->pos;
-
- if (size == 0) {
- buf->flush = 0;
- c->buffered &= ~NGX_SSL_BUFFERED;
- return in;
- }
-
- n = ngx_ssl_write(c, buf->pos, size);
-
- if (n == NGX_ERROR) {
- return NGX_CHAIN_ERROR;
- }
-
- if (n == NGX_AGAIN) {
- break;
- }
-
- buf->pos += n;
- c->sent += n;
-
- if (n < size) {
- break;
- }
-
- flush = 0;
-
- buf->pos = buf->start;
- buf->last = buf->start;
-
- if (in == NULL || send == limit) {
- break;
- }
- }
-
- buf->flush = flush;
-
- if (buf->pos < buf->last) {
- c->buffered |= NGX_SSL_BUFFERED;
-
- } else {
- c->buffered &= ~NGX_SSL_BUFFERED;
- }
-
- return in;
-}
-
-
-ssize_t
-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);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n);
-
- if (n > 0) {
-
- if (c->ssl->saved_read_handler) {
-
- c->read->handler = c->ssl->saved_read_handler;
- c->ssl->saved_read_handler = NULL;
- c->read->ready = 1;
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_post_event(c->read, &ngx_posted_events);
- }
-
- return n;
- }
-
- sslerr = SSL_get_error(c->ssl->connection, n);
-
- err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
-
- if (sslerr == SSL_ERROR_WANT_WRITE) {
- c->write->ready = 0;
- return NGX_AGAIN;
- }
-
- if (sslerr == SSL_ERROR_WANT_READ) {
-
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "peer started SSL renegotiation");
-
- c->read->ready = 0;
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- /*
- * we do not set the timer because there is already
- * the write event timer
- */
-
- if (c->ssl->saved_read_handler == NULL) {
- c->ssl->saved_read_handler = c->read->handler;
- c->read->handler = ngx_ssl_read_handler;
- }
-
- return NGX_AGAIN;
- }
-
- c->ssl->no_wait_shutdown = 1;
- c->ssl->no_send_shutdown = 1;
- c->write->error = 1;
-
- ngx_ssl_connection_error(c, sslerr, err, "SSL_write() failed");
-
- return NGX_ERROR;
-}
-
-
-static void
-ngx_ssl_read_handler(ngx_event_t *rev)
-{
- ngx_connection_t *c;
-
- c = rev->data;
-
- c->write->handler(c->write);
-}
-
-
-void
-ngx_ssl_free_buffer(ngx_connection_t *c)
-{
- if (c->ssl->buf && c->ssl->buf->start) {
- if (ngx_pfree(c->pool, c->ssl->buf->start) == NGX_OK) {
- c->ssl->buf->start = NULL;
- }
- }
-}
-
-
-ngx_int_t
-ngx_ssl_shutdown(ngx_connection_t *c)
-{
- int n, sslerr, mode;
- ngx_err_t err;
-
- if (c->timedout) {
- mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN;
- SSL_set_quiet_shutdown(c->ssl->connection, 1);
-
- } else {
- mode = SSL_get_shutdown(c->ssl->connection);
-
- if (c->ssl->no_wait_shutdown) {
- mode |= SSL_RECEIVED_SHUTDOWN;
- }
-
- if (c->ssl->no_send_shutdown) {
- mode |= SSL_SENT_SHUTDOWN;
- }
-
- if (c->ssl->no_wait_shutdown && c->ssl->no_send_shutdown) {
- SSL_set_quiet_shutdown(c->ssl->connection, 1);
- }
- }
-
- SSL_set_shutdown(c->ssl->connection, mode);
-
- 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;
-
- /* SSL_shutdown() never returns -1, on error it returns 0 */
-
- 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 (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;
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (sslerr == SSL_ERROR_WANT_READ) {
- ngx_add_timer(c->read, 30000);
- }
-
- return NGX_AGAIN;
- }
-
- err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
-
- ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
-
- SSL_free(c->ssl->connection);
- c->ssl = NULL;
-
- return NGX_ERROR;
-}
-
-
-static void
-ngx_ssl_shutdown_handler(ngx_event_t *ev)
-{
- ngx_connection_t *c;
- ngx_connection_handler_pt handler;
-
- c = ev->data;
- handler = c->ssl->handler;
-
- if (ev->timedout) {
- c->timedout = 1;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, "SSL shutdown handler");
-
- if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
- return;
- }
-
- handler(c);
-}
-
-
-static void
-ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
- char *text)
-{
- int n;
- ngx_uint_t level;
-
- level = NGX_LOG_CRIT;
-
- if (sslerr == SSL_ERROR_SYSCALL) {
-
- if (err == NGX_ECONNRESET
- || err == NGX_EPIPE
- || err == NGX_ENOTCONN
- || err == NGX_ETIMEDOUT
- || err == NGX_ECONNREFUSED
- || err == NGX_ENETDOWN
- || err == NGX_ENETUNREACH
- || err == NGX_EHOSTDOWN
- || err == NGX_EHOSTUNREACH)
- {
- switch (c->log_error) {
-
- case NGX_ERROR_IGNORE_ECONNRESET:
- case NGX_ERROR_INFO:
- level = NGX_LOG_INFO;
- break;
-
- case NGX_ERROR_ERR:
- level = NGX_LOG_ERR;
- break;
-
- default:
- break;
- }
- }
-
- } else if (sslerr == SSL_ERROR_SSL) {
-
- n = ERR_GET_REASON(ERR_peek_error());
-
- /* handshake failures */
- if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC /* 103 */
- || n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG /* 129 */
- || n == SSL_R_DIGEST_CHECK_FAILED /* 149 */
- || n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST /* 151 */
- || n == SSL_R_EXCESSIVE_MESSAGE_SIZE /* 152 */
- || n == SSL_R_LENGTH_MISMATCH /* 159 */
- || n == SSL_R_NO_CIPHERS_PASSED /* 182 */
- || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */
- || n == SSL_R_NO_COMPRESSION_SPECIFIED /* 187 */
- || n == SSL_R_NO_SHARED_CIPHER /* 193 */
- || n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */
-#ifdef SSL_R_PARSE_TLSEXT
- || n == SSL_R_PARSE_TLSEXT /* 227 */
-#endif
- || n == SSL_R_UNEXPECTED_MESSAGE /* 244 */
- || n == SSL_R_UNEXPECTED_RECORD /* 245 */
- || n == SSL_R_UNKNOWN_ALERT_TYPE /* 246 */
- || n == SSL_R_UNKNOWN_PROTOCOL /* 252 */
- || n == SSL_R_WRONG_VERSION_NUMBER /* 267 */
- || n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC /* 281 */
-#ifdef SSL_R_RENEGOTIATE_EXT_TOO_LONG
- || n == SSL_R_RENEGOTIATE_EXT_TOO_LONG /* 335 */
- || n == SSL_R_RENEGOTIATION_ENCODING_ERR /* 336 */
- || n == SSL_R_RENEGOTIATION_MISMATCH /* 337 */
-#endif
-#ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED
- || n == SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED /* 338 */
-#endif
-#ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING
- || n == SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING /* 345 */
-#endif
- || n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */
- || n == SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE /* 1010 */
- || n == SSL_R_SSLV3_ALERT_BAD_RECORD_MAC /* 1020 */
- || n == SSL_R_TLSV1_ALERT_DECRYPTION_FAILED /* 1021 */
- || n == SSL_R_TLSV1_ALERT_RECORD_OVERFLOW /* 1022 */
- || n == SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE /* 1030 */
- || n == SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE /* 1040 */
- || n == SSL_R_SSLV3_ALERT_NO_CERTIFICATE /* 1041 */
- || n == SSL_R_SSLV3_ALERT_BAD_CERTIFICATE /* 1042 */
- || n == SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE /* 1043 */
- || n == SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED /* 1044 */
- || n == SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED /* 1045 */
- || n == SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN /* 1046 */
- || n == SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER /* 1047 */
- || n == SSL_R_TLSV1_ALERT_UNKNOWN_CA /* 1048 */
- || n == SSL_R_TLSV1_ALERT_ACCESS_DENIED /* 1049 */
- || n == SSL_R_TLSV1_ALERT_DECODE_ERROR /* 1050 */
- || n == SSL_R_TLSV1_ALERT_DECRYPT_ERROR /* 1051 */
- || n == SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION /* 1060 */
- || n == SSL_R_TLSV1_ALERT_PROTOCOL_VERSION /* 1070 */
- || n == SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY /* 1071 */
- || n == SSL_R_TLSV1_ALERT_INTERNAL_ERROR /* 1080 */
- || n == SSL_R_TLSV1_ALERT_USER_CANCELLED /* 1090 */
- || n == SSL_R_TLSV1_ALERT_NO_RENEGOTIATION) /* 1100 */
- {
- switch (c->log_error) {
-
- case NGX_ERROR_IGNORE_ECONNRESET:
- case NGX_ERROR_INFO:
- level = NGX_LOG_INFO;
- break;
-
- case NGX_ERROR_ERR:
- level = NGX_LOG_ERR;
- break;
-
- default:
- break;
- }
- }
- }
-
- ngx_ssl_error(level, c->log, err, text);
-}
-
-
-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, ...)
-{
- int flags;
- u_long n;
- va_list args;
- u_char *p, *last;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
- const char *data;
-
- last = errstr + NGX_MAX_CONF_ERRSTR;
-
- va_start(args, fmt);
- p = ngx_vslprintf(errstr, last - 1, fmt, args);
- va_end(args);
-
- p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p);
-
- for ( ;; ) {
-
- n = ERR_peek_error_line_data(NULL, NULL, &data, &flags);
-
- if (n == 0) {
- break;
- }
-
- if (p >= last) {
- goto next;
- }
-
- *p++ = ' ';
-
- ERR_error_string_n(n, (char *) p, last - p);
-
- while (p < last && *p) {
- p++;
- }
-
- if (p < last && *data && (flags & ERR_TXT_STRING)) {
- *p++ = ':';
- p = ngx_cpystrn(p, (u_char *) data, last - p);
- }
-
- next:
-
- (void) ERR_get_error();
- }
-
- ngx_log_error(level, log, err, "%s)", errstr);
-}
-
-
-ngx_int_t
-ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
- ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout)
-{
- long cache_mode;
-
- SSL_CTX_set_timeout(ssl->ctx, (long) timeout);
-
- if (builtin_session_cache == NGX_SSL_NO_SCACHE) {
- SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF);
- return NGX_OK;
- }
-
- SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len);
-
- if (builtin_session_cache == NGX_SSL_NONE_SCACHE) {
-
- /*
- * If the server explicitly says that it does not support
- * session reuse (see SSL_SESS_CACHE_OFF above), then
- * Outlook Express fails to upload a sent email to
- * the Sent Items folder on the IMAP server via a separate IMAP
- * connection in the background. Therefore we have a special
- * mode (SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL_STORE)
- * where the server pretends that it supports session reuse,
- * but it does not actually store any session.
- */
-
- SSL_CTX_set_session_cache_mode(ssl->ctx,
- SSL_SESS_CACHE_SERVER
- |SSL_SESS_CACHE_NO_AUTO_CLEAR
- |SSL_SESS_CACHE_NO_INTERNAL_STORE);
-
- SSL_CTX_sess_set_cache_size(ssl->ctx, 1);
-
- return NGX_OK;
- }
-
- cache_mode = SSL_SESS_CACHE_SERVER;
-
- if (shm_zone && builtin_session_cache == NGX_SSL_NO_BUILTIN_SCACHE) {
- cache_mode |= SSL_SESS_CACHE_NO_INTERNAL;
- }
-
- SSL_CTX_set_session_cache_mode(ssl->ctx, cache_mode);
-
- if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) {
-
- if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) {
- SSL_CTX_sess_set_cache_size(ssl->ctx, builtin_session_cache);
- }
- }
-
- if (shm_zone) {
- SSL_CTX_sess_set_new_cb(ssl->ctx, ngx_ssl_new_session);
- SSL_CTX_sess_set_get_cb(ssl->ctx, ngx_ssl_get_cached_session);
- SSL_CTX_sess_set_remove_cb(ssl->ctx, ngx_ssl_remove_session);
-
- if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_session_cache_index, shm_zone)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_CTX_set_ex_data() failed");
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
-{
- size_t len;
- ngx_slab_pool_t *shpool;
- ngx_ssl_session_cache_t *cache;
-
- if (data) {
- shm_zone->data = data;
- return NGX_OK;
- }
-
- shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
-
- if (shm_zone->shm.exists) {
- shm_zone->data = shpool->data;
- return NGX_OK;
- }
-
- cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t));
- if (cache == NULL) {
- return NGX_ERROR;
- }
-
- shpool->data = cache;
- shm_zone->data = cache;
-
- ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel,
- ngx_ssl_session_rbtree_insert_value);
-
- ngx_queue_init(&cache->expire_queue);
-
- len = sizeof(" in SSL session shared cache \"\"") + shm_zone->shm.name.len;
-
- shpool->log_ctx = ngx_slab_alloc(shpool, len);
- if (shpool->log_ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_sprintf(shpool->log_ctx, " in SSL session shared cache \"%V\"%Z",
- &shm_zone->shm.name);
-
- shpool->log_nomem = 0;
-
- return NGX_OK;
-}
-
-
-/*
- * The length of the session id is 16 bytes for SSLv2 sessions and
- * between 1 and 32 bytes for SSLv3/TLSv1, typically 32 bytes.
- * It seems that the typical length of the external ASN1 representation
- * of a session is 118 or 119 bytes for SSLv3/TSLv1.
- *
- * Thus on 32-bit platforms we allocate separately an rbtree node,
- * a session id, and an ASN1 representation, they take accordingly
- * 64, 32, and 128 bytes.
- *
- * On 64-bit platforms we allocate separately an rbtree node + session_id,
- * and an ASN1 representation, they take accordingly 128 and 128 bytes.
- *
- * OpenSSL's i2d_SSL_SESSION() and d2i_SSL_SESSION are slow,
- * so they are outside the code locked by shared pool mutex
- */
-
-static int
-ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess)
-{
- int len;
- u_char *p, *id, *cached_sess;
- uint32_t hash;
- SSL_CTX *ssl_ctx;
- ngx_shm_zone_t *shm_zone;
- ngx_connection_t *c;
- ngx_slab_pool_t *shpool;
- ngx_ssl_sess_id_t *sess_id;
- ngx_ssl_session_cache_t *cache;
- u_char buf[NGX_SSL_MAX_SESSION_SIZE];
-
- len = i2d_SSL_SESSION(sess, NULL);
-
- /* do not cache too big session */
-
- if (len > (int) NGX_SSL_MAX_SESSION_SIZE) {
- return 0;
- }
-
- p = buf;
- i2d_SSL_SESSION(sess, &p);
-
- c = ngx_ssl_get_connection(ssl_conn);
-
- ssl_ctx = SSL_get_SSL_CTX(ssl_conn);
- shm_zone = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_cache_index);
-
- cache = shm_zone->data;
- shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
-
- ngx_shmtx_lock(&shpool->mutex);
-
- /* drop one or two expired sessions */
- ngx_ssl_expire_sessions(cache, shpool, 1);
-
- cached_sess = ngx_slab_alloc_locked(shpool, len);
-
- if (cached_sess == NULL) {
-
- /* drop the oldest non-expired session and try once more */
-
- ngx_ssl_expire_sessions(cache, shpool, 0);
-
- cached_sess = ngx_slab_alloc_locked(shpool, len);
-
- if (cached_sess == NULL) {
- sess_id = NULL;
- goto failed;
- }
- }
-
- sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t));
-
- if (sess_id == NULL) {
-
- /* drop the oldest non-expired session and try once more */
-
- ngx_ssl_expire_sessions(cache, shpool, 0);
-
- sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t));
-
- if (sess_id == NULL) {
- goto failed;
- }
- }
-
-#if (NGX_PTR_SIZE == 8)
-
- id = sess_id->sess_id;
-
-#else
-
- id = ngx_slab_alloc_locked(shpool, sess->session_id_length);
-
- if (id == NULL) {
-
- /* drop the oldest non-expired session and try once more */
-
- ngx_ssl_expire_sessions(cache, shpool, 0);
-
- id = ngx_slab_alloc_locked(shpool, sess->session_id_length);
-
- if (id == NULL) {
- goto failed;
- }
- }
-
-#endif
-
- ngx_memcpy(cached_sess, buf, len);
-
- ngx_memcpy(id, sess->session_id, sess->session_id_length);
-
- hash = ngx_crc32_short(sess->session_id, sess->session_id_length);
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "ssl new session: %08XD:%d:%d",
- hash, sess->session_id_length, len);
-
- sess_id->node.key = hash;
- sess_id->node.data = (u_char) sess->session_id_length;
- sess_id->id = id;
- sess_id->len = len;
- sess_id->session = cached_sess;
-
- sess_id->expire = ngx_time() + SSL_CTX_get_timeout(ssl_ctx);
-
- ngx_queue_insert_head(&cache->expire_queue, &sess_id->queue);
-
- ngx_rbtree_insert(&cache->session_rbtree, &sess_id->node);
-
- ngx_shmtx_unlock(&shpool->mutex);
-
- return 0;
-
-failed:
-
- if (cached_sess) {
- ngx_slab_free_locked(shpool, cached_sess);
- }
-
- if (sess_id) {
- ngx_slab_free_locked(shpool, sess_id);
- }
-
- ngx_shmtx_unlock(&shpool->mutex);
-
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "could not allocate new session%s", shpool->log_ctx);
-
- return 0;
-}
-
-
-static ngx_ssl_session_t *
-ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len,
- int *copy)
-{
-#if OPENSSL_VERSION_NUMBER >= 0x0090707fL
- const
-#endif
- u_char *p;
- uint32_t hash;
- ngx_int_t rc;
- ngx_shm_zone_t *shm_zone;
- ngx_slab_pool_t *shpool;
- ngx_rbtree_node_t *node, *sentinel;
- ngx_ssl_session_t *sess;
- ngx_ssl_sess_id_t *sess_id;
- ngx_ssl_session_cache_t *cache;
- u_char buf[NGX_SSL_MAX_SESSION_SIZE];
-#if (NGX_DEBUG)
- ngx_connection_t *c;
-#endif
-
- hash = ngx_crc32_short(id, (size_t) len);
- *copy = 0;
-
-#if (NGX_DEBUG)
- c = ngx_ssl_get_connection(ssl_conn);
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "ssl get session: %08XD:%d", hash, len);
-#endif
-
- shm_zone = SSL_CTX_get_ex_data(SSL_get_SSL_CTX(ssl_conn),
- ngx_ssl_session_cache_index);
-
- cache = shm_zone->data;
-
- sess = NULL;
-
- shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
-
- ngx_shmtx_lock(&shpool->mutex);
-
- node = cache->session_rbtree.root;
- sentinel = cache->session_rbtree.sentinel;
-
- while (node != sentinel) {
-
- if (hash < node->key) {
- node = node->left;
- continue;
- }
-
- if (hash > node->key) {
- node = node->right;
- continue;
- }
-
- /* hash == node->key */
-
- sess_id = (ngx_ssl_sess_id_t *) node;
-
- rc = ngx_memn2cmp(id, sess_id->id, (size_t) len, (size_t) node->data);
-
- if (rc == 0) {
-
- if (sess_id->expire > ngx_time()) {
- ngx_memcpy(buf, sess_id->session, sess_id->len);
-
- ngx_shmtx_unlock(&shpool->mutex);
-
- p = buf;
- sess = d2i_SSL_SESSION(NULL, &p, sess_id->len);
-
- return sess;
- }
-
- ngx_queue_remove(&sess_id->queue);
-
- ngx_rbtree_delete(&cache->session_rbtree, node);
-
- ngx_slab_free_locked(shpool, sess_id->session);
-#if (NGX_PTR_SIZE == 4)
- ngx_slab_free_locked(shpool, sess_id->id);
-#endif
- ngx_slab_free_locked(shpool, sess_id);
-
- sess = NULL;
-
- goto done;
- }
-
- node = (rc < 0) ? node->left : node->right;
- }
-
-done:
-
- ngx_shmtx_unlock(&shpool->mutex);
-
- return sess;
-}
-
-
-void
-ngx_ssl_remove_cached_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
-{
- SSL_CTX_remove_session(ssl, sess);
-
- ngx_ssl_remove_session(ssl, sess);
-}
-
-
-static void
-ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess)
-{
- size_t len;
- u_char *id;
- uint32_t hash;
- ngx_int_t rc;
- ngx_shm_zone_t *shm_zone;
- ngx_slab_pool_t *shpool;
- ngx_rbtree_node_t *node, *sentinel;
- ngx_ssl_sess_id_t *sess_id;
- ngx_ssl_session_cache_t *cache;
-
- shm_zone = SSL_CTX_get_ex_data(ssl, ngx_ssl_session_cache_index);
-
- if (shm_zone == NULL) {
- return;
- }
-
- cache = shm_zone->data;
-
- id = sess->session_id;
- len = (size_t) sess->session_id_length;
-
- hash = ngx_crc32_short(id, len);
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
- "ssl remove session: %08XD:%uz", hash, len);
-
- shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
-
- ngx_shmtx_lock(&shpool->mutex);
-
- node = cache->session_rbtree.root;
- sentinel = cache->session_rbtree.sentinel;
-
- while (node != sentinel) {
-
- if (hash < node->key) {
- node = node->left;
- continue;
- }
-
- if (hash > node->key) {
- node = node->right;
- continue;
- }
-
- /* hash == node->key */
-
- sess_id = (ngx_ssl_sess_id_t *) node;
-
- rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data);
-
- if (rc == 0) {
-
- ngx_queue_remove(&sess_id->queue);
-
- ngx_rbtree_delete(&cache->session_rbtree, node);
-
- ngx_slab_free_locked(shpool, sess_id->session);
-#if (NGX_PTR_SIZE == 4)
- ngx_slab_free_locked(shpool, sess_id->id);
-#endif
- ngx_slab_free_locked(shpool, sess_id);
-
- goto done;
- }
-
- node = (rc < 0) ? node->left : node->right;
- }
-
-done:
-
- ngx_shmtx_unlock(&shpool->mutex);
-}
-
-
-static void
-ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache,
- ngx_slab_pool_t *shpool, ngx_uint_t n)
-{
- time_t now;
- ngx_queue_t *q;
- ngx_ssl_sess_id_t *sess_id;
-
- now = ngx_time();
-
- while (n < 3) {
-
- if (ngx_queue_empty(&cache->expire_queue)) {
- return;
- }
-
- q = ngx_queue_last(&cache->expire_queue);
-
- sess_id = ngx_queue_data(q, ngx_ssl_sess_id_t, queue);
-
- if (n++ != 0 && sess_id->expire > now) {
- return;
- }
-
- ngx_queue_remove(q);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
- "expire session: %08Xi", sess_id->node.key);
-
- ngx_rbtree_delete(&cache->session_rbtree, &sess_id->node);
-
- ngx_slab_free_locked(shpool, sess_id->session);
-#if (NGX_PTR_SIZE == 4)
- ngx_slab_free_locked(shpool, sess_id->id);
-#endif
- ngx_slab_free_locked(shpool, sess_id);
- }
-}
-
-
-static void
-ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
-{
- ngx_rbtree_node_t **p;
- ngx_ssl_sess_id_t *sess_id, *sess_id_temp;
-
- for ( ;; ) {
-
- if (node->key < temp->key) {
-
- p = &temp->left;
-
- } else if (node->key > temp->key) {
-
- p = &temp->right;
-
- } else { /* node->key == temp->key */
-
- sess_id = (ngx_ssl_sess_id_t *) node;
- sess_id_temp = (ngx_ssl_sess_id_t *) temp;
-
- p = (ngx_memn2cmp(sess_id->id, sess_id_temp->id,
- (size_t) node->data, (size_t) temp->data)
- < 0) ? &temp->left : &temp->right;
- }
-
- if (*p == sentinel) {
- break;
- }
-
- temp = *p;
- }
-
- *p = node;
- node->parent = temp;
- node->left = sentinel;
- node->right = sentinel;
- ngx_rbt_red(node);
-}
-
-
-#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
-
-ngx_int_t
-ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
-{
- u_char buf[48];
- ssize_t n;
- ngx_str_t *path;
- ngx_file_t file;
- ngx_uint_t i;
- ngx_array_t *keys;
- ngx_file_info_t fi;
- ngx_ssl_session_ticket_key_t *key;
-
- if (paths == NULL) {
- return NGX_OK;
- }
-
- keys = ngx_array_create(cf->pool, paths->nelts,
- sizeof(ngx_ssl_session_ticket_key_t));
- if (keys == NULL) {
- return NGX_ERROR;
- }
-
- path = paths->elts;
- for (i = 0; i < paths->nelts; i++) {
-
- if (ngx_conf_full_name(cf->cycle, &path[i], 1) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_memzero(&file, sizeof(ngx_file_t));
- file.name = path[i];
- file.log = cf->log;
-
- file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY, 0, 0);
- if (file.fd == NGX_INVALID_FILE) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
- ngx_open_file_n " \"%V\" failed", &file.name);
- return NGX_ERROR;
- }
-
- if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) {
- ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
- ngx_fd_info_n " \"%V\" failed", &file.name);
- goto failed;
- }
-
- if (ngx_file_size(&fi) != 48) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%V\" must be 48 bytes", &file.name);
- goto failed;
- }
-
- n = ngx_read_file(&file, buf, 48, 0);
-
- if (n == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
- ngx_read_file_n " \"%V\" failed", &file.name);
- goto failed;
- }
-
- if (n != 48) {
- ngx_conf_log_error(NGX_LOG_CRIT, cf, 0,
- ngx_read_file_n " \"%V\" returned only "
- "%z bytes instead of 48", &file.name, n);
- goto failed;
- }
-
- key = ngx_array_push(keys);
- if (key == NULL) {
- goto failed;
- }
-
- ngx_memcpy(key->name, buf, 16);
- ngx_memcpy(key->aes_key, buf + 16, 16);
- ngx_memcpy(key->hmac_key, buf + 32, 16);
-
- if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
- ngx_close_file_n " \"%V\" failed", &file.name);
- }
- }
-
- if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_session_ticket_keys_index, keys)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_CTX_set_ex_data() failed");
- return NGX_ERROR;
- }
-
- if (SSL_CTX_set_tlsext_ticket_key_cb(ssl->ctx,
- ngx_ssl_session_ticket_key_callback)
- == 0)
- {
- ngx_log_error(NGX_LOG_WARN, cf->log, 0,
- "nginx was built with Session Tickets support, however, "
- "now it is linked dynamically to an OpenSSL library "
- "which has no tlsext support, therefore Session Tickets "
- "are not available");
- }
-
- return NGX_OK;
-
-failed:
-
- if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
- ngx_close_file_n " \"%V\" failed", &file.name);
- }
-
- return NGX_ERROR;
-}
-
-
-#ifdef OPENSSL_NO_SHA256
-#define ngx_ssl_session_ticket_md EVP_sha1
-#else
-#define ngx_ssl_session_ticket_md EVP_sha256
-#endif
-
-
-static int
-ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn,
- unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx,
- HMAC_CTX *hctx, int enc)
-{
- SSL_CTX *ssl_ctx;
- ngx_uint_t i;
- ngx_array_t *keys;
- ngx_ssl_session_ticket_key_t *key;
-#if (NGX_DEBUG)
- u_char buf[32];
- ngx_connection_t *c;
-#endif
-
- ssl_ctx = SSL_get_SSL_CTX(ssl_conn);
-
- keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_ticket_keys_index);
- if (keys == NULL) {
- return -1;
- }
-
- key = keys->elts;
-
-#if (NGX_DEBUG)
- c = ngx_ssl_get_connection(ssl_conn);
-#endif
-
- if (enc == 1) {
- /* encrypt session ticket */
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "ssl session ticket encrypt, key: \"%*s\" (%s session)",
- ngx_hex_dump(buf, key[0].name, 16) - buf, buf,
- SSL_session_reused(ssl_conn) ? "reused" : "new");
-
- RAND_pseudo_bytes(iv, 16);
- EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key[0].aes_key, iv);
- HMAC_Init_ex(hctx, key[0].hmac_key, 16,
- ngx_ssl_session_ticket_md(), NULL);
- memcpy(name, key[0].name, 16);
-
- return 0;
-
- } else {
- /* decrypt session ticket */
-
- for (i = 0; i < keys->nelts; i++) {
- if (ngx_memcmp(name, key[i].name, 16) == 0) {
- goto found;
- }
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "ssl session ticket decrypt, key: \"%*s\" not found",
- ngx_hex_dump(buf, name, 16) - buf, buf);
-
- return 0;
-
- found:
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "ssl session ticket decrypt, key: \"%*s\"%s",
- ngx_hex_dump(buf, key[i].name, 16) - buf, buf,
- (i == 0) ? " (default)" : "");
-
- HMAC_Init_ex(hctx, key[i].hmac_key, 16,
- ngx_ssl_session_ticket_md(), NULL);
- EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key[i].aes_key, iv);
-
- return (i == 0) ? 1 : 2 /* renew */;
- }
-}
-
-#else
-
-ngx_int_t
-ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
-{
- if (paths) {
- ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
- "\"ssl_session_ticket_keys\" ignored, not supported");
- }
-
- return NGX_OK;
-}
-
-#endif
-
-
-void
-ngx_ssl_cleanup_ctx(void *data)
-{
- ngx_ssl_t *ssl = data;
-
- SSL_CTX_free(ssl->ctx);
-}
-
-
-ngx_int_t
-ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
-{
- s->data = (u_char *) SSL_get_version(c->ssl->connection);
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
-{
- s->data = (u_char *) SSL_get_cipher_name(c->ssl->connection);
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
-{
- int len;
- u_char *buf;
- SSL_SESSION *sess;
-
- sess = SSL_get0_session(c->ssl->connection);
- if (sess == NULL) {
- s->len = 0;
- return NGX_OK;
- }
-
- buf = sess->session_id;
- len = sess->session_id_length;
-
- s->len = 2 * len;
- s->data = ngx_pnalloc(pool, 2 * len);
- if (s->data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_hex_dump(s->data, buf, len);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
-{
- if (SSL_session_reused(c->ssl->connection)) {
- ngx_str_set(s, "r");
-
- } else {
- ngx_str_set(s, ".");
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
-{
- size_t len;
- BIO *bio;
- X509 *cert;
-
- s->len = 0;
-
- cert = SSL_get_peer_certificate(c->ssl->connection);
- if (cert == NULL) {
- return NGX_OK;
- }
-
- bio = BIO_new(BIO_s_mem());
- if (bio == NULL) {
- ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "BIO_new() failed");
- X509_free(cert);
- return NGX_ERROR;
- }
-
- if (PEM_write_bio_X509(bio, cert) == 0) {
- ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "PEM_write_bio_X509() failed");
- goto failed;
- }
-
- len = BIO_pending(bio);
- s->len = len;
-
- s->data = ngx_pnalloc(pool, len);
- if (s->data == NULL) {
- goto failed;
- }
-
- BIO_read(bio, s->data, len);
-
- BIO_free(bio);
- X509_free(cert);
-
- return NGX_OK;
-
-failed:
-
- BIO_free(bio);
- X509_free(cert);
-
- return NGX_ERROR;
-}
-
-
-ngx_int_t
-ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
-{
- u_char *p;
- size_t len;
- ngx_uint_t i;
- ngx_str_t cert;
-
- if (ngx_ssl_get_raw_certificate(c, pool, &cert) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (cert.len == 0) {
- s->len = 0;
- return NGX_OK;
- }
-
- len = cert.len - 1;
-
- for (i = 0; i < cert.len - 1; i++) {
- if (cert.data[i] == LF) {
- len++;
- }
- }
-
- s->len = len;
- s->data = ngx_pnalloc(pool, len);
- if (s->data == NULL) {
- return NGX_ERROR;
- }
-
- p = s->data;
-
- for (i = 0; i < cert.len - 1; i++) {
- *p++ = cert.data[i];
- if (cert.data[i] == LF) {
- *p++ = '\t';
- }
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
-{
- char *p;
- size_t len;
- X509 *cert;
- X509_NAME *name;
-
- s->len = 0;
-
- cert = SSL_get_peer_certificate(c->ssl->connection);
- if (cert == NULL) {
- return NGX_OK;
- }
-
- name = X509_get_subject_name(cert);
- if (name == NULL) {
- X509_free(cert);
- return NGX_ERROR;
- }
-
- p = X509_NAME_oneline(name, NULL, 0);
-
- for (len = 0; p[len]; len++) { /* void */ }
-
- s->len = len;
- s->data = ngx_pnalloc(pool, len);
- if (s->data == NULL) {
- OPENSSL_free(p);
- X509_free(cert);
- return NGX_ERROR;
- }
-
- ngx_memcpy(s->data, p, len);
-
- OPENSSL_free(p);
- X509_free(cert);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
-{
- char *p;
- size_t len;
- X509 *cert;
- X509_NAME *name;
-
- s->len = 0;
-
- cert = SSL_get_peer_certificate(c->ssl->connection);
- if (cert == NULL) {
- return NGX_OK;
- }
-
- name = X509_get_issuer_name(cert);
- if (name == NULL) {
- X509_free(cert);
- return NGX_ERROR;
- }
-
- p = X509_NAME_oneline(name, NULL, 0);
-
- for (len = 0; p[len]; len++) { /* void */ }
-
- s->len = len;
- s->data = ngx_pnalloc(pool, len);
- if (s->data == NULL) {
- OPENSSL_free(p);
- X509_free(cert);
- return NGX_ERROR;
- }
-
- ngx_memcpy(s->data, p, len);
-
- OPENSSL_free(p);
- X509_free(cert);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
-{
- size_t len;
- X509 *cert;
- BIO *bio;
-
- s->len = 0;
-
- cert = SSL_get_peer_certificate(c->ssl->connection);
- if (cert == NULL) {
- return NGX_OK;
- }
-
- bio = BIO_new(BIO_s_mem());
- if (bio == NULL) {
- X509_free(cert);
- return NGX_ERROR;
- }
-
- i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert));
- len = BIO_pending(bio);
-
- s->len = len;
- s->data = ngx_pnalloc(pool, len);
- if (s->data == NULL) {
- BIO_free(bio);
- X509_free(cert);
- return NGX_ERROR;
- }
-
- BIO_read(bio, s->data, len);
- BIO_free(bio);
- X509_free(cert);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
-{
- X509 *cert;
-
- if (SSL_get_verify_result(c->ssl->connection) != X509_V_OK) {
- ngx_str_set(s, "FAILED");
- return NGX_OK;
- }
-
- cert = SSL_get_peer_certificate(c->ssl->connection);
-
- if (cert) {
- ngx_str_set(s, "SUCCESS");
-
- } else {
- ngx_str_set(s, "NONE");
- }
-
- X509_free(cert);
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_openssl_create_conf(ngx_cycle_t *cycle)
-{
- ngx_openssl_conf_t *oscf;
-
- oscf = ngx_pcalloc(cycle->pool, sizeof(ngx_openssl_conf_t));
- if (oscf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * oscf->engine = 0;
- */
-
- return oscf;
-}
-
-
-static char *
-ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_openssl_conf_t *oscf = conf;
-
- ENGINE *engine;
- ngx_str_t *value;
-
- if (oscf->engine) {
- return "is duplicate";
- }
-
- oscf->engine = 1;
-
- value = cf->args->elts;
-
- engine = ENGINE_by_id((const char *) value[1].data);
-
- if (engine == NULL) {
- ngx_ssl_error(NGX_LOG_WARN, cf->log, 0,
- "ENGINE_by_id(\"%V\") failed", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- if (ENGINE_set_default(engine, ENGINE_METHOD_ALL) == 0) {
- ngx_ssl_error(NGX_LOG_WARN, cf->log, 0,
- "ENGINE_set_default(\"%V\", ENGINE_METHOD_ALL) failed",
- &value[1]);
-
- ENGINE_free(engine);
-
- return NGX_CONF_ERROR;
- }
-
- ENGINE_free(engine);
-
- return NGX_CONF_OK;
-}
-
-
-static void
-ngx_openssl_exit(ngx_cycle_t *cycle)
-{
- EVP_cleanup();
- ENGINE_cleanup();
-}
diff --git a/usr.sbin/nginx/src/event/ngx_event_openssl.h b/usr.sbin/nginx/src/event/ngx_event_openssl.h
deleted file mode 100644
index b7f85001948..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_openssl.h
+++ /dev/null
@@ -1,197 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_EVENT_OPENSSL_H_INCLUDED_
-#define _NGX_EVENT_OPENSSL_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/conf.h>
-#include <openssl/engine.h>
-#include <openssl/evp.h>
-#include <openssl/ocsp.h>
-
-#define NGX_SSL_NAME "OpenSSL"
-
-
-#define ngx_ssl_session_t SSL_SESSION
-#define ngx_ssl_conn_t SSL
-
-
-typedef struct {
- SSL_CTX *ctx;
- ngx_log_t *log;
- size_t buffer_size;
-} ngx_ssl_t;
-
-
-typedef struct {
- ngx_ssl_conn_t *connection;
-
- ngx_int_t last;
- ngx_buf_t *buf;
- size_t buffer_size;
-
- ngx_connection_handler_pt handler;
-
- ngx_event_handler_pt saved_read_handler;
- ngx_event_handler_pt saved_write_handler;
-
- unsigned handshaked:1;
- unsigned renegotiation:1;
- unsigned buffer:1;
- unsigned no_wait_shutdown:1;
- unsigned no_send_shutdown:1;
- unsigned handshake_buffer_set:1;
-} ngx_ssl_connection_t;
-
-
-#define NGX_SSL_NO_SCACHE -2
-#define NGX_SSL_NONE_SCACHE -3
-#define NGX_SSL_NO_BUILTIN_SCACHE -4
-#define NGX_SSL_DFLT_BUILTIN_SCACHE -5
-
-
-#define NGX_SSL_MAX_SESSION_SIZE 4096
-
-typedef struct ngx_ssl_sess_id_s ngx_ssl_sess_id_t;
-
-struct ngx_ssl_sess_id_s {
- ngx_rbtree_node_t node;
- u_char *id;
- size_t len;
- u_char *session;
- ngx_queue_t queue;
- time_t expire;
-#if (NGX_PTR_SIZE == 8)
- void *stub;
- u_char sess_id[32];
-#endif
-};
-
-
-typedef struct {
- ngx_rbtree_t session_rbtree;
- ngx_rbtree_node_t sentinel;
- ngx_queue_t expire_queue;
-} ngx_ssl_session_cache_t;
-
-
-#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
-
-typedef struct {
- u_char name[16];
- u_char aes_key[16];
- u_char hmac_key[16];
-} ngx_ssl_session_ticket_key_t;
-
-#endif
-
-
-#define NGX_SSL_SSLv2 0x0002
-#define NGX_SSL_SSLv3 0x0004
-#define NGX_SSL_TLSv1 0x0008
-#define NGX_SSL_TLSv1_1 0x0010
-#define NGX_SSL_TLSv1_2 0x0020
-
-
-#define NGX_SSL_BUFFER 1
-#define NGX_SSL_CLIENT 2
-
-#define NGX_SSL_BUFSIZE 16384
-
-
-ngx_int_t ngx_ssl_init(ngx_log_t *log);
-ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data);
-ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
- ngx_str_t *cert, ngx_str_t *key);
-ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
- ngx_str_t *cert, ngx_int_t depth);
-ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
- ngx_str_t *cert, ngx_int_t depth);
-ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl);
-ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl,
- ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify);
-ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
- ngx_resolver_t *resolver, ngx_msec_t resolver_timeout);
-RSA *ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export,
- int key_length);
-ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
-ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name);
-ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
- ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout);
-ngx_int_t ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl,
- ngx_array_t *paths);
-ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
-ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c,
- ngx_uint_t flags);
-
-void ngx_ssl_remove_cached_session(SSL_CTX *ssl, ngx_ssl_session_t *sess);
-ngx_int_t ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session);
-#define ngx_ssl_get_session(c) SSL_get1_session(c->ssl->connection)
-#define ngx_ssl_free_session SSL_SESSION_free
-#define ngx_ssl_get_connection(ssl_conn) \
- SSL_get_ex_data(ssl_conn, ngx_ssl_connection_index)
-#define ngx_ssl_get_server_conf(ssl_ctx) \
- SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_server_conf_index)
-
-#define ngx_ssl_verify_error_optional(n) \
- (n == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT \
- || n == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN \
- || n == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY \
- || n == X509_V_ERR_CERT_UNTRUSTED \
- || n == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)
-
-
-ngx_int_t ngx_ssl_get_protocol(ngx_connection_t *c, ngx_pool_t *pool,
- ngx_str_t *s);
-ngx_int_t ngx_ssl_get_cipher_name(ngx_connection_t *c, ngx_pool_t *pool,
- ngx_str_t *s);
-ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool,
- ngx_str_t *s);
-ngx_int_t ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool,
- ngx_str_t *s);
-ngx_int_t ngx_ssl_get_raw_certificate(ngx_connection_t *c, ngx_pool_t *pool,
- ngx_str_t *s);
-ngx_int_t ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool,
- ngx_str_t *s);
-ngx_int_t ngx_ssl_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool,
- ngx_str_t *s);
-ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool,
- ngx_str_t *s);
-ngx_int_t ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool,
- ngx_str_t *s);
-ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool,
- ngx_str_t *s);
-
-
-ngx_int_t ngx_ssl_handshake(ngx_connection_t *c);
-ssize_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size);
-ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size);
-ssize_t ngx_ssl_recv_chain(ngx_connection_t *c, ngx_chain_t *cl);
-ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
-void ngx_ssl_free_buffer(ngx_connection_t *c);
-ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c);
-void ngx_cdecl ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
- char *fmt, ...);
-void ngx_ssl_cleanup_ctx(void *data);
-
-
-extern int ngx_ssl_connection_index;
-extern int ngx_ssl_server_conf_index;
-extern int ngx_ssl_session_cache_index;
-extern int ngx_ssl_session_ticket_keys_index;
-extern int ngx_ssl_certificate_index;
-extern int ngx_ssl_stapling_index;
-
-
-#endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/event/ngx_event_openssl_stapling.c b/usr.sbin/nginx/src/event/ngx_event_openssl_stapling.c
deleted file mode 100644
index 3a3cc7f9e03..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_openssl_stapling.c
+++ /dev/null
@@ -1,1760 +0,0 @@
-
-/*
- * Copyright (C) Maxim Dounin
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_event_connect.h>
-
-
-#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
-
-
-typedef struct {
- ngx_str_t staple;
- ngx_msec_t timeout;
-
- ngx_resolver_t *resolver;
- ngx_msec_t resolver_timeout;
-
- ngx_addr_t *addrs;
- ngx_str_t host;
- ngx_str_t uri;
- in_port_t port;
-
- SSL_CTX *ssl_ctx;
-
- X509 *cert;
- X509 *issuer;
-
- time_t valid;
-
- unsigned verify:1;
- unsigned loading:1;
-} ngx_ssl_stapling_t;
-
-
-typedef struct ngx_ssl_ocsp_ctx_s ngx_ssl_ocsp_ctx_t;
-
-struct ngx_ssl_ocsp_ctx_s {
- X509 *cert;
- X509 *issuer;
-
- ngx_uint_t naddrs;
-
- ngx_addr_t *addrs;
- ngx_str_t host;
- ngx_str_t uri;
- in_port_t port;
-
- ngx_resolver_t *resolver;
- ngx_msec_t resolver_timeout;
-
- ngx_msec_t timeout;
-
- void (*handler)(ngx_ssl_ocsp_ctx_t *r);
- void *data;
-
- ngx_buf_t *request;
- ngx_buf_t *response;
- ngx_peer_connection_t peer;
-
- ngx_int_t (*process)(ngx_ssl_ocsp_ctx_t *r);
-
- ngx_uint_t state;
-
- ngx_uint_t code;
- ngx_uint_t count;
-
- ngx_uint_t done;
-
- u_char *header_name_start;
- u_char *header_name_end;
- u_char *header_start;
- u_char *header_end;
-
- ngx_pool_t *pool;
- ngx_log_t *log;
-};
-
-
-static ngx_int_t ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl,
- ngx_str_t *file);
-static ngx_int_t ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl);
-static ngx_int_t ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl,
- ngx_str_t *responder);
-
-static int ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn,
- void *data);
-static void ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple);
-static void ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx);
-
-static void ngx_ssl_stapling_cleanup(void *data);
-
-static ngx_ssl_ocsp_ctx_t *ngx_ssl_ocsp_start(void);
-static void ngx_ssl_ocsp_done(ngx_ssl_ocsp_ctx_t *ctx);
-static void ngx_ssl_ocsp_request(ngx_ssl_ocsp_ctx_t *ctx);
-static void ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve);
-static void ngx_ssl_ocsp_connect(ngx_ssl_ocsp_ctx_t *ctx);
-static void ngx_ssl_ocsp_write_handler(ngx_event_t *wev);
-static void ngx_ssl_ocsp_read_handler(ngx_event_t *rev);
-static void ngx_ssl_ocsp_dummy_handler(ngx_event_t *ev);
-
-static ngx_int_t ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx);
-static ngx_int_t ngx_ssl_ocsp_process_status_line(ngx_ssl_ocsp_ctx_t *ctx);
-static ngx_int_t ngx_ssl_ocsp_parse_status_line(ngx_ssl_ocsp_ctx_t *ctx);
-static ngx_int_t ngx_ssl_ocsp_process_headers(ngx_ssl_ocsp_ctx_t *ctx);
-static ngx_int_t ngx_ssl_ocsp_parse_header_line(ngx_ssl_ocsp_ctx_t *ctx);
-static ngx_int_t ngx_ssl_ocsp_process_body(ngx_ssl_ocsp_ctx_t *ctx);
-
-static u_char *ngx_ssl_ocsp_log_error(ngx_log_t *log, u_char *buf, size_t len);
-
-
-ngx_int_t
-ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file,
- ngx_str_t *responder, ngx_uint_t verify)
-{
- ngx_int_t rc;
- ngx_pool_cleanup_t *cln;
- ngx_ssl_stapling_t *staple;
-
- staple = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_stapling_t));
- if (staple == NULL) {
- return NGX_ERROR;
- }
-
- cln = ngx_pool_cleanup_add(cf->pool, 0);
- if (cln == NULL) {
- return NGX_ERROR;
- }
-
- cln->handler = ngx_ssl_stapling_cleanup;
- cln->data = staple;
-
- if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_stapling_index, staple)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_CTX_set_ex_data() failed");
- return NGX_ERROR;
- }
-
- staple->ssl_ctx = ssl->ctx;
- staple->timeout = 60000;
- staple->verify = verify;
-
- if (file->len) {
- /* use OCSP response from the file */
-
- if (ngx_ssl_stapling_file(cf, ssl, file) != NGX_OK) {
- return NGX_ERROR;
- }
-
- goto done;
- }
-
- rc = ngx_ssl_stapling_issuer(cf, ssl);
-
- if (rc == NGX_DECLINED) {
- return NGX_OK;
- }
-
- if (rc != NGX_OK) {
- return NGX_ERROR;
- }
-
- rc = ngx_ssl_stapling_responder(cf, ssl, responder);
-
- if (rc == NGX_DECLINED) {
- return NGX_OK;
- }
-
- if (rc != NGX_OK) {
- return NGX_ERROR;
- }
-
-done:
-
- SSL_CTX_set_tlsext_status_cb(ssl->ctx, ngx_ssl_certificate_status_callback);
- SSL_CTX_set_tlsext_status_arg(ssl->ctx, staple);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_ssl_stapling_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
-{
- BIO *bio;
- int len;
- u_char *p, *buf;
- OCSP_RESPONSE *response;
- ngx_ssl_stapling_t *staple;
-
- staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
-
- if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) {
- return NGX_ERROR;
- }
-
- bio = BIO_new_file((char *) file->data, "r");
- if (bio == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "BIO_new_file(\"%s\") failed", file->data);
- return NGX_ERROR;
- }
-
- response = d2i_OCSP_RESPONSE_bio(bio, NULL);
- if (response == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "d2i_OCSP_RESPONSE_bio(\"%s\") failed", file->data);
- BIO_free(bio);
- return NGX_ERROR;
- }
-
- len = i2d_OCSP_RESPONSE(response, NULL);
- if (len <= 0) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "i2d_OCSP_RESPONSE(\"%s\") failed", file->data);
- goto failed;
- }
-
- buf = ngx_alloc(len, ssl->log);
- if (buf == NULL) {
- goto failed;
- }
-
- p = buf;
- len = i2d_OCSP_RESPONSE(response, &p);
- if (len <= 0) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "i2d_OCSP_RESPONSE(\"%s\") failed", file->data);
- ngx_free(buf);
- goto failed;
- }
-
- OCSP_RESPONSE_free(response);
- BIO_free(bio);
-
- staple->staple.data = buf;
- staple->staple.len = len;
-
- return NGX_OK;
-
-failed:
-
- OCSP_RESPONSE_free(response);
- BIO_free(bio);
-
- return NGX_ERROR;
-}
-
-
-static ngx_int_t
-ngx_ssl_stapling_issuer(ngx_conf_t *cf, ngx_ssl_t *ssl)
-{
- int i, n, rc;
- X509 *cert, *issuer;
- X509_STORE *store;
- X509_STORE_CTX *store_ctx;
- STACK_OF(X509) *chain;
- ngx_ssl_stapling_t *staple;
-
- staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
- cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
-
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- SSL_CTX_get_extra_chain_certs(ssl->ctx, &chain);
-#else
- chain = ssl->ctx->extra_certs;
-#endif
-
- n = sk_X509_num(chain);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0,
- "SSL get issuer: %d extra certs", n);
-
- for (i = 0; i < n; i++) {
- issuer = sk_X509_value(chain, i);
- if (X509_check_issued(issuer, cert) == X509_V_OK) {
- CRYPTO_add(&issuer->references, 1, CRYPTO_LOCK_X509);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0,
- "SSL get issuer: found %p in extra certs", issuer);
-
- staple->cert = cert;
- staple->issuer = issuer;
-
- return NGX_OK;
- }
- }
-
- store = SSL_CTX_get_cert_store(ssl->ctx);
- if (store == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_CTX_get_cert_store() failed");
- return NGX_ERROR;
- }
-
- store_ctx = X509_STORE_CTX_new();
- if (store_ctx == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "X509_STORE_CTX_new() failed");
- return NGX_ERROR;
- }
-
- if (X509_STORE_CTX_init(store_ctx, store, NULL, NULL) == 0) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "X509_STORE_CTX_init() failed");
- return NGX_ERROR;
- }
-
- rc = X509_STORE_CTX_get1_issuer(&issuer, store_ctx, cert);
-
- if (rc == -1) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "X509_STORE_CTX_get1_issuer() failed");
- X509_STORE_CTX_free(store_ctx);
- return NGX_ERROR;
- }
-
- if (rc == 0) {
- ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
- "\"ssl_stapling\" ignored, issuer certificate not found");
- X509_STORE_CTX_free(store_ctx);
- return NGX_DECLINED;
- }
-
- X509_STORE_CTX_free(store_ctx);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ssl->log, 0,
- "SSL get issuer: found %p in cert store", issuer);
-
- staple->cert = cert;
- staple->issuer = issuer;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_ssl_stapling_responder(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder)
-{
- ngx_url_t u;
- char *s;
- ngx_ssl_stapling_t *staple;
- STACK_OF(OPENSSL_STRING) *aia;
-
- staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
-
- if (responder->len == 0) {
-
- /* extract OCSP responder URL from certificate */
-
- aia = X509_get1_ocsp(staple->cert);
- if (aia == NULL) {
- ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
- "\"ssl_stapling\" ignored, "
- "no OCSP responder URL in the certificate");
- return NGX_DECLINED;
- }
-
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
- s = sk_OPENSSL_STRING_value(aia, 0);
-#else
- s = sk_value(aia, 0);
-#endif
- if (s == NULL) {
- ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
- "\"ssl_stapling\" ignored, "
- "no OCSP responder URL in the certificate");
- X509_email_free(aia);
- return NGX_DECLINED;
- }
-
- responder->len = ngx_strlen(s);
- responder->data = ngx_palloc(cf->pool, responder->len);
- if (responder->data == NULL) {
- X509_email_free(aia);
- return NGX_ERROR;
- }
-
- ngx_memcpy(responder->data, s, responder->len);
- X509_email_free(aia);
- }
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- u.url = *responder;
- u.default_port = 80;
- u.uri_part = 1;
-
- if (u.url.len > 7
- && ngx_strncasecmp(u.url.data, (u_char *) "http://", 7) == 0)
- {
- u.url.len -= 7;
- u.url.data += 7;
-
- } else {
- ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
- "\"ssl_stapling\" ignored, "
- "invalid URL prefix in OCSP responder \"%V\"", &u.url);
- return NGX_DECLINED;
- }
-
- if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
- if (u.err) {
- ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
- "\"ssl_stapling\" ignored, "
- "%s in OCSP responder \"%V\"", u.err, &u.url);
- return NGX_DECLINED;
- }
-
- return NGX_ERROR;
- }
-
- staple->addrs = u.addrs;
- staple->host = u.host;
- staple->uri = u.uri;
- staple->port = u.port;
-
- if (staple->uri.len == 0) {
- ngx_str_set(&staple->uri, "/");
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
- ngx_resolver_t *resolver, ngx_msec_t resolver_timeout)
-{
- ngx_ssl_stapling_t *staple;
-
- staple = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_stapling_index);
-
- staple->resolver = resolver;
- staple->resolver_timeout = resolver_timeout;
-
- return NGX_OK;
-}
-
-
-static int
-ngx_ssl_certificate_status_callback(ngx_ssl_conn_t *ssl_conn, void *data)
-{
- int rc;
- u_char *p;
- ngx_connection_t *c;
- ngx_ssl_stapling_t *staple;
-
- c = ngx_ssl_get_connection(ssl_conn);
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "SSL certificate status callback");
-
- staple = data;
- rc = SSL_TLSEXT_ERR_NOACK;
-
- if (staple->staple.len) {
- /* we have to copy ocsp response as OpenSSL will free it by itself */
-
- p = OPENSSL_malloc(staple->staple.len);
- if (p == NULL) {
- ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "OPENSSL_malloc() failed");
- return SSL_TLSEXT_ERR_NOACK;
- }
-
- ngx_memcpy(p, staple->staple.data, staple->staple.len);
-
- SSL_set_tlsext_status_ocsp_resp(ssl_conn, p, staple->staple.len);
-
- rc = SSL_TLSEXT_ERR_OK;
- }
-
- ngx_ssl_stapling_update(staple);
-
- return rc;
-}
-
-
-static void
-ngx_ssl_stapling_update(ngx_ssl_stapling_t *staple)
-{
- ngx_ssl_ocsp_ctx_t *ctx;
-
- if (staple->host.len == 0
- || staple->loading || staple->valid >= ngx_time())
- {
- return;
- }
-
- staple->loading = 1;
-
- ctx = ngx_ssl_ocsp_start();
- if (ctx == NULL) {
- return;
- }
-
- ctx->cert = staple->cert;
- ctx->issuer = staple->issuer;
-
- ctx->addrs = staple->addrs;
- ctx->host = staple->host;
- ctx->uri = staple->uri;
- ctx->port = staple->port;
- ctx->timeout = staple->timeout;
-
- ctx->resolver = staple->resolver;
- ctx->resolver_timeout = staple->resolver_timeout;
-
- ctx->handler = ngx_ssl_stapling_ocsp_handler;
- ctx->data = staple;
-
- ngx_ssl_ocsp_request(ctx);
-
- return;
-}
-
-
-static void
-ngx_ssl_stapling_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
-{
-#if OPENSSL_VERSION_NUMBER >= 0x0090707fL
- const
-#endif
- u_char *p;
- int n;
- size_t len;
- ngx_str_t response;
- X509_STORE *store;
- STACK_OF(X509) *chain;
- OCSP_CERTID *id;
- OCSP_RESPONSE *ocsp;
- OCSP_BASICRESP *basic;
- ngx_ssl_stapling_t *staple;
- ASN1_GENERALIZEDTIME *thisupdate, *nextupdate;
-
- staple = ctx->data;
- ocsp = NULL;
- basic = NULL;
- id = NULL;
-
- if (ctx->code != 200) {
- goto error;
- }
-
- /* check the response */
-
- len = ctx->response->last - ctx->response->pos;
- p = ctx->response->pos;
-
- ocsp = d2i_OCSP_RESPONSE(NULL, &p, len);
- if (ocsp == NULL) {
- ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
- "d2i_OCSP_RESPONSE() failed");
- goto error;
- }
-
- n = OCSP_response_status(ocsp);
-
- if (n != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
- ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
- "OCSP response not successful (%d: %s)",
- n, OCSP_response_status_str(n));
- goto error;
- }
-
- basic = OCSP_response_get1_basic(ocsp);
- if (basic == NULL) {
- ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
- "OCSP_response_get1_basic() failed");
- goto error;
- }
-
- store = SSL_CTX_get_cert_store(staple->ssl_ctx);
- if (store == NULL) {
- ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
- "SSL_CTX_get_cert_store() failed");
- goto error;
- }
-
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- SSL_CTX_get_extra_chain_certs(staple->ssl_ctx, &chain);
-#else
- chain = staple->ssl_ctx->extra_certs;
-#endif
-
- if (OCSP_basic_verify(basic, chain, store,
- staple->verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY)
- != 1)
- {
- ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
- "OCSP_basic_verify() failed");
- goto error;
- }
-
- id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer);
- if (id == NULL) {
- ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
- "OCSP_cert_to_id() failed");
- goto error;
- }
-
- if (OCSP_resp_find_status(basic, id, &n, NULL, NULL,
- &thisupdate, &nextupdate)
- != 1)
- {
- ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
- "certificate status not found in the OCSP response");
- goto error;
- }
-
- if (n != V_OCSP_CERTSTATUS_GOOD) {
- ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
- "certificate status \"%s\" in the OCSP response",
- OCSP_cert_status_str(n));
- goto error;
- }
-
- if (OCSP_check_validity(thisupdate, nextupdate, 300, -1) != 1) {
- ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
- "OCSP_check_validity() failed");
- goto error;
- }
-
- OCSP_CERTID_free(id);
- OCSP_BASICRESP_free(basic);
- OCSP_RESPONSE_free(ocsp);
-
- /* copy the response to memory not in ctx->pool */
-
- response.len = len;
- response.data = ngx_alloc(response.len, ctx->log);
-
- if (response.data == NULL) {
- goto done;
- }
-
- ngx_memcpy(response.data, ctx->response->pos, response.len);
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "ssl ocsp response, %s, %uz",
- OCSP_cert_status_str(n), response.len);
-
- if (staple->staple.data) {
- ngx_free(staple->staple.data);
- }
-
- staple->staple = response;
-
-done:
-
- staple->loading = 0;
- staple->valid = ngx_time() + 3600; /* ssl_stapling_valid */
-
- ngx_ssl_ocsp_done(ctx);
- return;
-
-error:
-
- staple->loading = 0;
- staple->valid = ngx_time() + 300; /* ssl_stapling_err_valid */
-
- if (id) {
- OCSP_CERTID_free(id);
- }
-
- if (basic) {
- OCSP_BASICRESP_free(basic);
- }
-
- if (ocsp) {
- OCSP_RESPONSE_free(ocsp);
- }
-
- ngx_ssl_ocsp_done(ctx);
-}
-
-
-static void
-ngx_ssl_stapling_cleanup(void *data)
-{
- ngx_ssl_stapling_t *staple = data;
-
- if (staple->issuer) {
- X509_free(staple->issuer);
- }
-
- if (staple->staple.data) {
- ngx_free(staple->staple.data);
- }
-}
-
-
-static ngx_ssl_ocsp_ctx_t *
-ngx_ssl_ocsp_start(void)
-{
- ngx_log_t *log;
- ngx_pool_t *pool;
- ngx_ssl_ocsp_ctx_t *ctx;
-
- pool = ngx_create_pool(2048, ngx_cycle->log);
- if (pool == NULL) {
- return NULL;
- }
-
- ctx = ngx_pcalloc(pool, sizeof(ngx_ssl_ocsp_ctx_t));
- if (ctx == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
- log = ngx_palloc(pool, sizeof(ngx_log_t));
- if (log == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
- ctx->pool = pool;
-
- *log = *ctx->pool->log;
-
- ctx->pool->log = log;
- ctx->log = log;
-
- log->handler = ngx_ssl_ocsp_log_error;
- log->data = ctx;
- log->action = "requesting certificate status";
-
- return ctx;
-}
-
-
-static void
-ngx_ssl_ocsp_done(ngx_ssl_ocsp_ctx_t *ctx)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "ssl ocsp done");
-
- if (ctx->peer.connection) {
- ngx_close_connection(ctx->peer.connection);
- }
-
- ngx_destroy_pool(ctx->pool);
-}
-
-
-static void
-ngx_ssl_ocsp_error(ngx_ssl_ocsp_ctx_t *ctx)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "ssl ocsp error");
-
- ctx->code = 0;
- ctx->handler(ctx);
-}
-
-
-static void
-ngx_ssl_ocsp_request(ngx_ssl_ocsp_ctx_t *ctx)
-{
- ngx_resolver_ctx_t *resolve, temp;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "ssl ocsp request");
-
- if (ngx_ssl_ocsp_create_request(ctx) != NGX_OK) {
- ngx_ssl_ocsp_error(ctx);
- return;
- }
-
- if (ctx->resolver) {
- /* resolve OCSP responder hostname */
-
- temp.name = ctx->host;
-
- resolve = ngx_resolve_start(ctx->resolver, &temp);
- if (resolve == NULL) {
- ngx_ssl_ocsp_error(ctx);
- return;
- }
-
- if (resolve == NGX_NO_RESOLVER) {
- ngx_log_error(NGX_LOG_WARN, ctx->log, 0,
- "no resolver defined to resolve %V", &ctx->host);
- goto connect;
- }
-
- resolve->name = ctx->host;
- resolve->handler = ngx_ssl_ocsp_resolve_handler;
- resolve->data = ctx;
- resolve->timeout = ctx->resolver_timeout;
-
- if (ngx_resolve_name(resolve) != NGX_OK) {
- ngx_ssl_ocsp_error(ctx);
- return;
- }
-
- return;
- }
-
-connect:
-
- ngx_ssl_ocsp_connect(ctx);
-}
-
-
-static void
-ngx_ssl_ocsp_resolve_handler(ngx_resolver_ctx_t *resolve)
-{
- ngx_ssl_ocsp_ctx_t *ctx = resolve->data;
-
- u_char *p;
- size_t len;
- in_port_t port;
- socklen_t socklen;
- ngx_uint_t i;
- struct sockaddr *sockaddr;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "ssl ocsp resolve handler");
-
- if (resolve->state) {
- ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
- "%V could not be resolved (%i: %s)",
- &resolve->name, resolve->state,
- ngx_resolver_strerror(resolve->state));
- goto failed;
- }
-
-#if (NGX_DEBUG)
- {
- u_char text[NGX_SOCKADDR_STRLEN];
- ngx_str_t addr;
-
- addr.data = text;
-
- for (i = 0; i < resolve->naddrs; i++) {
- addr.len = ngx_sock_ntop(resolve->addrs[i].sockaddr,
- resolve->addrs[i].socklen,
- text, NGX_SOCKADDR_STRLEN, 0);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "name was resolved to %V", &addr);
-
- }
- }
-#endif
-
- ctx->naddrs = resolve->naddrs;
- ctx->addrs = ngx_pcalloc(ctx->pool, ctx->naddrs * sizeof(ngx_addr_t));
-
- if (ctx->addrs == NULL) {
- goto failed;
- }
-
- port = htons(ctx->port);
-
- for (i = 0; i < resolve->naddrs; i++) {
-
- socklen = resolve->addrs[i].socklen;
-
- sockaddr = ngx_palloc(ctx->pool, socklen);
- if (sockaddr == NULL) {
- goto failed;
- }
-
- ngx_memcpy(sockaddr, resolve->addrs[i].sockaddr, socklen);
-
- switch (sockaddr->sa_family) {
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- ((struct sockaddr_in6 *) sockaddr)->sin6_port = port;
- break;
-#endif
- default: /* AF_INET */
- ((struct sockaddr_in *) sockaddr)->sin_port = port;
- }
-
- ctx->addrs[i].sockaddr = sockaddr;
- ctx->addrs[i].socklen = socklen;
-
- p = ngx_pnalloc(ctx->pool, NGX_SOCKADDR_STRLEN);
- if (p == NULL) {
- goto failed;
- }
-
- len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1);
-
- ctx->addrs[i].name.len = len;
- ctx->addrs[i].name.data = p;
- }
-
- ngx_resolve_name_done(resolve);
-
- ngx_ssl_ocsp_connect(ctx);
- return;
-
-failed:
-
- ngx_resolve_name_done(resolve);
- ngx_ssl_ocsp_error(ctx);
-}
-
-
-static void
-ngx_ssl_ocsp_connect(ngx_ssl_ocsp_ctx_t *ctx)
-{
- ngx_int_t rc;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "ssl ocsp connect");
-
- /* TODO: use all ip addresses */
-
- ctx->peer.sockaddr = ctx->addrs[0].sockaddr;
- ctx->peer.socklen = ctx->addrs[0].socklen;
- ctx->peer.name = &ctx->addrs[0].name;
- ctx->peer.get = ngx_event_get_peer;
- ctx->peer.log = ctx->log;
- ctx->peer.log_error = NGX_ERROR_ERR;
-
- rc = ngx_event_connect_peer(&ctx->peer);
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "ssl ocsp connect peer done");
-
- if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) {
- ngx_ssl_ocsp_error(ctx);
- return;
- }
-
- ctx->peer.connection->data = ctx;
- ctx->peer.connection->pool = ctx->pool;
-
- ctx->peer.connection->read->handler = ngx_ssl_ocsp_read_handler;
- ctx->peer.connection->write->handler = ngx_ssl_ocsp_write_handler;
-
- ctx->process = ngx_ssl_ocsp_process_status_line;
-
- ngx_add_timer(ctx->peer.connection->read, ctx->timeout);
- ngx_add_timer(ctx->peer.connection->write, ctx->timeout);
-
- if (rc == NGX_OK) {
- ngx_ssl_ocsp_write_handler(ctx->peer.connection->write);
- return;
- }
-}
-
-
-static void
-ngx_ssl_ocsp_write_handler(ngx_event_t *wev)
-{
- ssize_t n, size;
- ngx_connection_t *c;
- ngx_ssl_ocsp_ctx_t *ctx;
-
- c = wev->data;
- ctx = c->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, wev->log, 0,
- "ssl ocsp write handler");
-
- if (wev->timedout) {
- ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT,
- "OCSP responder timed out");
- ngx_ssl_ocsp_error(ctx);
- return;
- }
-
- size = ctx->request->last - ctx->request->pos;
-
- n = ngx_send(c, ctx->request->pos, size);
-
- if (n == NGX_ERROR) {
- ngx_ssl_ocsp_error(ctx);
- return;
- }
-
- if (n > 0) {
- ctx->request->pos += n;
-
- if (n == size) {
- wev->handler = ngx_ssl_ocsp_dummy_handler;
-
- if (wev->timer_set) {
- ngx_del_timer(wev);
- }
-
- if (ngx_handle_write_event(wev, 0) != NGX_OK) {
- ngx_ssl_ocsp_error(ctx);
- }
-
- return;
- }
- }
-
- if (!wev->timer_set) {
- ngx_add_timer(wev, ctx->timeout);
- }
-}
-
-
-static void
-ngx_ssl_ocsp_read_handler(ngx_event_t *rev)
-{
- ssize_t n, size;
- ngx_int_t rc;
- ngx_ssl_ocsp_ctx_t *ctx;
- ngx_connection_t *c;
-
- c = rev->data;
- ctx = c->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, rev->log, 0,
- "ssl ocsp read handler");
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
- "OCSP responder timed out");
- ngx_ssl_ocsp_error(ctx);
- return;
- }
-
- if (ctx->response == NULL) {
- ctx->response = ngx_create_temp_buf(ctx->pool, 16384);
- if (ctx->response == NULL) {
- ngx_ssl_ocsp_error(ctx);
- return;
- }
- }
-
- for ( ;; ) {
-
- size = ctx->response->end - ctx->response->last;
-
- n = ngx_recv(c, ctx->response->last, size);
-
- if (n > 0) {
- ctx->response->last += n;
-
- rc = ctx->process(ctx);
-
- if (rc == NGX_ERROR) {
- ngx_ssl_ocsp_error(ctx);
- return;
- }
-
- continue;
- }
-
- if (n == NGX_AGAIN) {
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- ngx_ssl_ocsp_error(ctx);
- }
-
- return;
- }
-
- break;
- }
-
- ctx->done = 1;
-
- rc = ctx->process(ctx);
-
- if (rc == NGX_DONE) {
- /* ctx->handler() was called */
- return;
- }
-
- ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
- "OCSP responder prematurely closed connection");
-
- ngx_ssl_ocsp_error(ctx);
-}
-
-
-static void
-ngx_ssl_ocsp_dummy_handler(ngx_event_t *ev)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "ssl ocsp dummy handler");
-}
-
-
-static ngx_int_t
-ngx_ssl_ocsp_create_request(ngx_ssl_ocsp_ctx_t *ctx)
-{
- int len;
- u_char *p;
- uintptr_t escape;
- ngx_str_t binary, base64;
- ngx_buf_t *b;
- OCSP_CERTID *id;
- OCSP_REQUEST *ocsp;
-
- ocsp = OCSP_REQUEST_new();
- if (ocsp == NULL) {
- ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
- "OCSP_REQUEST_new() failed");
- return NGX_ERROR;
- }
-
- id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer);
- if (id == NULL) {
- ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
- "OCSP_cert_to_id() failed");
- goto failed;
- }
-
- if (OCSP_request_add0_id(ocsp, id) == NULL) {
- ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
- "OCSP_request_add0_id() failed");
- goto failed;
- }
-
- len = i2d_OCSP_REQUEST(ocsp, NULL);
- if (len <= 0) {
- ngx_ssl_error(NGX_LOG_CRIT, ctx->log, 0,
- "i2d_OCSP_REQUEST() failed");
- goto failed;
- }
-
- binary.len = len;
- binary.data = ngx_palloc(ctx->pool, len);
- if (binary.data == NULL) {
- goto failed;
- }
-
- p = binary.data;
- len = i2d_OCSP_REQUEST(ocsp, &p);
- if (len <= 0) {
- ngx_ssl_error(NGX_LOG_EMERG, ctx->log, 0,
- "i2d_OCSP_REQUEST() failed");
- goto failed;
- }
-
- base64.len = ngx_base64_encoded_length(binary.len);
- base64.data = ngx_palloc(ctx->pool, base64.len);
- if (base64.data == NULL) {
- goto failed;
- }
-
- ngx_encode_base64(&base64, &binary);
-
- escape = ngx_escape_uri(NULL, base64.data, base64.len,
- NGX_ESCAPE_URI_COMPONENT);
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "ssl ocsp request length %z, escape %d",
- base64.len, escape);
-
- len = sizeof("GET ") - 1 + ctx->uri.len + sizeof("/") - 1
- + base64.len + 2 * escape + sizeof(" HTTP/1.0" CRLF) - 1
- + sizeof("Host: ") - 1 + ctx->host.len + sizeof(CRLF) - 1
- + sizeof(CRLF) - 1;
-
- b = ngx_create_temp_buf(ctx->pool, len);
- if (b == NULL) {
- goto failed;
- }
-
- p = b->last;
-
- p = ngx_cpymem(p, "GET ", sizeof("GET ") - 1);
- p = ngx_cpymem(p, ctx->uri.data, ctx->uri.len);
-
- if (ctx->uri.data[ctx->uri.len - 1] != '/') {
- *p++ = '/';
- }
-
- if (escape == 0) {
- p = ngx_cpymem(p, base64.data, base64.len);
-
- } else {
- p = (u_char *) ngx_escape_uri(p, base64.data, base64.len,
- NGX_ESCAPE_URI_COMPONENT);
- }
-
- p = ngx_cpymem(p, " HTTP/1.0" CRLF, sizeof(" HTTP/1.0" CRLF) - 1);
- p = ngx_cpymem(p, "Host: ", sizeof("Host: ") - 1);
- p = ngx_cpymem(p, ctx->host.data, ctx->host.len);
- *p++ = CR; *p++ = LF;
-
- /* add "\r\n" at the header end */
- *p++ = CR; *p++ = LF;
-
- b->last = p;
- ctx->request = b;
-
- return NGX_OK;
-
-failed:
-
- OCSP_REQUEST_free(ocsp);
-
- return NGX_ERROR;
-}
-
-
-static ngx_int_t
-ngx_ssl_ocsp_process_status_line(ngx_ssl_ocsp_ctx_t *ctx)
-{
- ngx_int_t rc;
-
- rc = ngx_ssl_ocsp_parse_status_line(ctx);
-
- if (rc == NGX_OK) {
-#if 0
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "ssl ocsp status line \"%*s\"",
- ctx->response->pos - ctx->response->start,
- ctx->response->start);
-#endif
-
- ctx->process = ngx_ssl_ocsp_process_headers;
- return ctx->process(ctx);
- }
-
- if (rc == NGX_AGAIN) {
- return NGX_AGAIN;
- }
-
- /* rc == NGX_ERROR */
-
- ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
- "OCSP responder sent invalid response");
-
- return NGX_ERROR;
-}
-
-
-static ngx_int_t
-ngx_ssl_ocsp_parse_status_line(ngx_ssl_ocsp_ctx_t *ctx)
-{
- u_char ch;
- u_char *p;
- ngx_buf_t *b;
- enum {
- sw_start = 0,
- sw_H,
- sw_HT,
- sw_HTT,
- sw_HTTP,
- sw_first_major_digit,
- sw_major_digit,
- sw_first_minor_digit,
- sw_minor_digit,
- sw_status,
- sw_space_after_status,
- sw_status_text,
- sw_almost_done
- } state;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "ssl ocsp process status line");
-
- state = ctx->state;
- b = ctx->response;
-
- for (p = b->pos; p < b->last; p++) {
- ch = *p;
-
- switch (state) {
-
- /* "HTTP/" */
- case sw_start:
- switch (ch) {
- case 'H':
- state = sw_H;
- break;
- default:
- return NGX_ERROR;
- }
- break;
-
- case sw_H:
- switch (ch) {
- case 'T':
- state = sw_HT;
- break;
- default:
- return NGX_ERROR;
- }
- break;
-
- case sw_HT:
- switch (ch) {
- case 'T':
- state = sw_HTT;
- break;
- default:
- return NGX_ERROR;
- }
- break;
-
- case sw_HTT:
- switch (ch) {
- case 'P':
- state = sw_HTTP;
- break;
- default:
- return NGX_ERROR;
- }
- break;
-
- case sw_HTTP:
- switch (ch) {
- case '/':
- state = sw_first_major_digit;
- break;
- default:
- return NGX_ERROR;
- }
- break;
-
- /* the first digit of major HTTP version */
- case sw_first_major_digit:
- if (ch < '1' || ch > '9') {
- return NGX_ERROR;
- }
-
- state = sw_major_digit;
- break;
-
- /* the major HTTP version or dot */
- case sw_major_digit:
- if (ch == '.') {
- state = sw_first_minor_digit;
- break;
- }
-
- if (ch < '0' || ch > '9') {
- return NGX_ERROR;
- }
-
- break;
-
- /* the first digit of minor HTTP version */
- case sw_first_minor_digit:
- if (ch < '0' || ch > '9') {
- return NGX_ERROR;
- }
-
- state = sw_minor_digit;
- break;
-
- /* the minor HTTP version or the end of the request line */
- case sw_minor_digit:
- if (ch == ' ') {
- state = sw_status;
- break;
- }
-
- if (ch < '0' || ch > '9') {
- return NGX_ERROR;
- }
-
- break;
-
- /* HTTP status code */
- case sw_status:
- if (ch == ' ') {
- break;
- }
-
- if (ch < '0' || ch > '9') {
- return NGX_ERROR;
- }
-
- ctx->code = ctx->code * 10 + ch - '0';
-
- if (++ctx->count == 3) {
- state = sw_space_after_status;
- }
-
- break;
-
- /* space or end of line */
- case sw_space_after_status:
- switch (ch) {
- case ' ':
- state = sw_status_text;
- break;
- case '.': /* IIS may send 403.1, 403.2, etc */
- state = sw_status_text;
- break;
- case CR:
- state = sw_almost_done;
- break;
- case LF:
- goto done;
- default:
- return NGX_ERROR;
- }
- break;
-
- /* any text until end of line */
- case sw_status_text:
- switch (ch) {
- case CR:
- state = sw_almost_done;
- break;
- case LF:
- goto done;
- }
- break;
-
- /* end of status line */
- case sw_almost_done:
- switch (ch) {
- case LF:
- goto done;
- default:
- return NGX_ERROR;
- }
- }
- }
-
- b->pos = p;
- ctx->state = state;
-
- return NGX_AGAIN;
-
-done:
-
- b->pos = p + 1;
- ctx->state = sw_start;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_ssl_ocsp_process_headers(ngx_ssl_ocsp_ctx_t *ctx)
-{
- size_t len;
- ngx_int_t rc;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "ssl ocsp process headers");
-
- for ( ;; ) {
- rc = ngx_ssl_ocsp_parse_header_line(ctx);
-
- if (rc == NGX_OK) {
-
- ngx_log_debug4(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "ssl ocsp header \"%*s: %*s\"",
- ctx->header_name_end - ctx->header_name_start,
- ctx->header_name_start,
- ctx->header_end - ctx->header_start,
- ctx->header_start);
-
- len = ctx->header_name_end - ctx->header_name_start;
-
- if (len == sizeof("Content-Type") - 1
- && ngx_strncasecmp(ctx->header_name_start,
- (u_char *) "Content-Type",
- sizeof("Content-Type") - 1)
- == 0)
- {
- len = ctx->header_end - ctx->header_start;
-
- if (len != sizeof("application/ocsp-response") - 1
- || ngx_strncasecmp(ctx->header_start,
- (u_char *) "application/ocsp-response",
- sizeof("application/ocsp-response") - 1)
- != 0)
- {
- ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
- "OCSP responder sent invalid "
- "\"Content-Type\" header: \"%*s\"",
- ctx->header_end - ctx->header_start,
- ctx->header_start);
- return NGX_ERROR;
- }
-
- continue;
- }
-
- /* TODO: honor Content-Length */
-
- continue;
- }
-
- if (rc == NGX_DONE) {
- break;
- }
-
- if (rc == NGX_AGAIN) {
- return NGX_AGAIN;
- }
-
- /* rc == NGX_ERROR */
-
- ngx_log_error(NGX_LOG_ERR, ctx->log, 0,
- "OCSP responder sent invalid response");
-
- return NGX_ERROR;
- }
-
- ctx->process = ngx_ssl_ocsp_process_body;
- return ctx->process(ctx);
-}
-
-static ngx_int_t
-ngx_ssl_ocsp_parse_header_line(ngx_ssl_ocsp_ctx_t *ctx)
-{
- u_char c, ch, *p;
- enum {
- sw_start = 0,
- sw_name,
- sw_space_before_value,
- sw_value,
- sw_space_after_value,
- sw_almost_done,
- sw_header_almost_done
- } state;
-
- state = ctx->state;
-
- for (p = ctx->response->pos; p < ctx->response->last; p++) {
- ch = *p;
-
-#if 0
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "s:%d in:'%02Xd:%c'", state, ch, ch);
-#endif
-
- switch (state) {
-
- /* first char */
- case sw_start:
-
- switch (ch) {
- case CR:
- ctx->header_end = p;
- state = sw_header_almost_done;
- break;
- case LF:
- ctx->header_end = p;
- goto header_done;
- default:
- state = sw_name;
- ctx->header_name_start = p;
-
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'z') {
- break;
- }
-
- if (ch >= '0' && ch <= '9') {
- break;
- }
-
- return NGX_ERROR;
- }
- break;
-
- /* header name */
- case sw_name:
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'z') {
- break;
- }
-
- if (ch == ':') {
- ctx->header_name_end = p;
- state = sw_space_before_value;
- break;
- }
-
- if (ch == '-') {
- break;
- }
-
- if (ch >= '0' && ch <= '9') {
- break;
- }
-
- if (ch == CR) {
- ctx->header_name_end = p;
- ctx->header_start = p;
- ctx->header_end = p;
- state = sw_almost_done;
- break;
- }
-
- if (ch == LF) {
- ctx->header_name_end = p;
- ctx->header_start = p;
- ctx->header_end = p;
- goto done;
- }
-
- return NGX_ERROR;
-
- /* space* before header value */
- case sw_space_before_value:
- switch (ch) {
- case ' ':
- break;
- case CR:
- ctx->header_start = p;
- ctx->header_end = p;
- state = sw_almost_done;
- break;
- case LF:
- ctx->header_start = p;
- ctx->header_end = p;
- goto done;
- default:
- ctx->header_start = p;
- state = sw_value;
- break;
- }
- break;
-
- /* header value */
- case sw_value:
- switch (ch) {
- case ' ':
- ctx->header_end = p;
- state = sw_space_after_value;
- break;
- case CR:
- ctx->header_end = p;
- state = sw_almost_done;
- break;
- case LF:
- ctx->header_end = p;
- goto done;
- }
- break;
-
- /* space* before end of header line */
- case sw_space_after_value:
- switch (ch) {
- case ' ':
- break;
- case CR:
- state = sw_almost_done;
- break;
- case LF:
- goto done;
- default:
- state = sw_value;
- break;
- }
- break;
-
- /* end of header line */
- case sw_almost_done:
- switch (ch) {
- case LF:
- goto done;
- default:
- return NGX_ERROR;
- }
-
- /* end of header */
- case sw_header_almost_done:
- switch (ch) {
- case LF:
- goto header_done;
- default:
- return NGX_ERROR;
- }
- }
- }
-
- ctx->response->pos = p;
- ctx->state = state;
-
- return NGX_AGAIN;
-
-done:
-
- ctx->response->pos = p + 1;
- ctx->state = sw_start;
-
- return NGX_OK;
-
-header_done:
-
- ctx->response->pos = p + 1;
- ctx->state = sw_start;
-
- return NGX_DONE;
-}
-
-
-static ngx_int_t
-ngx_ssl_ocsp_process_body(ngx_ssl_ocsp_ctx_t *ctx)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ctx->log, 0,
- "ssl ocsp process body");
-
- if (ctx->done) {
- ctx->handler(ctx);
- return NGX_DONE;
- }
-
- return NGX_AGAIN;
-}
-
-
-static u_char *
-ngx_ssl_ocsp_log_error(ngx_log_t *log, u_char *buf, size_t len)
-{
- u_char *p;
- ngx_ssl_ocsp_ctx_t *ctx;
-
- p = buf;
-
- if (log->action) {
- p = ngx_snprintf(buf, len, " while %s", log->action);
- len -= p - buf;
- }
-
- ctx = log->data;
-
- if (ctx) {
- p = ngx_snprintf(p, len, ", responder: %V", &ctx->host);
- }
-
- return p;
-}
-
-
-#else
-
-
-ngx_int_t
-ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file,
- ngx_str_t *responder, ngx_uint_t verify)
-{
- ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
- "\"ssl_stapling\" ignored, not supported");
-
- return NGX_OK;
-}
-
-ngx_int_t
-ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
- ngx_resolver_t *resolver, ngx_msec_t resolver_timeout)
-{
- return NGX_OK;
-}
-
-
-#endif
diff --git a/usr.sbin/nginx/src/event/ngx_event_pipe.c b/usr.sbin/nginx/src/event/ngx_event_pipe.c
deleted file mode 100644
index eed807d61b8..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_pipe.c
+++ /dev/null
@@ -1,1011 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_event_pipe.h>
-
-
-static ngx_int_t ngx_event_pipe_read_upstream(ngx_event_pipe_t *p);
-static ngx_int_t ngx_event_pipe_write_to_downstream(ngx_event_pipe_t *p);
-
-static ngx_int_t ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p);
-static ngx_inline void ngx_event_pipe_remove_shadow_links(ngx_buf_t *buf);
-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, ngx_int_t do_write)
-{
- u_int flags;
- ngx_int_t rc;
- ngx_event_t *rev, *wev;
-
- for ( ;; ) {
- if (do_write) {
- p->log->action = "sending to client";
-
- rc = ngx_event_pipe_write_to_downstream(p);
-
- if (rc == NGX_ABORT) {
- return NGX_ABORT;
- }
-
- if (rc == NGX_BUSY) {
- return NGX_OK;
- }
- }
-
- p->read = 0;
- p->upstream_blocked = 0;
-
- p->log->action = "reading upstream";
-
- if (ngx_event_pipe_read_upstream(p) == NGX_ABORT) {
- return NGX_ABORT;
- }
-
- if (!p->read && !p->upstream_blocked) {
- break;
- }
-
- do_write = 1;
- }
-
- if (p->upstream->fd != (ngx_socket_t) -1) {
- rev = p->upstream->read;
-
- flags = (rev->eof || rev->error) ? NGX_CLOSE_EVENT : 0;
-
- if (ngx_handle_read_event(rev, flags) != NGX_OK) {
- return NGX_ABORT;
- }
-
- if (rev->active && !rev->ready) {
- ngx_add_timer(rev, p->read_timeout);
-
- } else if (rev->timer_set) {
- ngx_del_timer(rev);
- }
- }
-
- if (p->downstream->fd != (ngx_socket_t) -1
- && p->downstream->data == p->output_ctx)
- {
- wev = p->downstream->write;
- if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
- return NGX_ABORT;
- }
-
- if (!wev->delayed) {
- if (wev->active && !wev->ready) {
- ngx_add_timer(wev, p->send_timeout);
-
- } else if (wev->timer_set) {
- ngx_del_timer(wev);
- }
- }
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
-{
- ssize_t n, size;
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t *chain, *cl, *ln;
-
- if (p->upstream_eof || p->upstream_error || p->upstream_done) {
- return NGX_OK;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe read upstream: %d", p->upstream->read->ready);
-
- for ( ;; ) {
-
- if (p->upstream_eof || p->upstream_error || p->upstream_done) {
- break;
- }
-
- if (p->preread_bufs == NULL && !p->upstream->read->ready) {
- break;
- }
-
- if (p->preread_bufs) {
-
- /* use the pre-read bufs if they exist */
-
- chain = p->preread_bufs;
- p->preread_bufs = NULL;
- n = p->preread_size;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe preread: %z", n);
-
- if (n) {
- p->read = 1;
- }
-
- } else {
-
-#if (NGX_HAVE_KQUEUE)
-
- /*
- * kqueue notifies about the end of file or a pending error.
- * This test allows not to allocate a buf on these conditions
- * and not to call c->recv_chain().
- */
-
- if (p->upstream->read->available == 0
- && p->upstream->read->pending_eof)
- {
- p->upstream->read->ready = 0;
- p->upstream->read->eof = 1;
- p->upstream_eof = 1;
- p->read = 1;
-
- if (p->upstream->read->kq_errno) {
- p->upstream->read->error = 1;
- p->upstream_error = 1;
- p->upstream_eof = 0;
-
- ngx_log_error(NGX_LOG_ERR, p->log,
- p->upstream->read->kq_errno,
- "kevent() reported that upstream "
- "closed connection");
- }
-
- break;
- }
-#endif
-
- if (p->free_raw_bufs) {
-
- /* use the free bufs if they exist */
-
- chain = p->free_raw_bufs;
- if (p->single_buf) {
- p->free_raw_bufs = p->free_raw_bufs->next;
- chain->next = NULL;
- } else {
- p->free_raw_bufs = NULL;
- }
-
- } else if (p->allocated < p->bufs.num) {
-
- /* allocate a new buf if it's still allowed */
-
- b = ngx_create_temp_buf(p->pool, p->bufs.size);
- if (b == NULL) {
- return NGX_ABORT;
- }
-
- p->allocated++;
-
- chain = ngx_alloc_chain_link(p->pool);
- if (chain == NULL) {
- return NGX_ABORT;
- }
-
- chain->buf = b;
- chain->next = NULL;
-
- } else if (!p->cacheable
- && p->downstream->data == p->output_ctx
- && p->downstream->write->ready
- && !p->downstream->write->delayed)
- {
- /*
- * if the bufs are not needed to be saved in a cache and
- * a downstream is ready then write the bufs to a downstream
- */
-
- p->upstream_blocked = 1;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe downstream ready");
-
- break;
-
- } else if (p->cacheable
- || p->temp_file->offset < p->max_temp_file_size)
- {
-
- /*
- * if it is allowed, then save some bufs from p->in
- * to a temporary file, and add them to a p->out chain
- */
-
- rc = ngx_event_pipe_write_chain_to_temp_file(p);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe temp offset: %O", p->temp_file->offset);
-
- if (rc == NGX_BUSY) {
- break;
- }
-
- if (rc == NGX_AGAIN) {
- if (ngx_event_flags & NGX_USE_LEVEL_EVENT
- && p->upstream->read->active
- && p->upstream->read->ready)
- {
- if (ngx_del_event(p->upstream->read, NGX_READ_EVENT, 0)
- == NGX_ERROR)
- {
- return NGX_ABORT;
- }
- }
- }
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- chain = p->free_raw_bufs;
- if (p->single_buf) {
- p->free_raw_bufs = p->free_raw_bufs->next;
- chain->next = NULL;
- } else {
- p->free_raw_bufs = NULL;
- }
-
- } else {
-
- /* there are no bufs to read in */
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "no pipe bufs to read in");
-
- break;
- }
-
- n = p->upstream->recv_chain(p->upstream, chain);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe recv chain: %z", n);
-
- if (p->free_raw_bufs) {
- chain->next = p->free_raw_bufs;
- }
- p->free_raw_bufs = chain;
-
- if (n == NGX_ERROR) {
- p->upstream_error = 1;
- return NGX_ERROR;
- }
-
- if (n == NGX_AGAIN) {
- if (p->single_buf) {
- ngx_event_pipe_remove_shadow_links(chain->buf);
- }
-
- break;
- }
-
- p->read = 1;
-
- if (n == 0) {
- p->upstream_eof = 1;
- break;
- }
- }
-
- p->read_length += n;
- cl = chain;
- p->free_raw_bufs = NULL;
-
- while (cl && n > 0) {
-
- ngx_event_pipe_remove_shadow_links(cl->buf);
-
- size = cl->buf->end - cl->buf->last;
-
- if (n >= size) {
- cl->buf->last = cl->buf->end;
-
- /* STUB */ cl->buf->num = p->num++;
-
- if (p->input_filter(p, cl->buf) == NGX_ERROR) {
- return NGX_ABORT;
- }
-
- n -= size;
- ln = cl;
- cl = cl->next;
- ngx_free_chain(p->pool, ln);
-
- } else {
- cl->buf->last += n;
- n = 0;
- }
- }
-
- if (cl) {
- for (ln = cl; ln->next; ln = ln->next) { /* void */ }
-
- ln->next = p->free_raw_bufs;
- p->free_raw_bufs = cl;
- }
- }
-
-#if (NGX_DEBUG)
-
- for (cl = p->busy; cl; cl = cl->next) {
- ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe buf busy s:%d t:%d f:%d "
- "%p, pos %p, size: %z "
- "file: %O, size: %z",
- (cl->buf->shadow ? 1 : 0),
- cl->buf->temporary, cl->buf->in_file,
- cl->buf->start, cl->buf->pos,
- cl->buf->last - cl->buf->pos,
- cl->buf->file_pos,
- cl->buf->file_last - cl->buf->file_pos);
- }
-
- for (cl = p->out; cl; cl = cl->next) {
- ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe buf out s:%d t:%d f:%d "
- "%p, pos %p, size: %z "
- "file: %O, size: %z",
- (cl->buf->shadow ? 1 : 0),
- cl->buf->temporary, cl->buf->in_file,
- cl->buf->start, cl->buf->pos,
- cl->buf->last - cl->buf->pos,
- cl->buf->file_pos,
- cl->buf->file_last - cl->buf->file_pos);
- }
-
- for (cl = p->in; cl; cl = cl->next) {
- ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe buf in s:%d t:%d f:%d "
- "%p, pos %p, size: %z "
- "file: %O, size: %z",
- (cl->buf->shadow ? 1 : 0),
- cl->buf->temporary, cl->buf->in_file,
- cl->buf->start, cl->buf->pos,
- cl->buf->last - cl->buf->pos,
- cl->buf->file_pos,
- cl->buf->file_last - cl->buf->file_pos);
- }
-
- for (cl = p->free_raw_bufs; cl; cl = cl->next) {
- ngx_log_debug8(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe buf free s:%d t:%d f:%d "
- "%p, pos %p, size: %z "
- "file: %O, size: %z",
- (cl->buf->shadow ? 1 : 0),
- cl->buf->temporary, cl->buf->in_file,
- cl->buf->start, cl->buf->pos,
- cl->buf->last - cl->buf->pos,
- cl->buf->file_pos,
- cl->buf->file_last - cl->buf->file_pos);
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe length: %O", p->length);
-
-#endif
-
- if (p->free_raw_bufs && p->length != -1) {
- cl = p->free_raw_bufs;
-
- if (cl->buf->last - cl->buf->pos >= p->length) {
-
- p->free_raw_bufs = cl->next;
-
- /* STUB */ cl->buf->num = p->num++;
-
- if (p->input_filter(p, cl->buf) == NGX_ERROR) {
- return NGX_ABORT;
- }
-
- ngx_free_chain(p->pool, cl);
- }
- }
-
- if (p->length == 0) {
- p->upstream_done = 1;
- p->read = 1;
- }
-
- if ((p->upstream_eof || p->upstream_error) && p->free_raw_bufs) {
-
- /* STUB */ p->free_raw_bufs->buf->num = p->num++;
-
- if (p->input_filter(p, p->free_raw_bufs->buf) == NGX_ERROR) {
- return NGX_ABORT;
- }
-
- p->free_raw_bufs = p->free_raw_bufs->next;
-
- if (p->free_bufs && p->buf_to_file == NULL) {
- for (cl = p->free_raw_bufs; cl; cl = cl->next) {
- if (cl->buf->shadow == NULL) {
- ngx_pfree(p->pool, cl->buf->start);
- }
- }
- }
- }
-
- if (p->cacheable && p->in) {
- if (ngx_event_pipe_write_chain_to_temp_file(p) == NGX_ABORT) {
- return NGX_ABORT;
- }
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-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, flushed, prev_last_shadow;
- ngx_chain_t *out, **ll, *cl;
- ngx_connection_t *downstream;
-
- downstream = p->downstream;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe write downstream: %d", downstream->write->ready);
-
- flushed = 0;
-
- for ( ;; ) {
- if (p->downstream_error) {
- return ngx_event_pipe_drain_chains(p);
- }
-
- if (p->upstream_eof || p->upstream_error || p->upstream_done) {
-
- /* pass the p->out and p->in chains to the output filter */
-
- for (cl = p->busy; cl; cl = cl->next) {
- cl->buf->recycled = 0;
- }
-
- if (p->out) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe write downstream flush out");
-
- for (cl = p->out; cl; cl = cl->next) {
- cl->buf->recycled = 0;
- }
-
- rc = p->output_filter(p->output_ctx, p->out);
-
- if (rc == NGX_ERROR) {
- p->downstream_error = 1;
- return ngx_event_pipe_drain_chains(p);
- }
-
- p->out = NULL;
- }
-
- if (p->in) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe write downstream flush in");
-
- for (cl = p->in; cl; cl = cl->next) {
- cl->buf->recycled = 0;
- }
-
- rc = p->output_filter(p->output_ctx, p->in);
-
- if (rc == NGX_ERROR) {
- p->downstream_error = 1;
- return ngx_event_pipe_drain_chains(p);
- }
-
- p->in = NULL;
- }
-
- if (p->cacheable && p->buf_to_file) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe write chain");
-
- if (ngx_event_pipe_write_chain_to_temp_file(p) == NGX_ABORT) {
- return NGX_ABORT;
- }
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe write downstream done");
-
- /* TODO: free unused bufs */
-
- p->downstream_done = 1;
- break;
- }
-
- if (downstream->data != p->output_ctx
- || !downstream->write->ready
- || downstream->write->delayed)
- {
- break;
- }
-
- /* bsize is the size of the busy recycled bufs */
-
- prev = NULL;
- bsize = 0;
-
- for (cl = p->busy; cl; cl = cl->next) {
-
- if (cl->buf->recycled) {
- if (prev == cl->buf->start) {
- continue;
- }
-
- bsize += cl->buf->end - cl->buf->start;
- prev = cl->buf->start;
- }
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe write busy: %uz", bsize);
-
- out = NULL;
-
- if (bsize >= (size_t) p->busy_size) {
- flush = 1;
- goto flush;
- }
-
- flush = 0;
- ll = NULL;
- prev_last_shadow = 1;
-
- for ( ;; ) {
- if (p->out) {
- cl = p->out;
-
- if (cl->buf->recycled) {
- ngx_log_error(NGX_LOG_ALERT, p->log, 0,
- "recycled buffer in pipe out chain");
- }
-
- p->out = p->out->next;
-
- } else if (!p->cacheable && p->in) {
- cl = p->in;
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe write buf ls:%d %p %z",
- cl->buf->last_shadow,
- cl->buf->pos,
- cl->buf->last - cl->buf->pos);
-
- if (cl->buf->recycled && prev_last_shadow) {
- if (bsize + cl->buf->end - cl->buf->start > p->busy_size) {
- flush = 1;
- break;
- }
-
- bsize += cl->buf->end - cl->buf->start;
- }
-
- prev_last_shadow = cl->buf->last_shadow;
-
- p->in = p->in->next;
-
- } else {
- break;
- }
-
- cl->next = NULL;
-
- if (out) {
- *ll = cl;
- } else {
- out = cl;
- }
- ll = &cl->next;
- }
-
- flush:
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe write: out:%p, f:%d", out, flush);
-
- if (out == NULL) {
-
- if (!flush) {
- break;
- }
-
- /* a workaround for AIO */
- if (flushed++ > 10) {
- return NGX_BUSY;
- }
- }
-
- rc = p->output_filter(p->output_ctx, out);
-
- ngx_chain_update_chains(p->pool, &p->free, &p->busy, &out, p->tag);
-
- if (rc == NGX_ERROR) {
- p->downstream_error = 1;
- return ngx_event_pipe_drain_chains(p);
- }
-
- for (cl = p->free; cl; cl = cl->next) {
-
- if (cl->buf->temp_file) {
- if (p->cacheable || !p->cyclic_temp_file) {
- continue;
- }
-
- /* reset p->temp_offset if all bufs had been sent */
-
- if (cl->buf->file_last == p->temp_file->offset) {
- p->temp_file->offset = 0;
- }
- }
-
- /* TODO: free buf if p->free_bufs && upstream done */
-
- /* add the free shadow raw buf to p->free_raw_bufs */
-
- if (cl->buf->last_shadow) {
- if (ngx_event_pipe_add_free_buf(p, cl->buf->shadow) != NGX_OK) {
- return NGX_ABORT;
- }
-
- cl->buf->last_shadow = 0;
- }
-
- cl->buf->shadow = NULL;
- }
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_event_pipe_write_chain_to_temp_file(ngx_event_pipe_t *p)
-{
- ssize_t size, bsize, n;
- ngx_buf_t *b;
- ngx_uint_t prev_last_shadow;
- ngx_chain_t *cl, *tl, *next, *out, **ll, **last_out, **last_free, fl;
-
- if (p->buf_to_file) {
- fl.buf = p->buf_to_file;
- fl.next = p->in;
- out = &fl;
-
- } else {
- out = p->in;
- }
-
- if (!p->cacheable) {
-
- size = 0;
- cl = out;
- ll = NULL;
- prev_last_shadow = 1;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe offset: %O", p->temp_file->offset);
-
- do {
- bsize = cl->buf->last - cl->buf->pos;
-
- ngx_log_debug4(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe buf ls:%d %p, pos %p, size: %z",
- cl->buf->last_shadow, cl->buf->start,
- cl->buf->pos, bsize);
-
- if (prev_last_shadow
- && ((size + bsize > p->temp_file_write_size)
- || (p->temp_file->offset + size + bsize
- > p->max_temp_file_size)))
- {
- break;
- }
-
- prev_last_shadow = cl->buf->last_shadow;
-
- size += bsize;
- ll = &cl->next;
- cl = cl->next;
-
- } while (cl);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "size: %z", size);
-
- if (ll == NULL) {
- return NGX_BUSY;
- }
-
- if (cl) {
- p->in = cl;
- *ll = NULL;
-
- } else {
- p->in = NULL;
- p->last_in = &p->in;
- }
-
- } else {
- p->in = NULL;
- p->last_in = &p->in;
- }
-
- n = ngx_write_chain_to_temp_file(p->temp_file, out);
-
- if (n == NGX_ERROR) {
- return NGX_ABORT;
- }
-
- if (p->buf_to_file) {
- p->temp_file->offset = p->buf_to_file->last - p->buf_to_file->pos;
- n -= p->buf_to_file->last - p->buf_to_file->pos;
- p->buf_to_file = NULL;
- out = out->next;
- }
-
- if (n > 0) {
- /* update previous buffer or add new buffer */
-
- if (p->out) {
- for (cl = p->out; cl->next; cl = cl->next) { /* void */ }
-
- b = cl->buf;
-
- if (b->file_last == p->temp_file->offset) {
- p->temp_file->offset += n;
- b->file_last = p->temp_file->offset;
- goto free;
- }
-
- last_out = &cl->next;
-
- } else {
- last_out = &p->out;
- }
-
- cl = ngx_chain_get_free_buf(p->pool, &p->free);
- if (cl == NULL) {
- return NGX_ABORT;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->tag = p->tag;
-
- b->file = &p->temp_file->file;
- b->file_pos = p->temp_file->offset;
- p->temp_file->offset += n;
- b->file_last = p->temp_file->offset;
-
- b->in_file = 1;
- b->temp_file = 1;
-
- *last_out = cl;
- }
-
-free:
-
- for (last_free = &p->free_raw_bufs;
- *last_free != NULL;
- last_free = &(*last_free)->next)
- {
- /* void */
- }
-
- for (cl = out; cl; cl = next) {
- next = cl->next;
-
- cl->next = p->free;
- p->free = cl;
-
- b = cl->buf;
-
- if (b->last_shadow) {
-
- tl = ngx_alloc_chain_link(p->pool);
- if (tl == NULL) {
- return NGX_ABORT;
- }
-
- tl->buf = b->shadow;
- tl->next = NULL;
-
- *last_free = tl;
- last_free = &tl->next;
-
- b->shadow->pos = b->shadow->start;
- b->shadow->last = b->shadow->start;
-
- ngx_event_pipe_remove_shadow_links(b->shadow);
- }
- }
-
- return NGX_OK;
-}
-
-
-/* the copy input filter */
-
-ngx_int_t
-ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
-{
- ngx_buf_t *b;
- ngx_chain_t *cl;
-
- if (buf->pos == buf->last) {
- return NGX_OK;
- }
-
- cl = ngx_chain_get_free_buf(p->pool, &p->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memcpy(b, buf, sizeof(ngx_buf_t));
- b->shadow = buf;
- b->tag = p->tag;
- b->last_shadow = 1;
- b->recycled = 1;
- buf->shadow = b;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d", b->num);
-
- if (p->in) {
- *p->last_in = cl;
- } else {
- p->in = cl;
- }
- p->last_in = &cl->next;
-
- if (p->length == -1) {
- return NGX_OK;
- }
-
- p->length -= b->last - b->pos;
-
- return NGX_OK;
-}
-
-
-static ngx_inline void
-ngx_event_pipe_remove_shadow_links(ngx_buf_t *buf)
-{
- ngx_buf_t *b, *next;
-
- b = buf->shadow;
-
- if (b == NULL) {
- return;
- }
-
- while (!b->last_shadow) {
- next = b->shadow;
-
- b->temporary = 0;
- b->recycled = 0;
-
- b->shadow = NULL;
- b = next;
- }
-
- b->temporary = 0;
- b->recycled = 0;
- b->last_shadow = 0;
-
- b->shadow = NULL;
-
- buf->shadow = NULL;
-}
-
-
-ngx_int_t
-ngx_event_pipe_add_free_buf(ngx_event_pipe_t *p, ngx_buf_t *b)
-{
- ngx_chain_t *cl;
-
- cl = ngx_alloc_chain_link(p->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- if (p->buf_to_file && b->start == p->buf_to_file->start) {
- b->pos = p->buf_to_file->last;
- b->last = p->buf_to_file->last;
-
- } else {
- b->pos = b->start;
- b->last = b->start;
- }
-
- b->shadow = NULL;
-
- cl->buf = b;
-
- if (p->free_raw_bufs == NULL) {
- p->free_raw_bufs = cl;
- cl->next = NULL;
-
- return NGX_OK;
- }
-
- if (p->free_raw_bufs->buf->pos == p->free_raw_bufs->buf->last) {
-
- /* add the free buf to the list start */
-
- cl->next = p->free_raw_bufs;
- p->free_raw_bufs = cl;
-
- return NGX_OK;
- }
-
- /* the first free buf is partially filled, thus add the free buf after it */
-
- cl->next = p->free_raw_bufs->next;
- p->free_raw_bufs->next = cl;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_event_pipe_drain_chains(ngx_event_pipe_t *p)
-{
- ngx_chain_t *cl, *tl;
-
- for ( ;; ) {
- if (p->busy) {
- cl = p->busy;
- p->busy = NULL;
-
- } else if (p->out) {
- cl = p->out;
- p->out = NULL;
-
- } else if (p->in) {
- cl = p->in;
- p->in = NULL;
-
- } else {
- return NGX_OK;
- }
-
- while (cl) {
- if (cl->buf->last_shadow) {
- if (ngx_event_pipe_add_free_buf(p, cl->buf->shadow) != NGX_OK) {
- return NGX_ABORT;
- }
-
- cl->buf->last_shadow = 0;
- }
-
- cl->buf->shadow = NULL;
- tl = cl->next;
- cl->next = p->free;
- p->free = cl;
- cl = tl;
- }
- }
-}
diff --git a/usr.sbin/nginx/src/event/ngx_event_pipe.h b/usr.sbin/nginx/src/event/ngx_event_pipe.h
deleted file mode 100644
index f24e6d148f5..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_pipe.h
+++ /dev/null
@@ -1,94 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_EVENT_PIPE_H_INCLUDED_
-#define _NGX_EVENT_PIPE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-typedef struct ngx_event_pipe_s ngx_event_pipe_t;
-
-typedef ngx_int_t (*ngx_event_pipe_input_filter_pt)(ngx_event_pipe_t *p,
- ngx_buf_t *buf);
-typedef ngx_int_t (*ngx_event_pipe_output_filter_pt)(void *data,
- ngx_chain_t *chain);
-
-
-struct ngx_event_pipe_s {
- ngx_connection_t *upstream;
- ngx_connection_t *downstream;
-
- ngx_chain_t *free_raw_bufs;
- ngx_chain_t *in;
- ngx_chain_t **last_in;
-
- ngx_chain_t *out;
- ngx_chain_t *free;
- ngx_chain_t *busy;
-
- /*
- * the input filter i.e. that moves HTTP/1.1 chunks
- * from the raw bufs to an incoming chain
- */
-
- ngx_event_pipe_input_filter_pt input_filter;
- void *input_ctx;
-
- ngx_event_pipe_output_filter_pt output_filter;
- void *output_ctx;
-
- unsigned read:1;
- unsigned cacheable:1;
- unsigned single_buf:1;
- unsigned free_bufs:1;
- unsigned upstream_done:1;
- unsigned upstream_error:1;
- unsigned upstream_eof:1;
- unsigned upstream_blocked:1;
- unsigned downstream_done:1;
- unsigned downstream_error:1;
- unsigned cyclic_temp_file:1;
-
- ngx_int_t allocated;
- ngx_bufs_t bufs;
- ngx_buf_tag_t tag;
-
- ssize_t busy_size;
-
- off_t read_length;
- off_t length;
-
- off_t max_temp_file_size;
- ssize_t temp_file_write_size;
-
- ngx_msec_t read_timeout;
- ngx_msec_t send_timeout;
- ssize_t send_lowat;
-
- ngx_pool_t *pool;
- ngx_log_t *log;
-
- ngx_chain_t *preread_bufs;
- size_t preread_size;
- ngx_buf_t *buf_to_file;
-
- ngx_temp_file_t *temp_file;
-
- /* STUB */ int num;
-};
-
-
-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);
-
-
-#endif /* _NGX_EVENT_PIPE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/event/ngx_event_posted.c b/usr.sbin/nginx/src/event/ngx_event_posted.c
deleted file mode 100644
index e548145ed73..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_posted.c
+++ /dev/null
@@ -1,173 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-ngx_thread_volatile ngx_event_t *ngx_posted_accept_events;
-ngx_thread_volatile ngx_event_t *ngx_posted_events;
-
-#if (NGX_THREADS)
-ngx_mutex_t *ngx_posted_events_mutex;
-#endif
-
-
-void
-ngx_event_process_posted(ngx_cycle_t *cycle,
- ngx_thread_volatile ngx_event_t **posted)
-{
- ngx_event_t *ev;
-
- for ( ;; ) {
-
- ev = (ngx_event_t *) *posted;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "posted event %p", ev);
-
- if (ev == NULL) {
- return;
- }
-
- ngx_delete_posted_event(ev);
-
- ev->handler(ev);
- }
-}
-
-
-#if (NGX_THREADS) && !(NGX_WIN32)
-
-void
-ngx_wakeup_worker_thread(ngx_cycle_t *cycle)
-{
- ngx_int_t i;
-#if 0
- ngx_uint_t busy;
- ngx_event_t *ev;
-
- busy = 1;
-
- if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
- return;
- }
-
- for (ev = (ngx_event_t *) ngx_posted_events; ev; ev = ev->next) {
- if (*(ev->lock) == 0) {
- busy = 0;
- break;
- }
- }
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- if (busy) {
- return;
- }
-#endif
-
- for (i = 0; i < ngx_threads_n; i++) {
- if (ngx_threads[i].state == NGX_THREAD_FREE) {
- ngx_cond_signal(ngx_threads[i].cv);
- return;
- }
- }
-}
-
-
-ngx_int_t
-ngx_event_thread_process_posted(ngx_cycle_t *cycle)
-{
- ngx_event_t *ev;
-
- for ( ;; ) {
-
- ev = (ngx_event_t *) ngx_posted_events;
-
- for ( ;; ) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "posted event %p", ev);
-
- if (ev == NULL) {
- return NGX_OK;
- }
-
- if (ngx_trylock(ev->lock) == 0) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "posted event %p is busy", ev);
-
- ev = ev->next;
- continue;
- }
-
- if (ev->lock != ev->own_lock) {
- if (*(ev->own_lock)) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "the own lock of the posted event %p is busy", ev);
- ngx_unlock(ev->lock);
- ev = ev->next;
- continue;
- }
- *(ev->own_lock) = 1;
- }
-
- ngx_delete_posted_event(ev);
-
- ev->locked = 1;
-
- ev->ready |= ev->posted_ready;
- ev->timedout |= ev->posted_timedout;
- ev->pending_eof |= ev->posted_eof;
-#if (NGX_HAVE_KQUEUE)
- ev->kq_errno |= ev->posted_errno;
-#endif
- if (ev->posted_available) {
- ev->available = ev->posted_available;
- }
-
- ev->posted_ready = 0;
- ev->posted_timedout = 0;
- ev->posted_eof = 0;
-#if (NGX_HAVE_KQUEUE)
- ev->posted_errno = 0;
-#endif
- ev->posted_available = 0;
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- ev->handler(ev);
-
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- if (ev->locked) {
- ngx_unlock(ev->lock);
-
- if (ev->lock != ev->own_lock) {
- ngx_unlock(ev->own_lock);
- }
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "posted event %p is done", ev);
-
- break;
- }
- }
-}
-
-#else
-
-void
-ngx_wakeup_worker_thread(ngx_cycle_t *cycle)
-{
-}
-
-#endif
diff --git a/usr.sbin/nginx/src/event/ngx_event_posted.h b/usr.sbin/nginx/src/event/ngx_event_posted.h
deleted file mode 100644
index abd2e261dff..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_posted.h
+++ /dev/null
@@ -1,75 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_EVENT_POSTED_H_INCLUDED_
-#define _NGX_EVENT_POSTED_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#if (NGX_THREADS)
-extern ngx_mutex_t *ngx_posted_events_mutex;
-#endif
-
-
-#define ngx_locked_post_event(ev, queue) \
- \
- if (ev->prev == NULL) { \
- ev->next = (ngx_event_t *) *queue; \
- ev->prev = (ngx_event_t **) queue; \
- *queue = ev; \
- \
- if (ev->next) { \
- ev->next->prev = &ev->next; \
- } \
- \
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "post event %p", ev); \
- \
- } else { \
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, \
- "update posted event %p", ev); \
- }
-
-
-#define ngx_post_event(ev, queue) \
- \
- ngx_mutex_lock(ngx_posted_events_mutex); \
- ngx_locked_post_event(ev, queue); \
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
-
-#define ngx_delete_posted_event(ev) \
- \
- *(ev->prev) = ev->next; \
- \
- if (ev->next) { \
- ev->next->prev = ev->prev; \
- } \
- \
- ev->prev = NULL; \
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, \
- "delete posted event %p", ev);
-
-
-
-void ngx_event_process_posted(ngx_cycle_t *cycle,
- ngx_thread_volatile ngx_event_t **posted);
-void ngx_wakeup_worker_thread(ngx_cycle_t *cycle);
-
-#if (NGX_THREADS)
-ngx_int_t ngx_event_thread_process_posted(ngx_cycle_t *cycle);
-#endif
-
-
-extern ngx_thread_volatile ngx_event_t *ngx_posted_accept_events;
-extern ngx_thread_volatile ngx_event_t *ngx_posted_events;
-
-
-#endif /* _NGX_EVENT_POSTED_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/event/ngx_event_timer.c b/usr.sbin/nginx/src/event/ngx_event_timer.c
deleted file mode 100644
index 177ac1cf113..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_timer.c
+++ /dev/null
@@ -1,158 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#if (NGX_THREADS)
-ngx_mutex_t *ngx_event_timer_mutex;
-#endif
-
-
-ngx_thread_volatile ngx_rbtree_t ngx_event_timer_rbtree;
-static ngx_rbtree_node_t ngx_event_timer_sentinel;
-
-/*
- * the event timer rbtree may contain the duplicate keys, however,
- * it should not be a problem, because we use the rbtree to find
- * a minimum timer value only
- */
-
-ngx_int_t
-ngx_event_timer_init(ngx_log_t *log)
-{
- ngx_rbtree_init(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel,
- ngx_rbtree_insert_timer_value);
-
-#if (NGX_THREADS)
-
- if (ngx_event_timer_mutex) {
- ngx_event_timer_mutex->log = log;
- return NGX_OK;
- }
-
- ngx_event_timer_mutex = ngx_mutex_init(log, 0);
- if (ngx_event_timer_mutex == NULL) {
- return NGX_ERROR;
- }
-
-#endif
-
- return NGX_OK;
-}
-
-
-ngx_msec_t
-ngx_event_find_timer(void)
-{
- ngx_msec_int_t timer;
- ngx_rbtree_node_t *node, *root, *sentinel;
-
- if (ngx_event_timer_rbtree.root == &ngx_event_timer_sentinel) {
- return NGX_TIMER_INFINITE;
- }
-
- ngx_mutex_lock(ngx_event_timer_mutex);
-
- root = ngx_event_timer_rbtree.root;
- sentinel = ngx_event_timer_rbtree.sentinel;
-
- node = ngx_rbtree_min(root, sentinel);
-
- ngx_mutex_unlock(ngx_event_timer_mutex);
-
- timer = (ngx_msec_int_t) (node->key - ngx_current_msec);
-
- return (ngx_msec_t) (timer > 0 ? timer : 0);
-}
-
-
-void
-ngx_event_expire_timers(void)
-{
- ngx_event_t *ev;
- ngx_rbtree_node_t *node, *root, *sentinel;
-
- sentinel = ngx_event_timer_rbtree.sentinel;
-
- for ( ;; ) {
-
- ngx_mutex_lock(ngx_event_timer_mutex);
-
- root = ngx_event_timer_rbtree.root;
-
- if (root == sentinel) {
- return;
- }
-
- node = ngx_rbtree_min(root, sentinel);
-
- /* node->key <= ngx_current_time */
-
- if ((ngx_msec_int_t) (node->key - ngx_current_msec) <= 0) {
- ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer));
-
-#if (NGX_THREADS)
-
- if (ngx_threaded && ngx_trylock(ev->lock) == 0) {
-
- /*
- * We cannot change the timer of the event that is being
- * handled by another thread. And we cannot easy walk
- * the rbtree to find next expired timer so we exit the loop.
- * However, it should be a rare case when the event that is
- * being handled has an expired timer.
- */
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "event %p is busy in expire timers", ev);
- break;
- }
-#endif
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "event timer del: %d: %M",
- ngx_event_ident(ev->data), ev->timer.key);
-
- ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
-
- ngx_mutex_unlock(ngx_event_timer_mutex);
-
-#if (NGX_DEBUG)
- ev->timer.left = NULL;
- ev->timer.right = NULL;
- ev->timer.parent = NULL;
-#endif
-
- ev->timer_set = 0;
-
-#if (NGX_THREADS)
- if (ngx_threaded) {
- ev->posted_timedout = 1;
-
- ngx_post_event(ev, &ngx_posted_events);
-
- ngx_unlock(ev->lock);
-
- continue;
- }
-#endif
-
- ev->timedout = 1;
-
- ev->handler(ev);
-
- continue;
- }
-
- break;
- }
-
- ngx_mutex_unlock(ngx_event_timer_mutex);
-}
diff --git a/usr.sbin/nginx/src/event/ngx_event_timer.h b/usr.sbin/nginx/src/event/ngx_event_timer.h
deleted file mode 100644
index ec9b316bdc8..00000000000
--- a/usr.sbin/nginx/src/event/ngx_event_timer.h
+++ /dev/null
@@ -1,102 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_EVENT_TIMER_H_INCLUDED_
-#define _NGX_EVENT_TIMER_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#define NGX_TIMER_INFINITE (ngx_msec_t) -1
-
-#define NGX_TIMER_LAZY_DELAY 300
-
-
-ngx_int_t ngx_event_timer_init(ngx_log_t *log);
-ngx_msec_t ngx_event_find_timer(void);
-void ngx_event_expire_timers(void);
-
-
-#if (NGX_THREADS)
-extern ngx_mutex_t *ngx_event_timer_mutex;
-#endif
-
-
-extern ngx_thread_volatile ngx_rbtree_t ngx_event_timer_rbtree;
-
-
-static ngx_inline void
-ngx_event_del_timer(ngx_event_t *ev)
-{
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "event timer del: %d: %M",
- ngx_event_ident(ev->data), ev->timer.key);
-
- ngx_mutex_lock(ngx_event_timer_mutex);
-
- ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
-
- ngx_mutex_unlock(ngx_event_timer_mutex);
-
-#if (NGX_DEBUG)
- ev->timer.left = NULL;
- ev->timer.right = NULL;
- ev->timer.parent = NULL;
-#endif
-
- ev->timer_set = 0;
-}
-
-
-static ngx_inline void
-ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
-{
- ngx_msec_t key;
- ngx_msec_int_t diff;
-
- key = ngx_current_msec + timer;
-
- if (ev->timer_set) {
-
- /*
- * Use a previous timer value if difference between it and a new
- * value is less than NGX_TIMER_LAZY_DELAY milliseconds: this allows
- * to minimize the rbtree operations for fast connections.
- */
-
- diff = (ngx_msec_int_t) (key - ev->timer.key);
-
- if (ngx_abs(diff) < NGX_TIMER_LAZY_DELAY) {
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "event timer: %d, old: %M, new: %M",
- ngx_event_ident(ev->data), ev->timer.key, key);
- return;
- }
-
- ngx_del_timer(ev);
- }
-
- ev->timer.key = key;
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "event timer add: %d: %M:%M",
- ngx_event_ident(ev->data), timer, ev->timer.key);
-
- ngx_mutex_lock(ngx_event_timer_mutex);
-
- ngx_rbtree_insert(&ngx_event_timer_rbtree, &ev->timer);
-
- ngx_mutex_unlock(ngx_event_timer_mutex);
-
- ev->timer_set = 1;
-}
-
-
-#endif /* _NGX_EVENT_TIMER_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_access_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_access_module.c
deleted file mode 100644
index c553e46106b..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_access_module.c
+++ /dev/null
@@ -1,469 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- in_addr_t mask;
- in_addr_t addr;
- ngx_uint_t deny; /* unsigned deny:1; */
-} ngx_http_access_rule_t;
-
-#if (NGX_HAVE_INET6)
-
-typedef struct {
- struct in6_addr addr;
- struct in6_addr mask;
- ngx_uint_t deny; /* unsigned deny:1; */
-} ngx_http_access_rule6_t;
-
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-
-typedef struct {
- ngx_uint_t deny; /* unsigned deny:1; */
-} ngx_http_access_rule_un_t;
-
-#endif
-
-typedef struct {
- ngx_array_t *rules; /* array of ngx_http_access_rule_t */
-#if (NGX_HAVE_INET6)
- ngx_array_t *rules6; /* array of ngx_http_access_rule6_t */
-#endif
-#if (NGX_HAVE_UNIX_DOMAIN)
- ngx_array_t *rules_un; /* array of ngx_http_access_rule_un_t */
-#endif
-} ngx_http_access_loc_conf_t;
-
-
-static ngx_int_t ngx_http_access_handler(ngx_http_request_t *r);
-static ngx_int_t ngx_http_access_inet(ngx_http_request_t *r,
- ngx_http_access_loc_conf_t *alcf, in_addr_t addr);
-#if (NGX_HAVE_INET6)
-static ngx_int_t ngx_http_access_inet6(ngx_http_request_t *r,
- ngx_http_access_loc_conf_t *alcf, u_char *p);
-#endif
-#if (NGX_HAVE_UNIX_DOMAIN)
-static ngx_int_t ngx_http_access_unix(ngx_http_request_t *r,
- ngx_http_access_loc_conf_t *alcf);
-#endif
-static ngx_int_t ngx_http_access_found(ngx_http_request_t *r, ngx_uint_t deny);
-static char *ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static void *ngx_http_access_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_access_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static ngx_int_t ngx_http_access_init(ngx_conf_t *cf);
-
-
-static ngx_command_t ngx_http_access_commands[] = {
-
- { ngx_string("allow"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF
- |NGX_CONF_TAKE1,
- ngx_http_access_rule,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("deny"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF
- |NGX_CONF_TAKE1,
- ngx_http_access_rule,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-
-static ngx_http_module_t ngx_http_access_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_access_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_access_create_loc_conf, /* create location configuration */
- ngx_http_access_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_access_module = {
- NGX_MODULE_V1,
- &ngx_http_access_module_ctx, /* module context */
- ngx_http_access_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_access_handler(ngx_http_request_t *r)
-{
- struct sockaddr_in *sin;
- ngx_http_access_loc_conf_t *alcf;
-#if (NGX_HAVE_INET6)
- u_char *p;
- in_addr_t addr;
- struct sockaddr_in6 *sin6;
-#endif
-
- alcf = ngx_http_get_module_loc_conf(r, ngx_http_access_module);
-
- switch (r->connection->sockaddr->sa_family) {
-
- case AF_INET:
- if (alcf->rules) {
- sin = (struct sockaddr_in *) r->connection->sockaddr;
- return ngx_http_access_inet(r, alcf, sin->sin_addr.s_addr);
- }
- break;
-
-#if (NGX_HAVE_INET6)
-
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
- p = sin6->sin6_addr.s6_addr;
-
- if (alcf->rules && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
- addr = p[12] << 24;
- addr += p[13] << 16;
- addr += p[14] << 8;
- addr += p[15];
- return ngx_http_access_inet(r, alcf, htonl(addr));
- }
-
- if (alcf->rules6) {
- return ngx_http_access_inet6(r, alcf, p);
- }
-
- break;
-
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-
- case AF_UNIX:
- if (alcf->rules_un) {
- return ngx_http_access_unix(r, alcf);
- }
-
- break;
-
-#endif
- }
-
- return NGX_DECLINED;
-}
-
-
-static ngx_int_t
-ngx_http_access_inet(ngx_http_request_t *r, ngx_http_access_loc_conf_t *alcf,
- in_addr_t addr)
-{
- ngx_uint_t i;
- ngx_http_access_rule_t *rule;
-
- rule = alcf->rules->elts;
- for (i = 0; i < alcf->rules->nelts; i++) {
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "access: %08XD %08XD %08XD",
- addr, rule[i].mask, rule[i].addr);
-
- if ((addr & rule[i].mask) == rule[i].addr) {
- return ngx_http_access_found(r, rule[i].deny);
- }
- }
-
- return NGX_DECLINED;
-}
-
-
-#if (NGX_HAVE_INET6)
-
-static ngx_int_t
-ngx_http_access_inet6(ngx_http_request_t *r, ngx_http_access_loc_conf_t *alcf,
- u_char *p)
-{
- ngx_uint_t n;
- ngx_uint_t i;
- ngx_http_access_rule6_t *rule6;
-
- rule6 = alcf->rules6->elts;
- for (i = 0; i < alcf->rules6->nelts; i++) {
-
-#if (NGX_DEBUG)
- {
- size_t cl, ml, al;
- u_char ct[NGX_INET6_ADDRSTRLEN];
- u_char mt[NGX_INET6_ADDRSTRLEN];
- u_char at[NGX_INET6_ADDRSTRLEN];
-
- cl = ngx_inet6_ntop(p, ct, NGX_INET6_ADDRSTRLEN);
- ml = ngx_inet6_ntop(rule6[i].mask.s6_addr, mt, NGX_INET6_ADDRSTRLEN);
- al = ngx_inet6_ntop(rule6[i].addr.s6_addr, at, NGX_INET6_ADDRSTRLEN);
-
- ngx_log_debug6(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "access: %*s %*s %*s", cl, ct, ml, mt, al, at);
- }
-#endif
-
- for (n = 0; n < 16; n++) {
- if ((p[n] & rule6[i].mask.s6_addr[n]) != rule6[i].addr.s6_addr[n]) {
- goto next;
- }
- }
-
- return ngx_http_access_found(r, rule6[i].deny);
-
- next:
- continue;
- }
-
- return NGX_DECLINED;
-}
-
-#endif
-
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-
-static ngx_int_t
-ngx_http_access_unix(ngx_http_request_t *r, ngx_http_access_loc_conf_t *alcf)
-{
- ngx_uint_t i;
- ngx_http_access_rule_un_t *rule_un;
-
- rule_un = alcf->rules_un->elts;
- for (i = 0; i < alcf->rules_un->nelts; i++) {
-
- /* TODO: check path */
- if (1) {
- return ngx_http_access_found(r, rule_un[i].deny);
- }
- }
-
- return NGX_DECLINED;
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_access_found(ngx_http_request_t *r, ngx_uint_t deny)
-{
- ngx_http_core_loc_conf_t *clcf;
-
- if (deny) {
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->satisfy == NGX_HTTP_SATISFY_ALL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "access forbidden by rule");
- }
-
- return NGX_HTTP_FORBIDDEN;
- }
-
- return NGX_OK;
-}
-
-
-static char *
-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_uint_t all;
- ngx_str_t *value;
- ngx_cidr_t cidr;
- ngx_http_access_rule_t *rule;
-#if (NGX_HAVE_INET6)
- ngx_http_access_rule6_t *rule6;
-#endif
-#if (NGX_HAVE_UNIX_DOMAIN)
- ngx_http_access_rule_un_t *rule_un;
-#endif
-
- ngx_memzero(&cidr, sizeof(ngx_cidr_t));
-
- value = cf->args->elts;
-
- all = (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0);
-
- if (!all) {
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-
- if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) {
- cidr.family = AF_UNIX;
- rc = NGX_OK;
-
- } else {
- rc = ngx_ptocidr(&value[1], &cidr);
- }
-
-#else
- rc = ngx_ptocidr(&value[1], &cidr);
-#endif
-
- 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]);
- }
- }
-
- if (cidr.family == AF_INET || all) {
-
- if (alcf->rules == NULL) {
- alcf->rules = ngx_array_create(cf->pool, 4,
- sizeof(ngx_http_access_rule_t));
- if (alcf->rules == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- rule = ngx_array_push(alcf->rules);
- if (rule == NULL) {
- return NGX_CONF_ERROR;
- }
-
- rule->mask = cidr.u.in.mask;
- rule->addr = cidr.u.in.addr;
- rule->deny = (value[0].data[0] == 'd') ? 1 : 0;
- }
-
-#if (NGX_HAVE_INET6)
- if (cidr.family == AF_INET6 || all) {
-
- if (alcf->rules6 == NULL) {
- alcf->rules6 = ngx_array_create(cf->pool, 4,
- sizeof(ngx_http_access_rule6_t));
- if (alcf->rules6 == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- rule6 = ngx_array_push(alcf->rules6);
- if (rule6 == NULL) {
- return NGX_CONF_ERROR;
- }
-
- rule6->mask = cidr.u.in6.mask;
- rule6->addr = cidr.u.in6.addr;
- rule6->deny = (value[0].data[0] == 'd') ? 1 : 0;
- }
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- if (cidr.family == AF_UNIX || all) {
-
- if (alcf->rules_un == NULL) {
- alcf->rules_un = ngx_array_create(cf->pool, 1,
- sizeof(ngx_http_access_rule_un_t));
- if (alcf->rules_un == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- rule_un = ngx_array_push(alcf->rules_un);
- if (rule_un == NULL) {
- return NGX_CONF_ERROR;
- }
-
- rule_un->deny = (value[0].data[0] == 'd') ? 1 : 0;
- }
-#endif
-
- return NGX_CONF_OK;
-}
-
-
-static void *
-ngx_http_access_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_access_loc_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_access_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- return conf;
-}
-
-
-static char *
-ngx_http_access_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_access_loc_conf_t *prev = parent;
- ngx_http_access_loc_conf_t *conf = child;
-
- if (conf->rules == NULL
-#if (NGX_HAVE_INET6)
- && conf->rules6 == NULL
-#endif
-#if (NGX_HAVE_UNIX_DOMAIN)
- && conf->rules_un == NULL
-#endif
- ) {
- conf->rules = prev->rules;
-#if (NGX_HAVE_INET6)
- conf->rules6 = prev->rules6;
-#endif
-#if (NGX_HAVE_UNIX_DOMAIN)
- conf->rules_un = prev->rules_un;
-#endif
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_access_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_access_handler;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_addition_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_addition_filter_module.c
deleted file mode 100644
index f598ceab3f7..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_addition_filter_module.c
+++ /dev/null
@@ -1,251 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_str_t before_body;
- ngx_str_t after_body;
-
- ngx_hash_t types;
- ngx_array_t *types_keys;
-} ngx_http_addition_conf_t;
-
-
-typedef struct {
- ngx_uint_t before_body_sent;
-} ngx_http_addition_ctx_t;
-
-
-static void *ngx_http_addition_create_conf(ngx_conf_t *cf);
-static char *ngx_http_addition_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static ngx_int_t ngx_http_addition_filter_init(ngx_conf_t *cf);
-
-
-static ngx_command_t ngx_http_addition_commands[] = {
-
- { ngx_string("add_before_body"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_addition_conf_t, before_body),
- NULL },
-
- { ngx_string("add_after_body"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_addition_conf_t, after_body),
- NULL },
-
- { ngx_string("addition_types"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_types_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_addition_conf_t, types_keys),
- &ngx_http_html_default_types[0] },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_addition_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_addition_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_addition_create_conf, /* create location configuration */
- ngx_http_addition_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_addition_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_addition_filter_module_ctx, /* module context */
- ngx_http_addition_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-
-
-static ngx_int_t
-ngx_http_addition_header_filter(ngx_http_request_t *r)
-{
- ngx_http_addition_ctx_t *ctx;
- ngx_http_addition_conf_t *conf;
-
- if (r->headers_out.status != NGX_HTTP_OK || r != r->main) {
- return ngx_http_next_header_filter(r);
- }
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module);
-
- if (conf->before_body.len == 0 && conf->after_body.len == 0) {
- return ngx_http_next_header_filter(r);
- }
-
- if (ngx_http_test_content_type(r, &conf->types) == NULL) {
- return ngx_http_next_header_filter(r);
- }
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_addition_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_addition_filter_module);
-
- ngx_http_clear_content_length(r);
- ngx_http_clear_accept_ranges(r);
- ngx_http_clear_etag(r);
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_int_t
-ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- ngx_int_t rc;
- ngx_uint_t last;
- ngx_chain_t *cl;
- ngx_http_request_t *sr;
- ngx_http_addition_ctx_t *ctx;
- ngx_http_addition_conf_t *conf;
-
- if (in == NULL || r->header_only) {
- return ngx_http_next_body_filter(r, in);
- }
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_addition_filter_module);
-
- if (ctx == NULL) {
- return ngx_http_next_body_filter(r, in);
- }
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module);
-
- if (!ctx->before_body_sent) {
- ctx->before_body_sent = 1;
-
- if (conf->before_body.len) {
- if (ngx_http_subrequest(r, &conf->before_body, NULL, &sr, NULL, 0)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
- }
- }
-
- if (conf->after_body.len == 0) {
- ngx_http_set_ctx(r, NULL, ngx_http_addition_filter_module);
- return ngx_http_next_body_filter(r, in);
- }
-
- last = 0;
-
- for (cl = in; cl; cl = cl->next) {
- if (cl->buf->last_buf) {
- cl->buf->last_buf = 0;
- cl->buf->sync = 1;
- last = 1;
- }
- }
-
- rc = ngx_http_next_body_filter(r, in);
-
- if (rc == NGX_ERROR || !last || conf->after_body.len == 0) {
- return rc;
- }
-
- if (ngx_http_subrequest(r, &conf->after_body, NULL, &sr, NULL, 0)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, NULL, ngx_http_addition_filter_module);
-
- return ngx_http_send_special(r, NGX_HTTP_LAST);
-}
-
-
-static ngx_int_t
-ngx_http_addition_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_addition_header_filter;
-
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_addition_body_filter;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_addition_create_conf(ngx_conf_t *cf)
-{
- ngx_http_addition_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_addition_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->before_body = { 0, NULL };
- * conf->after_body = { 0, NULL };
- * conf->types = { NULL };
- * conf->types_keys = NULL;
- */
-
- return conf;
-}
-
-
-static char *
-ngx_http_addition_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_addition_conf_t *prev = parent;
- ngx_http_addition_conf_t *conf = child;
-
- ngx_conf_merge_str_value(conf->before_body, prev->before_body, "");
- ngx_conf_merge_str_value(conf->after_body, prev->after_body, "");
-
- if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
- &prev->types_keys, &prev->types,
- ngx_http_html_default_types)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_auth_basic_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_auth_basic_module.c
deleted file mode 100644
index 38892c1063c..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_auth_basic_module.c
+++ /dev/null
@@ -1,471 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-#include <ngx_crypt.h>
-
-
-#define NGX_HTTP_AUTH_BUF_SIZE 2048
-
-
-typedef struct {
- ngx_str_t passwd;
-} ngx_http_auth_basic_ctx_t;
-
-
-typedef struct {
- ngx_http_complex_value_t *realm;
- ngx_http_complex_value_t user_file;
-} ngx_http_auth_basic_loc_conf_t;
-
-
-static ngx_int_t ngx_http_auth_basic_handler(ngx_http_request_t *r);
-static ngx_int_t ngx_http_auth_basic_crypt_handler(ngx_http_request_t *r,
- ngx_http_auth_basic_ctx_t *ctx, ngx_str_t *passwd, ngx_str_t *realm);
-static ngx_int_t ngx_http_auth_basic_set_realm(ngx_http_request_t *r,
- ngx_str_t *realm);
-static void ngx_http_auth_basic_close(ngx_file_t *file);
-static void *ngx_http_auth_basic_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static ngx_int_t ngx_http_auth_basic_init(ngx_conf_t *cf);
-static char *ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_command_t ngx_http_auth_basic_commands[] = {
-
- { ngx_string("auth_basic"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF
- |NGX_CONF_TAKE1,
- ngx_http_set_complex_value_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_auth_basic_loc_conf_t, realm),
- NULL },
-
- { ngx_string("auth_basic_user_file"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF
- |NGX_CONF_TAKE1,
- ngx_http_auth_basic_user_file,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_auth_basic_loc_conf_t, user_file),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_auth_basic_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_auth_basic_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_auth_basic_create_loc_conf, /* create location configuration */
- ngx_http_auth_basic_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_auth_basic_module = {
- NGX_MODULE_V1,
- &ngx_http_auth_basic_module_ctx, /* module context */
- ngx_http_auth_basic_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_auth_basic_handler(ngx_http_request_t *r)
-{
- off_t offset;
- ssize_t n;
- ngx_fd_t fd;
- ngx_int_t rc;
- ngx_err_t err;
- ngx_str_t pwd, realm, user_file;
- ngx_uint_t i, level, login, left, passwd;
- ngx_file_t file;
- ngx_http_auth_basic_ctx_t *ctx;
- ngx_http_auth_basic_loc_conf_t *alcf;
- u_char buf[NGX_HTTP_AUTH_BUF_SIZE];
- enum {
- sw_login,
- sw_passwd,
- sw_skip
- } state;
-
- alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_basic_module);
-
- if (alcf->realm == NULL || alcf->user_file.value.data == NULL) {
- return NGX_DECLINED;
- }
-
- if (ngx_http_complex_value(r, alcf->realm, &realm) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (realm.len == 3 && ngx_strncmp(realm.data, "off", 3) == 0) {
- return NGX_DECLINED;
- }
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_auth_basic_module);
-
- if (ctx) {
- return ngx_http_auth_basic_crypt_handler(r, ctx, &ctx->passwd,
- &realm);
- }
-
- rc = ngx_http_auth_basic_user(r);
-
- if (rc == NGX_DECLINED) {
-
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "no user/password was provided for basic authentication");
-
- return ngx_http_auth_basic_set_realm(r, &realm);
- }
-
- if (rc == NGX_ERROR) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_http_complex_value(r, &alcf->user_file, &user_file) != NGX_OK) {
- return NGX_ERROR;
- }
-
- fd = ngx_open_file(user_file.data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
-
- if (fd == NGX_INVALID_FILE) {
- err = ngx_errno;
-
- if (err == NGX_ENOENT) {
- level = NGX_LOG_ERR;
- rc = NGX_HTTP_FORBIDDEN;
-
- } else {
- level = NGX_LOG_CRIT;
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ngx_log_error(level, r->connection->log, err,
- ngx_open_file_n " \"%s\" failed", user_file.data);
-
- return rc;
- }
-
- ngx_memzero(&file, sizeof(ngx_file_t));
-
- file.fd = fd;
- file.name = user_file;
- file.log = r->connection->log;
-
- state = sw_login;
- passwd = 0;
- login = 0;
- left = 0;
- offset = 0;
-
- for ( ;; ) {
- i = left;
-
- n = ngx_read_file(&file, buf + left, NGX_HTTP_AUTH_BUF_SIZE - left,
- offset);
-
- if (n == NGX_ERROR) {
- ngx_http_auth_basic_close(&file);
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (n == 0) {
- break;
- }
-
- for (i = left; i < left + n; i++) {
- switch (state) {
-
- case sw_login:
- if (login == 0) {
-
- if (buf[i] == '#' || buf[i] == CR) {
- state = sw_skip;
- break;
- }
-
- if (buf[i] == LF) {
- break;
- }
- }
-
- if (buf[i] != r->headers_in.user.data[login]) {
- state = sw_skip;
- break;
- }
-
- if (login == r->headers_in.user.len) {
- state = sw_passwd;
- passwd = i + 1;
- }
-
- login++;
-
- break;
-
- case sw_passwd:
- if (buf[i] == LF || buf[i] == CR || buf[i] == ':') {
- buf[i] = '\0';
-
- ngx_http_auth_basic_close(&file);
-
- pwd.len = i - passwd;
- pwd.data = &buf[passwd];
-
- return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd,
- &realm);
- }
-
- break;
-
- case sw_skip:
- if (buf[i] == LF) {
- state = sw_login;
- login = 0;
- }
-
- break;
- }
- }
-
- if (state == sw_passwd) {
- left = left + n - passwd;
- ngx_memmove(buf, &buf[passwd], left);
- passwd = 0;
-
- } else {
- left = 0;
- }
-
- offset += n;
- }
-
- ngx_http_auth_basic_close(&file);
-
- if (state == sw_passwd) {
- pwd.len = i - passwd;
- pwd.data = ngx_pnalloc(r->pool, pwd.len + 1);
- if (pwd.data == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1);
-
- return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, &realm);
- }
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "user \"%V\" was not found in \"%V\"",
- &r->headers_in.user, &user_file);
-
- return ngx_http_auth_basic_set_realm(r, &realm);
-}
-
-
-static ngx_int_t
-ngx_http_auth_basic_crypt_handler(ngx_http_request_t *r,
- ngx_http_auth_basic_ctx_t *ctx, ngx_str_t *passwd, ngx_str_t *realm)
-{
- ngx_int_t rc;
- u_char *encrypted;
-
- rc = ngx_crypt(r->pool, r->headers_in.passwd.data, passwd->data,
- &encrypted);
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "rc: %d user: \"%V\" salt: \"%s\"",
- rc, &r->headers_in.user, passwd->data);
-
- if (rc == NGX_OK) {
- if (ngx_strcmp(encrypted, passwd->data) == 0) {
- return NGX_OK;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "encrypted: \"%s\"", encrypted);
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "user \"%V\": password mismatch",
- &r->headers_in.user);
-
- return ngx_http_auth_basic_set_realm(r, realm);
- }
-
- if (rc == NGX_ERROR) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- /* rc == NGX_AGAIN */
-
- if (ctx == NULL) {
- ctx = ngx_palloc(r->pool, sizeof(ngx_http_auth_basic_ctx_t));
- if (ctx == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_auth_basic_module);
-
- ctx->passwd.len = passwd->len;
- passwd->len++;
-
- ctx->passwd.data = ngx_pstrdup(r->pool, passwd);
- if (ctx->passwd.data == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- }
-
- /* TODO: add mutex event */
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
-{
- size_t len;
- u_char *basic, *p;
-
- r->headers_out.www_authenticate = ngx_list_push(&r->headers_out.headers);
- if (r->headers_out.www_authenticate == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- len = sizeof("Basic realm=\"\"") - 1 + realm->len;
-
- basic = ngx_pnalloc(r->pool, len);
- if (basic == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- p = ngx_cpymem(basic, "Basic realm=\"", sizeof("Basic realm=\"") - 1);
- p = ngx_cpymem(p, realm->data, realm->len);
- *p = '"';
-
- r->headers_out.www_authenticate->hash = 1;
- ngx_str_set(&r->headers_out.www_authenticate->key, "WWW-Authenticate");
- r->headers_out.www_authenticate->value.data = basic;
- r->headers_out.www_authenticate->value.len = len;
-
- return NGX_HTTP_UNAUTHORIZED;
-}
-
-static void
-ngx_http_auth_basic_close(ngx_file_t *file)
-{
- if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, file->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", file->name.data);
- }
-}
-
-
-static void *
-ngx_http_auth_basic_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_auth_basic_loc_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_auth_basic_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- return conf;
-}
-
-
-static char *
-ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_auth_basic_loc_conf_t *prev = parent;
- ngx_http_auth_basic_loc_conf_t *conf = child;
-
- if (conf->realm == NULL) {
- conf->realm = prev->realm;
- }
-
- if (conf->user_file.value.data == NULL) {
- conf->user_file = prev->user_file;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_auth_basic_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_auth_basic_handler;
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_auth_basic_loc_conf_t *alcf = conf;
-
- ngx_str_t *value;
- ngx_http_compile_complex_value_t ccv;
-
- if (alcf->user_file.value.data) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- if (ngx_chrooted) {
- ngx_strip_chroot(&value[1]);
- }
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &alcf->user_file;
- ccv.zero = 1;
- ccv.conf_prefix = 1;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_auth_request_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_auth_request_module.c
deleted file mode 100644
index b4307be2e7d..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_auth_request_module.c
+++ /dev/null
@@ -1,444 +0,0 @@
-
-/*
- * Copyright (C) Maxim Dounin
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_str_t uri;
- ngx_array_t *vars;
-} ngx_http_auth_request_conf_t;
-
-
-typedef struct {
- ngx_uint_t done;
- ngx_uint_t status;
- ngx_http_request_t *subrequest;
-} ngx_http_auth_request_ctx_t;
-
-
-typedef struct {
- ngx_int_t index;
- ngx_http_complex_value_t value;
- ngx_http_set_variable_pt set_handler;
-} ngx_http_auth_request_variable_t;
-
-
-static ngx_int_t ngx_http_auth_request_handler(ngx_http_request_t *r);
-static ngx_int_t ngx_http_auth_request_done(ngx_http_request_t *r,
- void *data, ngx_int_t rc);
-static ngx_int_t ngx_http_auth_request_set_variables(ngx_http_request_t *r,
- ngx_http_auth_request_conf_t *arcf, ngx_http_auth_request_ctx_t *ctx);
-static ngx_int_t ngx_http_auth_request_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static void *ngx_http_auth_request_create_conf(ngx_conf_t *cf);
-static char *ngx_http_auth_request_merge_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static ngx_int_t ngx_http_auth_request_init(ngx_conf_t *cf);
-static char *ngx_http_auth_request(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_auth_request_set(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_command_t ngx_http_auth_request_commands[] = {
-
- { ngx_string("auth_request"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_auth_request,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("auth_request_set"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_http_auth_request_set,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_auth_request_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_auth_request_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_auth_request_create_conf, /* create location configuration */
- ngx_http_auth_request_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_auth_request_module = {
- NGX_MODULE_V1,
- &ngx_http_auth_request_module_ctx, /* module context */
- ngx_http_auth_request_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_auth_request_handler(ngx_http_request_t *r)
-{
- ngx_table_elt_t *h, *ho;
- ngx_http_request_t *sr;
- ngx_http_post_subrequest_t *ps;
- ngx_http_auth_request_ctx_t *ctx;
- ngx_http_auth_request_conf_t *arcf;
-
- arcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_request_module);
-
- if (arcf->uri.len == 0) {
- return NGX_DECLINED;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "auth request handler");
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_auth_request_module);
-
- if (ctx != NULL) {
- if (!ctx->done) {
- return NGX_AGAIN;
- }
-
- /*
- * as soon as we are done - explicitly set variables to make
- * sure they will be available after internal redirects
- */
-
- if (ngx_http_auth_request_set_variables(r, arcf, ctx) != NGX_OK) {
- return NGX_ERROR;
- }
-
- /* return appropriate status */
-
- if (ctx->status == NGX_HTTP_FORBIDDEN) {
- return ctx->status;
- }
-
- if (ctx->status == NGX_HTTP_UNAUTHORIZED) {
- sr = ctx->subrequest;
-
- h = sr->headers_out.www_authenticate;
-
- if (!h && sr->upstream) {
- h = sr->upstream->headers_in.www_authenticate;
- }
-
- if (h) {
- ho = ngx_list_push(&r->headers_out.headers);
- if (ho == NULL) {
- return NGX_ERROR;
- }
-
- *ho = *h;
-
- r->headers_out.www_authenticate = ho;
- }
-
- return ctx->status;
- }
-
- if (ctx->status >= NGX_HTTP_OK
- && ctx->status < NGX_HTTP_SPECIAL_RESPONSE)
- {
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "auth request unexpected status: %d", ctx->status);
-
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_auth_request_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ps = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
- if (ps == NULL) {
- return NGX_ERROR;
- }
-
- ps->handler = ngx_http_auth_request_done;
- ps->data = ctx;
-
- if (ngx_http_subrequest(r, &arcf->uri, NULL, &sr, ps,
- NGX_HTTP_SUBREQUEST_WAITED)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- /*
- * allocate fake request body to avoid attempts to read it and to make
- * sure real body file (if already read) won't be closed by upstream
- */
-
- sr->request_body = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
- if (sr->request_body == NULL) {
- return NGX_ERROR;
- }
-
- sr->header_only = 1;
-
- ctx->subrequest = sr;
-
- ngx_http_set_ctx(r, ctx, ngx_http_auth_request_module);
-
- return NGX_AGAIN;
-}
-
-
-static ngx_int_t
-ngx_http_auth_request_done(ngx_http_request_t *r, void *data, ngx_int_t rc)
-{
- ngx_http_auth_request_ctx_t *ctx = data;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "auth request done s:%d", r->headers_out.status);
-
- ctx->done = 1;
- ctx->status = r->headers_out.status;
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_auth_request_set_variables(ngx_http_request_t *r,
- ngx_http_auth_request_conf_t *arcf, ngx_http_auth_request_ctx_t *ctx)
-{
- ngx_str_t val;
- ngx_http_variable_t *v;
- ngx_http_variable_value_t *vv;
- ngx_http_auth_request_variable_t *av, *last;
- ngx_http_core_main_conf_t *cmcf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "auth request set variables");
-
- if (arcf->vars == NULL) {
- return NGX_OK;
- }
-
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
- v = cmcf->variables.elts;
-
- av = arcf->vars->elts;
- last = av + arcf->vars->nelts;
-
- while (av < last) {
- /*
- * explicitly set new value to make sure it will be available after
- * internal redirects
- */
-
- vv = &r->variables[av->index];
-
- if (ngx_http_complex_value(ctx->subrequest, &av->value, &val)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- vv->valid = 1;
- vv->not_found = 0;
- vv->data = val.data;
- vv->len = val.len;
-
- if (av->set_handler) {
- /*
- * set_handler only available in cmcf->variables_keys, so we store
- * it explicitly
- */
-
- av->set_handler(r, vv, v[av->index].data);
- }
-
- av++;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_auth_request_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "auth request variable");
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_auth_request_create_conf(ngx_conf_t *cf)
-{
- ngx_http_auth_request_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_auth_request_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->uri = { 0, NULL };
- */
-
- conf->vars = NGX_CONF_UNSET_PTR;
-
- return conf;
-}
-
-
-static char *
-ngx_http_auth_request_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_auth_request_conf_t *prev = parent;
- ngx_http_auth_request_conf_t *conf = child;
-
- ngx_conf_merge_str_value(conf->uri, prev->uri, "");
- ngx_conf_merge_ptr_value(conf->vars, prev->vars, NULL);
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_auth_request_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_auth_request_handler;
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_http_auth_request(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_auth_request_conf_t *arcf = conf;
-
- ngx_str_t *value;
-
- if (arcf->uri.data != NULL) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- arcf->uri.len = 0;
- arcf->uri.data = (u_char *) "";
-
- return NGX_CONF_OK;
- }
-
- arcf->uri = value[1];
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_auth_request_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_auth_request_conf_t *arcf = conf;
-
- ngx_str_t *value;
- ngx_http_variable_t *v;
- ngx_http_auth_request_variable_t *av;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- if (value[1].data[0] != '$') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid variable name \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- value[1].len--;
- value[1].data++;
-
- if (arcf->vars == NGX_CONF_UNSET_PTR) {
- arcf->vars = ngx_array_create(cf->pool, 1,
- sizeof(ngx_http_auth_request_variable_t));
- if (arcf->vars == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- av = ngx_array_push(arcf->vars);
- if (av == NULL) {
- return NGX_CONF_ERROR;
- }
-
- v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE);
- if (v == NULL) {
- return NGX_CONF_ERROR;
- }
-
- av->index = ngx_http_get_variable_index(cf, &value[1]);
- if (av->index == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- if (v->get_handler == NULL) {
- v->get_handler = ngx_http_auth_request_variable;
- v->data = (uintptr_t) av;
- }
-
- av->set_handler = v->set_handler;
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[2];
- ccv.complex_value = &av->value;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_autoindex_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_autoindex_module.c
deleted file mode 100644
index f694df075db..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_autoindex_module.c
+++ /dev/null
@@ -1,705 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-#if 0
-
-typedef struct {
- ngx_buf_t *buf;
- size_t size;
- ngx_pool_t *pool;
- size_t alloc_size;
- ngx_chain_t **last_out;
-} ngx_http_autoindex_ctx_t;
-
-#endif
-
-
-typedef struct {
- ngx_str_t name;
- size_t utf_len;
- size_t escape;
- size_t escape_html;
-
- unsigned dir:1;
-
- time_t mtime;
- off_t size;
-} ngx_http_autoindex_entry_t;
-
-
-typedef struct {
- ngx_flag_t enable;
- ngx_flag_t localtime;
- ngx_flag_t exact_size;
-} ngx_http_autoindex_loc_conf_t;
-
-
-#define NGX_HTTP_AUTOINDEX_PREALLOCATE 50
-
-#define NGX_HTTP_AUTOINDEX_NAME_LEN 50
-
-
-static int ngx_libc_cdecl ngx_http_autoindex_cmp_entries(const void *one,
- const void *two);
-static ngx_int_t ngx_http_autoindex_error(ngx_http_request_t *r,
- ngx_dir_t *dir, ngx_str_t *name);
-static ngx_int_t ngx_http_autoindex_init(ngx_conf_t *cf);
-static void *ngx_http_autoindex_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_autoindex_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
-
-
-static ngx_command_t ngx_http_autoindex_commands[] = {
-
- { ngx_string("autoindex"),
- 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_autoindex_loc_conf_t, enable),
- NULL },
-
- { ngx_string("autoindex_localtime"),
- 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_autoindex_loc_conf_t, localtime),
- NULL },
-
- { ngx_string("autoindex_exact_size"),
- 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_autoindex_loc_conf_t, exact_size),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_autoindex_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_autoindex_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_autoindex_create_loc_conf, /* create location configuration */
- ngx_http_autoindex_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_autoindex_module = {
- NGX_MODULE_V1,
- &ngx_http_autoindex_module_ctx, /* module context */
- ngx_http_autoindex_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static u_char title[] =
-"<html>" CRLF
-"<head><title>Index of "
-;
-
-
-static u_char header[] =
-"</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<h1>Index of "
-;
-
-static u_char tail[] =
-"</body>" CRLF
-"</html>" CRLF
-;
-
-
-static ngx_int_t
-ngx_http_autoindex_handler(ngx_http_request_t *r)
-{
- u_char *last, *filename, scale;
- off_t length;
- size_t len, char_len, escape_html, allocated, root;
- ngx_tm_t tm;
- ngx_err_t err;
- ngx_buf_t *b;
- ngx_int_t rc, size;
- ngx_str_t path;
- ngx_dir_t dir;
- ngx_uint_t i, level, utf8;
- ngx_pool_t *pool;
- ngx_time_t *tp;
- ngx_chain_t out;
- ngx_array_t entries;
- ngx_http_autoindex_entry_t *entry;
- ngx_http_autoindex_loc_conf_t *alcf;
-
- static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
- if (r->uri.data[r->uri.len - 1] != '/') {
- return NGX_DECLINED;
- }
-
- if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
- return NGX_DECLINED;
- }
-
- alcf = ngx_http_get_module_loc_conf(r, ngx_http_autoindex_module);
-
- if (!alcf->enable) {
- return NGX_DECLINED;
- }
-
- /* NGX_DIR_MASK_LEN is lesser than NGX_HTTP_AUTOINDEX_PREALLOCATE */
-
- last = ngx_http_map_uri_to_path(r, &path, &root,
- NGX_HTTP_AUTOINDEX_PREALLOCATE);
- if (last == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- allocated = path.len;
- path.len = last - path.data;
- if (path.len > 1) {
- path.len--;
- }
- path.data[path.len] = '\0';
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http autoindex: \"%s\"", path.data);
-
- if (ngx_open_dir(&path, &dir) == NGX_ERROR) {
- err = ngx_errno;
-
- if (err == NGX_ENOENT
- || err == NGX_ENOTDIR
- || err == NGX_ENAMETOOLONG)
- {
- level = NGX_LOG_ERR;
- rc = NGX_HTTP_NOT_FOUND;
-
- } else if (err == NGX_EACCES) {
- level = NGX_LOG_ERR;
- rc = NGX_HTTP_FORBIDDEN;
-
- } else {
- level = NGX_LOG_CRIT;
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ngx_log_error(level, r->connection->log, err,
- ngx_open_dir_n " \"%s\" failed", path.data);
-
- return rc;
- }
-
-#if (NGX_SUPPRESS_WARN)
-
- /* MSVC thinks 'entries' may be used without having been initialized */
- ngx_memzero(&entries, sizeof(ngx_array_t));
-
-#endif
-
- /* TODO: pool should be temporary pool */
- pool = r->pool;
-
- if (ngx_array_init(&entries, pool, 40, sizeof(ngx_http_autoindex_entry_t))
- != NGX_OK)
- {
- return ngx_http_autoindex_error(r, &dir, &path);
- }
-
- r->headers_out.status = NGX_HTTP_OK;
- r->headers_out.content_type_len = sizeof("text/html") - 1;
- ngx_str_set(&r->headers_out.content_type, "text/html");
- r->headers_out.content_type_lowcase = NULL;
-
- 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;
- }
-
- filename = path.data;
- filename[path.len] = '/';
-
- if (r->headers_out.charset.len == 5
- && ngx_strncasecmp(r->headers_out.charset.data, (u_char *) "utf-8", 5)
- == 0)
- {
- utf8 = 1;
-
- } else {
- utf8 = 0;
- }
-
- for ( ;; ) {
- ngx_set_errno(0);
-
- if (ngx_read_dir(&dir) == NGX_ERROR) {
- err = ngx_errno;
-
- if (err != NGX_ENOMOREFILES) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
- ngx_read_dir_n " \"%V\" failed", &path);
- return ngx_http_autoindex_error(r, &dir, &path);
- }
-
- break;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http autoindex file: \"%s\"", ngx_de_name(&dir));
-
- len = ngx_de_namelen(&dir);
-
- if (ngx_de_name(&dir)[0] == '.') {
- continue;
- }
-
- if (!dir.valid_info) {
-
- /* 1 byte for '/' and 1 byte for terminating '\0' */
-
- if (path.len + 1 + len + 1 > allocated) {
- allocated = path.len + 1 + len + 1
- + NGX_HTTP_AUTOINDEX_PREALLOCATE;
-
- filename = ngx_pnalloc(pool, allocated);
- if (filename == NULL) {
- return ngx_http_autoindex_error(r, &dir, &path);
- }
-
- last = ngx_cpystrn(filename, path.data, path.len + 1);
- *last++ = '/';
- }
-
- ngx_cpystrn(last, ngx_de_name(&dir), len + 1);
-
- if (ngx_de_info(filename, &dir) == NGX_FILE_ERROR) {
- err = ngx_errno;
-
- if (err != NGX_ENOENT && err != NGX_ELOOP) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
- ngx_de_info_n " \"%s\" failed", filename);
-
- if (err == NGX_EACCES) {
- continue;
- }
-
- return ngx_http_autoindex_error(r, &dir, &path);
- }
-
- if (ngx_de_link_info(filename, &dir) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
- ngx_de_link_info_n " \"%s\" failed",
- filename);
- return ngx_http_autoindex_error(r, &dir, &path);
- }
- }
- }
-
- entry = ngx_array_push(&entries);
- if (entry == NULL) {
- return ngx_http_autoindex_error(r, &dir, &path);
- }
-
- entry->name.len = len;
-
- entry->name.data = ngx_pnalloc(pool, len + 1);
- if (entry->name.data == NULL) {
- return ngx_http_autoindex_error(r, &dir, &path);
- }
-
- ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1);
-
- entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len,
- NGX_ESCAPE_URI_COMPONENT);
-
- entry->escape_html = ngx_escape_html(NULL, entry->name.data,
- entry->name.len);
-
- if (utf8) {
- entry->utf_len = ngx_utf8_length(entry->name.data, entry->name.len);
- } else {
- entry->utf_len = len;
- }
-
- entry->dir = ngx_de_is_dir(&dir);
- entry->mtime = ngx_de_mtime(&dir);
- entry->size = ngx_de_size(&dir);
- }
-
- 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);
- }
-
- escape_html = ngx_escape_html(NULL, r->uri.data, r->uri.len);
-
- len = sizeof(title) - 1
- + r->uri.len + escape_html
- + sizeof(header) - 1
- + r->uri.len + escape_html
- + sizeof("</h1>") - 1
- + sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1
- + sizeof("</pre><hr>") - 1
- + sizeof(tail) - 1;
-
- entry = entries.elts;
- for (i = 0; i < entries.nelts; i++) {
- len += sizeof("<a href=\"") - 1
- + entry[i].name.len + entry[i].escape
- + 1 /* 1 is for "/" */
- + sizeof("\">") - 1
- + entry[i].name.len - entry[i].utf_len
- + entry[i].escape_html
- + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof("&gt;") - 2
- + sizeof("</a>") - 1
- + sizeof(" 28-Sep-1970 12:00 ") - 1
- + 20 /* the file size */
- + 2;
- }
-
- b = ngx_create_temp_buf(r->pool, len);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- if (entries.nelts > 1) {
- ngx_qsort(entry, (size_t) entries.nelts,
- sizeof(ngx_http_autoindex_entry_t),
- ngx_http_autoindex_cmp_entries);
- }
-
- b->last = ngx_cpymem(b->last, title, sizeof(title) - 1);
-
- if (escape_html) {
- b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len);
- b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);
- b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len);
-
- } else {
- b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
- b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);
- b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
- }
-
- b->last = ngx_cpymem(b->last, "</h1>", sizeof("</h1>") - 1);
-
- b->last = ngx_cpymem(b->last, "<hr><pre><a href=\"../\">../</a>" CRLF,
- sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1);
-
- tp = ngx_timeofday();
-
- for (i = 0; i < entries.nelts; i++) {
- b->last = ngx_cpymem(b->last, "<a href=\"", sizeof("<a href=\"") - 1);
-
- if (entry[i].escape) {
- ngx_escape_uri(b->last, entry[i].name.data, entry[i].name.len,
- NGX_ESCAPE_URI_COMPONENT);
-
- b->last += entry[i].name.len + entry[i].escape;
-
- } else {
- b->last = ngx_cpymem(b->last, entry[i].name.data,
- entry[i].name.len);
- }
-
- if (entry[i].dir) {
- *b->last++ = '/';
- }
-
- *b->last++ = '"';
- *b->last++ = '>';
-
- len = entry[i].utf_len;
-
- if (entry[i].name.len != len) {
- if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
- char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1;
-
- } else {
- char_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1;
- }
-
- last = b->last;
- b->last = ngx_utf8_cpystrn(b->last, entry[i].name.data,
- char_len, entry[i].name.len + 1);
-
- if (entry[i].escape_html) {
- b->last = (u_char *) ngx_escape_html(last, entry[i].name.data,
- b->last - last);
- }
-
- last = b->last;
-
- } else {
- if (entry[i].escape_html) {
- if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
- char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3;
-
- } else {
- char_len = len;
- }
-
- b->last = (u_char *) ngx_escape_html(b->last,
- entry[i].name.data, char_len);
- last = b->last;
-
- } else {
- b->last = ngx_cpystrn(b->last, entry[i].name.data,
- NGX_HTTP_AUTOINDEX_NAME_LEN + 1);
- last = b->last - 3;
- }
- }
-
- if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
- b->last = ngx_cpymem(last, "..&gt;</a>", sizeof("..&gt;</a>") - 1);
-
- } else {
- if (entry[i].dir && NGX_HTTP_AUTOINDEX_NAME_LEN - len > 0) {
- *b->last++ = '/';
- len++;
- }
-
- b->last = ngx_cpymem(b->last, "</a>", sizeof("</a>") - 1);
-
- if (NGX_HTTP_AUTOINDEX_NAME_LEN - len > 0) {
- ngx_memset(b->last, ' ', NGX_HTTP_AUTOINDEX_NAME_LEN - len);
- b->last += NGX_HTTP_AUTOINDEX_NAME_LEN - len;
- }
- }
-
- *b->last++ = ' ';
-
- ngx_gmtime(entry[i].mtime + tp->gmtoff * 60 * alcf->localtime, &tm);
-
- b->last = ngx_sprintf(b->last, "%02d-%s-%d %02d:%02d ",
- tm.ngx_tm_mday,
- months[tm.ngx_tm_mon - 1],
- tm.ngx_tm_year,
- tm.ngx_tm_hour,
- tm.ngx_tm_min);
-
- if (alcf->exact_size) {
- if (entry[i].dir) {
- b->last = ngx_cpymem(b->last, " -",
- sizeof(" -") - 1);
- } else {
- b->last = ngx_sprintf(b->last, "%19O", entry[i].size);
- }
-
- } else {
- if (entry[i].dir) {
- b->last = ngx_cpymem(b->last, " -",
- sizeof(" -") - 1);
-
- } else {
- length = entry[i].size;
-
- if (length > 1024 * 1024 * 1024 - 1) {
- size = (ngx_int_t) (length / (1024 * 1024 * 1024));
- if ((length % (1024 * 1024 * 1024))
- > (1024 * 1024 * 1024 / 2 - 1))
- {
- size++;
- }
- scale = 'G';
-
- } else if (length > 1024 * 1024 - 1) {
- size = (ngx_int_t) (length / (1024 * 1024));
- if ((length % (1024 * 1024)) > (1024 * 1024 / 2 - 1)) {
- size++;
- }
- scale = 'M';
-
- } else if (length > 9999) {
- size = (ngx_int_t) (length / 1024);
- if (length % 1024 > 511) {
- size++;
- }
- scale = 'K';
-
- } else {
- size = (ngx_int_t) length;
- scale = '\0';
- }
-
- if (scale) {
- b->last = ngx_sprintf(b->last, "%6i%c", size, scale);
-
- } else {
- b->last = ngx_sprintf(b->last, " %6i", size);
- }
- }
- }
-
- *b->last++ = CR;
- *b->last++ = LF;
- }
-
- /* TODO: free temporary pool */
-
- b->last = ngx_cpymem(b->last, "</pre><hr>", sizeof("</pre><hr>") - 1);
-
- b->last = ngx_cpymem(b->last, tail, sizeof(tail) - 1);
-
- if (r == r->main) {
- b->last_buf = 1;
- }
-
- b->last_in_chain = 1;
-
- out.buf = b;
- out.next = NULL;
-
- return ngx_http_output_filter(r, &out);
-}
-
-
-static int ngx_libc_cdecl
-ngx_http_autoindex_cmp_entries(const void *one, const void *two)
-{
- ngx_http_autoindex_entry_t *first = (ngx_http_autoindex_entry_t *) one;
- ngx_http_autoindex_entry_t *second = (ngx_http_autoindex_entry_t *) two;
-
- if (first->dir && !second->dir) {
- /* move the directories to the start */
- return -1;
- }
-
- if (!first->dir && second->dir) {
- /* move the directories to the start */
- return 1;
- }
-
- return (int) ngx_strcmp(first->name.data, second->name.data);
-}
-
-
-#if 0
-
-static ngx_buf_t *
-ngx_http_autoindex_alloc(ngx_http_autoindex_ctx_t *ctx, size_t size)
-{
- ngx_chain_t *cl;
-
- if (ctx->buf) {
-
- if ((size_t) (ctx->buf->end - ctx->buf->last) >= size) {
- return ctx->buf;
- }
-
- ctx->size += ctx->buf->last - ctx->buf->pos;
- }
-
- ctx->buf = ngx_create_temp_buf(ctx->pool, ctx->alloc_size);
- if (ctx->buf == NULL) {
- return NULL;
- }
-
- cl = ngx_alloc_chain_link(ctx->pool);
- if (cl == NULL) {
- return NULL;
- }
-
- cl->buf = ctx->buf;
- cl->next = NULL;
-
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- return ctx->buf;
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_autoindex_error(ngx_http_request_t *r, ngx_dir_t *dir, ngx_str_t *name)
-{
- if (ngx_close_dir(dir) == NGX_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
- ngx_close_dir_n " \"%V\" failed", name);
- }
-
- return r->header_sent ? NGX_ERROR : NGX_HTTP_INTERNAL_SERVER_ERROR;
-}
-
-
-static void *
-ngx_http_autoindex_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_autoindex_loc_conf_t *conf;
-
- conf = ngx_palloc(cf->pool, sizeof(ngx_http_autoindex_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- conf->enable = NGX_CONF_UNSET;
- conf->localtime = NGX_CONF_UNSET;
- conf->exact_size = NGX_CONF_UNSET;
-
- return conf;
-}
-
-
-static char *
-ngx_http_autoindex_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_autoindex_loc_conf_t *prev = parent;
- ngx_http_autoindex_loc_conf_t *conf = child;
-
- ngx_conf_merge_value(conf->enable, prev->enable, 0);
- ngx_conf_merge_value(conf->localtime, prev->localtime, 0);
- ngx_conf_merge_value(conf->exact_size, prev->exact_size, 1);
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_autoindex_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_autoindex_handler;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_browser_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_browser_module.c
deleted file mode 100644
index 80da0d8fa86..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_browser_module.c
+++ /dev/null
@@ -1,715 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-/*
- * The module can check browser versions conforming to the following formats:
- * X, X.X, X.X.X, and X.X.X.X. The maximum values of each format may be
- * 4000, 4000.99, 4000.99.99, and 4000.99.99.99.
- */
-
-
-#define NGX_HTTP_MODERN_BROWSER 0
-#define NGX_HTTP_ANCIENT_BROWSER 1
-
-
-typedef struct {
- u_char browser[12];
- size_t skip;
- size_t add;
- u_char name[12];
-} ngx_http_modern_browser_mask_t;
-
-
-typedef struct {
- ngx_uint_t version;
- size_t skip;
- size_t add;
- u_char name[12];
-} ngx_http_modern_browser_t;
-
-
-typedef struct {
- ngx_str_t name;
- ngx_http_get_variable_pt handler;
- uintptr_t data;
-} ngx_http_browser_variable_t;
-
-
-typedef struct {
- ngx_array_t *modern_browsers;
- ngx_array_t *ancient_browsers;
- ngx_http_variable_value_t *modern_browser_value;
- ngx_http_variable_value_t *ancient_browser_value;
-
- unsigned modern_unlisted_browsers:1;
- unsigned netscape4:1;
-} ngx_http_browser_conf_t;
-
-
-static ngx_int_t ngx_http_msie_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_browser_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-
-static ngx_uint_t ngx_http_browser(ngx_http_request_t *r,
- ngx_http_browser_conf_t *cf);
-
-static ngx_int_t ngx_http_browser_add_variable(ngx_conf_t *cf);
-static void *ngx_http_browser_create_conf(ngx_conf_t *cf);
-static char *ngx_http_browser_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static int ngx_libc_cdecl ngx_http_modern_browser_sort(const void *one,
- const void *two);
-static char *ngx_http_modern_browser(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_ancient_browser(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_modern_browser_value(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_ancient_browser_value(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_command_t ngx_http_browser_commands[] = {
-
- { ngx_string("modern_browser"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
- ngx_http_modern_browser,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("ancient_browser"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_ancient_browser,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("modern_browser_value"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_modern_browser_value,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("ancient_browser_value"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_ancient_browser_value,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_browser_module_ctx = {
- ngx_http_browser_add_variable, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_browser_create_conf, /* create location configuration */
- ngx_http_browser_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_browser_module = {
- NGX_MODULE_V1,
- &ngx_http_browser_module_ctx, /* module context */
- ngx_http_browser_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_modern_browser_mask_t ngx_http_modern_browser_masks[] = {
-
- /* Opera must be the first browser to check */
-
- /*
- * "Opera/7.50 (X11; FreeBSD i386; U) [en]"
- * "Mozilla/5.0 (X11; FreeBSD i386; U) Opera 7.50 [en]"
- * "Mozilla/4.0 (compatible; MSIE 6.0; X11; FreeBSD i386) Opera 7.50 [en]"
- * "Opera/8.0 (Windows NT 5.1; U; ru)"
- * "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; en) Opera 8.0"
- * "Opera/9.01 (X11; FreeBSD 6 i386; U; en)"
- */
-
- { "opera",
- 0,
- sizeof("Opera ") - 1,
- "Opera"},
-
- /* "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)" */
-
- { "msie",
- sizeof("Mozilla/4.0 (compatible; ") - 1,
- sizeof("MSIE ") - 1,
- "MSIE "},
-
- /*
- * "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020610"
- * "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.5) Gecko/20031006"
- * "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.6) Gecko/20040206
- * Firefox/0.8"
- * "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU; rv:1.7.8)
- * Gecko/20050511 Firefox/1.0.4"
- * "Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.8.0.5) Gecko/20060729
- * Firefox/1.5.0.5"
- */
-
- { "gecko",
- sizeof("Mozilla/5.0 (") - 1,
- sizeof("rv:") - 1,
- "rv:"},
-
- /*
- * "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; ru-ru) AppleWebKit/125.2
- * (KHTML, like Gecko) Safari/125.7"
- * "Mozilla/5.0 (SymbianOS/9.1; U; en-us) AppleWebKit/413
- * (KHTML, like Gecko) Safari/413"
- * "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/418
- * (KHTML, like Gecko) Safari/417.9.3"
- * "Mozilla/5.0 (Macintosh; U; PPC Mac OS X; ru-ru) AppleWebKit/418.8
- * (KHTML, like Gecko) Safari/419.3"
- */
-
- { "safari",
- sizeof("Mozilla/5.0 (") - 1,
- sizeof("Safari/") - 1,
- "Safari/"},
-
- /*
- * "Mozilla/5.0 (compatible; Konqueror/3.1; Linux)"
- * "Mozilla/5.0 (compatible; Konqueror/3.4; Linux) KHTML/3.4.2 (like Gecko)"
- * "Mozilla/5.0 (compatible; Konqueror/3.5; FreeBSD) KHTML/3.5.1
- * (like Gecko)"
- */
-
- { "konqueror",
- sizeof("Mozilla/5.0 (compatible; ") - 1,
- sizeof("Konqueror/") - 1,
- "Konqueror/"},
-
- { "", 0, 0, "" }
-
-};
-
-
-static ngx_http_browser_variable_t ngx_http_browsers[] = {
- { ngx_string("msie"), ngx_http_msie_variable, 0 },
- { ngx_string("modern_browser"), ngx_http_browser_variable,
- NGX_HTTP_MODERN_BROWSER },
- { ngx_string("ancient_browser"), ngx_http_browser_variable,
- NGX_HTTP_ANCIENT_BROWSER },
- { ngx_null_string, NULL, 0 }
-};
-
-
-static ngx_int_t
-ngx_http_browser_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- ngx_uint_t rc;
- ngx_http_browser_conf_t *cf;
-
- cf = ngx_http_get_module_loc_conf(r, ngx_http_browser_module);
-
- rc = ngx_http_browser(r, cf);
-
- if (data == NGX_HTTP_MODERN_BROWSER && rc == NGX_HTTP_MODERN_BROWSER) {
- *v = *cf->modern_browser_value;
- return NGX_OK;
- }
-
- if (data == NGX_HTTP_ANCIENT_BROWSER && rc == NGX_HTTP_ANCIENT_BROWSER) {
- *v = *cf->ancient_browser_value;
- return NGX_OK;
- }
-
- *v = ngx_http_variable_null_value;
- return NGX_OK;
-}
-
-
-static ngx_uint_t
-ngx_http_browser(ngx_http_request_t *r, ngx_http_browser_conf_t *cf)
-{
- size_t len;
- u_char *name, *ua, *last, c;
- ngx_str_t *ancient;
- ngx_uint_t i, version, ver, scale;
- ngx_http_modern_browser_t *modern;
-
- if (r->headers_in.user_agent == NULL) {
- if (cf->modern_unlisted_browsers) {
- return NGX_HTTP_MODERN_BROWSER;
- }
-
- return NGX_HTTP_ANCIENT_BROWSER;
- }
-
- ua = r->headers_in.user_agent->value.data;
- len = r->headers_in.user_agent->value.len;
- last = ua + len;
-
- if (cf->modern_browsers) {
- modern = cf->modern_browsers->elts;
-
- for (i = 0; i < cf->modern_browsers->nelts; i++) {
- name = ua + modern[i].skip;
-
- if (name >= last) {
- continue;
- }
-
- name = (u_char *) ngx_strstr(name, modern[i].name);
-
- if (name == NULL) {
- continue;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "browser: \"%s\"", name);
-
- name += modern[i].add;
-
- if (name >= last) {
- continue;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "version: \"%ui\" \"%s\"", modern[i].version, name);
-
- version = 0;
- ver = 0;
- scale = 1000000;
-
- while (name < last) {
-
- c = *name++;
-
- if (c >= '0' && c <= '9') {
- ver = ver * 10 + (c - '0');
- continue;
- }
-
- if (c == '.') {
- version += ver * scale;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "version: \"%ui\" \"%ui\"",
- modern[i].version, version);
-
- if (version > modern[i].version) {
- return NGX_HTTP_MODERN_BROWSER;
- }
-
- ver = 0;
- scale /= 100;
- continue;
- }
-
- break;
- }
-
- version += ver * scale;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "version: \"%ui\" \"%ui\"",
- modern[i].version, version);
-
- if (version >= modern[i].version) {
- return NGX_HTTP_MODERN_BROWSER;
- }
-
- return NGX_HTTP_ANCIENT_BROWSER;
- }
-
- if (!cf->modern_unlisted_browsers) {
- return NGX_HTTP_ANCIENT_BROWSER;
- }
- }
-
- if (cf->netscape4) {
- if (len > sizeof("Mozilla/4.72 ") - 1
- && ngx_strncmp(ua, "Mozilla/", sizeof("Mozilla/") - 1) == 0
- && ua[8] > '0' && ua[8] < '5')
- {
- return NGX_HTTP_ANCIENT_BROWSER;
- }
- }
-
- if (cf->ancient_browsers) {
- ancient = cf->ancient_browsers->elts;
-
- for (i = 0; i < cf->ancient_browsers->nelts; i++) {
- if (len >= ancient[i].len
- && ngx_strstr(ua, ancient[i].data) != NULL)
- {
- return NGX_HTTP_ANCIENT_BROWSER;
- }
- }
- }
-
- if (cf->modern_unlisted_browsers) {
- return NGX_HTTP_MODERN_BROWSER;
- }
-
- return NGX_HTTP_ANCIENT_BROWSER;
-}
-
-
-static ngx_int_t
-ngx_http_msie_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- if (r->headers_in.msie) {
- *v = ngx_http_variable_true_value;
- return NGX_OK;
- }
-
- *v = ngx_http_variable_null_value;
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_browser_add_variable(ngx_conf_t *cf)
-{
- ngx_http_browser_variable_t *var;
- ngx_http_variable_t *v;
-
- for (var = ngx_http_browsers; var->name.len; var++) {
-
- v = ngx_http_add_variable(cf, &var->name, NGX_HTTP_VAR_CHANGEABLE);
- if (v == NULL) {
- return NGX_ERROR;
- }
-
- v->get_handler = var->handler;
- v->data = var->data;
- }
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_browser_create_conf(ngx_conf_t *cf)
-{
- ngx_http_browser_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_browser_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->modern_browsers = NULL;
- * conf->ancient_browsers = NULL;
- * conf->modern_browser_value = NULL;
- * conf->ancient_browser_value = NULL;
- *
- * conf->modern_unlisted_browsers = 0;
- * conf->netscape4 = 0;
- */
-
- return conf;
-}
-
-
-static char *
-ngx_http_browser_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_browser_conf_t *prev = parent;
- ngx_http_browser_conf_t *conf = child;
-
- ngx_uint_t i, n;
- ngx_http_modern_browser_t *browsers, *opera;
-
- /*
- * At the merge the skip field is used to store the browser slot,
- * it will be used in sorting and then will overwritten
- * with a real skip value. The zero value means Opera.
- */
-
- if (conf->modern_browsers == NULL && conf->modern_unlisted_browsers == 0) {
- conf->modern_browsers = prev->modern_browsers;
- conf->modern_unlisted_browsers = prev->modern_unlisted_browsers;
-
- } else if (conf->modern_browsers != NULL) {
- browsers = conf->modern_browsers->elts;
-
- for (i = 0; i < conf->modern_browsers->nelts; i++) {
- if (browsers[i].skip == 0) {
- goto found;
- }
- }
-
- /*
- * Opera may contain MSIE string, so if Opera was not enumerated
- * as modern browsers, then add it and set a unreachable version
- */
-
- opera = ngx_array_push(conf->modern_browsers);
- if (opera == NULL) {
- return NGX_CONF_ERROR;
- }
-
- opera->skip = 0;
- opera->version = 4001000000U;
-
- browsers = conf->modern_browsers->elts;
-
-found:
-
- ngx_qsort(browsers, (size_t) conf->modern_browsers->nelts,
- sizeof(ngx_http_modern_browser_t),
- ngx_http_modern_browser_sort);
-
- for (i = 0; i < conf->modern_browsers->nelts; i++) {
- n = browsers[i].skip;
-
- browsers[i].skip = ngx_http_modern_browser_masks[n].skip;
- browsers[i].add = ngx_http_modern_browser_masks[n].add;
- (void) ngx_cpystrn(browsers[i].name,
- ngx_http_modern_browser_masks[n].name, 12);
- }
- }
-
- if (conf->ancient_browsers == NULL && conf->netscape4 == 0) {
- conf->ancient_browsers = prev->ancient_browsers;
- conf->netscape4 = prev->netscape4;
- }
-
- if (conf->modern_browser_value == NULL) {
- conf->modern_browser_value = prev->modern_browser_value;
- }
-
- if (conf->modern_browser_value == NULL) {
- conf->modern_browser_value = &ngx_http_variable_true_value;
- }
-
- if (conf->ancient_browser_value == NULL) {
- conf->ancient_browser_value = prev->ancient_browser_value;
- }
-
- if (conf->ancient_browser_value == NULL) {
- conf->ancient_browser_value = &ngx_http_variable_true_value;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static int ngx_libc_cdecl
-ngx_http_modern_browser_sort(const void *one, const void *two)
-{
- ngx_http_modern_browser_t *first = (ngx_http_modern_browser_t *) one;
- ngx_http_modern_browser_t *second = (ngx_http_modern_browser_t *) two;
-
- return (first->skip - second->skip);
-}
-
-
-static char *
-ngx_http_modern_browser(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_browser_conf_t *bcf = conf;
-
- u_char c;
- ngx_str_t *value;
- ngx_uint_t i, n, version, ver, scale;
- ngx_http_modern_browser_t *browser;
- ngx_http_modern_browser_mask_t *mask;
-
- value = cf->args->elts;
-
- if (cf->args->nelts == 2) {
- if (ngx_strcmp(value[1].data, "unlisted") == 0) {
- bcf->modern_unlisted_browsers = 1;
- return NGX_CONF_OK;
- }
-
- return NGX_CONF_ERROR;
- }
-
- if (bcf->modern_browsers == NULL) {
- bcf->modern_browsers = ngx_array_create(cf->pool, 5,
- sizeof(ngx_http_modern_browser_t));
- if (bcf->modern_browsers == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- browser = ngx_array_push(bcf->modern_browsers);
- if (browser == NULL) {
- return NGX_CONF_ERROR;
- }
-
- mask = ngx_http_modern_browser_masks;
-
- for (n = 0; mask[n].browser[0] != '\0'; n++) {
- if (ngx_strcasecmp(mask[n].browser, value[1].data) == 0) {
- goto found;
- }
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unknown browser name \"%V\"", &value[1]);
-
- return NGX_CONF_ERROR;
-
-found:
-
- /*
- * at this stage the skip field is used to store the browser slot,
- * it will be used in sorting in merge stage and then will overwritten
- * with a real value
- */
-
- browser->skip = n;
-
- version = 0;
- ver = 0;
- scale = 1000000;
-
- for (i = 0; i < value[2].len; i++) {
-
- c = value[2].data[i];
-
- if (c >= '0' && c <= '9') {
- ver = ver * 10 + (c - '0');
- continue;
- }
-
- if (c == '.') {
- version += ver * scale;
- ver = 0;
- scale /= 100;
- continue;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid browser version \"%V\"", &value[2]);
-
- return NGX_CONF_ERROR;
- }
-
- version += ver * scale;
-
- browser->version = version;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_ancient_browser(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_browser_conf_t *bcf = conf;
-
- ngx_str_t *value, *browser;
- ngx_uint_t i;
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
- if (ngx_strcmp(value[i].data, "netscape4") == 0) {
- bcf->netscape4 = 1;
- continue;
- }
-
- if (bcf->ancient_browsers == NULL) {
- bcf->ancient_browsers = ngx_array_create(cf->pool, 4,
- sizeof(ngx_str_t));
- if (bcf->ancient_browsers == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- browser = ngx_array_push(bcf->ancient_browsers);
- if (browser == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *browser = value[i];
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_modern_browser_value(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_browser_conf_t *bcf = conf;
-
- ngx_str_t *value;
-
- bcf->modern_browser_value = ngx_palloc(cf->pool,
- sizeof(ngx_http_variable_value_t));
- if (bcf->modern_browser_value == NULL) {
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
-
- bcf->modern_browser_value->len = value[1].len;
- bcf->modern_browser_value->valid = 1;
- bcf->modern_browser_value->no_cacheable = 0;
- bcf->modern_browser_value->not_found = 0;
- bcf->modern_browser_value->data = value[1].data;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_ancient_browser_value(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_browser_conf_t *bcf = conf;
-
- ngx_str_t *value;
-
- bcf->ancient_browser_value = ngx_palloc(cf->pool,
- sizeof(ngx_http_variable_value_t));
- if (bcf->ancient_browser_value == NULL) {
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
-
- bcf->ancient_browser_value->len = value[1].len;
- bcf->ancient_browser_value->valid = 1;
- bcf->ancient_browser_value->no_cacheable = 0;
- bcf->ancient_browser_value->not_found = 0;
- bcf->ancient_browser_value->data = value[1].data;
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_charset_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_charset_filter_module.c
deleted file mode 100644
index c9b7e9e8968..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_charset_filter_module.c
+++ /dev/null
@@ -1,1681 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-#define NGX_HTTP_CHARSET_OFF -2
-#define NGX_HTTP_NO_CHARSET -3
-#define NGX_HTTP_CHARSET_VAR 0x10000
-
-/* 1 byte length and up to 3 bytes for the UTF-8 encoding of the UCS-2 */
-#define NGX_UTF_LEN 4
-
-#define NGX_HTML_ENTITY_LEN (sizeof("&#1114111;") - 1)
-
-
-typedef struct {
- u_char **tables;
- ngx_str_t name;
-
- unsigned length:16;
- unsigned utf8:1;
-} ngx_http_charset_t;
-
-
-typedef struct {
- ngx_int_t src;
- ngx_int_t dst;
-} ngx_http_charset_recode_t;
-
-
-typedef struct {
- ngx_int_t src;
- ngx_int_t dst;
- u_char *src2dst;
- u_char *dst2src;
-} ngx_http_charset_tables_t;
-
-
-typedef struct {
- ngx_array_t charsets; /* ngx_http_charset_t */
- ngx_array_t tables; /* ngx_http_charset_tables_t */
- ngx_array_t recodes; /* ngx_http_charset_recode_t */
-} ngx_http_charset_main_conf_t;
-
-
-typedef struct {
- ngx_int_t charset;
- ngx_int_t source_charset;
- ngx_flag_t override_charset;
-
- ngx_hash_t types;
- ngx_array_t *types_keys;
-} ngx_http_charset_loc_conf_t;
-
-
-typedef struct {
- u_char *table;
- ngx_int_t charset;
- ngx_str_t charset_name;
-
- ngx_chain_t *busy;
- ngx_chain_t *free_bufs;
- ngx_chain_t *free_buffers;
-
- size_t saved_len;
- u_char saved[NGX_UTF_LEN];
-
- unsigned length:16;
- unsigned from_utf8:1;
- unsigned to_utf8:1;
-} ngx_http_charset_ctx_t;
-
-
-typedef struct {
- ngx_http_charset_tables_t *table;
- ngx_http_charset_t *charset;
- ngx_uint_t characters;
-} ngx_http_charset_conf_ctx_t;
-
-
-static ngx_int_t ngx_http_destination_charset(ngx_http_request_t *r,
- ngx_str_t *name);
-static ngx_int_t ngx_http_main_request_charset(ngx_http_request_t *r,
- ngx_str_t *name);
-static ngx_int_t ngx_http_source_charset(ngx_http_request_t *r,
- ngx_str_t *name);
-static ngx_int_t ngx_http_get_charset(ngx_http_request_t *r, ngx_str_t *name);
-static ngx_inline void ngx_http_set_charset(ngx_http_request_t *r,
- ngx_str_t *charset);
-static ngx_int_t ngx_http_charset_ctx(ngx_http_request_t *r,
- ngx_http_charset_t *charsets, ngx_int_t charset, ngx_int_t source_charset);
-static ngx_uint_t ngx_http_charset_recode(ngx_buf_t *b, u_char *table);
-static ngx_chain_t *ngx_http_charset_recode_from_utf8(ngx_pool_t *pool,
- ngx_buf_t *buf, ngx_http_charset_ctx_t *ctx);
-static ngx_chain_t *ngx_http_charset_recode_to_utf8(ngx_pool_t *pool,
- ngx_buf_t *buf, ngx_http_charset_ctx_t *ctx);
-
-static ngx_chain_t *ngx_http_charset_get_buf(ngx_pool_t *pool,
- ngx_http_charset_ctx_t *ctx);
-static ngx_chain_t *ngx_http_charset_get_buffer(ngx_pool_t *pool,
- ngx_http_charset_ctx_t *ctx, size_t size);
-
-static char *ngx_http_charset_map_block(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_charset_map(ngx_conf_t *cf, ngx_command_t *dummy,
- void *conf);
-
-static char *ngx_http_set_charset_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static ngx_int_t ngx_http_add_charset(ngx_array_t *charsets, ngx_str_t *name);
-
-static void *ngx_http_charset_create_main_conf(ngx_conf_t *cf);
-static void *ngx_http_charset_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_charset_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static ngx_int_t ngx_http_charset_postconfiguration(ngx_conf_t *cf);
-
-
-ngx_str_t ngx_http_charset_default_types[] = {
- ngx_string("text/html"),
- ngx_string("text/xml"),
- ngx_string("text/plain"),
- ngx_string("text/vnd.wap.wml"),
- ngx_string("application/javascript"),
- ngx_string("application/rss+xml"),
- ngx_null_string
-};
-
-
-static ngx_command_t ngx_http_charset_filter_commands[] = {
-
- { ngx_string("charset"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
- |NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
- ngx_http_set_charset_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_charset_loc_conf_t, charset),
- NULL },
-
- { ngx_string("source_charset"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
- |NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
- ngx_http_set_charset_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_charset_loc_conf_t, source_charset),
- NULL },
-
- { ngx_string("override_charset"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
- |NGX_HTTP_LIF_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_charset_loc_conf_t, override_charset),
- NULL },
-
- { ngx_string("charset_types"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_types_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_charset_loc_conf_t, types_keys),
- &ngx_http_charset_default_types[0] },
-
- { ngx_string("charset_map"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2,
- ngx_http_charset_map_block,
- NGX_HTTP_MAIN_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_charset_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_charset_postconfiguration, /* postconfiguration */
-
- ngx_http_charset_create_main_conf, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_charset_create_loc_conf, /* create location configuration */
- ngx_http_charset_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_charset_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_charset_filter_module_ctx, /* module context */
- ngx_http_charset_filter_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-
-
-static ngx_int_t
-ngx_http_charset_header_filter(ngx_http_request_t *r)
-{
- ngx_int_t charset, source_charset;
- ngx_str_t dst, src;
- ngx_http_charset_t *charsets;
- ngx_http_charset_main_conf_t *mcf;
-
- if (r == r->main) {
- charset = ngx_http_destination_charset(r, &dst);
-
- } else {
- charset = ngx_http_main_request_charset(r, &dst);
- }
-
- if (charset == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- if (charset == NGX_DECLINED) {
- return ngx_http_next_header_filter(r);
- }
-
- /* charset: charset index or NGX_HTTP_NO_CHARSET */
-
- source_charset = ngx_http_source_charset(r, &src);
-
- if (source_charset == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- /*
- * source_charset: charset index, NGX_HTTP_NO_CHARSET,
- * or NGX_HTTP_CHARSET_OFF
- */
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "charset: \"%V\" > \"%V\"", &src, &dst);
-
- if (source_charset == NGX_HTTP_CHARSET_OFF) {
- ngx_http_set_charset(r, &dst);
-
- return ngx_http_next_header_filter(r);
- }
-
- if (charset == NGX_HTTP_NO_CHARSET
- || source_charset == NGX_HTTP_NO_CHARSET)
- {
- if (source_charset != charset
- || ngx_strncasecmp(dst.data, src.data, dst.len) != 0)
- {
- goto no_charset_map;
- }
-
- ngx_http_set_charset(r, &dst);
-
- return ngx_http_next_header_filter(r);
- }
-
- mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
- charsets = mcf->charsets.elts;
-
- if (source_charset != charset
- && (charsets[source_charset].tables == NULL
- || charsets[source_charset].tables[charset] == NULL))
- {
- goto no_charset_map;
- }
-
- r->headers_out.content_type.len = r->headers_out.content_type_len;
-
- ngx_http_set_charset(r, &dst);
-
- if (source_charset != charset) {
- return ngx_http_charset_ctx(r, charsets, charset, source_charset);
- }
-
- return ngx_http_next_header_filter(r);
-
-no_charset_map:
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "no \"charset_map\" between the charsets \"%V\" and \"%V\"",
- &src, &dst);
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_int_t
-ngx_http_destination_charset(ngx_http_request_t *r, ngx_str_t *name)
-{
- ngx_int_t charset;
- ngx_http_charset_t *charsets;
- ngx_http_variable_value_t *vv;
- ngx_http_charset_loc_conf_t *mlcf;
- ngx_http_charset_main_conf_t *mcf;
-
- if (!r->ignore_content_encoding
- && r->headers_out.content_encoding
- && r->headers_out.content_encoding->value.len)
- {
- return NGX_DECLINED;
- }
-
- if (r->headers_out.content_type.len == 0) {
- return NGX_DECLINED;
- }
-
- if (r->headers_out.override_charset
- && r->headers_out.override_charset->len)
- {
- *name = *r->headers_out.override_charset;
-
- charset = ngx_http_get_charset(r, name);
-
- if (charset != NGX_HTTP_NO_CHARSET) {
- return charset;
- }
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "unknown charset \"%V\" to override", name);
-
- return NGX_DECLINED;
- }
-
- mlcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module);
- charset = mlcf->charset;
-
- if (charset == NGX_HTTP_CHARSET_OFF) {
- return NGX_DECLINED;
- }
-
- if (r->headers_out.charset.len) {
- if (mlcf->override_charset == 0) {
- return NGX_DECLINED;
- }
-
- } else {
- if (ngx_http_test_content_type(r, &mlcf->types) == NULL) {
- return NGX_DECLINED;
- }
- }
-
- if (charset < NGX_HTTP_CHARSET_VAR) {
- mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
- charsets = mcf->charsets.elts;
- *name = charsets[charset].name;
- return charset;
- }
-
- vv = ngx_http_get_indexed_variable(r, charset - NGX_HTTP_CHARSET_VAR);
-
- if (vv == NULL || vv->not_found) {
- return NGX_ERROR;
- }
-
- name->len = vv->len;
- name->data = vv->data;
-
- return ngx_http_get_charset(r, name);
-}
-
-
-static ngx_int_t
-ngx_http_main_request_charset(ngx_http_request_t *r, ngx_str_t *src)
-{
- ngx_int_t charset;
- ngx_str_t *main_charset;
- ngx_http_charset_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r->main, ngx_http_charset_filter_module);
-
- if (ctx) {
- *src = ctx->charset_name;
- return ctx->charset;
- }
-
- main_charset = &r->main->headers_out.charset;
-
- if (main_charset->len == 0) {
- return NGX_DECLINED;
- }
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r->main, ctx, ngx_http_charset_filter_module);
-
- charset = ngx_http_get_charset(r, main_charset);
-
- ctx->charset = charset;
- ctx->charset_name = *main_charset;
- *src = *main_charset;
-
- return charset;
-}
-
-
-static ngx_int_t
-ngx_http_source_charset(ngx_http_request_t *r, ngx_str_t *name)
-{
- ngx_int_t charset;
- ngx_http_charset_t *charsets;
- ngx_http_variable_value_t *vv;
- ngx_http_charset_loc_conf_t *lcf;
- ngx_http_charset_main_conf_t *mcf;
-
- if (r->headers_out.charset.len) {
- *name = r->headers_out.charset;
- return ngx_http_get_charset(r, name);
- }
-
- lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module);
-
- charset = lcf->source_charset;
-
- if (charset == NGX_HTTP_CHARSET_OFF) {
- name->len = 0;
- return charset;
- }
-
- if (charset < NGX_HTTP_CHARSET_VAR) {
- mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
- charsets = mcf->charsets.elts;
- *name = charsets[charset].name;
- return charset;
- }
-
- vv = ngx_http_get_indexed_variable(r, charset - NGX_HTTP_CHARSET_VAR);
-
- if (vv == NULL || vv->not_found) {
- return NGX_ERROR;
- }
-
- name->len = vv->len;
- name->data = vv->data;
-
- return ngx_http_get_charset(r, name);
-}
-
-
-static ngx_int_t
-ngx_http_get_charset(ngx_http_request_t *r, ngx_str_t *name)
-{
- ngx_uint_t i, n;
- ngx_http_charset_t *charset;
- ngx_http_charset_main_conf_t *mcf;
-
- mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
-
- charset = mcf->charsets.elts;
- n = mcf->charsets.nelts;
-
- for (i = 0; i < n; i++) {
- if (charset[i].name.len != name->len) {
- continue;
- }
-
- if (ngx_strncasecmp(charset[i].name.data, name->data, name->len) == 0) {
- return i;
- }
- }
-
- return NGX_HTTP_NO_CHARSET;
-}
-
-
-static ngx_inline void
-ngx_http_set_charset(ngx_http_request_t *r, ngx_str_t *charset)
-{
- if (r != r->main) {
- return;
- }
-
- if (r->headers_out.status == NGX_HTTP_MOVED_PERMANENTLY
- || r->headers_out.status == NGX_HTTP_MOVED_TEMPORARILY)
- {
- /*
- * do not set charset for the redirect because NN 4.x
- * use this charset instead of the next page charset
- */
-
- r->headers_out.charset.len = 0;
- return;
- }
-
- r->headers_out.charset = *charset;
-}
-
-
-static ngx_int_t
-ngx_http_charset_ctx(ngx_http_request_t *r, ngx_http_charset_t *charsets,
- ngx_int_t charset, ngx_int_t source_charset)
-{
- ngx_http_charset_ctx_t *ctx;
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_charset_filter_module);
-
- ctx->table = charsets[source_charset].tables[charset];
- ctx->charset = charset;
- ctx->charset_name = charsets[charset].name;
- ctx->length = charsets[charset].length;
- ctx->from_utf8 = charsets[source_charset].utf8;
- ctx->to_utf8 = charsets[charset].utf8;
-
- r->filter_need_in_memory = 1;
-
- if ((ctx->to_utf8 || ctx->from_utf8) && r == r->main) {
- ngx_http_clear_content_length(r);
-
- } else {
- r->filter_need_temporary = 1;
- }
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_int_t
-ngx_http_charset_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t *cl, *out, **ll;
- ngx_http_charset_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_charset_filter_module);
-
- if (ctx == NULL || ctx->table == NULL) {
- return ngx_http_next_body_filter(r, in);
- }
-
- if ((ctx->to_utf8 || ctx->from_utf8) || ctx->busy) {
-
- out = NULL;
- ll = &out;
-
- for (cl = in; cl; cl = cl->next) {
- b = cl->buf;
-
- if (ngx_buf_size(b) == 0) {
-
- *ll = ngx_alloc_chain_link(r->pool);
- if (*ll == NULL) {
- return NGX_ERROR;
- }
-
- (*ll)->buf = b;
- (*ll)->next = NULL;
-
- ll = &(*ll)->next;
-
- continue;
- }
-
- if (ctx->to_utf8) {
- *ll = ngx_http_charset_recode_to_utf8(r->pool, b, ctx);
-
- } else {
- *ll = ngx_http_charset_recode_from_utf8(r->pool, b, ctx);
- }
-
- if (*ll == NULL) {
- return NGX_ERROR;
- }
-
- while (*ll) {
- ll = &(*ll)->next;
- }
- }
-
- rc = ngx_http_next_body_filter(r, out);
-
- if (out) {
- if (ctx->busy == NULL) {
- ctx->busy = out;
-
- } else {
- for (cl = ctx->busy; cl->next; cl = cl->next) { /* void */ }
- cl->next = out;
- }
- }
-
- while (ctx->busy) {
-
- cl = ctx->busy;
- b = cl->buf;
-
- if (ngx_buf_size(b) != 0) {
- break;
- }
-
- ctx->busy = cl->next;
-
- if (b->tag != (ngx_buf_tag_t) &ngx_http_charset_filter_module) {
- continue;
- }
-
- if (b->shadow) {
- b->shadow->pos = b->shadow->last;
- }
-
- if (b->pos) {
- cl->next = ctx->free_buffers;
- ctx->free_buffers = cl;
- continue;
- }
-
- cl->next = ctx->free_bufs;
- ctx->free_bufs = cl;
- }
-
- return rc;
- }
-
- for (cl = in; cl; cl = cl->next) {
- (void) ngx_http_charset_recode(cl->buf, ctx->table);
- }
-
- return ngx_http_next_body_filter(r, in);
-}
-
-
-static ngx_uint_t
-ngx_http_charset_recode(ngx_buf_t *b, u_char *table)
-{
- u_char *p, *last;
-
- last = b->last;
-
- for (p = b->pos; p < last; p++) {
-
- if (*p != table[*p]) {
- goto recode;
- }
- }
-
- return 0;
-
-recode:
-
- do {
- if (*p != table[*p]) {
- *p = table[*p];
- }
-
- p++;
-
- } while (p < last);
-
- b->in_file = 0;
-
- return 1;
-}
-
-
-static ngx_chain_t *
-ngx_http_charset_recode_from_utf8(ngx_pool_t *pool, ngx_buf_t *buf,
- ngx_http_charset_ctx_t *ctx)
-{
- size_t len, size;
- u_char c, *p, *src, *dst, *saved, **table;
- uint32_t n;
- ngx_buf_t *b;
- ngx_uint_t i;
- ngx_chain_t *out, *cl, **ll;
-
- src = buf->pos;
-
- if (ctx->saved_len == 0) {
-
- for ( /* void */ ; src < buf->last; src++) {
-
- if (*src < 0x80) {
- continue;
- }
-
- len = src - buf->pos;
-
- if (len > 512) {
- out = ngx_http_charset_get_buf(pool, ctx);
- if (out == NULL) {
- return NULL;
- }
-
- b = out->buf;
-
- b->temporary = buf->temporary;
- b->memory = buf->memory;
- b->mmap = buf->mmap;
- b->flush = buf->flush;
-
- b->pos = buf->pos;
- b->last = src;
-
- out->buf = b;
- out->next = NULL;
-
- size = buf->last - src;
-
- saved = src;
- n = ngx_utf8_decode(&saved, size);
-
- if (n == 0xfffffffe) {
- /* incomplete UTF-8 symbol */
-
- ngx_memcpy(ctx->saved, src, size);
- ctx->saved_len = size;
-
- b->shadow = buf;
-
- return out;
- }
-
- } else {
- out = NULL;
- size = len + buf->last - src;
- src = buf->pos;
- }
-
- if (size < NGX_HTML_ENTITY_LEN) {
- size += NGX_HTML_ENTITY_LEN;
- }
-
- cl = ngx_http_charset_get_buffer(pool, ctx, size);
- if (cl == NULL) {
- return NULL;
- }
-
- if (out) {
- out->next = cl;
-
- } else {
- out = cl;
- }
-
- b = cl->buf;
- dst = b->pos;
-
- goto recode;
- }
-
- out = ngx_alloc_chain_link(pool);
- if (out == NULL) {
- return NULL;
- }
-
- out->buf = buf;
- out->next = NULL;
-
- return out;
- }
-
- /* process incomplete UTF sequence from previous buffer */
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pool->log, 0,
- "http charset utf saved: %z", ctx->saved_len);
-
- p = src;
-
- for (i = ctx->saved_len; i < NGX_UTF_LEN; i++) {
- ctx->saved[i] = *p++;
-
- if (p == buf->last) {
- break;
- }
- }
-
- saved = ctx->saved;
- n = ngx_utf8_decode(&saved, i);
-
- c = '\0';
-
- if (n < 0x10000) {
- table = (u_char **) ctx->table;
- p = table[n >> 8];
-
- if (p) {
- c = p[n & 0xff];
- }
-
- } else if (n == 0xfffffffe) {
-
- /* incomplete UTF-8 symbol */
-
- if (i < NGX_UTF_LEN) {
- out = ngx_http_charset_get_buf(pool, ctx);
- if (out == NULL) {
- return NULL;
- }
-
- b = out->buf;
-
- b->pos = buf->pos;
- b->last = buf->last;
- b->sync = 1;
- b->shadow = buf;
-
- ngx_memcpy(&ctx->saved[ctx->saved_len], src, i);
- ctx->saved_len += i;
-
- return out;
- }
- }
-
- size = buf->last - buf->pos;
-
- if (size < NGX_HTML_ENTITY_LEN) {
- size += NGX_HTML_ENTITY_LEN;
- }
-
- cl = ngx_http_charset_get_buffer(pool, ctx, size);
- if (cl == NULL) {
- return NULL;
- }
-
- out = cl;
-
- b = cl->buf;
- dst = b->pos;
-
- if (c) {
- *dst++ = c;
-
- } else if (n == 0xfffffffe) {
- *dst++ = '?';
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pool->log, 0,
- "http charset invalid utf 0");
-
- saved = &ctx->saved[NGX_UTF_LEN];
-
- } else if (n > 0x10ffff) {
- *dst++ = '?';
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pool->log, 0,
- "http charset invalid utf 1");
-
- } else {
- dst = ngx_sprintf(dst, "&#%uD;", n);
- }
-
- src += (saved - ctx->saved) - ctx->saved_len;
- ctx->saved_len = 0;
-
-recode:
-
- ll = &cl->next;
-
- table = (u_char **) ctx->table;
-
- while (src < buf->last) {
-
- if ((size_t) (b->end - dst) < NGX_HTML_ENTITY_LEN) {
- b->last = dst;
-
- size = buf->last - src + NGX_HTML_ENTITY_LEN;
-
- cl = ngx_http_charset_get_buffer(pool, ctx, size);
- if (cl == NULL) {
- return NULL;
- }
-
- *ll = cl;
- ll = &cl->next;
-
- b = cl->buf;
- dst = b->pos;
- }
-
- if (*src < 0x80) {
- *dst++ = *src++;
- continue;
- }
-
- len = buf->last - src;
-
- n = ngx_utf8_decode(&src, len);
-
- if (n < 0x10000) {
-
- p = table[n >> 8];
-
- if (p) {
- c = p[n & 0xff];
-
- if (c) {
- *dst++ = c;
- continue;
- }
- }
-
- dst = ngx_sprintf(dst, "&#%uD;", n);
-
- continue;
- }
-
- if (n == 0xfffffffe) {
- /* incomplete UTF-8 symbol */
-
- ngx_memcpy(ctx->saved, src, len);
- ctx->saved_len = len;
-
- if (b->pos == dst) {
- b->sync = 1;
- b->temporary = 0;
- }
-
- break;
- }
-
- if (n > 0x10ffff) {
- *dst++ = '?';
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pool->log, 0,
- "http charset invalid utf 2");
-
- continue;
- }
-
- /* n > 0xffff */
-
- dst = ngx_sprintf(dst, "&#%uD;", n);
- }
-
- b->last = dst;
-
- b->last_buf = buf->last_buf;
- b->last_in_chain = buf->last_in_chain;
- b->flush = buf->flush;
-
- b->shadow = buf;
-
- return out;
-}
-
-
-static ngx_chain_t *
-ngx_http_charset_recode_to_utf8(ngx_pool_t *pool, ngx_buf_t *buf,
- ngx_http_charset_ctx_t *ctx)
-{
- size_t len, size;
- u_char *p, *src, *dst, *table;
- ngx_buf_t *b;
- ngx_chain_t *out, *cl, **ll;
-
- table = ctx->table;
-
- for (src = buf->pos; src < buf->last; src++) {
- if (table[*src * NGX_UTF_LEN] == '\1') {
- continue;
- }
-
- goto recode;
- }
-
- out = ngx_alloc_chain_link(pool);
- if (out == NULL) {
- return NULL;
- }
-
- out->buf = buf;
- out->next = NULL;
-
- return out;
-
-recode:
-
- /*
- * we assume that there are about half of characters to be recoded,
- * so we preallocate "size / 2 + size / 2 * ctx->length"
- */
-
- len = src - buf->pos;
-
- if (len > 512) {
- out = ngx_http_charset_get_buf(pool, ctx);
- if (out == NULL) {
- return NULL;
- }
-
- b = out->buf;
-
- b->temporary = buf->temporary;
- b->memory = buf->memory;
- b->mmap = buf->mmap;
- b->flush = buf->flush;
-
- b->pos = buf->pos;
- b->last = src;
-
- out->buf = b;
- out->next = NULL;
-
- size = buf->last - src;
- size = size / 2 + size / 2 * ctx->length;
-
- } else {
- out = NULL;
-
- size = buf->last - src;
- size = len + size / 2 + size / 2 * ctx->length;
-
- src = buf->pos;
- }
-
- cl = ngx_http_charset_get_buffer(pool, ctx, size);
- if (cl == NULL) {
- return NULL;
- }
-
- if (out) {
- out->next = cl;
-
- } else {
- out = cl;
- }
-
- ll = &cl->next;
-
- b = cl->buf;
- dst = b->pos;
-
- while (src < buf->last) {
-
- p = &table[*src++ * NGX_UTF_LEN];
- len = *p++;
-
- if ((size_t) (b->end - dst) < len) {
- b->last = dst;
-
- size = buf->last - src;
- size = len + size / 2 + size / 2 * ctx->length;
-
- cl = ngx_http_charset_get_buffer(pool, ctx, size);
- if (cl == NULL) {
- return NULL;
- }
-
- *ll = cl;
- ll = &cl->next;
-
- b = cl->buf;
- dst = b->pos;
- }
-
- while (len) {
- *dst++ = *p++;
- len--;
- }
- }
-
- b->last = dst;
-
- b->last_buf = buf->last_buf;
- b->last_in_chain = buf->last_in_chain;
- b->flush = buf->flush;
-
- b->shadow = buf;
-
- return out;
-}
-
-
-static ngx_chain_t *
-ngx_http_charset_get_buf(ngx_pool_t *pool, ngx_http_charset_ctx_t *ctx)
-{
- ngx_chain_t *cl;
-
- cl = ctx->free_bufs;
-
- if (cl) {
- ctx->free_bufs = cl->next;
-
- cl->buf->shadow = NULL;
- cl->next = NULL;
-
- return cl;
- }
-
- cl = ngx_alloc_chain_link(pool);
- if (cl == NULL) {
- return NULL;
- }
-
- cl->buf = ngx_calloc_buf(pool);
- if (cl->buf == NULL) {
- return NULL;
- }
-
- cl->next = NULL;
-
- cl->buf->tag = (ngx_buf_tag_t) &ngx_http_charset_filter_module;
-
- return cl;
-}
-
-
-static ngx_chain_t *
-ngx_http_charset_get_buffer(ngx_pool_t *pool, ngx_http_charset_ctx_t *ctx,
- size_t size)
-{
- ngx_buf_t *b;
- ngx_chain_t *cl, **ll;
-
- for (ll = &ctx->free_buffers, cl = ctx->free_buffers;
- cl;
- ll = &cl->next, cl = cl->next)
- {
- b = cl->buf;
-
- if ((size_t) (b->end - b->start) >= size) {
- *ll = cl->next;
- cl->next = NULL;
-
- b->pos = b->start;
- b->temporary = 1;
- b->shadow = NULL;
-
- return cl;
- }
- }
-
- cl = ngx_alloc_chain_link(pool);
- if (cl == NULL) {
- return NULL;
- }
-
- cl->buf = ngx_create_temp_buf(pool, size);
- if (cl->buf == NULL) {
- return NULL;
- }
-
- cl->next = NULL;
-
- cl->buf->temporary = 1;
- cl->buf->tag = (ngx_buf_tag_t) &ngx_http_charset_filter_module;
-
- return cl;
-}
-
-
-static char *
-ngx_http_charset_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_charset_main_conf_t *mcf = conf;
-
- char *rv;
- u_char *p, *dst2src, **pp;
- ngx_int_t src, dst;
- ngx_uint_t i, n;
- ngx_str_t *value;
- ngx_conf_t pvcf;
- ngx_http_charset_t *charset;
- ngx_http_charset_tables_t *table;
- ngx_http_charset_conf_ctx_t ctx;
-
- value = cf->args->elts;
-
- src = ngx_http_add_charset(&mcf->charsets, &value[1]);
- if (src == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- dst = ngx_http_add_charset(&mcf->charsets, &value[2]);
- if (dst == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- if (src == dst) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"charset_map\" between the same charsets "
- "\"%V\" and \"%V\"", &value[1], &value[2]);
- return NGX_CONF_ERROR;
- }
-
- table = mcf->tables.elts;
- for (i = 0; i < mcf->tables.nelts; i++) {
- if ((src == table->src && dst == table->dst)
- || (src == table->dst && dst == table->src))
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate \"charset_map\" between "
- "\"%V\" and \"%V\"", &value[1], &value[2]);
- return NGX_CONF_ERROR;
- }
- }
-
- table = ngx_array_push(&mcf->tables);
- if (table == NULL) {
- return NGX_CONF_ERROR;
- }
-
- table->src = src;
- table->dst = dst;
-
- if (ngx_strcasecmp(value[2].data, (u_char *) "utf-8") == 0) {
- table->src2dst = ngx_pcalloc(cf->pool, 256 * NGX_UTF_LEN);
- if (table->src2dst == NULL) {
- return NGX_CONF_ERROR;
- }
-
- table->dst2src = ngx_pcalloc(cf->pool, 256 * sizeof(void *));
- if (table->dst2src == NULL) {
- return NGX_CONF_ERROR;
- }
-
- dst2src = ngx_pcalloc(cf->pool, 256);
- if (dst2src == NULL) {
- return NGX_CONF_ERROR;
- }
-
- pp = (u_char **) &table->dst2src[0];
- pp[0] = dst2src;
-
- for (i = 0; i < 128; i++) {
- p = &table->src2dst[i * NGX_UTF_LEN];
- p[0] = '\1';
- p[1] = (u_char) i;
- dst2src[i] = (u_char) i;
- }
-
- for (/* void */; i < 256; i++) {
- p = &table->src2dst[i * NGX_UTF_LEN];
- p[0] = '\1';
- p[1] = '?';
- }
-
- } else {
- table->src2dst = ngx_palloc(cf->pool, 256);
- if (table->src2dst == NULL) {
- return NGX_CONF_ERROR;
- }
-
- table->dst2src = ngx_palloc(cf->pool, 256);
- if (table->dst2src == NULL) {
- return NGX_CONF_ERROR;
- }
-
- for (i = 0; i < 128; i++) {
- table->src2dst[i] = (u_char) i;
- table->dst2src[i] = (u_char) i;
- }
-
- for (/* void */; i < 256; i++) {
- table->src2dst[i] = '?';
- table->dst2src[i] = '?';
- }
- }
-
- charset = mcf->charsets.elts;
-
- ctx.table = table;
- ctx.charset = &charset[dst];
- ctx.characters = 0;
-
- pvcf = *cf;
- cf->ctx = &ctx;
- cf->handler = ngx_http_charset_map;
- cf->handler_conf = conf;
-
- rv = ngx_conf_parse(cf, NULL);
-
- *cf = pvcf;
-
- if (ctx.characters) {
- n = ctx.charset->length;
- ctx.charset->length /= ctx.characters;
-
- if (((n * 10) / ctx.characters) % 10 > 4) {
- ctx.charset->length++;
- }
- }
-
- return rv;
-}
-
-
-static char *
-ngx_http_charset_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
-{
- u_char *p, *dst2src, **pp;
- uint32_t n;
- ngx_int_t src, dst;
- ngx_str_t *value;
- ngx_uint_t i;
- ngx_http_charset_tables_t *table;
- ngx_http_charset_conf_ctx_t *ctx;
-
- if (cf->args->nelts != 2) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameters number");
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
-
- src = ngx_hextoi(value[0].data, value[0].len);
- if (src == NGX_ERROR || src > 255) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\"", &value[0]);
- return NGX_CONF_ERROR;
- }
-
- ctx = cf->ctx;
- table = ctx->table;
-
- if (ctx->charset->utf8) {
- p = &table->src2dst[src * NGX_UTF_LEN];
-
- *p++ = (u_char) (value[1].len / 2);
-
- for (i = 0; i < value[1].len; i += 2) {
- dst = ngx_hextoi(&value[1].data[i], 2);
- if (dst == NGX_ERROR || dst > 255) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- *p++ = (u_char) dst;
- }
-
- i /= 2;
-
- ctx->charset->length += i;
- ctx->characters++;
-
- p = &table->src2dst[src * NGX_UTF_LEN] + 1;
-
- n = ngx_utf8_decode(&p, i);
-
- if (n > 0xffff) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- pp = (u_char **) &table->dst2src[0];
-
- dst2src = pp[n >> 8];
-
- if (dst2src == NULL) {
- dst2src = ngx_pcalloc(cf->pool, 256);
- if (dst2src == NULL) {
- return NGX_CONF_ERROR;
- }
-
- pp[n >> 8] = dst2src;
- }
-
- dst2src[n & 0xff] = (u_char) src;
-
- } else {
- dst = ngx_hextoi(value[1].data, value[1].len);
- if (dst == NGX_ERROR || dst > 255) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- table->src2dst[src] = (u_char) dst;
- table->dst2src[dst] = (u_char) src;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_set_charset_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_int_t *cp;
- ngx_str_t *value, var;
- ngx_http_charset_main_conf_t *mcf;
-
- cp = (ngx_int_t *) (p + cmd->offset);
-
- if (*cp != NGX_CONF_UNSET) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- if (cmd->offset == offsetof(ngx_http_charset_loc_conf_t, charset)
- && ngx_strcmp(value[1].data, "off") == 0)
- {
- *cp = NGX_HTTP_CHARSET_OFF;
- return NGX_CONF_OK;
- }
-
-
- if (value[1].data[0] == '$') {
- var.len = value[1].len - 1;
- var.data = value[1].data + 1;
-
- *cp = ngx_http_get_variable_index(cf, &var);
-
- if (*cp == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- *cp += NGX_HTTP_CHARSET_VAR;
-
- return NGX_CONF_OK;
- }
-
- mcf = ngx_http_conf_get_module_main_conf(cf,
- ngx_http_charset_filter_module);
-
- *cp = ngx_http_add_charset(&mcf->charsets, &value[1]);
- if (*cp == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_add_charset(ngx_array_t *charsets, ngx_str_t *name)
-{
- ngx_uint_t i;
- ngx_http_charset_t *c;
-
- c = charsets->elts;
- for (i = 0; i < charsets->nelts; i++) {
- if (name->len != c[i].name.len) {
- continue;
- }
-
- if (ngx_strcasecmp(name->data, c[i].name.data) == 0) {
- break;
- }
- }
-
- if (i < charsets->nelts) {
- return i;
- }
-
- c = ngx_array_push(charsets);
- if (c == NULL) {
- return NGX_ERROR;
- }
-
- c->tables = NULL;
- c->name = *name;
- c->length = 0;
-
- if (ngx_strcasecmp(name->data, (u_char *) "utf-8") == 0) {
- c->utf8 = 1;
-
- } else {
- c->utf8 = 0;
- }
-
- return i;
-}
-
-
-static void *
-ngx_http_charset_create_main_conf(ngx_conf_t *cf)
-{
- ngx_http_charset_main_conf_t *mcf;
-
- mcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_main_conf_t));
- if (mcf == NULL) {
- return NULL;
- }
-
- if (ngx_array_init(&mcf->charsets, cf->pool, 2, sizeof(ngx_http_charset_t))
- != NGX_OK)
- {
- return NULL;
- }
-
- if (ngx_array_init(&mcf->tables, cf->pool, 1,
- sizeof(ngx_http_charset_tables_t))
- != NGX_OK)
- {
- return NULL;
- }
-
- if (ngx_array_init(&mcf->recodes, cf->pool, 2,
- sizeof(ngx_http_charset_recode_t))
- != NGX_OK)
- {
- return NULL;
- }
-
- return mcf;
-}
-
-
-static void *
-ngx_http_charset_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_charset_loc_conf_t *lcf;
-
- lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_loc_conf_t));
- if (lcf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * lcf->types = { NULL };
- * lcf->types_keys = NULL;
- */
-
- lcf->charset = NGX_CONF_UNSET;
- lcf->source_charset = NGX_CONF_UNSET;
- lcf->override_charset = NGX_CONF_UNSET;
-
- return lcf;
-}
-
-
-static char *
-ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_charset_loc_conf_t *prev = parent;
- ngx_http_charset_loc_conf_t *conf = child;
-
- ngx_uint_t i;
- ngx_http_charset_recode_t *recode;
- ngx_http_charset_main_conf_t *mcf;
-
- if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
- &prev->types_keys, &prev->types,
- ngx_http_charset_default_types)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_value(conf->override_charset, prev->override_charset, 0);
- ngx_conf_merge_value(conf->charset, prev->charset, NGX_HTTP_CHARSET_OFF);
- ngx_conf_merge_value(conf->source_charset, prev->source_charset,
- NGX_HTTP_CHARSET_OFF);
-
- if (conf->charset == NGX_HTTP_CHARSET_OFF
- || conf->source_charset == NGX_HTTP_CHARSET_OFF
- || conf->charset == conf->source_charset)
- {
- 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;
- for (i = 0; i < mcf->recodes.nelts; i++) {
- if (conf->source_charset == recode[i].src
- && conf->charset == recode[i].dst)
- {
- return NGX_CONF_OK;
- }
- }
-
- recode = ngx_array_push(&mcf->recodes);
- if (recode == NULL) {
- return NGX_CONF_ERROR;
- }
-
- recode->src = conf->source_charset;
- recode->dst = conf->charset;
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_charset_postconfiguration(ngx_conf_t *cf)
-{
- u_char **src, **dst;
- ngx_int_t c;
- ngx_uint_t i, t;
- ngx_http_charset_t *charset;
- ngx_http_charset_recode_t *recode;
- ngx_http_charset_tables_t *tables;
- ngx_http_charset_main_conf_t *mcf;
-
- mcf = ngx_http_conf_get_module_main_conf(cf,
- ngx_http_charset_filter_module);
-
- recode = mcf->recodes.elts;
- tables = mcf->tables.elts;
- charset = mcf->charsets.elts;
-
- for (i = 0; i < mcf->recodes.nelts; i++) {
-
- c = recode[i].src;
-
- for (t = 0; t < mcf->tables.nelts; t++) {
-
- if (c == tables[t].src && recode[i].dst == tables[t].dst) {
- goto next;
- }
-
- if (c == tables[t].dst && recode[i].dst == tables[t].src) {
- goto next;
- }
- }
-
- 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);
- return NGX_ERROR;
-
- next:
- continue;
- }
-
-
- for (t = 0; t < mcf->tables.nelts; t++) {
-
- src = charset[tables[t].src].tables;
-
- if (src == NULL) {
- src = ngx_pcalloc(cf->pool, sizeof(u_char *) * mcf->charsets.nelts);
- if (src == NULL) {
- return NGX_ERROR;
- }
-
- charset[tables[t].src].tables = src;
- }
-
- dst = charset[tables[t].dst].tables;
-
- if (dst == NULL) {
- dst = ngx_pcalloc(cf->pool, sizeof(u_char *) * mcf->charsets.nelts);
- if (dst == NULL) {
- return NGX_ERROR;
- }
-
- charset[tables[t].dst].tables = dst;
- }
-
- src[tables[t].dst] = tables[t].src2dst;
- dst[tables[t].src] = tables[t].dst2src;
- }
-
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_charset_header_filter;
-
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_charset_body_filter;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_chunked_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_chunked_filter_module.c
deleted file mode 100644
index a7dc5bf4d4b..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_chunked_filter_module.c
+++ /dev/null
@@ -1,243 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_chain_t *free;
- ngx_chain_t *busy;
-} ngx_http_chunked_filter_ctx_t;
-
-
-static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf);
-
-
-static ngx_http_module_t ngx_http_chunked_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_chunked_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_chunked_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_chunked_filter_module_ctx, /* module context */
- NULL, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-
-
-static ngx_int_t
-ngx_http_chunked_header_filter(ngx_http_request_t *r)
-{
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_chunked_filter_ctx_t *ctx;
-
- if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED
- || r->headers_out.status == NGX_HTTP_NO_CONTENT
- || r->headers_out.status < NGX_HTTP_OK
- || r != r->main
- || (r->method & NGX_HTTP_HEAD))
- {
- return ngx_http_next_header_filter(r);
- }
-
- if (r->headers_out.content_length_n == -1) {
- if (r->http_version < NGX_HTTP_VERSION_11) {
- r->keepalive = 0;
-
- } else {
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->chunked_transfer_encoding) {
- r->chunked = 1;
-
- ctx = ngx_pcalloc(r->pool,
- sizeof(ngx_http_chunked_filter_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_chunked_filter_module);
-
- } else {
- r->keepalive = 0;
- }
- }
- }
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_int_t
-ngx_http_chunked_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- u_char *chunk;
- off_t size;
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t *out, *cl, *tl, **ll;
- ngx_http_chunked_filter_ctx_t *ctx;
-
- if (in == NULL || !r->chunked || r->header_only) {
- return ngx_http_next_body_filter(r, in);
- }
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_chunked_filter_module);
-
- out = NULL;
- ll = &out;
-
- size = 0;
- cl = in;
-
- for ( ;; ) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http chunk: %d", ngx_buf_size(cl->buf));
-
- size += ngx_buf_size(cl->buf);
-
- if (cl->buf->flush
- || cl->buf->sync
- || ngx_buf_in_memory(cl->buf)
- || cl->buf->in_file)
- {
- tl = ngx_alloc_chain_link(r->pool);
- if (tl == NULL) {
- return NGX_ERROR;
- }
-
- tl->buf = cl->buf;
- *ll = tl;
- ll = &tl->next;
- }
-
- if (cl->next == NULL) {
- break;
- }
-
- cl = cl->next;
- }
-
- if (size) {
- tl = ngx_chain_get_free_buf(r->pool, &ctx->free);
- if (tl == NULL) {
- return NGX_ERROR;
- }
-
- b = tl->buf;
- chunk = b->start;
-
- if (chunk == NULL) {
- /* the "0000000000000000" is 64-bit hexadecimal string */
-
- chunk = ngx_palloc(r->pool, sizeof("0000000000000000" CRLF) - 1);
- if (chunk == NULL) {
- return NGX_ERROR;
- }
-
- b->start = chunk;
- b->end = chunk + sizeof("0000000000000000" CRLF) - 1;
- }
-
- b->tag = (ngx_buf_tag_t) &ngx_http_chunked_filter_module;
- b->memory = 0;
- b->temporary = 1;
- b->pos = chunk;
- b->last = ngx_sprintf(chunk, "%xO" CRLF, size);
-
- tl->next = out;
- out = tl;
- }
-
- if (cl->buf->last_buf) {
- tl = ngx_chain_get_free_buf(r->pool, &ctx->free);
- if (tl == NULL) {
- return NGX_ERROR;
- }
-
- b = tl->buf;
-
- b->tag = (ngx_buf_tag_t) &ngx_http_chunked_filter_module;
- b->temporary = 0;
- b->memory = 1;
- b->last_buf = 1;
- b->pos = (u_char *) CRLF "0" CRLF CRLF;
- b->last = b->pos + 7;
-
- cl->buf->last_buf = 0;
-
- *ll = tl;
-
- if (size == 0) {
- b->pos += 2;
- }
-
- } else if (size > 0) {
- tl = ngx_chain_get_free_buf(r->pool, &ctx->free);
- if (tl == NULL) {
- return NGX_ERROR;
- }
-
- b = tl->buf;
-
- b->tag = (ngx_buf_tag_t) &ngx_http_chunked_filter_module;
- b->temporary = 0;
- b->memory = 1;
- b->pos = (u_char *) CRLF;
- b->last = b->pos + 2;
-
- *ll = tl;
-
- } else {
- *ll = NULL;
- }
-
- rc = ngx_http_next_body_filter(r, out);
-
- ngx_chain_update_chains(r->pool, &ctx->free, &ctx->busy, &out,
- (ngx_buf_tag_t) &ngx_http_chunked_filter_module);
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_chunked_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_chunked_header_filter;
-
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_chunked_body_filter;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_dav_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_dav_module.c
deleted file mode 100644
index e7f9e9ae3c8..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_dav_module.c
+++ /dev/null
@@ -1,1144 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-#define NGX_HTTP_DAV_OFF 2
-
-
-#define NGX_HTTP_DAV_NO_DEPTH -3
-#define NGX_HTTP_DAV_INVALID_DEPTH -2
-#define NGX_HTTP_DAV_INFINITY_DEPTH -1
-
-
-typedef struct {
- ngx_uint_t methods;
- ngx_uint_t access;
- ngx_uint_t min_delete_depth;
- ngx_flag_t create_full_put_path;
-} ngx_http_dav_loc_conf_t;
-
-
-typedef struct {
- ngx_str_t path;
- size_t len;
-} ngx_http_dav_copy_ctx_t;
-
-
-static ngx_int_t ngx_http_dav_handler(ngx_http_request_t *r);
-
-static void ngx_http_dav_put_handler(ngx_http_request_t *r);
-
-static ngx_int_t ngx_http_dav_delete_handler(ngx_http_request_t *r);
-static ngx_int_t ngx_http_dav_delete_path(ngx_http_request_t *r,
- ngx_str_t *path, ngx_uint_t dir);
-static ngx_int_t ngx_http_dav_delete_dir(ngx_tree_ctx_t *ctx, ngx_str_t *path);
-static ngx_int_t ngx_http_dav_delete_file(ngx_tree_ctx_t *ctx, ngx_str_t *path);
-static ngx_int_t ngx_http_dav_noop(ngx_tree_ctx_t *ctx, ngx_str_t *path);
-
-static ngx_int_t ngx_http_dav_mkcol_handler(ngx_http_request_t *r,
- ngx_http_dav_loc_conf_t *dlcf);
-
-static ngx_int_t ngx_http_dav_copy_move_handler(ngx_http_request_t *r);
-static ngx_int_t ngx_http_dav_copy_dir(ngx_tree_ctx_t *ctx, ngx_str_t *path);
-static ngx_int_t ngx_http_dav_copy_dir_time(ngx_tree_ctx_t *ctx,
- ngx_str_t *path);
-static ngx_int_t ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx,
- ngx_str_t *path);
-
-static ngx_int_t ngx_http_dav_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 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);
-static ngx_int_t ngx_http_dav_init(ngx_conf_t *cf);
-
-
-static ngx_conf_bitmask_t ngx_http_dav_methods_mask[] = {
- { ngx_string("off"), NGX_HTTP_DAV_OFF },
- { ngx_string("put"), NGX_HTTP_PUT },
- { ngx_string("delete"), NGX_HTTP_DELETE },
- { ngx_string("mkcol"), NGX_HTTP_MKCOL },
- { ngx_string("copy"), NGX_HTTP_COPY },
- { ngx_string("move"), NGX_HTTP_MOVE },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_command_t ngx_http_dav_commands[] = {
-
- { ngx_string("dav_methods"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_dav_loc_conf_t, methods),
- &ngx_http_dav_methods_mask },
-
- { ngx_string("create_full_put_path"),
- 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_dav_loc_conf_t, create_full_put_path),
- NULL },
-
- { ngx_string("min_delete_depth"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_dav_loc_conf_t, min_delete_depth),
- NULL },
-
- { ngx_string("dav_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_dav_loc_conf_t, access),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_dav_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_dav_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_dav_create_loc_conf, /* create location configuration */
- ngx_http_dav_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_dav_module = {
- NGX_MODULE_V1,
- &ngx_http_dav_module_ctx, /* module context */
- ngx_http_dav_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_dav_handler(ngx_http_request_t *r)
-{
- ngx_int_t rc;
- ngx_http_dav_loc_conf_t *dlcf;
-
- dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
-
- if (!(r->method & dlcf->methods)) {
- return NGX_DECLINED;
- }
-
- switch (r->method) {
-
- case NGX_HTTP_PUT:
-
- if (r->uri.data[r->uri.len - 1] == '/') {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "cannot PUT to a collection");
- return NGX_HTTP_CONFLICT;
- }
-
- r->request_body_in_file_only = 1;
- r->request_body_in_persistent_file = 1;
- r->request_body_in_clean_file = 1;
- r->request_body_file_group_access = 1;
- r->request_body_file_log_level = 0;
-
- rc = ngx_http_read_client_request_body(r, ngx_http_dav_put_handler);
-
- if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
- return rc;
- }
-
- return NGX_DONE;
-
- case NGX_HTTP_DELETE:
-
- return ngx_http_dav_delete_handler(r);
-
- case NGX_HTTP_MKCOL:
-
- return ngx_http_dav_mkcol_handler(r, dlcf);
-
- case NGX_HTTP_COPY:
-
- return ngx_http_dav_copy_move_handler(r);
-
- case NGX_HTTP_MOVE:
-
- return ngx_http_dav_copy_move_handler(r);
- }
-
- return NGX_DECLINED;
-}
-
-
-static void
-ngx_http_dav_put_handler(ngx_http_request_t *r)
-{
- size_t root;
- time_t date;
- ngx_str_t *temp, path;
- ngx_uint_t status;
- ngx_file_info_t fi;
- ngx_ext_rename_file_t ext;
- ngx_http_dav_loc_conf_t *dlcf;
-
- if (r->request_body == NULL || r->request_body->temp_file == NULL) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- ngx_http_map_uri_to_path(r, &path, &root, 0);
-
- path.len--;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http put filename: \"%s\"", path.data);
-
- temp = &r->request_body->temp_file->file.name;
-
- if (ngx_file_info(path.data, &fi) == NGX_FILE_ERROR) {
- status = NGX_HTTP_CREATED;
-
- } else {
- status = NGX_HTTP_NO_CONTENT;
-
- if (ngx_is_dir(&fi)) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_EISDIR,
- "\"%s\" could not be created", path.data);
-
- 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_http_finalize_request(r, NGX_HTTP_CONFLICT);
- return;
- }
- }
-
- dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
-
- ext.access = dlcf->access;
- ext.path_access = dlcf->access;
- ext.time = -1;
- ext.create_path = dlcf->create_full_put_path;
- ext.delete_file = 1;
- ext.log = r->connection->log;
-
- if (r->headers_in.date) {
- date = ngx_http_parse_time(r->headers_in.date->value.data,
- r->headers_in.date->value.len);
-
- if (date != NGX_ERROR) {
- ext.time = date;
- ext.fd = r->request_body->temp_file->file.fd;
- }
- }
-
- if (ngx_ext_rename_file(temp, &path, &ext) != NGX_OK) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- if (status == NGX_HTTP_CREATED) {
- if (ngx_http_dav_location(r, path.data) != NGX_OK) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- r->headers_out.content_length_n = 0;
- }
-
- r->headers_out.status = status;
- r->header_only = 1;
-
- ngx_http_finalize_request(r, ngx_http_send_header(r));
- return;
-}
-
-
-static ngx_int_t
-ngx_http_dav_delete_handler(ngx_http_request_t *r)
-{
- size_t root;
- ngx_err_t err;
- ngx_int_t rc, depth;
- ngx_uint_t i, d, dir;
- ngx_str_t path;
- ngx_file_info_t fi;
- ngx_http_dav_loc_conf_t *dlcf;
-
- if (r->headers_in.content_length_n > 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "DELETE with body is unsupported");
- return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE;
- }
-
- dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
-
- if (dlcf->min_delete_depth) {
- d = 0;
-
- for (i = 0; i < r->uri.len; /* void */) {
- if (r->uri.data[i++] == '/') {
- if (++d >= dlcf->min_delete_depth && i < r->uri.len) {
- goto ok;
- }
- }
- }
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "insufficient URI depth:%i to DELETE", d);
- return NGX_HTTP_CONFLICT;
- }
-
-ok:
-
- ngx_http_map_uri_to_path(r, &path, &root, 0);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http delete filename: \"%s\"", path.data);
-
- if (ngx_link_info(path.data, &fi) == NGX_FILE_ERROR) {
- err = ngx_errno;
-
- rc = (err == NGX_ENOTDIR) ? NGX_HTTP_CONFLICT : NGX_HTTP_NOT_FOUND;
-
- return ngx_http_dav_error(r->connection->log, err,
- rc, ngx_link_info_n, path.data);
- }
-
- if (ngx_is_dir(&fi)) {
-
- if (r->uri.data[r->uri.len - 1] != '/') {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_EISDIR,
- "DELETE \"%s\" failed", path.data);
- return NGX_HTTP_CONFLICT;
- }
-
- depth = ngx_http_dav_depth(r, NGX_HTTP_DAV_INFINITY_DEPTH);
-
- if (depth != NGX_HTTP_DAV_INFINITY_DEPTH) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "\"Depth\" header must be infinity");
- return NGX_HTTP_BAD_REQUEST;
- }
-
- path.len -= 2; /* omit "/\0" */
-
- dir = 1;
-
- } else {
-
- /*
- * we do not need to test (r->uri.data[r->uri.len - 1] == '/')
- * because ngx_link_info("/file/") returned NGX_ENOTDIR above
- */
-
- depth = ngx_http_dav_depth(r, 0);
-
- if (depth != 0 && depth != NGX_HTTP_DAV_INFINITY_DEPTH) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "\"Depth\" header must be 0 or infinity");
- return NGX_HTTP_BAD_REQUEST;
- }
-
- dir = 0;
- }
-
- rc = ngx_http_dav_delete_path(r, &path, dir);
-
- if (rc == NGX_OK) {
- return NGX_HTTP_NO_CONTENT;
- }
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_dav_delete_path(ngx_http_request_t *r, ngx_str_t *path, ngx_uint_t dir)
-{
- char *failed;
- ngx_tree_ctx_t tree;
-
- if (dir) {
-
- tree.init_handler = NULL;
- tree.file_handler = ngx_http_dav_delete_file;
- tree.pre_tree_handler = ngx_http_dav_noop;
- tree.post_tree_handler = ngx_http_dav_delete_dir;
- tree.spec_handler = ngx_http_dav_delete_file;
- tree.data = NULL;
- tree.alloc = 0;
- tree.log = r->connection->log;
-
- /* TODO: 207 */
-
- if (ngx_walk_tree(&tree, path) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_delete_dir(path->data) != NGX_FILE_ERROR) {
- return NGX_OK;
- }
-
- failed = ngx_delete_dir_n;
-
- } else {
-
- if (ngx_delete_file(path->data) != NGX_FILE_ERROR) {
- return NGX_OK;
- }
-
- failed = ngx_delete_file_n;
- }
-
- return ngx_http_dav_error(r->connection->log, ngx_errno,
- NGX_HTTP_NOT_FOUND, failed, path->data);
-}
-
-
-static ngx_int_t
-ngx_http_dav_delete_dir(ngx_tree_ctx_t *ctx, ngx_str_t *path)
-{
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
- "http delete dir: \"%s\"", path->data);
-
- if (ngx_delete_dir(path->data) == NGX_FILE_ERROR) {
-
- /* TODO: add to 207 */
-
- (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_delete_dir_n,
- path->data);
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_dav_delete_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
-{
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
- "http delete file: \"%s\"", path->data);
-
- if (ngx_delete_file(path->data) == NGX_FILE_ERROR) {
-
- /* TODO: add to 207 */
-
- (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_delete_file_n,
- path->data);
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_dav_noop(ngx_tree_ctx_t *ctx, ngx_str_t *path)
-{
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_dav_mkcol_handler(ngx_http_request_t *r, ngx_http_dav_loc_conf_t *dlcf)
-{
- u_char *p;
- size_t root;
- ngx_str_t path;
-
- if (r->headers_in.content_length_n > 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "MKCOL with body is unsupported");
- return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE;
- }
-
- if (r->uri.data[r->uri.len - 1] != '/') {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "MKCOL can create a collection only");
- return NGX_HTTP_CONFLICT;
- }
-
- p = ngx_http_map_uri_to_path(r, &path, &root, 0);
-
- *(p - 1) = '\0';
- r->uri.len--;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http mkcol path: \"%s\"", path.data);
-
- if (ngx_create_dir(path.data, ngx_dir_access(dlcf->access))
- != NGX_FILE_ERROR)
- {
- if (ngx_http_dav_location(r, path.data) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- return NGX_HTTP_CREATED;
- }
-
- return ngx_http_dav_error(r->connection->log, ngx_errno,
- NGX_HTTP_CONFLICT, ngx_create_dir_n, path.data);
-}
-
-
-static ngx_int_t
-ngx_http_dav_copy_move_handler(ngx_http_request_t *r)
-{
- u_char *p, *host, *last, ch;
- size_t len, root;
- ngx_err_t err;
- ngx_int_t rc, depth;
- ngx_uint_t overwrite, slash, dir, flags;
- ngx_str_t path, uri, duri, args;
- ngx_tree_ctx_t tree;
- ngx_copy_file_t cf;
- ngx_file_info_t fi;
- ngx_table_elt_t *dest, *over;
- ngx_ext_rename_file_t ext;
- ngx_http_dav_copy_ctx_t copy;
- ngx_http_dav_loc_conf_t *dlcf;
-
- if (r->headers_in.content_length_n > 0) {
- return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE;
- }
-
- dest = r->headers_in.destination;
-
- if (dest == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client sent no \"Destination\" header");
- return NGX_HTTP_BAD_REQUEST;
- }
-
- p = dest->value.data;
- /* there is always '\0' even after empty header value */
- if (p[0] == '/') {
- last = p + dest->value.len;
- goto destination_done;
- }
-
- len = r->headers_in.server.len;
-
- if (len == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client sent no \"Host\" header");
- return NGX_HTTP_BAD_REQUEST;
- }
-
-#if (NGX_HTTP_SSL)
-
- if (r->connection->ssl) {
- if (ngx_strncmp(dest->value.data, "https://", sizeof("https://") - 1)
- != 0)
- {
- goto invalid_destination;
- }
-
- host = dest->value.data + sizeof("https://") - 1;
-
- } else
-#endif
- {
- if (ngx_strncmp(dest->value.data, "http://", sizeof("http://") - 1)
- != 0)
- {
- goto invalid_destination;
- }
-
- host = dest->value.data + sizeof("http://") - 1;
- }
-
- if (ngx_strncmp(host, r->headers_in.server.data, len) != 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "\"Destination\" URI \"%V\" is handled by "
- "different repository than the source URI",
- &dest->value);
- return NGX_HTTP_BAD_REQUEST;
- }
-
- last = dest->value.data + dest->value.len;
-
- for (p = host + len; p < last; p++) {
- if (*p == '/') {
- goto destination_done;
- }
- }
-
-invalid_destination:
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client sent invalid \"Destination\" header: \"%V\"",
- &dest->value);
- return NGX_HTTP_BAD_REQUEST;
-
-destination_done:
-
- duri.len = last - p;
- duri.data = p;
- flags = NGX_HTTP_LOG_UNSAFE;
-
- if (ngx_http_parse_unsafe_uri(r, &duri, &args, &flags) != NGX_OK) {
- goto invalid_destination;
- }
-
- if ((r->uri.data[r->uri.len - 1] == '/' && *(last - 1) != '/')
- || (r->uri.data[r->uri.len - 1] != '/' && *(last - 1) == '/'))
- {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "both URI \"%V\" and \"Destination\" URI \"%V\" "
- "should be either collections or non-collections",
- &r->uri, &dest->value);
- return NGX_HTTP_CONFLICT;
- }
-
- depth = ngx_http_dav_depth(r, NGX_HTTP_DAV_INFINITY_DEPTH);
-
- if (depth != NGX_HTTP_DAV_INFINITY_DEPTH) {
-
- if (r->method == NGX_HTTP_COPY) {
- if (depth != 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "\"Depth\" header must be 0 or infinity");
- return NGX_HTTP_BAD_REQUEST;
- }
-
- } else {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "\"Depth\" header must be infinity");
- return NGX_HTTP_BAD_REQUEST;
- }
- }
-
- over = r->headers_in.overwrite;
-
- if (over) {
- if (over->value.len == 1) {
- ch = over->value.data[0];
-
- if (ch == 'T' || ch == 't') {
- overwrite = 1;
- goto overwrite_done;
- }
-
- if (ch == 'F' || ch == 'f') {
- overwrite = 0;
- goto overwrite_done;
- }
-
- }
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client sent invalid \"Overwrite\" header: \"%V\"",
- &over->value);
- return NGX_HTTP_BAD_REQUEST;
- }
-
- overwrite = 1;
-
-overwrite_done:
-
- ngx_http_map_uri_to_path(r, &path, &root, 0);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http copy from: \"%s\"", path.data);
-
- uri = r->uri;
- r->uri = duri;
-
- ngx_http_map_uri_to_path(r, &copy.path, &root, 0);
-
- r->uri = uri;
-
- copy.path.len--; /* omit "\0" */
-
- if (copy.path.data[copy.path.len - 1] == '/') {
- slash = 1;
- copy.path.len--;
- copy.path.data[copy.path.len] = '\0';
-
- } else {
- slash = 0;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http copy to: \"%s\"", copy.path.data);
-
- if (ngx_link_info(copy.path.data, &fi) == NGX_FILE_ERROR) {
- err = ngx_errno;
-
- if (err != NGX_ENOENT) {
- return ngx_http_dav_error(r->connection->log, err,
- NGX_HTTP_NOT_FOUND, ngx_link_info_n,
- copy.path.data);
- }
-
- /* destination does not exist */
-
- overwrite = 0;
- dir = 0;
-
- } else {
-
- /* destination exists */
-
- if (ngx_is_dir(&fi) && !slash) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "\"%V\" could not be %Ved to collection \"%V\"",
- &r->uri, &r->method_name, &dest->value);
- return NGX_HTTP_CONFLICT;
- }
-
- if (!overwrite) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_EEXIST,
- "\"%s\" could not be created", copy.path.data);
- return NGX_HTTP_PRECONDITION_FAILED;
- }
-
- dir = ngx_is_dir(&fi);
- }
-
- if (ngx_link_info(path.data, &fi) == NGX_FILE_ERROR) {
- return ngx_http_dav_error(r->connection->log, ngx_errno,
- NGX_HTTP_NOT_FOUND, ngx_link_info_n,
- path.data);
- }
-
- if (ngx_is_dir(&fi)) {
-
- if (r->uri.data[r->uri.len - 1] != '/') {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "\"%V\" is collection", &r->uri);
- return NGX_HTTP_BAD_REQUEST;
- }
-
- if (overwrite) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http delete: \"%s\"", copy.path.data);
-
- rc = ngx_http_dav_delete_path(r, &copy.path, dir);
-
- if (rc != NGX_OK) {
- return rc;
- }
- }
- }
-
- if (ngx_is_dir(&fi)) {
-
- path.len -= 2; /* omit "/\0" */
-
- if (r->method == NGX_HTTP_MOVE) {
- if (ngx_rename_file(path.data, copy.path.data) != NGX_FILE_ERROR) {
- return NGX_HTTP_CREATED;
- }
- }
-
- if (ngx_create_dir(copy.path.data, ngx_file_access(&fi))
- == NGX_FILE_ERROR)
- {
- return ngx_http_dav_error(r->connection->log, ngx_errno,
- NGX_HTTP_NOT_FOUND,
- ngx_create_dir_n, copy.path.data);
- }
-
- copy.len = path.len;
-
- tree.init_handler = NULL;
- tree.file_handler = ngx_http_dav_copy_tree_file;
- tree.pre_tree_handler = ngx_http_dav_copy_dir;
- tree.post_tree_handler = ngx_http_dav_copy_dir_time;
- tree.spec_handler = ngx_http_dav_noop;
- tree.data = &copy;
- tree.alloc = 0;
- tree.log = r->connection->log;
-
- if (ngx_walk_tree(&tree, &path) == NGX_OK) {
-
- if (r->method == NGX_HTTP_MOVE) {
- rc = ngx_http_dav_delete_path(r, &path, 1);
-
- if (rc != NGX_OK) {
- return rc;
- }
- }
-
- return NGX_HTTP_CREATED;
- }
-
- } else {
-
- if (r->method == NGX_HTTP_MOVE) {
-
- dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
-
- ext.access = 0;
- ext.path_access = dlcf->access;
- ext.time = -1;
- ext.create_path = 1;
- ext.delete_file = 0;
- ext.log = r->connection->log;
-
- if (ngx_ext_rename_file(&path, &copy.path, &ext) == NGX_OK) {
- return NGX_HTTP_NO_CONTENT;
- }
-
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
-
- cf.size = ngx_file_size(&fi);
- cf.buf_size = 0;
- cf.access = dlcf->access;
- cf.time = ngx_file_mtime(&fi);
- cf.log = r->connection->log;
-
- if (ngx_copy_file(path.data, copy.path.data, &cf) == NGX_OK) {
- return NGX_HTTP_NO_CONTENT;
- }
- }
-
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_dav_copy_dir(ngx_tree_ctx_t *ctx, ngx_str_t *path)
-{
- u_char *p, *dir;
- size_t len;
- ngx_http_dav_copy_ctx_t *copy;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
- "http copy dir: \"%s\"", path->data);
-
- copy = ctx->data;
-
- len = copy->path.len + path->len;
-
- dir = ngx_alloc(len + 1, ctx->log);
- if (dir == NULL) {
- return NGX_ABORT;
- }
-
- p = ngx_cpymem(dir, copy->path.data, copy->path.len);
- (void) ngx_cpystrn(p, path->data + copy->len, path->len - copy->len + 1);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
- "http copy dir to: \"%s\"", dir);
-
- if (ngx_create_dir(dir, ngx_dir_access(ctx->access)) == NGX_FILE_ERROR) {
- (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_create_dir_n,
- dir);
- }
-
- ngx_free(dir);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_dav_copy_dir_time(ngx_tree_ctx_t *ctx, ngx_str_t *path)
-{
- u_char *p, *dir;
- size_t len;
- ngx_http_dav_copy_ctx_t *copy;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
- "http copy dir time: \"%s\"", path->data);
-
- copy = ctx->data;
-
- len = copy->path.len + path->len;
-
- dir = ngx_alloc(len + 1, ctx->log);
- if (dir == NULL) {
- return NGX_ABORT;
- }
-
- p = ngx_cpymem(dir, copy->path.data, copy->path.len);
- (void) ngx_cpystrn(p, path->data + copy->len, path->len - copy->len + 1);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
- "http copy dir time to: \"%s\"", dir);
-
-#if (NGX_WIN32)
- {
- ngx_fd_t fd;
-
- fd = ngx_open_file(dir, NGX_FILE_RDWR, NGX_FILE_OPEN, 0);
-
- if (fd == NGX_INVALID_FILE) {
- (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_open_file_n, dir);
- goto failed;
- }
-
- if (ngx_set_file_time(NULL, fd, ctx->mtime) != NGX_OK) {
- ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
- ngx_set_file_time_n " \"%s\" failed", dir);
- }
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", dir);
- }
- }
-
-failed:
-
-#else
-
- if (ngx_set_file_time(dir, 0, ctx->mtime) != NGX_OK) {
- ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
- ngx_set_file_time_n " \"%s\" failed", dir);
- }
-
-#endif
-
- ngx_free(dir);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
-{
- u_char *p, *file;
- size_t len;
- ngx_copy_file_t cf;
- ngx_http_dav_copy_ctx_t *copy;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
- "http copy file: \"%s\"", path->data);
-
- copy = ctx->data;
-
- len = copy->path.len + path->len;
-
- file = ngx_alloc(len + 1, ctx->log);
- if (file == NULL) {
- return NGX_ABORT;
- }
-
- p = ngx_cpymem(file, copy->path.data, copy->path.len);
- (void) ngx_cpystrn(p, path->data + copy->len, path->len - copy->len + 1);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
- "http copy file to: \"%s\"", file);
-
- cf.size = ctx->size;
- cf.buf_size = 0;
- cf.access = ctx->access;
- cf.time = ctx->mtime;
- cf.log = ctx->log;
-
- (void) ngx_copy_file(path->data, file, &cf);
-
- ngx_free(file);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt)
-{
- ngx_table_elt_t *depth;
-
- depth = r->headers_in.depth;
-
- if (depth == NULL) {
- return dflt;
- }
-
- if (depth->value.len == 1) {
-
- if (depth->value.data[0] == '0') {
- return 0;
- }
-
- if (depth->value.data[0] == '1') {
- return 1;
- }
-
- } else {
-
- if (depth->value.len == sizeof("infinity") - 1
- && ngx_strcmp(depth->value.data, "infinity") == 0)
- {
- return NGX_HTTP_DAV_INFINITY_DEPTH;
- }
- }
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client sent invalid \"Depth\" header: \"%V\"",
- &depth->value);
-
- return NGX_HTTP_DAV_INVALID_DEPTH;
-}
-
-
-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)
-{
- ngx_int_t rc;
- ngx_uint_t level;
-
- if (err == NGX_ENOENT || err == NGX_ENOTDIR || err == NGX_ENAMETOOLONG) {
- level = NGX_LOG_ERR;
- rc = not_found;
-
- } else if (err == NGX_EACCES || err == NGX_EPERM) {
- level = NGX_LOG_ERR;
- rc = NGX_HTTP_FORBIDDEN;
-
- } else if (err == NGX_EEXIST) {
- level = NGX_LOG_ERR;
- rc = NGX_HTTP_NOT_ALLOWED;
-
- } else if (err == NGX_ENOSPC) {
- level = NGX_LOG_CRIT;
- rc = NGX_HTTP_INSUFFICIENT_STORAGE;
-
- } else {
- level = NGX_LOG_CRIT;
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ngx_log_error(level, log, err, "%s \"%s\" failed", failed, path);
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_dav_location(ngx_http_request_t *r, u_char *path)
-{
- u_char *location;
- ngx_http_core_loc_conf_t *clcf;
-
- r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t));
- if (r->headers_out.location == NULL) {
- return NGX_ERROR;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (!clcf->alias && clcf->root_lengths == NULL) {
- location = path + clcf->root.len;
-
- } else {
- location = ngx_pnalloc(r->pool, r->uri.len);
- if (location == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(location, r->uri.data, r->uri.len);
- }
-
- /*
- * we do not need to set the r->headers_out.location->hash and
- * r->headers_out.location->key fields
- */
-
- r->headers_out.location->value.len = r->uri.len;
- r->headers_out.location->value.data = location;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_dav_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_dav_loc_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_dav_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->methods = 0;
- */
-
- conf->min_delete_depth = NGX_CONF_UNSET_UINT;
- conf->access = NGX_CONF_UNSET_UINT;
- conf->create_full_put_path = NGX_CONF_UNSET;
-
- return conf;
-}
-
-
-static char *
-ngx_http_dav_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_dav_loc_conf_t *prev = parent;
- ngx_http_dav_loc_conf_t *conf = child;
-
- ngx_conf_merge_bitmask_value(conf->methods, prev->methods,
- (NGX_CONF_BITMASK_SET|NGX_HTTP_DAV_OFF));
-
- ngx_conf_merge_uint_value(conf->min_delete_depth,
- prev->min_delete_depth, 0);
-
- ngx_conf_merge_uint_value(conf->access, prev->access, 0600);
-
- ngx_conf_merge_value(conf->create_full_put_path,
- prev->create_full_put_path, 0);
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_dav_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_dav_handler;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_degradation_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_degradation_module.c
deleted file mode 100644
index b9c65cdc9e0..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_degradation_module.c
+++ /dev/null
@@ -1,243 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- size_t sbrk_size;
-} ngx_http_degradation_main_conf_t;
-
-
-typedef struct {
- ngx_uint_t degrade;
-} ngx_http_degradation_loc_conf_t;
-
-
-static ngx_conf_enum_t ngx_http_degrade[] = {
- { ngx_string("204"), 204 },
- { ngx_string("444"), 444 },
- { ngx_null_string, 0 }
-};
-
-
-static void *ngx_http_degradation_create_main_conf(ngx_conf_t *cf);
-static void *ngx_http_degradation_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_degradation_merge_loc_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static char *ngx_http_degradation(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static ngx_int_t ngx_http_degradation_init(ngx_conf_t *cf);
-
-
-static ngx_command_t ngx_http_degradation_commands[] = {
-
- { ngx_string("degradation"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_http_degradation,
- NGX_HTTP_MAIN_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("degrade"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_degradation_loc_conf_t, degrade),
- &ngx_http_degrade },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_degradation_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_degradation_init, /* postconfiguration */
-
- ngx_http_degradation_create_main_conf, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_degradation_create_loc_conf, /* create location configuration */
- ngx_http_degradation_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_degradation_module = {
- NGX_MODULE_V1,
- &ngx_http_degradation_module_ctx, /* module context */
- ngx_http_degradation_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_degradation_handler(ngx_http_request_t *r)
-{
- ngx_http_degradation_loc_conf_t *dlcf;
-
- dlcf = ngx_http_get_module_loc_conf(r, ngx_http_degradation_module);
-
- if (dlcf->degrade && ngx_http_degraded(r)) {
- return dlcf->degrade;
- }
-
- return NGX_DECLINED;
-}
-
-
-ngx_uint_t
-ngx_http_degraded(ngx_http_request_t *r)
-{
- time_t now;
- ngx_uint_t log;
- static size_t sbrk_size;
- static time_t sbrk_time;
- ngx_http_degradation_main_conf_t *dmcf;
-
- dmcf = ngx_http_get_module_main_conf(r, ngx_http_degradation_module);
-
- if (dmcf->sbrk_size) {
-
- log = 0;
- now = ngx_time();
-
- /* lock mutex */
-
- if (now != sbrk_time) {
-
- /*
- * ELF/i386 is loaded at 0x08000000, 128M
- * ELF/amd64 is loaded at 0x00400000, 4M
- *
- * use a function address to subtract the loading address
- */
-
- sbrk_size = (size_t) sbrk(0) - ((uintptr_t) ngx_palloc & ~0x3FFFFF);
- sbrk_time = now;
- log = 1;
- }
-
- /* unlock mutex */
-
- if (sbrk_size >= dmcf->sbrk_size) {
- if (log) {
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "degradation sbrk:%uzM",
- sbrk_size / (1024 * 1024));
- }
-
- return 1;
- }
- }
-
- return 0;
-}
-
-
-static void *
-ngx_http_degradation_create_main_conf(ngx_conf_t *cf)
-{
- ngx_http_degradation_main_conf_t *dmcf;
-
- dmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_degradation_main_conf_t));
- if (dmcf == NULL) {
- return NULL;
- }
-
- return dmcf;
-}
-
-
-static void *
-ngx_http_degradation_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_degradation_loc_conf_t *conf;
-
- conf = ngx_palloc(cf->pool, sizeof(ngx_http_degradation_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- conf->degrade = NGX_CONF_UNSET_UINT;
-
- return conf;
-}
-
-
-static char *
-ngx_http_degradation_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_degradation_loc_conf_t *prev = parent;
- ngx_http_degradation_loc_conf_t *conf = child;
-
- ngx_conf_merge_uint_value(conf->degrade, prev->degrade, 0);
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_degradation(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_degradation_main_conf_t *dmcf = conf;
-
- ngx_str_t *value, s;
-
- value = cf->args->elts;
-
- if (ngx_strncmp(value[1].data, "sbrk=", 5) == 0) {
-
- s.len = value[1].len - 5;
- s.data = value[1].data + 5;
-
- dmcf->sbrk_size = ngx_parse_size(&s);
- if (dmcf->sbrk_size == (size_t) NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid sbrk size \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[1]);
-
- return NGX_CONF_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_degradation_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_degradation_handler;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_empty_gif_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_empty_gif_module.c
deleted file mode 100644
index 04114dc3f41..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_empty_gif_module.c
+++ /dev/null
@@ -1,140 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static char *ngx_http_empty_gif(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-static ngx_command_t ngx_http_empty_gif_commands[] = {
-
- { ngx_string("empty_gif"),
- NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
- ngx_http_empty_gif,
- 0,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-/* the minimal single pixel transparent GIF, 43 bytes */
-
-static u_char ngx_empty_gif[] = {
-
- 'G', 'I', 'F', '8', '9', 'a', /* header */
-
- /* logical screen descriptor */
- 0x01, 0x00, /* logical screen width */
- 0x01, 0x00, /* logical screen height */
- 0x80, /* global 1-bit color table */
- 0x01, /* background color #1 */
- 0x00, /* no aspect ratio */
-
- /* global color table */
- 0x00, 0x00, 0x00, /* #0: black */
- 0xff, 0xff, 0xff, /* #1: white */
-
- /* graphic control extension */
- 0x21, /* extension introducer */
- 0xf9, /* graphic control label */
- 0x04, /* block size */
- 0x01, /* transparent color is given, */
- /* no disposal specified, */
- /* user input is not expected */
- 0x00, 0x00, /* delay time */
- 0x01, /* transparent color #1 */
- 0x00, /* block terminator */
-
- /* image descriptor */
- 0x2c, /* image separator */
- 0x00, 0x00, /* image left position */
- 0x00, 0x00, /* image top position */
- 0x01, 0x00, /* image width */
- 0x01, 0x00, /* image height */
- 0x00, /* no local color table, no interlaced */
-
- /* table based image data */
- 0x02, /* LZW minimum code size, */
- /* must be at least 2-bit */
- 0x02, /* block size */
- 0x4c, 0x01, /* compressed bytes 01_001_100, 0000000_1 */
- /* 100: clear code */
- /* 001: 1 */
- /* 101: end of information code */
- 0x00, /* block terminator */
-
- 0x3B /* trailer */
-};
-
-
-static ngx_http_module_t ngx_http_empty_gif_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_empty_gif_module = {
- NGX_MODULE_V1,
- &ngx_http_empty_gif_module_ctx, /* module context */
- ngx_http_empty_gif_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_str_t ngx_http_gif_type = ngx_string("image/gif");
-
-
-static ngx_int_t
-ngx_http_empty_gif_handler(ngx_http_request_t *r)
-{
- ngx_http_complex_value_t cv;
-
- if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
- return NGX_HTTP_NOT_ALLOWED;
- }
-
- ngx_memzero(&cv, sizeof(ngx_http_complex_value_t));
-
- cv.value.len = sizeof(ngx_empty_gif);
- cv.value.data = ngx_empty_gif;
- r->headers_out.last_modified_time = 23349600;
-
- return ngx_http_send_response(r, NGX_HTTP_OK, &ngx_http_gif_type, &cv);
-}
-
-
-static char *
-ngx_http_empty_gif(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
- clcf->handler = ngx_http_empty_gif_handler;
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_fastcgi_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_fastcgi_module.c
deleted file mode 100644
index 80cd1a220a6..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_fastcgi_module.c
+++ /dev/null
@@ -1,3279 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_http_upstream_conf_t upstream;
-
- ngx_str_t index;
-
- ngx_array_t *flushes;
- ngx_array_t *params_len;
- ngx_array_t *params;
- ngx_array_t *params_source;
- ngx_array_t *catch_stderr;
-
- ngx_array_t *fastcgi_lengths;
- ngx_array_t *fastcgi_values;
-
- ngx_hash_t headers_hash;
- ngx_uint_t header_params;
-
- ngx_flag_t keep_conn;
-
-#if (NGX_HTTP_CACHE)
- ngx_http_complex_value_t cache_key;
-#endif
-
-#if (NGX_PCRE)
- ngx_regex_t *split_regex;
- ngx_str_t split_name;
-#endif
-} ngx_http_fastcgi_loc_conf_t;
-
-
-typedef enum {
- ngx_http_fastcgi_st_version = 0,
- ngx_http_fastcgi_st_type,
- ngx_http_fastcgi_st_request_id_hi,
- ngx_http_fastcgi_st_request_id_lo,
- ngx_http_fastcgi_st_content_length_hi,
- ngx_http_fastcgi_st_content_length_lo,
- ngx_http_fastcgi_st_padding_length,
- ngx_http_fastcgi_st_reserved,
- ngx_http_fastcgi_st_data,
- ngx_http_fastcgi_st_padding
-} 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;
- u_char *last;
- ngx_uint_t type;
- size_t length;
- size_t padding;
-
- unsigned fastcgi_stdout:1;
- unsigned large_stderr:1;
-
- ngx_array_t *split_parts;
-
- ngx_str_t script_name;
- ngx_str_t path_info;
-} ngx_http_fastcgi_ctx_t;
-
-
-#define NGX_HTTP_FASTCGI_RESPONDER 1
-
-#define NGX_HTTP_FASTCGI_KEEP_CONN 1
-
-#define NGX_HTTP_FASTCGI_BEGIN_REQUEST 1
-#define NGX_HTTP_FASTCGI_ABORT_REQUEST 2
-#define NGX_HTTP_FASTCGI_END_REQUEST 3
-#define NGX_HTTP_FASTCGI_PARAMS 4
-#define NGX_HTTP_FASTCGI_STDIN 5
-#define NGX_HTTP_FASTCGI_STDOUT 6
-#define NGX_HTTP_FASTCGI_STDERR 7
-#define NGX_HTTP_FASTCGI_DATA 8
-
-
-typedef struct {
- u_char version;
- u_char type;
- u_char request_id_hi;
- u_char request_id_lo;
- u_char content_length_hi;
- u_char content_length_lo;
- u_char padding_length;
- u_char reserved;
-} ngx_http_fastcgi_header_t;
-
-
-typedef struct {
- u_char role_hi;
- u_char role_lo;
- u_char flags;
- u_char reserved[5];
-} ngx_http_fastcgi_begin_request_t;
-
-
-typedef struct {
- u_char version;
- u_char type;
- u_char request_id_hi;
- u_char request_id_lo;
-} ngx_http_fastcgi_header_small_t;
-
-
-typedef struct {
- ngx_http_fastcgi_header_t h0;
- ngx_http_fastcgi_begin_request_t br;
- ngx_http_fastcgi_header_small_t h1;
-} ngx_http_fastcgi_request_start_t;
-
-
-static ngx_int_t ngx_http_fastcgi_eval(ngx_http_request_t *r,
- ngx_http_fastcgi_loc_conf_t *flcf);
-#if (NGX_HTTP_CACHE)
-static ngx_int_t ngx_http_fastcgi_create_key(ngx_http_request_t *r);
-#endif
-static ngx_int_t ngx_http_fastcgi_create_request(ngx_http_request_t *r);
-static ngx_int_t ngx_http_fastcgi_reinit_request(ngx_http_request_t *r);
-static ngx_int_t ngx_http_fastcgi_process_header(ngx_http_request_t *r);
-static ngx_int_t ngx_http_fastcgi_input_filter_init(void *data);
-static ngx_int_t ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p,
- ngx_buf_t *buf);
-static ngx_int_t ngx_http_fastcgi_non_buffered_filter(void *data,
- ssize_t bytes);
-static ngx_int_t ngx_http_fastcgi_process_record(ngx_http_request_t *r,
- ngx_http_fastcgi_ctx_t *f);
-static void ngx_http_fastcgi_abort_request(ngx_http_request_t *r);
-static void ngx_http_fastcgi_finalize_request(ngx_http_request_t *r,
- ngx_int_t rc);
-
-static ngx_int_t ngx_http_fastcgi_add_variables(ngx_conf_t *cf);
-static void *ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static ngx_int_t ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
- ngx_http_fastcgi_loc_conf_t *conf, ngx_http_fastcgi_loc_conf_t *prev);
-
-static ngx_int_t ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_fastcgi_path_info_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_http_fastcgi_ctx_t *ngx_http_fastcgi_split(ngx_http_request_t *r,
- ngx_http_fastcgi_loc_conf_t *flcf);
-
-static char *ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_fastcgi_split_path_info(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);
-#if (NGX_HTTP_CACHE)
-static char *ngx_http_fastcgi_cache(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_fastcgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-#endif
-
-static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post,
- void *data);
-
-
-static ngx_conf_post_t ngx_http_fastcgi_lowat_post =
- { ngx_http_fastcgi_lowat_check };
-
-
-static ngx_conf_bitmask_t ngx_http_fastcgi_next_upstream_masks[] = {
- { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
- { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
- { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
- { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
- { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
- { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
- { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
- { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
- { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
- { ngx_null_string, 0 }
-};
-
-
-ngx_module_t ngx_http_fastcgi_module;
-
-
-static ngx_command_t ngx_http_fastcgi_commands[] = {
-
- { ngx_string("fastcgi_pass"),
- NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
- ngx_http_fastcgi_pass,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("fastcgi_index"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, index),
- NULL },
-
- { ngx_string("fastcgi_split_path_info"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_fastcgi_split_path_info,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- 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_buffering"),
- 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_fastcgi_loc_conf_t, upstream.buffering),
- 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,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.ignore_client_abort),
- NULL },
-
- { ngx_string("fastcgi_bind"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_upstream_bind_set_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.local),
- NULL },
-
- { ngx_string("fastcgi_connect_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.connect_timeout),
- NULL },
-
- { ngx_string("fastcgi_send_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.send_timeout),
- NULL },
-
- { ngx_string("fastcgi_send_lowat"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.send_lowat),
- &ngx_http_fastcgi_lowat_post },
-
- { ngx_string("fastcgi_buffer_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.buffer_size),
- NULL },
-
- { ngx_string("fastcgi_pass_request_headers"),
- 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_fastcgi_loc_conf_t, upstream.pass_request_headers),
- NULL },
-
- { ngx_string("fastcgi_pass_request_body"),
- 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_fastcgi_loc_conf_t, upstream.pass_request_body),
- NULL },
-
- { ngx_string("fastcgi_intercept_errors"),
- 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_fastcgi_loc_conf_t, upstream.intercept_errors),
- NULL },
-
- { ngx_string("fastcgi_read_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.read_timeout),
- NULL },
-
- { ngx_string("fastcgi_buffers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_conf_set_bufs_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.bufs),
- NULL },
-
- { ngx_string("fastcgi_busy_buffers_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.busy_buffers_size_conf),
- NULL },
-
-#if (NGX_HTTP_CACHE)
-
- { ngx_string("fastcgi_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_fastcgi_cache,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("fastcgi_cache_key"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_fastcgi_cache_key,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("fastcgi_cache_path"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE,
- ngx_http_file_cache_set_slot,
- 0,
- 0,
- &ngx_http_fastcgi_module },
-
- { ngx_string("fastcgi_cache_bypass"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_set_predicate_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_bypass),
- NULL },
-
- { ngx_string("fastcgi_no_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_set_predicate_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.no_cache),
- NULL },
-
- { ngx_string("fastcgi_cache_valid"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_file_cache_valid_set_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_valid),
- NULL },
-
- { ngx_string("fastcgi_cache_min_uses"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_min_uses),
- NULL },
-
- { ngx_string("fastcgi_cache_use_stale"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_use_stale),
- &ngx_http_fastcgi_next_upstream_masks },
-
- { ngx_string("fastcgi_cache_methods"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_methods),
- &ngx_http_upstream_cache_method_mask },
-
- { ngx_string("fastcgi_cache_lock"),
- 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_fastcgi_loc_conf_t, upstream.cache_lock),
- NULL },
-
- { ngx_string("fastcgi_cache_lock_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_lock_timeout),
- NULL },
-
- { ngx_string("fastcgi_cache_revalidate"),
- 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_fastcgi_loc_conf_t, upstream.cache_revalidate),
- NULL },
-
-#endif
-
- { ngx_string("fastcgi_temp_path"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
- ngx_conf_set_path_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.temp_path),
- NULL },
-
- { ngx_string("fastcgi_max_temp_file_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.max_temp_file_size_conf),
- NULL },
-
- { ngx_string("fastcgi_temp_file_write_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.temp_file_write_size_conf),
- NULL },
-
- { ngx_string("fastcgi_next_upstream"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream),
- &ngx_http_fastcgi_next_upstream_masks },
-
- { ngx_string("fastcgi_param"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
- ngx_http_upstream_param_set_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, params_source),
- NULL },
-
- { ngx_string("fastcgi_pass_header"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_array_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.pass_headers),
- NULL },
-
- { ngx_string("fastcgi_hide_header"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_array_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.hide_headers),
- NULL },
-
- { ngx_string("fastcgi_ignore_headers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.ignore_headers),
- &ngx_http_upstream_ignore_headers_masks },
-
- { ngx_string("fastcgi_catch_stderr"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_array_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, catch_stderr),
- NULL },
-
- { ngx_string("fastcgi_keep_conn"),
- 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_fastcgi_loc_conf_t, keep_conn),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_fastcgi_module_ctx = {
- ngx_http_fastcgi_add_variables, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_fastcgi_create_loc_conf, /* create location configuration */
- ngx_http_fastcgi_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_fastcgi_module = {
- NGX_MODULE_V1,
- &ngx_http_fastcgi_module_ctx, /* module context */
- ngx_http_fastcgi_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_fastcgi_request_start_t ngx_http_fastcgi_request_start = {
- { 1, /* version */
- NGX_HTTP_FASTCGI_BEGIN_REQUEST, /* type */
- 0, /* request_id_hi */
- 1, /* request_id_lo */
- 0, /* content_length_hi */
- sizeof(ngx_http_fastcgi_begin_request_t), /* content_length_lo */
- 0, /* padding_length */
- 0 }, /* reserved */
-
- { 0, /* role_hi */
- NGX_HTTP_FASTCGI_RESPONDER, /* role_lo */
- 0, /* NGX_HTTP_FASTCGI_KEEP_CONN */ /* flags */
- { 0, 0, 0, 0, 0 } }, /* reserved[5] */
-
- { 1, /* version */
- NGX_HTTP_FASTCGI_PARAMS, /* type */
- 0, /* request_id_hi */
- 1 }, /* request_id_lo */
-
-};
-
-
-static ngx_http_variable_t ngx_http_fastcgi_vars[] = {
-
- { ngx_string("fastcgi_script_name"), NULL,
- ngx_http_fastcgi_script_name_variable, 0,
- NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
-
- { ngx_string("fastcgi_path_info"), NULL,
- ngx_http_fastcgi_path_info_variable, 0,
- NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
-
- { ngx_null_string, NULL, NULL, 0, 0, 0 }
-};
-
-
-static ngx_str_t ngx_http_fastcgi_hide_headers[] = {
- ngx_string("Status"),
- ngx_string("X-Accel-Expires"),
- ngx_string("X-Accel-Redirect"),
- ngx_string("X-Accel-Limit-Rate"),
- ngx_string("X-Accel-Buffering"),
- ngx_string("X-Accel-Charset"),
- ngx_null_string
-};
-
-
-#if (NGX_HTTP_CACHE)
-
-static ngx_keyval_t ngx_http_fastcgi_cache_headers[] = {
- { ngx_string("HTTP_IF_MODIFIED_SINCE"),
- ngx_string("$upstream_cache_last_modified") },
- { ngx_string("HTTP_IF_UNMODIFIED_SINCE"), ngx_string("") },
- { ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("") },
- { ngx_string("HTTP_IF_MATCH"), ngx_string("") },
- { ngx_string("HTTP_RANGE"), ngx_string("") },
- { ngx_string("HTTP_IF_RANGE"), ngx_string("") },
- { ngx_null_string, ngx_null_string }
-};
-
-#endif
-
-
-static ngx_path_init_t ngx_http_fastcgi_temp_path = {
- ngx_string(NGX_HTTP_FASTCGI_TEMP_PATH), { 1, 2, 0 }
-};
-
-
-static ngx_int_t
-ngx_http_fastcgi_handler(ngx_http_request_t *r)
-{
- ngx_int_t rc;
- ngx_http_upstream_t *u;
- ngx_http_fastcgi_ctx_t *f;
- ngx_http_fastcgi_loc_conf_t *flcf;
-
- if (ngx_http_upstream_create(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
- if (f == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
-
- flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
-
- if (flcf->fastcgi_lengths) {
- if (ngx_http_fastcgi_eval(r, flcf) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
- }
-
- u = r->upstream;
-
- ngx_str_set(&u->schema, "fastcgi://");
- u->output.tag = (ngx_buf_tag_t) &ngx_http_fastcgi_module;
-
- u->conf = &flcf->upstream;
-
-#if (NGX_HTTP_CACHE)
- u->create_key = ngx_http_fastcgi_create_key;
-#endif
- u->create_request = ngx_http_fastcgi_create_request;
- u->reinit_request = ngx_http_fastcgi_reinit_request;
- u->process_header = ngx_http_fastcgi_process_header;
- u->abort_request = ngx_http_fastcgi_abort_request;
- u->finalize_request = ngx_http_fastcgi_finalize_request;
- r->state = 0;
-
- u->buffering = flcf->upstream.buffering;
-
- u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
- if (u->pipe == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- u->pipe->input_filter = ngx_http_fastcgi_input_filter;
- u->pipe->input_ctx = r;
-
- u->input_filter_init = ngx_http_fastcgi_input_filter_init;
- u->input_filter = ngx_http_fastcgi_non_buffered_filter;
- u->input_filter_ctx = r;
-
- rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init);
-
- if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
- return rc;
- }
-
- return NGX_DONE;
-}
-
-
-static ngx_int_t
-ngx_http_fastcgi_eval(ngx_http_request_t *r, ngx_http_fastcgi_loc_conf_t *flcf)
-{
- ngx_url_t url;
- ngx_http_upstream_t *u;
-
- ngx_memzero(&url, sizeof(ngx_url_t));
-
- if (ngx_http_script_run(r, &url.url, flcf->fastcgi_lengths->elts, 0,
- flcf->fastcgi_values->elts)
- == NULL)
- {
- return NGX_ERROR;
- }
-
- url.no_resolve = 1;
-
- if (ngx_parse_url(r->pool, &url) != NGX_OK) {
- if (url.err) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "%s in upstream \"%V\"", url.err, &url.url);
- }
-
- return NGX_ERROR;
- }
-
- u = r->upstream;
-
- u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
- if (u->resolved == NULL) {
- return NGX_ERROR;
- }
-
- if (url.addrs && url.addrs[0].sockaddr) {
- u->resolved->sockaddr = url.addrs[0].sockaddr;
- u->resolved->socklen = url.addrs[0].socklen;
- u->resolved->naddrs = 1;
- u->resolved->host = url.addrs[0].name;
-
- } else {
- u->resolved->host = url.host;
- u->resolved->port = url.port;
- u->resolved->no_port = url.no_port;
- }
-
- return NGX_OK;
-}
-
-
-#if (NGX_HTTP_CACHE)
-
-static ngx_int_t
-ngx_http_fastcgi_create_key(ngx_http_request_t *r)
-{
- ngx_str_t *key;
- ngx_http_fastcgi_loc_conf_t *flcf;
-
- key = ngx_array_push(&r->cache->keys);
- if (key == NULL) {
- return NGX_ERROR;
- }
-
- flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
-
- if (ngx_http_complex_value(r, &flcf->cache_key, key) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_fastcgi_create_request(ngx_http_request_t *r)
-{
- off_t file_pos;
- u_char ch, *pos, *lowcase_key;
- size_t size, len, key_len, val_len, padding,
- allocated;
- ngx_uint_t i, n, next, hash, skip_empty, header_params;
- ngx_buf_t *b;
- ngx_chain_t *cl, *body;
- ngx_list_part_t *part;
- ngx_table_elt_t *header, **ignored;
- ngx_http_script_code_pt code;
- ngx_http_script_engine_t e, le;
- ngx_http_fastcgi_header_t *h;
- ngx_http_fastcgi_loc_conf_t *flcf;
- ngx_http_script_len_code_pt lcode;
-
- len = 0;
- header_params = 0;
- ignored = NULL;
-
- flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
-
- if (flcf->params_len) {
- ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
-
- ngx_http_script_flush_no_cacheable_variables(r, flcf->flushes);
- le.flushed = 1;
-
- le.ip = flcf->params_len->elts;
- le.request = r;
-
- while (*(uintptr_t *) le.ip) {
-
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- key_len = lcode(&le);
-
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- skip_empty = lcode(&le);
-
- for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- }
- le.ip += sizeof(uintptr_t);
-
- if (skip_empty && val_len == 0) {
- continue;
- }
-
- len += 1 + key_len + ((val_len > 127) ? 4 : 1) + val_len;
- }
- }
-
- if (flcf->upstream.pass_request_headers) {
-
- allocated = 0;
- lowcase_key = NULL;
-
- if (flcf->header_params) {
- n = 0;
- part = &r->headers_in.headers.part;
-
- while (part) {
- n += part->nelts;
- part = part->next;
- }
-
- ignored = ngx_palloc(r->pool, n * sizeof(void *));
- if (ignored == NULL) {
- return NGX_ERROR;
- }
- }
-
- part = &r->headers_in.headers.part;
- header = part->elts;
-
- for (i = 0; /* void */; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- if (flcf->header_params) {
- if (allocated < header[i].key.len) {
- allocated = header[i].key.len + 16;
- lowcase_key = ngx_pnalloc(r->pool, allocated);
- if (lowcase_key == NULL) {
- return NGX_ERROR;
- }
- }
-
- hash = 0;
-
- for (n = 0; n < header[i].key.len; n++) {
- ch = header[i].key.data[n];
-
- if (ch >= 'A' && ch <= 'Z') {
- ch |= 0x20;
-
- } else if (ch == '-') {
- ch = '_';
- }
-
- hash = ngx_hash(hash, ch);
- lowcase_key[n] = ch;
- }
-
- if (ngx_hash_find(&flcf->headers_hash, hash, lowcase_key, n)) {
- ignored[header_params++] = &header[i];
- continue;
- }
-
- n += sizeof("HTTP_") - 1;
-
- } else {
- n = sizeof("HTTP_") - 1 + header[i].key.len;
- }
-
- len += ((n > 127) ? 4 : 1) + ((header[i].value.len > 127) ? 4 : 1)
- + n + header[i].value.len;
- }
- }
-
-
- if (len > 65535) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "fastcgi request record is too big: %uz", len);
- return NGX_ERROR;
- }
-
-
- padding = 8 - len % 8;
- padding = (padding == 8) ? 0 : padding;
-
-
- size = sizeof(ngx_http_fastcgi_header_t)
- + sizeof(ngx_http_fastcgi_begin_request_t)
-
- + sizeof(ngx_http_fastcgi_header_t) /* NGX_HTTP_FASTCGI_PARAMS */
- + len + padding
- + sizeof(ngx_http_fastcgi_header_t) /* NGX_HTTP_FASTCGI_PARAMS */
-
- + sizeof(ngx_http_fastcgi_header_t); /* NGX_HTTP_FASTCGI_STDIN */
-
-
- b = ngx_create_temp_buf(r->pool, size);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
-
- ngx_http_fastcgi_request_start.br.flags =
- flcf->keep_conn ? NGX_HTTP_FASTCGI_KEEP_CONN : 0;
-
- ngx_memcpy(b->pos, &ngx_http_fastcgi_request_start,
- sizeof(ngx_http_fastcgi_request_start_t));
-
- h = (ngx_http_fastcgi_header_t *)
- (b->pos + sizeof(ngx_http_fastcgi_header_t)
- + sizeof(ngx_http_fastcgi_begin_request_t));
-
- h->content_length_hi = (u_char) ((len >> 8) & 0xff);
- h->content_length_lo = (u_char) (len & 0xff);
- h->padding_length = (u_char) padding;
- h->reserved = 0;
-
- b->last = b->pos + sizeof(ngx_http_fastcgi_header_t)
- + sizeof(ngx_http_fastcgi_begin_request_t)
- + sizeof(ngx_http_fastcgi_header_t);
-
-
- if (flcf->params_len) {
- ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
-
- e.ip = flcf->params->elts;
- e.pos = b->last;
- e.request = r;
- e.flushed = 1;
-
- le.ip = flcf->params_len->elts;
-
- while (*(uintptr_t *) le.ip) {
-
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- key_len = (u_char) lcode(&le);
-
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- skip_empty = lcode(&le);
-
- for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- }
- le.ip += sizeof(uintptr_t);
-
- if (skip_empty && val_len == 0) {
- e.skip = 1;
-
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
- }
- e.ip += sizeof(uintptr_t);
-
- e.skip = 0;
-
- continue;
- }
-
- *e.pos++ = (u_char) key_len;
-
- if (val_len > 127) {
- *e.pos++ = (u_char) (((val_len >> 24) & 0x7f) | 0x80);
- *e.pos++ = (u_char) ((val_len >> 16) & 0xff);
- *e.pos++ = (u_char) ((val_len >> 8) & 0xff);
- *e.pos++ = (u_char) (val_len & 0xff);
-
- } else {
- *e.pos++ = (u_char) val_len;
- }
-
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
- }
- e.ip += sizeof(uintptr_t);
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "fastcgi param: \"%*s: %*s\"",
- key_len, e.pos - (key_len + val_len),
- val_len, e.pos - val_len);
- }
-
- b->last = e.pos;
- }
-
-
- if (flcf->upstream.pass_request_headers) {
-
- part = &r->headers_in.headers.part;
- header = part->elts;
-
- for (i = 0; /* void */; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- for (n = 0; n < header_params; n++) {
- if (&header[i] == ignored[n]) {
- goto next;
- }
- }
-
- key_len = sizeof("HTTP_") - 1 + header[i].key.len;
- if (key_len > 127) {
- *b->last++ = (u_char) (((key_len >> 24) & 0x7f) | 0x80);
- *b->last++ = (u_char) ((key_len >> 16) & 0xff);
- *b->last++ = (u_char) ((key_len >> 8) & 0xff);
- *b->last++ = (u_char) (key_len & 0xff);
-
- } else {
- *b->last++ = (u_char) key_len;
- }
-
- val_len = header[i].value.len;
- if (val_len > 127) {
- *b->last++ = (u_char) (((val_len >> 24) & 0x7f) | 0x80);
- *b->last++ = (u_char) ((val_len >> 16) & 0xff);
- *b->last++ = (u_char) ((val_len >> 8) & 0xff);
- *b->last++ = (u_char) (val_len & 0xff);
-
- } else {
- *b->last++ = (u_char) val_len;
- }
-
- b->last = ngx_cpymem(b->last, "HTTP_", sizeof("HTTP_") - 1);
-
- for (n = 0; n < header[i].key.len; n++) {
- ch = header[i].key.data[n];
-
- if (ch >= 'a' && ch <= 'z') {
- ch &= ~0x20;
-
- } else if (ch == '-') {
- ch = '_';
- }
-
- *b->last++ = ch;
- }
-
- b->last = ngx_copy(b->last, header[i].value.data, val_len);
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "fastcgi param: \"%*s: %*s\"",
- key_len, b->last - (key_len + val_len),
- val_len, b->last - val_len);
- next:
-
- continue;
- }
- }
-
-
- if (padding) {
- ngx_memzero(b->last, padding);
- b->last += padding;
- }
-
-
- h = (ngx_http_fastcgi_header_t *) b->last;
- b->last += sizeof(ngx_http_fastcgi_header_t);
-
- h->version = 1;
- h->type = NGX_HTTP_FASTCGI_PARAMS;
- h->request_id_hi = 0;
- h->request_id_lo = 1;
- h->content_length_hi = 0;
- h->content_length_lo = 0;
- h->padding_length = 0;
- h->reserved = 0;
-
- h = (ngx_http_fastcgi_header_t *) b->last;
- b->last += sizeof(ngx_http_fastcgi_header_t);
-
- if (flcf->upstream.pass_request_body) {
- body = r->upstream->request_bufs;
- r->upstream->request_bufs = cl;
-
-#if (NGX_SUPPRESS_WARN)
- file_pos = 0;
- pos = NULL;
-#endif
-
- while (body) {
-
- if (body->buf->in_file) {
- file_pos = body->buf->file_pos;
-
- } else {
- pos = body->buf->pos;
- }
-
- next = 0;
-
- do {
- b = ngx_alloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(b, body->buf, sizeof(ngx_buf_t));
-
- if (body->buf->in_file) {
- b->file_pos = file_pos;
- file_pos += 32 * 1024;
-
- if (file_pos >= body->buf->file_last) {
- file_pos = body->buf->file_last;
- next = 1;
- }
-
- b->file_last = file_pos;
- len = (ngx_uint_t) (file_pos - b->file_pos);
-
- } else {
- b->pos = pos;
- pos += 32 * 1024;
-
- if (pos >= body->buf->last) {
- pos = body->buf->last;
- next = 1;
- }
-
- b->last = pos;
- len = (ngx_uint_t) (pos - b->pos);
- }
-
- padding = 8 - len % 8;
- padding = (padding == 8) ? 0 : padding;
-
- h->version = 1;
- h->type = NGX_HTTP_FASTCGI_STDIN;
- h->request_id_hi = 0;
- h->request_id_lo = 1;
- h->content_length_hi = (u_char) ((len >> 8) & 0xff);
- h->content_length_lo = (u_char) (len & 0xff);
- h->padding_length = (u_char) padding;
- h->reserved = 0;
-
- cl->next = ngx_alloc_chain_link(r->pool);
- if (cl->next == NULL) {
- return NGX_ERROR;
- }
-
- cl = cl->next;
- cl->buf = b;
-
- b = ngx_create_temp_buf(r->pool,
- sizeof(ngx_http_fastcgi_header_t)
- + padding);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- if (padding) {
- ngx_memzero(b->last, padding);
- b->last += padding;
- }
-
- h = (ngx_http_fastcgi_header_t *) b->last;
- b->last += sizeof(ngx_http_fastcgi_header_t);
-
- cl->next = ngx_alloc_chain_link(r->pool);
- if (cl->next == NULL) {
- return NGX_ERROR;
- }
-
- cl = cl->next;
- cl->buf = b;
-
- } while (!next);
-
- body = body->next;
- }
-
- } else {
- r->upstream->request_bufs = cl;
- }
-
- h->version = 1;
- h->type = NGX_HTTP_FASTCGI_STDIN;
- h->request_id_hi = 0;
- h->request_id_lo = 1;
- h->content_length_hi = 0;
- h->content_length_lo = 0;
- h->padding_length = 0;
- h->reserved = 0;
-
- cl->next = NULL;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_fastcgi_reinit_request(ngx_http_request_t *r)
-{
- ngx_http_fastcgi_ctx_t *f;
-
- f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
-
- if (f == NULL) {
- return NGX_OK;
- }
-
- f->state = ngx_http_fastcgi_st_version;
- f->fastcgi_stdout = 0;
- f->large_stderr = 0;
-
- if (f->split_parts) {
- f->split_parts->nelts = 0;
- }
-
- r->state = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_fastcgi_process_header(ngx_http_request_t *r)
-{
- u_char *p, *msg, *start, *last,
- *part_start, *part_end;
- size_t size;
- ngx_str_t *status_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);
-
- umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
-
- u = r->upstream;
-
- for ( ;; ) {
-
- if (f->state < ngx_http_fastcgi_st_data) {
-
- f->pos = u->buffer.pos;
- f->last = u->buffer.last;
-
- rc = ngx_http_fastcgi_process_record(r, f);
-
- u->buffer.pos = f->pos;
- u->buffer.last = f->last;
-
- if (rc == NGX_AGAIN) {
- return NGX_AGAIN;
- }
-
- if (rc == NGX_ERROR) {
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
- }
-
- if (f->type != NGX_HTTP_FASTCGI_STDOUT
- && f->type != NGX_HTTP_FASTCGI_STDERR)
- {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream sent unexpected FastCGI record: %d",
- f->type);
-
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
- }
-
- if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream prematurely closed FastCGI stdout");
-
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
- }
- }
-
- if (f->state == ngx_http_fastcgi_st_padding) {
-
- if (u->buffer.pos + f->padding < u->buffer.last) {
- f->state = ngx_http_fastcgi_st_version;
- u->buffer.pos += f->padding;
-
- continue;
- }
-
- if (u->buffer.pos + f->padding == u->buffer.last) {
- f->state = ngx_http_fastcgi_st_version;
- u->buffer.pos = u->buffer.last;
-
- return NGX_AGAIN;
- }
-
- f->padding -= u->buffer.last - u->buffer.pos;
- u->buffer.pos = u->buffer.last;
-
- return NGX_AGAIN;
- }
-
-
- /* f->state == ngx_http_fastcgi_st_data */
-
- if (f->type == NGX_HTTP_FASTCGI_STDERR) {
-
- if (f->length) {
- msg = u->buffer.pos;
-
- if (u->buffer.pos + f->length <= u->buffer.last) {
- u->buffer.pos += f->length;
- f->length = 0;
- f->state = ngx_http_fastcgi_st_padding;
-
- } else {
- f->length -= u->buffer.last - u->buffer.pos;
- u->buffer.pos = u->buffer.last;
- }
-
- for (p = u->buffer.pos - 1; msg < p; p--) {
- if (*p != LF && *p != CR && *p != '.' && *p != ' ') {
- break;
- }
- }
-
- p++;
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "FastCGI sent in stderr: \"%*s\"", p - msg, msg);
-
- flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
-
- if (flcf->catch_stderr) {
- pattern = flcf->catch_stderr->elts;
-
- for (i = 0; i < flcf->catch_stderr->nelts; i++) {
- if (ngx_strnstr(msg, (char *) pattern[i].data,
- p - msg)
- != NULL)
- {
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
- }
- }
- }
-
- if (u->buffer.pos == u->buffer.last) {
-
- if (!f->fastcgi_stdout) {
-
- /*
- * the special handling the large number
- * of the PHP warnings to not allocate memory
- */
-
-#if (NGX_HTTP_CACHE)
- if (r->cache) {
- u->buffer.pos = u->buffer.start
- + r->cache->header_start;
- } else {
- u->buffer.pos = u->buffer.start;
- }
-#else
- u->buffer.pos = u->buffer.start;
-#endif
- u->buffer.last = u->buffer.pos;
- f->large_stderr = 1;
- }
-
- return NGX_AGAIN;
- }
-
- } else {
- f->state = ngx_http_fastcgi_st_padding;
- }
-
- continue;
- }
-
-
- /* f->type == NGX_HTTP_FASTCGI_STDOUT */
-
-#if (NGX_HTTP_CACHE)
-
- if (f->large_stderr && r->cache) {
- u_char *start;
- ssize_t len;
- ngx_http_fastcgi_header_t *fh;
-
- start = u->buffer.start + r->cache->header_start;
-
- len = u->buffer.pos - start - 2 * sizeof(ngx_http_fastcgi_header_t);
-
- /*
- * A tail of large stderr output before HTTP header is placed
- * in a cache file without a FastCGI record header.
- * To workaround it we put a dummy FastCGI record header at the
- * start of the stderr output or update r->cache_header_start,
- * if there is no enough place for the record header.
- */
-
- if (len >= 0) {
- fh = (ngx_http_fastcgi_header_t *) start;
- fh->version = 1;
- fh->type = NGX_HTTP_FASTCGI_STDERR;
- fh->request_id_hi = 0;
- fh->request_id_lo = 1;
- fh->content_length_hi = (u_char) ((len >> 8) & 0xff);
- fh->content_length_lo = (u_char) (len & 0xff);
- fh->padding_length = 0;
- fh->reserved = 0;
-
- } else {
- r->cache->header_start += u->buffer.pos - start
- - sizeof(ngx_http_fastcgi_header_t);
- }
-
- f->large_stderr = 0;
- }
-
-#endif
-
- f->fastcgi_stdout = 1;
-
- start = u->buffer.pos;
-
- if (u->buffer.pos + f->length < u->buffer.last) {
-
- /*
- * set u->buffer.last to the end of the FastCGI record data
- * for ngx_http_parse_header_line()
- */
-
- last = u->buffer.last;
- u->buffer.last = u->buffer.pos + f->length;
-
- } else {
- last = NULL;
- }
-
- for ( ;; ) {
-
- part_start = u->buffer.pos;
- part_end = u->buffer.last;
-
- rc = ngx_http_parse_header_line(r, &u->buffer, 1);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http fastcgi parser: %d", rc);
-
- if (rc == NGX_AGAIN) {
- break;
- }
-
- if (rc == NGX_OK) {
-
- /* a header line has been parsed successfully */
-
- h = ngx_list_push(&u->headers_in.headers);
- if (h == NULL) {
- 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_pnalloc(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, 1);
-
- if (rc != NGX_OK) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "invalid header after joining "
- "FastCGI records");
- return NGX_ERROR;
- }
-
- 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_pnalloc(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_pnalloc(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_memcpy(h->key.data, r->header_name_start, h->key.len);
- h->key.data[h->key.len] = '\0';
- ngx_memcpy(h->value.data, r->header_start, h->value.len);
- h->value.data[h->value.len] = '\0';
- }
-
- h->hash = r->header_hash;
-
- if (h->key.len == r->lowcase_index) {
- ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
-
- } else {
- ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
- }
-
- hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
- h->lowcase_key, h->key.len);
-
- if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http fastcgi header: \"%V: %V\"",
- &h->key, &h->value);
-
- if (u->buffer.pos < u->buffer.last) {
- continue;
- }
-
- /* the end of the FastCGI record */
-
- break;
- }
-
- if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
-
- /* a whole header has been parsed successfully */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http fastcgi header done");
-
- if (u->headers_in.status) {
- status_line = &u->headers_in.status->value;
-
- status = ngx_atoi(status_line->data, 3);
-
- if (status == NGX_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;
- u->headers_in.status_line = *status_line;
-
- } else if (u->headers_in.location) {
- u->headers_in.status_n = 302;
- ngx_str_set(&u->headers_in.status_line,
- "302 Moved Temporarily");
-
- } else {
- u->headers_in.status_n = 200;
- ngx_str_set(&u->headers_in.status_line, "200 OK");
- }
-
- if (u->state && u->state->status == 0) {
- u->state->status = u->headers_in.status_n;
- }
-
- break;
- }
-
- /* there was error while a header line parsing */
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream sent invalid header");
-
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
- }
-
- if (last) {
- u->buffer.last = last;
- }
-
- f->length -= u->buffer.pos - start;
-
- if (f->length == 0) {
- f->state = ngx_http_fastcgi_st_padding;
- }
-
- if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
- return NGX_OK;
- }
-
- if (rc == NGX_OK) {
- continue;
- }
-
- /* rc == NGX_AGAIN */
-
- 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);
- if (part == NULL) {
- return NGX_ERROR;
- }
-
- part->start = part_start;
- part->end = part_end;
-
- if (u->buffer.pos < u->buffer.last) {
- continue;
- }
-
- return NGX_AGAIN;
- }
-}
-
-
-static ngx_int_t
-ngx_http_fastcgi_input_filter_init(void *data)
-{
- ngx_http_request_t *r = data;
- ngx_http_fastcgi_loc_conf_t *flcf;
-
- flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
-
- r->upstream->pipe->length = flcf->keep_conn ?
- (off_t) sizeof(ngx_http_fastcgi_header_t) : -1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
-{
- u_char *m, *msg;
- ngx_int_t rc;
- ngx_buf_t *b, **prev;
- ngx_chain_t *cl;
- ngx_http_request_t *r;
- ngx_http_fastcgi_ctx_t *f;
- ngx_http_fastcgi_loc_conf_t *flcf;
-
- if (buf->pos == buf->last) {
- return NGX_OK;
- }
-
- r = p->input_ctx;
- f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
- flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
-
- b = NULL;
- prev = &buf->shadow;
-
- f->pos = buf->pos;
- f->last = buf->last;
-
- for ( ;; ) {
- if (f->state < ngx_http_fastcgi_st_data) {
-
- rc = ngx_http_fastcgi_process_record(r, f);
-
- if (rc == NGX_AGAIN) {
- break;
- }
-
- if (rc == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) {
- f->state = ngx_http_fastcgi_st_padding;
-
- if (!flcf->keep_conn) {
- p->upstream_done = 1;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
- "http fastcgi closed stdout");
-
- continue;
- }
-
- if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
- "http fastcgi sent end request");
-
- if (!flcf->keep_conn) {
- p->upstream_done = 1;
- break;
- }
-
- continue;
- }
- }
-
-
- if (f->state == ngx_http_fastcgi_st_padding) {
-
- if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
-
- if (f->pos + f->padding < f->last) {
- p->upstream_done = 1;
- break;
- }
-
- if (f->pos + f->padding == f->last) {
- p->upstream_done = 1;
- r->upstream->keepalive = 1;
- break;
- }
-
- f->padding -= f->last - f->pos;
-
- break;
- }
-
- if (f->pos + f->padding < f->last) {
- f->state = ngx_http_fastcgi_st_version;
- f->pos += f->padding;
-
- continue;
- }
-
- if (f->pos + f->padding == f->last) {
- f->state = ngx_http_fastcgi_st_version;
-
- break;
- }
-
- f->padding -= f->last - f->pos;
-
- break;
- }
-
-
- /* f->state == ngx_http_fastcgi_st_data */
-
- if (f->type == NGX_HTTP_FASTCGI_STDERR) {
-
- if (f->length) {
-
- if (f->pos == f->last) {
- break;
- }
-
- msg = f->pos;
-
- if (f->pos + f->length <= f->last) {
- f->pos += f->length;
- f->length = 0;
- f->state = ngx_http_fastcgi_st_padding;
-
- } else {
- f->length -= f->last - f->pos;
- f->pos = f->last;
- }
-
- for (m = f->pos - 1; msg < m; m--) {
- if (*m != LF && *m != CR && *m != '.' && *m != ' ') {
- break;
- }
- }
-
- ngx_log_error(NGX_LOG_ERR, p->log, 0,
- "FastCGI sent in stderr: \"%*s\"",
- m + 1 - msg, msg);
-
- } else {
- f->state = ngx_http_fastcgi_st_padding;
- }
-
- continue;
- }
-
- if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
-
- if (f->pos + f->length <= f->last) {
- f->state = ngx_http_fastcgi_st_padding;
- f->pos += f->length;
-
- continue;
- }
-
- f->length -= f->last - f->pos;
-
- break;
- }
-
-
- /* f->type == NGX_HTTP_FASTCGI_STDOUT */
-
- if (f->pos == f->last) {
- break;
- }
-
- cl = ngx_chain_get_free_buf(p->pool, &p->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->pos = f->pos;
- b->start = buf->start;
- b->end = buf->end;
- b->tag = p->tag;
- b->temporary = 1;
- b->recycled = 1;
-
- *prev = b;
- prev = &b->shadow;
-
- if (p->in) {
- *p->last_in = cl;
- } else {
- p->in = cl;
- }
- p->last_in = &cl->next;
-
-
- /* STUB */ b->num = buf->num;
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "input buf #%d %p", b->num, b->pos);
-
- if (f->pos + f->length <= f->last) {
- f->state = ngx_http_fastcgi_st_padding;
- f->pos += f->length;
- b->last = f->pos;
-
- continue;
- }
-
- f->length -= f->last - f->pos;
-
- b->last = f->last;
-
- break;
-
- }
-
- if (flcf->keep_conn) {
-
- /* set p->length, minimal amount of data we want to see */
-
- if (f->state < ngx_http_fastcgi_st_data) {
- p->length = 1;
-
- } else if (f->state == ngx_http_fastcgi_st_padding) {
- p->length = f->padding;
-
- } else {
- /* ngx_http_fastcgi_st_data */
-
- p->length = f->length;
- }
- }
-
- if (b) {
- b->shadow = buf;
- b->last_shadow = 1;
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "input buf %p %z", b->pos, b->last - b->pos);
-
- return NGX_OK;
- }
-
- /* there is no data record in the buf, add it to free chain */
-
- if (ngx_event_pipe_add_free_buf(p, buf) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_fastcgi_non_buffered_filter(void *data, ssize_t bytes)
-{
- u_char *m, *msg;
- ngx_int_t rc;
- ngx_buf_t *b, *buf;
- ngx_chain_t *cl, **ll;
- ngx_http_request_t *r;
- ngx_http_upstream_t *u;
- ngx_http_fastcgi_ctx_t *f;
-
- r = data;
- f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
-
- u = r->upstream;
- buf = &u->buffer;
-
- buf->pos = buf->last;
- buf->last += bytes;
-
- for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) {
- ll = &cl->next;
- }
-
- f->pos = buf->pos;
- f->last = buf->last;
-
- for ( ;; ) {
- if (f->state < ngx_http_fastcgi_st_data) {
-
- rc = ngx_http_fastcgi_process_record(r, f);
-
- if (rc == NGX_AGAIN) {
- break;
- }
-
- if (rc == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) {
- f->state = ngx_http_fastcgi_st_padding;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http fastcgi closed stdout");
-
- continue;
- }
- }
-
- if (f->state == ngx_http_fastcgi_st_padding) {
-
- if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
-
- if (f->pos + f->padding < f->last) {
- u->length = 0;
- break;
- }
-
- if (f->pos + f->padding == f->last) {
- u->length = 0;
- u->keepalive = 1;
- break;
- }
-
- f->padding -= f->last - f->pos;
-
- break;
- }
-
- if (f->pos + f->padding < f->last) {
- f->state = ngx_http_fastcgi_st_version;
- f->pos += f->padding;
-
- continue;
- }
-
- if (f->pos + f->padding == f->last) {
- f->state = ngx_http_fastcgi_st_version;
-
- break;
- }
-
- f->padding -= f->last - f->pos;
-
- break;
- }
-
-
- /* f->state == ngx_http_fastcgi_st_data */
-
- if (f->type == NGX_HTTP_FASTCGI_STDERR) {
-
- if (f->length) {
-
- if (f->pos == f->last) {
- break;
- }
-
- msg = f->pos;
-
- if (f->pos + f->length <= f->last) {
- f->pos += f->length;
- f->length = 0;
- f->state = ngx_http_fastcgi_st_padding;
-
- } else {
- f->length -= f->last - f->pos;
- f->pos = f->last;
- }
-
- for (m = f->pos - 1; msg < m; m--) {
- if (*m != LF && *m != CR && *m != '.' && *m != ' ') {
- break;
- }
- }
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "FastCGI sent in stderr: \"%*s\"",
- m + 1 - msg, msg);
-
- } else {
- f->state = ngx_http_fastcgi_st_padding;
- }
-
- continue;
- }
-
- if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
-
- if (f->pos + f->length <= f->last) {
- f->state = ngx_http_fastcgi_st_padding;
- f->pos += f->length;
-
- continue;
- }
-
- f->length -= f->last - f->pos;
-
- break;
- }
-
-
- /* f->type == NGX_HTTP_FASTCGI_STDOUT */
-
- if (f->pos == f->last) {
- break;
- }
-
- cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- *ll = cl;
- ll = &cl->next;
-
- b = cl->buf;
-
- b->flush = 1;
- b->memory = 1;
-
- b->pos = f->pos;
- b->tag = u->output.tag;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http fastcgi output buf %p", b->pos);
-
- if (f->pos + f->length <= f->last) {
- f->state = ngx_http_fastcgi_st_padding;
- f->pos += f->length;
- b->last = f->pos;
-
- continue;
- }
-
- f->length -= f->last - f->pos;
- b->last = f->last;
-
- break;
- }
-
- /* provide continuous buffer for subrequests in memory */
-
- if (r->subrequest_in_memory) {
-
- cl = u->out_bufs;
-
- if (cl) {
- buf->pos = cl->buf->pos;
- }
-
- buf->last = buf->pos;
-
- for (cl = u->out_bufs; cl; cl = cl->next) {
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http fastcgi in memory %p-%p %uz",
- cl->buf->pos, cl->buf->last, ngx_buf_size(cl->buf));
-
- if (buf->last == cl->buf->pos) {
- buf->last = cl->buf->last;
- continue;
- }
-
- buf->last = ngx_movemem(buf->last, cl->buf->pos,
- cl->buf->last - cl->buf->pos);
-
- cl->buf->pos = buf->last - (cl->buf->last - cl->buf->pos);
- cl->buf->last = buf->last;
- }
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_fastcgi_process_record(ngx_http_request_t *r,
- ngx_http_fastcgi_ctx_t *f)
-{
- u_char ch, *p;
- ngx_http_fastcgi_state_e state;
-
- state = f->state;
-
- for (p = f->pos; p < f->last; p++) {
-
- ch = *p;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http fastcgi record byte: %02Xd", ch);
-
- switch (state) {
-
- case ngx_http_fastcgi_st_version:
- if (ch != 1) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream sent unsupported FastCGI "
- "protocol version: %d", ch);
- return NGX_ERROR;
- }
- state = ngx_http_fastcgi_st_type;
- break;
-
- case ngx_http_fastcgi_st_type:
- switch (ch) {
- case NGX_HTTP_FASTCGI_STDOUT:
- case NGX_HTTP_FASTCGI_STDERR:
- case NGX_HTTP_FASTCGI_END_REQUEST:
- f->type = (ngx_uint_t) ch;
- break;
- default:
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream sent invalid FastCGI "
- "record type: %d", ch);
- return NGX_ERROR;
-
- }
- state = ngx_http_fastcgi_st_request_id_hi;
- break;
-
- /* we support the single request per connection */
-
- case ngx_http_fastcgi_st_request_id_hi:
- if (ch != 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream sent unexpected FastCGI "
- "request id high byte: %d", ch);
- return NGX_ERROR;
- }
- state = ngx_http_fastcgi_st_request_id_lo;
- break;
-
- case ngx_http_fastcgi_st_request_id_lo:
- if (ch != 1) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream sent unexpected FastCGI "
- "request id low byte: %d", ch);
- return NGX_ERROR;
- }
- state = ngx_http_fastcgi_st_content_length_hi;
- break;
-
- case ngx_http_fastcgi_st_content_length_hi:
- f->length = ch << 8;
- state = ngx_http_fastcgi_st_content_length_lo;
- break;
-
- case ngx_http_fastcgi_st_content_length_lo:
- f->length |= (size_t) ch;
- state = ngx_http_fastcgi_st_padding_length;
- break;
-
- case ngx_http_fastcgi_st_padding_length:
- f->padding = (size_t) ch;
- state = ngx_http_fastcgi_st_reserved;
- break;
-
- case ngx_http_fastcgi_st_reserved:
- state = ngx_http_fastcgi_st_data;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http fastcgi record length: %z", f->length);
-
- f->pos = p + 1;
- f->state = state;
-
- return NGX_OK;
-
- /* suppress warning */
- case ngx_http_fastcgi_st_data:
- case ngx_http_fastcgi_st_padding:
- break;
- }
- }
-
- f->state = state;
-
- return NGX_AGAIN;
-}
-
-
-static void
-ngx_http_fastcgi_abort_request(ngx_http_request_t *r)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "abort http fastcgi request");
-
- return;
-}
-
-
-static void
-ngx_http_fastcgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "finalize http fastcgi request");
-
- return;
-}
-
-
-static ngx_int_t
-ngx_http_fastcgi_add_variables(ngx_conf_t *cf)
-{
- ngx_http_variable_t *var, *v;
-
- for (v = ngx_http_fastcgi_vars; v->name.len; v++) {
- var = ngx_http_add_variable(cf, &v->name, v->flags);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = v->get_handler;
- var->data = v->data;
- }
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_fastcgi_loc_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_fastcgi_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->upstream.bufs.num = 0;
- * conf->upstream.ignore_headers = 0;
- * conf->upstream.next_upstream = 0;
- * conf->upstream.cache_use_stale = 0;
- * conf->upstream.cache_methods = 0;
- * conf->upstream.temp_path = NULL;
- * conf->upstream.hide_headers_hash = { NULL, 0 };
- * conf->upstream.uri = { 0, NULL };
- * conf->upstream.location = NULL;
- * conf->upstream.store_lengths = NULL;
- * conf->upstream.store_values = NULL;
- *
- * conf->index.len = { 0, 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;
-
- conf->upstream.local = NGX_CONF_UNSET_PTR;
-
- conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
-
- conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
- conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
-
- conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE;
- conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
- conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
-
- conf->upstream.pass_request_headers = NGX_CONF_UNSET;
- conf->upstream.pass_request_body = NGX_CONF_UNSET;
-
-#if (NGX_HTTP_CACHE)
- conf->upstream.cache = NGX_CONF_UNSET_PTR;
- conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
- conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
- conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
- conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
- conf->upstream.cache_lock = NGX_CONF_UNSET;
- conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.cache_revalidate = NGX_CONF_UNSET;
-#endif
-
- 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->upstream.change_buffering = 1;
-
- conf->catch_stderr = NGX_CONF_UNSET_PTR;
-
- conf->keep_conn = NGX_CONF_UNSET;
-
- ngx_str_set(&conf->upstream.module, "fastcgi");
-
- return conf;
-}
-
-
-static char *
-ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_fastcgi_loc_conf_t *prev = parent;
- ngx_http_fastcgi_loc_conf_t *conf = child;
-
- size_t size;
- ngx_hash_init_t hash;
- ngx_http_core_loc_conf_t *clcf;
-
- 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);
-
- ngx_conf_merge_value(conf->upstream.ignore_client_abort,
- prev->upstream.ignore_client_abort, 0);
-
- ngx_conf_merge_ptr_value(conf->upstream.local,
- prev->upstream.local, NULL);
-
- ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
- prev->upstream.connect_timeout, 60000);
-
- ngx_conf_merge_msec_value(conf->upstream.send_timeout,
- prev->upstream.send_timeout, 60000);
-
- ngx_conf_merge_msec_value(conf->upstream.read_timeout,
- prev->upstream.read_timeout, 60000);
-
- ngx_conf_merge_size_value(conf->upstream.send_lowat,
- prev->upstream.send_lowat, 0);
-
- ngx_conf_merge_size_value(conf->upstream.buffer_size,
- prev->upstream.buffer_size,
- (size_t) ngx_pagesize);
-
-
- ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs,
- 8, ngx_pagesize);
-
- if (conf->upstream.bufs.num < 2) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "there must be at least 2 \"fastcgi_buffers\"");
- return NGX_CONF_ERROR;
- }
-
-
- size = conf->upstream.buffer_size;
- if (size < conf->upstream.bufs.size) {
- size = conf->upstream.bufs.size;
- }
-
-
- ngx_conf_merge_size_value(conf->upstream.busy_buffers_size_conf,
- prev->upstream.busy_buffers_size_conf,
- NGX_CONF_UNSET_SIZE);
-
- if (conf->upstream.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) {
- conf->upstream.busy_buffers_size = 2 * size;
- } else {
- conf->upstream.busy_buffers_size =
- conf->upstream.busy_buffers_size_conf;
- }
-
- if (conf->upstream.busy_buffers_size < size) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"fastcgi_busy_buffers_size\" must be equal to or greater than "
- "the maximum of the value of \"fastcgi_buffer_size\" and "
- "one of the \"fastcgi_buffers\"");
-
- return NGX_CONF_ERROR;
- }
-
- if (conf->upstream.busy_buffers_size
- > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size)
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"fastcgi_busy_buffers_size\" must be less than "
- "the size of all \"fastcgi_buffers\" minus one buffer");
-
- return NGX_CONF_ERROR;
- }
-
-
- ngx_conf_merge_size_value(conf->upstream.temp_file_write_size_conf,
- prev->upstream.temp_file_write_size_conf,
- NGX_CONF_UNSET_SIZE);
-
- if (conf->upstream.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) {
- conf->upstream.temp_file_write_size = 2 * size;
- } else {
- conf->upstream.temp_file_write_size =
- conf->upstream.temp_file_write_size_conf;
- }
-
- if (conf->upstream.temp_file_write_size < size) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"fastcgi_temp_file_write_size\" must be equal to or greater "
- "than the maximum of the value of \"fastcgi_buffer_size\" and "
- "one of the \"fastcgi_buffers\"");
-
- return NGX_CONF_ERROR;
- }
-
-
- ngx_conf_merge_size_value(conf->upstream.max_temp_file_size_conf,
- prev->upstream.max_temp_file_size_conf,
- NGX_CONF_UNSET_SIZE);
-
- if (conf->upstream.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) {
- conf->upstream.max_temp_file_size = 1024 * 1024 * 1024;
- } else {
- conf->upstream.max_temp_file_size =
- conf->upstream.max_temp_file_size_conf;
- }
-
- if (conf->upstream.max_temp_file_size != 0
- && conf->upstream.max_temp_file_size < size)
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"fastcgi_max_temp_file_size\" must be equal to zero to disable "
- "temporary files usage or must be equal to or greater than "
- "the maximum of the value of \"fastcgi_buffer_size\" and "
- "one of the \"fastcgi_buffers\"");
-
- return NGX_CONF_ERROR;
- }
-
-
- ngx_conf_merge_bitmask_value(conf->upstream.ignore_headers,
- prev->upstream.ignore_headers,
- NGX_CONF_BITMASK_SET);
-
-
- ngx_conf_merge_bitmask_value(conf->upstream.next_upstream,
- prev->upstream.next_upstream,
- (NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_ERROR
- |NGX_HTTP_UPSTREAM_FT_TIMEOUT));
-
- if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) {
- conf->upstream.next_upstream = NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_OFF;
- }
-
- if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,
- prev->upstream.temp_path,
- &ngx_http_fastcgi_temp_path)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
-#if (NGX_HTTP_CACHE)
-
- ngx_conf_merge_ptr_value(conf->upstream.cache,
- prev->upstream.cache, NULL);
-
- if (conf->upstream.cache && conf->upstream.cache->data == NULL) {
- ngx_shm_zone_t *shm_zone;
-
- shm_zone = conf->upstream.cache;
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"fastcgi_cache\" zone \"%V\" is unknown",
- &shm_zone->shm.name);
-
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_uint_value(conf->upstream.cache_min_uses,
- prev->upstream.cache_min_uses, 1);
-
- ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale,
- prev->upstream.cache_use_stale,
- (NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_OFF));
-
- if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) {
- conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_OFF;
- }
-
- if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_ERROR) {
- conf->upstream.cache_use_stale |= NGX_HTTP_UPSTREAM_FT_NOLIVE;
- }
-
- if (conf->upstream.cache_methods == 0) {
- conf->upstream.cache_methods = prev->upstream.cache_methods;
- }
-
- conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
-
- ngx_conf_merge_ptr_value(conf->upstream.cache_bypass,
- prev->upstream.cache_bypass, NULL);
-
- ngx_conf_merge_ptr_value(conf->upstream.no_cache,
- prev->upstream.no_cache, NULL);
-
- ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
- prev->upstream.cache_valid, NULL);
-
- if (conf->cache_key.value.data == NULL) {
- conf->cache_key = prev->cache_key;
- }
-
- ngx_conf_merge_value(conf->upstream.cache_lock,
- prev->upstream.cache_lock, 0);
-
- ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout,
- prev->upstream.cache_lock_timeout, 5000);
-
- ngx_conf_merge_value(conf->upstream.cache_revalidate,
- prev->upstream.cache_revalidate, 0);
-
-#endif
-
- ngx_conf_merge_value(conf->upstream.pass_request_headers,
- prev->upstream.pass_request_headers, 1);
- ngx_conf_merge_value(conf->upstream.pass_request_body,
- prev->upstream.pass_request_body, 1);
-
- ngx_conf_merge_value(conf->upstream.intercept_errors,
- prev->upstream.intercept_errors, 0);
-
- ngx_conf_merge_ptr_value(conf->catch_stderr, prev->catch_stderr, NULL);
-
- ngx_conf_merge_value(conf->keep_conn, prev->keep_conn, 0);
-
-
- ngx_conf_merge_str_value(conf->index, prev->index, "");
-
- hash.max_size = 512;
- hash.bucket_size = ngx_align(64, ngx_cacheline_size);
- hash.name = "fastcgi_hide_headers_hash";
-
- if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
- &prev->upstream, ngx_http_fastcgi_hide_headers, &hash)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- if (conf->upstream.upstream == NULL) {
- conf->upstream.upstream = prev->upstream.upstream;
- }
-
- if (conf->fastcgi_lengths == NULL) {
- conf->fastcgi_lengths = prev->fastcgi_lengths;
- conf->fastcgi_values = prev->fastcgi_values;
- }
-
- if (conf->upstream.upstream || conf->fastcgi_lengths) {
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
- if (clcf->handler == NULL && clcf->lmt_excpt) {
- clcf->handler = ngx_http_fastcgi_handler;
- }
- }
-
-#if (NGX_PCRE)
- if (conf->split_regex == NULL) {
- conf->split_regex = prev->split_regex;
- conf->split_name = prev->split_name;
- }
-#endif
-
- if (ngx_http_fastcgi_merge_params(cf, conf, prev) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
- ngx_http_fastcgi_loc_conf_t *conf, ngx_http_fastcgi_loc_conf_t *prev)
-{
- u_char *p;
- size_t size;
- uintptr_t *code;
- ngx_uint_t i, nsrc;
- ngx_array_t headers_names;
-#if (NGX_HTTP_CACHE)
- ngx_array_t params_merged;
-#endif
- ngx_hash_key_t *hk;
- ngx_hash_init_t hash;
- ngx_http_upstream_param_t *src;
- ngx_http_script_compile_t sc;
- ngx_http_script_copy_code_t *copy;
-
- if (conf->params_source == NULL) {
- conf->params_source = prev->params_source;
-
- if (prev->headers_hash.buckets
-#if (NGX_HTTP_CACHE)
- && ((conf->upstream.cache == NULL)
- == (prev->upstream.cache == NULL))
-#endif
- )
- {
- conf->flushes = prev->flushes;
- conf->params_len = prev->params_len;
- conf->params = prev->params;
- conf->headers_hash = prev->headers_hash;
- conf->header_params = prev->header_params;
-
- return NGX_OK;
- }
- }
-
- if (conf->params_source == NULL
-#if (NGX_HTTP_CACHE)
- && (conf->upstream.cache == NULL)
-#endif
- )
- {
- conf->headers_hash.buckets = (void *) 1;
- return NGX_OK;
- }
-
- conf->params_len = ngx_array_create(cf->pool, 64, 1);
- if (conf->params_len == NULL) {
- return NGX_ERROR;
- }
-
- conf->params = ngx_array_create(cf->pool, 512, 1);
- if (conf->params == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (conf->params_source) {
- src = conf->params_source->elts;
- nsrc = conf->params_source->nelts;
-
- } else {
- src = NULL;
- nsrc = 0;
- }
-
-#if (NGX_HTTP_CACHE)
-
- if (conf->upstream.cache) {
- ngx_keyval_t *h;
- ngx_http_upstream_param_t *s;
-
- if (ngx_array_init(&params_merged, cf->temp_pool, 4,
- sizeof(ngx_http_upstream_param_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- for (i = 0; i < nsrc; i++) {
-
- s = ngx_array_push(&params_merged);
- if (s == NULL) {
- return NGX_ERROR;
- }
-
- *s = src[i];
- }
-
- h = ngx_http_fastcgi_cache_headers;
-
- while (h->key.len) {
-
- src = params_merged.elts;
- nsrc = params_merged.nelts;
-
- for (i = 0; i < nsrc; i++) {
- if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
- goto next;
- }
- }
-
- s = ngx_array_push(&params_merged);
- if (s == NULL) {
- return NGX_ERROR;
- }
-
- s->key = h->key;
- s->value = h->value;
- s->skip_empty = 1;
-
- next:
-
- h++;
- }
-
- src = params_merged.elts;
- nsrc = params_merged.nelts;
- }
-
-#endif
-
- for (i = 0; i < nsrc; i++) {
-
- if (src[i].key.len > sizeof("HTTP_") - 1
- && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0)
- {
- hk = ngx_array_push(&headers_names);
- if (hk == NULL) {
- return NGX_ERROR;
- }
-
- hk->key.len = src[i].key.len - 5;
- hk->key.data = src[i].key.data + 5;
- hk->key_hash = ngx_hash_key_lc(hk->key.data, hk->key.len);
- hk->value = (void *) 1;
-
- if (src[i].value.len == 0) {
- continue;
- }
- }
-
- copy = ngx_array_push_n(conf->params_len,
- sizeof(ngx_http_script_copy_code_t));
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
- copy->len = src[i].key.len;
-
- copy = ngx_array_push_n(conf->params_len,
- sizeof(ngx_http_script_copy_code_t));
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
- copy->len = src[i].skip_empty;
-
-
- size = (sizeof(ngx_http_script_copy_code_t)
- + src[i].key.len + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
-
- copy = ngx_array_push_n(conf->params, size);
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = ngx_http_script_copy_code;
- copy->len = src[i].key.len;
-
- p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
- ngx_memcpy(p, src[i].key.data, src[i].key.len);
-
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = &src[i].value;
- sc.flushes = &conf->flushes;
- sc.lengths = &conf->params_len;
- sc.values = &conf->params;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_ERROR;
- }
-
- code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
-
-
- code = ngx_array_push_n(conf->params, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
- }
-
- code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
-
- conf->header_params = headers_names.nelts;
-
- hash.hash = &conf->headers_hash;
- hash.key = ngx_hash_key_lc;
- hash.max_size = 512;
- hash.bucket_size = 64;
- hash.name = "fastcgi_params_hash";
- hash.pool = cf->pool;
- hash.temp_pool = NULL;
-
- return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts);
-}
-
-
-static ngx_int_t
-ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
- ngx_http_fastcgi_ctx_t *f;
- ngx_http_fastcgi_loc_conf_t *flcf;
-
- flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
-
- f = ngx_http_fastcgi_split(r, flcf);
-
- if (f == NULL) {
- return NGX_ERROR;
- }
-
- if (f->script_name.len == 0
- || f->script_name.data[f->script_name.len - 1] != '/')
- {
- v->len = f->script_name.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = f->script_name.data;
-
- return NGX_OK;
- }
-
- v->len = f->script_name.len + flcf->index.len;
-
- v->data = ngx_pnalloc(r->pool, v->len);
- if (v->data == NULL) {
- return NGX_ERROR;
- }
-
- p = ngx_copy(v->data, f->script_name.data, f->script_name.len);
- ngx_memcpy(p, flcf->index.data, flcf->index.len);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_fastcgi_path_info_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_http_fastcgi_ctx_t *f;
- ngx_http_fastcgi_loc_conf_t *flcf;
-
- flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
-
- f = ngx_http_fastcgi_split(r, flcf);
-
- if (f == NULL) {
- return NGX_ERROR;
- }
-
- v->len = f->path_info.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = f->path_info.data;
-
- return NGX_OK;
-}
-
-
-static ngx_http_fastcgi_ctx_t *
-ngx_http_fastcgi_split(ngx_http_request_t *r, ngx_http_fastcgi_loc_conf_t *flcf)
-{
- ngx_http_fastcgi_ctx_t *f;
-#if (NGX_PCRE)
- ngx_int_t n;
- int captures[(1 + 2) * 3];
-
- f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
-
- if (f == NULL) {
- f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
- if (f == NULL) {
- return NULL;
- }
-
- ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
- }
-
- if (f->script_name.len) {
- return f;
- }
-
- if (flcf->split_regex == NULL) {
- f->script_name = r->uri;
- return f;
- }
-
- n = ngx_regex_exec(flcf->split_regex, &r->uri, captures, (1 + 2) * 3);
-
- if (n >= 0) { /* match */
- f->script_name.len = captures[3] - captures[2];
- f->script_name.data = r->uri.data + captures[2];
-
- f->path_info.len = captures[5] - captures[4];
- f->path_info.data = r->uri.data + captures[4];
-
- return f;
- }
-
- if (n == NGX_REGEX_NO_MATCHED) {
- f->script_name = r->uri;
- return f;
- }
-
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
- n, &r->uri, &flcf->split_name);
- return NULL;
-
-#else
-
- f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
-
- if (f == NULL) {
- f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
- if (f == NULL) {
- return NULL;
- }
-
- ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
- }
-
- f->script_name = r->uri;
-
- return f;
-
-#endif
-}
-
-
-static char *
-ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_fastcgi_loc_conf_t *flcf = conf;
-
- ngx_url_t u;
- ngx_str_t *value, *url;
- ngx_uint_t n;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_script_compile_t sc;
-
- if (flcf->upstream.upstream || flcf->fastcgi_lengths) {
- return "is duplicate";
- }
-
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
-
- clcf->handler = ngx_http_fastcgi_handler;
-
- if (clcf->name.data[clcf->name.len - 1] == '/') {
- clcf->auto_redirect = 1;
- }
-
- value = cf->args->elts;
-
- url = &value[1];
-
- n = ngx_http_script_variables_count(url);
-
- if (n) {
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = url;
- sc.lengths = &flcf->fastcgi_lengths;
- sc.values = &flcf->fastcgi_values;
- sc.variables = n;
- sc.complete_lengths = 1;
- sc.complete_values = 1;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
- }
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- u.url = value[1];
- u.no_resolve = 1;
-
- flcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
- if (flcf->upstream.upstream == NULL) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_fastcgi_split_path_info(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
-#if (NGX_PCRE)
- ngx_http_fastcgi_loc_conf_t *flcf = conf;
-
- ngx_str_t *value;
- ngx_regex_compile_t rc;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
-
- value = cf->args->elts;
-
- flcf->split_name = value[1];
-
- ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
-
- rc.pattern = value[1];
- rc.pool = cf->pool;
- rc.err.len = NGX_MAX_CONF_ERRSTR;
- rc.err.data = errstr;
-
- if (ngx_regex_compile(&rc) != NGX_OK) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
- return NGX_CONF_ERROR;
- }
-
- if (rc.captures != 2) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "pattern \"%V\" must have 2 captures", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- flcf->split_regex = rc.regex;
-
- return NGX_CONF_OK;
-
-#else
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%V\" requires PCRE library", &cmd->name);
- return NGX_CONF_ERROR;
-
-#endif
-}
-
-
-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, "off") == 0) {
- flcf->upstream.store = 0;
- return NGX_CONF_OK;
- }
-
-#if (NGX_HTTP_CACHE)
-
- if (flcf->upstream.cache != NGX_CONF_UNSET_PTR
- && flcf->upstream.cache != NULL)
- {
- return "is incompatible with \"fastcgi_cache\"";
- }
-
-#endif
-
- if (ngx_strcmp(value[1].data, "on") == 0) {
- flcf->upstream.store = 1;
- return NGX_CONF_OK;
- }
-
- /* 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;
-}
-
-
-#if (NGX_HTTP_CACHE)
-
-static char *
-ngx_http_fastcgi_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_fastcgi_loc_conf_t *flcf = conf;
-
- ngx_str_t *value;
-
- value = cf->args->elts;
-
- if (flcf->upstream.cache != NGX_CONF_UNSET_PTR) {
- return "is duplicate";
- }
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- flcf->upstream.cache = NULL;
- return NGX_CONF_OK;
- }
-
- if (flcf->upstream.store > 0 || flcf->upstream.store_lengths) {
- return "is incompatible with \"fastcgi_store\"";
- }
-
- flcf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0,
- &ngx_http_fastcgi_module);
- if (flcf->upstream.cache == NULL) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_fastcgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_fastcgi_loc_conf_t *flcf = conf;
-
- ngx_str_t *value;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- if (flcf->cache_key.value.data) {
- return "is duplicate";
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &flcf->cache_key;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-#endif
-
-
-static char *
-ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post, void *data)
-{
-#if (NGX_FREEBSD)
- ssize_t *np = data;
-
- if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"fastcgi_send_lowat\" must be less than %d "
- "(sysctl net.inet.tcp.sendspace)",
- ngx_freebsd_net_inet_tcp_sendspace);
-
- return NGX_CONF_ERROR;
- }
-
-#elif !(NGX_HAVE_SO_SNDLOWAT)
- ssize_t *np = data;
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "\"fastcgi_send_lowat\" is not supported, ignored");
-
- *np = 0;
-
-#endif
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_flv_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_flv_module.c
deleted file mode 100644
index cc2532027cc..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_flv_module.c
+++ /dev/null
@@ -1,266 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static char *ngx_http_flv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-
-static ngx_command_t ngx_http_flv_commands[] = {
-
- { ngx_string("flv"),
- NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
- ngx_http_flv,
- 0,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static u_char ngx_flv_header[] = "FLV\x1\x5\0\0\0\x9\0\0\0\0";
-
-
-static ngx_http_module_t ngx_http_flv_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_flv_module = {
- NGX_MODULE_V1,
- &ngx_http_flv_module_ctx, /* module context */
- ngx_http_flv_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_flv_handler(ngx_http_request_t *r)
-{
- u_char *last;
- off_t start, len;
- size_t root;
- ngx_int_t rc;
- ngx_uint_t level, i;
- ngx_str_t path, value;
- ngx_log_t *log;
- ngx_buf_t *b;
- ngx_chain_t out[2];
- ngx_open_file_info_t of;
- ngx_http_core_loc_conf_t *clcf;
-
- if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
- return NGX_HTTP_NOT_ALLOWED;
- }
-
- if (r->uri.data[r->uri.len - 1] == '/') {
- return NGX_DECLINED;
- }
-
- rc = ngx_http_discard_request_body(r);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- last = ngx_http_map_uri_to_path(r, &path, &root, 0);
- if (last == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- log = r->connection->log;
-
- path.len = last - path.data;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
- "http flv filename: \"%V\"", &path);
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- ngx_memzero(&of, sizeof(ngx_open_file_info_t));
-
- of.read_ahead = clcf->read_ahead;
- of.directio = clcf->directio;
- of.valid = clcf->open_file_cache_valid;
- of.min_uses = clcf->open_file_cache_min_uses;
- of.errors = clcf->open_file_cache_errors;
- of.events = clcf->open_file_cache_events;
-
- if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
- != NGX_OK)
- {
- switch (of.err) {
-
- case 0:
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
-
- case NGX_ENOENT:
- case NGX_ENOTDIR:
- case NGX_ENAMETOOLONG:
-
- level = NGX_LOG_ERR;
- rc = NGX_HTTP_NOT_FOUND;
- break;
-
- case NGX_EACCES:
-#if (NGX_HAVE_OPENAT)
- case NGX_EMLINK:
- case NGX_ELOOP:
-#endif
-
- level = NGX_LOG_ERR;
- rc = NGX_HTTP_FORBIDDEN;
- break;
-
- default:
-
- level = NGX_LOG_CRIT;
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- break;
- }
-
- if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
- ngx_log_error(level, log, of.err,
- "%s \"%s\" failed", of.failed, path.data);
- }
-
- return rc;
- }
-
- if (!of.is_file) {
-
- if (ngx_close_file(of.fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", path.data);
- }
-
- return NGX_DECLINED;
- }
-
- r->root_tested = !r->error_page;
-
- start = 0;
- len = of.size;
- i = 1;
-
- if (r->args.len) {
-
- if (ngx_http_arg(r, (u_char *) "start", 5, &value) == NGX_OK) {
-
- start = ngx_atoof(value.data, value.len);
-
- if (start == NGX_ERROR || start >= len) {
- start = 0;
- }
-
- if (start) {
- len = sizeof(ngx_flv_header) - 1 + len - start;
- i = 0;
- }
- }
- }
-
- log->action = "sending flv to client";
-
- r->headers_out.status = NGX_HTTP_OK;
- r->headers_out.content_length_n = len;
- r->headers_out.last_modified_time = of.mtime;
-
- if (ngx_http_set_etag(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_http_set_content_type(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (i == 0) {
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- b->pos = ngx_flv_header;
- b->last = ngx_flv_header + sizeof(ngx_flv_header) - 1;
- b->memory = 1;
-
- out[0].buf = b;
- out[0].next = &out[1];
- }
-
-
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
- if (b->file == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- r->allow_ranges = 1;
-
- rc = ngx_http_send_header(r);
-
- if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
- return rc;
- }
-
- b->file_pos = start;
- b->file_last = of.size;
-
- b->in_file = b->file_last ? 1: 0;
- b->last_buf = (r == r->main) ? 1 : 0;
- b->last_in_chain = 1;
-
- b->file->fd = of.fd;
- b->file->name = path;
- b->file->log = log;
- b->file->directio = of.is_directio;
-
- out[1].buf = b;
- out[1].next = NULL;
-
- return ngx_http_output_filter(r, &out[i]);
-}
-
-
-static char *
-ngx_http_flv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
- clcf->handler = ngx_http_flv_handler;
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_geo_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_geo_module.c
deleted file mode 100644
index 34c3b190d18..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_geo_module.c
+++ /dev/null
@@ -1,1644 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_http_variable_value_t *value;
- u_short start;
- u_short end;
-} ngx_http_geo_range_t;
-
-
-typedef struct {
- ngx_radix_tree_t *tree;
-#if (NGX_HAVE_INET6)
- ngx_radix_tree_t *tree6;
-#endif
-} ngx_http_geo_trees_t;
-
-
-typedef struct {
- ngx_http_geo_range_t **low;
- ngx_http_variable_value_t *default_value;
-} ngx_http_geo_high_ranges_t;
-
-
-typedef struct {
- ngx_str_node_t sn;
- ngx_http_variable_value_t *value;
- size_t offset;
-} ngx_http_geo_variable_value_node_t;
-
-
-typedef struct {
- ngx_http_variable_value_t *value;
- ngx_str_t *net;
- ngx_http_geo_high_ranges_t high;
- ngx_radix_tree_t *tree;
-#if (NGX_HAVE_INET6)
- ngx_radix_tree_t *tree6;
-#endif
- ngx_rbtree_t rbtree;
- ngx_rbtree_node_t sentinel;
- ngx_array_t *proxies;
- ngx_pool_t *pool;
- ngx_pool_t *temp_pool;
-
- size_t data_size;
-
- ngx_str_t include_name;
- ngx_uint_t includes;
- ngx_uint_t entries;
-
- unsigned ranges:1;
- unsigned outside_entries:1;
- unsigned allow_binary_include:1;
- unsigned binary_include:1;
- unsigned proxy_recursive:1;
-} ngx_http_geo_conf_ctx_t;
-
-
-typedef struct {
- union {
- ngx_http_geo_trees_t trees;
- ngx_http_geo_high_ranges_t high;
- } u;
-
- ngx_array_t *proxies;
- unsigned proxy_recursive:1;
-
- ngx_int_t index;
-} ngx_http_geo_ctx_t;
-
-
-static ngx_int_t ngx_http_geo_addr(ngx_http_request_t *r,
- ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr);
-static ngx_int_t ngx_http_geo_real_addr(ngx_http_request_t *r,
- ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr);
-static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static char *ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf);
-static char *ngx_http_geo_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
- ngx_str_t *value);
-static char *ngx_http_geo_add_range(ngx_conf_t *cf,
- ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end);
-static ngx_uint_t ngx_http_geo_delete_range(ngx_conf_t *cf,
- ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end);
-static char *ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
- ngx_str_t *value);
-static char *ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
- ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net);
-static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf,
- ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value);
-static char *ngx_http_geo_add_proxy(ngx_conf_t *cf,
- ngx_http_geo_conf_ctx_t *ctx, ngx_cidr_t *cidr);
-static ngx_int_t ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net,
- ngx_cidr_t *cidr);
-static char *ngx_http_geo_include(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
- ngx_str_t *name);
-static ngx_int_t ngx_http_geo_include_binary_base(ngx_conf_t *cf,
- ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *name);
-static void ngx_http_geo_create_binary_base(ngx_http_geo_conf_ctx_t *ctx);
-static u_char *ngx_http_geo_copy_values(u_char *base, u_char *p,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
-
-
-static ngx_command_t ngx_http_geo_commands[] = {
-
- { ngx_string("geo"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
- ngx_http_geo_block,
- NGX_HTTP_MAIN_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_geo_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_geo_module = {
- NGX_MODULE_V1,
- &ngx_http_geo_module_ctx, /* module context */
- ngx_http_geo_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-typedef struct {
- u_char GEORNG[6];
- u_char version;
- u_char ptr_size;
- uint32_t endianness;
- uint32_t crc32;
-} ngx_http_geo_header_t;
-
-
-static ngx_http_geo_header_t ngx_http_geo_header = {
- { 'G', 'E', 'O', 'R', 'N', 'G' }, 0, sizeof(void *), 0x12345678, 0
-};
-
-
-/* geo range is AF_INET only */
-
-static ngx_int_t
-ngx_http_geo_cidr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data;
-
- in_addr_t inaddr;
- ngx_addr_t addr;
- struct sockaddr_in *sin;
- ngx_http_variable_value_t *vv;
-#if (NGX_HAVE_INET6)
- u_char *p;
- struct in6_addr *inaddr6;
-#endif
-
- if (ngx_http_geo_addr(r, ctx, &addr) != NGX_OK) {
- vv = (ngx_http_variable_value_t *)
- ngx_radix32tree_find(ctx->u.trees.tree, INADDR_NONE);
- goto done;
- }
-
- switch (addr.sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
- p = inaddr6->s6_addr;
-
- if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
- inaddr = p[12] << 24;
- inaddr += p[13] << 16;
- inaddr += p[14] << 8;
- inaddr += p[15];
-
- vv = (ngx_http_variable_value_t *)
- ngx_radix32tree_find(ctx->u.trees.tree, inaddr);
-
- } else {
- vv = (ngx_http_variable_value_t *)
- ngx_radix128tree_find(ctx->u.trees.tree6, p);
- }
-
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) addr.sockaddr;
- inaddr = ntohl(sin->sin_addr.s_addr);
-
- vv = (ngx_http_variable_value_t *)
- ngx_radix32tree_find(ctx->u.trees.tree, inaddr);
-
- break;
- }
-
-done:
-
- *v = *vv;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http geo: %v", v);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_geo_range_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data;
-
- in_addr_t inaddr;
- ngx_addr_t addr;
- ngx_uint_t n;
- struct sockaddr_in *sin;
- ngx_http_geo_range_t *range;
-#if (NGX_HAVE_INET6)
- u_char *p;
- struct in6_addr *inaddr6;
-#endif
-
- *v = *ctx->u.high.default_value;
-
- if (ngx_http_geo_addr(r, ctx, &addr) == NGX_OK) {
-
- switch (addr.sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
-
- if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
- p = inaddr6->s6_addr;
-
- inaddr = p[12] << 24;
- inaddr += p[13] << 16;
- inaddr += p[14] << 8;
- inaddr += p[15];
-
- } else {
- inaddr = INADDR_NONE;
- }
-
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) addr.sockaddr;
- inaddr = ntohl(sin->sin_addr.s_addr);
- break;
- }
-
- } else {
- inaddr = INADDR_NONE;
- }
-
- if (ctx->u.high.low) {
- range = ctx->u.high.low[inaddr >> 16];
-
- if (range) {
- n = inaddr & 0xffff;
- do {
- if (n >= (ngx_uint_t) range->start
- && n <= (ngx_uint_t) range->end)
- {
- *v = *range->value;
- break;
- }
- } while ((++range)->value);
- }
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http geo: %v", v);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx,
- ngx_addr_t *addr)
-{
- ngx_array_t *xfwd;
-
- if (ngx_http_geo_real_addr(r, ctx, addr) != NGX_OK) {
- return NGX_ERROR;
- }
-
- xfwd = &r->headers_in.x_forwarded_for;
-
- if (xfwd->nelts > 0 && ctx->proxies != NULL) {
- (void) ngx_http_get_forwarded_addr(r, addr, xfwd, NULL,
- ctx->proxies, ctx->proxy_recursive);
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx,
- ngx_addr_t *addr)
-{
- ngx_http_variable_value_t *v;
-
- if (ctx->index == -1) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http geo started: %V", &r->connection->addr_text);
-
- addr->sockaddr = r->connection->sockaddr;
- addr->socklen = r->connection->socklen;
- /* addr->name = r->connection->addr_text; */
-
- return NGX_OK;
- }
-
- v = ngx_http_get_flushed_variable(r, ctx->index);
-
- if (v == NULL || v->not_found) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http geo not found");
-
- return NGX_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http geo started: %v", v);
-
- if (ngx_parse_addr(r->pool, addr, v->data, v->len) == NGX_OK) {
- return NGX_OK;
- }
-
- return NGX_ERROR;
-}
-
-
-static char *
-ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *rv;
- size_t len;
- ngx_str_t *value, name;
- ngx_uint_t i;
- ngx_conf_t save;
- ngx_pool_t *pool;
- ngx_array_t *a;
- ngx_http_variable_t *var;
- ngx_http_geo_ctx_t *geo;
- ngx_http_geo_conf_ctx_t ctx;
-#if (NGX_HAVE_INET6)
- static struct in6_addr zero;
-#endif
-
- value = cf->args->elts;
-
- geo = ngx_palloc(cf->pool, sizeof(ngx_http_geo_ctx_t));
- if (geo == NULL) {
- return NGX_CONF_ERROR;
- }
-
- name = value[1];
-
- if (name.data[0] != '$') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid variable name \"%V\"", &name);
- return NGX_CONF_ERROR;
- }
-
- name.len--;
- name.data++;
-
- if (cf->args->nelts == 3) {
-
- geo->index = ngx_http_get_variable_index(cf, &name);
- if (geo->index == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- name = value[2];
-
- if (name.data[0] != '$') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid variable name \"%V\"", &name);
- return NGX_CONF_ERROR;
- }
-
- name.len--;
- name.data++;
-
- } else {
- geo->index = -1;
- }
-
- var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
- if (var == NULL) {
- return NGX_CONF_ERROR;
- }
-
- pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
- if (pool == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(&ctx, sizeof(ngx_http_geo_conf_ctx_t));
-
- ctx.temp_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
- if (ctx.temp_pool == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_rbtree_init(&ctx.rbtree, &ctx.sentinel, ngx_str_rbtree_insert_value);
-
- ctx.pool = cf->pool;
- ctx.data_size = sizeof(ngx_http_geo_header_t)
- + sizeof(ngx_http_variable_value_t)
- + 0x10000 * sizeof(ngx_http_geo_range_t *);
- ctx.allow_binary_include = 1;
-
- save = *cf;
- cf->pool = pool;
- cf->ctx = &ctx;
- cf->handler = ngx_http_geo;
- cf->handler_conf = conf;
-
- rv = ngx_conf_parse(cf, NULL);
-
- *cf = save;
-
- geo->proxies = ctx.proxies;
- geo->proxy_recursive = ctx.proxy_recursive;
-
- if (ctx.ranges) {
-
- if (ctx.high.low && !ctx.binary_include) {
- for (i = 0; i < 0x10000; i++) {
- a = (ngx_array_t *) ctx.high.low[i];
-
- if (a == NULL || a->nelts == 0) {
- continue;
- }
-
- len = a->nelts * sizeof(ngx_http_geo_range_t);
-
- ctx.high.low[i] = ngx_palloc(cf->pool, len + sizeof(void *));
- if (ctx.high.low[i] == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memcpy(ctx.high.low[i], a->elts, len);
- ctx.high.low[i][a->nelts].value = NULL;
- ctx.data_size += len + sizeof(void *);
- }
-
- if (ctx.allow_binary_include
- && !ctx.outside_entries
- && ctx.entries > 100000
- && ctx.includes == 1)
- {
- ngx_http_geo_create_binary_base(&ctx);
- }
- }
-
- if (ctx.high.default_value == NULL) {
- ctx.high.default_value = &ngx_http_variable_null_value;
- }
-
- geo->u.high = ctx.high;
-
- var->get_handler = ngx_http_geo_range_variable;
- var->data = (uintptr_t) geo;
-
- ngx_destroy_pool(ctx.temp_pool);
- ngx_destroy_pool(pool);
-
- } else {
- if (ctx.tree == NULL) {
- ctx.tree = ngx_radix_tree_create(cf->pool, -1);
- if (ctx.tree == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- geo->u.trees.tree = ctx.tree;
-
-#if (NGX_HAVE_INET6)
- if (ctx.tree6 == NULL) {
- ctx.tree6 = ngx_radix_tree_create(cf->pool, -1);
- if (ctx.tree6 == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- geo->u.trees.tree6 = ctx.tree6;
-#endif
-
- var->get_handler = ngx_http_geo_cidr_variable;
- var->data = (uintptr_t) geo;
-
- ngx_destroy_pool(ctx.temp_pool);
- ngx_destroy_pool(pool);
-
- if (ngx_radix32tree_insert(ctx.tree, 0, 0,
- (uintptr_t) &ngx_http_variable_null_value)
- == NGX_ERROR)
- {
- return NGX_CONF_ERROR;
- }
-
- /* NGX_BUSY is okay (default was set explicitly) */
-
-#if (NGX_HAVE_INET6)
- if (ngx_radix128tree_insert(ctx.tree6, zero.s6_addr, zero.s6_addr,
- (uintptr_t) &ngx_http_variable_null_value)
- == NGX_ERROR)
- {
- return NGX_CONF_ERROR;
- }
-#endif
- }
-
- return rv;
-}
-
-
-static char *
-ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
-{
- char *rv;
- ngx_str_t *value;
- ngx_cidr_t cidr;
- ngx_http_geo_conf_ctx_t *ctx;
-
- ctx = cf->ctx;
-
- value = cf->args->elts;
-
- if (cf->args->nelts == 1) {
-
- if (ngx_strcmp(value[0].data, "ranges") == 0) {
-
- if (ctx->tree
-#if (NGX_HAVE_INET6)
- || ctx->tree6
-#endif
- )
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the \"ranges\" directive must be "
- "the first directive inside \"geo\" block");
- goto failed;
- }
-
- ctx->ranges = 1;
-
- rv = NGX_CONF_OK;
-
- goto done;
- }
-
- else if (ngx_strcmp(value[0].data, "proxy_recursive") == 0) {
- ctx->proxy_recursive = 1;
- rv = NGX_CONF_OK;
- goto done;
- }
- }
-
- if (cf->args->nelts != 2) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid number of the geo parameters");
- goto failed;
- }
-
- if (ngx_strcmp(value[0].data, "include") == 0) {
-
- rv = ngx_http_geo_include(cf, ctx, &value[1]);
-
- goto done;
-
- } else if (ngx_strcmp(value[0].data, "proxy") == 0) {
-
- if (ngx_http_geo_cidr_value(cf, &value[1], &cidr) != NGX_OK) {
- goto failed;
- }
-
- rv = ngx_http_geo_add_proxy(cf, ctx, &cidr);
-
- goto done;
- }
-
- if (ctx->ranges) {
- rv = ngx_http_geo_range(cf, ctx, value);
-
- } else {
- rv = ngx_http_geo_cidr(cf, ctx, value);
- }
-
-done:
-
- ngx_reset_pool(cf->pool);
-
- return rv;
-
-failed:
-
- ngx_reset_pool(cf->pool);
-
- return NGX_CONF_ERROR;
-}
-
-
-static char *
-ngx_http_geo_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
- ngx_str_t *value)
-{
- u_char *p, *last;
- in_addr_t start, end;
- ngx_str_t *net;
- ngx_uint_t del;
-
- if (ngx_strcmp(value[0].data, "default") == 0) {
-
- if (ctx->high.default_value) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "duplicate default geo range value: \"%V\", old value: \"%v\"",
- &value[1], ctx->high.default_value);
- }
-
- ctx->high.default_value = ngx_http_geo_value(cf, ctx, &value[1]);
- if (ctx->high.default_value == NULL) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
- }
-
- if (ctx->binary_include) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "binary geo range base \"%s\" cannot be mixed with usual entries",
- ctx->include_name.data);
- return NGX_CONF_ERROR;
- }
-
- if (ctx->high.low == NULL) {
- ctx->high.low = ngx_pcalloc(ctx->pool,
- 0x10000 * sizeof(ngx_http_geo_range_t *));
- if (ctx->high.low == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- ctx->entries++;
- ctx->outside_entries = 1;
-
- if (ngx_strcmp(value[0].data, "delete") == 0) {
- net = &value[1];
- del = 1;
-
- } else {
- net = &value[0];
- del = 0;
- }
-
- last = net->data + net->len;
-
- p = ngx_strlchr(net->data, last, '-');
-
- if (p == NULL) {
- goto invalid;
- }
-
- start = ngx_inet_addr(net->data, p - net->data);
-
- if (start == INADDR_NONE) {
- goto invalid;
- }
-
- start = ntohl(start);
-
- p++;
-
- end = ngx_inet_addr(p, last - p);
-
- if (end == INADDR_NONE) {
- goto invalid;
- }
-
- end = ntohl(end);
-
- if (start > end) {
- goto invalid;
- }
-
- if (del) {
- if (ngx_http_geo_delete_range(cf, ctx, start, end)) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "no address range \"%V\" to delete", net);
- }
-
- return NGX_CONF_OK;
- }
-
- ctx->value = ngx_http_geo_value(cf, ctx, &value[1]);
-
- if (ctx->value == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->net = net;
-
- return ngx_http_geo_add_range(cf, ctx, start, end);
-
-invalid:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid range \"%V\"", net);
-
- return NGX_CONF_ERROR;
-}
-
-
-/* the add procedure is optimized to add a growing up sequence */
-
-static char *
-ngx_http_geo_add_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
- in_addr_t start, in_addr_t end)
-{
- in_addr_t n;
- ngx_uint_t h, i, s, e;
- ngx_array_t *a;
- ngx_http_geo_range_t *range;
-
- for (n = start; n <= end; n = (n + 0x10000) & 0xffff0000) {
-
- h = n >> 16;
-
- if (n == start) {
- s = n & 0xffff;
- } else {
- s = 0;
- }
-
- if ((n | 0xffff) > end) {
- e = end & 0xffff;
-
- } else {
- e = 0xffff;
- }
-
- a = (ngx_array_t *) ctx->high.low[h];
-
- if (a == NULL) {
- a = ngx_array_create(ctx->temp_pool, 64,
- sizeof(ngx_http_geo_range_t));
- if (a == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->high.low[h] = (ngx_http_geo_range_t *) a;
- }
-
- i = a->nelts;
- range = a->elts;
-
- while (i) {
-
- i--;
-
- if (e < (ngx_uint_t) range[i].start) {
- continue;
- }
-
- if (s > (ngx_uint_t) range[i].end) {
-
- /* add after the range */
-
- range = ngx_array_push(a);
- if (range == NULL) {
- return NGX_CONF_ERROR;
- }
-
- range = a->elts;
-
- ngx_memmove(&range[i + 2], &range[i + 1],
- (a->nelts - 2 - i) * sizeof(ngx_http_geo_range_t));
-
- range[i + 1].start = (u_short) s;
- range[i + 1].end = (u_short) e;
- range[i + 1].value = ctx->value;
-
- goto next;
- }
-
- if (s == (ngx_uint_t) range[i].start
- && e == (ngx_uint_t) range[i].end)
- {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "duplicate range \"%V\", value: \"%v\", old value: \"%v\"",
- ctx->net, ctx->value, range[i].value);
-
- range[i].value = ctx->value;
-
- goto next;
- }
-
- if (s > (ngx_uint_t) range[i].start
- && e < (ngx_uint_t) range[i].end)
- {
- /* split the range and insert the new one */
-
- range = ngx_array_push(a);
- if (range == NULL) {
- return NGX_CONF_ERROR;
- }
-
- range = ngx_array_push(a);
- if (range == NULL) {
- return NGX_CONF_ERROR;
- }
-
- range = a->elts;
-
- ngx_memmove(&range[i + 3], &range[i + 1],
- (a->nelts - 3 - i) * sizeof(ngx_http_geo_range_t));
-
- range[i + 2].start = (u_short) (e + 1);
- range[i + 2].end = range[i].end;
- range[i + 2].value = range[i].value;
-
- range[i + 1].start = (u_short) s;
- range[i + 1].end = (u_short) e;
- range[i + 1].value = ctx->value;
-
- range[i].end = (u_short) (s - 1);
-
- goto next;
- }
-
- if (s == (ngx_uint_t) range[i].start
- && e < (ngx_uint_t) range[i].end)
- {
- /* shift the range start and insert the new range */
-
- range = ngx_array_push(a);
- if (range == NULL) {
- return NGX_CONF_ERROR;
- }
-
- range = a->elts;
-
- ngx_memmove(&range[i + 1], &range[i],
- (a->nelts - 1 - i) * sizeof(ngx_http_geo_range_t));
-
- range[i + 1].start = (u_short) (e + 1);
-
- range[i].start = (u_short) s;
- range[i].end = (u_short) e;
- range[i].value = ctx->value;
-
- goto next;
- }
-
- if (s > (ngx_uint_t) range[i].start
- && e == (ngx_uint_t) range[i].end)
- {
- /* shift the range end and insert the new range */
-
- range = ngx_array_push(a);
- if (range == NULL) {
- return NGX_CONF_ERROR;
- }
-
- range = a->elts;
-
- ngx_memmove(&range[i + 2], &range[i + 1],
- (a->nelts - 2 - i) * sizeof(ngx_http_geo_range_t));
-
- range[i + 1].start = (u_short) s;
- range[i + 1].end = (u_short) e;
- range[i + 1].value = ctx->value;
-
- range[i].end = (u_short) (s - 1);
-
- goto next;
- }
-
- s = (ngx_uint_t) range[i].start;
- e = (ngx_uint_t) range[i].end;
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "range \"%V\" overlaps \"%d.%d.%d.%d-%d.%d.%d.%d\"",
- ctx->net,
- h >> 8, h & 0xff, s >> 8, s & 0xff,
- h >> 8, h & 0xff, e >> 8, e & 0xff);
-
- return NGX_CONF_ERROR;
- }
-
- /* add the first range */
-
- range = ngx_array_push(a);
- if (range == NULL) {
- return NGX_CONF_ERROR;
- }
-
- range->start = (u_short) s;
- range->end = (u_short) e;
- range->value = ctx->value;
-
- next:
-
- continue;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_uint_t
-ngx_http_geo_delete_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
- in_addr_t start, in_addr_t end)
-{
- in_addr_t n;
- ngx_uint_t h, i, s, e, warn;
- ngx_array_t *a;
- ngx_http_geo_range_t *range;
-
- warn = 0;
-
- for (n = start; n <= end; n += 0x10000) {
-
- h = n >> 16;
-
- if (n == start) {
- s = n & 0xffff;
- } else {
- s = 0;
- }
-
- if ((n | 0xffff) > end) {
- e = end & 0xffff;
-
- } else {
- e = 0xffff;
- }
-
- a = (ngx_array_t *) ctx->high.low[h];
-
- if (a == NULL) {
- warn = 1;
- continue;
- }
-
- range = a->elts;
- for (i = 0; i < a->nelts; i++) {
-
- if (s == (ngx_uint_t) range[i].start
- && e == (ngx_uint_t) range[i].end)
- {
- ngx_memmove(&range[i], &range[i + 1],
- (a->nelts - 1 - i) * sizeof(ngx_http_geo_range_t));
-
- a->nelts--;
-
- break;
- }
-
- if (s != (ngx_uint_t) range[i].start
- && e != (ngx_uint_t) range[i].end)
- {
- continue;
- }
-
- warn = 1;
- }
- }
-
- return warn;
-}
-
-
-static char *
-ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
- ngx_str_t *value)
-{
- char *rv;
- ngx_int_t rc, del;
- ngx_str_t *net;
- ngx_cidr_t cidr;
-
- if (ctx->tree == NULL) {
- ctx->tree = ngx_radix_tree_create(ctx->pool, -1);
- if (ctx->tree == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
-#if (NGX_HAVE_INET6)
- if (ctx->tree6 == NULL) {
- ctx->tree6 = ngx_radix_tree_create(ctx->pool, -1);
- if (ctx->tree6 == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-#endif
-
- if (ngx_strcmp(value[0].data, "default") == 0) {
- cidr.family = AF_INET;
- cidr.u.in.addr = 0;
- cidr.u.in.mask = 0;
-
- rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]);
-
- if (rv != NGX_CONF_OK) {
- return rv;
- }
-
-#if (NGX_HAVE_INET6)
- cidr.family = AF_INET6;
- ngx_memzero(&cidr.u.in6, sizeof(ngx_in6_cidr_t));
-
- rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]);
-
- if (rv != NGX_CONF_OK) {
- return rv;
- }
-#endif
-
- return NGX_CONF_OK;
- }
-
- if (ngx_strcmp(value[0].data, "delete") == 0) {
- net = &value[1];
- del = 1;
-
- } else {
- net = &value[0];
- del = 0;
- }
-
- if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (cidr.family == AF_INET) {
- cidr.u.in.addr = ntohl(cidr.u.in.addr);
- cidr.u.in.mask = ntohl(cidr.u.in.mask);
- }
-
- if (del) {
- switch (cidr.family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- rc = ngx_radix128tree_delete(ctx->tree6,
- cidr.u.in6.addr.s6_addr,
- cidr.u.in6.mask.s6_addr);
- break;
-#endif
-
- default: /* AF_INET */
- rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr,
- cidr.u.in.mask);
- break;
- }
-
- if (rc != NGX_OK) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "no network \"%V\" to delete", net);
- }
-
- return NGX_CONF_OK;
- }
-
- return ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], net);
-}
-
-
-static char *
-ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
- ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net)
-{
- ngx_int_t rc;
- ngx_http_variable_value_t *val, *old;
-
- val = ngx_http_geo_value(cf, ctx, value);
-
- if (val == NULL) {
- return NGX_CONF_ERROR;
- }
-
- switch (cidr->family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr,
- cidr->u.in6.mask.s6_addr,
- (uintptr_t) val);
-
- if (rc == NGX_OK) {
- return NGX_CONF_OK;
- }
-
- if (rc == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- /* rc == NGX_BUSY */
-
- old = (ngx_http_variable_value_t *)
- ngx_radix128tree_find(ctx->tree6,
- cidr->u.in6.addr.s6_addr);
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
- net, val, old);
-
- rc = ngx_radix128tree_delete(ctx->tree6,
- cidr->u.in6.addr.s6_addr,
- cidr->u.in6.mask.s6_addr);
-
- if (rc == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
- return NGX_CONF_ERROR;
- }
-
- rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr,
- cidr->u.in6.mask.s6_addr,
- (uintptr_t) val);
-
- break;
-#endif
-
- default: /* AF_INET */
- rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr,
- cidr->u.in.mask, (uintptr_t) val);
-
- if (rc == NGX_OK) {
- return NGX_CONF_OK;
- }
-
- if (rc == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- /* rc == NGX_BUSY */
-
- old = (ngx_http_variable_value_t *)
- ngx_radix32tree_find(ctx->tree, cidr->u.in.addr);
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "duplicate network \"%V\", value: \"%v\", old value: \"%v\"",
- net, val, old);
-
- rc = ngx_radix32tree_delete(ctx->tree,
- cidr->u.in.addr, cidr->u.in.mask);
-
- if (rc == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree");
- return NGX_CONF_ERROR;
- }
-
- rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr,
- cidr->u.in.mask, (uintptr_t) val);
-
- break;
- }
-
- if (rc == NGX_OK) {
- return NGX_CONF_OK;
- }
-
- return NGX_CONF_ERROR;
-}
-
-
-static ngx_http_variable_value_t *
-ngx_http_geo_value(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
- ngx_str_t *value)
-{
- uint32_t hash;
- ngx_http_variable_value_t *val;
- ngx_http_geo_variable_value_node_t *gvvn;
-
- hash = ngx_crc32_long(value->data, value->len);
-
- gvvn = (ngx_http_geo_variable_value_node_t *)
- ngx_str_rbtree_lookup(&ctx->rbtree, value, hash);
-
- if (gvvn) {
- return gvvn->value;
- }
-
- val = ngx_palloc(ctx->pool, sizeof(ngx_http_variable_value_t));
- if (val == NULL) {
- return NULL;
- }
-
- val->len = value->len;
- val->data = ngx_pstrdup(ctx->pool, value);
- if (val->data == NULL) {
- return NULL;
- }
-
- val->valid = 1;
- val->no_cacheable = 0;
- val->not_found = 0;
-
- gvvn = ngx_palloc(ctx->temp_pool,
- sizeof(ngx_http_geo_variable_value_node_t));
- if (gvvn == NULL) {
- return NULL;
- }
-
- gvvn->sn.node.key = hash;
- gvvn->sn.str.len = val->len;
- gvvn->sn.str.data = val->data;
- gvvn->value = val;
- gvvn->offset = 0;
-
- ngx_rbtree_insert(&ctx->rbtree, &gvvn->sn.node);
-
- ctx->data_size += ngx_align(sizeof(ngx_http_variable_value_t) + value->len,
- sizeof(void *));
-
- return val;
-}
-
-
-static char *
-ngx_http_geo_add_proxy(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
- ngx_cidr_t *cidr)
-{
- ngx_cidr_t *c;
-
- if (ctx->proxies == NULL) {
- ctx->proxies = ngx_array_create(ctx->pool, 4, sizeof(ngx_cidr_t));
- if (ctx->proxies == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- c = ngx_array_push(ctx->proxies);
- if (c == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *c = *cidr;
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
-{
- ngx_int_t rc;
-
- if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
- cidr->family = AF_INET;
- cidr->u.in.addr = 0xffffffff;
- cidr->u.in.mask = 0xffffffff;
-
- return NGX_OK;
- }
-
- rc = ngx_ptocidr(net, cidr);
-
- if (rc == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net);
- return NGX_ERROR;
- }
-
- if (rc == NGX_DONE) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "low address bits of %V are meaningless", net);
- }
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_http_geo_include(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
- ngx_str_t *name)
-{
- char *rv;
- ngx_str_t file;
-
- file.len = name->len + 4;
- file.data = ngx_pnalloc(ctx->temp_pool, name->len + 5);
- if (file.data == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_sprintf(file.data, "%V.bin%Z", name);
-
- if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (ctx->ranges) {
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
-
- switch (ngx_http_geo_include_binary_base(cf, ctx, &file)) {
- case NGX_OK:
- return NGX_CONF_OK;
- case NGX_ERROR:
- return NGX_CONF_ERROR;
- default:
- break;
- }
- }
-
- file.len -= 4;
- file.data[file.len] = '\0';
-
- ctx->include_name = file;
-
- if (ctx->outside_entries) {
- ctx->allow_binary_include = 0;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);
-
- rv = ngx_conf_parse(cf, &file);
-
- ctx->includes++;
- ctx->outside_entries = 0;
-
- return rv;
-}
-
-
-static ngx_int_t
-ngx_http_geo_include_binary_base(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
- ngx_str_t *name)
-{
- u_char *base, ch;
- time_t mtime;
- size_t size, len;
- ssize_t n;
- uint32_t crc32;
- ngx_err_t err;
- ngx_int_t rc;
- ngx_uint_t i;
- ngx_file_t file;
- ngx_file_info_t fi;
- ngx_http_geo_range_t *range, **ranges;
- ngx_http_geo_header_t *header;
- ngx_http_variable_value_t *vv;
-
- ngx_memzero(&file, sizeof(ngx_file_t));
- file.name = *name;
- file.log = cf->log;
-
- file.fd = ngx_open_file(name->data, NGX_FILE_RDONLY, 0, 0);
- if (file.fd == NGX_INVALID_FILE) {
- err = ngx_errno;
- if (err != NGX_ENOENT) {
- ngx_conf_log_error(NGX_LOG_CRIT, cf, err,
- ngx_open_file_n " \"%s\" failed", name->data);
- }
- return NGX_DECLINED;
- }
-
- if (ctx->outside_entries) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "binary geo range base \"%s\" cannot be mixed with usual entries",
- name->data);
- rc = NGX_ERROR;
- goto done;
- }
-
- if (ctx->binary_include) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "second binary geo range base \"%s\" cannot be mixed with \"%s\"",
- name->data, ctx->include_name.data);
- rc = NGX_ERROR;
- goto done;
- }
-
- if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) {
- ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
- ngx_fd_info_n " \"%s\" failed", name->data);
- goto failed;
- }
-
- size = (size_t) ngx_file_size(&fi);
- mtime = ngx_file_mtime(&fi);
-
- ch = name->data[name->len - 4];
- name->data[name->len - 4] = '\0';
-
- if (ngx_file_info(name->data, &fi) == NGX_FILE_ERROR) {
- ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
- ngx_file_info_n " \"%s\" failed", name->data);
- goto failed;
- }
-
- name->data[name->len - 4] = ch;
-
- if (mtime < ngx_file_mtime(&fi)) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "stale binary geo range base \"%s\"", name->data);
- goto failed;
- }
-
- base = ngx_palloc(ctx->pool, size);
- if (base == NULL) {
- goto failed;
- }
-
- n = ngx_read_file(&file, base, size, 0);
-
- if (n == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
- ngx_read_file_n " \"%s\" failed", name->data);
- goto failed;
- }
-
- if ((size_t) n != size) {
- ngx_conf_log_error(NGX_LOG_CRIT, cf, 0,
- ngx_read_file_n " \"%s\" returned only %z bytes instead of %z",
- name->data, n, size);
- goto failed;
- }
-
- header = (ngx_http_geo_header_t *) base;
-
- if (size < 16 || ngx_memcmp(&ngx_http_geo_header, header, 12) != 0) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "incompatible binary geo range base \"%s\"", name->data);
- goto failed;
- }
-
- ngx_crc32_init(crc32);
-
- vv = (ngx_http_variable_value_t *) (base + sizeof(ngx_http_geo_header_t));
-
- while(vv->data) {
- len = ngx_align(sizeof(ngx_http_variable_value_t) + vv->len,
- sizeof(void *));
- ngx_crc32_update(&crc32, (u_char *) vv, len);
- vv->data += (size_t) base;
- vv = (ngx_http_variable_value_t *) ((u_char *) vv + len);
- }
- ngx_crc32_update(&crc32, (u_char *) vv, sizeof(ngx_http_variable_value_t));
- vv++;
-
- ranges = (ngx_http_geo_range_t **) vv;
-
- for (i = 0; i < 0x10000; i++) {
- ngx_crc32_update(&crc32, (u_char *) &ranges[i], sizeof(void *));
- if (ranges[i]) {
- ranges[i] = (ngx_http_geo_range_t *)
- ((u_char *) ranges[i] + (size_t) base);
- }
- }
-
- range = (ngx_http_geo_range_t *) &ranges[0x10000];
-
- while ((u_char *) range < base + size) {
- while (range->value) {
- ngx_crc32_update(&crc32, (u_char *) range,
- sizeof(ngx_http_geo_range_t));
- range->value = (ngx_http_variable_value_t *)
- ((u_char *) range->value + (size_t) base);
- range++;
- }
- ngx_crc32_update(&crc32, (u_char *) range, sizeof(void *));
- range = (ngx_http_geo_range_t *) ((u_char *) range + sizeof(void *));
- }
-
- ngx_crc32_final(crc32);
-
- if (crc32 != header->crc32) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "CRC32 mismatch in binary geo range base \"%s\"", name->data);
- goto failed;
- }
-
- ngx_conf_log_error(NGX_LOG_NOTICE, cf, 0,
- "using binary geo range base \"%s\"", name->data);
-
- ctx->include_name = *name;
- ctx->binary_include = 1;
- ctx->high.low = ranges;
- rc = NGX_OK;
-
- goto done;
-
-failed:
-
- rc = NGX_DECLINED;
-
-done:
-
- if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", name->data);
- }
-
- return rc;
-}
-
-
-static void
-ngx_http_geo_create_binary_base(ngx_http_geo_conf_ctx_t *ctx)
-{
- u_char *p;
- uint32_t hash;
- ngx_str_t s;
- ngx_uint_t i;
- ngx_file_mapping_t fm;
- ngx_http_geo_range_t *r, *range, **ranges;
- ngx_http_geo_header_t *header;
- ngx_http_geo_variable_value_node_t *gvvn;
-
- fm.name = ngx_pnalloc(ctx->temp_pool, ctx->include_name.len + 5);
- if (fm.name == NULL) {
- return;
- }
-
- ngx_sprintf(fm.name, "%V.bin%Z", &ctx->include_name);
-
- fm.size = ctx->data_size;
- fm.log = ctx->pool->log;
-
- ngx_log_error(NGX_LOG_NOTICE, fm.log, 0,
- "creating binary geo range base \"%s\"", fm.name);
-
- if (ngx_create_file_mapping(&fm) != NGX_OK) {
- return;
- }
-
- p = ngx_cpymem(fm.addr, &ngx_http_geo_header,
- sizeof(ngx_http_geo_header_t));
-
- p = ngx_http_geo_copy_values(fm.addr, p, ctx->rbtree.root,
- ctx->rbtree.sentinel);
-
- p += sizeof(ngx_http_variable_value_t);
-
- ranges = (ngx_http_geo_range_t **) p;
-
- p += 0x10000 * sizeof(ngx_http_geo_range_t *);
-
- for (i = 0; i < 0x10000; i++) {
- r = ctx->high.low[i];
- if (r == NULL) {
- continue;
- }
-
- range = (ngx_http_geo_range_t *) p;
- ranges[i] = (ngx_http_geo_range_t *) (p - (u_char *) fm.addr);
-
- do {
- s.len = r->value->len;
- s.data = r->value->data;
- hash = ngx_crc32_long(s.data, s.len);
- gvvn = (ngx_http_geo_variable_value_node_t *)
- ngx_str_rbtree_lookup(&ctx->rbtree, &s, hash);
-
- range->value = (ngx_http_variable_value_t *) gvvn->offset;
- range->start = r->start;
- range->end = r->end;
- range++;
-
- } while ((++r)->value);
-
- range->value = NULL;
-
- p = (u_char *) range + sizeof(void *);
- }
-
- header = fm.addr;
- header->crc32 = ngx_crc32_long((u_char *) fm.addr
- + sizeof(ngx_http_geo_header_t),
- fm.size - sizeof(ngx_http_geo_header_t));
-
- ngx_close_file_mapping(&fm);
-}
-
-
-static u_char *
-ngx_http_geo_copy_values(u_char *base, u_char *p, ngx_rbtree_node_t *node,
- ngx_rbtree_node_t *sentinel)
-{
- ngx_http_variable_value_t *vv;
- ngx_http_geo_variable_value_node_t *gvvn;
-
- if (node == sentinel) {
- return p;
- }
-
- gvvn = (ngx_http_geo_variable_value_node_t *) node;
- gvvn->offset = p - base;
-
- vv = (ngx_http_variable_value_t *) p;
- *vv = *gvvn->value;
- p += sizeof(ngx_http_variable_value_t);
- vv->data = (u_char *) (p - base);
-
- p = ngx_cpymem(p, gvvn->sn.str.data, gvvn->sn.str.len);
-
- p = ngx_align_ptr(p, sizeof(void *));
-
- p = ngx_http_geo_copy_values(base, p, node->left, sentinel);
-
- return ngx_http_geo_copy_values(base, p, node->right, sentinel);
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_geoip_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_geoip_module.c
deleted file mode 100644
index 576fc5f3cd3..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_geoip_module.c
+++ /dev/null
@@ -1,919 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-#include <GeoIP.h>
-#include <GeoIPCity.h>
-
-
-#define NGX_GEOIP_COUNTRY_CODE 0
-#define NGX_GEOIP_COUNTRY_CODE3 1
-#define NGX_GEOIP_COUNTRY_NAME 2
-
-
-typedef struct {
- GeoIP *country;
- GeoIP *org;
- GeoIP *city;
- ngx_array_t *proxies; /* array of ngx_cidr_t */
- ngx_flag_t proxy_recursive;
-#if (NGX_HAVE_GEOIP_V6)
- unsigned country_v6:1;
- unsigned org_v6:1;
- unsigned city_v6:1;
-#endif
-} ngx_http_geoip_conf_t;
-
-
-typedef struct {
- ngx_str_t *name;
- uintptr_t data;
-} ngx_http_geoip_var_t;
-
-
-typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *,
- u_long addr);
-
-
-ngx_http_geoip_variable_handler_pt ngx_http_geoip_country_functions[] = {
- GeoIP_country_code_by_ipnum,
- GeoIP_country_code3_by_ipnum,
- GeoIP_country_name_by_ipnum,
-};
-
-
-#if (NGX_HAVE_GEOIP_V6)
-
-typedef const char *(*ngx_http_geoip_variable_handler_v6_pt)(GeoIP *,
- geoipv6_t addr);
-
-
-ngx_http_geoip_variable_handler_v6_pt ngx_http_geoip_country_v6_functions[] = {
- GeoIP_country_code_by_ipnum_v6,
- GeoIP_country_code3_by_ipnum_v6,
- GeoIP_country_name_by_ipnum_v6,
-};
-
-#endif
-
-
-static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_geoip_org_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_geoip_city_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_geoip_region_name_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_geoip_city_float_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_geoip_city_int_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static GeoIPRecord *ngx_http_geoip_get_city_record(ngx_http_request_t *r);
-
-static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf);
-static void *ngx_http_geoip_create_conf(ngx_conf_t *cf);
-static char *ngx_http_geoip_init_conf(ngx_conf_t *cf, void *conf);
-static char *ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_geoip_proxy(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static ngx_int_t ngx_http_geoip_cidr_value(ngx_conf_t *cf, ngx_str_t *net,
- ngx_cidr_t *cidr);
-static void ngx_http_geoip_cleanup(void *data);
-
-
-static ngx_command_t ngx_http_geoip_commands[] = {
-
- { ngx_string("geoip_country"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE12,
- ngx_http_geoip_country,
- NGX_HTTP_MAIN_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("geoip_org"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE12,
- ngx_http_geoip_org,
- NGX_HTTP_MAIN_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("geoip_city"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE12,
- ngx_http_geoip_city,
- NGX_HTTP_MAIN_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("geoip_proxy"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_http_geoip_proxy,
- NGX_HTTP_MAIN_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("geoip_proxy_recursive"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_MAIN_CONF_OFFSET,
- offsetof(ngx_http_geoip_conf_t, proxy_recursive),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_geoip_module_ctx = {
- ngx_http_geoip_add_variables, /* preconfiguration */
- NULL, /* postconfiguration */
-
- ngx_http_geoip_create_conf, /* create main configuration */
- ngx_http_geoip_init_conf, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_geoip_module = {
- NGX_MODULE_V1,
- &ngx_http_geoip_module_ctx, /* module context */
- ngx_http_geoip_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_variable_t ngx_http_geoip_vars[] = {
-
- { ngx_string("geoip_country_code"), NULL,
- ngx_http_geoip_country_variable,
- NGX_GEOIP_COUNTRY_CODE, 0, 0 },
-
- { ngx_string("geoip_country_code3"), NULL,
- ngx_http_geoip_country_variable,
- NGX_GEOIP_COUNTRY_CODE3, 0, 0 },
-
- { ngx_string("geoip_country_name"), NULL,
- ngx_http_geoip_country_variable,
- NGX_GEOIP_COUNTRY_NAME, 0, 0 },
-
- { ngx_string("geoip_org"), NULL,
- ngx_http_geoip_org_variable,
- 0, 0, 0 },
-
- { ngx_string("geoip_city_continent_code"), NULL,
- ngx_http_geoip_city_variable,
- offsetof(GeoIPRecord, continent_code), 0, 0 },
-
- { ngx_string("geoip_city_country_code"), NULL,
- ngx_http_geoip_city_variable,
- offsetof(GeoIPRecord, country_code), 0, 0 },
-
- { ngx_string("geoip_city_country_code3"), NULL,
- ngx_http_geoip_city_variable,
- offsetof(GeoIPRecord, country_code3), 0, 0 },
-
- { ngx_string("geoip_city_country_name"), NULL,
- ngx_http_geoip_city_variable,
- offsetof(GeoIPRecord, country_name), 0, 0 },
-
- { ngx_string("geoip_region"), NULL,
- ngx_http_geoip_city_variable,
- offsetof(GeoIPRecord, region), 0, 0 },
-
- { ngx_string("geoip_region_name"), NULL,
- ngx_http_geoip_region_name_variable,
- 0, 0, 0 },
-
- { ngx_string("geoip_city"), NULL,
- ngx_http_geoip_city_variable,
- offsetof(GeoIPRecord, city), 0, 0 },
-
- { ngx_string("geoip_postal_code"), NULL,
- ngx_http_geoip_city_variable,
- offsetof(GeoIPRecord, postal_code), 0, 0 },
-
- { ngx_string("geoip_latitude"), NULL,
- ngx_http_geoip_city_float_variable,
- offsetof(GeoIPRecord, latitude), 0, 0 },
-
- { ngx_string("geoip_longitude"), NULL,
- ngx_http_geoip_city_float_variable,
- offsetof(GeoIPRecord, longitude), 0, 0 },
-
- { ngx_string("geoip_dma_code"), NULL,
- ngx_http_geoip_city_int_variable,
- offsetof(GeoIPRecord, dma_code), 0, 0 },
-
- { ngx_string("geoip_area_code"), NULL,
- ngx_http_geoip_city_int_variable,
- offsetof(GeoIPRecord, area_code), 0, 0 },
-
- { ngx_null_string, NULL, NULL, 0, 0, 0 }
-};
-
-
-static u_long
-ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
-{
- ngx_addr_t addr;
- ngx_array_t *xfwd;
- struct sockaddr_in *sin;
-
- addr.sockaddr = r->connection->sockaddr;
- addr.socklen = r->connection->socklen;
- /* addr.name = r->connection->addr_text; */
-
- xfwd = &r->headers_in.x_forwarded_for;
-
- if (xfwd->nelts > 0 && gcf->proxies != NULL) {
- (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
- gcf->proxies, gcf->proxy_recursive);
- }
-
-#if (NGX_HAVE_INET6)
-
- if (addr.sockaddr->sa_family == AF_INET6) {
- u_char *p;
- in_addr_t inaddr;
- struct in6_addr *inaddr6;
-
- inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;
-
- if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
- p = inaddr6->s6_addr;
-
- inaddr = p[12] << 24;
- inaddr += p[13] << 16;
- inaddr += p[14] << 8;
- inaddr += p[15];
-
- return inaddr;
- }
- }
-
-#endif
-
- if (addr.sockaddr->sa_family != AF_INET) {
- return INADDR_NONE;
- }
-
- sin = (struct sockaddr_in *) addr.sockaddr;
- return ntohl(sin->sin_addr.s_addr);
-}
-
-
-#if (NGX_HAVE_GEOIP_V6)
-
-static geoipv6_t
-ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
-{
- ngx_addr_t addr;
- ngx_array_t *xfwd;
- in_addr_t addr4;
- struct in6_addr addr6;
- struct sockaddr_in *sin;
- struct sockaddr_in6 *sin6;
-
- addr.sockaddr = r->connection->sockaddr;
- addr.socklen = r->connection->socklen;
- /* addr.name = r->connection->addr_text; */
-
- xfwd = &r->headers_in.x_forwarded_for;
-
- if (xfwd->nelts > 0 && gcf->proxies != NULL) {
- (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
- gcf->proxies, gcf->proxy_recursive);
- }
-
- switch (addr.sockaddr->sa_family) {
-
- case AF_INET:
- /* Produce IPv4-mapped IPv6 address. */
- sin = (struct sockaddr_in *) addr.sockaddr;
- addr4 = ntohl(sin->sin_addr.s_addr);
-
- ngx_memzero(&addr6, sizeof(struct in6_addr));
- addr6.s6_addr[10] = 0xff;
- addr6.s6_addr[11] = 0xff;
- addr6.s6_addr[12] = addr4 >> 24;
- addr6.s6_addr[13] = addr4 >> 16;
- addr6.s6_addr[14] = addr4 >> 8;
- addr6.s6_addr[15] = addr4;
- return addr6;
-
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) addr.sockaddr;
- return sin6->sin6_addr;
-
- default:
- return in6addr_any;
- }
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_geoip_country_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_http_geoip_variable_handler_pt handler =
- ngx_http_geoip_country_functions[data];
-#if (NGX_HAVE_GEOIP_V6)
- ngx_http_geoip_variable_handler_v6_pt handler_v6 =
- ngx_http_geoip_country_v6_functions[data];
-#endif
-
- const char *val;
- ngx_http_geoip_conf_t *gcf;
-
- gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
-
- if (gcf->country == NULL) {
- goto not_found;
- }
-
-#if (NGX_HAVE_GEOIP_V6)
- val = gcf->country_v6
- ? handler_v6(gcf->country, ngx_http_geoip_addr_v6(r, gcf))
- : handler(gcf->country, ngx_http_geoip_addr(r, gcf));
-#else
- val = handler(gcf->country, ngx_http_geoip_addr(r, gcf));
-#endif
-
- if (val == NULL) {
- goto not_found;
- }
-
- v->len = ngx_strlen(val);
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = (u_char *) val;
-
- return NGX_OK;
-
-not_found:
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_geoip_org_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- size_t len;
- char *val;
- ngx_http_geoip_conf_t *gcf;
-
- gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
-
- if (gcf->org == NULL) {
- goto not_found;
- }
-
-#if (NGX_HAVE_GEOIP_V6)
- val = gcf->org_v6
- ? GeoIP_name_by_ipnum_v6(gcf->org,
- ngx_http_geoip_addr_v6(r, gcf))
- : GeoIP_name_by_ipnum(gcf->org,
- ngx_http_geoip_addr(r, gcf));
-#else
- val = GeoIP_name_by_ipnum(gcf->org, ngx_http_geoip_addr(r, gcf));
-#endif
-
- if (val == NULL) {
- goto not_found;
- }
-
- len = ngx_strlen(val);
- v->data = ngx_pnalloc(r->pool, len);
- if (v->data == NULL) {
- ngx_free(val);
- return NGX_ERROR;
- }
-
- ngx_memcpy(v->data, val, len);
-
- v->len = len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- ngx_free(val);
-
- return NGX_OK;
-
-not_found:
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_geoip_city_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- char *val;
- size_t len;
- GeoIPRecord *gr;
-
- gr = ngx_http_geoip_get_city_record(r);
- if (gr == NULL) {
- goto not_found;
- }
-
- val = *(char **) ((char *) gr + data);
- if (val == NULL) {
- goto no_value;
- }
-
- len = ngx_strlen(val);
- v->data = ngx_pnalloc(r->pool, len);
- if (v->data == NULL) {
- GeoIPRecord_delete(gr);
- return NGX_ERROR;
- }
-
- ngx_memcpy(v->data, val, len);
-
- v->len = len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- GeoIPRecord_delete(gr);
-
- return NGX_OK;
-
-no_value:
-
- GeoIPRecord_delete(gr);
-
-not_found:
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_geoip_region_name_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- size_t len;
- const char *val;
- GeoIPRecord *gr;
-
- gr = ngx_http_geoip_get_city_record(r);
- if (gr == NULL) {
- goto not_found;
- }
-
- val = GeoIP_region_name_by_code(gr->country_code, gr->region);
-
- GeoIPRecord_delete(gr);
-
- if (val == NULL) {
- goto not_found;
- }
-
- len = ngx_strlen(val);
- v->data = ngx_pnalloc(r->pool, len);
- if (v->data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(v->data, val, len);
-
- v->len = len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- return NGX_OK;
-
-not_found:
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_geoip_city_float_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- float val;
- GeoIPRecord *gr;
-
- gr = ngx_http_geoip_get_city_record(r);
- if (gr == NULL) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- v->data = ngx_pnalloc(r->pool, NGX_INT64_LEN + 5);
- if (v->data == NULL) {
- GeoIPRecord_delete(gr);
- return NGX_ERROR;
- }
-
- val = *(float *) ((char *) gr + data);
-
- v->len = ngx_sprintf(v->data, "%.4f", val) - v->data;
-
- GeoIPRecord_delete(gr);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_geoip_city_int_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- int val;
- GeoIPRecord *gr;
-
- gr = ngx_http_geoip_get_city_record(r);
- if (gr == NULL) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- v->data = ngx_pnalloc(r->pool, NGX_INT64_LEN);
- if (v->data == NULL) {
- GeoIPRecord_delete(gr);
- return NGX_ERROR;
- }
-
- val = *(int *) ((char *) gr + data);
-
- v->len = ngx_sprintf(v->data, "%d", val) - v->data;
-
- GeoIPRecord_delete(gr);
-
- return NGX_OK;
-}
-
-
-static GeoIPRecord *
-ngx_http_geoip_get_city_record(ngx_http_request_t *r)
-{
- ngx_http_geoip_conf_t *gcf;
-
- gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
-
- if (gcf->city) {
-#if (NGX_HAVE_GEOIP_V6)
- return gcf->city_v6
- ? GeoIP_record_by_ipnum_v6(gcf->city,
- ngx_http_geoip_addr_v6(r, gcf))
- : GeoIP_record_by_ipnum(gcf->city,
- ngx_http_geoip_addr(r, gcf));
-#else
- return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r, gcf));
-#endif
- }
-
- return NULL;
-}
-
-
-static ngx_int_t
-ngx_http_geoip_add_variables(ngx_conf_t *cf)
-{
- ngx_http_variable_t *var, *v;
-
- for (v = ngx_http_geoip_vars; v->name.len; v++) {
- var = ngx_http_add_variable(cf, &v->name, v->flags);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = v->get_handler;
- var->data = v->data;
- }
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_geoip_create_conf(ngx_conf_t *cf)
-{
- ngx_pool_cleanup_t *cln;
- ngx_http_geoip_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_geoip_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- conf->proxy_recursive = NGX_CONF_UNSET;
-
- cln = ngx_pool_cleanup_add(cf->pool, 0);
- if (cln == NULL) {
- return NULL;
- }
-
- cln->handler = ngx_http_geoip_cleanup;
- cln->data = conf;
-
- return conf;
-}
-
-
-static char *
-ngx_http_geoip_init_conf(ngx_conf_t *cf, void *conf)
-{
- ngx_http_geoip_conf_t *gcf = conf;
-
- ngx_conf_init_value(gcf->proxy_recursive, 0);
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_geoip_conf_t *gcf = conf;
-
- ngx_str_t *value;
-
- if (gcf->country) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- gcf->country = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
-
- if (gcf->country == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "GeoIP_open(\"%V\") failed", &value[1]);
-
- return NGX_CONF_ERROR;
- }
-
- if (cf->args->nelts == 3) {
- if (ngx_strcmp(value[2].data, "utf8") == 0) {
- GeoIP_set_charset (gcf->country, GEOIP_CHARSET_UTF8);
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[2]);
- return NGX_CONF_ERROR;
- }
- }
-
- switch (gcf->country->databaseType) {
-
- case GEOIP_COUNTRY_EDITION:
-
- return NGX_CONF_OK;
-
-#if (NGX_HAVE_GEOIP_V6)
- case GEOIP_COUNTRY_EDITION_V6:
-
- gcf->country_v6 = 1;
- return NGX_CONF_OK;
-#endif
-
- default:
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid GeoIP database \"%V\" type:%d",
- &value[1], gcf->country->databaseType);
- return NGX_CONF_ERROR;
- }
-}
-
-
-static char *
-ngx_http_geoip_org(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_geoip_conf_t *gcf = conf;
-
- ngx_str_t *value;
-
- if (gcf->org) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- gcf->org = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
-
- if (gcf->org == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "GeoIP_open(\"%V\") failed", &value[1]);
-
- return NGX_CONF_ERROR;
- }
-
- if (cf->args->nelts == 3) {
- if (ngx_strcmp(value[2].data, "utf8") == 0) {
- GeoIP_set_charset (gcf->org, GEOIP_CHARSET_UTF8);
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[2]);
- return NGX_CONF_ERROR;
- }
- }
-
- switch (gcf->org->databaseType) {
-
- case GEOIP_ISP_EDITION:
- case GEOIP_ORG_EDITION:
- case GEOIP_DOMAIN_EDITION:
- case GEOIP_ASNUM_EDITION:
-
- return NGX_CONF_OK;
-
-#if (NGX_HAVE_GEOIP_V6)
- case GEOIP_ISP_EDITION_V6:
- case GEOIP_ORG_EDITION_V6:
- case GEOIP_DOMAIN_EDITION_V6:
- case GEOIP_ASNUM_EDITION_V6:
-
- gcf->org_v6 = 1;
- return NGX_CONF_OK;
-#endif
-
- default:
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid GeoIP database \"%V\" type:%d",
- &value[1], gcf->org->databaseType);
- return NGX_CONF_ERROR;
- }
-}
-
-
-static char *
-ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_geoip_conf_t *gcf = conf;
-
- ngx_str_t *value;
-
- if (gcf->city) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- gcf->city = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
-
- if (gcf->city == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "GeoIP_open(\"%V\") failed", &value[1]);
-
- return NGX_CONF_ERROR;
- }
-
- if (cf->args->nelts == 3) {
- if (ngx_strcmp(value[2].data, "utf8") == 0) {
- GeoIP_set_charset (gcf->city, GEOIP_CHARSET_UTF8);
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[2]);
- return NGX_CONF_ERROR;
- }
- }
-
- switch (gcf->city->databaseType) {
-
- case GEOIP_CITY_EDITION_REV0:
- case GEOIP_CITY_EDITION_REV1:
-
- return NGX_CONF_OK;
-
-#if (NGX_HAVE_GEOIP_V6)
- case GEOIP_CITY_EDITION_REV0_V6:
- case GEOIP_CITY_EDITION_REV1_V6:
-
- gcf->city_v6 = 1;
- return NGX_CONF_OK;
-#endif
-
- default:
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid GeoIP City database \"%V\" type:%d",
- &value[1], gcf->city->databaseType);
- return NGX_CONF_ERROR;
- }
-}
-
-
-static char *
-ngx_http_geoip_proxy(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_geoip_conf_t *gcf = conf;
-
- ngx_str_t *value;
- ngx_cidr_t cidr, *c;
-
- value = cf->args->elts;
-
- if (ngx_http_geoip_cidr_value(cf, &value[1], &cidr) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (gcf->proxies == NULL) {
- gcf->proxies = ngx_array_create(cf->pool, 4, sizeof(ngx_cidr_t));
- if (gcf->proxies == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- c = ngx_array_push(gcf->proxies);
- if (c == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *c = cidr;
-
- return NGX_CONF_OK;
-}
-
-static ngx_int_t
-ngx_http_geoip_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
-{
- ngx_int_t rc;
-
- if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
- cidr->family = AF_INET;
- cidr->u.in.addr = 0xffffffff;
- cidr->u.in.mask = 0xffffffff;
-
- return NGX_OK;
- }
-
- rc = ngx_ptocidr(net, cidr);
-
- if (rc == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net);
- return NGX_ERROR;
- }
-
- if (rc == NGX_DONE) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "low address bits of %V are meaningless", net);
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_geoip_cleanup(void *data)
-{
- ngx_http_geoip_conf_t *gcf = data;
-
- if (gcf->country) {
- GeoIP_delete(gcf->country);
- }
-
- if (gcf->org) {
- GeoIP_delete(gcf->org);
- }
-
- if (gcf->city) {
- GeoIP_delete(gcf->city);
- }
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_gunzip_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_gunzip_filter_module.c
deleted file mode 100644
index adadc9da6dd..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_gunzip_filter_module.c
+++ /dev/null
@@ -1,681 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Maxim Dounin
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-#include <zlib.h>
-
-
-typedef struct {
- ngx_flag_t enable;
- ngx_bufs_t bufs;
-} ngx_http_gunzip_conf_t;
-
-
-typedef struct {
- ngx_chain_t *in;
- ngx_chain_t *free;
- ngx_chain_t *busy;
- ngx_chain_t *out;
- ngx_chain_t **last_out;
-
- ngx_buf_t *in_buf;
- ngx_buf_t *out_buf;
- ngx_int_t bufs;
-
- unsigned started:1;
- unsigned flush:4;
- unsigned redo:1;
- unsigned done:1;
- unsigned nomem:1;
-
- z_stream zstream;
- ngx_http_request_t *request;
-} ngx_http_gunzip_ctx_t;
-
-
-static ngx_int_t ngx_http_gunzip_filter_inflate_start(ngx_http_request_t *r,
- ngx_http_gunzip_ctx_t *ctx);
-static ngx_int_t ngx_http_gunzip_filter_add_data(ngx_http_request_t *r,
- ngx_http_gunzip_ctx_t *ctx);
-static ngx_int_t ngx_http_gunzip_filter_get_buf(ngx_http_request_t *r,
- ngx_http_gunzip_ctx_t *ctx);
-static ngx_int_t ngx_http_gunzip_filter_inflate(ngx_http_request_t *r,
- ngx_http_gunzip_ctx_t *ctx);
-static ngx_int_t ngx_http_gunzip_filter_inflate_end(ngx_http_request_t *r,
- ngx_http_gunzip_ctx_t *ctx);
-
-static void *ngx_http_gunzip_filter_alloc(void *opaque, u_int items,
- u_int size);
-static void ngx_http_gunzip_filter_free(void *opaque, void *address);
-
-static ngx_int_t ngx_http_gunzip_filter_init(ngx_conf_t *cf);
-static void *ngx_http_gunzip_create_conf(ngx_conf_t *cf);
-static char *ngx_http_gunzip_merge_conf(ngx_conf_t *cf,
- void *parent, void *child);
-
-
-static ngx_command_t ngx_http_gunzip_filter_commands[] = {
-
- { ngx_string("gunzip"),
- 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_gunzip_conf_t, enable),
- NULL },
-
- { ngx_string("gunzip_buffers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_conf_set_bufs_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_gunzip_conf_t, bufs),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_gunzip_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_gunzip_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_gunzip_create_conf, /* create location configuration */
- ngx_http_gunzip_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_gunzip_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_gunzip_filter_module_ctx, /* module context */
- ngx_http_gunzip_filter_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-
-
-static ngx_int_t
-ngx_http_gunzip_header_filter(ngx_http_request_t *r)
-{
- ngx_http_gunzip_ctx_t *ctx;
- ngx_http_gunzip_conf_t *conf;
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_gunzip_filter_module);
-
- /* TODO support multiple content-codings */
- /* TODO always gunzip - due to configuration or module request */
- /* TODO ignore content encoding? */
-
- if (!conf->enable
- || r->headers_out.content_encoding == NULL
- || r->headers_out.content_encoding->value.len != 4
- || ngx_strncasecmp(r->headers_out.content_encoding->value.data,
- (u_char *) "gzip", 4) != 0)
- {
- return ngx_http_next_header_filter(r);
- }
-
- r->gzip_vary = 1;
-
- if (!r->gzip_tested) {
- if (ngx_http_gzip_ok(r) == NGX_OK) {
- return ngx_http_next_header_filter(r);
- }
-
- } else if (r->gzip_ok) {
- return ngx_http_next_header_filter(r);
- }
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gunzip_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_gunzip_filter_module);
-
- ctx->request = r;
-
- r->filter_need_in_memory = 1;
-
- r->headers_out.content_encoding->hash = 0;
- r->headers_out.content_encoding = NULL;
-
- ngx_http_clear_content_length(r);
- ngx_http_clear_accept_ranges(r);
- ngx_http_clear_etag(r);
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_int_t
-ngx_http_gunzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- int rc;
- ngx_chain_t *cl;
- ngx_http_gunzip_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_gunzip_filter_module);
-
- if (ctx == NULL || ctx->done) {
- return ngx_http_next_body_filter(r, in);
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http gunzip filter");
-
- if (!ctx->started) {
- if (ngx_http_gunzip_filter_inflate_start(r, ctx) != NGX_OK) {
- goto failed;
- }
- }
-
- if (in) {
- if (ngx_chain_add_copy(r->pool, &ctx->in, in) != NGX_OK) {
- goto failed;
- }
- }
-
- if (ctx->nomem || in == NULL) {
-
- /* flush busy buffers */
-
- if (ngx_http_next_body_filter(r, NULL) == NGX_ERROR) {
- goto failed;
- }
-
- cl = NULL;
-
- ngx_chain_update_chains(r->pool, &ctx->free, &ctx->busy, &cl,
- (ngx_buf_tag_t) &ngx_http_gunzip_filter_module);
- ctx->nomem = 0;
- }
-
- for ( ;; ) {
-
- /* cycle while we can write to a client */
-
- for ( ;; ) {
-
- /* cycle while there is data to feed zlib and ... */
-
- rc = ngx_http_gunzip_filter_add_data(r, ctx);
-
- if (rc == NGX_DECLINED) {
- break;
- }
-
- if (rc == NGX_AGAIN) {
- continue;
- }
-
-
- /* ... there are buffers to write zlib output */
-
- rc = ngx_http_gunzip_filter_get_buf(r, ctx);
-
- if (rc == NGX_DECLINED) {
- break;
- }
-
- if (rc == NGX_ERROR) {
- goto failed;
- }
-
- rc = ngx_http_gunzip_filter_inflate(r, ctx);
-
- if (rc == NGX_OK) {
- break;
- }
-
- if (rc == NGX_ERROR) {
- goto failed;
- }
-
- /* rc == NGX_AGAIN */
- }
-
- if (ctx->out == NULL) {
- return ctx->busy ? NGX_AGAIN : NGX_OK;
- }
-
- rc = ngx_http_next_body_filter(r, ctx->out);
-
- if (rc == NGX_ERROR) {
- goto failed;
- }
-
- ngx_chain_update_chains(r->pool, &ctx->free, &ctx->busy, &ctx->out,
- (ngx_buf_tag_t) &ngx_http_gunzip_filter_module);
- ctx->last_out = &ctx->out;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "gunzip out: %p", ctx->out);
-
- ctx->nomem = 0;
-
- if (ctx->done) {
- return rc;
- }
- }
-
- /* unreachable */
-
-failed:
-
- ctx->done = 1;
-
- return NGX_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_gunzip_filter_inflate_start(ngx_http_request_t *r,
- ngx_http_gunzip_ctx_t *ctx)
-{
- int rc;
-
- ctx->zstream.next_in = Z_NULL;
- ctx->zstream.avail_in = 0;
-
- ctx->zstream.zalloc = ngx_http_gunzip_filter_alloc;
- ctx->zstream.zfree = ngx_http_gunzip_filter_free;
- ctx->zstream.opaque = ctx;
-
- /* windowBits +16 to decode gzip, zlib 1.2.0.4+ */
- rc = inflateInit2(&ctx->zstream, MAX_WBITS + 16);
-
- if (rc != Z_OK) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "inflateInit2() failed: %d", rc);
- return NGX_ERROR;
- }
-
- ctx->started = 1;
-
- ctx->last_out = &ctx->out;
- ctx->flush = Z_NO_FLUSH;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_gunzip_filter_add_data(ngx_http_request_t *r,
- ngx_http_gunzip_ctx_t *ctx)
-{
- if (ctx->zstream.avail_in || ctx->flush != Z_NO_FLUSH || ctx->redo) {
- return NGX_OK;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "gunzip in: %p", ctx->in);
-
- if (ctx->in == NULL) {
- return NGX_DECLINED;
- }
-
- ctx->in_buf = ctx->in->buf;
- ctx->in = ctx->in->next;
-
- ctx->zstream.next_in = ctx->in_buf->pos;
- ctx->zstream.avail_in = ctx->in_buf->last - ctx->in_buf->pos;
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "gunzip in_buf:%p ni:%p ai:%ud",
- ctx->in_buf,
- ctx->zstream.next_in, ctx->zstream.avail_in);
-
- if (ctx->in_buf->last_buf || ctx->in_buf->last_in_chain) {
- ctx->flush = Z_FINISH;
-
- } else if (ctx->in_buf->flush) {
- ctx->flush = Z_SYNC_FLUSH;
-
- } else if (ctx->zstream.avail_in == 0) {
- /* ctx->flush == Z_NO_FLUSH */
- return NGX_AGAIN;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_gunzip_filter_get_buf(ngx_http_request_t *r,
- ngx_http_gunzip_ctx_t *ctx)
-{
- ngx_http_gunzip_conf_t *conf;
-
- if (ctx->zstream.avail_out) {
- return NGX_OK;
- }
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_gunzip_filter_module);
-
- if (ctx->free) {
- ctx->out_buf = ctx->free->buf;
- ctx->free = ctx->free->next;
-
- ctx->out_buf->flush = 0;
-
- } else if (ctx->bufs < conf->bufs.num) {
-
- ctx->out_buf = ngx_create_temp_buf(r->pool, conf->bufs.size);
- if (ctx->out_buf == NULL) {
- return NGX_ERROR;
- }
-
- ctx->out_buf->tag = (ngx_buf_tag_t) &ngx_http_gunzip_filter_module;
- ctx->out_buf->recycled = 1;
- ctx->bufs++;
-
- } else {
- ctx->nomem = 1;
- return NGX_DECLINED;
- }
-
- ctx->zstream.next_out = ctx->out_buf->pos;
- ctx->zstream.avail_out = conf->bufs.size;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_gunzip_filter_inflate(ngx_http_request_t *r,
- ngx_http_gunzip_ctx_t *ctx)
-{
- int rc;
- ngx_buf_t *b;
- ngx_chain_t *cl;
-
- ngx_log_debug6(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "inflate in: ni:%p no:%p ai:%ud ao:%ud fl:%d redo:%d",
- ctx->zstream.next_in, ctx->zstream.next_out,
- ctx->zstream.avail_in, ctx->zstream.avail_out,
- ctx->flush, ctx->redo);
-
- rc = inflate(&ctx->zstream, ctx->flush);
-
- if (rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "inflate() failed: %d, %d", ctx->flush, rc);
- return NGX_ERROR;
- }
-
- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "inflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
- ctx->zstream.next_in, ctx->zstream.next_out,
- ctx->zstream.avail_in, ctx->zstream.avail_out,
- rc);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "gunzip in_buf:%p pos:%p",
- ctx->in_buf, ctx->in_buf->pos);
-
- if (ctx->zstream.next_in) {
- ctx->in_buf->pos = ctx->zstream.next_in;
-
- if (ctx->zstream.avail_in == 0) {
- ctx->zstream.next_in = NULL;
- }
- }
-
- ctx->out_buf->last = ctx->zstream.next_out;
-
- if (ctx->zstream.avail_out == 0) {
-
- /* zlib wants to output some more data */
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = ctx->out_buf;
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- ctx->redo = 1;
-
- return NGX_AGAIN;
- }
-
- ctx->redo = 0;
-
- if (ctx->flush == Z_SYNC_FLUSH) {
-
- ctx->flush = Z_NO_FLUSH;
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = ctx->out_buf;
-
- if (ngx_buf_size(b) == 0) {
-
- b = ngx_calloc_buf(ctx->request->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- } else {
- ctx->zstream.avail_out = 0;
- }
-
- b->flush = 1;
-
- cl->buf = b;
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- return NGX_OK;
- }
-
- if (ctx->flush == Z_FINISH && ctx->zstream.avail_in == 0) {
-
- if (rc != Z_STREAM_END) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "inflate() returned %d on response end", rc);
- return NGX_ERROR;
- }
-
- if (ngx_http_gunzip_filter_inflate_end(r, ctx) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
- }
-
- if (rc == Z_STREAM_END && ctx->zstream.avail_in > 0) {
-
- rc = inflateReset(&ctx->zstream);
-
- if (rc != Z_OK) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "inflateReset() failed: %d", rc);
- return NGX_ERROR;
- }
-
- ctx->redo = 1;
-
- return NGX_AGAIN;
- }
-
- if (ctx->in == NULL) {
-
- b = ctx->out_buf;
-
- if (ngx_buf_size(b) == 0) {
- return NGX_OK;
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- ctx->zstream.avail_out = 0;
-
- cl->buf = b;
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- return NGX_OK;
- }
-
- return NGX_AGAIN;
-}
-
-
-static ngx_int_t
-ngx_http_gunzip_filter_inflate_end(ngx_http_request_t *r,
- ngx_http_gunzip_ctx_t *ctx)
-{
- int rc;
- ngx_buf_t *b;
- ngx_chain_t *cl;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "gunzip inflate end");
-
- rc = inflateEnd(&ctx->zstream);
-
- if (rc != Z_OK) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "inflateEnd() failed: %d", rc);
- return NGX_ERROR;
- }
-
- b = ctx->out_buf;
-
- if (ngx_buf_size(b) == 0) {
-
- b = ngx_calloc_buf(ctx->request->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- b->last_buf = (r == r->main) ? 1 : 0;
- b->last_in_chain = 1;
- b->sync = 1;
-
- ctx->done = 1;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_gunzip_filter_alloc(void *opaque, u_int items, u_int size)
-{
- ngx_http_gunzip_ctx_t *ctx = opaque;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ctx->request->connection->log, 0,
- "gunzip alloc: n:%ud s:%ud",
- items, size);
-
- return ngx_palloc(ctx->request->pool, items * size);
-}
-
-
-static void
-ngx_http_gunzip_filter_free(void *opaque, void *address)
-{
-#if 0
- ngx_http_gunzip_ctx_t *ctx = opaque;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->request->connection->log, 0,
- "gunzip free: %p", address);
-#endif
-}
-
-
-static void *
-ngx_http_gunzip_create_conf(ngx_conf_t *cf)
-{
- ngx_http_gunzip_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_gunzip_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->bufs.num = 0;
- */
-
- conf->enable = NGX_CONF_UNSET;
-
- return conf;
-}
-
-
-static char *
-ngx_http_gunzip_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_gunzip_conf_t *prev = parent;
- ngx_http_gunzip_conf_t *conf = child;
-
- ngx_conf_merge_value(conf->enable, prev->enable, 0);
-
- ngx_conf_merge_bufs_value(conf->bufs, prev->bufs,
- (128 * 1024) / ngx_pagesize, ngx_pagesize);
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_gunzip_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_gunzip_header_filter;
-
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_gunzip_body_filter;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_gzip_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_gzip_filter_module.c
deleted file mode 100644
index ea1f1d0b9a2..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_gzip_filter_module.c
+++ /dev/null
@@ -1,1229 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-#include <zlib.h>
-
-
-typedef struct {
- ngx_flag_t enable;
- ngx_flag_t no_buffer;
-
- ngx_hash_t types;
-
- ngx_bufs_t bufs;
-
- size_t postpone_gzipping;
- ngx_int_t level;
- size_t wbits;
- size_t memlevel;
- ssize_t min_length;
-
- ngx_array_t *types_keys;
-} ngx_http_gzip_conf_t;
-
-
-typedef struct {
- ngx_chain_t *in;
- ngx_chain_t *free;
- ngx_chain_t *busy;
- ngx_chain_t *out;
- ngx_chain_t **last_out;
-
- ngx_chain_t *copied;
- ngx_chain_t *copy_buf;
-
- ngx_buf_t *in_buf;
- ngx_buf_t *out_buf;
- ngx_int_t bufs;
-
- void *preallocated;
- char *free_mem;
- ngx_uint_t allocated;
-
- int wbits;
- int memlevel;
-
- unsigned flush:4;
- unsigned redo:1;
- unsigned done:1;
- unsigned nomem:1;
- unsigned gzheader:1;
- unsigned buffering:1;
-
- size_t zin;
- size_t zout;
-
- uint32_t crc32;
- z_stream zstream;
- ngx_http_request_t *request;
-} ngx_http_gzip_ctx_t;
-
-
-#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED)
-
-struct gztrailer {
- uint32_t crc32;
- uint32_t zlen;
-};
-
-#else /* NGX_HAVE_BIG_ENDIAN || !NGX_HAVE_NONALIGNED */
-
-struct gztrailer {
- u_char crc32[4];
- u_char zlen[4];
-};
-
-#endif
-
-
-static void ngx_http_gzip_filter_memory(ngx_http_request_t *r,
- ngx_http_gzip_ctx_t *ctx);
-static ngx_int_t ngx_http_gzip_filter_buffer(ngx_http_gzip_ctx_t *ctx,
- ngx_chain_t *in);
-static ngx_int_t ngx_http_gzip_filter_deflate_start(ngx_http_request_t *r,
- ngx_http_gzip_ctx_t *ctx);
-static ngx_int_t ngx_http_gzip_filter_gzheader(ngx_http_request_t *r,
- ngx_http_gzip_ctx_t *ctx);
-static ngx_int_t ngx_http_gzip_filter_add_data(ngx_http_request_t *r,
- ngx_http_gzip_ctx_t *ctx);
-static ngx_int_t ngx_http_gzip_filter_get_buf(ngx_http_request_t *r,
- ngx_http_gzip_ctx_t *ctx);
-static ngx_int_t ngx_http_gzip_filter_deflate(ngx_http_request_t *r,
- ngx_http_gzip_ctx_t *ctx);
-static ngx_int_t ngx_http_gzip_filter_deflate_end(ngx_http_request_t *r,
- ngx_http_gzip_ctx_t *ctx);
-
-static void *ngx_http_gzip_filter_alloc(void *opaque, u_int items,
- u_int size);
-static void ngx_http_gzip_filter_free(void *opaque, void *address);
-static void ngx_http_gzip_filter_free_copy_buf(ngx_http_request_t *r,
- ngx_http_gzip_ctx_t *ctx);
-
-static ngx_int_t ngx_http_gzip_add_variables(ngx_conf_t *cf);
-static ngx_int_t ngx_http_gzip_ratio_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-
-static ngx_int_t ngx_http_gzip_filter_init(ngx_conf_t *cf);
-static void *ngx_http_gzip_create_conf(ngx_conf_t *cf);
-static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static char *ngx_http_gzip_window(ngx_conf_t *cf, void *post, void *data);
-static char *ngx_http_gzip_hash(ngx_conf_t *cf, void *post, void *data);
-
-
-static ngx_conf_num_bounds_t ngx_http_gzip_comp_level_bounds = {
- ngx_conf_check_num_bounds, 1, 9
-};
-
-static ngx_conf_post_handler_pt ngx_http_gzip_window_p = ngx_http_gzip_window;
-static ngx_conf_post_handler_pt ngx_http_gzip_hash_p = ngx_http_gzip_hash;
-
-
-static ngx_command_t ngx_http_gzip_filter_commands[] = {
-
- { ngx_string("gzip"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_gzip_conf_t, enable),
- NULL },
-
- { ngx_string("gzip_buffers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_conf_set_bufs_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_gzip_conf_t, bufs),
- NULL },
-
- { ngx_string("gzip_types"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_types_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_gzip_conf_t, types_keys),
- &ngx_http_html_default_types[0] },
-
- { ngx_string("gzip_comp_level"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_gzip_conf_t, level),
- &ngx_http_gzip_comp_level_bounds },
-
- { ngx_string("gzip_window"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_gzip_conf_t, wbits),
- &ngx_http_gzip_window_p },
-
- { ngx_string("gzip_hash"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_gzip_conf_t, memlevel),
- &ngx_http_gzip_hash_p },
-
- { ngx_string("postpone_gzipping"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_gzip_conf_t, postpone_gzipping),
- NULL },
-
- { ngx_string("gzip_no_buffer"),
- 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, no_buffer),
- NULL },
-
- { ngx_string("gzip_min_length"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_gzip_conf_t, min_length),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_gzip_filter_module_ctx = {
- ngx_http_gzip_add_variables, /* preconfiguration */
- ngx_http_gzip_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_gzip_create_conf, /* create location configuration */
- ngx_http_gzip_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_gzip_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_gzip_filter_module_ctx, /* module context */
- ngx_http_gzip_filter_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_str_t ngx_http_gzip_ratio = ngx_string("gzip_ratio");
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-
-
-static ngx_int_t
-ngx_http_gzip_header_filter(ngx_http_request_t *r)
-{
- ngx_table_elt_t *h;
- ngx_http_gzip_ctx_t *ctx;
- ngx_http_gzip_conf_t *conf;
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
-
- if (!conf->enable
- || (r->headers_out.status != NGX_HTTP_OK
- && r->headers_out.status != NGX_HTTP_FORBIDDEN
- && r->headers_out.status != NGX_HTTP_NOT_FOUND)
- || (r->headers_out.content_encoding
- && r->headers_out.content_encoding->value.len)
- || (r->headers_out.content_length_n != -1
- && r->headers_out.content_length_n < conf->min_length)
- || ngx_http_test_content_type(r, &conf->types) == NULL
- || r->header_only)
- {
- return ngx_http_next_header_filter(r);
- }
-
- r->gzip_vary = 1;
-
-#if (NGX_HTTP_DEGRADATION)
- {
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->gzip_disable_degradation && ngx_http_degraded(r)) {
- return ngx_http_next_header_filter(r);
- }
- }
-#endif
-
- if (!r->gzip_tested) {
- if (ngx_http_gzip_ok(r) != NGX_OK) {
- return ngx_http_next_header_filter(r);
- }
-
- } else if (!r->gzip_ok) {
- return ngx_http_next_header_filter(r);
- }
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gzip_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_gzip_filter_module);
-
- ctx->request = r;
- ctx->buffering = (conf->postpone_gzipping != 0);
-
- ngx_http_gzip_filter_memory(r, ctx);
-
- h = ngx_list_push(&r->headers_out.headers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- h->hash = 1;
- ngx_str_set(&h->key, "Content-Encoding");
- ngx_str_set(&h->value, "gzip");
- r->headers_out.content_encoding = h;
-
- r->main_filter_need_in_memory = 1;
-
- ngx_http_clear_content_length(r);
- ngx_http_clear_accept_ranges(r);
- ngx_http_clear_etag(r);
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_int_t
-ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- int rc;
- ngx_chain_t *cl;
- ngx_http_gzip_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module);
-
- if (ctx == NULL || ctx->done || r->header_only) {
- return ngx_http_next_body_filter(r, in);
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http gzip filter");
-
- if (ctx->buffering) {
-
- /*
- * With default memory settings zlib starts to output gzipped data
- * only after it has got about 90K, so it makes sense to allocate
- * zlib memory (200-400K) only after we have enough data to compress.
- * Although we copy buffers, nevertheless for not big responses
- * this allows to allocate zlib memory, to compress and to output
- * the response in one step using hot CPU cache.
- */
-
- if (in) {
- switch (ngx_http_gzip_filter_buffer(ctx, in)) {
-
- case NGX_OK:
- return NGX_OK;
-
- case NGX_DONE:
- in = NULL;
- break;
-
- default: /* NGX_ERROR */
- goto failed;
- }
-
- } else {
- ctx->buffering = 0;
- }
- }
-
- if (ctx->preallocated == NULL) {
- if (ngx_http_gzip_filter_deflate_start(r, ctx) != NGX_OK) {
- goto failed;
- }
- }
-
- if (in) {
- if (ngx_chain_add_copy(r->pool, &ctx->in, in) != NGX_OK) {
- goto failed;
- }
-
- r->connection->buffered |= NGX_HTTP_GZIP_BUFFERED;
- }
-
- if (ctx->nomem || in == NULL) {
-
- /* flush busy buffers */
-
- if (ngx_http_next_body_filter(r, NULL) == NGX_ERROR) {
- goto failed;
- }
-
- cl = NULL;
-
- ngx_chain_update_chains(r->pool, &ctx->free, &ctx->busy, &cl,
- (ngx_buf_tag_t) &ngx_http_gzip_filter_module);
- ctx->nomem = 0;
- }
-
- for ( ;; ) {
-
- /* cycle while we can write to a client */
-
- for ( ;; ) {
-
- /* cycle while there is data to feed zlib and ... */
-
- rc = ngx_http_gzip_filter_add_data(r, ctx);
-
- if (rc == NGX_DECLINED) {
- break;
- }
-
- if (rc == NGX_AGAIN) {
- continue;
- }
-
-
- /* ... there are buffers to write zlib output */
-
- rc = ngx_http_gzip_filter_get_buf(r, ctx);
-
- if (rc == NGX_DECLINED) {
- break;
- }
-
- if (rc == NGX_ERROR) {
- goto failed;
- }
-
-
- rc = ngx_http_gzip_filter_deflate(r, ctx);
-
- if (rc == NGX_OK) {
- break;
- }
-
- if (rc == NGX_ERROR) {
- goto failed;
- }
-
- /* rc == NGX_AGAIN */
- }
-
- if (ctx->out == NULL) {
- ngx_http_gzip_filter_free_copy_buf(r, ctx);
-
- return ctx->busy ? NGX_AGAIN : NGX_OK;
- }
-
- if (!ctx->gzheader) {
- if (ngx_http_gzip_filter_gzheader(r, ctx) != NGX_OK) {
- goto failed;
- }
- }
-
- rc = ngx_http_next_body_filter(r, ctx->out);
-
- if (rc == NGX_ERROR) {
- goto failed;
- }
-
- ngx_http_gzip_filter_free_copy_buf(r, ctx);
-
- ngx_chain_update_chains(r->pool, &ctx->free, &ctx->busy, &ctx->out,
- (ngx_buf_tag_t) &ngx_http_gzip_filter_module);
- ctx->last_out = &ctx->out;
-
- ctx->nomem = 0;
-
- if (ctx->done) {
- return rc;
- }
- }
-
- /* unreachable */
-
-failed:
-
- ctx->done = 1;
-
- if (ctx->preallocated) {
- deflateEnd(&ctx->zstream);
-
- ngx_pfree(r->pool, ctx->preallocated);
- }
-
- ngx_http_gzip_filter_free_copy_buf(r, ctx);
-
- return NGX_ERROR;
-}
-
-
-static void
-ngx_http_gzip_filter_memory(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
-{
- int wbits, memlevel;
- ngx_http_gzip_conf_t *conf;
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
-
- wbits = conf->wbits;
- memlevel = conf->memlevel;
-
- if (r->headers_out.content_length_n > 0) {
-
- /* the actual zlib window size is smaller by 262 bytes */
-
- while (r->headers_out.content_length_n < ((1 << (wbits - 1)) - 262)) {
- wbits--;
- memlevel--;
- }
-
- if (memlevel < 1) {
- memlevel = 1;
- }
- }
-
- ctx->wbits = wbits;
- ctx->memlevel = memlevel;
-
- /*
- * We preallocate a memory for zlib in one buffer (200K-400K), this
- * decreases a number of malloc() and free() calls and also probably
- * decreases a number of syscalls (sbrk()/mmap() and so on).
- * Besides we free the memory as soon as a gzipping will complete
- * and do not wait while a whole response will be sent to a client.
- *
- * 8K is for zlib deflate_state, it takes
- * *) 5816 bytes on i386 and sparc64 (32-bit mode)
- * *) 5920 bytes on amd64 and sparc64
- */
-
- ctx->allocated = 8192 + (1 << (wbits + 2)) + (1 << (memlevel + 9));
-}
-
-
-static ngx_int_t
-ngx_http_gzip_filter_buffer(ngx_http_gzip_ctx_t *ctx, ngx_chain_t *in)
-{
- size_t size, buffered;
- ngx_buf_t *b, *buf;
- ngx_chain_t *cl, **ll;
- ngx_http_request_t *r;
- ngx_http_gzip_conf_t *conf;
-
- r = ctx->request;
-
- r->connection->buffered |= NGX_HTTP_GZIP_BUFFERED;
-
- buffered = 0;
- ll = &ctx->in;
-
- for (cl = ctx->in; cl; cl = cl->next) {
- buffered += cl->buf->last - cl->buf->pos;
- ll = &cl->next;
- }
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
-
- while (in) {
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = in->buf;
-
- size = b->last - b->pos;
- buffered += size;
-
- if (b->flush || b->last_buf || buffered > conf->postpone_gzipping) {
- ctx->buffering = 0;
- }
-
- if (ctx->buffering && size) {
-
- buf = ngx_create_temp_buf(r->pool, size);
- if (buf == NULL) {
- return NGX_ERROR;
- }
-
- buf->last = ngx_cpymem(buf->pos, b->pos, size);
- b->pos = b->last;
-
- buf->last_buf = b->last_buf;
- buf->tag = (ngx_buf_tag_t) &ngx_http_gzip_filter_module;
-
- cl->buf = buf;
-
- } else {
- cl->buf = b;
- }
-
- *ll = cl;
- ll = &cl->next;
- in = in->next;
- }
-
- *ll = NULL;
-
- return ctx->buffering ? NGX_OK : NGX_DONE;
-}
-
-
-static ngx_int_t
-ngx_http_gzip_filter_deflate_start(ngx_http_request_t *r,
- ngx_http_gzip_ctx_t *ctx)
-{
- int rc;
- ngx_http_gzip_conf_t *conf;
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
-
- ctx->preallocated = ngx_palloc(r->pool, ctx->allocated);
- if (ctx->preallocated == NULL) {
- return NGX_ERROR;
- }
-
- ctx->free_mem = ctx->preallocated;
-
- ctx->zstream.zalloc = ngx_http_gzip_filter_alloc;
- ctx->zstream.zfree = ngx_http_gzip_filter_free;
- ctx->zstream.opaque = ctx;
-
- rc = deflateInit2(&ctx->zstream, (int) conf->level, Z_DEFLATED,
- - ctx->wbits, ctx->memlevel, Z_DEFAULT_STRATEGY);
-
- if (rc != Z_OK) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "deflateInit2() failed: %d", rc);
- return NGX_ERROR;
- }
-
- ctx->last_out = &ctx->out;
- ctx->crc32 = crc32(0L, Z_NULL, 0);
- ctx->flush = Z_NO_FLUSH;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_gzip_filter_gzheader(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
-{
- ngx_buf_t *b;
- ngx_chain_t *cl;
- static u_char gzheader[10] =
- { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 };
-
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- b->memory = 1;
- b->pos = gzheader;
- b->last = b->pos + 10;
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- cl->next = ctx->out;
- ctx->out = cl;
-
- ctx->gzheader = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
-{
- if (ctx->zstream.avail_in || ctx->flush != Z_NO_FLUSH || ctx->redo) {
- return NGX_OK;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "gzip in: %p", ctx->in);
-
- if (ctx->in == NULL) {
- return NGX_DECLINED;
- }
-
- if (ctx->copy_buf) {
-
- /*
- * to avoid CPU cache trashing we do not free() just quit buf,
- * but postpone free()ing after zlib compressing and data output
- */
-
- ctx->copy_buf->next = ctx->copied;
- ctx->copied = ctx->copy_buf;
- ctx->copy_buf = NULL;
- }
-
- ctx->in_buf = ctx->in->buf;
-
- if (ctx->in_buf->tag == (ngx_buf_tag_t) &ngx_http_gzip_filter_module) {
- ctx->copy_buf = ctx->in;
- }
-
- ctx->in = ctx->in->next;
-
- ctx->zstream.next_in = ctx->in_buf->pos;
- ctx->zstream.avail_in = ctx->in_buf->last - ctx->in_buf->pos;
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "gzip in_buf:%p ni:%p ai:%ud",
- ctx->in_buf,
- ctx->zstream.next_in, ctx->zstream.avail_in);
-
- if (ctx->in_buf->last_buf) {
- ctx->flush = Z_FINISH;
-
- } else if (ctx->in_buf->flush) {
- ctx->flush = Z_SYNC_FLUSH;
- }
-
- if (ctx->zstream.avail_in) {
-
- ctx->crc32 = crc32(ctx->crc32, ctx->zstream.next_in,
- ctx->zstream.avail_in);
-
- } else if (ctx->flush == Z_NO_FLUSH) {
- return NGX_AGAIN;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_gzip_filter_get_buf(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
-{
- ngx_http_gzip_conf_t *conf;
-
- if (ctx->zstream.avail_out) {
- return NGX_OK;
- }
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
-
- if (ctx->free) {
- ctx->out_buf = ctx->free->buf;
- ctx->free = ctx->free->next;
-
- } else if (ctx->bufs < conf->bufs.num) {
-
- ctx->out_buf = ngx_create_temp_buf(r->pool, conf->bufs.size);
- if (ctx->out_buf == NULL) {
- return NGX_ERROR;
- }
-
- ctx->out_buf->tag = (ngx_buf_tag_t) &ngx_http_gzip_filter_module;
- ctx->out_buf->recycled = 1;
- ctx->bufs++;
-
- } else {
- ctx->nomem = 1;
- return NGX_DECLINED;
- }
-
- ctx->zstream.next_out = ctx->out_buf->pos;
- ctx->zstream.avail_out = conf->bufs.size;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_gzip_filter_deflate(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
-{
- int rc;
- ngx_buf_t *b;
- ngx_chain_t *cl;
- ngx_http_gzip_conf_t *conf;
-
- ngx_log_debug6(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "deflate in: ni:%p no:%p ai:%ud ao:%ud fl:%d redo:%d",
- ctx->zstream.next_in, ctx->zstream.next_out,
- ctx->zstream.avail_in, ctx->zstream.avail_out,
- ctx->flush, ctx->redo);
-
- rc = deflate(&ctx->zstream, ctx->flush);
-
- if (rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "deflate() failed: %d, %d", ctx->flush, rc);
- return NGX_ERROR;
- }
-
- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "deflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
- ctx->zstream.next_in, ctx->zstream.next_out,
- ctx->zstream.avail_in, ctx->zstream.avail_out,
- rc);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "gzip in_buf:%p pos:%p",
- ctx->in_buf, ctx->in_buf->pos);
-
- if (ctx->zstream.next_in) {
- ctx->in_buf->pos = ctx->zstream.next_in;
-
- if (ctx->zstream.avail_in == 0) {
- ctx->zstream.next_in = NULL;
- }
- }
-
- ctx->out_buf->last = ctx->zstream.next_out;
-
- if (ctx->zstream.avail_out == 0) {
-
- /* zlib wants to output some more gzipped data */
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = ctx->out_buf;
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- ctx->redo = 1;
-
- return NGX_AGAIN;
- }
-
- ctx->redo = 0;
-
- if (ctx->flush == Z_SYNC_FLUSH) {
-
- ctx->flush = Z_NO_FLUSH;
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = ctx->out_buf;
-
- if (ngx_buf_size(b) == 0) {
-
- b = ngx_calloc_buf(ctx->request->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- } else {
- ctx->zstream.avail_out = 0;
- }
-
- b->flush = 1;
-
- cl->buf = b;
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- r->connection->buffered &= ~NGX_HTTP_GZIP_BUFFERED;
-
- return NGX_OK;
- }
-
- if (rc == Z_STREAM_END) {
-
- if (ngx_http_gzip_filter_deflate_end(r, ctx) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
- }
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
-
- if (conf->no_buffer && ctx->in == NULL) {
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = ctx->out_buf;
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- return NGX_OK;
- }
-
- return NGX_AGAIN;
-}
-
-
-static ngx_int_t
-ngx_http_gzip_filter_deflate_end(ngx_http_request_t *r,
- ngx_http_gzip_ctx_t *ctx)
-{
- int rc;
- ngx_buf_t *b;
- ngx_chain_t *cl;
- struct gztrailer *trailer;
-
- ctx->zin = ctx->zstream.total_in;
- ctx->zout = 10 + ctx->zstream.total_out + 8;
-
- rc = deflateEnd(&ctx->zstream);
-
- if (rc != Z_OK) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "deflateEnd() failed: %d", rc);
- return NGX_ERROR;
- }
-
- ngx_pfree(r->pool, ctx->preallocated);
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = ctx->out_buf;
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- if (ctx->zstream.avail_out >= 8) {
- trailer = (struct gztrailer *) ctx->out_buf->last;
- ctx->out_buf->last += 8;
- ctx->out_buf->last_buf = 1;
-
- } else {
- b = ngx_create_temp_buf(r->pool, 8);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- b->last_buf = 1;
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
- trailer = (struct gztrailer *) b->pos;
- b->last += 8;
- }
-
-#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED)
-
- trailer->crc32 = ctx->crc32;
- trailer->zlen = ctx->zin;
-
-#else
-
- trailer->crc32[0] = (u_char) (ctx->crc32 & 0xff);
- trailer->crc32[1] = (u_char) ((ctx->crc32 >> 8) & 0xff);
- trailer->crc32[2] = (u_char) ((ctx->crc32 >> 16) & 0xff);
- trailer->crc32[3] = (u_char) ((ctx->crc32 >> 24) & 0xff);
-
- trailer->zlen[0] = (u_char) (ctx->zin & 0xff);
- trailer->zlen[1] = (u_char) ((ctx->zin >> 8) & 0xff);
- trailer->zlen[2] = (u_char) ((ctx->zin >> 16) & 0xff);
- trailer->zlen[3] = (u_char) ((ctx->zin >> 24) & 0xff);
-
-#endif
-
- ctx->zstream.avail_in = 0;
- ctx->zstream.avail_out = 0;
-
- ctx->done = 1;
-
- r->connection->buffered &= ~NGX_HTTP_GZIP_BUFFERED;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_gzip_filter_alloc(void *opaque, u_int items, u_int size)
-{
- ngx_http_gzip_ctx_t *ctx = opaque;
-
- void *p;
- ngx_uint_t alloc;
-
- alloc = items * size;
-
- if (alloc % 512 != 0 && alloc < 8192) {
-
- /*
- * The zlib deflate_state allocation, it takes about 6K,
- * we allocate 8K. Other allocations are divisible by 512.
- */
-
- alloc = 8192;
- }
-
- if (alloc <= ctx->allocated) {
- p = ctx->free_mem;
- ctx->free_mem += alloc;
- ctx->allocated -= alloc;
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, ctx->request->connection->log, 0,
- "gzip alloc: n:%ud s:%ud a:%ud p:%p",
- items, size, alloc, p);
-
- return p;
- }
-
- ngx_log_error(NGX_LOG_ALERT, ctx->request->connection->log, 0,
- "gzip filter failed to use preallocated memory: %ud of %ud",
- items * size, ctx->allocated);
-
- p = ngx_palloc(ctx->request->pool, items * size);
-
- return p;
-}
-
-
-static void
-ngx_http_gzip_filter_free(void *opaque, void *address)
-{
-#if 0
- ngx_http_gzip_ctx_t *ctx = opaque;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->request->connection->log, 0,
- "gzip free: %p", address);
-#endif
-}
-
-
-static void
-ngx_http_gzip_filter_free_copy_buf(ngx_http_request_t *r,
- ngx_http_gzip_ctx_t *ctx)
-{
- ngx_chain_t *cl;
-
- for (cl = ctx->copied; cl; cl = cl->next) {
- ngx_pfree(r->pool, cl->buf->start);
- }
-
- ctx->copied = NULL;
-}
-
-
-static ngx_int_t
-ngx_http_gzip_add_variables(ngx_conf_t *cf)
-{
- ngx_http_variable_t *var;
-
- var = ngx_http_add_variable(cf, &ngx_http_gzip_ratio, NGX_HTTP_VAR_NOHASH);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = ngx_http_gzip_ratio_variable;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_gzip_ratio_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_uint_t zint, zfrac;
- ngx_http_gzip_ctx_t *ctx;
-
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module);
-
- if (ctx == NULL || ctx->zout == 0) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- v->data = ngx_pnalloc(r->pool, NGX_INT32_LEN + 3);
- if (v->data == NULL) {
- return NGX_ERROR;
- }
-
- zint = (ngx_uint_t) (ctx->zin / ctx->zout);
- zfrac = (ngx_uint_t) ((ctx->zin * 100 / ctx->zout) % 100);
-
- if ((ctx->zin * 1000 / ctx->zout) % 10 > 4) {
-
- /* the rounding, e.g., 2.125 to 2.13 */
-
- zfrac++;
-
- if (zfrac > 99) {
- zint++;
- zfrac = 0;
- }
- }
-
- v->len = ngx_sprintf(v->data, "%ui.%02ui", zint, zfrac) - v->data;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_gzip_create_conf(ngx_conf_t *cf)
-{
- ngx_http_gzip_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_gzip_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->bufs.num = 0;
- * conf->types = { NULL };
- * conf->types_keys = NULL;
- */
-
- conf->enable = NGX_CONF_UNSET;
- conf->no_buffer = NGX_CONF_UNSET;
-
- conf->postpone_gzipping = NGX_CONF_UNSET_SIZE;
- conf->level = NGX_CONF_UNSET;
- conf->wbits = NGX_CONF_UNSET_SIZE;
- conf->memlevel = NGX_CONF_UNSET_SIZE;
- conf->min_length = NGX_CONF_UNSET;
-
- return conf;
-}
-
-
-static char *
-ngx_http_gzip_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_gzip_conf_t *prev = parent;
- ngx_http_gzip_conf_t *conf = child;
-
- ngx_conf_merge_value(conf->enable, prev->enable, 0);
- ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0);
-
- ngx_conf_merge_bufs_value(conf->bufs, prev->bufs,
- (128 * 1024) / ngx_pagesize, ngx_pagesize);
-
- ngx_conf_merge_size_value(conf->postpone_gzipping, prev->postpone_gzipping,
- 0);
- ngx_conf_merge_value(conf->level, prev->level, 1);
- ngx_conf_merge_size_value(conf->wbits, prev->wbits, MAX_WBITS);
- ngx_conf_merge_size_value(conf->memlevel, prev->memlevel,
- MAX_MEM_LEVEL - 1);
- ngx_conf_merge_value(conf->min_length, prev->min_length, 20);
-
- if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
- &prev->types_keys, &prev->types,
- ngx_http_html_default_types)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_gzip_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_gzip_header_filter;
-
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_gzip_body_filter;
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_http_gzip_window(ngx_conf_t *cf, void *post, void *data)
-{
- size_t *np = data;
-
- size_t wbits, wsize;
-
- wbits = 15;
-
- for (wsize = 32 * 1024; wsize > 256; wsize >>= 1) {
-
- if (wsize == *np) {
- *np = wbits;
-
- return NGX_CONF_OK;
- }
-
- wbits--;
- }
-
- return "must be 512, 1k, 2k, 4k, 8k, 16k, or 32k";
-}
-
-
-static char *
-ngx_http_gzip_hash(ngx_conf_t *cf, void *post, void *data)
-{
- size_t *np = data;
-
- size_t memlevel, hsize;
-
- memlevel = 9;
-
- for (hsize = 128 * 1024; hsize > 256; hsize >>= 1) {
-
- if (hsize == *np) {
- *np = memlevel;
-
- return NGX_CONF_OK;
- }
-
- memlevel--;
- }
-
- return "must be 512, 1k, 2k, 4k, 8k, 16k, 32k, 64k, or 128k";
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_gzip_static_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_gzip_static_module.c
deleted file mode 100644
index 1746e550423..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_gzip_static_module.c
+++ /dev/null
@@ -1,333 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-#define NGX_HTTP_GZIP_STATIC_OFF 0
-#define NGX_HTTP_GZIP_STATIC_ON 1
-#define NGX_HTTP_GZIP_STATIC_ALWAYS 2
-
-
-typedef struct {
- ngx_uint_t enable;
-} ngx_http_gzip_static_conf_t;
-
-
-static ngx_int_t ngx_http_gzip_static_handler(ngx_http_request_t *r);
-static void *ngx_http_gzip_static_create_conf(ngx_conf_t *cf);
-static char *ngx_http_gzip_static_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static ngx_int_t ngx_http_gzip_static_init(ngx_conf_t *cf);
-
-
-static ngx_conf_enum_t ngx_http_gzip_static[] = {
- { ngx_string("off"), NGX_HTTP_GZIP_STATIC_OFF },
- { ngx_string("on"), NGX_HTTP_GZIP_STATIC_ON },
- { ngx_string("always"), NGX_HTTP_GZIP_STATIC_ALWAYS },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_command_t ngx_http_gzip_static_commands[] = {
-
- { ngx_string("gzip_static"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_gzip_static_conf_t, enable),
- &ngx_http_gzip_static },
-
- ngx_null_command
-};
-
-
-ngx_http_module_t ngx_http_gzip_static_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_gzip_static_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_gzip_static_create_conf, /* create location configuration */
- ngx_http_gzip_static_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_gzip_static_module = {
- NGX_MODULE_V1,
- &ngx_http_gzip_static_module_ctx, /* module context */
- ngx_http_gzip_static_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_gzip_static_handler(ngx_http_request_t *r)
-{
- u_char *p;
- size_t root;
- ngx_str_t path;
- ngx_int_t rc;
- ngx_uint_t level;
- ngx_log_t *log;
- ngx_buf_t *b;
- ngx_chain_t out;
- ngx_table_elt_t *h;
- ngx_open_file_info_t of;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_gzip_static_conf_t *gzcf;
-
- if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
- return NGX_DECLINED;
- }
-
- if (r->uri.data[r->uri.len - 1] == '/') {
- return NGX_DECLINED;
- }
-
- gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module);
-
- if (gzcf->enable == NGX_HTTP_GZIP_STATIC_OFF) {
- return NGX_DECLINED;
- }
-
- if (gzcf->enable == NGX_HTTP_GZIP_STATIC_ON) {
- rc = ngx_http_gzip_ok(r);
-
- } else {
- /* always */
- rc = NGX_OK;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (!clcf->gzip_vary && rc != NGX_OK) {
- return NGX_DECLINED;
- }
-
- log = r->connection->log;
-
- p = ngx_http_map_uri_to_path(r, &path, &root, sizeof(".gz") - 1);
- if (p == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- *p++ = '.';
- *p++ = 'g';
- *p++ = 'z';
- *p = '\0';
-
- path.len = p - path.data;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
- "http filename: \"%s\"", path.data);
-
- ngx_memzero(&of, sizeof(ngx_open_file_info_t));
-
- of.read_ahead = clcf->read_ahead;
- of.directio = clcf->directio;
- of.valid = clcf->open_file_cache_valid;
- of.min_uses = clcf->open_file_cache_min_uses;
- of.errors = clcf->open_file_cache_errors;
- of.events = clcf->open_file_cache_events;
-
- if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
- != NGX_OK)
- {
- switch (of.err) {
-
- case 0:
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
-
- case NGX_ENOENT:
- case NGX_ENOTDIR:
- case NGX_ENAMETOOLONG:
-
- return NGX_DECLINED;
-
- case NGX_EACCES:
-#if (NGX_HAVE_OPENAT)
- case NGX_EMLINK:
- case NGX_ELOOP:
-#endif
-
- level = NGX_LOG_ERR;
- break;
-
- default:
-
- level = NGX_LOG_CRIT;
- break;
- }
-
- ngx_log_error(level, log, of.err,
- "%s \"%s\" failed", of.failed, path.data);
-
- return NGX_DECLINED;
- }
-
- if (gzcf->enable == NGX_HTTP_GZIP_STATIC_ON) {
- r->gzip_vary = 1;
-
- if (rc != NGX_OK) {
- return NGX_DECLINED;
- }
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", of.fd);
-
- if (of.is_dir) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http dir");
- return NGX_DECLINED;
- }
-
-#if !(NGX_WIN32) /* the not regular files are probably Unix specific */
-
- if (!of.is_file) {
- ngx_log_error(NGX_LOG_CRIT, log, 0,
- "\"%s\" is not a regular file", path.data);
-
- return NGX_HTTP_NOT_FOUND;
- }
-
-#endif
-
- r->root_tested = !r->error_page;
-
- rc = ngx_http_discard_request_body(r);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- log->action = "sending response to client";
-
- r->headers_out.status = NGX_HTTP_OK;
- r->headers_out.content_length_n = of.size;
- r->headers_out.last_modified_time = of.mtime;
-
- if (ngx_http_set_etag(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_http_set_content_type(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- h = ngx_list_push(&r->headers_out.headers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- h->hash = 1;
- ngx_str_set(&h->key, "Content-Encoding");
- ngx_str_set(&h->value, "gzip");
- r->headers_out.content_encoding = h;
-
- r->ignore_content_encoding = 1;
-
- /* we need to allocate all before the header would be sent */
-
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
- if (b->file == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- rc = ngx_http_send_header(r);
-
- if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
- return rc;
- }
-
- b->file_pos = 0;
- b->file_last = of.size;
-
- b->in_file = b->file_last ? 1 : 0;
- b->last_buf = (r == r->main) ? 1 : 0;
- b->last_in_chain = 1;
-
- b->file->fd = of.fd;
- b->file->name = path;
- b->file->log = log;
- b->file->directio = of.is_directio;
-
- out.buf = b;
- out.next = NULL;
-
- return ngx_http_output_filter(r, &out);
-}
-
-
-static void *
-ngx_http_gzip_static_create_conf(ngx_conf_t *cf)
-{
- ngx_http_gzip_static_conf_t *conf;
-
- conf = ngx_palloc(cf->pool, sizeof(ngx_http_gzip_static_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- conf->enable = NGX_CONF_UNSET_UINT;
-
- return conf;
-}
-
-
-static char *
-ngx_http_gzip_static_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_gzip_static_conf_t *prev = parent;
- ngx_http_gzip_static_conf_t *conf = child;
-
- ngx_conf_merge_uint_value(conf->enable, prev->enable,
- NGX_HTTP_GZIP_STATIC_OFF);
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_gzip_static_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_gzip_static_handler;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_headers_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_headers_filter_module.c
deleted file mode 100644
index e33e7ce5271..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_headers_filter_module.c
+++ /dev/null
@@ -1,635 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-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 {
- 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_http_complex_value_t value;
- ngx_str_t key;
- ngx_http_set_header_pt handler;
- ngx_uint_t offset;
-};
-
-
-typedef enum {
- NGX_HTTP_EXPIRES_OFF,
- NGX_HTTP_EXPIRES_EPOCH,
- NGX_HTTP_EXPIRES_MAX,
- NGX_HTTP_EXPIRES_ACCESS,
- NGX_HTTP_EXPIRES_MODIFIED,
- NGX_HTTP_EXPIRES_DAILY,
- NGX_HTTP_EXPIRES_UNSET
-} ngx_http_expires_t;
-
-
-typedef struct {
- ngx_http_expires_t expires;
- time_t expires_time;
- ngx_array_t *headers;
-} ngx_http_headers_conf_t;
-
-
-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_add_header(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 ngx_int_t ngx_http_set_response_header(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);
-static ngx_int_t ngx_http_headers_filter_init(ngx_conf_t *cf);
-static char *ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_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_string("ETag"),
- offsetof(ngx_http_headers_out_t, etag),
- ngx_http_set_response_header },
-
- { ngx_null_string, 0, NULL }
-};
-
-
-static ngx_command_t ngx_http_headers_filter_commands[] = {
-
- { ngx_string("expires"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_TAKE12,
- ngx_http_headers_expires,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL},
-
- { ngx_string("add_header"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_TAKE2,
- ngx_http_headers_add,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL},
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_headers_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_headers_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_headers_create_conf, /* create location configuration */
- ngx_http_headers_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_headers_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_headers_filter_module_ctx, /* module context */
- ngx_http_headers_filter_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-
-
-static ngx_int_t
-ngx_http_headers_filter(ngx_http_request_t *r)
-{
- ngx_str_t value;
- ngx_uint_t i;
- ngx_http_header_val_t *h;
- ngx_http_headers_conf_t *conf;
-
- 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_CREATED
- && r->headers_out.status != NGX_HTTP_NO_CONTENT
- && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT
- && r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY
- && r->headers_out.status != NGX_HTTP_MOVED_TEMPORARILY
- && r->headers_out.status != NGX_HTTP_SEE_OTHER
- && r->headers_out.status != NGX_HTTP_NOT_MODIFIED
- && r->headers_out.status != NGX_HTTP_TEMPORARY_REDIRECT))
- {
- return ngx_http_next_header_filter(r);
- }
-
- if (conf->expires != NGX_HTTP_EXPIRES_OFF) {
- if (ngx_http_set_expires(r, conf) != NGX_OK) {
- return NGX_ERROR;
- }
- }
-
- if (conf->headers) {
- h = conf->headers->elts;
- for (i = 0; i < conf->headers->nelts; i++) {
-
- if (ngx_http_complex_value(r, &h[i].value, &value) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (h[i].handler(r, &h[i], &value) != NGX_OK) {
- return NGX_ERROR;
- }
- }
- }
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_int_t
-ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
-{
- size_t len;
- time_t now, expires_time, max_age;
- ngx_uint_t i;
- ngx_table_elt_t *expires, *cc, **ccp;
-
- 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;
- ngx_str_set(&expires->key, "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);
- if (ccp == NULL) {
- return NGX_ERROR;
- }
-
- cc = ngx_list_push(&r->headers_out.headers);
- if (cc == NULL) {
- return NGX_ERROR;
- }
-
- cc->hash = 1;
- ngx_str_set(&cc->key, "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";
- ngx_str_set(&cc->value, "no-cache");
- return NGX_OK;
- }
-
- if (conf->expires == NGX_HTTP_EXPIRES_MAX) {
- expires->value.data = (u_char *) "Thu, 31 Dec 2037 23:55:55 GMT";
- /* 10 years */
- ngx_str_set(&cc->value, "max-age=315360000");
- return NGX_OK;
- }
-
- expires->value.data = ngx_pnalloc(r->pool, len);
- if (expires->value.data == NULL) {
- return NGX_ERROR;
- }
-
- if (conf->expires_time == 0 && conf->expires != NGX_HTTP_EXPIRES_DAILY) {
- ngx_memcpy(expires->value.data, ngx_cached_http_time.data,
- ngx_cached_http_time.len + 1);
- ngx_str_set(&cc->value, "max-age=0");
- return NGX_OK;
- }
-
- now = ngx_time();
-
- if (conf->expires == NGX_HTTP_EXPIRES_DAILY) {
- expires_time = ngx_next_time(conf->expires_time);
- max_age = expires_time - now;
-
- } else if (conf->expires == NGX_HTTP_EXPIRES_ACCESS
- || r->headers_out.last_modified_time == -1)
- {
- expires_time = now + conf->expires_time;
- max_age = conf->expires_time;
-
- } else {
- expires_time = r->headers_out.last_modified_time + conf->expires_time;
- max_age = expires_time - now;
- }
-
- ngx_http_time(expires->value.data, expires_time);
-
- if (conf->expires_time < 0 || max_age < 0) {
- ngx_str_set(&cc->value, "no-cache");
- return NGX_OK;
- }
-
- cc->value.data = ngx_pnalloc(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", max_age)
- - 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;
-
- if (value->len) {
- h = ngx_list_push(&r->headers_out.headers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- h->hash = 1;
- h->key = hv->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;
-
- if (value->len == 0) {
- return NGX_OK;
- }
-
- 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;
- ngx_str_set(&cc->key, "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)
-{
- if (ngx_http_set_response_header(r, hv, value) != NGX_OK) {
- return NGX_ERROR;
- }
-
- r->headers_out.last_modified_time =
- (value->len) ? ngx_http_parse_time(value->data, value->len) : -1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_set_response_header(ngx_http_request_t *r, ngx_http_header_val_t *hv,
- ngx_str_t *value)
-{
- ngx_table_elt_t *h, **old;
-
- old = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset);
-
- if (value->len == 0) {
- if (*old) {
- (*old)->hash = 0;
- *old = NULL;
- }
-
- return NGX_OK;
- }
-
- if (*old) {
- h = *old;
-
- } else {
- h = ngx_list_push(&r->headers_out.headers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *old = h;
- }
-
- h->hash = 1;
- h->key = hv->key;
- h->value = *value;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_headers_create_conf(ngx_conf_t *cf)
-{
- ngx_http_headers_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_headers_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->headers = NULL;
- * conf->expires_time = 0;
- */
-
- conf->expires = NGX_HTTP_EXPIRES_UNSET;
-
- return conf;
-}
-
-
-static char *
-ngx_http_headers_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_headers_conf_t *prev = parent;
- ngx_http_headers_conf_t *conf = child;
-
- if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
- conf->expires = prev->expires;
- conf->expires_time = prev->expires_time;
-
- if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
- conf->expires = NGX_HTTP_EXPIRES_OFF;
- }
- }
-
- if (conf->headers == NULL) {
- conf->headers = prev->headers;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_headers_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_headers_filter;
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_headers_conf_t *hcf = conf;
-
- ngx_uint_t minus, n;
- ngx_str_t *value;
-
- if (hcf->expires != NGX_HTTP_EXPIRES_UNSET) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- if (cf->args->nelts == 2) {
-
- if (ngx_strcmp(value[1].data, "epoch") == 0) {
- hcf->expires = NGX_HTTP_EXPIRES_EPOCH;
- return NGX_CONF_OK;
- }
-
- if (ngx_strcmp(value[1].data, "max") == 0) {
- hcf->expires = NGX_HTTP_EXPIRES_MAX;
- return NGX_CONF_OK;
- }
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- hcf->expires = NGX_HTTP_EXPIRES_OFF;
- return NGX_CONF_OK;
- }
-
- hcf->expires = NGX_HTTP_EXPIRES_ACCESS;
-
- n = 1;
-
- } else { /* cf->args->nelts == 3 */
-
- if (ngx_strcmp(value[1].data, "modified") != 0) {
- return "invalid value";
- }
-
- hcf->expires = NGX_HTTP_EXPIRES_MODIFIED;
-
- n = 2;
- }
-
- if (value[n].data[0] == '@') {
- value[n].data++;
- value[n].len--;
- minus = 0;
-
- if (hcf->expires == NGX_HTTP_EXPIRES_MODIFIED) {
- return "daily time cannot be used with \"modified\" parameter";
- }
-
- hcf->expires = NGX_HTTP_EXPIRES_DAILY;
-
- } else if (value[n].data[0] == '+') {
- value[n].data++;
- value[n].len--;
- minus = 0;
-
- } else if (value[n].data[0] == '-') {
- value[n].data++;
- value[n].len--;
- minus = 1;
-
- } else {
- minus = 0;
- }
-
- hcf->expires_time = ngx_parse_time(&value[n], 1);
-
- if (hcf->expires_time == (time_t) NGX_ERROR) {
- return "invalid value";
- }
-
- if (hcf->expires == NGX_HTTP_EXPIRES_DAILY
- && hcf->expires_time > 24 * 60 * 60)
- {
- return "daily time value must be less than 24 hours";
- }
-
- if (minus) {
- hcf->expires_time = - hcf->expires_time;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_headers_conf_t *hcf = conf;
-
- ngx_str_t *value;
- ngx_uint_t i;
- ngx_http_header_val_t *hv;
- ngx_http_set_header_t *set;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- if (hcf->headers == NULL) {
- hcf->headers = ngx_array_create(cf->pool, 1,
- sizeof(ngx_http_header_val_t));
- if (hcf->headers == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- hv = ngx_array_push(hcf->headers);
- if (hv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- hv->key = value[1];
- hv->handler = ngx_http_add_header;
- hv->offset = 0;
-
- set = ngx_http_set_headers;
- for (i = 0; set[i].name.len; i++) {
- if (ngx_strcasecmp(value[1].data, set[i].name.data) != 0) {
- continue;
- }
-
- hv->offset = set[i].offset;
- hv->handler = set[i].handler;
-
- break;
- }
-
- if (value[2].len == 0) {
- ngx_memzero(&hv->value, sizeof(ngx_http_complex_value_t));
- return NGX_CONF_OK;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[2];
- ccv.complex_value = &hv->value;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_image_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_image_filter_module.c
deleted file mode 100644
index c983b973b46..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_image_filter_module.c
+++ /dev/null
@@ -1,1520 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-#include <gd.h>
-
-
-#define NGX_HTTP_IMAGE_OFF 0
-#define NGX_HTTP_IMAGE_TEST 1
-#define NGX_HTTP_IMAGE_SIZE 2
-#define NGX_HTTP_IMAGE_RESIZE 3
-#define NGX_HTTP_IMAGE_CROP 4
-#define NGX_HTTP_IMAGE_ROTATE 5
-
-
-#define NGX_HTTP_IMAGE_START 0
-#define NGX_HTTP_IMAGE_READ 1
-#define NGX_HTTP_IMAGE_PROCESS 2
-#define NGX_HTTP_IMAGE_PASS 3
-#define NGX_HTTP_IMAGE_DONE 4
-
-
-#define NGX_HTTP_IMAGE_NONE 0
-#define NGX_HTTP_IMAGE_JPEG 1
-#define NGX_HTTP_IMAGE_GIF 2
-#define NGX_HTTP_IMAGE_PNG 3
-
-
-#define NGX_HTTP_IMAGE_BUFFERED 0x08
-
-
-typedef struct {
- ngx_uint_t filter;
- ngx_uint_t width;
- ngx_uint_t height;
- ngx_uint_t angle;
- ngx_uint_t jpeg_quality;
- ngx_uint_t sharpen;
-
- ngx_flag_t transparency;
- ngx_flag_t interlace;
-
- ngx_http_complex_value_t *wcv;
- ngx_http_complex_value_t *hcv;
- ngx_http_complex_value_t *acv;
- ngx_http_complex_value_t *jqcv;
- ngx_http_complex_value_t *shcv;
-
- size_t buffer_size;
-} ngx_http_image_filter_conf_t;
-
-
-typedef struct {
- u_char *image;
- u_char *last;
-
- size_t length;
-
- ngx_uint_t width;
- ngx_uint_t height;
- ngx_uint_t max_width;
- ngx_uint_t max_height;
- ngx_uint_t angle;
-
- ngx_uint_t phase;
- ngx_uint_t type;
- ngx_uint_t force;
-} ngx_http_image_filter_ctx_t;
-
-
-static ngx_int_t ngx_http_image_send(ngx_http_request_t *r,
- ngx_http_image_filter_ctx_t *ctx, ngx_chain_t *in);
-static ngx_uint_t ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in);
-static ngx_int_t ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in);
-static ngx_buf_t *ngx_http_image_process(ngx_http_request_t *r);
-static ngx_buf_t *ngx_http_image_json(ngx_http_request_t *r,
- ngx_http_image_filter_ctx_t *ctx);
-static ngx_buf_t *ngx_http_image_asis(ngx_http_request_t *r,
- ngx_http_image_filter_ctx_t *ctx);
-static void ngx_http_image_length(ngx_http_request_t *r, ngx_buf_t *b);
-static ngx_int_t ngx_http_image_size(ngx_http_request_t *r,
- ngx_http_image_filter_ctx_t *ctx);
-
-static ngx_buf_t *ngx_http_image_resize(ngx_http_request_t *r,
- ngx_http_image_filter_ctx_t *ctx);
-static gdImagePtr ngx_http_image_source(ngx_http_request_t *r,
- ngx_http_image_filter_ctx_t *ctx);
-static gdImagePtr ngx_http_image_new(ngx_http_request_t *r, int w, int h,
- int colors);
-static u_char *ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type,
- gdImagePtr img, int *size);
-static void ngx_http_image_cleanup(void *data);
-static ngx_uint_t ngx_http_image_filter_get_value(ngx_http_request_t *r,
- ngx_http_complex_value_t *cv, ngx_uint_t v);
-static ngx_uint_t ngx_http_image_filter_value(ngx_str_t *value);
-
-
-static void *ngx_http_image_filter_create_conf(ngx_conf_t *cf);
-static char *ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static char *ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_image_filter_jpeg_quality(ngx_conf_t *cf,
- ngx_command_t *cmd, void *conf);
-static char *ngx_http_image_filter_sharpen(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static ngx_int_t ngx_http_image_filter_init(ngx_conf_t *cf);
-
-
-static ngx_command_t ngx_http_image_filter_commands[] = {
-
- { ngx_string("image_filter"),
- NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
- ngx_http_image_filter,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("image_filter_jpeg_quality"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_image_filter_jpeg_quality,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("image_filter_sharpen"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_image_filter_sharpen,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("image_filter_transparency"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_image_filter_conf_t, transparency),
- NULL },
-
- { ngx_string("image_filter_interlace"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_image_filter_conf_t, interlace),
- NULL },
-
- { ngx_string("image_filter_buffer"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_image_filter_conf_t, buffer_size),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_image_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_image_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_image_filter_create_conf, /* create location configuration */
- ngx_http_image_filter_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_image_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_image_filter_module_ctx, /* module context */
- ngx_http_image_filter_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-
-
-static ngx_str_t ngx_http_image_types[] = {
- ngx_string("image/jpeg"),
- ngx_string("image/gif"),
- ngx_string("image/png")
-};
-
-
-static ngx_int_t
-ngx_http_image_header_filter(ngx_http_request_t *r)
-{
- off_t len;
- ngx_http_image_filter_ctx_t *ctx;
- ngx_http_image_filter_conf_t *conf;
-
- if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) {
- return ngx_http_next_header_filter(r);
- }
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module);
-
- if (ctx) {
- ngx_http_set_ctx(r, NULL, ngx_http_image_filter_module);
- return ngx_http_next_header_filter(r);
- }
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
-
- if (conf->filter == NGX_HTTP_IMAGE_OFF) {
- return ngx_http_next_header_filter(r);
- }
-
- if (r->headers_out.content_type.len
- >= sizeof("multipart/x-mixed-replace") - 1
- && ngx_strncasecmp(r->headers_out.content_type.data,
- (u_char *) "multipart/x-mixed-replace",
- sizeof("multipart/x-mixed-replace") - 1)
- == 0)
- {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "image filter: multipart/x-mixed-replace response");
-
- return NGX_ERROR;
- }
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_image_filter_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_image_filter_module);
-
- len = r->headers_out.content_length_n;
-
- if (len != -1 && len > (off_t) conf->buffer_size) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "image filter: too big response: %O", len);
-
- return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE;
- }
-
- if (len == -1) {
- ctx->length = conf->buffer_size;
-
- } else {
- ctx->length = (size_t) len;
- }
-
- if (r->headers_out.refresh) {
- r->headers_out.refresh->hash = 0;
- }
-
- r->main_filter_need_in_memory = 1;
- r->allow_ranges = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_image_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- ngx_int_t rc;
- ngx_str_t *ct;
- ngx_chain_t out;
- ngx_http_image_filter_ctx_t *ctx;
- ngx_http_image_filter_conf_t *conf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "image filter");
-
- if (in == NULL) {
- return ngx_http_next_body_filter(r, in);
- }
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module);
-
- if (ctx == NULL) {
- return ngx_http_next_body_filter(r, in);
- }
-
- switch (ctx->phase) {
-
- case NGX_HTTP_IMAGE_START:
-
- ctx->type = ngx_http_image_test(r, in);
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
-
- if (ctx->type == NGX_HTTP_IMAGE_NONE) {
-
- if (conf->filter == NGX_HTTP_IMAGE_SIZE) {
- out.buf = ngx_http_image_json(r, NULL);
-
- if (out.buf) {
- out.next = NULL;
- ctx->phase = NGX_HTTP_IMAGE_DONE;
-
- return ngx_http_image_send(r, ctx, &out);
- }
- }
-
- return ngx_http_filter_finalize_request(r,
- &ngx_http_image_filter_module,
- NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
- }
-
- /* override content type */
-
- ct = &ngx_http_image_types[ctx->type - 1];
- r->headers_out.content_type_len = ct->len;
- r->headers_out.content_type = *ct;
- r->headers_out.content_type_lowcase = NULL;
-
- if (conf->filter == NGX_HTTP_IMAGE_TEST) {
- ctx->phase = NGX_HTTP_IMAGE_PASS;
-
- return ngx_http_image_send(r, ctx, in);
- }
-
- ctx->phase = NGX_HTTP_IMAGE_READ;
-
- /* fall through */
-
- case NGX_HTTP_IMAGE_READ:
-
- rc = ngx_http_image_read(r, in);
-
- if (rc == NGX_AGAIN) {
- return NGX_OK;
- }
-
- if (rc == NGX_ERROR) {
- return ngx_http_filter_finalize_request(r,
- &ngx_http_image_filter_module,
- NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
- }
-
- /* fall through */
-
- case NGX_HTTP_IMAGE_PROCESS:
-
- out.buf = ngx_http_image_process(r);
-
- if (out.buf == NULL) {
- return ngx_http_filter_finalize_request(r,
- &ngx_http_image_filter_module,
- NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
- }
-
- out.next = NULL;
- ctx->phase = NGX_HTTP_IMAGE_PASS;
-
- return ngx_http_image_send(r, ctx, &out);
-
- case NGX_HTTP_IMAGE_PASS:
-
- return ngx_http_next_body_filter(r, in);
-
- default: /* NGX_HTTP_IMAGE_DONE */
-
- rc = ngx_http_next_body_filter(r, NULL);
-
- /* NGX_ERROR resets any pending data */
- return (rc == NGX_OK) ? NGX_ERROR : rc;
- }
-}
-
-
-static ngx_int_t
-ngx_http_image_send(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx,
- ngx_chain_t *in)
-{
- ngx_int_t rc;
-
- rc = ngx_http_next_header_filter(r);
-
- if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
- return NGX_ERROR;
- }
-
- rc = ngx_http_next_body_filter(r, in);
-
- if (ctx->phase == NGX_HTTP_IMAGE_DONE) {
- /* NGX_ERROR resets any pending data */
- return (rc == NGX_OK) ? NGX_ERROR : rc;
- }
-
- return rc;
-}
-
-
-static ngx_uint_t
-ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in)
-{
- u_char *p;
-
- p = in->buf->pos;
-
- if (in->buf->last - p < 16) {
- return NGX_HTTP_IMAGE_NONE;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "image filter: \"%c%c\"", p[0], p[1]);
-
- if (p[0] == 0xff && p[1] == 0xd8) {
-
- /* JPEG */
-
- return NGX_HTTP_IMAGE_JPEG;
-
- } else if (p[0] == 'G' && p[1] == 'I' && p[2] == 'F' && p[3] == '8'
- && p[5] == 'a')
- {
- if (p[4] == '9' || p[4] == '7') {
- /* GIF */
- return NGX_HTTP_IMAGE_GIF;
- }
-
- } else if (p[0] == 0x89 && p[1] == 'P' && p[2] == 'N' && p[3] == 'G'
- && p[4] == 0x0d && p[5] == 0x0a && p[6] == 0x1a && p[7] == 0x0a)
- {
- /* PNG */
-
- return NGX_HTTP_IMAGE_PNG;
- }
-
- return NGX_HTTP_IMAGE_NONE;
-}
-
-
-static ngx_int_t
-ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in)
-{
- u_char *p;
- size_t size, rest;
- ngx_buf_t *b;
- ngx_chain_t *cl;
- ngx_http_image_filter_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module);
-
- if (ctx->image == NULL) {
- ctx->image = ngx_palloc(r->pool, ctx->length);
- if (ctx->image == NULL) {
- return NGX_ERROR;
- }
-
- ctx->last = ctx->image;
- }
-
- p = ctx->last;
-
- for (cl = in; cl; cl = cl->next) {
-
- b = cl->buf;
- size = b->last - b->pos;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "image buf: %uz", size);
-
- rest = ctx->image + ctx->length - p;
-
- if (size > rest) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "image filter: too big response");
- return NGX_ERROR;
- }
-
- p = ngx_cpymem(p, b->pos, size);
- b->pos += size;
-
- if (b->last_buf) {
- ctx->last = p;
- return NGX_OK;
- }
- }
-
- ctx->last = p;
- r->connection->buffered |= NGX_HTTP_IMAGE_BUFFERED;
-
- return NGX_AGAIN;
-}
-
-
-static ngx_buf_t *
-ngx_http_image_process(ngx_http_request_t *r)
-{
- ngx_int_t rc;
- ngx_http_image_filter_ctx_t *ctx;
- ngx_http_image_filter_conf_t *conf;
-
- r->connection->buffered &= ~NGX_HTTP_IMAGE_BUFFERED;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module);
-
- rc = ngx_http_image_size(r, ctx);
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
-
- if (conf->filter == NGX_HTTP_IMAGE_SIZE) {
- return ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL);
- }
-
- ctx->angle = ngx_http_image_filter_get_value(r, conf->acv, conf->angle);
-
- if (conf->filter == NGX_HTTP_IMAGE_ROTATE) {
-
- if (ctx->angle != 90 && ctx->angle != 180 && ctx->angle != 270) {
- return NULL;
- }
-
- return ngx_http_image_resize(r, ctx);
- }
-
- ctx->max_width = ngx_http_image_filter_get_value(r, conf->wcv, conf->width);
- if (ctx->max_width == 0) {
- return NULL;
- }
-
- ctx->max_height = ngx_http_image_filter_get_value(r, conf->hcv,
- conf->height);
- if (ctx->max_height == 0) {
- return NULL;
- }
-
- if (rc == NGX_OK
- && ctx->width <= ctx->max_width
- && ctx->height <= ctx->max_height
- && ctx->angle == 0
- && !ctx->force)
- {
- return ngx_http_image_asis(r, ctx);
- }
-
- return ngx_http_image_resize(r, ctx);
-}
-
-
-static ngx_buf_t *
-ngx_http_image_json(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
-{
- size_t len;
- ngx_buf_t *b;
-
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- return NULL;
- }
-
- b->memory = 1;
- b->last_buf = 1;
-
- ngx_http_clean_header(r);
-
- r->headers_out.status = NGX_HTTP_OK;
- r->headers_out.content_type_len = sizeof("application/json") - 1;
- ngx_str_set(&r->headers_out.content_type, "application/json");
- r->headers_out.content_type_lowcase = NULL;
-
- if (ctx == NULL) {
- b->pos = (u_char *) "{}" CRLF;
- b->last = b->pos + sizeof("{}" CRLF) - 1;
-
- ngx_http_image_length(r, b);
-
- return b;
- }
-
- len = sizeof("{ \"img\" : "
- "{ \"width\": , \"height\": , \"type\": \"jpeg\" } }" CRLF) - 1
- + 2 * NGX_SIZE_T_LEN;
-
- b->pos = ngx_pnalloc(r->pool, len);
- if (b->pos == NULL) {
- return NULL;
- }
-
- b->last = ngx_sprintf(b->pos,
- "{ \"img\" : "
- "{ \"width\": %uz,"
- " \"height\": %uz,"
- " \"type\": \"%s\" } }" CRLF,
- ctx->width, ctx->height,
- ngx_http_image_types[ctx->type - 1].data + 6);
-
- ngx_http_image_length(r, b);
-
- return b;
-}
-
-
-static ngx_buf_t *
-ngx_http_image_asis(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
-{
- ngx_buf_t *b;
-
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- return NULL;
- }
-
- b->pos = ctx->image;
- b->last = ctx->last;
- b->memory = 1;
- b->last_buf = 1;
-
- ngx_http_image_length(r, b);
-
- return b;
-}
-
-
-static void
-ngx_http_image_length(ngx_http_request_t *r, ngx_buf_t *b)
-{
- r->headers_out.content_length_n = b->last - b->pos;
-
- if (r->headers_out.content_length) {
- r->headers_out.content_length->hash = 0;
- }
-
- r->headers_out.content_length = NULL;
-}
-
-
-static ngx_int_t
-ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
-{
- u_char *p, *last;
- size_t len, app;
- ngx_uint_t width, height;
-
- p = ctx->image;
-
- switch (ctx->type) {
-
- case NGX_HTTP_IMAGE_JPEG:
-
- p += 2;
- last = ctx->image + ctx->length - 10;
- width = 0;
- height = 0;
- app = 0;
-
- while (p < last) {
-
- if (p[0] == 0xff && p[1] != 0xff) {
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "JPEG: %02xd %02xd", p[0], p[1]);
-
- p++;
-
- if ((*p == 0xc0 || *p == 0xc1 || *p == 0xc2 || *p == 0xc3
- || *p == 0xc9 || *p == 0xca || *p == 0xcb)
- && (width == 0 || height == 0))
- {
- width = p[6] * 256 + p[7];
- height = p[4] * 256 + p[5];
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "JPEG: %02xd %02xd", p[1], p[2]);
-
- len = p[1] * 256 + p[2];
-
- if (*p >= 0xe1 && *p <= 0xef) {
- /* application data, e.g., EXIF, Adobe XMP, etc. */
- app += len;
- }
-
- p += len;
-
- continue;
- }
-
- p++;
- }
-
- if (width == 0 || height == 0) {
- return NGX_DECLINED;
- }
-
- if (ctx->length / 20 < app) {
- /* force conversion if application data consume more than 5% */
- ctx->force = 1;
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "app data size: %uz", app);
- }
-
- break;
-
- case NGX_HTTP_IMAGE_GIF:
-
- if (ctx->length < 10) {
- return NGX_DECLINED;
- }
-
- width = p[7] * 256 + p[6];
- height = p[9] * 256 + p[8];
-
- break;
-
- case NGX_HTTP_IMAGE_PNG:
-
- if (ctx->length < 24) {
- return NGX_DECLINED;
- }
-
- width = p[18] * 256 + p[19];
- height = p[22] * 256 + p[23];
-
- break;
-
- default:
-
- return NGX_DECLINED;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "image size: %d x %d", width, height);
-
- ctx->width = width;
- ctx->height = height;
-
- return NGX_OK;
-}
-
-
-static ngx_buf_t *
-ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
-{
- int sx, sy, dx, dy, ox, oy, ax, ay, size,
- colors, palette, transparent, sharpen,
- red, green, blue, t;
- u_char *out;
- ngx_buf_t *b;
- ngx_uint_t resize;
- gdImagePtr src, dst;
- ngx_pool_cleanup_t *cln;
- ngx_http_image_filter_conf_t *conf;
-
- src = ngx_http_image_source(r, ctx);
-
- if (src == NULL) {
- return NULL;
- }
-
- sx = gdImageSX(src);
- sy = gdImageSY(src);
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
-
- if (!ctx->force
- && ctx->angle == 0
- && (ngx_uint_t) sx <= ctx->max_width
- && (ngx_uint_t) sy <= ctx->max_height)
- {
- gdImageDestroy(src);
- return ngx_http_image_asis(r, ctx);
- }
-
- colors = gdImageColorsTotal(src);
-
- if (colors && conf->transparency) {
- transparent = gdImageGetTransparent(src);
-
- if (transparent != -1) {
- palette = colors;
- red = gdImageRed(src, transparent);
- green = gdImageGreen(src, transparent);
- blue = gdImageBlue(src, transparent);
-
- goto transparent;
- }
- }
-
- palette = 0;
- transparent = -1;
- red = 0;
- green = 0;
- blue = 0;
-
-transparent:
-
- gdImageColorTransparent(src, -1);
-
- dx = sx;
- dy = sy;
-
- if (conf->filter == NGX_HTTP_IMAGE_RESIZE) {
-
- if ((ngx_uint_t) dx > ctx->max_width) {
- dy = dy * ctx->max_width / dx;
- dy = dy ? dy : 1;
- dx = ctx->max_width;
- }
-
- if ((ngx_uint_t) dy > ctx->max_height) {
- dx = dx * ctx->max_height / dy;
- dx = dx ? dx : 1;
- dy = ctx->max_height;
- }
-
- resize = 1;
-
- } else if (conf->filter == NGX_HTTP_IMAGE_ROTATE) {
-
- resize = 0;
-
- } else { /* NGX_HTTP_IMAGE_CROP */
-
- resize = 0;
-
- if ((double) dx / dy < (double) ctx->max_width / ctx->max_height) {
- if ((ngx_uint_t) dx > ctx->max_width) {
- dy = dy * ctx->max_width / dx;
- dy = dy ? dy : 1;
- dx = ctx->max_width;
- resize = 1;
- }
-
- } else {
- if ((ngx_uint_t) dy > ctx->max_height) {
- dx = dx * ctx->max_height / dy;
- dx = dx ? dx : 1;
- dy = ctx->max_height;
- resize = 1;
- }
- }
- }
-
- if (resize) {
- dst = ngx_http_image_new(r, dx, dy, palette);
- if (dst == NULL) {
- gdImageDestroy(src);
- return NULL;
- }
-
- if (colors == 0) {
- gdImageSaveAlpha(dst, 1);
- gdImageAlphaBlending(dst, 0);
- }
-
- gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy);
-
- if (colors) {
- gdImageTrueColorToPalette(dst, 1, 256);
- }
-
- gdImageDestroy(src);
-
- } else {
- dst = src;
- }
-
- if (ctx->angle) {
- src = dst;
-
- ax = (dx % 2 == 0) ? 1 : 0;
- ay = (dy % 2 == 0) ? 1 : 0;
-
- switch (ctx->angle) {
-
- case 90:
- case 270:
- dst = ngx_http_image_new(r, dy, dx, palette);
- if (dst == NULL) {
- gdImageDestroy(src);
- return NULL;
- }
- if (ctx->angle == 90) {
- ox = dy / 2 + ay;
- oy = dx / 2 - ax;
-
- } else {
- ox = dy / 2 - ay;
- oy = dx / 2 + ax;
- }
-
- gdImageCopyRotated(dst, src, ox, oy, 0, 0,
- dx + ax, dy + ay, ctx->angle);
- gdImageDestroy(src);
-
- t = dx;
- dx = dy;
- dy = t;
- break;
-
- case 180:
- dst = ngx_http_image_new(r, dx, dy, palette);
- if (dst == NULL) {
- gdImageDestroy(src);
- return NULL;
- }
- gdImageCopyRotated(dst, src, dx / 2 - ax, dy / 2 - ay, 0, 0,
- dx + ax, dy + ay, ctx->angle);
- gdImageDestroy(src);
- break;
- }
- }
-
- if (conf->filter == NGX_HTTP_IMAGE_CROP) {
-
- src = dst;
-
- if ((ngx_uint_t) dx > ctx->max_width) {
- ox = dx - ctx->max_width;
-
- } else {
- ox = 0;
- }
-
- if ((ngx_uint_t) dy > ctx->max_height) {
- oy = dy - ctx->max_height;
-
- } else {
- oy = 0;
- }
-
- if (ox || oy) {
-
- dst = ngx_http_image_new(r, dx - ox, dy - oy, colors);
-
- if (dst == NULL) {
- gdImageDestroy(src);
- return NULL;
- }
-
- ox /= 2;
- oy /= 2;
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "image crop: %d x %d @ %d x %d",
- dx, dy, ox, oy);
-
- if (colors == 0) {
- gdImageSaveAlpha(dst, 1);
- gdImageAlphaBlending(dst, 0);
- }
-
- gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy);
-
- if (colors) {
- gdImageTrueColorToPalette(dst, 1, 256);
- }
-
- gdImageDestroy(src);
- }
- }
-
- if (transparent != -1 && colors) {
- gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
- }
-
- sharpen = ngx_http_image_filter_get_value(r, conf->shcv, conf->sharpen);
- if (sharpen > 0) {
- gdImageSharpen(dst, sharpen);
- }
-
- gdImageInterlace(dst, (int) conf->interlace);
-
- out = ngx_http_image_out(r, ctx->type, dst, &size);
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "image: %d x %d %d", sx, sy, colors);
-
- gdImageDestroy(dst);
- ngx_pfree(r->pool, ctx->image);
-
- if (out == NULL) {
- return NULL;
- }
-
- cln = ngx_pool_cleanup_add(r->pool, 0);
- if (cln == NULL) {
- gdFree(out);
- return NULL;
- }
-
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- gdFree(out);
- return NULL;
- }
-
- cln->handler = ngx_http_image_cleanup;
- cln->data = out;
-
- b->pos = out;
- b->last = out + size;
- b->memory = 1;
- b->last_buf = 1;
-
- ngx_http_image_length(r, b);
-
- return b;
-}
-
-
-static gdImagePtr
-ngx_http_image_source(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
-{
- char *failed;
- gdImagePtr img;
-
- img = NULL;
-
- switch (ctx->type) {
-
- case NGX_HTTP_IMAGE_JPEG:
- img = gdImageCreateFromJpegPtr(ctx->length, ctx->image);
- failed = "gdImageCreateFromJpegPtr() failed";
- break;
-
- case NGX_HTTP_IMAGE_GIF:
- img = gdImageCreateFromGifPtr(ctx->length, ctx->image);
- failed = "gdImageCreateFromGifPtr() failed";
- break;
-
- case NGX_HTTP_IMAGE_PNG:
- img = gdImageCreateFromPngPtr(ctx->length, ctx->image);
- failed = "gdImageCreateFromPngPtr() failed";
- break;
-
- default:
- failed = "unknown image type";
- break;
- }
-
- if (img == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, failed);
- }
-
- return img;
-}
-
-
-static gdImagePtr
-ngx_http_image_new(ngx_http_request_t *r, int w, int h, int colors)
-{
- gdImagePtr img;
-
- if (colors == 0) {
- img = gdImageCreateTrueColor(w, h);
-
- if (img == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "gdImageCreateTrueColor() failed");
- return NULL;
- }
-
- } else {
- img = gdImageCreate(w, h);
-
- if (img == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "gdImageCreate() failed");
- return NULL;
- }
- }
-
- return img;
-}
-
-
-static u_char *
-ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type, gdImagePtr img,
- int *size)
-{
- char *failed;
- u_char *out;
- ngx_int_t jq;
- ngx_http_image_filter_conf_t *conf;
-
- out = NULL;
-
- switch (type) {
-
- case NGX_HTTP_IMAGE_JPEG:
- conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
-
- jq = ngx_http_image_filter_get_value(r, conf->jqcv, conf->jpeg_quality);
- if (jq <= 0) {
- return NULL;
- }
-
- out = gdImageJpegPtr(img, size, jq);
- failed = "gdImageJpegPtr() failed";
- break;
-
- case NGX_HTTP_IMAGE_GIF:
- out = gdImageGifPtr(img, size);
- failed = "gdImageGifPtr() failed";
- break;
-
- case NGX_HTTP_IMAGE_PNG:
- out = gdImagePngPtr(img, size);
- failed = "gdImagePngPtr() failed";
- break;
-
- default:
- failed = "unknown image type";
- break;
- }
-
- if (out == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, failed);
- }
-
- return out;
-}
-
-
-static void
-ngx_http_image_cleanup(void *data)
-{
- gdFree(data);
-}
-
-
-static ngx_uint_t
-ngx_http_image_filter_get_value(ngx_http_request_t *r,
- ngx_http_complex_value_t *cv, ngx_uint_t v)
-{
- ngx_str_t val;
-
- if (cv == NULL) {
- return v;
- }
-
- if (ngx_http_complex_value(r, cv, &val) != NGX_OK) {
- return 0;
- }
-
- return ngx_http_image_filter_value(&val);
-}
-
-
-static ngx_uint_t
-ngx_http_image_filter_value(ngx_str_t *value)
-{
- ngx_int_t n;
-
- if (value->len == 1 && value->data[0] == '-') {
- return (ngx_uint_t) -1;
- }
-
- n = ngx_atoi(value->data, value->len);
-
- if (n > 0) {
- return (ngx_uint_t) n;
- }
-
- return 0;
-}
-
-
-static void *
-ngx_http_image_filter_create_conf(ngx_conf_t *cf)
-{
- ngx_http_image_filter_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_image_filter_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->width = 0;
- * conf->height = 0;
- * conf->angle = 0;
- * conf->wcv = NULL;
- * conf->hcv = NULL;
- * conf->acv = NULL;
- * conf->jqcv = NULL;
- * conf->shcv = NULL;
- */
-
- conf->filter = NGX_CONF_UNSET_UINT;
- conf->jpeg_quality = NGX_CONF_UNSET_UINT;
- conf->sharpen = NGX_CONF_UNSET_UINT;
- conf->transparency = NGX_CONF_UNSET;
- conf->interlace = NGX_CONF_UNSET;
- conf->buffer_size = NGX_CONF_UNSET_SIZE;
-
- return conf;
-}
-
-
-static char *
-ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_image_filter_conf_t *prev = parent;
- ngx_http_image_filter_conf_t *conf = child;
-
- if (conf->filter == NGX_CONF_UNSET_UINT) {
-
- if (prev->filter == NGX_CONF_UNSET_UINT) {
- conf->filter = NGX_HTTP_IMAGE_OFF;
-
- } else {
- conf->filter = prev->filter;
- conf->width = prev->width;
- conf->height = prev->height;
- conf->angle = prev->angle;
- conf->wcv = prev->wcv;
- conf->hcv = prev->hcv;
- conf->acv = prev->acv;
- }
- }
-
- if (conf->jpeg_quality == NGX_CONF_UNSET_UINT) {
-
- /* 75 is libjpeg default quality */
- ngx_conf_merge_uint_value(conf->jpeg_quality, prev->jpeg_quality, 75);
-
- if (conf->jqcv == NULL) {
- conf->jqcv = prev->jqcv;
- }
- }
-
- if (conf->sharpen == NGX_CONF_UNSET_UINT) {
- ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0);
-
- if (conf->shcv == NULL) {
- conf->shcv = prev->shcv;
- }
- }
-
- ngx_conf_merge_value(conf->transparency, prev->transparency, 1);
-
- ngx_conf_merge_value(conf->interlace, prev->interlace, 0);
-
- ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
- 1 * 1024 * 1024);
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_image_filter_conf_t *imcf = conf;
-
- ngx_str_t *value;
- ngx_int_t n;
- ngx_uint_t i;
- ngx_http_complex_value_t cv;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- i = 1;
-
- if (cf->args->nelts == 2) {
- if (ngx_strcmp(value[i].data, "off") == 0) {
- imcf->filter = NGX_HTTP_IMAGE_OFF;
-
- } else if (ngx_strcmp(value[i].data, "test") == 0) {
- imcf->filter = NGX_HTTP_IMAGE_TEST;
-
- } else if (ngx_strcmp(value[i].data, "size") == 0) {
- imcf->filter = NGX_HTTP_IMAGE_SIZE;
-
- } else {
- goto failed;
- }
-
- return NGX_CONF_OK;
-
- } else if (cf->args->nelts == 3) {
-
- if (ngx_strcmp(value[i].data, "rotate") == 0) {
- if (imcf->filter != NGX_HTTP_IMAGE_RESIZE
- && imcf->filter != NGX_HTTP_IMAGE_CROP)
- {
- imcf->filter = NGX_HTTP_IMAGE_ROTATE;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[++i];
- ccv.complex_value = &cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (cv.lengths == NULL) {
- n = ngx_http_image_filter_value(&value[i]);
-
- if (n != 90 && n != 180 && n != 270) {
- goto failed;
- }
-
- imcf->angle = (ngx_uint_t) n;
-
- } else {
- imcf->acv = ngx_palloc(cf->pool,
- sizeof(ngx_http_complex_value_t));
- if (imcf->acv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *imcf->acv = cv;
- }
-
- return NGX_CONF_OK;
-
- } else {
- goto failed;
- }
- }
-
- if (ngx_strcmp(value[i].data, "resize") == 0) {
- imcf->filter = NGX_HTTP_IMAGE_RESIZE;
-
- } else if (ngx_strcmp(value[i].data, "crop") == 0) {
- imcf->filter = NGX_HTTP_IMAGE_CROP;
-
- } else {
- goto failed;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[++i];
- ccv.complex_value = &cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (cv.lengths == NULL) {
- n = ngx_http_image_filter_value(&value[i]);
-
- if (n == 0) {
- goto failed;
- }
-
- imcf->width = (ngx_uint_t) n;
-
- } else {
- imcf->wcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (imcf->wcv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *imcf->wcv = cv;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[++i];
- ccv.complex_value = &cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (cv.lengths == NULL) {
- n = ngx_http_image_filter_value(&value[i]);
-
- if (n == 0) {
- goto failed;
- }
-
- imcf->height = (ngx_uint_t) n;
-
- } else {
- imcf->hcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (imcf->hcv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *imcf->hcv = cv;
- }
-
- return NGX_CONF_OK;
-
-failed:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
- &value[i]);
-
- return NGX_CONF_ERROR;
-}
-
-
-static char *
-ngx_http_image_filter_jpeg_quality(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf)
-{
- ngx_http_image_filter_conf_t *imcf = conf;
-
- ngx_str_t *value;
- ngx_int_t n;
- ngx_http_complex_value_t cv;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (cv.lengths == NULL) {
- n = ngx_http_image_filter_value(&value[1]);
-
- if (n <= 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- imcf->jpeg_quality = (ngx_uint_t) n;
-
- } else {
- imcf->jqcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (imcf->jqcv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *imcf->jqcv = cv;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_image_filter_sharpen(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf)
-{
- ngx_http_image_filter_conf_t *imcf = conf;
-
- ngx_str_t *value;
- ngx_int_t n;
- ngx_http_complex_value_t cv;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (cv.lengths == NULL) {
- n = ngx_http_image_filter_value(&value[1]);
-
- if (n < 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- imcf->sharpen = (ngx_uint_t) n;
-
- } else {
- imcf->shcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (imcf->shcv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *imcf->shcv = cv;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_image_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_image_header_filter;
-
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_image_body_filter;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_index_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_index_module.c
deleted file mode 100644
index d3544db5bf5..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_index_module.c
+++ /dev/null
@@ -1,540 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_str_t name;
- ngx_array_t *lengths;
- ngx_array_t *values;
-} ngx_http_index_t;
-
-
-typedef struct {
- ngx_array_t *indices; /* array of ngx_http_index_t */
- size_t max_index_len;
-} ngx_http_index_loc_conf_t;
-
-
-#define NGX_HTTP_DEFAULT_INDEX "index.html"
-
-
-static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
- ngx_http_core_loc_conf_t *clcf, u_char *path, u_char *last);
-static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
- ngx_http_core_loc_conf_t *clcf, u_char *file, ngx_err_t err);
-
-static ngx_int_t ngx_http_index_init(ngx_conf_t *cf);
-static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_index_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_command_t ngx_http_index_commands[] = {
-
- { ngx_string("index"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_index_set_index,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_index_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_index_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_index_create_loc_conf, /* create location configuration */
- ngx_http_index_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_index_module = {
- NGX_MODULE_V1,
- &ngx_http_index_module_ctx, /* module context */
- ngx_http_index_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-/*
- * Try to open/test the first index file before the test of directory
- * existence because valid requests should prevail over invalid ones.
- * If open()/stat() of a file will fail then stat() of a directory
- * should be faster because kernel may have already cached some data.
- * Besides, Win32 may return ERROR_PATH_NOT_FOUND (NGX_ENOTDIR) at once.
- * Unix has ENOTDIR error; however, it's less helpful than Win32's one:
- * it only indicates that path points to a regular file, not a directory.
- */
-
-static ngx_int_t
-ngx_http_index_handler(ngx_http_request_t *r)
-{
- u_char *p, *name;
- size_t len, root, reserve, allocated;
- ngx_int_t rc;
- ngx_str_t path, uri;
- ngx_uint_t i, dir_tested;
- ngx_http_index_t *index;
- ngx_open_file_info_t of;
- ngx_http_script_code_pt code;
- ngx_http_script_engine_t e;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_index_loc_conf_t *ilcf;
- ngx_http_script_len_code_pt lcode;
-
- if (r->uri.data[r->uri.len - 1] != '/') {
- return NGX_DECLINED;
- }
-
- if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) {
- return NGX_DECLINED;
- }
-
- ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- allocated = 0;
- root = 0;
- dir_tested = 0;
- name = NULL;
- /* suppress MSVC warning */
- path.data = NULL;
-
- index = ilcf->indices->elts;
- for (i = 0; i < ilcf->indices->nelts; i++) {
-
- if (index[i].lengths == NULL) {
-
- if (index[i].name.data[0] == '/') {
- return ngx_http_internal_redirect(r, &index[i].name, &r->args);
- }
-
- reserve = ilcf->max_index_len;
- len = index[i].name.len;
-
- } else {
- ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
-
- e.ip = index[i].lengths->elts;
- e.request = r;
- e.flushed = 1;
-
- /* 1 is for terminating '\0' as in static names */
- len = 1;
-
- while (*(uintptr_t *) e.ip) {
- lcode = *(ngx_http_script_len_code_pt *) e.ip;
- len += lcode(&e);
- }
-
- /* 16 bytes are preallocation */
-
- reserve = len + 16;
- }
-
- if (reserve > allocated) {
-
- name = ngx_http_map_uri_to_path(r, &path, &root, reserve);
- if (name == NULL) {
- return NGX_ERROR;
- }
-
- allocated = path.data + path.len - name;
- }
-
- if (index[i].values == NULL) {
-
- /* index[i].name.len includes the terminating '\0' */
-
- ngx_memcpy(name, index[i].name.data, index[i].name.len);
-
- path.len = (name + index[i].name.len - 1) - path.data;
-
- } else {
- e.ip = index[i].values->elts;
- e.pos = name;
-
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
- }
-
- if (*name == '/') {
- uri.len = len - 1;
- uri.data = name;
- return ngx_http_internal_redirect(r, &uri, &r->args);
- }
-
- path.len = e.pos - path.data;
-
- *e.pos = '\0';
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "open index \"%V\"", &path);
-
- ngx_memzero(&of, sizeof(ngx_open_file_info_t));
-
- of.read_ahead = clcf->read_ahead;
- of.directio = clcf->directio;
- of.valid = clcf->open_file_cache_valid;
- of.min_uses = clcf->open_file_cache_min_uses;
- of.test_only = 1;
- of.errors = clcf->open_file_cache_errors;
- of.events = clcf->open_file_cache_events;
-
- if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
- != NGX_OK)
- {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, of.err,
- "%s \"%s\" failed", of.failed, path.data);
-
- if (of.err == 0) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
-#if (NGX_HAVE_OPENAT)
- if (of.err == NGX_EMLINK
- || of.err == NGX_ELOOP)
- {
- return NGX_HTTP_FORBIDDEN;
- }
-#endif
-
- if (of.err == NGX_ENOTDIR
- || of.err == NGX_ENAMETOOLONG
- || of.err == NGX_EACCES)
- {
- return ngx_http_index_error(r, clcf, path.data, of.err);
- }
-
- if (!dir_tested) {
- rc = ngx_http_index_test_dir(r, clcf, path.data, name - 1);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- dir_tested = 1;
- }
-
- if (of.err == NGX_ENOENT) {
- continue;
- }
-
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
- "%s \"%s\" failed", of.failed, path.data);
-
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- uri.len = r->uri.len + len - 1;
-
- if (!clcf->alias) {
- uri.data = path.data + root;
-
- } else {
- uri.data = ngx_pnalloc(r->pool, uri.len);
- if (uri.data == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- p = ngx_copy(uri.data, r->uri.data, r->uri.len);
- ngx_memcpy(p, name, len - 1);
- }
-
- return ngx_http_internal_redirect(r, &uri, &r->args);
- }
-
- return NGX_DECLINED;
-}
-
-
-static ngx_int_t
-ngx_http_index_test_dir(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf,
- u_char *path, u_char *last)
-{
- u_char c;
- ngx_str_t dir;
- ngx_open_file_info_t of;
-
- c = *last;
- if (c != '/' || path == last) {
- /* "alias" without trailing slash */
- c = *(++last);
- }
- *last = '\0';
-
- dir.len = last - path;
- dir.data = path;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http index check dir: \"%V\"", &dir);
-
- ngx_memzero(&of, sizeof(ngx_open_file_info_t));
-
- of.test_dir = 1;
- of.test_only = 1;
- of.valid = clcf->open_file_cache_valid;
- of.errors = clcf->open_file_cache_errors;
-
- if (ngx_http_set_disable_symlinks(r, clcf, &dir, &of) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_open_cached_file(clcf->open_file_cache, &dir, &of, r->pool)
- != NGX_OK)
- {
- if (of.err) {
-
-#if (NGX_HAVE_OPENAT)
- if (of.err == NGX_EMLINK
- || of.err == NGX_ELOOP)
- {
- return NGX_HTTP_FORBIDDEN;
- }
-#endif
-
- if (of.err == NGX_ENOENT) {
- *last = c;
- return ngx_http_index_error(r, clcf, dir.data, NGX_ENOENT);
- }
-
- if (of.err == NGX_EACCES) {
-
- *last = c;
-
- /*
- * ngx_http_index_test_dir() is called after the first index
- * file testing has returned an error distinct from NGX_EACCES.
- * This means that directory searching is allowed.
- */
-
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
- "%s \"%s\" failed", of.failed, dir.data);
- }
-
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- *last = c;
-
- if (of.is_dir) {
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "\"%s\" is not a directory", dir.data);
-
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_index_error(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf,
- u_char *file, ngx_err_t err)
-{
- if (err == NGX_EACCES) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
- "\"%s\" is forbidden", file);
-
- return NGX_HTTP_FORBIDDEN;
- }
-
- if (clcf->log_not_found) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
- "\"%s\" is not found", file);
- }
-
- return NGX_HTTP_NOT_FOUND;
-}
-
-
-static void *
-ngx_http_index_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_index_loc_conf_t *conf;
-
- conf = ngx_palloc(cf->pool, sizeof(ngx_http_index_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- conf->indices = NULL;
- conf->max_index_len = 0;
-
- return conf;
-}
-
-
-static char *
-ngx_http_index_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_index_loc_conf_t *prev = parent;
- ngx_http_index_loc_conf_t *conf = child;
-
- ngx_http_index_t *index;
-
- if (conf->indices == NULL) {
- conf->indices = prev->indices;
- conf->max_index_len = prev->max_index_len;
- }
-
- if (conf->indices == NULL) {
- conf->indices = ngx_array_create(cf->pool, 1, sizeof(ngx_http_index_t));
- if (conf->indices == NULL) {
- return NGX_CONF_ERROR;
- }
-
- index = ngx_array_push(conf->indices);
- if (index == NULL) {
- return NGX_CONF_ERROR;
- }
-
- index->name.len = sizeof(NGX_HTTP_DEFAULT_INDEX);
- index->name.data = (u_char *) NGX_HTTP_DEFAULT_INDEX;
- index->lengths = NULL;
- index->values = NULL;
-
- conf->max_index_len = sizeof(NGX_HTTP_DEFAULT_INDEX);
-
- return NGX_CONF_OK;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_index_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_index_handler;
-
- return NGX_OK;
-}
-
-
-/* TODO: warn about duplicate indices */
-
-static char *
-ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_index_loc_conf_t *ilcf = conf;
-
- ngx_str_t *value;
- ngx_uint_t i, n;
- ngx_http_index_t *index;
- ngx_http_script_compile_t sc;
-
- if (ilcf->indices == NULL) {
- ilcf->indices = ngx_array_create(cf->pool, 2, sizeof(ngx_http_index_t));
- if (ilcf->indices == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (value[i].data[0] == '/' && i != cf->args->nelts - 1) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "only the last index in \"index\" directive "
- "should be absolute");
- }
-
- if (value[i].len == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "index \"%V\" in \"index\" directive is invalid",
- &value[1]);
- return NGX_CONF_ERROR;
- }
-
- index = ngx_array_push(ilcf->indices);
- if (index == NULL) {
- return NGX_CONF_ERROR;
- }
-
- index->name.len = value[i].len;
- index->name.data = value[i].data;
- index->lengths = NULL;
- index->values = NULL;
-
- n = ngx_http_script_variables_count(&value[i]);
-
- if (n == 0) {
- if (ilcf->max_index_len < index->name.len) {
- ilcf->max_index_len = index->name.len;
- }
-
- if (index->name.data[0] == '/') {
- continue;
- }
-
- /* include the terminating '\0' to the length to use ngx_memcpy() */
- index->name.len++;
-
- continue;
- }
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = &value[i];
- sc.lengths = &index->lengths;
- sc.values = &index->values;
- sc.variables = n;
- sc.complete_lengths = 1;
- sc.complete_values = 1;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_limit_conn_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_limit_conn_module.c
deleted file mode 100644
index 7f0eea7ab00..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_limit_conn_module.c
+++ /dev/null
@@ -1,767 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- u_char color;
- u_char len;
- u_short conn;
- u_char data[1];
-} ngx_http_limit_conn_node_t;
-
-
-typedef struct {
- ngx_shm_zone_t *shm_zone;
- ngx_rbtree_node_t *node;
-} ngx_http_limit_conn_cleanup_t;
-
-
-typedef struct {
- ngx_rbtree_t *rbtree;
- ngx_int_t index;
- ngx_str_t var;
-} ngx_http_limit_conn_ctx_t;
-
-
-typedef struct {
- ngx_shm_zone_t *shm_zone;
- ngx_uint_t conn;
-} ngx_http_limit_conn_limit_t;
-
-
-typedef struct {
- ngx_array_t limits;
- ngx_uint_t log_level;
- ngx_uint_t status_code;
-} ngx_http_limit_conn_conf_t;
-
-
-static ngx_rbtree_node_t *ngx_http_limit_conn_lookup(ngx_rbtree_t *rbtree,
- ngx_http_variable_value_t *vv, uint32_t hash);
-static void ngx_http_limit_conn_cleanup(void *data);
-static ngx_inline void ngx_http_limit_conn_cleanup_all(ngx_pool_t *pool);
-
-static void *ngx_http_limit_conn_create_conf(ngx_conf_t *cf);
-static char *ngx_http_limit_conn_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static char *ngx_http_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_limit_zone(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static ngx_int_t ngx_http_limit_conn_init(ngx_conf_t *cf);
-
-
-static ngx_conf_deprecated_t ngx_conf_deprecated_limit_zone = {
- ngx_conf_deprecated, "limit_zone", "limit_conn_zone"
-};
-
-
-static ngx_conf_enum_t ngx_http_limit_conn_log_levels[] = {
- { ngx_string("info"), NGX_LOG_INFO },
- { ngx_string("notice"), NGX_LOG_NOTICE },
- { ngx_string("warn"), NGX_LOG_WARN },
- { ngx_string("error"), NGX_LOG_ERR },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_conf_num_bounds_t ngx_http_limit_conn_status_bounds = {
- ngx_conf_check_num_bounds, 400, 599
-};
-
-
-static ngx_command_t ngx_http_limit_conn_commands[] = {
-
- { ngx_string("limit_conn_zone"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE2,
- ngx_http_limit_conn_zone,
- 0,
- 0,
- NULL },
-
- { ngx_string("limit_zone"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE3,
- ngx_http_limit_zone,
- 0,
- 0,
- NULL },
-
- { ngx_string("limit_conn"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_http_limit_conn,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("limit_conn_log_level"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_limit_conn_conf_t, log_level),
- &ngx_http_limit_conn_log_levels },
-
- { ngx_string("limit_conn_status"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_limit_conn_conf_t, status_code),
- &ngx_http_limit_conn_status_bounds },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_limit_conn_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_limit_conn_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_limit_conn_create_conf, /* create location configuration */
- ngx_http_limit_conn_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_limit_conn_module = {
- NGX_MODULE_V1,
- &ngx_http_limit_conn_module_ctx, /* module context */
- ngx_http_limit_conn_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_limit_conn_handler(ngx_http_request_t *r)
-{
- size_t len, n;
- uint32_t hash;
- ngx_uint_t i;
- ngx_slab_pool_t *shpool;
- ngx_rbtree_node_t *node;
- ngx_pool_cleanup_t *cln;
- ngx_http_variable_value_t *vv;
- ngx_http_limit_conn_ctx_t *ctx;
- ngx_http_limit_conn_node_t *lc;
- ngx_http_limit_conn_conf_t *lccf;
- ngx_http_limit_conn_limit_t *limits;
- ngx_http_limit_conn_cleanup_t *lccln;
-
- if (r->main->limit_conn_set) {
- return NGX_DECLINED;
- }
-
- lccf = ngx_http_get_module_loc_conf(r, ngx_http_limit_conn_module);
- limits = lccf->limits.elts;
-
- for (i = 0; i < lccf->limits.nelts; i++) {
- ctx = limits[i].shm_zone->data;
-
- vv = ngx_http_get_indexed_variable(r, ctx->index);
-
- if (vv == NULL || vv->not_found) {
- continue;
- }
-
- len = vv->len;
-
- if (len == 0) {
- continue;
- }
-
- 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\"",
- &ctx->var, vv);
- continue;
- }
-
- r->main->limit_conn_set = 1;
-
- hash = ngx_crc32_short(vv->data, len);
-
- shpool = (ngx_slab_pool_t *) limits[i].shm_zone->shm.addr;
-
- ngx_shmtx_lock(&shpool->mutex);
-
- node = ngx_http_limit_conn_lookup(ctx->rbtree, vv, hash);
-
- if (node == NULL) {
-
- n = offsetof(ngx_rbtree_node_t, color)
- + offsetof(ngx_http_limit_conn_node_t, data)
- + len;
-
- node = ngx_slab_alloc_locked(shpool, n);
-
- if (node == NULL) {
- ngx_shmtx_unlock(&shpool->mutex);
- ngx_http_limit_conn_cleanup_all(r->pool);
- return lccf->status_code;
- }
-
- lc = (ngx_http_limit_conn_node_t *) &node->color;
-
- node->key = hash;
- lc->len = (u_char) len;
- lc->conn = 1;
- ngx_memcpy(lc->data, vv->data, len);
-
- ngx_rbtree_insert(ctx->rbtree, node);
-
- } else {
-
- lc = (ngx_http_limit_conn_node_t *) &node->color;
-
- if ((ngx_uint_t) lc->conn >= limits[i].conn) {
-
- ngx_shmtx_unlock(&shpool->mutex);
-
- ngx_log_error(lccf->log_level, r->connection->log, 0,
- "limiting connections by zone \"%V\"",
- &limits[i].shm_zone->shm.name);
-
- ngx_http_limit_conn_cleanup_all(r->pool);
- return lccf->status_code;
- }
-
- lc->conn++;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "limit conn: %08XD %d", node->key, lc->conn);
-
- ngx_shmtx_unlock(&shpool->mutex);
-
- cln = ngx_pool_cleanup_add(r->pool,
- sizeof(ngx_http_limit_conn_cleanup_t));
- if (cln == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- cln->handler = ngx_http_limit_conn_cleanup;
- lccln = cln->data;
-
- lccln->shm_zone = limits[i].shm_zone;
- lccln->node = node;
- }
-
- return NGX_DECLINED;
-}
-
-
-static void
-ngx_http_limit_conn_rbtree_insert_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
-{
- ngx_rbtree_node_t **p;
- ngx_http_limit_conn_node_t *lcn, *lcnt;
-
- for ( ;; ) {
-
- if (node->key < temp->key) {
-
- p = &temp->left;
-
- } else if (node->key > temp->key) {
-
- p = &temp->right;
-
- } else { /* node->key == temp->key */
-
- lcn = (ngx_http_limit_conn_node_t *) &node->color;
- lcnt = (ngx_http_limit_conn_node_t *) &temp->color;
-
- p = (ngx_memn2cmp(lcn->data, lcnt->data, lcn->len, lcnt->len) < 0)
- ? &temp->left : &temp->right;
- }
-
- if (*p == sentinel) {
- break;
- }
-
- temp = *p;
- }
-
- *p = node;
- node->parent = temp;
- node->left = sentinel;
- node->right = sentinel;
- ngx_rbt_red(node);
-}
-
-
-static ngx_rbtree_node_t *
-ngx_http_limit_conn_lookup(ngx_rbtree_t *rbtree, ngx_http_variable_value_t *vv,
- uint32_t hash)
-{
- ngx_int_t rc;
- ngx_rbtree_node_t *node, *sentinel;
- ngx_http_limit_conn_node_t *lcn;
-
- node = rbtree->root;
- sentinel = rbtree->sentinel;
-
- while (node != sentinel) {
-
- if (hash < node->key) {
- node = node->left;
- continue;
- }
-
- if (hash > node->key) {
- node = node->right;
- continue;
- }
-
- /* hash == node->key */
-
- lcn = (ngx_http_limit_conn_node_t *) &node->color;
-
- rc = ngx_memn2cmp(vv->data, lcn->data,
- (size_t) vv->len, (size_t) lcn->len);
- if (rc == 0) {
- return node;
- }
-
- node = (rc < 0) ? node->left : node->right;
- }
-
- return NULL;
-}
-
-
-static void
-ngx_http_limit_conn_cleanup(void *data)
-{
- ngx_http_limit_conn_cleanup_t *lccln = data;
-
- ngx_slab_pool_t *shpool;
- ngx_rbtree_node_t *node;
- ngx_http_limit_conn_ctx_t *ctx;
- ngx_http_limit_conn_node_t *lc;
-
- ctx = lccln->shm_zone->data;
- shpool = (ngx_slab_pool_t *) lccln->shm_zone->shm.addr;
- node = lccln->node;
- lc = (ngx_http_limit_conn_node_t *) &node->color;
-
- ngx_shmtx_lock(&shpool->mutex);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, lccln->shm_zone->shm.log, 0,
- "limit conn cleanup: %08XD %d", node->key, lc->conn);
-
- lc->conn--;
-
- if (lc->conn == 0) {
- ngx_rbtree_delete(ctx->rbtree, node);
- ngx_slab_free_locked(shpool, node);
- }
-
- ngx_shmtx_unlock(&shpool->mutex);
-}
-
-
-static ngx_inline void
-ngx_http_limit_conn_cleanup_all(ngx_pool_t *pool)
-{
- ngx_pool_cleanup_t *cln;
-
- cln = pool->cleanup;
-
- while (cln && cln->handler == ngx_http_limit_conn_cleanup) {
- ngx_http_limit_conn_cleanup(cln->data);
- cln = cln->next;
- }
-
- pool->cleanup = cln;
-}
-
-
-static ngx_int_t
-ngx_http_limit_conn_init_zone(ngx_shm_zone_t *shm_zone, void *data)
-{
- ngx_http_limit_conn_ctx_t *octx = data;
-
- size_t len;
- ngx_slab_pool_t *shpool;
- ngx_rbtree_node_t *sentinel;
- ngx_http_limit_conn_ctx_t *ctx;
-
- ctx = shm_zone->data;
-
- if (octx) {
- if (ngx_strcmp(ctx->var.data, octx->var.data) != 0) {
- ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
- "limit_conn_zone \"%V\" uses the \"%V\" variable "
- "while previously it used the \"%V\" variable",
- &shm_zone->shm.name, &ctx->var, &octx->var);
- return NGX_ERROR;
- }
-
- ctx->rbtree = octx->rbtree;
-
- return NGX_OK;
- }
-
- shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
-
- if (shm_zone->shm.exists) {
- ctx->rbtree = shpool->data;
-
- return NGX_OK;
- }
-
- ctx->rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t));
- if (ctx->rbtree == NULL) {
- return NGX_ERROR;
- }
-
- shpool->data = ctx->rbtree;
-
- sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t));
- if (sentinel == NULL) {
- return NGX_ERROR;
- }
-
- ngx_rbtree_init(ctx->rbtree, sentinel,
- ngx_http_limit_conn_rbtree_insert_value);
-
- len = sizeof(" in limit_conn_zone \"\"") + shm_zone->shm.name.len;
-
- shpool->log_ctx = ngx_slab_alloc(shpool, len);
- if (shpool->log_ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_sprintf(shpool->log_ctx, " in limit_conn_zone \"%V\"%Z",
- &shm_zone->shm.name);
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_limit_conn_create_conf(ngx_conf_t *cf)
-{
- ngx_http_limit_conn_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_conn_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->limits.elts = NULL;
- */
-
- conf->log_level = NGX_CONF_UNSET_UINT;
- conf->status_code = NGX_CONF_UNSET_UINT;
-
- return conf;
-}
-
-
-static char *
-ngx_http_limit_conn_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_limit_conn_conf_t *prev = parent;
- ngx_http_limit_conn_conf_t *conf = child;
-
- if (conf->limits.elts == NULL) {
- conf->limits = prev->limits;
- }
-
- ngx_conf_merge_uint_value(conf->log_level, prev->log_level, NGX_LOG_ERR);
- ngx_conf_merge_uint_value(conf->status_code, prev->status_code,
- NGX_HTTP_SERVICE_UNAVAILABLE);
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- u_char *p;
- ssize_t size;
- ngx_str_t *value, name, s;
- ngx_uint_t i;
- ngx_shm_zone_t *shm_zone;
- ngx_http_limit_conn_ctx_t *ctx;
-
- value = cf->args->elts;
-
- ctx = NULL;
- size = 0;
- name.len = 0;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (ngx_strncmp(value[i].data, "zone=", 5) == 0) {
-
- name.data = value[i].data + 5;
-
- p = (u_char *) ngx_strchr(name.data, ':');
-
- if (p == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid zone size \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- name.len = p - name.data;
-
- s.data = p + 1;
- s.len = value[i].data + value[i].len - s.data;
-
- size = ngx_parse_size(&s);
-
- if (size == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid zone size \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (size < (ssize_t) (8 * ngx_pagesize)) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "zone \"%V\" is too small", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (value[i].data[0] == '$') {
-
- value[i].len--;
- value[i].data++;
-
- ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_conn_ctx_t));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->index = ngx_http_get_variable_index(cf, &value[i]);
- if (ctx->index == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- ctx->var = value[i];
-
- continue;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (name.len == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%V\" must have \"zone\" parameter",
- &cmd->name);
- return NGX_CONF_ERROR;
- }
-
- if (ctx == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "no variable is defined for %V \"%V\"",
- &cmd->name, &name);
- return NGX_CONF_ERROR;
- }
-
- shm_zone = ngx_shared_memory_add(cf, &name, size,
- &ngx_http_limit_conn_module);
- if (shm_zone == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (shm_zone->data) {
- ctx = shm_zone->data;
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "%V \"%V\" is already bound to variable \"%V\"",
- &cmd->name, &name, &ctx->var);
- return NGX_CONF_ERROR;
- }
-
- shm_zone->init = ngx_http_limit_conn_init_zone;
- shm_zone->data = ctx;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_limit_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ssize_t n;
- ngx_str_t *value;
- ngx_shm_zone_t *shm_zone;
- ngx_http_limit_conn_ctx_t *ctx;
-
- ngx_conf_deprecated(cf, &ngx_conf_deprecated_limit_zone, NULL);
-
- value = cf->args->elts;
-
- if (value[2].data[0] != '$') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid variable name \"%V\"", &value[2]);
- return NGX_CONF_ERROR;
- }
-
- value[2].len--;
- value[2].data++;
-
- ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_conn_ctx_t));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->index = ngx_http_get_variable_index(cf, &value[2]);
- if (ctx->index == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- ctx->var = value[2];
-
- n = ngx_parse_size(&value[3]);
-
- if (n == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid size of limit_zone \"%V\"", &value[3]);
- return NGX_CONF_ERROR;
- }
-
- if (n < (ngx_int_t) (8 * ngx_pagesize)) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "limit_zone \"%V\" is too small", &value[1]);
- return NGX_CONF_ERROR;
- }
-
-
- shm_zone = ngx_shared_memory_add(cf, &value[1], n,
- &ngx_http_limit_conn_module);
- if (shm_zone == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (shm_zone->data) {
- ctx = shm_zone->data;
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "limit_zone \"%V\" is already bound to variable \"%V\"",
- &value[1], &ctx->var);
- return NGX_CONF_ERROR;
- }
-
- shm_zone->init = ngx_http_limit_conn_init_zone;
- shm_zone->data = ctx;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_shm_zone_t *shm_zone;
- ngx_http_limit_conn_conf_t *lccf = conf;
- ngx_http_limit_conn_limit_t *limit, *limits;
-
- ngx_str_t *value;
- ngx_int_t n;
- ngx_uint_t i;
-
- value = cf->args->elts;
-
- shm_zone = ngx_shared_memory_add(cf, &value[1], 0,
- &ngx_http_limit_conn_module);
- if (shm_zone == NULL) {
- return NGX_CONF_ERROR;
- }
-
- limits = lccf->limits.elts;
-
- if (limits == NULL) {
- if (ngx_array_init(&lccf->limits, cf->pool, 1,
- sizeof(ngx_http_limit_conn_limit_t))
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
- }
-
- for (i = 0; i < lccf->limits.nelts; i++) {
- if (shm_zone == limits[i].shm_zone) {
- return "is duplicate";
- }
- }
-
- n = ngx_atoi(value[2].data, value[2].len);
- if (n <= 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid number of connections \"%V\"", &value[2]);
- return NGX_CONF_ERROR;
- }
-
- if (n > 65535) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "connection limit must be less 65536");
- return NGX_CONF_ERROR;
- }
-
- limit = ngx_array_push(&lccf->limits);
- if (limit == NULL) {
- return NGX_CONF_ERROR;
- }
-
- limit->conn = n;
- limit->shm_zone = shm_zone;
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_limit_conn_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_limit_conn_handler;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_limit_req_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_limit_req_module.c
deleted file mode 100644
index 74f7fdaa75f..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_limit_req_module.c
+++ /dev/null
@@ -1,989 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- u_char color;
- u_char dummy;
- u_short len;
- ngx_queue_t queue;
- ngx_msec_t last;
- /* integer value, 1 corresponds to 0.001 r/s */
- ngx_uint_t excess;
- ngx_uint_t count;
- u_char data[1];
-} ngx_http_limit_req_node_t;
-
-
-typedef struct {
- ngx_rbtree_t rbtree;
- ngx_rbtree_node_t sentinel;
- ngx_queue_t queue;
-} ngx_http_limit_req_shctx_t;
-
-
-typedef struct {
- ngx_http_limit_req_shctx_t *sh;
- ngx_slab_pool_t *shpool;
- /* integer value, 1 corresponds to 0.001 r/s */
- ngx_uint_t rate;
- ngx_int_t index;
- ngx_str_t var;
- ngx_http_limit_req_node_t *node;
-} ngx_http_limit_req_ctx_t;
-
-
-typedef struct {
- ngx_shm_zone_t *shm_zone;
- /* integer value, 1 corresponds to 0.001 r/s */
- ngx_uint_t burst;
- ngx_uint_t nodelay; /* unsigned nodelay:1 */
-} ngx_http_limit_req_limit_t;
-
-
-typedef struct {
- ngx_array_t limits;
- ngx_uint_t limit_log_level;
- ngx_uint_t delay_log_level;
- ngx_uint_t status_code;
-} ngx_http_limit_req_conf_t;
-
-
-static void ngx_http_limit_req_delay(ngx_http_request_t *r);
-static ngx_int_t ngx_http_limit_req_lookup(ngx_http_limit_req_limit_t *limit,
- ngx_uint_t hash, u_char *data, size_t len, ngx_uint_t *ep,
- ngx_uint_t account);
-static ngx_msec_t ngx_http_limit_req_account(ngx_http_limit_req_limit_t *limits,
- ngx_uint_t n, ngx_uint_t *ep, ngx_http_limit_req_limit_t **limit);
-static void ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx,
- ngx_uint_t n);
-
-static void *ngx_http_limit_req_create_conf(ngx_conf_t *cf);
-static char *ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static char *ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static ngx_int_t ngx_http_limit_req_init(ngx_conf_t *cf);
-
-
-static ngx_conf_enum_t ngx_http_limit_req_log_levels[] = {
- { ngx_string("info"), NGX_LOG_INFO },
- { ngx_string("notice"), NGX_LOG_NOTICE },
- { ngx_string("warn"), NGX_LOG_WARN },
- { ngx_string("error"), NGX_LOG_ERR },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_conf_num_bounds_t ngx_http_limit_req_status_bounds = {
- ngx_conf_check_num_bounds, 400, 599
-};
-
-
-static ngx_command_t ngx_http_limit_req_commands[] = {
-
- { ngx_string("limit_req_zone"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE3,
- ngx_http_limit_req_zone,
- 0,
- 0,
- NULL },
-
- { ngx_string("limit_req"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
- ngx_http_limit_req,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("limit_req_log_level"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_limit_req_conf_t, limit_log_level),
- &ngx_http_limit_req_log_levels },
-
- { ngx_string("limit_req_status"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_limit_req_conf_t, status_code),
- &ngx_http_limit_req_status_bounds },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_limit_req_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_limit_req_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_limit_req_create_conf, /* create location configuration */
- ngx_http_limit_req_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_limit_req_module = {
- NGX_MODULE_V1,
- &ngx_http_limit_req_module_ctx, /* module context */
- ngx_http_limit_req_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_limit_req_handler(ngx_http_request_t *r)
-{
- size_t len;
- uint32_t hash;
- ngx_int_t rc;
- ngx_uint_t n, excess;
- ngx_msec_t delay;
- ngx_http_variable_value_t *vv;
- ngx_http_limit_req_ctx_t *ctx;
- ngx_http_limit_req_conf_t *lrcf;
- ngx_http_limit_req_limit_t *limit, *limits;
-
- if (r->main->limit_req_set) {
- return NGX_DECLINED;
- }
-
- lrcf = ngx_http_get_module_loc_conf(r, ngx_http_limit_req_module);
- limits = lrcf->limits.elts;
-
- excess = 0;
-
- rc = NGX_DECLINED;
-
-#if (NGX_SUPPRESS_WARN)
- limit = NULL;
-#endif
-
- for (n = 0; n < lrcf->limits.nelts; n++) {
-
- limit = &limits[n];
-
- ctx = limit->shm_zone->data;
-
- vv = ngx_http_get_indexed_variable(r, ctx->index);
-
- if (vv == NULL || vv->not_found) {
- continue;
- }
-
- len = vv->len;
-
- if (len == 0) {
- continue;
- }
-
- if (len > 65535) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "the value of the \"%V\" variable "
- "is more than 65535 bytes: \"%v\"",
- &ctx->var, vv);
- continue;
- }
-
- hash = ngx_crc32_short(vv->data, len);
-
- ngx_shmtx_lock(&ctx->shpool->mutex);
-
- rc = ngx_http_limit_req_lookup(limit, hash, vv->data, len, &excess,
- (n == lrcf->limits.nelts - 1));
-
- ngx_shmtx_unlock(&ctx->shpool->mutex);
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "limit_req[%ui]: %i %ui.%03ui",
- n, rc, excess / 1000, excess % 1000);
-
- if (rc != NGX_AGAIN) {
- break;
- }
- }
-
- if (rc == NGX_DECLINED) {
- return NGX_DECLINED;
- }
-
- r->main->limit_req_set = 1;
-
- if (rc == NGX_BUSY || rc == NGX_ERROR) {
-
- if (rc == NGX_BUSY) {
- ngx_log_error(lrcf->limit_log_level, r->connection->log, 0,
- "limiting requests, excess: %ui.%03ui by zone \"%V\"",
- excess / 1000, excess % 1000,
- &limit->shm_zone->shm.name);
- }
-
- while (n--) {
- ctx = limits[n].shm_zone->data;
-
- if (ctx->node == NULL) {
- continue;
- }
-
- ngx_shmtx_lock(&ctx->shpool->mutex);
-
- ctx->node->count--;
-
- ngx_shmtx_unlock(&ctx->shpool->mutex);
-
- ctx->node = NULL;
- }
-
- return lrcf->status_code;
- }
-
- /* rc == NGX_AGAIN || rc == NGX_OK */
-
- if (rc == NGX_AGAIN) {
- excess = 0;
- }
-
- delay = ngx_http_limit_req_account(limits, n, &excess, &limit);
-
- if (!delay) {
- return NGX_DECLINED;
- }
-
- ngx_log_error(lrcf->delay_log_level, r->connection->log, 0,
- "delaying request, excess: %ui.%03ui, by zone \"%V\"",
- excess / 1000, excess % 1000, &limit->shm_zone->shm.name);
-
- if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- r->read_event_handler = ngx_http_test_reading;
- r->write_event_handler = ngx_http_limit_req_delay;
- ngx_add_timer(r->connection->write, delay);
-
- return NGX_AGAIN;
-}
-
-
-static void
-ngx_http_limit_req_delay(ngx_http_request_t *r)
-{
- ngx_event_t *wev;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "limit_req delay");
-
- wev = r->connection->write;
-
- if (!wev->timedout) {
-
- if (ngx_handle_write_event(wev, 0) != NGX_OK) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- }
-
- return;
- }
-
- wev->timedout = 0;
-
- if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- r->read_event_handler = ngx_http_block_reading;
- r->write_event_handler = ngx_http_core_run_phases;
-
- ngx_http_core_run_phases(r);
-}
-
-
-static void
-ngx_http_limit_req_rbtree_insert_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
-{
- ngx_rbtree_node_t **p;
- ngx_http_limit_req_node_t *lrn, *lrnt;
-
- for ( ;; ) {
-
- if (node->key < temp->key) {
-
- p = &temp->left;
-
- } else if (node->key > temp->key) {
-
- p = &temp->right;
-
- } else { /* node->key == temp->key */
-
- lrn = (ngx_http_limit_req_node_t *) &node->color;
- lrnt = (ngx_http_limit_req_node_t *) &temp->color;
-
- p = (ngx_memn2cmp(lrn->data, lrnt->data, lrn->len, lrnt->len) < 0)
- ? &temp->left : &temp->right;
- }
-
- if (*p == sentinel) {
- break;
- }
-
- temp = *p;
- }
-
- *p = node;
- node->parent = temp;
- node->left = sentinel;
- node->right = sentinel;
- ngx_rbt_red(node);
-}
-
-
-static ngx_int_t
-ngx_http_limit_req_lookup(ngx_http_limit_req_limit_t *limit, ngx_uint_t hash,
- u_char *data, size_t len, ngx_uint_t *ep, ngx_uint_t account)
-{
- size_t size;
- ngx_int_t rc, excess;
- ngx_time_t *tp;
- ngx_msec_t now;
- ngx_msec_int_t ms;
- ngx_rbtree_node_t *node, *sentinel;
- ngx_http_limit_req_ctx_t *ctx;
- ngx_http_limit_req_node_t *lr;
-
- tp = ngx_timeofday();
- now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
-
- ctx = limit->shm_zone->data;
-
- node = ctx->sh->rbtree.root;
- sentinel = ctx->sh->rbtree.sentinel;
-
- while (node != sentinel) {
-
- if (hash < node->key) {
- node = node->left;
- continue;
- }
-
- if (hash > node->key) {
- node = node->right;
- continue;
- }
-
- /* hash == node->key */
-
- lr = (ngx_http_limit_req_node_t *) &node->color;
-
- rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len);
-
- if (rc == 0) {
- ngx_queue_remove(&lr->queue);
- ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
-
- ms = (ngx_msec_int_t) (now - lr->last);
-
- excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
-
- if (excess < 0) {
- excess = 0;
- }
-
- *ep = excess;
-
- if ((ngx_uint_t) excess > limit->burst) {
- return NGX_BUSY;
- }
-
- if (account) {
- lr->excess = excess;
- lr->last = now;
- return NGX_OK;
- }
-
- lr->count++;
-
- ctx->node = lr;
-
- return NGX_AGAIN;
- }
-
- node = (rc < 0) ? node->left : node->right;
- }
-
- *ep = 0;
-
- size = offsetof(ngx_rbtree_node_t, color)
- + offsetof(ngx_http_limit_req_node_t, data)
- + len;
-
- ngx_http_limit_req_expire(ctx, 1);
-
- node = ngx_slab_alloc_locked(ctx->shpool, size);
-
- if (node == NULL) {
- ngx_http_limit_req_expire(ctx, 0);
-
- node = ngx_slab_alloc_locked(ctx->shpool, size);
- if (node == NULL) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
- "could not allocate node%s", ctx->shpool->log_ctx);
- return NGX_ERROR;
- }
- }
-
- node->key = hash;
-
- lr = (ngx_http_limit_req_node_t *) &node->color;
-
- lr->len = (u_char) len;
- lr->excess = 0;
-
- ngx_memcpy(lr->data, data, len);
-
- ngx_rbtree_insert(&ctx->sh->rbtree, node);
-
- ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
-
- if (account) {
- lr->last = now;
- lr->count = 0;
- return NGX_OK;
- }
-
- lr->last = 0;
- lr->count = 1;
-
- ctx->node = lr;
-
- return NGX_AGAIN;
-}
-
-
-static ngx_msec_t
-ngx_http_limit_req_account(ngx_http_limit_req_limit_t *limits, ngx_uint_t n,
- ngx_uint_t *ep, ngx_http_limit_req_limit_t **limit)
-{
- ngx_int_t excess;
- ngx_time_t *tp;
- ngx_msec_t now, delay, max_delay;
- ngx_msec_int_t ms;
- ngx_http_limit_req_ctx_t *ctx;
- ngx_http_limit_req_node_t *lr;
-
- excess = *ep;
-
- if (excess == 0 || (*limit)->nodelay) {
- max_delay = 0;
-
- } else {
- ctx = (*limit)->shm_zone->data;
- max_delay = excess * 1000 / ctx->rate;
- }
-
- while (n--) {
- ctx = limits[n].shm_zone->data;
- lr = ctx->node;
-
- if (lr == NULL) {
- continue;
- }
-
- ngx_shmtx_lock(&ctx->shpool->mutex);
-
- tp = ngx_timeofday();
-
- now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
- ms = (ngx_msec_int_t) (now - lr->last);
-
- excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000;
-
- if (excess < 0) {
- excess = 0;
- }
-
- lr->last = now;
- lr->excess = excess;
- lr->count--;
-
- ngx_shmtx_unlock(&ctx->shpool->mutex);
-
- ctx->node = NULL;
-
- if (limits[n].nodelay) {
- continue;
- }
-
- delay = excess * 1000 / ctx->rate;
-
- if (delay > max_delay) {
- max_delay = delay;
- *ep = excess;
- *limit = &limits[n];
- }
- }
-
- return max_delay;
-}
-
-
-static void
-ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n)
-{
- ngx_int_t excess;
- ngx_time_t *tp;
- ngx_msec_t now;
- ngx_queue_t *q;
- ngx_msec_int_t ms;
- ngx_rbtree_node_t *node;
- ngx_http_limit_req_node_t *lr;
-
- tp = ngx_timeofday();
-
- now = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
-
- /*
- * n == 1 deletes one or two zero rate entries
- * n == 0 deletes oldest entry by force
- * and one or two zero rate entries
- */
-
- while (n < 3) {
-
- if (ngx_queue_empty(&ctx->sh->queue)) {
- return;
- }
-
- q = ngx_queue_last(&ctx->sh->queue);
-
- lr = ngx_queue_data(q, ngx_http_limit_req_node_t, queue);
-
- if (lr->count) {
-
- /*
- * There is not much sense in looking further,
- * because we bump nodes on the lookup stage.
- */
-
- return;
- }
-
- if (n++ != 0) {
-
- ms = (ngx_msec_int_t) (now - lr->last);
- ms = ngx_abs(ms);
-
- if (ms < 60000) {
- return;
- }
-
- excess = lr->excess - ctx->rate * ms / 1000;
-
- if (excess > 0) {
- return;
- }
- }
-
- ngx_queue_remove(q);
-
- node = (ngx_rbtree_node_t *)
- ((u_char *) lr - offsetof(ngx_rbtree_node_t, color));
-
- ngx_rbtree_delete(&ctx->sh->rbtree, node);
-
- ngx_slab_free_locked(ctx->shpool, node);
- }
-}
-
-
-static ngx_int_t
-ngx_http_limit_req_init_zone(ngx_shm_zone_t *shm_zone, void *data)
-{
- ngx_http_limit_req_ctx_t *octx = data;
-
- size_t len;
- ngx_http_limit_req_ctx_t *ctx;
-
- ctx = shm_zone->data;
-
- if (octx) {
- if (ngx_strcmp(ctx->var.data, octx->var.data) != 0) {
- ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
- "limit_req \"%V\" uses the \"%V\" variable "
- "while previously it used the \"%V\" variable",
- &shm_zone->shm.name, &ctx->var, &octx->var);
- return NGX_ERROR;
- }
-
- ctx->sh = octx->sh;
- ctx->shpool = octx->shpool;
-
- return NGX_OK;
- }
-
- ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
-
- if (shm_zone->shm.exists) {
- ctx->sh = ctx->shpool->data;
-
- return NGX_OK;
- }
-
- ctx->sh = ngx_slab_alloc(ctx->shpool, sizeof(ngx_http_limit_req_shctx_t));
- if (ctx->sh == NULL) {
- return NGX_ERROR;
- }
-
- ctx->shpool->data = ctx->sh;
-
- ngx_rbtree_init(&ctx->sh->rbtree, &ctx->sh->sentinel,
- ngx_http_limit_req_rbtree_insert_value);
-
- ngx_queue_init(&ctx->sh->queue);
-
- len = sizeof(" in limit_req zone \"\"") + shm_zone->shm.name.len;
-
- ctx->shpool->log_ctx = ngx_slab_alloc(ctx->shpool, len);
- if (ctx->shpool->log_ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_sprintf(ctx->shpool->log_ctx, " in limit_req zone \"%V\"%Z",
- &shm_zone->shm.name);
-
- ctx->shpool->log_nomem = 0;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_limit_req_create_conf(ngx_conf_t *cf)
-{
- ngx_http_limit_req_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_req_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->limits.elts = NULL;
- */
-
- conf->limit_log_level = NGX_CONF_UNSET_UINT;
- conf->status_code = NGX_CONF_UNSET_UINT;
-
- return conf;
-}
-
-
-static char *
-ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_limit_req_conf_t *prev = parent;
- ngx_http_limit_req_conf_t *conf = child;
-
- if (conf->limits.elts == NULL) {
- conf->limits = prev->limits;
- }
-
- ngx_conf_merge_uint_value(conf->limit_log_level, prev->limit_log_level,
- NGX_LOG_ERR);
-
- conf->delay_log_level = (conf->limit_log_level == NGX_LOG_INFO) ?
- NGX_LOG_INFO : conf->limit_log_level + 1;
-
- ngx_conf_merge_uint_value(conf->status_code, prev->status_code,
- NGX_HTTP_SERVICE_UNAVAILABLE);
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- u_char *p;
- size_t len;
- ssize_t size;
- ngx_str_t *value, name, s;
- ngx_int_t rate, scale;
- ngx_uint_t i;
- ngx_shm_zone_t *shm_zone;
- ngx_http_limit_req_ctx_t *ctx;
-
- value = cf->args->elts;
-
- ctx = NULL;
- size = 0;
- rate = 1;
- scale = 1;
- name.len = 0;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (ngx_strncmp(value[i].data, "zone=", 5) == 0) {
-
- name.data = value[i].data + 5;
-
- p = (u_char *) ngx_strchr(name.data, ':');
-
- if (p == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid zone size \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- name.len = p - name.data;
-
- s.data = p + 1;
- s.len = value[i].data + value[i].len - s.data;
-
- size = ngx_parse_size(&s);
-
- if (size == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid zone size \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (size < (ssize_t) (8 * ngx_pagesize)) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "zone \"%V\" is too small", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "rate=", 5) == 0) {
-
- len = value[i].len;
- p = value[i].data + len - 3;
-
- if (ngx_strncmp(p, "r/s", 3) == 0) {
- scale = 1;
- len -= 3;
-
- } else if (ngx_strncmp(p, "r/m", 3) == 0) {
- scale = 60;
- len -= 3;
- }
-
- rate = ngx_atoi(value[i].data + 5, len - 5);
- if (rate <= 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid rate \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (value[i].data[0] == '$') {
-
- value[i].len--;
- value[i].data++;
-
- ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_req_ctx_t));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->index = ngx_http_get_variable_index(cf, &value[i]);
- if (ctx->index == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- ctx->var = value[i];
-
- continue;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (name.len == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%V\" must have \"zone\" parameter",
- &cmd->name);
- return NGX_CONF_ERROR;
- }
-
- if (ctx == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "no variable is defined for %V \"%V\"",
- &cmd->name, &name);
- return NGX_CONF_ERROR;
- }
-
- ctx->rate = rate * 1000 / scale;
-
- shm_zone = ngx_shared_memory_add(cf, &name, size,
- &ngx_http_limit_req_module);
- if (shm_zone == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (shm_zone->data) {
- ctx = shm_zone->data;
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "%V \"%V\" is already bound to variable \"%V\"",
- &cmd->name, &name, &ctx->var);
- return NGX_CONF_ERROR;
- }
-
- shm_zone->init = ngx_http_limit_req_init_zone;
- shm_zone->data = ctx;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_limit_req_conf_t *lrcf = conf;
-
- ngx_int_t burst;
- ngx_str_t *value, s;
- ngx_uint_t i, nodelay;
- ngx_shm_zone_t *shm_zone;
- ngx_http_limit_req_limit_t *limit, *limits;
-
- value = cf->args->elts;
-
- shm_zone = NULL;
- burst = 0;
- nodelay = 0;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (ngx_strncmp(value[i].data, "zone=", 5) == 0) {
-
- s.len = value[i].len - 5;
- s.data = value[i].data + 5;
-
- shm_zone = ngx_shared_memory_add(cf, &s, 0,
- &ngx_http_limit_req_module);
- if (shm_zone == NULL) {
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "burst=", 6) == 0) {
-
- burst = ngx_atoi(value[i].data + 6, value[i].len - 6);
- if (burst <= 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid burst rate \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (ngx_strcmp(value[i].data, "nodelay") == 0) {
- nodelay = 1;
- continue;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (shm_zone == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%V\" must have \"zone\" parameter",
- &cmd->name);
- return NGX_CONF_ERROR;
- }
-
- if (shm_zone->data == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unknown limit_req_zone \"%V\"",
- &shm_zone->shm.name);
- return NGX_CONF_ERROR;
- }
-
- limits = lrcf->limits.elts;
-
- if (limits == NULL) {
- if (ngx_array_init(&lrcf->limits, cf->pool, 1,
- sizeof(ngx_http_limit_req_limit_t))
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
- }
-
- for (i = 0; i < lrcf->limits.nelts; i++) {
- if (shm_zone == limits[i].shm_zone) {
- return "is duplicate";
- }
- }
-
- limit = ngx_array_push(&lrcf->limits);
- if (limit == NULL) {
- return NGX_CONF_ERROR;
- }
-
- limit->shm_zone = shm_zone;
- limit->burst = burst * 1000;
- limit->nodelay = nodelay;
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_limit_req_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_limit_req_handler;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_log_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_log_module.c
deleted file mode 100644
index cd9afa7ac9e..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_log_module.c
+++ /dev/null
@@ -1,1758 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-#if (NGX_ZLIB)
-#include <zlib.h>
-#endif
-
-
-typedef struct ngx_http_log_op_s ngx_http_log_op_t;
-
-typedef u_char *(*ngx_http_log_op_run_pt) (ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op);
-
-typedef size_t (*ngx_http_log_op_getlen_pt) (ngx_http_request_t *r,
- uintptr_t data);
-
-
-struct ngx_http_log_op_s {
- size_t len;
- ngx_http_log_op_getlen_pt getlen;
- ngx_http_log_op_run_pt run;
- uintptr_t data;
-};
-
-
-typedef struct {
- ngx_str_t name;
- ngx_array_t *flushes;
- ngx_array_t *ops; /* array of ngx_http_log_op_t */
-} ngx_http_log_fmt_t;
-
-
-typedef struct {
- ngx_array_t formats; /* array of ngx_http_log_fmt_t */
- ngx_uint_t combined_used; /* unsigned combined_used:1 */
-} ngx_http_log_main_conf_t;
-
-
-typedef struct {
- u_char *start;
- u_char *pos;
- u_char *last;
-
- ngx_event_t *event;
- ngx_msec_t flush;
- ngx_int_t gzip;
-} ngx_http_log_buf_t;
-
-
-typedef struct {
- ngx_array_t *lengths;
- ngx_array_t *values;
-} ngx_http_log_script_t;
-
-
-typedef struct {
- ngx_open_file_t *file;
- ngx_http_log_script_t *script;
- time_t disk_full_time;
- time_t error_log_time;
- ngx_syslog_peer_t *syslog_peer;
- ngx_http_log_fmt_t *format;
-} ngx_http_log_t;
-
-
-typedef struct {
- ngx_array_t *logs; /* array of ngx_http_log_t */
-
- ngx_open_file_cache_t *open_file_cache;
- time_t open_file_cache_valid;
- ngx_uint_t open_file_cache_min_uses;
-
- ngx_uint_t off; /* unsigned off:1 */
-} ngx_http_log_loc_conf_t;
-
-
-typedef struct {
- ngx_str_t name;
- size_t len;
- ngx_http_log_op_run_pt run;
-} ngx_http_log_var_t;
-
-
-static void ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log,
- u_char *buf, size_t len);
-static ssize_t ngx_http_log_script_write(ngx_http_request_t *r,
- ngx_http_log_script_t *script, u_char **name, u_char *buf, size_t len);
-
-#if (NGX_ZLIB)
-static ssize_t ngx_http_log_gzip(ngx_fd_t fd, u_char *buf, size_t len,
- ngx_int_t level, ngx_log_t *log);
-
-static void *ngx_http_log_gzip_alloc(void *opaque, u_int items, u_int size);
-static void ngx_http_log_gzip_free(void *opaque, void *address);
-#endif
-
-static void ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log);
-static void ngx_http_log_flush_handler(ngx_event_t *ev);
-
-static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op);
-static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op);
-static u_char *ngx_http_log_iso8601(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op);
-static u_char *ngx_http_log_msec(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op);
-static u_char *ngx_http_log_request_time(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op);
-static u_char *ngx_http_log_status(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op);
-static u_char *ngx_http_log_bytes_sent(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op);
-static u_char *ngx_http_log_body_bytes_sent(ngx_http_request_t *r,
- u_char *buf, ngx_http_log_op_t *op);
-static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op);
-
-static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf,
- ngx_http_log_op_t *op, ngx_str_t *value);
-static size_t ngx_http_log_variable_getlen(ngx_http_request_t *r,
- uintptr_t data);
-static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op);
-static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size);
-
-
-static void *ngx_http_log_create_main_conf(ngx_conf_t *cf);
-static void *ngx_http_log_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static char *ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_log_compile_format(ngx_conf_t *cf,
- ngx_array_t *flushes, ngx_array_t *ops, ngx_array_t *args, ngx_uint_t s);
-static char *ngx_http_log_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static ngx_int_t ngx_http_log_init(ngx_conf_t *cf);
-
-
-static ngx_command_t ngx_http_log_commands[] = {
-
- { ngx_string("log_format"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
- ngx_http_log_set_format,
- NGX_HTTP_MAIN_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("access_log"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_HTTP_LMT_CONF|NGX_CONF_1MORE,
- ngx_http_log_set_log,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("open_log_file_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
- ngx_http_log_open_file_cache,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_log_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_log_init, /* postconfiguration */
-
- ngx_http_log_create_main_conf, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_log_create_loc_conf, /* create location configuration */
- ngx_http_log_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_log_module = {
- NGX_MODULE_V1,
- &ngx_http_log_module_ctx, /* module context */
- ngx_http_log_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_str_t ngx_http_access_log = ngx_string(NGX_HTTP_LOG_PATH);
-
-
-static ngx_str_t ngx_http_combined_fmt =
- ngx_string("$remote_addr - $remote_user [$time_local] "
- "\"$request\" $status $body_bytes_sent "
- "\"$http_referer\" \"$http_user_agent\"");
-
-
-static ngx_http_log_var_t ngx_http_log_vars[] = {
- { ngx_string("pipe"), 1, ngx_http_log_pipe },
- { ngx_string("time_local"), sizeof("28/Sep/1970:12:00:00 +0600") - 1,
- ngx_http_log_time },
- { ngx_string("time_iso8601"), sizeof("1970-09-28T12:00:00+06:00") - 1,
- ngx_http_log_iso8601 },
- { ngx_string("msec"), NGX_TIME_T_LEN + 4, ngx_http_log_msec },
- { ngx_string("request_time"), NGX_TIME_T_LEN + 4,
- ngx_http_log_request_time },
- { ngx_string("status"), NGX_INT_T_LEN, ngx_http_log_status },
- { ngx_string("bytes_sent"), NGX_OFF_T_LEN, ngx_http_log_bytes_sent },
- { ngx_string("body_bytes_sent"), NGX_OFF_T_LEN,
- ngx_http_log_body_bytes_sent },
- { ngx_string("request_length"), NGX_SIZE_T_LEN,
- ngx_http_log_request_length },
-
- { ngx_null_string, 0, NULL }
-};
-
-
-static ngx_int_t
-ngx_http_log_handler(ngx_http_request_t *r)
-{
- u_char *line, *p;
- size_t len, size;
- ssize_t n;
- ngx_uint_t i, l;
- ngx_http_log_t *log;
- ngx_http_log_op_t *op;
- ngx_http_log_buf_t *buffer;
- ngx_http_log_loc_conf_t *lcf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http log handler");
-
- lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
-
- if (lcf->off) {
- return NGX_OK;
- }
-
- log = lcf->logs->elts;
- for (l = 0; l < lcf->logs->nelts; l++) {
-
- if (ngx_time() == log[l].disk_full_time) {
-
- /*
- * on FreeBSD writing to a full filesystem with enabled softupdates
- * may block process for much longer time than writing to non-full
- * filesystem, so we skip writing to a log for one second
- */
-
- continue;
- }
-
- ngx_http_script_flush_no_cacheable_variables(r, log[l].format->flushes);
-
- len = 0;
- op = log[l].format->ops->elts;
- for (i = 0; i < log[l].format->ops->nelts; i++) {
- if (op[i].len == 0) {
- len += op[i].getlen(r, op[i].data);
-
- } else {
- len += op[i].len;
- }
- }
-
- if (log[l].syslog_peer) {
-
- /* length of syslog's PRI and HEADER message parts */
- len += sizeof("<255>Jan 01 00:00:00 ") - 1
- + ngx_cycle->hostname.len + 1
- + log[l].syslog_peer->tag.len + 2;
-
- goto alloc_line;
- }
-
- len += NGX_LINEFEED_SIZE;
-
- buffer = log[l].file ? log[l].file->data : NULL;
-
- if (buffer) {
-
- if (len > (size_t) (buffer->last - buffer->pos)) {
-
- ngx_http_log_write(r, &log[l], buffer->start,
- buffer->pos - buffer->start);
-
- buffer->pos = buffer->start;
- }
-
- if (len <= (size_t) (buffer->last - buffer->pos)) {
-
- p = buffer->pos;
-
- if (buffer->event && p == buffer->start) {
- ngx_add_timer(buffer->event, buffer->flush);
- }
-
- for (i = 0; i < log[l].format->ops->nelts; i++) {
- p = op[i].run(r, p, &op[i]);
- }
-
- ngx_linefeed(p);
-
- buffer->pos = p;
-
- continue;
- }
-
- if (buffer->event && buffer->event->timer_set) {
- ngx_del_timer(buffer->event);
- }
- }
-
- alloc_line:
-
- line = ngx_pnalloc(r->pool, len);
- if (line == NULL) {
- return NGX_ERROR;
- }
-
- p = line;
-
- if (log[l].syslog_peer) {
- p = ngx_syslog_add_header(log[l].syslog_peer, line);
- }
-
- for (i = 0; i < log[l].format->ops->nelts; i++) {
- p = op[i].run(r, p, &op[i]);
- }
-
- if (log[l].syslog_peer) {
-
- size = p - line;
-
- n = ngx_syslog_send(log[l].syslog_peer, line, size);
-
- if (n < 0) {
- ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
- "send() to syslog failed");
-
- } else if ((size_t) n != size) {
- ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
- "send() to syslog has written only %z of %uz",
- n, size);
- }
-
- continue;
- }
-
- ngx_linefeed(p);
-
- ngx_http_log_write(r, &log[l], line, p - line);
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf,
- size_t len)
-{
- u_char *name;
- time_t now;
- ssize_t n;
- ngx_err_t err;
-#if (NGX_ZLIB)
- ngx_http_log_buf_t *buffer;
-#endif
-
- if (log->script == NULL) {
- name = log->file->name.data;
-
-#if (NGX_ZLIB)
- buffer = log->file->data;
-
- if (buffer && buffer->gzip) {
- n = ngx_http_log_gzip(log->file->fd, buf, len, buffer->gzip,
- r->connection->log);
- } else {
- n = ngx_write_fd(log->file->fd, buf, len);
- }
-#else
- n = ngx_write_fd(log->file->fd, buf, len);
-#endif
-
- } else {
- name = NULL;
- n = ngx_http_log_script_write(r, log->script, &name, buf, len);
- }
-
- if (n == (ssize_t) len) {
- return;
- }
-
- now = ngx_time();
-
- if (n == -1) {
- err = ngx_errno;
-
- if (err == NGX_ENOSPC) {
- log->disk_full_time = now;
- }
-
- if (now - log->error_log_time > 59) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, err,
- ngx_write_fd_n " to \"%s\" failed", name);
-
- log->error_log_time = now;
- }
-
- return;
- }
-
- if (now - log->error_log_time > 59) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
- name, n, len);
-
- log->error_log_time = now;
- }
-}
-
-
-static ssize_t
-ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script,
- u_char **name, u_char *buf, size_t len)
-{
- size_t root;
- ssize_t n;
- ngx_str_t log, path;
- ngx_open_file_info_t of;
- ngx_http_log_loc_conf_t *llcf;
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (!r->root_tested) {
-
- /* test root directory existence */
-
- if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) {
- /* simulate successful logging */
- return len;
- }
-
- path.data[root] = '\0';
-
- ngx_memzero(&of, sizeof(ngx_open_file_info_t));
-
- of.valid = clcf->open_file_cache_valid;
- of.min_uses = clcf->open_file_cache_min_uses;
- of.test_dir = 1;
- of.test_only = 1;
- of.errors = clcf->open_file_cache_errors;
- of.events = clcf->open_file_cache_events;
-
- if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
- /* simulate successful logging */
- return len;
- }
-
- if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
- != NGX_OK)
- {
- if (of.err == 0) {
- /* simulate successful logging */
- return len;
- }
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, of.err,
- "testing \"%s\" existence failed", path.data);
-
- /* simulate successful logging */
- return len;
- }
-
- if (!of.is_dir) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ENOTDIR,
- "testing \"%s\" existence failed", path.data);
-
- /* simulate successful logging */
- return len;
- }
- }
-
- if (ngx_http_script_run(r, &log, script->lengths->elts, 1,
- script->values->elts)
- == NULL)
- {
- /* simulate successful logging */
- return len;
- }
-
- log.data[log.len - 1] = '\0';
- *name = log.data;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http log \"%s\"", log.data);
-
- llcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
-
- ngx_memzero(&of, sizeof(ngx_open_file_info_t));
-
- of.log = 1;
- of.valid = llcf->open_file_cache_valid;
- of.min_uses = llcf->open_file_cache_min_uses;
- of.directio = NGX_OPEN_FILE_DIRECTIO_OFF;
-
- if (ngx_http_set_disable_symlinks(r, clcf, &log, &of) != NGX_OK) {
- /* simulate successful logging */
- return len;
- }
-
- if (ngx_open_cached_file(llcf->open_file_cache, &log, &of, r->pool)
- != NGX_OK)
- {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
- "%s \"%s\" failed", of.failed, log.data);
- /* simulate successful logging */
- return len;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http log #%d", of.fd);
-
- n = ngx_write_fd(of.fd, buf, len);
-
- return n;
-}
-
-
-#if (NGX_ZLIB)
-
-static ssize_t
-ngx_http_log_gzip(ngx_fd_t fd, u_char *buf, size_t len, ngx_int_t level,
- ngx_log_t *log)
-{
- int rc, wbits, memlevel;
- u_char *out;
- size_t size;
- ssize_t n;
- z_stream zstream;
- ngx_err_t err;
- ngx_pool_t *pool;
-
- wbits = MAX_WBITS;
- memlevel = MAX_MEM_LEVEL - 1;
-
- while ((ssize_t) len < ((1 << (wbits - 1)) - 262)) {
- wbits--;
- memlevel--;
- }
-
- /*
- * This is a formula from deflateBound() for conservative upper bound of
- * compressed data plus 18 bytes of gzip wrapper.
- */
-
- size = len + ((len + 7) >> 3) + ((len + 63) >> 6) + 5 + 18;
-
- ngx_memzero(&zstream, sizeof(z_stream));
-
- pool = ngx_create_pool(256, log);
- if (pool == NULL) {
- /* simulate successful logging */
- return len;
- }
-
- pool->log = log;
-
- zstream.zalloc = ngx_http_log_gzip_alloc;
- zstream.zfree = ngx_http_log_gzip_free;
- zstream.opaque = pool;
-
- out = ngx_pnalloc(pool, size);
- if (out == NULL) {
- goto done;
- }
-
- zstream.next_in = buf;
- zstream.avail_in = len;
- zstream.next_out = out;
- zstream.avail_out = size;
-
- rc = deflateInit2(&zstream, (int) level, Z_DEFLATED, wbits + 16, memlevel,
- Z_DEFAULT_STRATEGY);
-
- if (rc != Z_OK) {
- ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateInit2() failed: %d", rc);
- goto done;
- }
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, log, 0,
- "deflate in: ni:%p no:%p ai:%ud ao:%ud",
- zstream.next_in, zstream.next_out,
- zstream.avail_in, zstream.avail_out);
-
- rc = deflate(&zstream, Z_FINISH);
-
- if (rc != Z_STREAM_END) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- "deflate(Z_FINISH) failed: %d", rc);
- goto done;
- }
-
- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, log, 0,
- "deflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
- zstream.next_in, zstream.next_out,
- zstream.avail_in, zstream.avail_out,
- rc);
-
- size -= zstream.avail_out;
-
- rc = deflateEnd(&zstream);
-
- if (rc != Z_OK) {
- ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateEnd() failed: %d", rc);
- goto done;
- }
-
- n = ngx_write_fd(fd, out, size);
-
- if (n != (ssize_t) size) {
- err = (n == -1) ? ngx_errno : 0;
-
- ngx_destroy_pool(pool);
-
- ngx_set_errno(err);
- return -1;
- }
-
-done:
-
- ngx_destroy_pool(pool);
-
- /* simulate successful logging */
- return len;
-}
-
-
-static void *
-ngx_http_log_gzip_alloc(void *opaque, u_int items, u_int size)
-{
- ngx_pool_t *pool = opaque;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pool->log, 0,
- "gzip alloc: n:%ud s:%ud", items, size);
-
- return ngx_palloc(pool, items * size);
-}
-
-
-static void
-ngx_http_log_gzip_free(void *opaque, void *address)
-{
-#if 0
- ngx_pool_t *pool = opaque;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pool->log, 0, "gzip free: %p", address);
-#endif
-}
-
-#endif
-
-
-static void
-ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log)
-{
- size_t len;
- ssize_t n;
- ngx_http_log_buf_t *buffer;
-
- buffer = file->data;
-
- len = buffer->pos - buffer->start;
-
- if (len == 0) {
- return;
- }
-
-#if (NGX_ZLIB)
- if (buffer->gzip) {
- n = ngx_http_log_gzip(file->fd, buffer->start, len, buffer->gzip, log);
- } else {
- n = ngx_write_fd(file->fd, buffer->start, len);
- }
-#else
- n = ngx_write_fd(file->fd, buffer->start, len);
-#endif
-
- if (n == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_write_fd_n " to \"%s\" failed",
- file->name.data);
-
- } else if ((size_t) n != len) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz",
- file->name.data, n, len);
- }
-
- buffer->pos = buffer->start;
-
- if (buffer->event && buffer->event->timer_set) {
- ngx_del_timer(buffer->event);
- }
-}
-
-
-static void
-ngx_http_log_flush_handler(ngx_event_t *ev)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "http log buffer flush handler");
-
- ngx_http_log_flush(ev->data, ev->log);
-}
-
-
-static u_char *
-ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op)
-{
- size_t len;
- uintptr_t data;
-
- len = op->len;
- data = op->data;
-
- while (len--) {
- *buf++ = (u_char) (data & 0xff);
- data >>= 8;
- }
-
- return buf;
-}
-
-
-static u_char *
-ngx_http_log_copy_long(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op)
-{
- return ngx_cpymem(buf, (u_char *) op->data, op->len);
-}
-
-
-static u_char *
-ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
-{
- if (r->pipeline) {
- *buf = 'p';
- } else {
- *buf = '.';
- }
-
- return buf + 1;
-}
-
-
-static u_char *
-ngx_http_log_time(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
-{
- return ngx_cpymem(buf, ngx_cached_http_log_time.data,
- ngx_cached_http_log_time.len);
-}
-
-static u_char *
-ngx_http_log_iso8601(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
-{
- return ngx_cpymem(buf, ngx_cached_http_log_iso8601.data,
- ngx_cached_http_log_iso8601.len);
-}
-
-static u_char *
-ngx_http_log_msec(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
-{
- ngx_time_t *tp;
-
- tp = ngx_timeofday();
-
- return ngx_sprintf(buf, "%T.%03M", tp->sec, tp->msec);
-}
-
-
-static u_char *
-ngx_http_log_request_time(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op)
-{
- ngx_time_t *tp;
- ngx_msec_int_t ms;
-
- tp = ngx_timeofday();
-
- ms = (ngx_msec_int_t)
- ((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec));
- ms = ngx_max(ms, 0);
-
- return ngx_sprintf(buf, "%T.%03M", (time_t) ms / 1000, ms % 1000);
-}
-
-
-static u_char *
-ngx_http_log_status(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
-{
- ngx_uint_t status;
-
- if (r->err_status) {
- status = r->err_status;
-
- } else if (r->headers_out.status) {
- status = r->headers_out.status;
-
- } else if (r->http_version == NGX_HTTP_VERSION_9) {
- status = 9;
-
- } else {
- status = 0;
- }
-
- return ngx_sprintf(buf, "%03ui", status);
-}
-
-
-static u_char *
-ngx_http_log_bytes_sent(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op)
-{
- return ngx_sprintf(buf, "%O", r->connection->sent);
-}
-
-
-/*
- * 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)
-{
- off_t length;
-
- length = r->connection->sent - r->header_size;
-
- if (length > 0) {
- return ngx_sprintf(buf, "%O", length);
- }
-
- *buf = '0';
-
- return buf + 1;
-}
-
-
-static u_char *
-ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf,
- ngx_http_log_op_t *op)
-{
- return ngx_sprintf(buf, "%O", r->request_length);
-}
-
-
-static ngx_int_t
-ngx_http_log_variable_compile(ngx_conf_t *cf, ngx_http_log_op_t *op,
- ngx_str_t *value)
-{
- ngx_int_t index;
-
- index = ngx_http_get_variable_index(cf, value);
- if (index == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- op->len = 0;
- op->getlen = ngx_http_log_variable_getlen;
- op->run = ngx_http_log_variable;
- op->data = index;
-
- return NGX_OK;
-}
-
-
-static size_t
-ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data)
-{
- uintptr_t len;
- ngx_http_variable_value_t *value;
-
- value = ngx_http_get_indexed_variable(r, data);
-
- if (value == NULL || value->not_found) {
- return 1;
- }
-
- len = ngx_http_log_escape(NULL, value->data, value->len);
-
- value->escape = len ? 1 : 0;
-
- return value->len + len * 3;
-}
-
-
-static u_char *
-ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
-{
- ngx_http_variable_value_t *value;
-
- value = ngx_http_get_indexed_variable(r, op->data);
-
- if (value == NULL || value->not_found) {
- *buf = '-';
- return buf + 1;
- }
-
- if (value->escape == 0) {
- return ngx_cpymem(buf, value->data, value->len);
-
- } else {
- return (u_char *) ngx_http_log_escape(buf, value->data, value->len);
- }
-}
-
-
-static uintptr_t
-ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
-{
- ngx_uint_t n;
- static u_char hex[] = "0123456789ABCDEF";
-
- static uint32_t escape[] = {
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
-
- /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
- 0x00000004, /* 0000 0000 0000 0000 0000 0000 0000 0100 */
-
- /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
- 0x10000000, /* 0001 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 */
- };
-
-
- if (dst == NULL) {
-
- /* find the number of the characters to be escaped */
-
- n = 0;
-
- while (size) {
- if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
- n++;
- }
- src++;
- size--;
- }
-
- return (uintptr_t) n;
- }
-
- while (size) {
- if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
- *dst++ = '\\';
- *dst++ = 'x';
- *dst++ = hex[*src >> 4];
- *dst++ = hex[*src & 0xf];
- src++;
-
- } else {
- *dst++ = *src++;
- }
- size--;
- }
-
- return (uintptr_t) dst;
-}
-
-
-static void *
-ngx_http_log_create_main_conf(ngx_conf_t *cf)
-{
- ngx_http_log_main_conf_t *conf;
-
- ngx_http_log_fmt_t *fmt;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_main_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- if (ngx_array_init(&conf->formats, cf->pool, 4, sizeof(ngx_http_log_fmt_t))
- != NGX_OK)
- {
- return NULL;
- }
-
- fmt = ngx_array_push(&conf->formats);
- if (fmt == NULL) {
- return NULL;
- }
-
- ngx_str_set(&fmt->name, "combined");
-
- fmt->flushes = NULL;
-
- fmt->ops = ngx_array_create(cf->pool, 16, sizeof(ngx_http_log_op_t));
- if (fmt->ops == NULL) {
- return NULL;
- }
-
- return conf;
-}
-
-
-static void *
-ngx_http_log_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_log_loc_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- conf->open_file_cache = NGX_CONF_UNSET_PTR;
-
- return conf;
-}
-
-
-static char *
-ngx_http_log_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_log_loc_conf_t *prev = parent;
- ngx_http_log_loc_conf_t *conf = child;
-
- ngx_http_log_t *log;
- ngx_http_log_fmt_t *fmt;
- ngx_http_log_main_conf_t *lmcf;
-
- if (conf->open_file_cache == NGX_CONF_UNSET_PTR) {
-
- conf->open_file_cache = prev->open_file_cache;
- conf->open_file_cache_valid = prev->open_file_cache_valid;
- conf->open_file_cache_min_uses = prev->open_file_cache_min_uses;
-
- if (conf->open_file_cache == NGX_CONF_UNSET_PTR) {
- conf->open_file_cache = NULL;
- }
- }
-
- if (conf->logs || conf->off) {
- return NGX_CONF_OK;
- }
-
- conf->logs = prev->logs;
- conf->off = prev->off;
-
- if (conf->logs || conf->off) {
- return NGX_CONF_OK;
- }
-
- conf->logs = ngx_array_create(cf->pool, 2, sizeof(ngx_http_log_t));
- if (conf->logs == NULL) {
- return NGX_CONF_ERROR;
- }
-
- log = ngx_array_push(conf->logs);
- if (log == NULL) {
- return NGX_CONF_ERROR;
- }
-
- log->file = ngx_conf_open_file(cf->cycle, &ngx_http_access_log);
- if (log->file == NULL) {
- return NGX_CONF_ERROR;
- }
-
- log->script = NULL;
- log->disk_full_time = 0;
- log->error_log_time = 0;
- log->syslog_peer = NULL;
-
- lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module);
- fmt = lmcf->formats.elts;
-
- /* the default "combined" format */
- log->format = &fmt[0];
- lmcf->combined_used = 1;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_log_loc_conf_t *llcf = conf;
-
- ssize_t size;
- ngx_int_t gzip;
- ngx_uint_t i, n;
- ngx_msec_t flush;
- ngx_str_t *value, name, s;
- ngx_http_log_t *log;
- ngx_syslog_peer_t *peer;
- ngx_http_log_buf_t *buffer;
- ngx_http_log_fmt_t *fmt;
- ngx_http_log_main_conf_t *lmcf;
- ngx_http_script_compile_t sc;
-
- value = cf->args->elts;
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- llcf->off = 1;
- if (cf->args->nelts == 2) {
- return NGX_CONF_OK;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[2]);
- return NGX_CONF_ERROR;
- }
-
- if (llcf->logs == NULL) {
- llcf->logs = ngx_array_create(cf->pool, 2, sizeof(ngx_http_log_t));
- if (llcf->logs == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module);
-
- log = ngx_array_push(llcf->logs);
- if (log == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(log, sizeof(ngx_http_log_t));
-
-
- if (ngx_strncmp(value[1].data, "syslog:", 7) == 0) {
-
- peer = ngx_pcalloc(cf->pool, sizeof(ngx_syslog_peer_t));
- if (peer == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (ngx_syslog_process_conf(cf, peer) != NGX_CONF_OK) {
- return NGX_CONF_ERROR;
- }
-
- log->syslog_peer = peer;
-
- goto process_formats;
- }
-
- n = ngx_http_script_variables_count(&value[1]);
-
- if (n == 0) {
- log->file = ngx_conf_open_file(cf->cycle, &value[1]);
- if (log->file == NULL) {
- return NGX_CONF_ERROR;
- }
-
- } else {
- if (ngx_conf_full_name(cf->cycle, &value[1], 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- log->script = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_script_t));
- if (log->script == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = &value[1];
- sc.lengths = &log->script->lengths;
- sc.values = &log->script->values;
- sc.variables = n;
- sc.complete_lengths = 1;
- sc.complete_values = 1;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
-process_formats:
-
- if (cf->args->nelts >= 3) {
- name = value[2];
-
- if (ngx_strcmp(name.data, "combined") == 0) {
- lmcf->combined_used = 1;
- }
-
- } else {
- ngx_str_set(&name, "combined");
- lmcf->combined_used = 1;
- }
-
- fmt = lmcf->formats.elts;
- for (i = 0; i < lmcf->formats.nelts; i++) {
- if (fmt[i].name.len == name.len
- && ngx_strcasecmp(fmt[i].name.data, name.data) == 0)
- {
- log->format = &fmt[i];
- break;
- }
- }
-
- if (log->format == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unknown log format \"%V\"", &name);
- return NGX_CONF_ERROR;
- }
-
- if (log->syslog_peer != NULL) {
- if (cf->args->nelts > 3) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "parameter \"%V\" is not supported by syslog",
- &value[3]);
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
- }
-
- size = 0;
- flush = 0;
- gzip = 0;
-
- for (i = 3; i < cf->args->nelts; i++) {
-
- if (ngx_strncmp(value[i].data, "buffer=", 7) == 0) {
- s.len = value[i].len - 7;
- s.data = value[i].data + 7;
-
- size = ngx_parse_size(&s);
-
- if (size == NGX_ERROR || size == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid buffer size \"%V\"", &s);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "flush=", 6) == 0) {
- s.len = value[i].len - 6;
- s.data = value[i].data + 6;
-
- flush = ngx_parse_time(&s, 0);
-
- if (flush == (ngx_msec_t) NGX_ERROR || flush == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid flush time \"%V\"", &s);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "gzip", 4) == 0
- && (value[i].len == 4 || value[i].data[4] == '='))
- {
-#if (NGX_ZLIB)
- if (size == 0) {
- size = 64 * 1024;
- }
-
- if (value[i].len == 4) {
- gzip = Z_BEST_SPEED;
- continue;
- }
-
- s.len = value[i].len - 5;
- s.data = value[i].data + 5;
-
- gzip = ngx_atoi(s.data, s.len);
-
- if (gzip < 1 || gzip > 9) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid compression level \"%V\"", &s);
- return NGX_CONF_ERROR;
- }
-
- continue;
-
-#else
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "nginx was built without zlib support");
- return NGX_CONF_ERROR;
-#endif
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (flush && size == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "no buffer is defined for access_log \"%V\"",
- &value[1]);
- return NGX_CONF_ERROR;
- }
-
- if (size) {
-
- if (log->script) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "buffered logs cannot have variables in name");
- return NGX_CONF_ERROR;
- }
-
- if (log->file->data) {
- buffer = log->file->data;
-
- if (buffer->last - buffer->start != size
- || buffer->flush != flush
- || buffer->gzip != gzip)
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "access_log \"%V\" already defined "
- "with conflicting parameters",
- &value[1]);
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
- }
-
- buffer = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_buf_t));
- if (buffer == NULL) {
- return NGX_CONF_ERROR;
- }
-
- buffer->start = ngx_pnalloc(cf->pool, size);
- if (buffer->start == NULL) {
- return NGX_CONF_ERROR;
- }
-
- buffer->pos = buffer->start;
- buffer->last = buffer->start + size;
-
- if (flush) {
- buffer->event = ngx_pcalloc(cf->pool, sizeof(ngx_event_t));
- if (buffer->event == NULL) {
- return NGX_CONF_ERROR;
- }
-
- buffer->event->data = log->file;
- buffer->event->handler = ngx_http_log_flush_handler;
- buffer->event->log = &cf->cycle->new_log;
-
- buffer->flush = flush;
- }
-
- buffer->gzip = gzip;
-
- log->file->flush = ngx_http_log_flush;
- log->file->data = buffer;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_log_main_conf_t *lmcf = conf;
-
- ngx_str_t *value;
- ngx_uint_t i;
- ngx_http_log_fmt_t *fmt;
-
- if (cf->cmd_type != NGX_HTTP_MAIN_CONF) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "the \"log_format\" directive may be used "
- "only on \"http\" level");
- }
-
- value = cf->args->elts;
-
- fmt = lmcf->formats.elts;
- for (i = 0; i < lmcf->formats.nelts; i++) {
- if (fmt[i].name.len == value[1].len
- && ngx_strcmp(fmt[i].name.data, value[1].data) == 0)
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate \"log_format\" name \"%V\"",
- &value[1]);
- return NGX_CONF_ERROR;
- }
- }
-
- fmt = ngx_array_push(&lmcf->formats);
- if (fmt == NULL) {
- return NGX_CONF_ERROR;
- }
-
- fmt->name = value[1];
-
- fmt->flushes = ngx_array_create(cf->pool, 4, sizeof(ngx_int_t));
- if (fmt->flushes == NULL) {
- return NGX_CONF_ERROR;
- }
-
- fmt->ops = ngx_array_create(cf->pool, 16, sizeof(ngx_http_log_op_t));
- if (fmt->ops == NULL) {
- return NGX_CONF_ERROR;
- }
-
- return ngx_http_log_compile_format(cf, fmt->flushes, fmt->ops, cf->args, 2);
-}
-
-
-static char *
-ngx_http_log_compile_format(ngx_conf_t *cf, ngx_array_t *flushes,
- ngx_array_t *ops, ngx_array_t *args, ngx_uint_t s)
-{
- u_char *data, *p, ch;
- size_t i, len;
- ngx_str_t *value, var;
- ngx_int_t *flush;
- ngx_uint_t bracket;
- ngx_http_log_op_t *op;
- ngx_http_log_var_t *v;
-
- value = args->elts;
-
- for ( /* void */ ; s < args->nelts; s++) {
-
- i = 0;
-
- while (i < value[s].len) {
-
- op = ngx_array_push(ops);
- if (op == NULL) {
- return NGX_CONF_ERROR;
- }
-
- data = &value[s].data[i];
-
- if (value[s].data[i] == '$') {
-
- if (++i == value[s].len) {
- goto invalid;
- }
-
- if (value[s].data[i] == '{') {
- bracket = 1;
-
- if (++i == value[s].len) {
- goto invalid;
- }
-
- var.data = &value[s].data[i];
-
- } else {
- bracket = 0;
- var.data = &value[s].data[i];
- }
-
- for (var.len = 0; i < value[s].len; i++, var.len++) {
- ch = value[s].data[i];
-
- if (ch == '}' && bracket) {
- i++;
- bracket = 0;
- break;
- }
-
- if ((ch >= 'A' && ch <= 'Z')
- || (ch >= 'a' && ch <= 'z')
- || (ch >= '0' && ch <= '9')
- || ch == '_')
- {
- continue;
- }
-
- break;
- }
-
- if (bracket) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the closing bracket in \"%V\" "
- "variable is missing", &var);
- return NGX_CONF_ERROR;
- }
-
- if (var.len == 0) {
- goto invalid;
- }
-
- for (v = ngx_http_log_vars; v->name.len; v++) {
-
- if (v->name.len == var.len
- && ngx_strncmp(v->name.data, var.data, var.len) == 0)
- {
- op->len = v->len;
- op->getlen = NULL;
- op->run = v->run;
- op->data = 0;
-
- goto found;
- }
- }
-
- if (ngx_http_log_variable_compile(cf, op, &var) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (flushes) {
-
- flush = ngx_array_push(flushes);
- if (flush == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *flush = op->data; /* variable index */
- }
-
- found:
-
- continue;
- }
-
- i++;
-
- while (i < value[s].len && value[s].data[i] != '$') {
- i++;
- }
-
- len = &value[s].data[i] - data;
-
- if (len) {
-
- op->len = len;
- op->getlen = NULL;
-
- if (len <= sizeof(uintptr_t)) {
- op->run = ngx_http_log_copy_short;
- op->data = 0;
-
- while (len--) {
- op->data <<= 8;
- op->data |= data[len];
- }
-
- } else {
- op->run = ngx_http_log_copy_long;
-
- p = ngx_pnalloc(cf->pool, len);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memcpy(p, data, len);
- op->data = (uintptr_t) p;
- }
- }
- }
- }
-
- return NGX_CONF_OK;
-
-invalid:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%s\"", data);
-
- return NGX_CONF_ERROR;
-}
-
-
-static char *
-ngx_http_log_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_log_loc_conf_t *llcf = conf;
-
- time_t inactive, valid;
- ngx_str_t *value, s;
- ngx_int_t max, min_uses;
- ngx_uint_t i;
-
- if (llcf->open_file_cache != NGX_CONF_UNSET_PTR) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- max = 0;
- inactive = 10;
- valid = 60;
- min_uses = 1;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (ngx_strncmp(value[i].data, "max=", 4) == 0) {
-
- max = ngx_atoi(value[i].data + 4, value[i].len - 4);
- if (max == NGX_ERROR) {
- goto failed;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
-
- s.len = value[i].len - 9;
- s.data = value[i].data + 9;
-
- inactive = ngx_parse_time(&s, 1);
- if (inactive == (time_t) NGX_ERROR) {
- goto failed;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "min_uses=", 9) == 0) {
-
- min_uses = ngx_atoi(value[i].data + 9, value[i].len - 9);
- if (min_uses == NGX_ERROR) {
- goto failed;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "valid=", 6) == 0) {
-
- s.len = value[i].len - 6;
- s.data = value[i].data + 6;
-
- valid = ngx_parse_time(&s, 1);
- if (valid == (time_t) NGX_ERROR) {
- goto failed;
- }
-
- continue;
- }
-
- if (ngx_strcmp(value[i].data, "off") == 0) {
-
- llcf->open_file_cache = NULL;
-
- continue;
- }
-
- failed:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid \"open_log_file_cache\" parameter \"%V\"",
- &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (llcf->open_file_cache == NULL) {
- return NGX_CONF_OK;
- }
-
- if (max == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"open_log_file_cache\" must have \"max\" parameter");
- return NGX_CONF_ERROR;
- }
-
- llcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
-
- if (llcf->open_file_cache) {
-
- llcf->open_file_cache_valid = valid;
- llcf->open_file_cache_min_uses = min_uses;
-
- return NGX_CONF_OK;
- }
-
- return NGX_CONF_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_log_init(ngx_conf_t *cf)
-{
- ngx_str_t *value;
- ngx_array_t a;
- ngx_http_handler_pt *h;
- ngx_http_log_fmt_t *fmt;
- ngx_http_log_main_conf_t *lmcf;
- ngx_http_core_main_conf_t *cmcf;
-
- lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_module);
-
- if (lmcf->combined_used) {
- if (ngx_array_init(&a, cf->pool, 1, sizeof(ngx_str_t)) != NGX_OK) {
- return NGX_ERROR;
- }
-
- value = ngx_array_push(&a);
- if (value == NULL) {
- return NGX_ERROR;
- }
-
- *value = ngx_http_combined_fmt;
- fmt = lmcf->formats.elts;
-
- if (ngx_http_log_compile_format(cf, NULL, fmt->ops, &a, 0)
- != NGX_CONF_OK)
- {
- return NGX_ERROR;
- }
- }
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_log_handler;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_map_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_map_module.c
deleted file mode 100644
index 3245e04132c..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_map_module.c
+++ /dev/null
@@ -1,567 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_uint_t hash_max_size;
- ngx_uint_t hash_bucket_size;
-} ngx_http_map_conf_t;
-
-
-typedef struct {
- ngx_hash_keys_arrays_t keys;
-
- ngx_array_t *values_hash;
- ngx_array_t var_values;
-#if (NGX_PCRE)
- ngx_array_t regexes;
-#endif
-
- ngx_http_variable_value_t *default_value;
- ngx_conf_t *cf;
- ngx_uint_t hostnames; /* unsigned hostnames:1 */
-} ngx_http_map_conf_ctx_t;
-
-
-typedef struct {
- ngx_http_map_t map;
- ngx_http_complex_value_t value;
- ngx_http_variable_value_t *default_value;
- ngx_uint_t hostnames; /* unsigned hostnames:1 */
-} ngx_http_map_ctx_t;
-
-
-static int ngx_libc_cdecl ngx_http_map_cmp_dns_wildcards(const void *one,
- const void *two);
-static void *ngx_http_map_create_conf(ngx_conf_t *cf);
-static char *ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static char *ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf);
-
-
-static ngx_command_t ngx_http_map_commands[] = {
-
- { ngx_string("map"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2,
- ngx_http_map_block,
- NGX_HTTP_MAIN_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("map_hash_max_size"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_MAIN_CONF_OFFSET,
- offsetof(ngx_http_map_conf_t, hash_max_size),
- NULL },
-
- { ngx_string("map_hash_bucket_size"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_MAIN_CONF_OFFSET,
- offsetof(ngx_http_map_conf_t, hash_bucket_size),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_map_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- ngx_http_map_create_conf, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_map_module = {
- NGX_MODULE_V1,
- &ngx_http_map_module_ctx, /* module context */
- ngx_http_map_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_map_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- ngx_http_map_ctx_t *map = (ngx_http_map_ctx_t *) data;
-
- ngx_str_t val;
- ngx_http_variable_value_t *value;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http map started");
-
- if (ngx_http_complex_value(r, &map->value, &val) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (map->hostnames && val.len > 0 && val.data[val.len - 1] == '.') {
- val.len--;
- }
-
- value = ngx_http_map_find(r, &map->map, &val);
-
- if (value == NULL) {
- value = map->default_value;
- }
-
- if (!value->valid) {
- value = ngx_http_get_flushed_variable(r, (uintptr_t) value->data);
-
- if (value == NULL || value->not_found) {
- value = &ngx_http_variable_null_value;
- }
- }
-
- *v = *value;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http map: \"%v\" \"%v\"", &val, v);
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_map_create_conf(ngx_conf_t *cf)
-{
- ngx_http_map_conf_t *mcf;
-
- mcf = ngx_palloc(cf->pool, sizeof(ngx_http_map_conf_t));
- if (mcf == NULL) {
- return NULL;
- }
-
- mcf->hash_max_size = NGX_CONF_UNSET_UINT;
- mcf->hash_bucket_size = NGX_CONF_UNSET_UINT;
-
- return mcf;
-}
-
-
-static char *
-ngx_http_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_map_conf_t *mcf = conf;
-
- char *rv;
- ngx_str_t *value, name;
- ngx_conf_t save;
- ngx_pool_t *pool;
- ngx_hash_init_t hash;
- ngx_http_map_ctx_t *map;
- ngx_http_variable_t *var;
- ngx_http_map_conf_ctx_t ctx;
- ngx_http_compile_complex_value_t ccv;
-
- if (mcf->hash_max_size == NGX_CONF_UNSET_UINT) {
- mcf->hash_max_size = 2048;
- }
-
- if (mcf->hash_bucket_size == NGX_CONF_UNSET_UINT) {
- mcf->hash_bucket_size = ngx_cacheline_size;
-
- } else {
- mcf->hash_bucket_size = ngx_align(mcf->hash_bucket_size,
- ngx_cacheline_size);
- }
-
- map = ngx_pcalloc(cf->pool, sizeof(ngx_http_map_ctx_t));
- if (map == NULL) {
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &map->value;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- name = value[2];
-
- if (name.data[0] != '$') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid variable name \"%V\"", &name);
- return NGX_CONF_ERROR;
- }
-
- name.len--;
- name.data++;
-
- var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
- if (var == NULL) {
- return NGX_CONF_ERROR;
- }
-
- var->get_handler = ngx_http_map_variable;
- var->data = (uintptr_t) map;
-
- pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
- if (pool == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx.keys.pool = cf->pool;
- ctx.keys.temp_pool = pool;
-
- if (ngx_hash_keys_array_init(&ctx.keys, NGX_HASH_LARGE) != NGX_OK) {
- ngx_destroy_pool(pool);
- return NGX_CONF_ERROR;
- }
-
- ctx.values_hash = ngx_pcalloc(pool, sizeof(ngx_array_t) * ctx.keys.hsize);
- if (ctx.values_hash == NULL) {
- ngx_destroy_pool(pool);
- return NGX_CONF_ERROR;
- }
-
- if (ngx_array_init(&ctx.var_values, cf->pool, 2,
- sizeof(ngx_http_variable_value_t))
- != NGX_OK)
- {
- ngx_destroy_pool(pool);
- return NGX_CONF_ERROR;
- }
-
-#if (NGX_PCRE)
- if (ngx_array_init(&ctx.regexes, cf->pool, 2, sizeof(ngx_http_map_regex_t))
- != NGX_OK)
- {
- ngx_destroy_pool(pool);
- return NGX_CONF_ERROR;
- }
-#endif
-
- ctx.default_value = NULL;
- ctx.cf = &save;
- ctx.hostnames = 0;
-
- save = *cf;
- cf->pool = pool;
- cf->ctx = &ctx;
- cf->handler = ngx_http_map;
- cf->handler_conf = conf;
-
- rv = ngx_conf_parse(cf, NULL);
-
- *cf = save;
-
- if (rv != NGX_CONF_OK) {
- ngx_destroy_pool(pool);
- return rv;
- }
-
- map->default_value = ctx.default_value ? ctx.default_value:
- &ngx_http_variable_null_value;
-
- map->hostnames = ctx.hostnames;
-
- hash.key = ngx_hash_key_lc;
- hash.max_size = mcf->hash_max_size;
- hash.bucket_size = mcf->hash_bucket_size;
- hash.name = "map_hash";
- hash.pool = cf->pool;
-
- if (ctx.keys.keys.nelts) {
- hash.hash = &map->map.hash.hash;
- hash.temp_pool = NULL;
-
- if (ngx_hash_init(&hash, ctx.keys.keys.elts, ctx.keys.keys.nelts)
- != NGX_OK)
- {
- ngx_destroy_pool(pool);
- return NGX_CONF_ERROR;
- }
- }
-
- if (ctx.keys.dns_wc_head.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_wc_head.elts,
- ctx.keys.dns_wc_head.nelts)
- != NGX_OK)
- {
- ngx_destroy_pool(pool);
- return NGX_CONF_ERROR;
- }
-
- map->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->map.hash.wc_tail = (ngx_hash_wildcard_t *) hash.hash;
- }
-
-#if (NGX_PCRE)
-
- if (ctx.regexes.nelts) {
- map->map.regex = ctx.regexes.elts;
- map->map.nregex = ctx.regexes.nelts;
- }
-
-#endif
-
- ngx_destroy_pool(pool);
-
- return rv;
-}
-
-
-static int ngx_libc_cdecl
-ngx_http_map_cmp_dns_wildcards(const void *one, const void *two)
-{
- ngx_hash_key_t *first, *second;
-
- first = (ngx_hash_key_t *) one;
- second = (ngx_hash_key_t *) two;
-
- return ngx_dns_strcmp(first->key.data, second->key.data);
-}
-
-
-static char *
-ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
-{
- ngx_int_t rc, index;
- ngx_str_t *value, name;
- ngx_uint_t i, key;
- ngx_http_map_conf_ctx_t *ctx;
- ngx_http_variable_value_t *var, **vp;
-
- ctx = cf->ctx;
-
- value = cf->args->elts;
-
- if (cf->args->nelts == 1
- && ngx_strcmp(value[0].data, "hostnames") == 0)
- {
- ctx->hostnames = 1;
- return NGX_CONF_OK;
-
- } else if (cf->args->nelts != 2) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid number of the map parameters");
- return NGX_CONF_ERROR;
- }
-
- if (ngx_strcmp(value[0].data, "include") == 0) {
- return ngx_conf_include(cf, dummy, conf);
- }
-
- if (value[1].data[0] == '$') {
- name = value[1];
- name.len--;
- name.data++;
-
- index = ngx_http_get_variable_index(ctx->cf, &name);
- if (index == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- var = ctx->var_values.elts;
-
- for (i = 0; i < ctx->var_values.nelts; i++) {
- if (index == (intptr_t) var[i].data) {
- var = &var[i];
- goto found;
- }
- }
-
- var = ngx_array_push(&ctx->var_values);
- if (var == NULL) {
- return NGX_CONF_ERROR;
- }
-
- var->valid = 0;
- var->no_cacheable = 0;
- var->not_found = 0;
- var->len = 0;
- var->data = (u_char *) (intptr_t) index;
-
- goto found;
- }
-
- key = 0;
-
- for (i = 0; i < value[1].len; i++) {
- key = ngx_hash(key, value[1].data[i]);
- }
-
- key %= ctx->keys.hsize;
-
- vp = ctx->values_hash[key].elts;
-
- if (vp) {
- for (i = 0; i < ctx->values_hash[key].nelts; i++) {
- if (value[1].len != (size_t) vp[i]->len) {
- continue;
- }
-
- if (ngx_strncmp(value[1].data, vp[i]->data, value[1].len) == 0) {
- var = vp[i];
- goto found;
- }
- }
-
- } else {
- if (ngx_array_init(&ctx->values_hash[key], cf->pool, 4,
- sizeof(ngx_http_variable_value_t *))
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
- }
-
- var = ngx_palloc(ctx->keys.pool, sizeof(ngx_http_variable_value_t));
- if (var == NULL) {
- return NGX_CONF_ERROR;
- }
-
- var->len = value[1].len;
- var->data = ngx_pstrdup(ctx->keys.pool, &value[1]);
- if (var->data == NULL) {
- return NGX_CONF_ERROR;
- }
-
- var->valid = 1;
- var->no_cacheable = 0;
- var->not_found = 0;
-
- vp = ngx_array_push(&ctx->values_hash[key]);
- if (vp == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *vp = var;
-
-found:
-
- 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 (NGX_PCRE)
-
- if (value[0].len && value[0].data[0] == '~') {
- ngx_regex_compile_t rc;
- ngx_http_map_regex_t *regex;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
-
- regex = ngx_array_push(&ctx->regexes);
- if (regex == NULL) {
- return NGX_CONF_ERROR;
- }
-
- value[0].len--;
- value[0].data++;
-
- ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
-
- if (value[0].data[0] == '*') {
- value[0].len--;
- value[0].data++;
- rc.options = NGX_REGEX_CASELESS;
- }
-
- rc.pattern = value[0];
- rc.err.len = NGX_MAX_CONF_ERRSTR;
- rc.err.data = errstr;
-
- regex->regex = ngx_http_regex_compile(ctx->cf, &rc);
- if (regex->regex == NULL) {
- return NGX_CONF_ERROR;
- }
-
- regex->value = var;
-
- return NGX_CONF_OK;
- }
-
-#endif
-
- 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]);
- }
-
- return NGX_CONF_ERROR;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_memcached_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_memcached_module.c
deleted file mode 100644
index aaa047e8fb7..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_memcached_module.c
+++ /dev/null
@@ -1,703 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_http_upstream_conf_t upstream;
- ngx_int_t index;
- ngx_uint_t gzip_flag;
-} ngx_http_memcached_loc_conf_t;
-
-
-typedef struct {
- size_t rest;
- ngx_http_request_t *request;
- ngx_str_t key;
-} ngx_http_memcached_ctx_t;
-
-
-static ngx_int_t ngx_http_memcached_create_request(ngx_http_request_t *r);
-static ngx_int_t ngx_http_memcached_reinit_request(ngx_http_request_t *r);
-static ngx_int_t ngx_http_memcached_process_header(ngx_http_request_t *r);
-static ngx_int_t ngx_http_memcached_filter_init(void *data);
-static ngx_int_t ngx_http_memcached_filter(void *data, ssize_t bytes);
-static void ngx_http_memcached_abort_request(ngx_http_request_t *r);
-static void ngx_http_memcached_finalize_request(ngx_http_request_t *r,
- ngx_int_t rc);
-
-static void *ngx_http_memcached_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
-
-static char *ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_conf_bitmask_t ngx_http_memcached_next_upstream_masks[] = {
- { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
- { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
- { ngx_string("invalid_response"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
- { ngx_string("not_found"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
- { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_command_t ngx_http_memcached_commands[] = {
-
- { ngx_string("memcached_pass"),
- NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
- ngx_http_memcached_pass,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("memcached_bind"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_upstream_bind_set_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_memcached_loc_conf_t, upstream.local),
- NULL },
-
- { ngx_string("memcached_connect_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_memcached_loc_conf_t, upstream.connect_timeout),
- NULL },
-
- { ngx_string("memcached_send_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_memcached_loc_conf_t, upstream.send_timeout),
- NULL },
-
- { ngx_string("memcached_buffer_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_memcached_loc_conf_t, upstream.buffer_size),
- NULL },
-
- { ngx_string("memcached_read_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_memcached_loc_conf_t, upstream.read_timeout),
- NULL },
-
- { ngx_string("memcached_next_upstream"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_memcached_loc_conf_t, upstream.next_upstream),
- &ngx_http_memcached_next_upstream_masks },
-
- { ngx_string("memcached_gzip_flag"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_memcached_loc_conf_t, gzip_flag),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_memcached_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_memcached_create_loc_conf, /* create location configuration */
- ngx_http_memcached_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_memcached_module = {
- NGX_MODULE_V1,
- &ngx_http_memcached_module_ctx, /* module context */
- ngx_http_memcached_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_str_t ngx_http_memcached_key = ngx_string("memcached_key");
-
-
-#define NGX_HTTP_MEMCACHED_END (sizeof(ngx_http_memcached_end) - 1)
-static u_char ngx_http_memcached_end[] = CRLF "END" CRLF;
-
-
-static ngx_int_t
-ngx_http_memcached_handler(ngx_http_request_t *r)
-{
- ngx_int_t rc;
- ngx_http_upstream_t *u;
- ngx_http_memcached_ctx_t *ctx;
- ngx_http_memcached_loc_conf_t *mlcf;
-
- if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
- return NGX_HTTP_NOT_ALLOWED;
- }
-
- rc = ngx_http_discard_request_body(r);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- if (ngx_http_set_content_type(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_http_upstream_create(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- u = r->upstream;
-
- ngx_str_set(&u->schema, "memcached://");
- u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module;
-
- mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
-
- u->conf = &mlcf->upstream;
-
- u->create_request = ngx_http_memcached_create_request;
- u->reinit_request = ngx_http_memcached_reinit_request;
- u->process_header = ngx_http_memcached_process_header;
- u->abort_request = ngx_http_memcached_abort_request;
- u->finalize_request = ngx_http_memcached_finalize_request;
-
- ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t));
- if (ctx == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ctx->request = r;
-
- ngx_http_set_ctx(r, ctx, ngx_http_memcached_module);
-
- u->input_filter_init = ngx_http_memcached_filter_init;
- u->input_filter = ngx_http_memcached_filter;
- u->input_filter_ctx = ctx;
-
- r->main->count++;
-
- ngx_http_upstream_init(r);
-
- return NGX_DONE;
-}
-
-
-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;
- ngx_http_variable_value_t *vv;
- ngx_http_memcached_loc_conf_t *mlcf;
-
- mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
-
- vv = ngx_http_get_indexed_variable(r, mlcf->index);
-
- if (vv == NULL || vv->not_found || vv->len == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "the \"$memcached_key\" variable is not set");
- return NGX_ERROR;
- }
-
- 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) {
- return NGX_ERROR;
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- cl->next = NULL;
-
- r->upstream->request_bufs = cl;
-
- *b->last++ = 'g'; *b->last++ = 'e'; *b->last++ = 't'; *b->last++ = ' ';
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_memcached_module);
-
- ctx->key.data = b->last;
-
- 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;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http memcached request: \"%V\"", &ctx->key);
-
- *b->last++ = CR; *b->last++ = LF;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_memcached_reinit_request(ngx_http_request_t *r)
-{
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_memcached_process_header(ngx_http_request_t *r)
-{
- u_char *p, *start;
- ngx_str_t line;
- ngx_uint_t flags;
- ngx_table_elt_t *h;
- ngx_http_upstream_t *u;
- ngx_http_memcached_ctx_t *ctx;
- ngx_http_memcached_loc_conf_t *mlcf;
-
- u = r->upstream;
-
- for (p = u->buffer.pos; p < u->buffer.last; p++) {
- if (*p == LF) {
- goto found;
- }
- }
-
- return NGX_AGAIN;
-
-found:
-
- line.data = u->buffer.pos;
- line.len = p - u->buffer.pos;
-
- if (line.len == 0 || *(p - 1) != CR) {
- goto no_valid;
- }
-
- *p = '\0';
- line.len--;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "memcached: \"%V\"", &line);
-
- p = u->buffer.pos;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_memcached_module);
- mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
-
- if (ngx_strncmp(p, "VALUE ", sizeof("VALUE ") - 1) == 0) {
-
- p += sizeof("VALUE ") - 1;
-
- if (ngx_strncmp(p, ctx->key.data, ctx->key.len) != 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "memcached sent invalid key in response \"%V\" "
- "for key \"%V\"",
- &line, &ctx->key);
-
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
- }
-
- p += ctx->key.len;
-
- if (*p++ != ' ') {
- goto no_valid;
- }
-
- /* flags */
-
- start = p;
-
- while (*p) {
- if (*p++ == ' ') {
- if (mlcf->gzip_flag) {
- goto flags;
- } else {
- goto length;
- }
- }
- }
-
- goto no_valid;
-
- flags:
-
- flags = ngx_atoi(start, p - start - 1);
-
- if (flags == (ngx_uint_t) NGX_ERROR) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "memcached sent invalid flags in response \"%V\" "
- "for key \"%V\"",
- &line, &ctx->key);
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
- }
-
- if (flags & mlcf->gzip_flag) {
- h = ngx_list_push(&r->headers_out.headers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- h->hash = 1;
- h->key.len = sizeof("Content-Encoding") - 1;
- h->key.data = (u_char *) "Content-Encoding";
- h->value.len = sizeof("gzip") - 1;
- h->value.data = (u_char *) "gzip";
-
- r->headers_out.content_encoding = h;
- }
-
- length:
-
- start = p;
- p = line.data + line.len;
-
- u->headers_in.content_length_n = ngx_atoof(start, p - start);
- if (u->headers_in.content_length_n == -1) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "memcached sent invalid length in response \"%V\" "
- "for key \"%V\"",
- &line, &ctx->key);
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
- }
-
- u->headers_in.status_n = 200;
- u->state->status = 200;
- u->buffer.pos = p + sizeof(CRLF) - 1;
-
- return NGX_OK;
- }
-
- if (ngx_strcmp(p, "END\x0d") == 0) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "key: \"%V\" was not found by memcached", &ctx->key);
-
- u->headers_in.content_length_n = 0;
- u->headers_in.status_n = 404;
- u->state->status = 404;
- u->buffer.pos = p + sizeof("END" CRLF) - 1;
- u->keepalive = 1;
-
- return NGX_OK;
- }
-
-no_valid:
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "memcached sent invalid response: \"%V\"", &line);
-
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
-}
-
-
-static ngx_int_t
-ngx_http_memcached_filter_init(void *data)
-{
- ngx_http_memcached_ctx_t *ctx = data;
-
- ngx_http_upstream_t *u;
-
- u = ctx->request->upstream;
-
- if (u->headers_in.status_n != 404) {
- u->length = u->headers_in.content_length_n + NGX_HTTP_MEMCACHED_END;
- ctx->rest = NGX_HTTP_MEMCACHED_END;
-
- } else {
- u->length = 0;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_memcached_filter(void *data, ssize_t bytes)
-{
- ngx_http_memcached_ctx_t *ctx = data;
-
- u_char *last;
- ngx_buf_t *b;
- ngx_chain_t *cl, **ll;
- ngx_http_upstream_t *u;
-
- u = ctx->request->upstream;
- b = &u->buffer;
-
- if (u->length == (ssize_t) ctx->rest) {
-
- if (ngx_strncmp(b->last,
- ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END - ctx->rest,
- bytes)
- != 0)
- {
- ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
- "memcached sent invalid trailer");
-
- u->length = 0;
- ctx->rest = 0;
-
- return NGX_OK;
- }
-
- u->length -= bytes;
- ctx->rest -= bytes;
-
- if (u->length == 0) {
- u->keepalive = 1;
- }
-
- return NGX_OK;
- }
-
- for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) {
- ll = &cl->next;
- }
-
- cl = ngx_chain_get_free_buf(ctx->request->pool, &u->free_bufs);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf->flush = 1;
- cl->buf->memory = 1;
-
- *ll = cl;
-
- last = b->last;
- cl->buf->pos = last;
- b->last += bytes;
- cl->buf->last = b->last;
- cl->buf->tag = u->output.tag;
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, ctx->request->connection->log, 0,
- "memcached filter bytes:%z size:%z length:%z rest:%z",
- bytes, b->last - b->pos, u->length, ctx->rest);
-
- if (bytes <= (ssize_t) (u->length - NGX_HTTP_MEMCACHED_END)) {
- u->length -= bytes;
- return NGX_OK;
- }
-
- last += (size_t) (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");
-
- b->last = last;
- cl->buf->last = last;
- u->length = 0;
- ctx->rest = 0;
-
- return NGX_OK;
- }
-
- ctx->rest -= b->last - last;
- b->last = last;
- cl->buf->last = last;
- u->length = ctx->rest;
-
- if (u->length == 0) {
- u->keepalive = 1;
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_memcached_abort_request(ngx_http_request_t *r)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "abort http memcached request");
- return;
-}
-
-
-static void
-ngx_http_memcached_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "finalize http memcached request");
- return;
-}
-
-
-static void *
-ngx_http_memcached_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_memcached_loc_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_memcached_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->upstream.bufs.num = 0;
- * conf->upstream.next_upstream = 0;
- * conf->upstream.temp_path = NULL;
- * conf->upstream.uri = { 0, NULL };
- * conf->upstream.location = NULL;
- */
-
- conf->upstream.local = NGX_CONF_UNSET_PTR;
- conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
-
- conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
-
- /* the hardcoded values */
- conf->upstream.cyclic_temp_file = 0;
- conf->upstream.buffering = 0;
- conf->upstream.ignore_client_abort = 0;
- conf->upstream.send_lowat = 0;
- conf->upstream.bufs.num = 0;
- conf->upstream.busy_buffers_size = 0;
- conf->upstream.max_temp_file_size = 0;
- conf->upstream.temp_file_write_size = 0;
- conf->upstream.intercept_errors = 1;
- conf->upstream.intercept_404 = 1;
- conf->upstream.pass_request_headers = 0;
- conf->upstream.pass_request_body = 0;
-
- conf->index = NGX_CONF_UNSET;
- conf->gzip_flag = NGX_CONF_UNSET_UINT;
-
- return conf;
-}
-
-
-static char *
-ngx_http_memcached_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_memcached_loc_conf_t *prev = parent;
- ngx_http_memcached_loc_conf_t *conf = child;
-
- ngx_conf_merge_ptr_value(conf->upstream.local,
- prev->upstream.local, NULL);
-
- ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
- prev->upstream.connect_timeout, 60000);
-
- ngx_conf_merge_msec_value(conf->upstream.send_timeout,
- prev->upstream.send_timeout, 60000);
-
- ngx_conf_merge_msec_value(conf->upstream.read_timeout,
- prev->upstream.read_timeout, 60000);
-
- ngx_conf_merge_size_value(conf->upstream.buffer_size,
- prev->upstream.buffer_size,
- (size_t) ngx_pagesize);
-
- ngx_conf_merge_bitmask_value(conf->upstream.next_upstream,
- prev->upstream.next_upstream,
- (NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_ERROR
- |NGX_HTTP_UPSTREAM_FT_TIMEOUT));
-
- if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) {
- conf->upstream.next_upstream = NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_OFF;
- }
-
- if (conf->upstream.upstream == NULL) {
- conf->upstream.upstream = prev->upstream.upstream;
- }
-
- if (conf->index == NGX_CONF_UNSET) {
- conf->index = prev->index;
- }
-
- ngx_conf_merge_uint_value(conf->gzip_flag, prev->gzip_flag, 0);
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_memcached_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_memcached_loc_conf_t *mlcf = conf;
-
- ngx_str_t *value;
- ngx_url_t u;
- ngx_http_core_loc_conf_t *clcf;
-
- if (mlcf->upstream.upstream) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- u.url = value[1];
- u.no_resolve = 1;
-
- mlcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
- if (mlcf->upstream.upstream == NULL) {
- return NGX_CONF_ERROR;
- }
-
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
-
- clcf->handler = ngx_http_memcached_handler;
-
- if (clcf->name.data[clcf->name.len - 1] == '/') {
- clcf->auto_redirect = 1;
- }
-
- mlcf->index = ngx_http_get_variable_index(cf, &ngx_http_memcached_key);
-
- if (mlcf->index == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_mp4_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_mp4_module.c
deleted file mode 100644
index 8f439ba9239..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_mp4_module.c
+++ /dev/null
@@ -1,3500 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-#define NGX_HTTP_MP4_TRAK_ATOM 0
-#define NGX_HTTP_MP4_TKHD_ATOM 1
-#define NGX_HTTP_MP4_MDIA_ATOM 2
-#define NGX_HTTP_MP4_MDHD_ATOM 3
-#define NGX_HTTP_MP4_HDLR_ATOM 4
-#define NGX_HTTP_MP4_MINF_ATOM 5
-#define NGX_HTTP_MP4_VMHD_ATOM 6
-#define NGX_HTTP_MP4_SMHD_ATOM 7
-#define NGX_HTTP_MP4_DINF_ATOM 8
-#define NGX_HTTP_MP4_STBL_ATOM 9
-#define NGX_HTTP_MP4_STSD_ATOM 10
-#define NGX_HTTP_MP4_STTS_ATOM 11
-#define NGX_HTTP_MP4_STTS_DATA 12
-#define NGX_HTTP_MP4_STSS_ATOM 13
-#define NGX_HTTP_MP4_STSS_DATA 14
-#define NGX_HTTP_MP4_CTTS_ATOM 15
-#define NGX_HTTP_MP4_CTTS_DATA 16
-#define NGX_HTTP_MP4_STSC_ATOM 17
-#define NGX_HTTP_MP4_STSC_START 18
-#define NGX_HTTP_MP4_STSC_DATA 19
-#define NGX_HTTP_MP4_STSC_END 20
-#define NGX_HTTP_MP4_STSZ_ATOM 21
-#define NGX_HTTP_MP4_STSZ_DATA 22
-#define NGX_HTTP_MP4_STCO_ATOM 23
-#define NGX_HTTP_MP4_STCO_DATA 24
-#define NGX_HTTP_MP4_CO64_ATOM 25
-#define NGX_HTTP_MP4_CO64_DATA 26
-
-#define NGX_HTTP_MP4_LAST_ATOM NGX_HTTP_MP4_CO64_DATA
-
-
-typedef struct {
- size_t buffer_size;
- size_t max_buffer_size;
-} ngx_http_mp4_conf_t;
-
-
-typedef struct {
- u_char chunk[4];
- u_char samples[4];
- u_char id[4];
-} ngx_mp4_stsc_entry_t;
-
-
-typedef struct {
- uint32_t timescale;
- uint32_t time_to_sample_entries;
- uint32_t sample_to_chunk_entries;
- uint32_t sync_samples_entries;
- uint32_t composition_offset_entries;
- uint32_t sample_sizes_entries;
- uint32_t chunks;
-
- ngx_uint_t start_sample;
- ngx_uint_t end_sample;
- ngx_uint_t start_chunk;
- ngx_uint_t end_chunk;
- ngx_uint_t start_chunk_samples;
- ngx_uint_t end_chunk_samples;
- uint64_t start_chunk_samples_size;
- uint64_t end_chunk_samples_size;
- off_t start_offset;
- off_t end_offset;
-
- size_t tkhd_size;
- size_t mdhd_size;
- size_t hdlr_size;
- size_t vmhd_size;
- size_t smhd_size;
- size_t dinf_size;
- size_t size;
-
- ngx_chain_t out[NGX_HTTP_MP4_LAST_ATOM + 1];
-
- ngx_buf_t trak_atom_buf;
- ngx_buf_t tkhd_atom_buf;
- ngx_buf_t mdia_atom_buf;
- ngx_buf_t mdhd_atom_buf;
- ngx_buf_t hdlr_atom_buf;
- ngx_buf_t minf_atom_buf;
- ngx_buf_t vmhd_atom_buf;
- ngx_buf_t smhd_atom_buf;
- ngx_buf_t dinf_atom_buf;
- ngx_buf_t stbl_atom_buf;
- ngx_buf_t stsd_atom_buf;
- ngx_buf_t stts_atom_buf;
- ngx_buf_t stts_data_buf;
- ngx_buf_t stss_atom_buf;
- ngx_buf_t stss_data_buf;
- ngx_buf_t ctts_atom_buf;
- ngx_buf_t ctts_data_buf;
- ngx_buf_t stsc_atom_buf;
- ngx_buf_t stsc_start_chunk_buf;
- ngx_buf_t stsc_end_chunk_buf;
- ngx_buf_t stsc_data_buf;
- ngx_buf_t stsz_atom_buf;
- ngx_buf_t stsz_data_buf;
- ngx_buf_t stco_atom_buf;
- ngx_buf_t stco_data_buf;
- ngx_buf_t co64_atom_buf;
- ngx_buf_t co64_data_buf;
-
- ngx_mp4_stsc_entry_t stsc_start_chunk_entry;
- ngx_mp4_stsc_entry_t stsc_end_chunk_entry;
-} ngx_http_mp4_trak_t;
-
-
-typedef struct {
- ngx_file_t file;
-
- u_char *buffer;
- u_char *buffer_start;
- u_char *buffer_pos;
- u_char *buffer_end;
- size_t buffer_size;
-
- off_t offset;
- off_t end;
- off_t content_length;
- ngx_uint_t start;
- ngx_uint_t length;
- uint32_t timescale;
- ngx_http_request_t *request;
- ngx_array_t trak;
- ngx_http_mp4_trak_t traks[2];
-
- size_t ftyp_size;
- size_t moov_size;
-
- ngx_chain_t *out;
- ngx_chain_t ftyp_atom;
- ngx_chain_t moov_atom;
- ngx_chain_t mvhd_atom;
- ngx_chain_t mdat_atom;
- ngx_chain_t mdat_data;
-
- ngx_buf_t ftyp_atom_buf;
- ngx_buf_t moov_atom_buf;
- ngx_buf_t mvhd_atom_buf;
- ngx_buf_t mdat_atom_buf;
- ngx_buf_t mdat_data_buf;
-
- u_char moov_atom_header[8];
- u_char mdat_atom_header[16];
-} ngx_http_mp4_file_t;
-
-
-typedef struct {
- char *name;
- ngx_int_t (*handler)(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-} ngx_http_mp4_atom_handler_t;
-
-
-#define ngx_mp4_atom_header(mp4) (mp4->buffer_pos - 8)
-#define ngx_mp4_atom_data(mp4) mp4->buffer_pos
-#define ngx_mp4_atom_data_size(t) (uint64_t) (sizeof(t) - 8)
-
-
-#define ngx_mp4_atom_next(mp4, n) \
- mp4->buffer_pos += (size_t) n; \
- mp4->offset += n
-
-
-#define ngx_mp4_set_atom_name(p, n1, n2, n3, n4) \
- ((u_char *) (p))[4] = n1; \
- ((u_char *) (p))[5] = n2; \
- ((u_char *) (p))[6] = n3; \
- ((u_char *) (p))[7] = n4
-
-#define ngx_mp4_get_32value(p) \
- ( ((uint32_t) ((u_char *) (p))[0] << 24) \
- + ( ((u_char *) (p))[1] << 16) \
- + ( ((u_char *) (p))[2] << 8) \
- + ( ((u_char *) (p))[3]) )
-
-#define ngx_mp4_set_32value(p, n) \
- ((u_char *) (p))[0] = (u_char) ((n) >> 24); \
- ((u_char *) (p))[1] = (u_char) ((n) >> 16); \
- ((u_char *) (p))[2] = (u_char) ((n) >> 8); \
- ((u_char *) (p))[3] = (u_char) (n)
-
-#define ngx_mp4_get_64value(p) \
- ( ((uint64_t) ((u_char *) (p))[0] << 56) \
- + ((uint64_t) ((u_char *) (p))[1] << 48) \
- + ((uint64_t) ((u_char *) (p))[2] << 40) \
- + ((uint64_t) ((u_char *) (p))[3] << 32) \
- + ((uint64_t) ((u_char *) (p))[4] << 24) \
- + ( ((u_char *) (p))[5] << 16) \
- + ( ((u_char *) (p))[6] << 8) \
- + ( ((u_char *) (p))[7]) )
-
-#define ngx_mp4_set_64value(p, n) \
- ((u_char *) (p))[0] = (u_char) ((uint64_t) (n) >> 56); \
- ((u_char *) (p))[1] = (u_char) ((uint64_t) (n) >> 48); \
- ((u_char *) (p))[2] = (u_char) ((uint64_t) (n) >> 40); \
- ((u_char *) (p))[3] = (u_char) ((uint64_t) (n) >> 32); \
- ((u_char *) (p))[4] = (u_char) ( (n) >> 24); \
- ((u_char *) (p))[5] = (u_char) ( (n) >> 16); \
- ((u_char *) (p))[6] = (u_char) ( (n) >> 8); \
- ((u_char *) (p))[7] = (u_char) (n)
-
-#define ngx_mp4_last_trak(mp4) \
- &((ngx_http_mp4_trak_t *) mp4->trak.elts)[mp4->trak.nelts - 1]
-
-
-static ngx_int_t ngx_http_mp4_handler(ngx_http_request_t *r);
-
-static ngx_int_t ngx_http_mp4_process(ngx_http_mp4_file_t *mp4);
-static ngx_int_t ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_atom_handler_t *atom, uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_read(ngx_http_mp4_file_t *mp4, size_t size);
-static ngx_int_t ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_read_mdat_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static size_t ngx_http_mp4_update_mdat_atom(ngx_http_mp4_file_t *mp4,
- off_t start_offset, off_t end_offset);
-static ngx_int_t ngx_http_mp4_read_mvhd_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_read_trak_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static void ngx_http_mp4_update_trak_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak);
-static ngx_int_t ngx_http_mp4_read_cmov_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_read_tkhd_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_read_mdia_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static void ngx_http_mp4_update_mdia_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak);
-static ngx_int_t ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_read_hdlr_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_read_minf_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static void ngx_http_mp4_update_minf_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak);
-static ngx_int_t ngx_http_mp4_read_dinf_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_read_vmhd_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_read_smhd_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_read_stbl_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static void ngx_http_mp4_update_stbl_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak);
-static ngx_int_t ngx_http_mp4_read_stsd_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_read_stts_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak);
-static ngx_int_t ngx_http_mp4_crop_stts_data(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak, ngx_uint_t start);
-static ngx_int_t ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_update_stss_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak);
-static void ngx_http_mp4_crop_stss_data(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak, ngx_uint_t start);
-static ngx_int_t ngx_http_mp4_read_ctts_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static void ngx_http_mp4_update_ctts_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak);
-static void ngx_http_mp4_crop_ctts_data(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak, ngx_uint_t start);
-static ngx_int_t ngx_http_mp4_read_stsc_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak);
-static ngx_int_t ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak, ngx_uint_t start);
-static ngx_int_t ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak);
-static ngx_int_t ngx_http_mp4_read_stco_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_update_stco_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak);
-static void ngx_http_mp4_adjust_stco_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak, int32_t adjustment);
-static ngx_int_t ngx_http_mp4_read_co64_atom(ngx_http_mp4_file_t *mp4,
- uint64_t atom_data_size);
-static ngx_int_t ngx_http_mp4_update_co64_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak);
-static void ngx_http_mp4_adjust_co64_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak, off_t adjustment);
-
-static char *ngx_http_mp4(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static void *ngx_http_mp4_create_conf(ngx_conf_t *cf);
-static char *ngx_http_mp4_merge_conf(ngx_conf_t *cf, void *parent, void *child);
-
-
-static ngx_command_t ngx_http_mp4_commands[] = {
-
- { ngx_string("mp4"),
- NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
- ngx_http_mp4,
- 0,
- 0,
- NULL },
-
- { ngx_string("mp4_buffer_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_mp4_conf_t, buffer_size),
- NULL },
-
- { ngx_string("mp4_max_buffer_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_mp4_conf_t, max_buffer_size),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_mp4_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_mp4_create_conf, /* create location configuration */
- ngx_http_mp4_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_mp4_module = {
- NGX_MODULE_V1,
- &ngx_http_mp4_module_ctx, /* module context */
- ngx_http_mp4_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_mp4_atom_handler_t ngx_http_mp4_atoms[] = {
- { "ftyp", ngx_http_mp4_read_ftyp_atom },
- { "moov", ngx_http_mp4_read_moov_atom },
- { "mdat", ngx_http_mp4_read_mdat_atom },
- { NULL, NULL }
-};
-
-static ngx_http_mp4_atom_handler_t ngx_http_mp4_moov_atoms[] = {
- { "mvhd", ngx_http_mp4_read_mvhd_atom },
- { "trak", ngx_http_mp4_read_trak_atom },
- { "cmov", ngx_http_mp4_read_cmov_atom },
- { NULL, NULL }
-};
-
-static ngx_http_mp4_atom_handler_t ngx_http_mp4_trak_atoms[] = {
- { "tkhd", ngx_http_mp4_read_tkhd_atom },
- { "mdia", ngx_http_mp4_read_mdia_atom },
- { NULL, NULL }
-};
-
-static ngx_http_mp4_atom_handler_t ngx_http_mp4_mdia_atoms[] = {
- { "mdhd", ngx_http_mp4_read_mdhd_atom },
- { "hdlr", ngx_http_mp4_read_hdlr_atom },
- { "minf", ngx_http_mp4_read_minf_atom },
- { NULL, NULL }
-};
-
-static ngx_http_mp4_atom_handler_t ngx_http_mp4_minf_atoms[] = {
- { "vmhd", ngx_http_mp4_read_vmhd_atom },
- { "smhd", ngx_http_mp4_read_smhd_atom },
- { "dinf", ngx_http_mp4_read_dinf_atom },
- { "stbl", ngx_http_mp4_read_stbl_atom },
- { NULL, NULL }
-};
-
-static ngx_http_mp4_atom_handler_t ngx_http_mp4_stbl_atoms[] = {
- { "stsd", ngx_http_mp4_read_stsd_atom },
- { "stts", ngx_http_mp4_read_stts_atom },
- { "stss", ngx_http_mp4_read_stss_atom },
- { "ctts", ngx_http_mp4_read_ctts_atom },
- { "stsc", ngx_http_mp4_read_stsc_atom },
- { "stsz", ngx_http_mp4_read_stsz_atom },
- { "stco", ngx_http_mp4_read_stco_atom },
- { "co64", ngx_http_mp4_read_co64_atom },
- { NULL, NULL }
-};
-
-
-static ngx_int_t
-ngx_http_mp4_handler(ngx_http_request_t *r)
-{
- u_char *last;
- size_t root;
- ngx_int_t rc, start, end;
- ngx_uint_t level, length;
- ngx_str_t path, value;
- ngx_log_t *log;
- ngx_buf_t *b;
- ngx_chain_t out;
- ngx_http_mp4_file_t *mp4;
- ngx_open_file_info_t of;
- ngx_http_core_loc_conf_t *clcf;
-
- if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
- return NGX_HTTP_NOT_ALLOWED;
- }
-
- if (r->uri.data[r->uri.len - 1] == '/') {
- return NGX_DECLINED;
- }
-
- rc = ngx_http_discard_request_body(r);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- last = ngx_http_map_uri_to_path(r, &path, &root, 0);
- if (last == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- log = r->connection->log;
-
- path.len = last - path.data;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
- "http mp4 filename: \"%V\"", &path);
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- ngx_memzero(&of, sizeof(ngx_open_file_info_t));
-
- of.read_ahead = clcf->read_ahead;
- of.directio = NGX_MAX_OFF_T_VALUE;
- of.valid = clcf->open_file_cache_valid;
- of.min_uses = clcf->open_file_cache_min_uses;
- of.errors = clcf->open_file_cache_errors;
- of.events = clcf->open_file_cache_events;
-
- if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
- != NGX_OK)
- {
- switch (of.err) {
-
- case 0:
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
-
- case NGX_ENOENT:
- case NGX_ENOTDIR:
- case NGX_ENAMETOOLONG:
-
- level = NGX_LOG_ERR;
- rc = NGX_HTTP_NOT_FOUND;
- break;
-
- case NGX_EACCES:
-#if (NGX_HAVE_OPENAT)
- case NGX_EMLINK:
- case NGX_ELOOP:
-#endif
-
- level = NGX_LOG_ERR;
- rc = NGX_HTTP_FORBIDDEN;
- break;
-
- default:
-
- level = NGX_LOG_CRIT;
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- break;
- }
-
- if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
- ngx_log_error(level, log, of.err,
- "%s \"%s\" failed", of.failed, path.data);
- }
-
- return rc;
- }
-
- if (!of.is_file) {
-
- if (ngx_close_file(of.fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", path.data);
- }
-
- return NGX_DECLINED;
- }
-
- r->root_tested = !r->error_page;
- r->allow_ranges = 1;
-
- start = -1;
- length = 0;
- r->headers_out.content_length_n = of.size;
- mp4 = NULL;
- b = NULL;
-
- if (r->args.len) {
-
- if (ngx_http_arg(r, (u_char *) "start", 5, &value) == NGX_OK) {
-
- /*
- * A Flash player may send start value with a lot of digits
- * after dot so strtod() is used instead of atofp(). NaNs and
- * infinities become negative numbers after (int) conversion.
- */
-
- ngx_set_errno(0);
- start = (int) (strtod((char *) value.data, NULL) * 1000);
-
- if (ngx_errno != 0) {
- start = -1;
- }
- }
-
- if (ngx_http_arg(r, (u_char *) "end", 3, &value) == NGX_OK) {
-
- ngx_set_errno(0);
- end = (int) (strtod((char *) value.data, NULL) * 1000);
-
- if (ngx_errno != 0) {
- end = -1;
- }
-
- if (end > 0) {
- if (start < 0) {
- start = 0;
- }
-
- if (end > start) {
- length = end - start;
- }
- }
- }
- }
-
- if (start >= 0) {
- r->single_range = 1;
-
- mp4 = ngx_pcalloc(r->pool, sizeof(ngx_http_mp4_file_t));
- if (mp4 == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- mp4->file.fd = of.fd;
- mp4->file.name = path;
- mp4->file.log = r->connection->log;
- mp4->end = of.size;
- mp4->start = (ngx_uint_t) start;
- mp4->length = length;
- mp4->request = r;
-
- switch (ngx_http_mp4_process(mp4)) {
-
- case NGX_DECLINED:
- if (mp4->buffer) {
- ngx_pfree(r->pool, mp4->buffer);
- }
-
- ngx_pfree(r->pool, mp4);
- mp4 = NULL;
-
- break;
-
- case NGX_OK:
- r->headers_out.content_length_n = mp4->content_length;
- break;
-
- default: /* NGX_ERROR */
- if (mp4->buffer) {
- ngx_pfree(r->pool, mp4->buffer);
- }
-
- ngx_pfree(r->pool, mp4);
-
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
- }
-
- log->action = "sending mp4 to client";
-
- if (clcf->directio <= of.size) {
-
- /*
- * DIRECTIO is set on transfer only
- * to allow kernel to cache "moov" atom
- */
-
- if (ngx_directio_on(of.fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- ngx_directio_on_n " \"%s\" failed", path.data);
- }
-
- of.is_directio = 1;
-
- if (mp4) {
- mp4->file.directio = 1;
- }
- }
-
- r->headers_out.status = NGX_HTTP_OK;
- r->headers_out.last_modified_time = of.mtime;
-
- if (ngx_http_set_etag(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_http_set_content_type(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (mp4 == NULL) {
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
- if (b->file == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
- }
-
- rc = ngx_http_send_header(r);
-
- if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
- return rc;
- }
-
- if (mp4) {
- return ngx_http_output_filter(r, mp4->out);
- }
-
- b->file_pos = 0;
- b->file_last = of.size;
-
- b->in_file = b->file_last ? 1 : 0;
- b->last_buf = (r == r->main) ? 1 : 0;
- b->last_in_chain = 1;
-
- b->file->fd = of.fd;
- b->file->name = path;
- b->file->log = log;
- b->file->directio = of.is_directio;
-
- out.buf = b;
- out.next = NULL;
-
- return ngx_http_output_filter(r, &out);
-}
-
-
-static ngx_int_t
-ngx_http_mp4_process(ngx_http_mp4_file_t *mp4)
-{
- off_t start_offset, end_offset, adjustment;
- ngx_int_t rc;
- ngx_uint_t i, j;
- ngx_chain_t **prev;
- ngx_http_mp4_trak_t *trak;
- ngx_http_mp4_conf_t *conf;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 start:%ui, length:%ui", mp4->start, mp4->length);
-
- conf = ngx_http_get_module_loc_conf(mp4->request, ngx_http_mp4_module);
-
- mp4->buffer_size = conf->buffer_size;
-
- rc = ngx_http_mp4_read_atom(mp4, ngx_http_mp4_atoms, mp4->end);
- if (rc != NGX_OK) {
- return rc;
- }
-
- if (mp4->trak.nelts == 0) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "no mp4 trak atoms were found in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- if (mp4->mdat_atom.buf == NULL) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "no mp4 mdat atom was found in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- prev = &mp4->out;
-
- if (mp4->ftyp_atom.buf) {
- *prev = &mp4->ftyp_atom;
- prev = &mp4->ftyp_atom.next;
- }
-
- *prev = &mp4->moov_atom;
- prev = &mp4->moov_atom.next;
-
- if (mp4->mvhd_atom.buf) {
- mp4->moov_size += mp4->mvhd_atom_buf.last - mp4->mvhd_atom_buf.pos;
- *prev = &mp4->mvhd_atom;
- prev = &mp4->mvhd_atom.next;
- }
-
- start_offset = mp4->end;
- end_offset = 0;
- trak = mp4->trak.elts;
-
- for (i = 0; i < mp4->trak.nelts; i++) {
-
- if (ngx_http_mp4_update_stts_atom(mp4, &trak[i]) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (ngx_http_mp4_update_stss_atom(mp4, &trak[i]) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_http_mp4_update_ctts_atom(mp4, &trak[i]);
-
- if (ngx_http_mp4_update_stsc_atom(mp4, &trak[i]) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (ngx_http_mp4_update_stsz_atom(mp4, &trak[i]) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (trak[i].out[NGX_HTTP_MP4_CO64_DATA].buf) {
- if (ngx_http_mp4_update_co64_atom(mp4, &trak[i]) != NGX_OK) {
- return NGX_ERROR;
- }
-
- } else {
- if (ngx_http_mp4_update_stco_atom(mp4, &trak[i]) != NGX_OK) {
- return NGX_ERROR;
- }
- }
-
- ngx_http_mp4_update_stbl_atom(mp4, &trak[i]);
- ngx_http_mp4_update_minf_atom(mp4, &trak[i]);
- trak[i].size += trak[i].mdhd_size;
- trak[i].size += trak[i].hdlr_size;
- ngx_http_mp4_update_mdia_atom(mp4, &trak[i]);
- trak[i].size += trak[i].tkhd_size;
- ngx_http_mp4_update_trak_atom(mp4, &trak[i]);
-
- mp4->moov_size += trak[i].size;
-
- if (start_offset > trak[i].start_offset) {
- start_offset = trak[i].start_offset;
- }
-
- if (end_offset < trak[i].end_offset) {
- end_offset = trak[i].end_offset;
- }
-
- *prev = &trak[i].out[NGX_HTTP_MP4_TRAK_ATOM];
- prev = &trak[i].out[NGX_HTTP_MP4_TRAK_ATOM].next;
-
- for (j = 0; j < NGX_HTTP_MP4_LAST_ATOM + 1; j++) {
- if (trak[i].out[j].buf) {
- *prev = &trak[i].out[j];
- prev = &trak[i].out[j].next;
- }
- }
- }
-
- if (end_offset < start_offset) {
- end_offset = start_offset;
- }
-
- mp4->moov_size += 8;
-
- ngx_mp4_set_32value(mp4->moov_atom_header, mp4->moov_size);
- ngx_mp4_set_atom_name(mp4->moov_atom_header, 'm', 'o', 'o', 'v');
- mp4->content_length += mp4->moov_size;
-
- *prev = &mp4->mdat_atom;
-
- if (start_offset > mp4->mdat_data.buf->file_last) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "start time is out mp4 mdat atom in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- adjustment = mp4->ftyp_size + mp4->moov_size
- + ngx_http_mp4_update_mdat_atom(mp4, start_offset, end_offset)
- - start_offset;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 adjustment:%O", adjustment);
-
- for (i = 0; i < mp4->trak.nelts; i++) {
- if (trak[i].out[NGX_HTTP_MP4_CO64_DATA].buf) {
- ngx_http_mp4_adjust_co64_atom(mp4, &trak[i], adjustment);
- } else {
- ngx_http_mp4_adjust_stco_atom(mp4, &trak[i], (int32_t) adjustment);
- }
- }
-
- return NGX_OK;
-}
-
-
-typedef struct {
- u_char size[4];
- u_char name[4];
-} ngx_mp4_atom_header_t;
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char size64[8];
-} ngx_mp4_atom_header64_t;
-
-
-static ngx_int_t
-ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_atom_handler_t *atom, uint64_t atom_data_size)
-{
- off_t end;
- size_t atom_header_size;
- u_char *atom_header, *atom_name;
- uint64_t atom_size;
- ngx_int_t rc;
- ngx_uint_t n;
-
- end = mp4->offset + atom_data_size;
-
- while (mp4->offset < end) {
-
- if (ngx_http_mp4_read(mp4, sizeof(uint32_t)) != NGX_OK) {
- return NGX_ERROR;
- }
-
- atom_header = mp4->buffer_pos;
- atom_size = ngx_mp4_get_32value(atom_header);
- atom_header_size = sizeof(ngx_mp4_atom_header_t);
-
- if (atom_size == 0) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 atom end");
- return NGX_OK;
- }
-
- if (atom_size < sizeof(ngx_mp4_atom_header_t)) {
-
- if (atom_size == 1) {
-
- if (ngx_http_mp4_read(mp4, sizeof(ngx_mp4_atom_header64_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- /* 64-bit atom size */
- atom_header = mp4->buffer_pos;
- atom_size = ngx_mp4_get_64value(atom_header + 8);
- atom_header_size = sizeof(ngx_mp4_atom_header64_t);
-
- } else {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 atom is too small:%uL",
- mp4->file.name.data, atom_size);
- return NGX_ERROR;
- }
- }
-
- if (ngx_http_mp4_read(mp4, sizeof(ngx_mp4_atom_header_t)) != NGX_OK) {
- return NGX_ERROR;
- }
-
- atom_header = mp4->buffer_pos;
- atom_name = atom_header + sizeof(uint32_t);
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 atom: %*s @%O:%uL",
- 4, atom_name, mp4->offset, atom_size);
-
- if (atom_size > (uint64_t) (NGX_MAX_OFF_T_VALUE - mp4->offset)
- || mp4->offset + (off_t) atom_size > end)
- {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 atom too large:%uL",
- mp4->file.name.data, atom_size);
- return NGX_ERROR;
- }
-
- for (n = 0; atom[n].name; n++) {
-
- if (ngx_strncmp(atom_name, atom[n].name, 4) == 0) {
-
- ngx_mp4_atom_next(mp4, atom_header_size);
-
- rc = atom[n].handler(mp4, atom_size - atom_header_size);
- if (rc != NGX_OK) {
- return rc;
- }
-
- goto next;
- }
- }
-
- ngx_mp4_atom_next(mp4, atom_size);
-
- next:
- continue;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_read(ngx_http_mp4_file_t *mp4, size_t size)
-{
- ssize_t n;
-
- if (mp4->buffer_pos + size <= mp4->buffer_end) {
- return NGX_OK;
- }
-
- if (mp4->offset + (off_t) mp4->buffer_size > mp4->end) {
- mp4->buffer_size = (size_t) (mp4->end - mp4->offset);
- }
-
- if (mp4->buffer_size < size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 file truncated", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- if (mp4->buffer == NULL) {
- mp4->buffer = ngx_palloc(mp4->request->pool, mp4->buffer_size);
- if (mp4->buffer == NULL) {
- return NGX_ERROR;
- }
-
- mp4->buffer_start = mp4->buffer;
- }
-
- n = ngx_read_file(&mp4->file, mp4->buffer_start, mp4->buffer_size,
- mp4->offset);
-
- if (n == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- if ((size_t) n != mp4->buffer_size) {
- ngx_log_error(NGX_LOG_CRIT, mp4->file.log, 0,
- ngx_read_file_n " read only %z of %z from \"%s\"",
- n, mp4->buffer_size, mp4->file.name.data);
- return NGX_ERROR;
- }
-
- mp4->buffer_pos = mp4->buffer_start;
- mp4->buffer_end = mp4->buffer_start + mp4->buffer_size;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *ftyp_atom;
- size_t atom_size;
- ngx_buf_t *atom;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 ftyp atom");
-
- if (atom_data_size > 1024
- || ngx_mp4_atom_data(mp4) + (size_t) atom_data_size > mp4->buffer_end)
- {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 ftyp atom is too large:%uL",
- mp4->file.name.data, atom_data_size);
- return NGX_ERROR;
- }
-
- atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
-
- ftyp_atom = ngx_palloc(mp4->request->pool, atom_size);
- if (ftyp_atom == NULL) {
- return NGX_ERROR;
- }
-
- ngx_mp4_set_32value(ftyp_atom, atom_size);
- ngx_mp4_set_atom_name(ftyp_atom, 'f', 't', 'y', 'p');
-
- /*
- * only moov atom content is guaranteed to be in mp4->buffer
- * during sending response, so ftyp atom content should be copied
- */
- ngx_memcpy(ftyp_atom + sizeof(ngx_mp4_atom_header_t),
- ngx_mp4_atom_data(mp4), (size_t) atom_data_size);
-
- atom = &mp4->ftyp_atom_buf;
- atom->temporary = 1;
- atom->pos = ftyp_atom;
- atom->last = ftyp_atom + atom_size;
-
- mp4->ftyp_atom.buf = atom;
- mp4->ftyp_size = atom_size;
- mp4->content_length = atom_size;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-/*
- * Small excess buffer to process atoms after moov atom, mp4->buffer_start
- * will be set to this buffer part after moov atom processing.
- */
-#define NGX_HTTP_MP4_MOOV_BUFFER_EXCESS (4 * 1024)
-
-static ngx_int_t
-ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- ngx_int_t rc;
- ngx_uint_t no_mdat;
- ngx_buf_t *atom;
- ngx_http_mp4_conf_t *conf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 moov atom");
-
- no_mdat = (mp4->mdat_atom.buf == NULL);
-
- if (no_mdat && mp4->start == 0 && mp4->length == 0) {
- /*
- * send original file if moov atom resides before
- * mdat atom and client requests integral file
- */
- return NGX_DECLINED;
- }
-
- conf = ngx_http_get_module_loc_conf(mp4->request, ngx_http_mp4_module);
-
- if (atom_data_size > mp4->buffer_size) {
-
- if (atom_data_size > conf->max_buffer_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 moov atom is too large:%uL, "
- "you may want to increase mp4_max_buffer_size",
- mp4->file.name.data, atom_data_size);
- return NGX_ERROR;
- }
-
- ngx_pfree(mp4->request->pool, mp4->buffer);
- mp4->buffer = NULL;
- mp4->buffer_pos = NULL;
- mp4->buffer_end = NULL;
-
- mp4->buffer_size = (size_t) atom_data_size
- + NGX_HTTP_MP4_MOOV_BUFFER_EXCESS * no_mdat;
- }
-
- if (ngx_http_mp4_read(mp4, (size_t) atom_data_size) != NGX_OK) {
- return NGX_ERROR;
- }
-
- mp4->trak.elts = &mp4->traks;
- mp4->trak.size = sizeof(ngx_http_mp4_trak_t);
- mp4->trak.nalloc = 2;
- mp4->trak.pool = mp4->request->pool;
-
- atom = &mp4->moov_atom_buf;
- atom->temporary = 1;
- atom->pos = mp4->moov_atom_header;
- atom->last = mp4->moov_atom_header + 8;
-
- mp4->moov_atom.buf = &mp4->moov_atom_buf;
-
- rc = ngx_http_mp4_read_atom(mp4, ngx_http_mp4_moov_atoms, atom_data_size);
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 moov atom done");
-
- if (no_mdat) {
- mp4->buffer_start = mp4->buffer_pos;
- mp4->buffer_size = NGX_HTTP_MP4_MOOV_BUFFER_EXCESS;
-
- if (mp4->buffer_start + mp4->buffer_size > mp4->buffer_end) {
- mp4->buffer = NULL;
- mp4->buffer_pos = NULL;
- mp4->buffer_end = NULL;
- }
-
- } else {
- /* skip atoms after moov atom */
- mp4->offset = mp4->end;
- }
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_read_mdat_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- ngx_buf_t *data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mdat atom");
-
- data = &mp4->mdat_data_buf;
- data->file = &mp4->file;
- data->in_file = 1;
- data->last_buf = 1;
- data->last_in_chain = 1;
- data->file_last = mp4->offset + atom_data_size;
-
- mp4->mdat_atom.buf = &mp4->mdat_atom_buf;
- mp4->mdat_atom.next = &mp4->mdat_data;
- mp4->mdat_data.buf = data;
-
- if (mp4->trak.nelts) {
- /* skip atoms after mdat atom */
- mp4->offset = mp4->end;
-
- } else {
- ngx_mp4_atom_next(mp4, atom_data_size);
- }
-
- return NGX_OK;
-}
-
-
-static size_t
-ngx_http_mp4_update_mdat_atom(ngx_http_mp4_file_t *mp4, off_t start_offset,
- off_t end_offset)
-{
- off_t atom_data_size;
- u_char *atom_header;
- uint32_t atom_header_size;
- uint64_t atom_size;
- ngx_buf_t *atom;
-
- atom_data_size = end_offset - start_offset;
- mp4->mdat_data.buf->file_pos = start_offset;
- mp4->mdat_data.buf->file_last = end_offset;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mdat new offset @%O:%O", start_offset, atom_data_size);
-
- atom_header = mp4->mdat_atom_header;
-
- if ((uint64_t) atom_data_size > (uint64_t) 0xffffffff) {
- atom_size = 1;
- atom_header_size = sizeof(ngx_mp4_atom_header64_t);
- ngx_mp4_set_64value(atom_header + sizeof(ngx_mp4_atom_header_t),
- sizeof(ngx_mp4_atom_header64_t) + atom_data_size);
- } else {
- atom_size = sizeof(ngx_mp4_atom_header_t) + atom_data_size;
- atom_header_size = sizeof(ngx_mp4_atom_header_t);
- }
-
- mp4->content_length += atom_header_size + atom_data_size;
-
- ngx_mp4_set_32value(atom_header, atom_size);
- ngx_mp4_set_atom_name(atom_header, 'm', 'd', 'a', 't');
-
- atom = &mp4->mdat_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_header + atom_header_size;
-
- return atom_header_size;
-}
-
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char creation_time[4];
- u_char modification_time[4];
- u_char timescale[4];
- u_char duration[4];
- u_char rate[4];
- u_char volume[2];
- u_char reserved[10];
- u_char matrix[36];
- u_char preview_time[4];
- u_char preview_duration[4];
- u_char poster_time[4];
- u_char selection_time[4];
- u_char selection_duration[4];
- u_char current_time[4];
- u_char next_track_id[4];
-} ngx_mp4_mvhd_atom_t;
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char creation_time[8];
- u_char modification_time[8];
- u_char timescale[4];
- u_char duration[8];
- u_char rate[4];
- u_char volume[2];
- u_char reserved[10];
- u_char matrix[36];
- u_char preview_time[4];
- u_char preview_duration[4];
- u_char poster_time[4];
- u_char selection_time[4];
- u_char selection_duration[4];
- u_char current_time[4];
- u_char next_track_id[4];
-} ngx_mp4_mvhd64_atom_t;
-
-
-static ngx_int_t
-ngx_http_mp4_read_mvhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header;
- size_t atom_size;
- uint32_t timescale;
- uint64_t duration, start_time, length_time;
- ngx_buf_t *atom;
- ngx_mp4_mvhd_atom_t *mvhd_atom;
- ngx_mp4_mvhd64_atom_t *mvhd64_atom;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mvhd atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- mvhd_atom = (ngx_mp4_mvhd_atom_t *) atom_header;
- mvhd64_atom = (ngx_mp4_mvhd64_atom_t *) atom_header;
- ngx_mp4_set_atom_name(atom_header, 'm', 'v', 'h', 'd');
-
- if (ngx_mp4_atom_data_size(ngx_mp4_mvhd_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 mvhd atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- if (mvhd_atom->version[0] == 0) {
- /* version 0: 32-bit duration */
- timescale = ngx_mp4_get_32value(mvhd_atom->timescale);
- duration = ngx_mp4_get_32value(mvhd_atom->duration);
-
- } else {
- /* version 1: 64-bit duration */
-
- if (ngx_mp4_atom_data_size(ngx_mp4_mvhd64_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 mvhd atom too small",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- timescale = ngx_mp4_get_32value(mvhd64_atom->timescale);
- duration = ngx_mp4_get_64value(mvhd64_atom->duration);
- }
-
- mp4->timescale = timescale;
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mvhd timescale:%uD, duration:%uL, time:%.3fs",
- timescale, duration, (double) duration / timescale);
-
- start_time = (uint64_t) mp4->start * timescale / 1000;
-
- if (duration < start_time) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 start time exceeds file duration",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- duration -= start_time;
-
- if (mp4->length) {
- length_time = (uint64_t) mp4->length * timescale / 1000;
-
- if (duration > length_time) {
- duration = length_time;
- }
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mvhd new duration:%uL, time:%.3fs",
- duration, (double) duration / timescale);
-
- atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
- ngx_mp4_set_32value(mvhd_atom->size, atom_size);
-
- if (mvhd_atom->version[0] == 0) {
- ngx_mp4_set_32value(mvhd_atom->duration, duration);
-
- } else {
- ngx_mp4_set_64value(mvhd64_atom->duration, duration);
- }
-
- atom = &mp4->mvhd_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_header + atom_size;
-
- mp4->mvhd_atom.buf = atom;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_read_trak_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header, *atom_end;
- off_t atom_file_end;
- ngx_int_t rc;
- ngx_buf_t *atom;
- ngx_http_mp4_trak_t *trak;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 trak atom");
-
- trak = ngx_array_push(&mp4->trak);
- if (trak == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memzero(trak, sizeof(ngx_http_mp4_trak_t));
-
- atom_header = ngx_mp4_atom_header(mp4);
- ngx_mp4_set_atom_name(atom_header, 't', 'r', 'a', 'k');
-
- atom = &trak->trak_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_header + sizeof(ngx_mp4_atom_header_t);
-
- trak->out[NGX_HTTP_MP4_TRAK_ATOM].buf = atom;
-
- atom_end = mp4->buffer_pos + (size_t) atom_data_size;
- atom_file_end = mp4->offset + atom_data_size;
-
- rc = ngx_http_mp4_read_atom(mp4, ngx_http_mp4_trak_atoms, atom_data_size);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 trak atom: %i", rc);
-
- if (rc == NGX_DECLINED) {
- /* skip this trak */
- ngx_memzero(trak, sizeof(ngx_http_mp4_trak_t));
- mp4->trak.nelts--;
- mp4->buffer_pos = atom_end;
- mp4->offset = atom_file_end;
- return NGX_OK;
- }
-
- return rc;
-}
-
-
-static void
-ngx_http_mp4_update_trak_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak)
-{
- ngx_buf_t *atom;
-
- trak->size += sizeof(ngx_mp4_atom_header_t);
- atom = &trak->trak_atom_buf;
- ngx_mp4_set_32value(atom->pos, trak->size);
-}
-
-
-static ngx_int_t
-ngx_http_mp4_read_cmov_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 compressed moov atom (cmov) is not supported",
- mp4->file.name.data);
-
- return NGX_ERROR;
-}
-
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char creation_time[4];
- u_char modification_time[4];
- u_char track_id[4];
- u_char reserved1[4];
- u_char duration[4];
- u_char reserved2[8];
- u_char layer[2];
- u_char group[2];
- u_char volume[2];
- u_char reverved3[2];
- u_char matrix[36];
- u_char width[4];
- u_char heigth[4];
-} ngx_mp4_tkhd_atom_t;
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char creation_time[8];
- u_char modification_time[8];
- u_char track_id[4];
- u_char reserved1[4];
- u_char duration[8];
- u_char reserved2[8];
- u_char layer[2];
- u_char group[2];
- u_char volume[2];
- u_char reverved3[2];
- u_char matrix[36];
- u_char width[4];
- u_char heigth[4];
-} ngx_mp4_tkhd64_atom_t;
-
-
-static ngx_int_t
-ngx_http_mp4_read_tkhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header;
- size_t atom_size;
- uint64_t duration, start_time, length_time;
- ngx_buf_t *atom;
- ngx_http_mp4_trak_t *trak;
- ngx_mp4_tkhd_atom_t *tkhd_atom;
- ngx_mp4_tkhd64_atom_t *tkhd64_atom;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 tkhd atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- tkhd_atom = (ngx_mp4_tkhd_atom_t *) atom_header;
- tkhd64_atom = (ngx_mp4_tkhd64_atom_t *) atom_header;
- ngx_mp4_set_atom_name(tkhd_atom, 't', 'k', 'h', 'd');
-
- if (ngx_mp4_atom_data_size(ngx_mp4_tkhd_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 tkhd atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- if (tkhd_atom->version[0] == 0) {
- /* version 0: 32-bit duration */
- duration = ngx_mp4_get_32value(tkhd_atom->duration);
-
- } else {
- /* version 1: 64-bit duration */
-
- if (ngx_mp4_atom_data_size(ngx_mp4_tkhd64_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 tkhd atom too small",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- duration = ngx_mp4_get_64value(tkhd64_atom->duration);
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "tkhd duration:%uL, time:%.3fs",
- duration, (double) duration / mp4->timescale);
-
- start_time = (uint64_t) mp4->start * mp4->timescale / 1000;
-
- if (duration <= start_time) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "tkhd duration is less than start time");
- return NGX_DECLINED;
- }
-
- duration -= start_time;
-
- if (mp4->length) {
- length_time = (uint64_t) mp4->length * mp4->timescale / 1000;
-
- if (duration > length_time) {
- duration = length_time;
- }
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "tkhd new duration:%uL, time:%.3fs",
- duration, (double) duration / mp4->timescale);
-
- atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
-
- trak = ngx_mp4_last_trak(mp4);
- trak->tkhd_size = atom_size;
-
- ngx_mp4_set_32value(tkhd_atom->size, atom_size);
-
- if (tkhd_atom->version[0] == 0) {
- ngx_mp4_set_32value(tkhd_atom->duration, duration);
-
- } else {
- ngx_mp4_set_64value(tkhd64_atom->duration, duration);
- }
-
- atom = &trak->tkhd_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_header + atom_size;
-
- trak->out[NGX_HTTP_MP4_TKHD_ATOM].buf = atom;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_read_mdia_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header;
- ngx_buf_t *atom;
- ngx_http_mp4_trak_t *trak;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "process mdia atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- ngx_mp4_set_atom_name(atom_header, 'm', 'd', 'i', 'a');
-
- trak = ngx_mp4_last_trak(mp4);
-
- atom = &trak->mdia_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_header + sizeof(ngx_mp4_atom_header_t);
-
- trak->out[NGX_HTTP_MP4_MDIA_ATOM].buf = atom;
-
- return ngx_http_mp4_read_atom(mp4, ngx_http_mp4_mdia_atoms, atom_data_size);
-}
-
-
-static void
-ngx_http_mp4_update_mdia_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak)
-{
- ngx_buf_t *atom;
-
- trak->size += sizeof(ngx_mp4_atom_header_t);
- atom = &trak->mdia_atom_buf;
- ngx_mp4_set_32value(atom->pos, trak->size);
-}
-
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char creation_time[4];
- u_char modification_time[4];
- u_char timescale[4];
- u_char duration[4];
- u_char language[2];
- u_char quality[2];
-} ngx_mp4_mdhd_atom_t;
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char creation_time[8];
- u_char modification_time[8];
- u_char timescale[4];
- u_char duration[8];
- u_char language[2];
- u_char quality[2];
-} ngx_mp4_mdhd64_atom_t;
-
-
-static ngx_int_t
-ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header;
- size_t atom_size;
- uint32_t timescale;
- uint64_t duration, start_time, length_time;
- ngx_buf_t *atom;
- ngx_http_mp4_trak_t *trak;
- ngx_mp4_mdhd_atom_t *mdhd_atom;
- ngx_mp4_mdhd64_atom_t *mdhd64_atom;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mdhd atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- mdhd_atom = (ngx_mp4_mdhd_atom_t *) atom_header;
- mdhd64_atom = (ngx_mp4_mdhd64_atom_t *) atom_header;
- ngx_mp4_set_atom_name(mdhd_atom, 'm', 'd', 'h', 'd');
-
- if (ngx_mp4_atom_data_size(ngx_mp4_mdhd_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 mdhd atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- if (mdhd_atom->version[0] == 0) {
- /* version 0: everything is 32-bit */
- timescale = ngx_mp4_get_32value(mdhd_atom->timescale);
- duration = ngx_mp4_get_32value(mdhd_atom->duration);
-
- } else {
- /* version 1: 64-bit duration and 32-bit timescale */
-
- if (ngx_mp4_atom_data_size(ngx_mp4_mdhd64_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 mdhd atom too small",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- timescale = ngx_mp4_get_32value(mdhd64_atom->timescale);
- duration = ngx_mp4_get_64value(mdhd64_atom->duration);
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mdhd timescale:%uD, duration:%uL, time:%.3fs",
- timescale, duration, (double) duration / timescale);
-
- start_time = (uint64_t) mp4->start * timescale / 1000;
-
- if (duration <= start_time) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mdhd duration is less than start time");
- return NGX_DECLINED;
- }
-
- duration -= start_time;
-
- if (mp4->length) {
- length_time = (uint64_t) mp4->length * timescale / 1000;
-
- if (duration > length_time) {
- duration = length_time;
- }
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mdhd new duration:%uL, time:%.3fs",
- duration, (double) duration / timescale);
-
- atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
-
- trak = ngx_mp4_last_trak(mp4);
- trak->mdhd_size = atom_size;
- trak->timescale = timescale;
-
- ngx_mp4_set_32value(mdhd_atom->size, atom_size);
-
- if (mdhd_atom->version[0] == 0) {
- ngx_mp4_set_32value(mdhd_atom->duration, duration);
-
- } else {
- ngx_mp4_set_64value(mdhd64_atom->duration, duration);
- }
-
- atom = &trak->mdhd_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_header + atom_size;
-
- trak->out[NGX_HTTP_MP4_MDHD_ATOM].buf = atom;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_read_hdlr_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header;
- size_t atom_size;
- ngx_buf_t *atom;
- ngx_http_mp4_trak_t *trak;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 hdlr atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
- ngx_mp4_set_32value(atom_header, atom_size);
- ngx_mp4_set_atom_name(atom_header, 'h', 'd', 'l', 'r');
-
- trak = ngx_mp4_last_trak(mp4);
-
- atom = &trak->hdlr_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_header + atom_size;
-
- trak->hdlr_size = atom_size;
- trak->out[NGX_HTTP_MP4_HDLR_ATOM].buf = atom;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_read_minf_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header;
- ngx_buf_t *atom;
- ngx_http_mp4_trak_t *trak;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "process minf atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- ngx_mp4_set_atom_name(atom_header, 'm', 'i', 'n', 'f');
-
- trak = ngx_mp4_last_trak(mp4);
-
- atom = &trak->minf_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_header + sizeof(ngx_mp4_atom_header_t);
-
- trak->out[NGX_HTTP_MP4_MINF_ATOM].buf = atom;
-
- return ngx_http_mp4_read_atom(mp4, ngx_http_mp4_minf_atoms, atom_data_size);
-}
-
-
-static void
-ngx_http_mp4_update_minf_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak)
-{
- ngx_buf_t *atom;
-
- trak->size += sizeof(ngx_mp4_atom_header_t)
- + trak->vmhd_size
- + trak->smhd_size
- + trak->dinf_size;
- atom = &trak->minf_atom_buf;
- ngx_mp4_set_32value(atom->pos, trak->size);
-}
-
-
-static ngx_int_t
-ngx_http_mp4_read_vmhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header;
- size_t atom_size;
- ngx_buf_t *atom;
- ngx_http_mp4_trak_t *trak;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 vmhd atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
- ngx_mp4_set_32value(atom_header, atom_size);
- ngx_mp4_set_atom_name(atom_header, 'v', 'm', 'h', 'd');
-
- trak = ngx_mp4_last_trak(mp4);
-
- atom = &trak->vmhd_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_header + atom_size;
-
- trak->vmhd_size += atom_size;
- trak->out[NGX_HTTP_MP4_VMHD_ATOM].buf = atom;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_read_smhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header;
- size_t atom_size;
- ngx_buf_t *atom;
- ngx_http_mp4_trak_t *trak;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 smhd atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
- ngx_mp4_set_32value(atom_header, atom_size);
- ngx_mp4_set_atom_name(atom_header, 's', 'm', 'h', 'd');
-
- trak = ngx_mp4_last_trak(mp4);
-
- atom = &trak->smhd_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_header + atom_size;
-
- trak->vmhd_size += atom_size;
- trak->out[NGX_HTTP_MP4_SMHD_ATOM].buf = atom;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_read_dinf_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header;
- size_t atom_size;
- ngx_buf_t *atom;
- ngx_http_mp4_trak_t *trak;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 dinf atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
- ngx_mp4_set_32value(atom_header, atom_size);
- ngx_mp4_set_atom_name(atom_header, 'd', 'i', 'n', 'f');
-
- trak = ngx_mp4_last_trak(mp4);
-
- atom = &trak->dinf_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_header + atom_size;
-
- trak->dinf_size += atom_size;
- trak->out[NGX_HTTP_MP4_DINF_ATOM].buf = atom;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_read_stbl_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header;
- ngx_buf_t *atom;
- ngx_http_mp4_trak_t *trak;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "process stbl atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- ngx_mp4_set_atom_name(atom_header, 's', 't', 'b', 'l');
-
- trak = ngx_mp4_last_trak(mp4);
-
- atom = &trak->stbl_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_header + sizeof(ngx_mp4_atom_header_t);
-
- trak->out[NGX_HTTP_MP4_STBL_ATOM].buf = atom;
-
- return ngx_http_mp4_read_atom(mp4, ngx_http_mp4_stbl_atoms, atom_data_size);
-}
-
-
-static void
-ngx_http_mp4_update_stbl_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak)
-{
- ngx_buf_t *atom;
-
- trak->size += sizeof(ngx_mp4_atom_header_t);
- atom = &trak->stbl_atom_buf;
- ngx_mp4_set_32value(atom->pos, trak->size);
-}
-
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char entries[4];
-
- u_char media_size[4];
- u_char media_name[4];
-} ngx_mp4_stsd_atom_t;
-
-
-static ngx_int_t
-ngx_http_mp4_read_stsd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header, *atom_table;
- size_t atom_size;
- ngx_buf_t *atom;
- ngx_mp4_stsd_atom_t *stsd_atom;
- ngx_http_mp4_trak_t *trak;
-
- /* sample description atom */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stsd atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- stsd_atom = (ngx_mp4_stsd_atom_t *) atom_header;
- atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
- atom_table = atom_header + atom_size;
- ngx_mp4_set_32value(stsd_atom->size, atom_size);
- ngx_mp4_set_atom_name(stsd_atom, 's', 't', 's', 'd');
-
- if (ngx_mp4_atom_data_size(ngx_mp4_stsd_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 stsd atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "stsd entries:%uD, media:%*s",
- ngx_mp4_get_32value(stsd_atom->entries),
- 4, stsd_atom->media_name);
-
- trak = ngx_mp4_last_trak(mp4);
-
- atom = &trak->stsd_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_table;
-
- trak->out[NGX_HTTP_MP4_STSD_ATOM].buf = atom;
- trak->size += atom_size;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char entries[4];
-} ngx_mp4_stts_atom_t;
-
-typedef struct {
- u_char count[4];
- u_char duration[4];
-} ngx_mp4_stts_entry_t;
-
-
-static ngx_int_t
-ngx_http_mp4_read_stts_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header, *atom_table, *atom_end;
- uint32_t entries;
- ngx_buf_t *atom, *data;
- ngx_mp4_stts_atom_t *stts_atom;
- ngx_http_mp4_trak_t *trak;
-
- /* time-to-sample atom */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stts atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- stts_atom = (ngx_mp4_stts_atom_t *) atom_header;
- ngx_mp4_set_atom_name(stts_atom, 's', 't', 't', 's');
-
- if (ngx_mp4_atom_data_size(ngx_mp4_stts_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 stts atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- entries = ngx_mp4_get_32value(stts_atom->entries);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 time-to-sample entries:%uD", entries);
-
- if (ngx_mp4_atom_data_size(ngx_mp4_stts_atom_t)
- + entries * sizeof(ngx_mp4_stts_entry_t) > atom_data_size)
- {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 stts atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- atom_table = atom_header + sizeof(ngx_mp4_stts_atom_t);
- atom_end = atom_table + entries * sizeof(ngx_mp4_stts_entry_t);
-
- trak = ngx_mp4_last_trak(mp4);
- trak->time_to_sample_entries = entries;
-
- atom = &trak->stts_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_table;
-
- data = &trak->stts_data_buf;
- data->temporary = 1;
- data->pos = atom_table;
- data->last = atom_end;
-
- trak->out[NGX_HTTP_MP4_STTS_ATOM].buf = atom;
- trak->out[NGX_HTTP_MP4_STTS_DATA].buf = data;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak)
-{
- size_t atom_size;
- ngx_buf_t *atom, *data;
- ngx_mp4_stts_atom_t *stts_atom;
-
- /*
- * mdia.minf.stbl.stts updating requires trak->timescale
- * from mdia.mdhd atom which may reside after mdia.minf
- */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 stts atom update");
-
- data = trak->out[NGX_HTTP_MP4_STTS_DATA].buf;
-
- if (data == NULL) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "no mp4 stts atoms were found in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- if (ngx_http_mp4_crop_stts_data(mp4, trak, 1) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (ngx_http_mp4_crop_stts_data(mp4, trak, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "time-to-sample entries:%uD", trak->time_to_sample_entries);
-
- atom_size = sizeof(ngx_mp4_stts_atom_t) + (data->last - data->pos);
- trak->size += atom_size;
-
- atom = trak->out[NGX_HTTP_MP4_STTS_ATOM].buf;
- stts_atom = (ngx_mp4_stts_atom_t *) atom->pos;
- ngx_mp4_set_32value(stts_atom->size, atom_size);
- ngx_mp4_set_32value(stts_atom->entries, trak->time_to_sample_entries);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_crop_stts_data(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak, ngx_uint_t start)
-{
- uint32_t count, duration, rest;
- uint64_t start_time;
- ngx_buf_t *data;
- ngx_uint_t start_sample, entries, start_sec;
- ngx_mp4_stts_entry_t *entry, *end;
-
- if (start) {
- start_sec = mp4->start;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 stts crop start_time:%ui", start_sec);
-
- } else if (mp4->length) {
- start_sec = mp4->length;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 stts crop end_time:%ui", start_sec);
-
- } else {
- return NGX_OK;
- }
-
- data = trak->out[NGX_HTTP_MP4_STTS_DATA].buf;
-
- start_time = (uint64_t) start_sec * trak->timescale / 1000;
-
- entries = trak->time_to_sample_entries;
- start_sample = 0;
- entry = (ngx_mp4_stts_entry_t *) data->pos;
- end = (ngx_mp4_stts_entry_t *) data->last;
-
- while (entry < end) {
- count = ngx_mp4_get_32value(entry->count);
- duration = ngx_mp4_get_32value(entry->duration);
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "time:%uL, count:%uD, duration:%uD",
- start_time, count, duration);
-
- if (start_time < (uint64_t) count * duration) {
- start_sample += (ngx_uint_t) (start_time / duration);
- rest = (uint32_t) (start_time / duration);
- goto found;
- }
-
- start_sample += count;
- start_time -= count * duration;
- entries--;
- entry++;
- }
-
- if (start) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "start time is out mp4 stts samples in \"%s\"",
- mp4->file.name.data);
-
- return NGX_ERROR;
-
- } else {
- trak->end_sample = trak->start_sample + start_sample;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "end_sample:%ui", trak->end_sample);
-
- return NGX_OK;
- }
-
-found:
-
- if (start) {
- ngx_mp4_set_32value(entry->count, count - rest);
- data->pos = (u_char *) entry;
- trak->time_to_sample_entries = entries;
- trak->start_sample = start_sample;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "start_sample:%ui, new count:%uD",
- trak->start_sample, count - rest);
-
- } else {
- ngx_mp4_set_32value(entry->count, rest);
- data->last = (u_char *) (entry + 1);
- trak->time_to_sample_entries -= entries - 1;
- trak->end_sample = trak->start_sample + start_sample;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "end_sample:%ui, new count:%uD",
- trak->end_sample, rest);
- }
-
- return NGX_OK;
-}
-
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char entries[4];
-} ngx_http_mp4_stss_atom_t;
-
-
-static ngx_int_t
-ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header, *atom_table, *atom_end;
- uint32_t entries;
- ngx_buf_t *atom, *data;
- ngx_http_mp4_trak_t *trak;
- ngx_http_mp4_stss_atom_t *stss_atom;
-
- /* sync samples atom */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stss atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- stss_atom = (ngx_http_mp4_stss_atom_t *) atom_header;
- ngx_mp4_set_atom_name(stss_atom, 's', 't', 's', 's');
-
- if (ngx_mp4_atom_data_size(ngx_http_mp4_stss_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 stss atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- entries = ngx_mp4_get_32value(stss_atom->entries);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "sync sample entries:%uD", entries);
-
- trak = ngx_mp4_last_trak(mp4);
- trak->sync_samples_entries = entries;
-
- atom_table = atom_header + sizeof(ngx_http_mp4_stss_atom_t);
-
- atom = &trak->stss_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_table;
-
- if (ngx_mp4_atom_data_size(ngx_http_mp4_stss_atom_t)
- + entries * sizeof(uint32_t) > atom_data_size)
- {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 stss atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- atom_end = atom_table + entries * sizeof(uint32_t);
-
- data = &trak->stss_data_buf;
- data->temporary = 1;
- data->pos = atom_table;
- data->last = atom_end;
-
- trak->out[NGX_HTTP_MP4_STSS_ATOM].buf = atom;
- trak->out[NGX_HTTP_MP4_STSS_DATA].buf = data;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_update_stss_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak)
-{
- size_t atom_size;
- uint32_t sample, start_sample, *entry, *end;
- ngx_buf_t *atom, *data;
- ngx_http_mp4_stss_atom_t *stss_atom;
-
- /*
- * mdia.minf.stbl.stss updating requires trak->start_sample
- * from mdia.minf.stbl.stts which depends on value from mdia.mdhd
- * atom which may reside after mdia.minf
- */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 stss atom update");
-
- data = trak->out[NGX_HTTP_MP4_STSS_DATA].buf;
-
- if (data == NULL) {
- return NGX_OK;
- }
-
- ngx_http_mp4_crop_stss_data(mp4, trak, 1);
- ngx_http_mp4_crop_stss_data(mp4, trak, 0);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "sync sample entries:%uD", trak->sync_samples_entries);
-
- if (trak->sync_samples_entries) {
- entry = (uint32_t *) data->pos;
- end = (uint32_t *) data->last;
-
- start_sample = trak->start_sample;
-
- while (entry < end) {
- sample = ngx_mp4_get_32value(entry);
- sample -= start_sample;
- ngx_mp4_set_32value(entry, sample);
- entry++;
- }
-
- } else {
- trak->out[NGX_HTTP_MP4_STSS_DATA].buf = NULL;
- }
-
- atom_size = sizeof(ngx_http_mp4_stss_atom_t) + (data->last - data->pos);
- trak->size += atom_size;
-
- atom = trak->out[NGX_HTTP_MP4_STSS_ATOM].buf;
- stss_atom = (ngx_http_mp4_stss_atom_t *) atom->pos;
-
- ngx_mp4_set_32value(stss_atom->size, atom_size);
- ngx_mp4_set_32value(stss_atom->entries, trak->sync_samples_entries);
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_mp4_crop_stss_data(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak, ngx_uint_t start)
-{
- uint32_t sample, start_sample, *entry, *end;
- ngx_buf_t *data;
- ngx_uint_t entries;
-
- /* sync samples starts from 1 */
-
- if (start) {
- start_sample = trak->start_sample + 1;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 stss crop start_sample:%uD", start_sample);
-
- } else if (mp4->length) {
- start_sample = trak->end_sample + 1;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 stss crop end_sample:%uD", start_sample);
-
- } else {
- return;
- }
-
- data = trak->out[NGX_HTTP_MP4_STSS_DATA].buf;
-
- entries = trak->sync_samples_entries;
- entry = (uint32_t *) data->pos;
- end = (uint32_t *) data->last;
-
- while (entry < end) {
- sample = ngx_mp4_get_32value(entry);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "sync:%uD", sample);
-
- if (sample >= start_sample) {
- goto found;
- }
-
- entries--;
- entry++;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "sample is out of mp4 stss atom");
-
-found:
-
- if (start) {
- data->pos = (u_char *) entry;
- trak->sync_samples_entries = entries;
-
- } else {
- data->last = (u_char *) entry;
- trak->sync_samples_entries -= entries;
- }
-}
-
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char entries[4];
-} ngx_mp4_ctts_atom_t;
-
-typedef struct {
- u_char count[4];
- u_char offset[4];
-} ngx_mp4_ctts_entry_t;
-
-
-static ngx_int_t
-ngx_http_mp4_read_ctts_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header, *atom_table, *atom_end;
- uint32_t entries;
- ngx_buf_t *atom, *data;
- ngx_mp4_ctts_atom_t *ctts_atom;
- ngx_http_mp4_trak_t *trak;
-
- /* composition offsets atom */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 ctts atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- ctts_atom = (ngx_mp4_ctts_atom_t *) atom_header;
- ngx_mp4_set_atom_name(ctts_atom, 'c', 't', 't', 's');
-
- if (ngx_mp4_atom_data_size(ngx_mp4_ctts_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 ctts atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- entries = ngx_mp4_get_32value(ctts_atom->entries);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "composition offset entries:%uD", entries);
-
- trak = ngx_mp4_last_trak(mp4);
- trak->composition_offset_entries = entries;
-
- atom_table = atom_header + sizeof(ngx_mp4_ctts_atom_t);
-
- atom = &trak->ctts_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_table;
-
- if (ngx_mp4_atom_data_size(ngx_mp4_ctts_atom_t)
- + entries * sizeof(ngx_mp4_ctts_entry_t) > atom_data_size)
- {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 ctts atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- atom_end = atom_table + entries * sizeof(ngx_mp4_ctts_entry_t);
-
- data = &trak->ctts_data_buf;
- data->temporary = 1;
- data->pos = atom_table;
- data->last = atom_end;
-
- trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf = atom;
- trak->out[NGX_HTTP_MP4_CTTS_DATA].buf = data;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_mp4_update_ctts_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak)
-{
- size_t atom_size;
- ngx_buf_t *atom, *data;
- ngx_mp4_ctts_atom_t *ctts_atom;
-
- /*
- * mdia.minf.stbl.ctts updating requires trak->start_sample
- * from mdia.minf.stbl.stts which depends on value from mdia.mdhd
- * atom which may reside after mdia.minf
- */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 ctts atom update");
-
- data = trak->out[NGX_HTTP_MP4_CTTS_DATA].buf;
-
- if (data == NULL) {
- return;
- }
-
- ngx_http_mp4_crop_ctts_data(mp4, trak, 1);
- ngx_http_mp4_crop_ctts_data(mp4, trak, 0);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "composition offset entries:%uD",
- trak->composition_offset_entries);
-
- if (trak->composition_offset_entries == 0) {
- trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf = NULL;
- trak->out[NGX_HTTP_MP4_CTTS_DATA].buf = NULL;
- return;
- }
-
- atom_size = sizeof(ngx_mp4_ctts_atom_t) + (data->last - data->pos);
- trak->size += atom_size;
-
- atom = trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf;
- ctts_atom = (ngx_mp4_ctts_atom_t *) atom->pos;
-
- ngx_mp4_set_32value(ctts_atom->size, atom_size);
- ngx_mp4_set_32value(ctts_atom->entries, trak->composition_offset_entries);
-
- return;
-}
-
-
-static void
-ngx_http_mp4_crop_ctts_data(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak, ngx_uint_t start)
-{
- uint32_t count, start_sample, rest;
- ngx_buf_t *data;
- ngx_uint_t entries;
- ngx_mp4_ctts_entry_t *entry, *end;
-
- /* sync samples starts from 1 */
-
- if (start) {
- start_sample = trak->start_sample + 1;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 ctts crop start_sample:%uD", start_sample);
-
- } else if (mp4->length) {
- start_sample = trak->end_sample - trak->start_sample + 1;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 ctts crop end_sample:%uD", start_sample);
-
- } else {
- return;
- }
-
- data = trak->out[NGX_HTTP_MP4_CTTS_DATA].buf;
-
- entries = trak->composition_offset_entries;
- entry = (ngx_mp4_ctts_entry_t *) data->pos;
- end = (ngx_mp4_ctts_entry_t *) data->last;
-
- while (entry < end) {
- count = ngx_mp4_get_32value(entry->count);
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "sample:%uD, count:%uD, offset:%uD",
- start_sample, count, ngx_mp4_get_32value(entry->offset));
-
- if (start_sample <= count) {
- rest = start_sample - 1;
- goto found;
- }
-
- start_sample -= count;
- entries--;
- entry++;
- }
-
- if (start) {
- data->pos = (u_char *) end;
- trak->composition_offset_entries = 0;
- }
-
- return;
-
-found:
-
- if (start) {
- ngx_mp4_set_32value(entry->count, count - rest);
- data->pos = (u_char *) entry;
- trak->composition_offset_entries = entries;
-
- } else {
- ngx_mp4_set_32value(entry->count, rest);
- data->last = (u_char *) (entry + 1);
- trak->composition_offset_entries -= entries - 1;
- }
-}
-
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char entries[4];
-} ngx_mp4_stsc_atom_t;
-
-
-static ngx_int_t
-ngx_http_mp4_read_stsc_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header, *atom_table, *atom_end;
- uint32_t entries;
- ngx_buf_t *atom, *data;
- ngx_mp4_stsc_atom_t *stsc_atom;
- ngx_http_mp4_trak_t *trak;
-
- /* sample-to-chunk atom */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stsc atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- stsc_atom = (ngx_mp4_stsc_atom_t *) atom_header;
- ngx_mp4_set_atom_name(stsc_atom, 's', 't', 's', 'c');
-
- if (ngx_mp4_atom_data_size(ngx_mp4_stsc_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 stsc atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- entries = ngx_mp4_get_32value(stsc_atom->entries);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "sample-to-chunk entries:%uD", entries);
-
- if (ngx_mp4_atom_data_size(ngx_mp4_stsc_atom_t)
- + entries * sizeof(ngx_mp4_stsc_entry_t) > atom_data_size)
- {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 stsc atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- atom_table = atom_header + sizeof(ngx_mp4_stsc_atom_t);
- atom_end = atom_table + entries * sizeof(ngx_mp4_stsc_entry_t);
-
- trak = ngx_mp4_last_trak(mp4);
- trak->sample_to_chunk_entries = entries;
-
- atom = &trak->stsc_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_table;
-
- data = &trak->stsc_data_buf;
- data->temporary = 1;
- data->pos = atom_table;
- data->last = atom_end;
-
- trak->out[NGX_HTTP_MP4_STSC_ATOM].buf = atom;
- trak->out[NGX_HTTP_MP4_STSC_DATA].buf = data;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_update_stsc_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak)
-{
- size_t atom_size;
- uint32_t chunk;
- ngx_buf_t *atom, *data;
- ngx_mp4_stsc_atom_t *stsc_atom;
- ngx_mp4_stsc_entry_t *entry, *end;
-
- /*
- * mdia.minf.stbl.stsc updating requires trak->start_sample
- * from mdia.minf.stbl.stts which depends on value from mdia.mdhd
- * atom which may reside after mdia.minf
- */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 stsc atom update");
-
- data = trak->out[NGX_HTTP_MP4_STSC_DATA].buf;
-
- if (data == NULL) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "no mp4 stsc atoms were found in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- if (trak->sample_to_chunk_entries == 0) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "zero number of entries in stsc atom in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- if (ngx_http_mp4_crop_stsc_data(mp4, trak, 1) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (ngx_http_mp4_crop_stsc_data(mp4, trak, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "sample-to-chunk entries:%uD",
- trak->sample_to_chunk_entries);
-
- entry = (ngx_mp4_stsc_entry_t *) data->pos;
- end = (ngx_mp4_stsc_entry_t *) data->last;
-
- while (entry < end) {
- chunk = ngx_mp4_get_32value(entry->chunk);
- chunk -= trak->start_chunk;
- ngx_mp4_set_32value(entry->chunk, chunk);
- entry++;
- }
-
- atom_size = sizeof(ngx_mp4_stsc_atom_t)
- + trak->sample_to_chunk_entries * sizeof(ngx_mp4_stsc_entry_t);
-
- trak->size += atom_size;
-
- atom = trak->out[NGX_HTTP_MP4_STSC_ATOM].buf;
- stsc_atom = (ngx_mp4_stsc_atom_t *) atom->pos;
-
- ngx_mp4_set_32value(stsc_atom->size, atom_size);
- ngx_mp4_set_32value(stsc_atom->entries, trak->sample_to_chunk_entries);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak, ngx_uint_t start)
-{
- uint32_t start_sample, chunk, samples, id, next_chunk, n,
- prev_samples;
- ngx_buf_t *data, *buf;
- ngx_uint_t entries, target_chunk, chunk_samples;
- ngx_mp4_stsc_entry_t *entry, *end, *first;
-
- entries = trak->sample_to_chunk_entries - 1;
-
- if (start) {
- start_sample = (uint32_t) trak->start_sample;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 stsc crop start_sample:%uD", start_sample);
-
- } else if (mp4->length) {
- start_sample = (uint32_t) (trak->end_sample - trak->start_sample);
- samples = 0;
-
- data = trak->out[NGX_HTTP_MP4_STSC_START].buf;
-
- if (data) {
- entry = (ngx_mp4_stsc_entry_t *) data->pos;
- samples = ngx_mp4_get_32value(entry->samples);
- entries--;
-
- if (samples > start_sample) {
- samples = start_sample;
- ngx_mp4_set_32value(entry->samples, samples);
- }
-
- start_sample -= samples;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 stsc crop end_sample:%uD, ext_samples:%uD",
- start_sample, samples);
-
- } else {
- return NGX_OK;
- }
-
- data = trak->out[NGX_HTTP_MP4_STSC_DATA].buf;
-
- entry = (ngx_mp4_stsc_entry_t *) data->pos;
- end = (ngx_mp4_stsc_entry_t *) data->last;
-
- chunk = ngx_mp4_get_32value(entry->chunk);
- samples = ngx_mp4_get_32value(entry->samples);
- id = ngx_mp4_get_32value(entry->id);
- prev_samples = 0;
- entry++;
-
- while (entry < end) {
-
- next_chunk = ngx_mp4_get_32value(entry->chunk);
-
- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "sample:%uD, chunk:%uD, chunks:%uD, "
- "samples:%uD, id:%uD",
- start_sample, chunk, next_chunk - chunk, samples, id);
-
- n = (next_chunk - chunk) * samples;
-
- if (start_sample < n) {
- goto found;
- }
-
- start_sample -= n;
-
- prev_samples = samples;
- chunk = next_chunk;
- samples = ngx_mp4_get_32value(entry->samples);
- id = ngx_mp4_get_32value(entry->id);
- entries--;
- entry++;
- }
-
- next_chunk = trak->chunks + 1;
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "sample:%uD, chunk:%uD, chunks:%uD, samples:%uD",
- start_sample, chunk, next_chunk - chunk, samples);
-
- n = (next_chunk - chunk) * samples;
-
- if (start_sample > n) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "%s time is out mp4 stsc chunks in \"%s\"",
- start ? "start" : "end", mp4->file.name.data);
- return NGX_ERROR;
- }
-
-found:
-
- entries++;
- entry--;
-
- if (samples == 0) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "zero number of samples in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- target_chunk = chunk - 1;
- target_chunk += start_sample / samples;
- chunk_samples = start_sample % samples;
-
- if (start) {
- data->pos = (u_char *) entry;
-
- trak->sample_to_chunk_entries = entries;
- trak->start_chunk = target_chunk;
- trak->start_chunk_samples = chunk_samples;
-
- ngx_mp4_set_32value(entry->chunk, trak->start_chunk + 1);
-
- samples -= chunk_samples;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "start_chunk:%ui, start_chunk_samples:%ui",
- trak->start_chunk, trak->start_chunk_samples);
-
- } else {
- if (start_sample) {
- data->last = (u_char *) (entry + 1);
- trak->sample_to_chunk_entries -= entries - 1;
- trak->end_chunk_samples = samples;
-
- } else {
- data->last = (u_char *) entry;
- trak->sample_to_chunk_entries -= entries;
- trak->end_chunk_samples = prev_samples;
- }
-
- if (chunk_samples) {
- trak->end_chunk = target_chunk + 1;
- trak->end_chunk_samples = chunk_samples;
-
- } else {
- trak->end_chunk = target_chunk;
- }
-
- samples = chunk_samples;
- next_chunk = chunk + 1;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "end_chunk:%ui, end_chunk_samples:%ui",
- trak->end_chunk, trak->end_chunk_samples);
- }
-
- if (chunk_samples && next_chunk - target_chunk == 2) {
-
- ngx_mp4_set_32value(entry->samples, samples);
-
- } else if (chunk_samples && start) {
-
- first = &trak->stsc_start_chunk_entry;
- ngx_mp4_set_32value(first->chunk, 1);
- ngx_mp4_set_32value(first->samples, samples);
- ngx_mp4_set_32value(first->id, id);
-
- buf = &trak->stsc_start_chunk_buf;
- buf->temporary = 1;
- buf->pos = (u_char *) first;
- buf->last = (u_char *) first + sizeof(ngx_mp4_stsc_entry_t);
-
- trak->out[NGX_HTTP_MP4_STSC_START].buf = buf;
-
- ngx_mp4_set_32value(entry->chunk, trak->start_chunk + 2);
-
- trak->sample_to_chunk_entries++;
-
- } else if (chunk_samples) {
-
- first = &trak->stsc_end_chunk_entry;
- ngx_mp4_set_32value(first->chunk, trak->end_chunk - trak->start_chunk);
- ngx_mp4_set_32value(first->samples, samples);
- ngx_mp4_set_32value(first->id, id);
-
- buf = &trak->stsc_end_chunk_buf;
- buf->temporary = 1;
- buf->pos = (u_char *) first;
- buf->last = (u_char *) first + sizeof(ngx_mp4_stsc_entry_t);
-
- trak->out[NGX_HTTP_MP4_STSC_END].buf = buf;
-
- trak->sample_to_chunk_entries++;
- }
-
- return NGX_OK;
-}
-
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char uniform_size[4];
- u_char entries[4];
-} ngx_mp4_stsz_atom_t;
-
-
-static ngx_int_t
-ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header, *atom_table, *atom_end;
- size_t atom_size;
- uint32_t entries, size;
- ngx_buf_t *atom, *data;
- ngx_mp4_stsz_atom_t *stsz_atom;
- ngx_http_mp4_trak_t *trak;
-
- /* sample sizes atom */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stsz atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- stsz_atom = (ngx_mp4_stsz_atom_t *) atom_header;
- ngx_mp4_set_atom_name(stsz_atom, 's', 't', 's', 'z');
-
- if (ngx_mp4_atom_data_size(ngx_mp4_stsz_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 stsz atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- size = ngx_mp4_get_32value(stsz_atom->uniform_size);
- entries = ngx_mp4_get_32value(stsz_atom->entries);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "sample uniform size:%uD, entries:%uD", size, entries);
-
- trak = ngx_mp4_last_trak(mp4);
- trak->sample_sizes_entries = entries;
-
- atom_table = atom_header + sizeof(ngx_mp4_stsz_atom_t);
-
- atom = &trak->stsz_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_table;
-
- trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf = atom;
-
- if (size == 0) {
- if (ngx_mp4_atom_data_size(ngx_mp4_stsz_atom_t)
- + entries * sizeof(uint32_t) > atom_data_size)
- {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 stsz atom too small",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- atom_end = atom_table + entries * sizeof(uint32_t);
-
- data = &trak->stsz_data_buf;
- data->temporary = 1;
- data->pos = atom_table;
- data->last = atom_end;
-
- trak->out[NGX_HTTP_MP4_STSZ_DATA].buf = data;
-
- } else {
- /* if size != 0 then all samples are the same size */
- /* TODO : chunk samples */
- atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size;
- ngx_mp4_set_32value(atom_header, atom_size);
- trak->size += atom_size;
- }
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_update_stsz_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak)
-{
- size_t atom_size;
- uint32_t *pos, *end, entries;
- ngx_buf_t *atom, *data;
- ngx_mp4_stsz_atom_t *stsz_atom;
-
- /*
- * mdia.minf.stbl.stsz updating requires trak->start_sample
- * from mdia.minf.stbl.stts which depends on value from mdia.mdhd
- * atom which may reside after mdia.minf
- */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 stsz atom update");
-
- data = trak->out[NGX_HTTP_MP4_STSZ_DATA].buf;
-
- if (data) {
- entries = trak->sample_sizes_entries;
-
- if (trak->start_sample > entries) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "start time is out mp4 stsz samples in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- entries -= trak->start_sample;
- data->pos += trak->start_sample * sizeof(uint32_t);
- end = (uint32_t *) data->pos;
-
- for (pos = end - trak->start_chunk_samples; pos < end; pos++) {
- trak->start_chunk_samples_size += ngx_mp4_get_32value(pos);
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "chunk samples sizes:%uL",
- trak->start_chunk_samples_size);
-
- if (mp4->length) {
- if (trak->end_sample - trak->start_sample > entries) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "end time is out mp4 stsz samples in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- entries = trak->end_sample - trak->start_sample;
- data->last = data->pos + entries * sizeof(uint32_t);
- end = (uint32_t *) data->last;
-
- for (pos = end - trak->end_chunk_samples; pos < end; pos++) {
- trak->end_chunk_samples_size += ngx_mp4_get_32value(pos);
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 stsz end_chunk_samples_size:%uL",
- trak->end_chunk_samples_size);
- }
-
- atom_size = sizeof(ngx_mp4_stsz_atom_t) + (data->last - data->pos);
- trak->size += atom_size;
-
- atom = trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf;
- stsz_atom = (ngx_mp4_stsz_atom_t *) atom->pos;
-
- ngx_mp4_set_32value(stsz_atom->size, atom_size);
- ngx_mp4_set_32value(stsz_atom->entries, entries);
- }
-
- return NGX_OK;
-}
-
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char entries[4];
-} ngx_mp4_stco_atom_t;
-
-
-static ngx_int_t
-ngx_http_mp4_read_stco_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header, *atom_table, *atom_end;
- uint32_t entries;
- ngx_buf_t *atom, *data;
- ngx_mp4_stco_atom_t *stco_atom;
- ngx_http_mp4_trak_t *trak;
-
- /* chunk offsets atom */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 stco atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- stco_atom = (ngx_mp4_stco_atom_t *) atom_header;
- ngx_mp4_set_atom_name(stco_atom, 's', 't', 'c', 'o');
-
- if (ngx_mp4_atom_data_size(ngx_mp4_stco_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 stco atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- entries = ngx_mp4_get_32value(stco_atom->entries);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", entries);
-
- if (ngx_mp4_atom_data_size(ngx_mp4_stco_atom_t)
- + entries * sizeof(uint32_t) > atom_data_size)
- {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 stco atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- atom_table = atom_header + sizeof(ngx_mp4_stco_atom_t);
- atom_end = atom_table + entries * sizeof(uint32_t);
-
- trak = ngx_mp4_last_trak(mp4);
- trak->chunks = entries;
-
- atom = &trak->stco_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_table;
-
- data = &trak->stco_data_buf;
- data->temporary = 1;
- data->pos = atom_table;
- data->last = atom_end;
-
- trak->out[NGX_HTTP_MP4_STCO_ATOM].buf = atom;
- trak->out[NGX_HTTP_MP4_STCO_DATA].buf = data;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_update_stco_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak)
-{
- size_t atom_size;
- uint32_t entries;
- ngx_buf_t *atom, *data;
- ngx_mp4_stco_atom_t *stco_atom;
-
- /*
- * mdia.minf.stbl.stco updating requires trak->start_chunk
- * from mdia.minf.stbl.stsc which depends on value from mdia.mdhd
- * atom which may reside after mdia.minf
- */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 stco atom update");
-
- data = trak->out[NGX_HTTP_MP4_STCO_DATA].buf;
-
- if (data == NULL) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "no mp4 stco atoms were found in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- if (trak->start_chunk > trak->chunks) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "start time is out mp4 stco chunks in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- data->pos += trak->start_chunk * sizeof(uint32_t);
-
- trak->start_offset = ngx_mp4_get_32value(data->pos);
- trak->start_offset += trak->start_chunk_samples_size;
- ngx_mp4_set_32value(data->pos, trak->start_offset);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "start chunk offset:%O", trak->start_offset);
-
- if (mp4->length) {
-
- if (trak->end_chunk > trak->chunks) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "end time is out mp4 stco chunks in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- entries = trak->end_chunk - trak->start_chunk;
- data->last = data->pos + entries * sizeof(uint32_t);
-
- if (entries) {
- trak->end_offset =
- ngx_mp4_get_32value(data->last - sizeof(uint32_t));
- trak->end_offset += trak->end_chunk_samples_size;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "end chunk offset:%O", trak->end_offset);
- }
-
- } else {
- entries = trak->chunks - trak->start_chunk;
- trak->end_offset = mp4->mdat_data.buf->file_last;
- }
-
- if (entries == 0) {
- trak->start_offset = mp4->end;
- trak->end_offset = 0;
- }
-
- atom_size = sizeof(ngx_mp4_stco_atom_t) + (data->last - data->pos);
- trak->size += atom_size;
-
- atom = trak->out[NGX_HTTP_MP4_STCO_ATOM].buf;
- stco_atom = (ngx_mp4_stco_atom_t *) atom->pos;
-
- ngx_mp4_set_32value(stco_atom->size, atom_size);
- ngx_mp4_set_32value(stco_atom->entries, entries);
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_mp4_adjust_stco_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak, int32_t adjustment)
-{
- uint32_t offset, *entry, *end;
- ngx_buf_t *data;
-
- /*
- * moov.trak.mdia.minf.stbl.stco adjustment requires
- * minimal start offset of all traks and new moov atom size
- */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 stco atom adjustment");
-
- data = trak->out[NGX_HTTP_MP4_STCO_DATA].buf;
- entry = (uint32_t *) data->pos;
- end = (uint32_t *) data->last;
-
- while (entry < end) {
- offset = ngx_mp4_get_32value(entry);
- offset += adjustment;
- ngx_mp4_set_32value(entry, offset);
- entry++;
- }
-}
-
-
-typedef struct {
- u_char size[4];
- u_char name[4];
- u_char version[1];
- u_char flags[3];
- u_char entries[4];
-} ngx_mp4_co64_atom_t;
-
-
-static ngx_int_t
-ngx_http_mp4_read_co64_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
-{
- u_char *atom_header, *atom_table, *atom_end;
- uint32_t entries;
- ngx_buf_t *atom, *data;
- ngx_mp4_co64_atom_t *co64_atom;
- ngx_http_mp4_trak_t *trak;
-
- /* chunk offsets atom */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 co64 atom");
-
- atom_header = ngx_mp4_atom_header(mp4);
- co64_atom = (ngx_mp4_co64_atom_t *) atom_header;
- ngx_mp4_set_atom_name(co64_atom, 'c', 'o', '6', '4');
-
- if (ngx_mp4_atom_data_size(ngx_mp4_co64_atom_t) > atom_data_size) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 co64 atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- entries = ngx_mp4_get_32value(co64_atom->entries);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", entries);
-
- if (ngx_mp4_atom_data_size(ngx_mp4_co64_atom_t)
- + entries * sizeof(uint64_t) > atom_data_size)
- {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "\"%s\" mp4 co64 atom too small", mp4->file.name.data);
- return NGX_ERROR;
- }
-
- atom_table = atom_header + sizeof(ngx_mp4_co64_atom_t);
- atom_end = atom_table + entries * sizeof(uint64_t);
-
- trak = ngx_mp4_last_trak(mp4);
- trak->chunks = entries;
-
- atom = &trak->co64_atom_buf;
- atom->temporary = 1;
- atom->pos = atom_header;
- atom->last = atom_table;
-
- data = &trak->co64_data_buf;
- data->temporary = 1;
- data->pos = atom_table;
- data->last = atom_end;
-
- trak->out[NGX_HTTP_MP4_CO64_ATOM].buf = atom;
- trak->out[NGX_HTTP_MP4_CO64_DATA].buf = data;
-
- ngx_mp4_atom_next(mp4, atom_data_size);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_mp4_update_co64_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak)
-{
- size_t atom_size;
- uint64_t entries;
- ngx_buf_t *atom, *data;
- ngx_mp4_co64_atom_t *co64_atom;
-
- /*
- * mdia.minf.stbl.co64 updating requires trak->start_chunk
- * from mdia.minf.stbl.stsc which depends on value from mdia.mdhd
- * atom which may reside after mdia.minf
- */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 co64 atom update");
-
- data = trak->out[NGX_HTTP_MP4_CO64_DATA].buf;
-
- if (data == NULL) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "no mp4 co64 atoms were found in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- if (trak->start_chunk > trak->chunks) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "start time is out mp4 co64 chunks in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- data->pos += trak->start_chunk * sizeof(uint64_t);
-
- trak->start_offset = ngx_mp4_get_64value(data->pos);
- trak->start_offset += trak->start_chunk_samples_size;
- ngx_mp4_set_64value(data->pos, trak->start_offset);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "start chunk offset:%O", trak->start_offset);
-
- if (mp4->length) {
-
- if (trak->end_chunk > trak->chunks) {
- ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
- "end time is out mp4 co64 chunks in \"%s\"",
- mp4->file.name.data);
- return NGX_ERROR;
- }
-
- entries = trak->end_chunk - trak->start_chunk;
- data->last = data->pos + entries * sizeof(uint64_t);
-
- if (entries) {
- trak->end_offset =
- ngx_mp4_get_64value(data->last - sizeof(uint64_t));
- trak->end_offset += trak->end_chunk_samples_size;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "end chunk offset:%O", trak->end_offset);
- }
-
- } else {
- entries = trak->chunks - trak->start_chunk;
- trak->end_offset = mp4->mdat_data.buf->file_last;
- }
-
- if (entries == 0) {
- trak->start_offset = mp4->end;
- trak->end_offset = 0;
- }
-
- atom_size = sizeof(ngx_mp4_co64_atom_t) + (data->last - data->pos);
- trak->size += atom_size;
-
- atom = trak->out[NGX_HTTP_MP4_CO64_ATOM].buf;
- co64_atom = (ngx_mp4_co64_atom_t *) atom->pos;
-
- ngx_mp4_set_32value(co64_atom->size, atom_size);
- ngx_mp4_set_32value(co64_atom->entries, entries);
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_mp4_adjust_co64_atom(ngx_http_mp4_file_t *mp4,
- ngx_http_mp4_trak_t *trak, off_t adjustment)
-{
- uint64_t offset, *entry, *end;
- ngx_buf_t *data;
-
- /*
- * moov.trak.mdia.minf.stbl.co64 adjustment requires
- * minimal start offset of all traks and new moov atom size
- */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
- "mp4 co64 atom adjustment");
-
- data = trak->out[NGX_HTTP_MP4_CO64_DATA].buf;
- entry = (uint64_t *) data->pos;
- end = (uint64_t *) data->last;
-
- while (entry < end) {
- offset = ngx_mp4_get_64value(entry);
- offset += adjustment;
- ngx_mp4_set_64value(entry, offset);
- entry++;
- }
-}
-
-
-static char *
-ngx_http_mp4(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
- clcf->handler = ngx_http_mp4_handler;
-
- return NGX_CONF_OK;
-}
-
-
-static void *
-ngx_http_mp4_create_conf(ngx_conf_t *cf)
-{
- ngx_http_mp4_conf_t *conf;
-
- conf = ngx_palloc(cf->pool, sizeof(ngx_http_mp4_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- conf->buffer_size = NGX_CONF_UNSET_SIZE;
- conf->max_buffer_size = NGX_CONF_UNSET_SIZE;
-
- return conf;
-}
-
-
-static char *
-ngx_http_mp4_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_mp4_conf_t *prev = parent;
- ngx_http_mp4_conf_t *conf = child;
-
- ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, 512 * 1024);
- ngx_conf_merge_size_value(conf->max_buffer_size, prev->max_buffer_size,
- 10 * 1024 * 1024);
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_not_modified_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_not_modified_filter_module.c
deleted file mode 100644
index 7f1ab623694..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_not_modified_filter_module.c
+++ /dev/null
@@ -1,240 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static ngx_uint_t ngx_http_test_if_unmodified(ngx_http_request_t *r);
-static ngx_uint_t ngx_http_test_if_modified(ngx_http_request_t *r);
-static ngx_uint_t ngx_http_test_if_match(ngx_http_request_t *r,
- ngx_table_elt_t *header);
-static ngx_int_t ngx_http_not_modified_filter_init(ngx_conf_t *cf);
-
-
-static ngx_http_module_t ngx_http_not_modified_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_not_modified_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_not_modified_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_not_modified_filter_module_ctx, /* module context */
- NULL, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-
-
-static ngx_int_t
-ngx_http_not_modified_header_filter(ngx_http_request_t *r)
-{
- if (r->headers_out.status != NGX_HTTP_OK
- || r != r->main
- || r->headers_out.last_modified_time == -1)
- {
- return ngx_http_next_header_filter(r);
- }
-
- if (r->headers_in.if_unmodified_since
- && !ngx_http_test_if_unmodified(r))
- {
- return ngx_http_filter_finalize_request(r, NULL,
- NGX_HTTP_PRECONDITION_FAILED);
- }
-
- if (r->headers_in.if_match
- && !ngx_http_test_if_match(r, r->headers_in.if_match))
- {
- return ngx_http_filter_finalize_request(r, NULL,
- NGX_HTTP_PRECONDITION_FAILED);
- }
-
- if (r->headers_in.if_modified_since || r->headers_in.if_none_match) {
-
- if (r->headers_in.if_modified_since
- && ngx_http_test_if_modified(r))
- {
- return ngx_http_next_header_filter(r);
- }
-
- if (r->headers_in.if_none_match
- && !ngx_http_test_if_match(r, r->headers_in.if_none_match))
- {
- return ngx_http_next_header_filter(r);
- }
-
- /* not modified */
-
- r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
- r->headers_out.status_line.len = 0;
- r->headers_out.content_type.len = 0;
- ngx_http_clear_content_length(r);
- ngx_http_clear_accept_ranges(r);
-
- if (r->headers_out.content_encoding) {
- r->headers_out.content_encoding->hash = 0;
- r->headers_out.content_encoding = NULL;
- }
-
- return ngx_http_next_header_filter(r);
- }
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_uint_t
-ngx_http_test_if_unmodified(ngx_http_request_t *r)
-{
- time_t iums;
-
- iums = ngx_http_parse_time(r->headers_in.if_unmodified_since->value.data,
- r->headers_in.if_unmodified_since->value.len);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http iums:%d lm:%d", iums, r->headers_out.last_modified_time);
-
- if (iums >= r->headers_out.last_modified_time) {
- return 1;
- }
-
- return 0;
-}
-
-
-static ngx_uint_t
-ngx_http_test_if_modified(ngx_http_request_t *r)
-{
- time_t ims;
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->if_modified_since == NGX_HTTP_IMS_OFF) {
- return 1;
- }
-
- ims = ngx_http_parse_time(r->headers_in.if_modified_since->value.data,
- r->headers_in.if_modified_since->value.len);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http ims:%d lm:%d", ims, r->headers_out.last_modified_time);
-
- if (ims == r->headers_out.last_modified_time) {
- return 0;
- }
-
- if (clcf->if_modified_since == NGX_HTTP_IMS_EXACT
- || ims < r->headers_out.last_modified_time)
- {
- return 1;
- }
-
- return 0;
-}
-
-
-static ngx_uint_t
-ngx_http_test_if_match(ngx_http_request_t *r, ngx_table_elt_t *header)
-{
- u_char *start, *end, ch;
- ngx_str_t *etag, *list;
-
- list = &header->value;
-
- if (list->len == 1 && list->data[0] == '*') {
- return 1;
- }
-
- if (r->headers_out.etag == NULL) {
- return 0;
- }
-
- etag = &r->headers_out.etag->value;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http im:\"%V\" etag:%V", list, etag);
-
- start = list->data;
- end = list->data + list->len;
-
- while (start < end) {
-
- if (etag->len > (size_t) (end - start)) {
- return 0;
- }
-
- if (ngx_strncmp(start, etag->data, etag->len) != 0) {
- goto skip;
- }
-
- start += etag->len;
-
- while (start < end) {
- ch = *start;
-
- if (ch == ' ' || ch == '\t') {
- start++;
- continue;
- }
-
- break;
- }
-
- if (start == end || *start == ',') {
- return 1;
- }
-
- skip:
-
- while (start < end && *start != ',') { start++; }
- while (start < end) {
- ch = *start;
-
- if (ch == ' ' || ch == '\t' || ch == ',') {
- start++;
- continue;
- }
-
- break;
- }
- }
-
- return 0;
-}
-
-
-static ngx_int_t
-ngx_http_not_modified_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_not_modified_header_filter;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_proxy_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_proxy_module.c
deleted file mode 100644
index 8ee32f491a1..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_proxy_module.c
+++ /dev/null
@@ -1,3832 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct ngx_http_proxy_rewrite_s ngx_http_proxy_rewrite_t;
-
-typedef ngx_int_t (*ngx_http_proxy_rewrite_pt)(ngx_http_request_t *r,
- ngx_table_elt_t *h, size_t prefix, size_t len,
- ngx_http_proxy_rewrite_t *pr);
-
-struct ngx_http_proxy_rewrite_s {
- ngx_http_proxy_rewrite_pt handler;
-
- union {
- ngx_http_complex_value_t complex;
-#if (NGX_PCRE)
- ngx_http_regex_t *regex;
-#endif
- } pattern;
-
- ngx_http_complex_value_t replacement;
-};
-
-
-typedef struct {
- ngx_str_t key_start;
- ngx_str_t schema;
- ngx_str_t host_header;
- ngx_str_t port;
- ngx_str_t uri;
-} ngx_http_proxy_vars_t;
-
-
-typedef struct {
- ngx_http_upstream_conf_t upstream;
-
- ngx_array_t *flushes;
- ngx_array_t *body_set_len;
- ngx_array_t *body_set;
- ngx_array_t *headers_set_len;
- ngx_array_t *headers_set;
- ngx_hash_t headers_set_hash;
-
- ngx_array_t *headers_source;
-
- ngx_array_t *proxy_lengths;
- ngx_array_t *proxy_values;
-
- ngx_array_t *redirects;
- ngx_array_t *cookie_domains;
- ngx_array_t *cookie_paths;
-
- ngx_str_t body_source;
-
- ngx_str_t method;
- ngx_str_t location;
- ngx_str_t url;
-
-#if (NGX_HTTP_CACHE)
- ngx_http_complex_value_t cache_key;
-#endif
-
- ngx_http_proxy_vars_t vars;
-
- ngx_flag_t redirect;
-
- ngx_uint_t http_version;
-
- ngx_uint_t headers_hash_max_size;
- ngx_uint_t headers_hash_bucket_size;
-
-#if (NGX_HTTP_SSL)
- ngx_uint_t ssl;
- ngx_uint_t ssl_protocols;
- ngx_str_t ssl_ciphers;
-#endif
-} ngx_http_proxy_loc_conf_t;
-
-
-typedef struct {
- ngx_http_status_t status;
- ngx_http_chunked_t chunked;
- ngx_http_proxy_vars_t vars;
- off_t internal_body_length;
-
- ngx_uint_t head; /* unsigned head:1 */
-} ngx_http_proxy_ctx_t;
-
-
-static ngx_int_t ngx_http_proxy_eval(ngx_http_request_t *r,
- ngx_http_proxy_ctx_t *ctx, ngx_http_proxy_loc_conf_t *plcf);
-#if (NGX_HTTP_CACHE)
-static ngx_int_t ngx_http_proxy_create_key(ngx_http_request_t *r);
-#endif
-static ngx_int_t ngx_http_proxy_create_request(ngx_http_request_t *r);
-static ngx_int_t ngx_http_proxy_reinit_request(ngx_http_request_t *r);
-static ngx_int_t ngx_http_proxy_process_status_line(ngx_http_request_t *r);
-static ngx_int_t ngx_http_proxy_process_header(ngx_http_request_t *r);
-static ngx_int_t ngx_http_proxy_input_filter_init(void *data);
-static ngx_int_t ngx_http_proxy_copy_filter(ngx_event_pipe_t *p,
- ngx_buf_t *buf);
-static ngx_int_t ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p,
- ngx_buf_t *buf);
-static ngx_int_t ngx_http_proxy_non_buffered_copy_filter(void *data,
- ssize_t bytes);
-static ngx_int_t ngx_http_proxy_non_buffered_chunked_filter(void *data,
- ssize_t bytes);
-static void ngx_http_proxy_abort_request(ngx_http_request_t *r);
-static void ngx_http_proxy_finalize_request(ngx_http_request_t *r,
- ngx_int_t rc);
-
-static ngx_int_t ngx_http_proxy_host_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_proxy_port_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t
- ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t
- ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r,
- ngx_table_elt_t *h, size_t prefix);
-static ngx_int_t ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r,
- ngx_table_elt_t *h);
-static ngx_int_t ngx_http_proxy_rewrite_cookie_value(ngx_http_request_t *r,
- ngx_table_elt_t *h, u_char *value, ngx_array_t *rewrites);
-static ngx_int_t ngx_http_proxy_rewrite(ngx_http_request_t *r,
- ngx_table_elt_t *h, size_t prefix, size_t len, ngx_str_t *replacement);
-
-static ngx_int_t ngx_http_proxy_add_variables(ngx_conf_t *cf);
-static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static ngx_int_t ngx_http_proxy_merge_headers(ngx_conf_t *cf,
- ngx_http_proxy_loc_conf_t *conf, ngx_http_proxy_loc_conf_t *prev);
-
-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_cookie_domain(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_proxy_cookie_path(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);
-#if (NGX_HTTP_CACHE)
-static char *ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_proxy_cache_key(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-#endif
-
-static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data);
-
-static ngx_int_t ngx_http_proxy_rewrite_regex(ngx_conf_t *cf,
- ngx_http_proxy_rewrite_t *pr, ngx_str_t *regex, ngx_uint_t caseless);
-
-#if (NGX_HTTP_SSL)
-static ngx_int_t ngx_http_proxy_set_ssl(ngx_conf_t *cf,
- ngx_http_proxy_loc_conf_t *plcf);
-#endif
-static void ngx_http_proxy_set_vars(ngx_url_t *u, ngx_http_proxy_vars_t *v);
-
-
-static ngx_conf_post_t ngx_http_proxy_lowat_post =
- { ngx_http_proxy_lowat_check };
-
-
-static ngx_conf_bitmask_t ngx_http_proxy_next_upstream_masks[] = {
- { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
- { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
- { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
- { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
- { ngx_string("http_502"), NGX_HTTP_UPSTREAM_FT_HTTP_502 },
- { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
- { ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 },
- { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
- { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
- { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
- { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
- { ngx_null_string, 0 }
-};
-
-
-#if (NGX_HTTP_SSL)
-
-static ngx_conf_bitmask_t ngx_http_proxy_ssl_protocols[] = {
- { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
- { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
- { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
- { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
- { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
- { ngx_null_string, 0 }
-};
-
-#endif
-
-
-static ngx_conf_enum_t ngx_http_proxy_http_version[] = {
- { ngx_string("1.0"), NGX_HTTP_VERSION_10 },
- { ngx_string("1.1"), NGX_HTTP_VERSION_11 },
- { ngx_null_string, 0 }
-};
-
-
-ngx_module_t ngx_http_proxy_module;
-
-
-static ngx_command_t ngx_http_proxy_commands[] = {
-
- { ngx_string("proxy_pass"),
- NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
- ngx_http_proxy_pass,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("proxy_redirect"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
- ngx_http_proxy_redirect,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("proxy_cookie_domain"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
- ngx_http_proxy_cookie_domain,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("proxy_cookie_path"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
- ngx_http_proxy_cookie_path,
- NGX_HTTP_LOC_CONF_OFFSET,
- 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,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.buffering),
- NULL },
-
- { ngx_string("proxy_ignore_client_abort"),
- 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_proxy_loc_conf_t, upstream.ignore_client_abort),
- NULL },
-
- { ngx_string("proxy_bind"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_upstream_bind_set_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.local),
- NULL },
-
- { ngx_string("proxy_connect_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.connect_timeout),
- NULL },
-
- { ngx_string("proxy_send_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.send_timeout),
- NULL },
-
- { ngx_string("proxy_send_lowat"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.send_lowat),
- &ngx_http_proxy_lowat_post },
-
- { ngx_string("proxy_intercept_errors"),
- 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_proxy_loc_conf_t, upstream.intercept_errors),
- NULL },
-
- { ngx_string("proxy_set_header"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_conf_set_keyval_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, headers_source),
- NULL },
-
- { ngx_string("proxy_headers_hash_max_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, headers_hash_max_size),
- NULL },
-
- { ngx_string("proxy_headers_hash_bucket_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, headers_hash_bucket_size),
- NULL },
-
- { ngx_string("proxy_set_body"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, body_source),
- NULL },
-
- { ngx_string("proxy_method"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, method),
- NULL },
-
- { ngx_string("proxy_pass_request_headers"),
- 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_proxy_loc_conf_t, upstream.pass_request_headers),
- NULL },
-
- { ngx_string("proxy_pass_request_body"),
- 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_proxy_loc_conf_t, upstream.pass_request_body),
- NULL },
-
- { ngx_string("proxy_buffer_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.buffer_size),
- NULL },
-
- { ngx_string("proxy_read_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.read_timeout),
- NULL },
-
- { ngx_string("proxy_buffers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_conf_set_bufs_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.bufs),
- NULL },
-
- { ngx_string("proxy_busy_buffers_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.busy_buffers_size_conf),
- NULL },
-
-#if (NGX_HTTP_CACHE)
-
- { ngx_string("proxy_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_proxy_cache,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("proxy_cache_key"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_proxy_cache_key,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("proxy_cache_path"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE,
- ngx_http_file_cache_set_slot,
- 0,
- 0,
- &ngx_http_proxy_module },
-
- { ngx_string("proxy_cache_bypass"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_set_predicate_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_bypass),
- NULL },
-
- { ngx_string("proxy_no_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_set_predicate_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.no_cache),
- NULL },
-
- { ngx_string("proxy_cache_valid"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_file_cache_valid_set_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_valid),
- NULL },
-
- { ngx_string("proxy_cache_min_uses"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_min_uses),
- NULL },
-
- { ngx_string("proxy_cache_use_stale"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_use_stale),
- &ngx_http_proxy_next_upstream_masks },
-
- { ngx_string("proxy_cache_methods"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_methods),
- &ngx_http_upstream_cache_method_mask },
-
- { ngx_string("proxy_cache_lock"),
- 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_proxy_loc_conf_t, upstream.cache_lock),
- NULL },
-
- { ngx_string("proxy_cache_lock_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_lock_timeout),
- NULL },
-
- { ngx_string("proxy_cache_revalidate"),
- 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_proxy_loc_conf_t, upstream.cache_revalidate),
- NULL },
-
-#endif
-
- { ngx_string("proxy_temp_path"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
- ngx_conf_set_path_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.temp_path),
- NULL },
-
- { ngx_string("proxy_max_temp_file_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.max_temp_file_size_conf),
- NULL },
-
- { ngx_string("proxy_temp_file_write_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.temp_file_write_size_conf),
- NULL },
-
- { ngx_string("proxy_next_upstream"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream),
- &ngx_http_proxy_next_upstream_masks },
-
- { ngx_string("proxy_pass_header"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_array_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_headers),
- NULL },
-
- { ngx_string("proxy_hide_header"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_array_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.hide_headers),
- NULL },
-
- { ngx_string("proxy_ignore_headers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.ignore_headers),
- &ngx_http_upstream_ignore_headers_masks },
-
- { ngx_string("proxy_http_version"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, http_version),
- &ngx_http_proxy_http_version },
-
-#if (NGX_HTTP_SSL)
-
- { ngx_string("proxy_ssl_session_reuse"),
- 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_proxy_loc_conf_t, upstream.ssl_session_reuse),
- NULL },
-
- { ngx_string("proxy_ssl_protocols"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, ssl_protocols),
- &ngx_http_proxy_ssl_protocols },
-
- { ngx_string("proxy_ssl_ciphers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, ssl_ciphers),
- NULL },
-
-#endif
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_proxy_module_ctx = {
- ngx_http_proxy_add_variables, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_proxy_create_loc_conf, /* create location configuration */
- ngx_http_proxy_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_proxy_module = {
- NGX_MODULE_V1,
- &ngx_http_proxy_module_ctx, /* module context */
- ngx_http_proxy_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static char ngx_http_proxy_version[] = " HTTP/1.0" CRLF;
-static char ngx_http_proxy_version_11[] = " HTTP/1.1" CRLF;
-
-
-static ngx_keyval_t ngx_http_proxy_headers[] = {
- { ngx_string("Host"), ngx_string("$proxy_host") },
- { ngx_string("Connection"), ngx_string("close") },
- { ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") },
- { ngx_string("Transfer-Encoding"), ngx_string("") },
- { ngx_string("Keep-Alive"), ngx_string("") },
- { ngx_string("Expect"), ngx_string("") },
- { ngx_string("Upgrade"), ngx_string("") },
- { ngx_null_string, ngx_null_string }
-};
-
-
-static ngx_str_t ngx_http_proxy_hide_headers[] = {
- ngx_string("Date"),
- ngx_string("Server"),
- ngx_string("X-Pad"),
- ngx_string("X-Accel-Expires"),
- ngx_string("X-Accel-Redirect"),
- ngx_string("X-Accel-Limit-Rate"),
- ngx_string("X-Accel-Buffering"),
- ngx_string("X-Accel-Charset"),
- ngx_null_string
-};
-
-
-#if (NGX_HTTP_CACHE)
-
-static ngx_keyval_t ngx_http_proxy_cache_headers[] = {
- { ngx_string("Host"), ngx_string("$proxy_host") },
- { ngx_string("Connection"), ngx_string("close") },
- { ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") },
- { ngx_string("Transfer-Encoding"), ngx_string("") },
- { ngx_string("Keep-Alive"), ngx_string("") },
- { ngx_string("Expect"), ngx_string("") },
- { ngx_string("Upgrade"), ngx_string("") },
- { ngx_string("If-Modified-Since"),
- ngx_string("$upstream_cache_last_modified") },
- { ngx_string("If-Unmodified-Since"), ngx_string("") },
- { ngx_string("If-None-Match"), ngx_string("") },
- { ngx_string("If-Match"), ngx_string("") },
- { ngx_string("Range"), ngx_string("") },
- { ngx_string("If-Range"), ngx_string("") },
- { ngx_null_string, ngx_null_string }
-};
-
-#endif
-
-
-static ngx_http_variable_t ngx_http_proxy_vars[] = {
-
- { ngx_string("proxy_host"), NULL, ngx_http_proxy_host_variable, 0,
- NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
-
- { ngx_string("proxy_port"), NULL, ngx_http_proxy_port_variable, 0,
- NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|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 },
-
-#if 0
- { ngx_string("proxy_add_via"), NULL, NULL, 0, NGX_HTTP_VAR_NOHASH, 0 },
-#endif
-
- { ngx_string("proxy_internal_body_length"), NULL,
- ngx_http_proxy_internal_body_length_variable, 0,
- NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
-
- { ngx_null_string, NULL, NULL, 0, 0, 0 }
-};
-
-
-static ngx_path_init_t ngx_http_proxy_temp_path = {
- ngx_string(NGX_HTTP_PROXY_TEMP_PATH), { 1, 2, 0 }
-};
-
-
-static ngx_int_t
-ngx_http_proxy_handler(ngx_http_request_t *r)
-{
- ngx_int_t rc;
- ngx_http_upstream_t *u;
- ngx_http_proxy_ctx_t *ctx;
- ngx_http_proxy_loc_conf_t *plcf;
-
- if (ngx_http_upstream_create(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_proxy_module);
-
- plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
-
- u = r->upstream;
-
- if (plcf->proxy_lengths == NULL) {
- ctx->vars = plcf->vars;
- u->schema = plcf->vars.schema;
-#if (NGX_HTTP_SSL)
- u->ssl = (plcf->upstream.ssl != NULL);
-#endif
-
- } else {
- if (ngx_http_proxy_eval(r, ctx, plcf) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
- }
-
- u->output.tag = (ngx_buf_tag_t) &ngx_http_proxy_module;
-
- u->conf = &plcf->upstream;
-
-#if (NGX_HTTP_CACHE)
- u->create_key = ngx_http_proxy_create_key;
-#endif
- u->create_request = ngx_http_proxy_create_request;
- u->reinit_request = ngx_http_proxy_reinit_request;
- u->process_header = ngx_http_proxy_process_status_line;
- u->abort_request = ngx_http_proxy_abort_request;
- u->finalize_request = ngx_http_proxy_finalize_request;
- r->state = 0;
-
- if (plcf->redirects) {
- u->rewrite_redirect = ngx_http_proxy_rewrite_redirect;
- }
-
- if (plcf->cookie_domains || plcf->cookie_paths) {
- u->rewrite_cookie = ngx_http_proxy_rewrite_cookie;
- }
-
- u->buffering = plcf->upstream.buffering;
-
- u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
- if (u->pipe == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- u->pipe->input_filter = ngx_http_proxy_copy_filter;
- u->pipe->input_ctx = r;
-
- u->input_filter_init = ngx_http_proxy_input_filter_init;
- u->input_filter = ngx_http_proxy_non_buffered_copy_filter;
- u->input_filter_ctx = r;
-
- u->accel = 1;
-
- rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init);
-
- if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
- return rc;
- }
-
- return NGX_DONE;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx,
- ngx_http_proxy_loc_conf_t *plcf)
-{
- u_char *p;
- size_t add;
- u_short port;
- ngx_str_t proxy;
- ngx_url_t url;
- ngx_http_upstream_t *u;
-
- if (ngx_http_script_run(r, &proxy, plcf->proxy_lengths->elts, 0,
- plcf->proxy_values->elts)
- == NULL)
- {
- return NGX_ERROR;
- }
-
- if (proxy.len > 7
- && ngx_strncasecmp(proxy.data, (u_char *) "http://", 7) == 0)
- {
- add = 7;
- port = 80;
-
-#if (NGX_HTTP_SSL)
-
- } else if (proxy.len > 8
- && ngx_strncasecmp(proxy.data, (u_char *) "https://", 8) == 0)
- {
- add = 8;
- port = 443;
- r->upstream->ssl = 1;
-
-#endif
-
- } else {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "invalid URL prefix in \"%V\"", &proxy);
- return NGX_ERROR;
- }
-
- u = r->upstream;
-
- u->schema.len = add;
- u->schema.data = proxy.data;
-
- ngx_memzero(&url, sizeof(ngx_url_t));
-
- url.url.len = proxy.len - add;
- url.url.data = proxy.data + add;
- url.default_port = port;
- url.uri_part = 1;
- url.no_resolve = 1;
-
- if (ngx_parse_url(r->pool, &url) != NGX_OK) {
- if (url.err) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "%s in upstream \"%V\"", url.err, &url.url);
- }
-
- return NGX_ERROR;
- }
-
- if (url.uri.len) {
- if (url.uri.data[0] == '?') {
- p = ngx_pnalloc(r->pool, url.uri.len + 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- *p++ = '/';
- ngx_memcpy(p, url.uri.data, url.uri.len);
-
- url.uri.len++;
- url.uri.data = p - 1;
- }
- }
-
- ctx->vars.key_start = u->schema;
-
- ngx_http_proxy_set_vars(&url, &ctx->vars);
-
- u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
- if (u->resolved == NULL) {
- return NGX_ERROR;
- }
-
- if (url.addrs && url.addrs[0].sockaddr) {
- u->resolved->sockaddr = url.addrs[0].sockaddr;
- u->resolved->socklen = url.addrs[0].socklen;
- u->resolved->naddrs = 1;
- u->resolved->host = url.addrs[0].name;
-
- } else {
- u->resolved->host = url.host;
- u->resolved->port = (in_port_t) (url.no_port ? port : url.port);
- u->resolved->no_port = url.no_port;
- }
-
- return NGX_OK;
-}
-
-
-#if (NGX_HTTP_CACHE)
-
-static ngx_int_t
-ngx_http_proxy_create_key(ngx_http_request_t *r)
-{
- size_t len, loc_len;
- u_char *p;
- uintptr_t escape;
- ngx_str_t *key;
- ngx_http_upstream_t *u;
- ngx_http_proxy_ctx_t *ctx;
- ngx_http_proxy_loc_conf_t *plcf;
-
- u = r->upstream;
-
- plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
- key = ngx_array_push(&r->cache->keys);
- if (key == NULL) {
- return NGX_ERROR;
- }
-
- if (plcf->cache_key.value.data) {
-
- if (ngx_http_complex_value(r, &plcf->cache_key, key) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
- }
-
- *key = ctx->vars.key_start;
-
- key = ngx_array_push(&r->cache->keys);
- if (key == NULL) {
- return NGX_ERROR;
- }
-
- if (plcf->proxy_lengths && ctx->vars.uri.len) {
-
- *key = ctx->vars.uri;
- u->uri = ctx->vars.uri;
-
- return NGX_OK;
-
- } else if (ctx->vars.uri.len == 0 && r->valid_unparsed_uri && r == r->main)
- {
- *key = r->unparsed_uri;
- u->uri = r->unparsed_uri;
-
- return NGX_OK;
- }
-
- loc_len = (r->valid_location && ctx->vars.uri.len) ? plcf->location.len : 0;
-
- 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);
- } else {
- escape = 0;
- }
-
- len = ctx->vars.uri.len + r->uri.len - loc_len + escape
- + sizeof("?") - 1 + r->args.len;
-
- p = ngx_pnalloc(r->pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- key->data = p;
-
- if (r->valid_location) {
- p = ngx_copy(p, ctx->vars.uri.data, ctx->vars.uri.len);
- }
-
- if (escape) {
- ngx_escape_uri(p, r->uri.data + loc_len,
- r->uri.len - loc_len, NGX_ESCAPE_URI);
- p += r->uri.len - loc_len + escape;
-
- } else {
- p = ngx_copy(p, r->uri.data + loc_len, r->uri.len - loc_len);
- }
-
- if (r->args.len > 0) {
- *p++ = '?';
- p = ngx_copy(p, r->args.data, r->args.len);
- }
-
- key->len = p - key->data;
- u->uri = *key;
-
- return NGX_OK;
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_proxy_create_request(ngx_http_request_t *r)
-{
- size_t len, uri_len, loc_len, body_len;
- uintptr_t escape;
- ngx_buf_t *b;
- ngx_str_t method;
- ngx_uint_t i, unparsed_uri;
- ngx_chain_t *cl, *body;
- ngx_list_part_t *part;
- ngx_table_elt_t *header;
- ngx_http_upstream_t *u;
- ngx_http_proxy_ctx_t *ctx;
- ngx_http_script_code_pt code;
- ngx_http_script_engine_t e, le;
- ngx_http_proxy_loc_conf_t *plcf;
- ngx_http_script_len_code_pt lcode;
-
- u = r->upstream;
-
- plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
-
- if (u->method.len) {
- /* HEAD was changed to GET to cache response */
- method = u->method;
- method.len++;
-
- } else if (plcf->method.len) {
- method = plcf->method;
-
- } else {
- method = r->method_name;
- method.len++;
- }
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
- if (method.len == 5
- && ngx_strncasecmp(method.data, (u_char *) "HEAD ", 5) == 0)
- {
- ctx->head = 1;
- }
-
- len = method.len + sizeof(ngx_http_proxy_version) - 1 + sizeof(CRLF) - 1;
-
- escape = 0;
- loc_len = 0;
- unparsed_uri = 0;
-
- if (plcf->proxy_lengths && ctx->vars.uri.len) {
- uri_len = ctx->vars.uri.len;
-
- } else if (ctx->vars.uri.len == 0 && r->valid_unparsed_uri && r == r->main)
- {
- unparsed_uri = 1;
- uri_len = r->unparsed_uri.len;
-
- } else {
- loc_len = (r->valid_location && ctx->vars.uri.len) ?
- plcf->location.len : 0;
-
- if (r->quoted_uri || r->space_in_uri || r->internal) {
- escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len,
- r->uri.len - loc_len, NGX_ESCAPE_URI);
- }
-
- uri_len = ctx->vars.uri.len + r->uri.len - loc_len + escape
- + sizeof("?") - 1 + r->args.len;
- }
-
- if (uri_len == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "zero length URI to proxy");
- return NGX_ERROR;
- }
-
- len += uri_len;
-
- ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
-
- ngx_http_script_flush_no_cacheable_variables(r, plcf->flushes);
-
- if (plcf->body_set_len) {
- le.ip = plcf->body_set_len->elts;
- le.request = r;
- le.flushed = 1;
- body_len = 0;
-
- while (*(uintptr_t *) le.ip) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- body_len += lcode(&le);
- }
-
- ctx->internal_body_length = body_len;
- len += body_len;
-
- } else {
- ctx->internal_body_length = r->headers_in.content_length_n;
- }
-
- le.ip = plcf->headers_set_len->elts;
- le.request = r;
- le.flushed = 1;
-
- while (*(uintptr_t *) le.ip) {
- while (*(uintptr_t *) le.ip) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- len += lcode(&le);
- }
- le.ip += sizeof(uintptr_t);
- }
-
-
- if (plcf->upstream.pass_request_headers) {
- part = &r->headers_in.headers.part;
- header = part->elts;
-
- for (i = 0; /* void */; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- if (ngx_hash_find(&plcf->headers_set_hash, header[i].hash,
- header[i].lowcase_key, header[i].key.len))
- {
- continue;
- }
-
- len += header[i].key.len + sizeof(": ") - 1
- + header[i].value.len + sizeof(CRLF) - 1;
- }
- }
-
-
- b = ngx_create_temp_buf(r->pool, len);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
-
-
- /* the request line */
-
- b->last = ngx_copy(b->last, method.data, method.len);
-
- u->uri.data = b->last;
-
- if (plcf->proxy_lengths && ctx->vars.uri.len) {
- b->last = ngx_copy(b->last, ctx->vars.uri.data, ctx->vars.uri.len);
-
- } else if (unparsed_uri) {
- b->last = ngx_copy(b->last, r->unparsed_uri.data, r->unparsed_uri.len);
-
- } else {
- if (r->valid_location) {
- b->last = ngx_copy(b->last, ctx->vars.uri.data, ctx->vars.uri.len);
- }
-
- if (escape) {
- ngx_escape_uri(b->last, r->uri.data + loc_len,
- r->uri.len - loc_len, NGX_ESCAPE_URI);
- b->last += r->uri.len - loc_len + escape;
-
- } else {
- b->last = ngx_copy(b->last, r->uri.data + loc_len,
- r->uri.len - loc_len);
- }
-
- if (r->args.len > 0) {
- *b->last++ = '?';
- b->last = ngx_copy(b->last, r->args.data, r->args.len);
- }
- }
-
- u->uri.len = b->last - u->uri.data;
-
- if (plcf->http_version == NGX_HTTP_VERSION_11) {
- b->last = ngx_cpymem(b->last, ngx_http_proxy_version_11,
- sizeof(ngx_http_proxy_version_11) - 1);
-
- } else {
- b->last = ngx_cpymem(b->last, ngx_http_proxy_version,
- sizeof(ngx_http_proxy_version) - 1);
- }
-
- ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
-
- e.ip = plcf->headers_set->elts;
- e.pos = b->last;
- e.request = r;
- e.flushed = 1;
-
- le.ip = plcf->headers_set_len->elts;
-
- while (*(uintptr_t *) le.ip) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
-
- /* skip the header line name length */
- (void) lcode(&le);
-
- if (*(ngx_http_script_len_code_pt *) le.ip) {
-
- for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- }
-
- e.skip = (len == sizeof(CRLF) - 1) ? 1 : 0;
-
- } else {
- e.skip = 0;
- }
-
- le.ip += sizeof(uintptr_t);
-
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
- }
- e.ip += sizeof(uintptr_t);
- }
-
- b->last = e.pos;
-
-
- if (plcf->upstream.pass_request_headers) {
- part = &r->headers_in.headers.part;
- header = part->elts;
-
- for (i = 0; /* void */; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- if (ngx_hash_find(&plcf->headers_set_hash, header[i].hash,
- header[i].lowcase_key, header[i].key.len))
- {
- continue;
- }
-
- b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len);
-
- *b->last++ = ':'; *b->last++ = ' ';
-
- b->last = ngx_copy(b->last, header[i].value.data,
- header[i].value.len);
-
- *b->last++ = CR; *b->last++ = LF;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http proxy header: \"%V: %V\"",
- &header[i].key, &header[i].value);
- }
- }
-
-
- /* add "\r\n" at the header end */
- *b->last++ = CR; *b->last++ = LF;
-
- if (plcf->body_set) {
- e.ip = plcf->body_set->elts;
- e.pos = b->last;
-
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
- }
-
- b->last = e.pos;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http proxy header:\n\"%*s\"",
- (size_t) (b->last - b->pos), b->pos);
-
- if (plcf->body_set == NULL && plcf->upstream.pass_request_body) {
-
- body = u->request_bufs;
- u->request_bufs = cl;
-
- while (body) {
- b = ngx_alloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(b, body->buf, sizeof(ngx_buf_t));
-
- cl->next = ngx_alloc_chain_link(r->pool);
- if (cl->next == NULL) {
- return NGX_ERROR;
- }
-
- cl = cl->next;
- cl->buf = b;
-
- body = body->next;
- }
-
- } else {
- u->request_bufs = cl;
- }
-
- b->flush = 1;
- cl->next = NULL;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_reinit_request(ngx_http_request_t *r)
-{
- ngx_http_proxy_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
- if (ctx == NULL) {
- return NGX_OK;
- }
-
- ctx->status.code = 0;
- ctx->status.count = 0;
- ctx->status.start = NULL;
- ctx->status.end = NULL;
- ctx->chunked.state = 0;
-
- r->upstream->process_header = ngx_http_proxy_process_status_line;
- r->upstream->pipe->input_filter = ngx_http_proxy_copy_filter;
- r->upstream->input_filter = ngx_http_proxy_non_buffered_copy_filter;
- r->state = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_process_status_line(ngx_http_request_t *r)
-{
- size_t len;
- ngx_int_t rc;
- ngx_http_upstream_t *u;
- ngx_http_proxy_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- u = r->upstream;
-
- rc = ngx_http_parse_status_line(r, &u->buffer, &ctx->status);
-
- if (rc == NGX_AGAIN) {
- return rc;
- }
-
- if (rc == NGX_ERROR) {
-
-#if (NGX_HTTP_CACHE)
-
- if (r->cache) {
- r->http_version = NGX_HTTP_VERSION_9;
- return NGX_OK;
- }
-
-#endif
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream sent no valid HTTP/1.0 header");
-
-#if 0
- if (u->accel) {
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
- }
-#endif
-
- r->http_version = NGX_HTTP_VERSION_9;
- u->state->status = NGX_HTTP_OK;
- u->headers_in.connection_close = 1;
-
- return NGX_OK;
- }
-
- if (u->state && u->state->status == 0) {
- u->state->status = ctx->status.code;
- }
-
- u->headers_in.status_n = ctx->status.code;
-
- len = ctx->status.end - ctx->status.start;
- u->headers_in.status_line.len = len;
-
- u->headers_in.status_line.data = ngx_pnalloc(r->pool, len);
- if (u->headers_in.status_line.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(u->headers_in.status_line.data, ctx->status.start, len);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http proxy status %ui \"%V\"",
- u->headers_in.status_n, &u->headers_in.status_line);
-
- if (ctx->status.http_version < NGX_HTTP_VERSION_11) {
- u->headers_in.connection_close = 1;
- }
-
- u->process_header = ngx_http_proxy_process_header;
-
- return ngx_http_proxy_process_header(r);
-}
-
-
-static ngx_int_t
-ngx_http_proxy_process_header(ngx_http_request_t *r)
-{
- ngx_int_t rc;
- ngx_table_elt_t *h;
- ngx_http_upstream_t *u;
- ngx_http_proxy_ctx_t *ctx;
- ngx_http_upstream_header_t *hh;
- ngx_http_upstream_main_conf_t *umcf;
-
- umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
-
- for ( ;; ) {
-
- rc = ngx_http_parse_header_line(r, &r->upstream->buffer, 1);
-
- if (rc == NGX_OK) {
-
- /* a header line has been parsed successfully */
-
- h = ngx_list_push(&r->upstream->headers_in.headers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- 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_pnalloc(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_memcpy(h->key.data, r->header_name_start, h->key.len);
- h->key.data[h->key.len] = '\0';
- ngx_memcpy(h->value.data, r->header_start, h->value.len);
- h->value.data[h->value.len] = '\0';
-
- if (h->key.len == r->lowcase_index) {
- ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
-
- } else {
- ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
- }
-
- hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
- h->lowcase_key, h->key.len);
-
- if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http proxy header: \"%V: %V\"",
- &h->key, &h->value);
-
- continue;
- }
-
- if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
-
- /* a whole header has been parsed successfully */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http proxy header done");
-
- /*
- * if no "Server" and "Date" in header line,
- * then add the special empty headers
- */
-
- if (r->upstream->headers_in.server == NULL) {
- h = ngx_list_push(&r->upstream->headers_in.headers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(
- ngx_hash('s', 'e'), 'r'), 'v'), 'e'), 'r');
-
- ngx_str_set(&h->key, "Server");
- ngx_str_null(&h->value);
- h->lowcase_key = (u_char *) "server";
- }
-
- if (r->upstream->headers_in.date == NULL) {
- h = ngx_list_push(&r->upstream->headers_in.headers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e');
-
- ngx_str_set(&h->key, "Date");
- ngx_str_null(&h->value);
- h->lowcase_key = (u_char *) "date";
- }
-
- /* clear content length if response is chunked */
-
- u = r->upstream;
-
- if (u->headers_in.chunked) {
- u->headers_in.content_length_n = -1;
- }
-
- /*
- * set u->keepalive if response has no body; this allows to keep
- * connections alive in case of r->header_only or X-Accel-Redirect
- */
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
- if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
- || u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED
- || ctx->head
- || (!u->headers_in.chunked
- && u->headers_in.content_length_n == 0))
- {
- u->keepalive = !u->headers_in.connection_close;
- }
-
- if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS) {
- u->keepalive = 0;
-
- if (r->headers_in.upgrade) {
- u->upgrade = 1;
- }
- }
-
- return NGX_OK;
- }
-
- if (rc == NGX_AGAIN) {
- return NGX_AGAIN;
- }
-
- /* there was error while a header line parsing */
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream sent invalid header");
-
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
- }
-}
-
-
-static ngx_int_t
-ngx_http_proxy_input_filter_init(void *data)
-{
- ngx_http_request_t *r = data;
- ngx_http_upstream_t *u;
- ngx_http_proxy_ctx_t *ctx;
-
- u = r->upstream;
- ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http proxy filter init s:%d h:%d c:%d l:%O",
- u->headers_in.status_n, ctx->head, u->headers_in.chunked,
- u->headers_in.content_length_n);
-
- /* as per RFC2616, 4.4 Message Length */
-
- if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
- || u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED
- || ctx->head)
- {
- /* 1xx, 204, and 304 and replies to HEAD requests */
- /* no 1xx since we don't send Expect and Upgrade */
-
- u->pipe->length = 0;
- u->length = 0;
- u->keepalive = !u->headers_in.connection_close;
-
- } else if (u->headers_in.chunked) {
- /* chunked */
-
- u->pipe->input_filter = ngx_http_proxy_chunked_filter;
- u->pipe->length = 3; /* "0" LF LF */
-
- u->input_filter = ngx_http_proxy_non_buffered_chunked_filter;
- u->length = 1;
-
- } else if (u->headers_in.content_length_n == 0) {
- /* empty body: special case as filter won't be called */
-
- u->pipe->length = 0;
- u->length = 0;
- u->keepalive = !u->headers_in.connection_close;
-
- } else {
- /* content length or connection close */
-
- u->pipe->length = u->headers_in.content_length_n;
- u->length = u->headers_in.content_length_n;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_copy_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
-{
- ngx_buf_t *b;
- ngx_chain_t *cl;
- ngx_http_request_t *r;
-
- if (buf->pos == buf->last) {
- return NGX_OK;
- }
-
- cl = ngx_chain_get_free_buf(p->pool, &p->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memcpy(b, buf, sizeof(ngx_buf_t));
- b->shadow = buf;
- b->tag = p->tag;
- b->last_shadow = 1;
- b->recycled = 1;
- buf->shadow = b;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d", b->num);
-
- if (p->in) {
- *p->last_in = cl;
- } else {
- p->in = cl;
- }
- p->last_in = &cl->next;
-
- if (p->length == -1) {
- return NGX_OK;
- }
-
- p->length -= b->last - b->pos;
-
- if (p->length == 0) {
- r = p->input_ctx;
- p->upstream_done = 1;
- r->upstream->keepalive = !r->upstream->headers_in.connection_close;
-
- } else if (p->length < 0) {
- r = p->input_ctx;
- p->upstream_done = 1;
-
- ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
- "upstream sent more data than specified in "
- "\"Content-Length\" header");
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
-{
- ngx_int_t rc;
- ngx_buf_t *b, **prev;
- ngx_chain_t *cl;
- ngx_http_request_t *r;
- ngx_http_proxy_ctx_t *ctx;
-
- if (buf->pos == buf->last) {
- return NGX_OK;
- }
-
- r = p->input_ctx;
- ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- b = NULL;
- prev = &buf->shadow;
-
- for ( ;; ) {
-
- rc = ngx_http_parse_chunked(r, buf, &ctx->chunked);
-
- if (rc == NGX_OK) {
-
- /* a chunk has been parsed successfully */
-
- cl = ngx_chain_get_free_buf(p->pool, &p->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->pos = buf->pos;
- b->start = buf->start;
- b->end = buf->end;
- b->tag = p->tag;
- b->temporary = 1;
- b->recycled = 1;
-
- *prev = b;
- prev = &b->shadow;
-
- if (p->in) {
- *p->last_in = cl;
- } else {
- p->in = cl;
- }
- p->last_in = &cl->next;
-
- /* STUB */ b->num = buf->num;
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "input buf #%d %p", b->num, b->pos);
-
- if (buf->last - buf->pos >= ctx->chunked.size) {
-
- buf->pos += (size_t) ctx->chunked.size;
- b->last = buf->pos;
- ctx->chunked.size = 0;
-
- continue;
- }
-
- ctx->chunked.size -= buf->last - buf->pos;
- buf->pos = buf->last;
- b->last = buf->last;
-
- continue;
- }
-
- if (rc == NGX_DONE) {
-
- /* a whole response has been parsed successfully */
-
- p->upstream_done = 1;
- r->upstream->keepalive = !r->upstream->headers_in.connection_close;
-
- break;
- }
-
- if (rc == NGX_AGAIN) {
-
- /* set p->length, minimal amount of data we want to see */
-
- p->length = ctx->chunked.length;
-
- break;
- }
-
- /* invalid response */
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream sent invalid chunked response");
-
- return NGX_ERROR;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http proxy chunked state %d, length %d",
- ctx->chunked.state, p->length);
-
- if (b) {
- b->shadow = buf;
- b->last_shadow = 1;
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "input buf %p %z", b->pos, b->last - b->pos);
-
- return NGX_OK;
- }
-
- /* there is no data record in the buf, add it to free chain */
-
- if (ngx_event_pipe_add_free_buf(p, buf) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_non_buffered_copy_filter(void *data, ssize_t bytes)
-{
- ngx_http_request_t *r = data;
-
- ngx_buf_t *b;
- ngx_chain_t *cl, **ll;
- ngx_http_upstream_t *u;
-
- u = r->upstream;
-
- for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) {
- ll = &cl->next;
- }
-
- cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- *ll = cl;
-
- cl->buf->flush = 1;
- cl->buf->memory = 1;
-
- b = &u->buffer;
-
- cl->buf->pos = b->last;
- b->last += bytes;
- cl->buf->last = b->last;
- cl->buf->tag = u->output.tag;
-
- if (u->length == -1) {
- return NGX_OK;
- }
-
- u->length -= bytes;
-
- if (u->length == 0) {
- u->keepalive = !u->headers_in.connection_close;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_non_buffered_chunked_filter(void *data, ssize_t bytes)
-{
- ngx_http_request_t *r = data;
-
- ngx_int_t rc;
- ngx_buf_t *b, *buf;
- ngx_chain_t *cl, **ll;
- ngx_http_upstream_t *u;
- ngx_http_proxy_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- u = r->upstream;
- buf = &u->buffer;
-
- buf->pos = buf->last;
- buf->last += bytes;
-
- for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) {
- ll = &cl->next;
- }
-
- for ( ;; ) {
-
- rc = ngx_http_parse_chunked(r, buf, &ctx->chunked);
-
- if (rc == NGX_OK) {
-
- /* a chunk has been parsed successfully */
-
- cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- *ll = cl;
- ll = &cl->next;
-
- b = cl->buf;
-
- b->flush = 1;
- b->memory = 1;
-
- b->pos = buf->pos;
- b->tag = u->output.tag;
-
- if (buf->last - buf->pos >= ctx->chunked.size) {
- buf->pos += (size_t) ctx->chunked.size;
- b->last = buf->pos;
- ctx->chunked.size = 0;
-
- } else {
- ctx->chunked.size -= buf->last - buf->pos;
- buf->pos = buf->last;
- b->last = buf->last;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http proxy out buf %p %z",
- b->pos, b->last - b->pos);
-
- continue;
- }
-
- if (rc == NGX_DONE) {
-
- /* a whole response has been parsed successfully */
-
- u->keepalive = !u->headers_in.connection_close;
- u->length = 0;
-
- break;
- }
-
- if (rc == NGX_AGAIN) {
- break;
- }
-
- /* invalid response */
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream sent invalid chunked response");
-
- return NGX_ERROR;
- }
-
- /* provide continuous buffer for subrequests in memory */
-
- if (r->subrequest_in_memory) {
-
- cl = u->out_bufs;
-
- if (cl) {
- buf->pos = cl->buf->pos;
- }
-
- buf->last = buf->pos;
-
- for (cl = u->out_bufs; cl; cl = cl->next) {
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http proxy in memory %p-%p %uz",
- cl->buf->pos, cl->buf->last, ngx_buf_size(cl->buf));
-
- if (buf->last == cl->buf->pos) {
- buf->last = cl->buf->last;
- continue;
- }
-
- buf->last = ngx_movemem(buf->last, cl->buf->pos,
- cl->buf->last - cl->buf->pos);
-
- cl->buf->pos = buf->last - (cl->buf->last - cl->buf->pos);
- cl->buf->last = buf->last;
- }
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_proxy_abort_request(ngx_http_request_t *r)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "abort http proxy request");
-
- return;
-}
-
-
-static void
-ngx_http_proxy_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "finalize http proxy request");
-
- return;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_host_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_http_proxy_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
- if (ctx == NULL) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- v->len = ctx->vars.host_header.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = ctx->vars.host_header.data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_port_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_http_proxy_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
- if (ctx == NULL) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- v->len = ctx->vars.port.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = ctx->vars.port.data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- size_t len;
- u_char *p;
- ngx_uint_t i, n;
- ngx_table_elt_t **h;
-
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- n = r->headers_in.x_forwarded_for.nelts;
- h = r->headers_in.x_forwarded_for.elts;
-
- len = 0;
-
- for (i = 0; i < n; i++) {
- len += h[i]->value.len + sizeof(", ") - 1;
- }
-
- if (len == 0) {
- v->len = r->connection->addr_text.len;
- v->data = r->connection->addr_text.data;
- return NGX_OK;
- }
-
- len += r->connection->addr_text.len;
-
- p = ngx_pnalloc(r->pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->len = len;
- v->data = p;
-
- for (i = 0; i < n; i++) {
- p = ngx_copy(p, h[i]->value.data, h[i]->value.len);
- *p++ = ','; *p++ = ' ';
- }
-
- ngx_memcpy(p, r->connection->addr_text.data, r->connection->addr_text.len);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_http_proxy_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
- if (ctx == NULL || ctx->internal_body_length < 0) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- v->data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN);
-
- if (v->data == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_sprintf(v->data, "%O", ctx->internal_body_length) - v->data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h,
- size_t prefix)
-{
- size_t len;
- ngx_int_t rc;
- ngx_uint_t i;
- ngx_http_proxy_rewrite_t *pr;
- ngx_http_proxy_loc_conf_t *plcf;
-
- plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
-
- pr = plcf->redirects->elts;
-
- if (pr == NULL) {
- return NGX_DECLINED;
- }
-
- len = h->value.len - prefix;
-
- for (i = 0; i < plcf->redirects->nelts; i++) {
- rc = pr[i].handler(r, h, prefix, len, &pr[i]);
-
- if (rc != NGX_DECLINED) {
- return rc;
- }
- }
-
- return NGX_DECLINED;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r, ngx_table_elt_t *h)
-{
- size_t prefix;
- u_char *p;
- ngx_int_t rc, rv;
- ngx_http_proxy_loc_conf_t *plcf;
-
- p = (u_char *) ngx_strchr(h->value.data, ';');
- if (p == NULL) {
- return NGX_DECLINED;
- }
-
- prefix = p + 1 - h->value.data;
-
- rv = NGX_DECLINED;
-
- plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
-
- if (plcf->cookie_domains) {
- p = ngx_strcasestrn(h->value.data + prefix, "domain=", 7 - 1);
-
- if (p) {
- rc = ngx_http_proxy_rewrite_cookie_value(r, h, p + 7,
- plcf->cookie_domains);
- if (rc == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- if (rc != NGX_DECLINED) {
- rv = rc;
- }
- }
- }
-
- if (plcf->cookie_paths) {
- p = ngx_strcasestrn(h->value.data + prefix, "path=", 5 - 1);
-
- if (p) {
- rc = ngx_http_proxy_rewrite_cookie_value(r, h, p + 5,
- plcf->cookie_paths);
- if (rc == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- if (rc != NGX_DECLINED) {
- rv = rc;
- }
- }
- }
-
- return rv;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_rewrite_cookie_value(ngx_http_request_t *r, ngx_table_elt_t *h,
- u_char *value, ngx_array_t *rewrites)
-{
- size_t len, prefix;
- u_char *p;
- ngx_int_t rc;
- ngx_uint_t i;
- ngx_http_proxy_rewrite_t *pr;
-
- prefix = value - h->value.data;
-
- p = (u_char *) ngx_strchr(value, ';');
-
- len = p ? (size_t) (p - value) : (h->value.len - prefix);
-
- pr = rewrites->elts;
-
- for (i = 0; i < rewrites->nelts; i++) {
- rc = pr[i].handler(r, h, prefix, len, &pr[i]);
-
- if (rc != NGX_DECLINED) {
- return rc;
- }
- }
-
- return NGX_DECLINED;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_rewrite_complex_handler(ngx_http_request_t *r,
- ngx_table_elt_t *h, size_t prefix, size_t len, ngx_http_proxy_rewrite_t *pr)
-{
- ngx_str_t pattern, replacement;
-
- if (ngx_http_complex_value(r, &pr->pattern.complex, &pattern) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (pattern.len > len
- || ngx_rstrncmp(h->value.data + prefix, pattern.data,
- pattern.len) != 0)
- {
- return NGX_DECLINED;
- }
-
- if (ngx_http_complex_value(r, &pr->replacement, &replacement) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return ngx_http_proxy_rewrite(r, h, prefix, pattern.len, &replacement);
-}
-
-
-#if (NGX_PCRE)
-
-static ngx_int_t
-ngx_http_proxy_rewrite_regex_handler(ngx_http_request_t *r, ngx_table_elt_t *h,
- size_t prefix, size_t len, ngx_http_proxy_rewrite_t *pr)
-{
- ngx_str_t pattern, replacement;
-
- pattern.len = len;
- pattern.data = h->value.data + prefix;
-
- if (ngx_http_regex_exec(r, pr->pattern.regex, &pattern) != NGX_OK) {
- return NGX_DECLINED;
- }
-
- if (ngx_http_complex_value(r, &pr->replacement, &replacement) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (prefix == 0 && h->value.len == len) {
- h->value = replacement;
- return NGX_OK;
- }
-
- return ngx_http_proxy_rewrite(r, h, prefix, len, &replacement);
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_proxy_rewrite_domain_handler(ngx_http_request_t *r,
- ngx_table_elt_t *h, size_t prefix, size_t len, ngx_http_proxy_rewrite_t *pr)
-{
- u_char *p;
- ngx_str_t pattern, replacement;
-
- if (ngx_http_complex_value(r, &pr->pattern.complex, &pattern) != NGX_OK) {
- return NGX_ERROR;
- }
-
- p = h->value.data + prefix;
-
- if (p[0] == '.') {
- p++;
- prefix++;
- len--;
- }
-
- if (pattern.len != len || ngx_rstrncasecmp(pattern.data, p, len) != 0) {
- return NGX_DECLINED;
- }
-
- if (ngx_http_complex_value(r, &pr->replacement, &replacement) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return ngx_http_proxy_rewrite(r, h, prefix, len, &replacement);
-}
-
-
-static ngx_int_t
-ngx_http_proxy_rewrite(ngx_http_request_t *r, ngx_table_elt_t *h, size_t prefix,
- size_t len, ngx_str_t *replacement)
-{
- u_char *p, *data;
- size_t new_len;
-
- new_len = replacement->len + h->value.len - len;
-
- if (replacement->len > len) {
-
- data = ngx_pnalloc(r->pool, new_len);
- if (data == NULL) {
- return NGX_ERROR;
- }
-
- p = ngx_copy(data, h->value.data, prefix);
- p = ngx_copy(p, replacement->data, replacement->len);
-
- ngx_memcpy(p, h->value.data + prefix + len,
- h->value.len - len - prefix);
-
- h->value.data = data;
-
- } else {
- p = ngx_copy(h->value.data + prefix, replacement->data,
- replacement->len);
-
- ngx_memmove(p, h->value.data + prefix + len,
- h->value.len - len - prefix);
- }
-
- h->value.len = new_len;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_add_variables(ngx_conf_t *cf)
-{
- ngx_http_variable_t *var, *v;
-
- for (v = ngx_http_proxy_vars; v->name.len; v++) {
- var = ngx_http_add_variable(cf, &v->name, v->flags);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = v->get_handler;
- var->data = v->data;
- }
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_proxy_loc_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->upstream.bufs.num = 0;
- * conf->upstream.ignore_headers = 0;
- * conf->upstream.next_upstream = 0;
- * conf->upstream.cache_use_stale = 0;
- * conf->upstream.cache_methods = 0;
- * conf->upstream.temp_path = NULL;
- * conf->upstream.hide_headers_hash = { NULL, 0 };
- * conf->upstream.uri = { 0, NULL };
- * conf->upstream.location = NULL;
- * conf->upstream.store_lengths = NULL;
- * conf->upstream.store_values = NULL;
- *
- * conf->method = { 0, NULL };
- * conf->headers_source = NULL;
- * conf->headers_set_len = NULL;
- * conf->headers_set = NULL;
- * conf->headers_set_hash = NULL;
- * conf->body_set_len = NULL;
- * conf->body_set = NULL;
- * conf->body_source = { 0, NULL };
- * conf->redirects = NULL;
- * conf->ssl = 0;
- * conf->ssl_protocols = 0;
- * conf->ssl_ciphers = { 0, 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;
-
- conf->upstream.local = NGX_CONF_UNSET_PTR;
-
- conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
-
- conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
- conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
-
- conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE;
- conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
- conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
-
- conf->upstream.pass_request_headers = NGX_CONF_UNSET;
- conf->upstream.pass_request_body = NGX_CONF_UNSET;
-
-#if (NGX_HTTP_CACHE)
- conf->upstream.cache = NGX_CONF_UNSET_PTR;
- conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
- conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
- conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
- conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
- conf->upstream.cache_lock = NGX_CONF_UNSET;
- conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.cache_revalidate = NGX_CONF_UNSET;
-#endif
-
- conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
- conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
-
- conf->upstream.intercept_errors = NGX_CONF_UNSET;
-#if (NGX_HTTP_SSL)
- conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
-#endif
-
- /* "proxy_cyclic_temp_file" is disabled */
- conf->upstream.cyclic_temp_file = 0;
-
- conf->redirect = NGX_CONF_UNSET;
- conf->upstream.change_buffering = 1;
-
- conf->cookie_domains = NGX_CONF_UNSET_PTR;
- conf->cookie_paths = NGX_CONF_UNSET_PTR;
-
- conf->http_version = NGX_CONF_UNSET_UINT;
-
- conf->headers_hash_max_size = NGX_CONF_UNSET_UINT;
- conf->headers_hash_bucket_size = NGX_CONF_UNSET_UINT;
-
- ngx_str_set(&conf->upstream.module, "proxy");
-
- return conf;
-}
-
-
-static char *
-ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_proxy_loc_conf_t *prev = parent;
- ngx_http_proxy_loc_conf_t *conf = child;
-
- u_char *p;
- size_t size;
- ngx_hash_init_t hash;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_proxy_rewrite_t *pr;
- ngx_http_script_compile_t sc;
-
- 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);
-
- ngx_conf_merge_value(conf->upstream.ignore_client_abort,
- prev->upstream.ignore_client_abort, 0);
-
- ngx_conf_merge_ptr_value(conf->upstream.local,
- prev->upstream.local, NULL);
-
- ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
- prev->upstream.connect_timeout, 60000);
-
- ngx_conf_merge_msec_value(conf->upstream.send_timeout,
- prev->upstream.send_timeout, 60000);
-
- ngx_conf_merge_msec_value(conf->upstream.read_timeout,
- prev->upstream.read_timeout, 60000);
-
- ngx_conf_merge_size_value(conf->upstream.send_lowat,
- prev->upstream.send_lowat, 0);
-
- ngx_conf_merge_size_value(conf->upstream.buffer_size,
- prev->upstream.buffer_size,
- (size_t) ngx_pagesize);
-
- ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs,
- 8, ngx_pagesize);
-
- if (conf->upstream.bufs.num < 2) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "there must be at least 2 \"proxy_buffers\"");
- return NGX_CONF_ERROR;
- }
-
-
- size = conf->upstream.buffer_size;
- if (size < conf->upstream.bufs.size) {
- size = conf->upstream.bufs.size;
- }
-
-
- ngx_conf_merge_size_value(conf->upstream.busy_buffers_size_conf,
- prev->upstream.busy_buffers_size_conf,
- NGX_CONF_UNSET_SIZE);
-
- if (conf->upstream.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) {
- conf->upstream.busy_buffers_size = 2 * size;
- } else {
- conf->upstream.busy_buffers_size =
- conf->upstream.busy_buffers_size_conf;
- }
-
- if (conf->upstream.busy_buffers_size < size) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"proxy_busy_buffers_size\" must be equal to or greater than "
- "the maximum of the value of \"proxy_buffer_size\" and "
- "one of the \"proxy_buffers\"");
-
- return NGX_CONF_ERROR;
- }
-
- if (conf->upstream.busy_buffers_size
- > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size)
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"proxy_busy_buffers_size\" must be less than "
- "the size of all \"proxy_buffers\" minus one buffer");
-
- return NGX_CONF_ERROR;
- }
-
-
- ngx_conf_merge_size_value(conf->upstream.temp_file_write_size_conf,
- prev->upstream.temp_file_write_size_conf,
- NGX_CONF_UNSET_SIZE);
-
- if (conf->upstream.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) {
- conf->upstream.temp_file_write_size = 2 * size;
- } else {
- conf->upstream.temp_file_write_size =
- conf->upstream.temp_file_write_size_conf;
- }
-
- if (conf->upstream.temp_file_write_size < size) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"proxy_temp_file_write_size\" must be equal to or greater "
- "than the maximum of the value of \"proxy_buffer_size\" and "
- "one of the \"proxy_buffers\"");
-
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_size_value(conf->upstream.max_temp_file_size_conf,
- prev->upstream.max_temp_file_size_conf,
- NGX_CONF_UNSET_SIZE);
-
- if (conf->upstream.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) {
- conf->upstream.max_temp_file_size = 1024 * 1024 * 1024;
- } else {
- conf->upstream.max_temp_file_size =
- conf->upstream.max_temp_file_size_conf;
- }
-
- if (conf->upstream.max_temp_file_size != 0
- && conf->upstream.max_temp_file_size < size)
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"proxy_max_temp_file_size\" must be equal to zero to disable "
- "temporary files usage or must be equal to or greater than "
- "the maximum of the value of \"proxy_buffer_size\" and "
- "one of the \"proxy_buffers\"");
-
- return NGX_CONF_ERROR;
- }
-
-
- ngx_conf_merge_bitmask_value(conf->upstream.ignore_headers,
- prev->upstream.ignore_headers,
- NGX_CONF_BITMASK_SET);
-
-
- ngx_conf_merge_bitmask_value(conf->upstream.next_upstream,
- prev->upstream.next_upstream,
- (NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_ERROR
- |NGX_HTTP_UPSTREAM_FT_TIMEOUT));
-
- if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) {
- conf->upstream.next_upstream = NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_OFF;
- }
-
- if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,
- prev->upstream.temp_path,
- &ngx_http_proxy_temp_path)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
-
-#if (NGX_HTTP_CACHE)
-
- ngx_conf_merge_ptr_value(conf->upstream.cache,
- prev->upstream.cache, NULL);
-
- if (conf->upstream.cache && conf->upstream.cache->data == NULL) {
- ngx_shm_zone_t *shm_zone;
-
- shm_zone = conf->upstream.cache;
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"proxy_cache\" zone \"%V\" is unknown",
- &shm_zone->shm.name);
-
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_uint_value(conf->upstream.cache_min_uses,
- prev->upstream.cache_min_uses, 1);
-
- ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale,
- prev->upstream.cache_use_stale,
- (NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_OFF));
-
- if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) {
- conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_OFF;
- }
-
- if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_ERROR) {
- conf->upstream.cache_use_stale |= NGX_HTTP_UPSTREAM_FT_NOLIVE;
- }
-
- if (conf->upstream.cache_methods == 0) {
- conf->upstream.cache_methods = prev->upstream.cache_methods;
- }
-
- conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
-
- ngx_conf_merge_ptr_value(conf->upstream.cache_bypass,
- prev->upstream.cache_bypass, NULL);
-
- ngx_conf_merge_ptr_value(conf->upstream.no_cache,
- prev->upstream.no_cache, NULL);
-
- ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
- prev->upstream.cache_valid, NULL);
-
- if (conf->cache_key.value.data == NULL) {
- conf->cache_key = prev->cache_key;
- }
-
- ngx_conf_merge_value(conf->upstream.cache_lock,
- prev->upstream.cache_lock, 0);
-
- ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout,
- prev->upstream.cache_lock_timeout, 5000);
-
- ngx_conf_merge_value(conf->upstream.cache_revalidate,
- prev->upstream.cache_revalidate, 0);
-
-#endif
-
- ngx_conf_merge_str_value(conf->method, prev->method, "");
-
- if (conf->method.len
- && conf->method.data[conf->method.len - 1] != ' ')
- {
- conf->method.data[conf->method.len] = ' ';
- conf->method.len++;
- }
-
- ngx_conf_merge_value(conf->upstream.pass_request_headers,
- prev->upstream.pass_request_headers, 1);
- ngx_conf_merge_value(conf->upstream.pass_request_body,
- prev->upstream.pass_request_body, 1);
-
- ngx_conf_merge_value(conf->upstream.intercept_errors,
- prev->upstream.intercept_errors, 0);
-
-#if (NGX_HTTP_SSL)
- ngx_conf_merge_value(conf->upstream.ssl_session_reuse,
- prev->upstream.ssl_session_reuse, 1);
-
- ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
- (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3
- |NGX_SSL_TLSv1|NGX_SSL_TLSv1_1
- |NGX_SSL_TLSv1_2));
-
- ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
- "DEFAULT");
-
- if (conf->ssl && ngx_http_proxy_set_ssl(cf, conf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-#endif
-
- ngx_conf_merge_value(conf->redirect, prev->redirect, 1);
-
- if (conf->redirect) {
-
- if (conf->redirects == NULL) {
- conf->redirects = prev->redirects;
- }
-
- if (conf->redirects == NULL && conf->url.data) {
-
- conf->redirects = ngx_array_create(cf->pool, 1,
- sizeof(ngx_http_proxy_rewrite_t));
- if (conf->redirects == NULL) {
- return NGX_CONF_ERROR;
- }
-
- pr = ngx_array_push(conf->redirects);
- if (pr == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(&pr->pattern.complex,
- sizeof(ngx_http_complex_value_t));
-
- ngx_memzero(&pr->replacement, sizeof(ngx_http_complex_value_t));
-
- pr->handler = ngx_http_proxy_rewrite_complex_handler;
-
- if (conf->vars.uri.len) {
- pr->pattern.complex.value = conf->url;
- pr->replacement.value = conf->location;
-
- } else {
- pr->pattern.complex.value.len = conf->url.len
- + sizeof("/") - 1;
-
- p = ngx_pnalloc(cf->pool, pr->pattern.complex.value.len);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- pr->pattern.complex.value.data = p;
-
- p = ngx_cpymem(p, conf->url.data, conf->url.len);
- *p = '/';
-
- ngx_str_set(&pr->replacement.value, "/");
- }
- }
- }
-
- ngx_conf_merge_ptr_value(conf->cookie_domains, prev->cookie_domains, NULL);
-
- ngx_conf_merge_ptr_value(conf->cookie_paths, prev->cookie_paths, NULL);
-
-#if (NGX_HTTP_SSL)
- if (conf->upstream.ssl == NULL) {
- conf->upstream.ssl = prev->upstream.ssl;
- }
-#endif
-
- ngx_conf_merge_uint_value(conf->http_version, prev->http_version,
- NGX_HTTP_VERSION_10);
-
- ngx_conf_merge_uint_value(conf->headers_hash_max_size,
- prev->headers_hash_max_size, 512);
-
- ngx_conf_merge_uint_value(conf->headers_hash_bucket_size,
- prev->headers_hash_bucket_size, 64);
-
- conf->headers_hash_bucket_size = ngx_align(conf->headers_hash_bucket_size,
- ngx_cacheline_size);
-
- hash.max_size = conf->headers_hash_max_size;
- hash.bucket_size = conf->headers_hash_bucket_size;
- hash.name = "proxy_headers_hash";
-
- if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
- &prev->upstream, ngx_http_proxy_hide_headers, &hash)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- if (conf->upstream.upstream == NULL) {
- conf->upstream.upstream = prev->upstream.upstream;
- conf->vars = prev->vars;
- }
-
- if (conf->proxy_lengths == NULL) {
- conf->proxy_lengths = prev->proxy_lengths;
- conf->proxy_values = prev->proxy_values;
- }
-
- if (conf->upstream.upstream || conf->proxy_lengths) {
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
- if (clcf->handler == NULL && clcf->lmt_excpt) {
- clcf->handler = ngx_http_proxy_handler;
- conf->location = prev->location;
- }
- }
-
- if (conf->body_source.data == NULL) {
- conf->body_source = prev->body_source;
- conf->body_set_len = prev->body_set_len;
- conf->body_set = prev->body_set;
- }
-
- if (conf->body_source.data && conf->body_set_len == NULL) {
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = &conf->body_source;
- sc.flushes = &conf->flushes;
- sc.lengths = &conf->body_set_len;
- sc.values = &conf->body_set;
- sc.complete_lengths = 1;
- sc.complete_values = 1;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- if (ngx_http_proxy_merge_headers(cf, conf, prev) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_merge_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf,
- ngx_http_proxy_loc_conf_t *prev)
-{
- u_char *p;
- size_t size;
- uintptr_t *code;
- ngx_uint_t i;
- ngx_array_t headers_names, headers_merged;
- ngx_keyval_t *src, *s, *h;
- 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->headers_source == NULL) {
- conf->flushes = prev->flushes;
- conf->headers_set_len = prev->headers_set_len;
- conf->headers_set = prev->headers_set;
- conf->headers_set_hash = prev->headers_set_hash;
- conf->headers_source = prev->headers_source;
- }
-
- if (conf->headers_set_hash.buckets
-#if (NGX_HTTP_CACHE)
- && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL))
-#endif
- )
- {
- return NGX_OK;
- }
-
-
- if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&headers_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (conf->headers_source == NULL) {
- conf->headers_source = ngx_array_create(cf->pool, 4,
- sizeof(ngx_keyval_t));
- if (conf->headers_source == NULL) {
- return NGX_ERROR;
- }
- }
-
- conf->headers_set_len = ngx_array_create(cf->pool, 64, 1);
- if (conf->headers_set_len == NULL) {
- return NGX_ERROR;
- }
-
- conf->headers_set = ngx_array_create(cf->pool, 512, 1);
- if (conf->headers_set == NULL) {
- return NGX_ERROR;
- }
-
-
-#if (NGX_HTTP_CACHE)
-
- h = conf->upstream.cache ? ngx_http_proxy_cache_headers:
- ngx_http_proxy_headers;
-#else
-
- h = ngx_http_proxy_headers;
-
-#endif
-
- src = conf->headers_source->elts;
- for (i = 0; i < conf->headers_source->nelts; i++) {
-
- s = ngx_array_push(&headers_merged);
- if (s == NULL) {
- return NGX_ERROR;
- }
-
- *s = src[i];
- }
-
- while (h->key.len) {
-
- src = headers_merged.elts;
- for (i = 0; i < headers_merged.nelts; i++) {
- if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
- goto next;
- }
- }
-
- s = ngx_array_push(&headers_merged);
- if (s == NULL) {
- return NGX_ERROR;
- }
-
- *s = *h;
-
- next:
-
- h++;
- }
-
-
- src = headers_merged.elts;
- for (i = 0; i < headers_merged.nelts; i++) {
-
- hk = ngx_array_push(&headers_names);
- if (hk == NULL) {
- return NGX_ERROR;
- }
-
- hk->key = src[i].key;
- hk->key_hash = ngx_hash_key_lc(src[i].key.data, src[i].key.len);
- hk->value = (void *) 1;
-
- if (src[i].value.len == 0) {
- continue;
- }
-
- if (ngx_http_script_variables_count(&src[i].value) == 0) {
- copy = ngx_array_push_n(conf->headers_set_len,
- sizeof(ngx_http_script_copy_code_t));
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = (ngx_http_script_code_pt)
- ngx_http_script_copy_len_code;
- copy->len = src[i].key.len + sizeof(": ") - 1
- + src[i].value.len + sizeof(CRLF) - 1;
-
-
- size = (sizeof(ngx_http_script_copy_code_t)
- + src[i].key.len + sizeof(": ") - 1
- + src[i].value.len + sizeof(CRLF) - 1
- + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
-
- copy = ngx_array_push_n(conf->headers_set, size);
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = ngx_http_script_copy_code;
- copy->len = src[i].key.len + sizeof(": ") - 1
- + src[i].value.len + sizeof(CRLF) - 1;
-
- p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
-
- p = ngx_cpymem(p, src[i].key.data, src[i].key.len);
- *p++ = ':'; *p++ = ' ';
- p = ngx_cpymem(p, src[i].value.data, src[i].value.len);
- *p++ = CR; *p = LF;
-
- } else {
- copy = ngx_array_push_n(conf->headers_set_len,
- sizeof(ngx_http_script_copy_code_t));
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = (ngx_http_script_code_pt)
- ngx_http_script_copy_len_code;
- copy->len = src[i].key.len + sizeof(": ") - 1;
-
-
- size = (sizeof(ngx_http_script_copy_code_t)
- + src[i].key.len + sizeof(": ") - 1 + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
-
- copy = ngx_array_push_n(conf->headers_set, size);
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = ngx_http_script_copy_code;
- copy->len = src[i].key.len + sizeof(": ") - 1;
-
- p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
- p = ngx_cpymem(p, src[i].key.data, src[i].key.len);
- *p++ = ':'; *p = ' ';
-
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = &src[i].value;
- sc.flushes = &conf->flushes;
- sc.lengths = &conf->headers_set_len;
- sc.values = &conf->headers_set;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_ERROR;
- }
-
-
- copy = ngx_array_push_n(conf->headers_set_len,
- sizeof(ngx_http_script_copy_code_t));
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = (ngx_http_script_code_pt)
- ngx_http_script_copy_len_code;
- copy->len = sizeof(CRLF) - 1;
-
-
- size = (sizeof(ngx_http_script_copy_code_t)
- + sizeof(CRLF) - 1 + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
-
- copy = ngx_array_push_n(conf->headers_set, size);
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = ngx_http_script_copy_code;
- copy->len = sizeof(CRLF) - 1;
-
- p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
- *p++ = CR; *p = LF;
- }
-
- code = ngx_array_push_n(conf->headers_set_len, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
-
- code = ngx_array_push_n(conf->headers_set, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
- }
-
- code = ngx_array_push_n(conf->headers_set_len, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
-
-
- hash.hash = &conf->headers_set_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;
-
- return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts);
-}
-
-
-static char *
-ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_proxy_loc_conf_t *plcf = conf;
-
- size_t add;
- u_short port;
- ngx_str_t *value, *url;
- ngx_url_t u;
- ngx_uint_t n;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_script_compile_t sc;
-
- if (plcf->upstream.upstream || plcf->proxy_lengths) {
- return "is duplicate";
- }
-
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
-
- clcf->handler = ngx_http_proxy_handler;
-
- if (clcf->name.data[clcf->name.len - 1] == '/') {
- clcf->auto_redirect = 1;
- }
-
- value = cf->args->elts;
-
- url = &value[1];
-
- n = ngx_http_script_variables_count(url);
-
- if (n) {
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = url;
- sc.lengths = &plcf->proxy_lengths;
- sc.values = &plcf->proxy_values;
- sc.variables = n;
- sc.complete_lengths = 1;
- sc.complete_values = 1;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
-#if (NGX_HTTP_SSL)
- plcf->ssl = 1;
-#endif
-
- return NGX_CONF_OK;
- }
-
- if (ngx_strncasecmp(url->data, (u_char *) "http://", 7) == 0) {
- add = 7;
- port = 80;
-
- } else if (ngx_strncasecmp(url->data, (u_char *) "https://", 8) == 0) {
-
-#if (NGX_HTTP_SSL)
- plcf->ssl = 1;
-
- add = 8;
- port = 443;
-#else
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "https protocol requires SSL support");
- return NGX_CONF_ERROR;
-#endif
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid URL prefix");
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- u.url.len = url->len - add;
- u.url.data = url->data + add;
- u.default_port = port;
- u.uri_part = 1;
- u.no_resolve = 1;
-
- plcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
- if (plcf->upstream.upstream == NULL) {
- return NGX_CONF_ERROR;
- }
-
- plcf->vars.schema.len = add;
- plcf->vars.schema.data = url->data;
- plcf->vars.key_start = plcf->vars.schema;
-
- ngx_http_proxy_set_vars(&u, &plcf->vars);
-
- plcf->location = clcf->name;
-
- if (clcf->named
-#if (NGX_PCRE)
- || clcf->regex
-#endif
- || clcf->noname)
- {
- if (plcf->vars.uri.len) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"proxy_pass\" cannot have URI part in "
- "location given by regular expression, "
- "or inside named location, "
- "or inside \"if\" statement, "
- "or inside \"limit_except\" block");
- return NGX_CONF_ERROR;
- }
-
- plcf->location.len = 0;
- }
-
- plcf->url = *url;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_proxy_loc_conf_t *plcf = conf;
-
- u_char *p;
- ngx_str_t *value;
- ngx_http_proxy_rewrite_t *pr;
- ngx_http_compile_complex_value_t ccv;
-
- if (plcf->redirect == 0) {
- return NGX_CONF_OK;
- }
-
- plcf->redirect = 1;
-
- value = cf->args->elts;
-
- if (cf->args->nelts == 2) {
- if (ngx_strcmp(value[1].data, "off") == 0) {
- plcf->redirect = 0;
- plcf->redirects = NULL;
- return NGX_CONF_OK;
- }
-
- if (ngx_strcmp(value[1].data, "false") == 0) {
- ngx_conf_log_error(NGX_LOG_ERR, cf, 0,
- "invalid parameter \"false\", use \"off\" instead");
- plcf->redirect = 0;
- plcf->redirects = NULL;
- return NGX_CONF_OK;
- }
-
- if (ngx_strcmp(value[1].data, "default") != 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
- }
-
- if (plcf->redirects == NULL) {
- plcf->redirects = ngx_array_create(cf->pool, 1,
- sizeof(ngx_http_proxy_rewrite_t));
- if (plcf->redirects == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- pr = ngx_array_push(plcf->redirects);
- if (pr == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (ngx_strcmp(value[1].data, "default") == 0) {
- if (plcf->proxy_lengths) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"proxy_redirect default\" cannot be used "
- "with \"proxy_pass\" directive with variables");
- return NGX_CONF_ERROR;
- }
-
- if (plcf->url.data == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"proxy_redirect default\" should be placed "
- "after the \"proxy_pass\" directive");
- return NGX_CONF_ERROR;
- }
-
- pr->handler = ngx_http_proxy_rewrite_complex_handler;
-
- ngx_memzero(&pr->pattern.complex, sizeof(ngx_http_complex_value_t));
-
- ngx_memzero(&pr->replacement, sizeof(ngx_http_complex_value_t));
-
- if (plcf->vars.uri.len) {
- pr->pattern.complex.value = plcf->url;
- pr->replacement.value = plcf->location;
-
- } else {
- pr->pattern.complex.value.len = plcf->url.len + sizeof("/") - 1;
-
- p = ngx_pnalloc(cf->pool, pr->pattern.complex.value.len);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- pr->pattern.complex.value.data = p;
-
- p = ngx_cpymem(p, plcf->url.data, plcf->url.len);
- *p = '/';
-
- ngx_str_set(&pr->replacement.value, "/");
- }
-
- return NGX_CONF_OK;
- }
-
-
- if (value[1].data[0] == '~') {
- value[1].len--;
- value[1].data++;
-
- if (value[1].data[0] == '*') {
- value[1].len--;
- value[1].data++;
-
- if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 1) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- } else {
- if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- } else {
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &pr->pattern.complex;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- pr->handler = ngx_http_proxy_rewrite_complex_handler;
- }
-
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[2];
- ccv.complex_value = &pr->replacement;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_proxy_cookie_domain(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_proxy_loc_conf_t *plcf = conf;
-
- ngx_str_t *value;
- ngx_http_proxy_rewrite_t *pr;
- ngx_http_compile_complex_value_t ccv;
-
- if (plcf->cookie_domains == NULL) {
- return NGX_CONF_OK;
- }
-
- value = cf->args->elts;
-
- if (cf->args->nelts == 2) {
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- plcf->cookie_domains = NULL;
- return NGX_CONF_OK;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- if (plcf->cookie_domains == NGX_CONF_UNSET_PTR) {
- plcf->cookie_domains = ngx_array_create(cf->pool, 1,
- sizeof(ngx_http_proxy_rewrite_t));
- if (plcf->cookie_domains == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- pr = ngx_array_push(plcf->cookie_domains);
- if (pr == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (value[1].data[0] == '~') {
- value[1].len--;
- value[1].data++;
-
- if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 1) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- } else {
-
- if (value[1].data[0] == '.') {
- value[1].len--;
- value[1].data++;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &pr->pattern.complex;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- pr->handler = ngx_http_proxy_rewrite_domain_handler;
-
- if (value[2].data[0] == '.') {
- value[2].len--;
- value[2].data++;
- }
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[2];
- ccv.complex_value = &pr->replacement;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_proxy_cookie_path(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_proxy_loc_conf_t *plcf = conf;
-
- ngx_str_t *value;
- ngx_http_proxy_rewrite_t *pr;
- ngx_http_compile_complex_value_t ccv;
-
- if (plcf->cookie_paths == NULL) {
- return NGX_CONF_OK;
- }
-
- value = cf->args->elts;
-
- if (cf->args->nelts == 2) {
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- plcf->cookie_paths = NULL;
- return NGX_CONF_OK;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- if (plcf->cookie_paths == NGX_CONF_UNSET_PTR) {
- plcf->cookie_paths = ngx_array_create(cf->pool, 1,
- sizeof(ngx_http_proxy_rewrite_t));
- if (plcf->cookie_paths == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- pr = ngx_array_push(plcf->cookie_paths);
- if (pr == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (value[1].data[0] == '~') {
- value[1].len--;
- value[1].data++;
-
- if (value[1].data[0] == '*') {
- value[1].len--;
- value[1].data++;
-
- if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 1) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- } else {
- if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- } else {
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &pr->pattern.complex;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- pr->handler = ngx_http_proxy_rewrite_complex_handler;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[2];
- ccv.complex_value = &pr->replacement;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_proxy_rewrite_regex(ngx_conf_t *cf, ngx_http_proxy_rewrite_t *pr,
- ngx_str_t *regex, ngx_uint_t caseless)
-{
-#if (NGX_PCRE)
- u_char errstr[NGX_MAX_CONF_ERRSTR];
- ngx_regex_compile_t rc;
-
- ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
-
- rc.pattern = *regex;
- rc.err.len = NGX_MAX_CONF_ERRSTR;
- rc.err.data = errstr;
-
- if (caseless) {
- rc.options = NGX_REGEX_CASELESS;
- }
-
- pr->pattern.regex = ngx_http_regex_compile(cf, &rc);
- if (pr->pattern.regex == NULL) {
- return NGX_ERROR;
- }
-
- pr->handler = ngx_http_proxy_rewrite_regex_handler;
-
- return NGX_OK;
-
-#else
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "using regex \"%V\" requires PCRE library", regex);
- return NGX_ERROR;
-
-#endif
-}
-
-
-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, "off") == 0) {
- plcf->upstream.store = 0;
- return NGX_CONF_OK;
- }
-
-#if (NGX_HTTP_CACHE)
-
- if (plcf->upstream.cache != NGX_CONF_UNSET_PTR
- && plcf->upstream.cache != NULL)
- {
- return "is incompatible with \"proxy_cache\"";
- }
-
-#endif
-
- if (ngx_strcmp(value[1].data, "on") == 0) {
- plcf->upstream.store = 1;
- return NGX_CONF_OK;
- }
-
- /* 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;
-}
-
-
-#if (NGX_HTTP_CACHE)
-
-static char *
-ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_proxy_loc_conf_t *plcf = conf;
-
- ngx_str_t *value;
-
- value = cf->args->elts;
-
- if (plcf->upstream.cache != NGX_CONF_UNSET_PTR) {
- return "is duplicate";
- }
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- plcf->upstream.cache = NULL;
- return NGX_CONF_OK;
- }
-
- if (plcf->upstream.store > 0 || plcf->upstream.store_lengths) {
- return "is incompatible with \"proxy_store\"";
- }
-
- plcf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0,
- &ngx_http_proxy_module);
- if (plcf->upstream.cache == NULL) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_proxy_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_proxy_loc_conf_t *plcf = conf;
-
- ngx_str_t *value;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- if (plcf->cache_key.value.data) {
- return "is duplicate";
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &plcf->cache_key;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-#endif
-
-
-static char *
-ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data)
-{
-#if (NGX_FREEBSD)
- ssize_t *np = data;
-
- if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"proxy_send_lowat\" must be less than %d "
- "(sysctl net.inet.tcp.sendspace)",
- ngx_freebsd_net_inet_tcp_sendspace);
-
- return NGX_CONF_ERROR;
- }
-
-#elif !(NGX_HAVE_SO_SNDLOWAT)
- ssize_t *np = data;
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "\"proxy_send_lowat\" is not supported, ignored");
-
- *np = 0;
-
-#endif
-
- return NGX_CONF_OK;
-}
-
-
-#if (NGX_HTTP_SSL)
-
-static ngx_int_t
-ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf)
-{
- ngx_pool_cleanup_t *cln;
-
- plcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
- if (plcf->upstream.ssl == NULL) {
- return NGX_ERROR;
- }
-
- plcf->upstream.ssl->log = cf->log;
-
- if (ngx_ssl_create(plcf->upstream.ssl, plcf->ssl_protocols, NULL)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (SSL_CTX_set_cipher_list(plcf->upstream.ssl->ctx,
- (const char *) plcf->ssl_ciphers.data)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
- "SSL_CTX_set_cipher_list(\"%V\") failed",
- &plcf->ssl_ciphers);
- return NGX_ERROR;
- }
-
- cln = ngx_pool_cleanup_add(cf->pool, 0);
- if (cln == NULL) {
- return NGX_ERROR;
- }
-
- cln->handler = ngx_ssl_cleanup_ctx;
- cln->data = plcf->upstream.ssl;
-
- return NGX_OK;
-}
-
-#endif
-
-
-static void
-ngx_http_proxy_set_vars(ngx_url_t *u, ngx_http_proxy_vars_t *v)
-{
- if (u->family != AF_UNIX) {
-
- if (u->no_port || u->port == u->default_port) {
-
- v->host_header = u->host;
-
- if (u->default_port == 80) {
- ngx_str_set(&v->port, "80");
-
- } else {
- ngx_str_set(&v->port, "443");
- }
-
- } else {
- v->host_header.len = u->host.len + 1 + u->port_text.len;
- v->host_header.data = u->host.data;
- v->port = u->port_text;
- }
-
- v->key_start.len += v->host_header.len;
-
- } else {
- ngx_str_set(&v->host_header, "localhost");
- ngx_str_null(&v->port);
- v->key_start.len += sizeof("unix:") - 1 + u->host.len + 1;
- }
-
- v->uri = u->uri;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_random_index_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_random_index_module.c
deleted file mode 100644
index b0f0e080912..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_random_index_module.c
+++ /dev/null
@@ -1,317 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_flag_t enable;
-} ngx_http_random_index_loc_conf_t;
-
-
-#define NGX_HTTP_RANDOM_INDEX_PREALLOCATE 50
-
-
-static ngx_int_t ngx_http_random_index_error(ngx_http_request_t *r,
- ngx_dir_t *dir, ngx_str_t *name);
-static ngx_int_t ngx_http_random_index_init(ngx_conf_t *cf);
-static void *ngx_http_random_index_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_random_index_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
-
-
-static ngx_command_t ngx_http_random_index_commands[] = {
-
- { ngx_string("random_index"),
- NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_random_index_loc_conf_t, enable),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_random_index_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_random_index_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_random_index_create_loc_conf, /* create location configuration */
- ngx_http_random_index_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_random_index_module = {
- NGX_MODULE_V1,
- &ngx_http_random_index_module_ctx, /* module context */
- ngx_http_random_index_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_random_index_handler(ngx_http_request_t *r)
-{
- u_char *last, *filename;
- size_t len, allocated, root;
- ngx_err_t err;
- ngx_int_t rc;
- ngx_str_t path, uri, *name;
- ngx_dir_t dir;
- ngx_uint_t n, level;
- ngx_array_t names;
- ngx_http_random_index_loc_conf_t *rlcf;
-
- if (r->uri.data[r->uri.len - 1] != '/') {
- return NGX_DECLINED;
- }
-
- if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) {
- return NGX_DECLINED;
- }
-
- rlcf = ngx_http_get_module_loc_conf(r, ngx_http_random_index_module);
-
- if (!rlcf->enable) {
- return NGX_DECLINED;
- }
-
-#if (NGX_HAVE_D_TYPE)
- len = NGX_DIR_MASK_LEN;
-#else
- len = NGX_HTTP_RANDOM_INDEX_PREALLOCATE;
-#endif
-
- last = ngx_http_map_uri_to_path(r, &path, &root, len);
- if (last == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- allocated = path.len;
-
- path.len = last - path.data - 1;
- path.data[path.len] = '\0';
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http random index: \"%s\"", path.data);
-
- if (ngx_open_dir(&path, &dir) == NGX_ERROR) {
- err = ngx_errno;
-
- if (err == NGX_ENOENT
- || err == NGX_ENOTDIR
- || err == NGX_ENAMETOOLONG)
- {
- level = NGX_LOG_ERR;
- rc = NGX_HTTP_NOT_FOUND;
-
- } else if (err == NGX_EACCES) {
- level = NGX_LOG_ERR;
- rc = NGX_HTTP_FORBIDDEN;
-
- } else {
- level = NGX_LOG_CRIT;
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ngx_log_error(level, r->connection->log, err,
- ngx_open_dir_n " \"%s\" failed", path.data);
-
- return rc;
- }
-
- if (ngx_array_init(&names, r->pool, 32, sizeof(ngx_str_t)) != NGX_OK) {
- return ngx_http_random_index_error(r, &dir, &path);
- }
-
- filename = path.data;
- filename[path.len] = '/';
-
- for ( ;; ) {
- ngx_set_errno(0);
-
- if (ngx_read_dir(&dir) == NGX_ERROR) {
- err = ngx_errno;
-
- if (err != NGX_ENOMOREFILES) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
- ngx_read_dir_n " \"%V\" failed", &path);
- return ngx_http_random_index_error(r, &dir, &path);
- }
-
- break;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http random index file: \"%s\"", ngx_de_name(&dir));
-
- if (ngx_de_name(&dir)[0] == '.') {
- continue;
- }
-
- len = ngx_de_namelen(&dir);
-
- if (dir.type == 0 || ngx_de_is_link(&dir)) {
-
- /* 1 byte for '/' and 1 byte for terminating '\0' */
-
- if (path.len + 1 + len + 1 > allocated) {
- allocated = path.len + 1 + len + 1
- + NGX_HTTP_RANDOM_INDEX_PREALLOCATE;
-
- filename = ngx_pnalloc(r->pool, allocated);
- if (filename == NULL) {
- return ngx_http_random_index_error(r, &dir, &path);
- }
-
- last = ngx_cpystrn(filename, path.data, path.len + 1);
- *last++ = '/';
- }
-
- ngx_cpystrn(last, ngx_de_name(&dir), len + 1);
-
- if (ngx_de_info(filename, &dir) == NGX_FILE_ERROR) {
- err = ngx_errno;
-
- if (err != NGX_ENOENT) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
- ngx_de_info_n " \"%s\" failed", filename);
- return ngx_http_random_index_error(r, &dir, &path);
- }
-
- if (ngx_de_link_info(filename, &dir) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
- ngx_de_link_info_n " \"%s\" failed",
- filename);
- return ngx_http_random_index_error(r, &dir, &path);
- }
- }
- }
-
- if (!ngx_de_is_file(&dir)) {
- continue;
- }
-
- name = ngx_array_push(&names);
- if (name == NULL) {
- return ngx_http_random_index_error(r, &dir, &path);
- }
-
- name->len = len;
-
- name->data = ngx_pnalloc(r->pool, len);
- if (name->data == NULL) {
- return ngx_http_random_index_error(r, &dir, &path);
- }
-
- ngx_memcpy(name->data, ngx_de_name(&dir), len);
- }
-
- if (ngx_close_dir(&dir) == NGX_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
- ngx_close_dir_n " \"%s\" failed", &path);
- }
-
- n = names.nelts;
-
- if (n == 0) {
- return NGX_DECLINED;
- }
-
- name = names.elts;
-
- n = (ngx_uint_t) (((uint64_t) ngx_random() * n) / 0x80000000);
-
- uri.len = r->uri.len + name[n].len;
-
- uri.data = ngx_pnalloc(r->pool, uri.len);
- if (uri.data == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- last = ngx_copy(uri.data, r->uri.data, r->uri.len);
- ngx_memcpy(last, name[n].data, name[n].len);
-
- return ngx_http_internal_redirect(r, &uri, &r->args);
-}
-
-
-static ngx_int_t
-ngx_http_random_index_error(ngx_http_request_t *r, ngx_dir_t *dir,
- ngx_str_t *name)
-{
- if (ngx_close_dir(dir) == NGX_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
- ngx_close_dir_n " \"%V\" failed", name);
- }
-
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
-}
-
-
-static void *
-ngx_http_random_index_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_random_index_loc_conf_t *conf;
-
- conf = ngx_palloc(cf->pool, sizeof(ngx_http_random_index_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- conf->enable = NGX_CONF_UNSET;
-
- return conf;
-}
-
-
-static char *
-ngx_http_random_index_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_random_index_loc_conf_t *prev = parent;
- ngx_http_random_index_loc_conf_t *conf = child;
-
- ngx_conf_merge_value(conf->enable, prev->enable, 0);
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_random_index_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_random_index_handler;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_range_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_range_filter_module.c
deleted file mode 100644
index 6a65e48498d..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_range_filter_module.c
+++ /dev/null
@@ -1,890 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-/*
- * the single part format:
- *
- * "HTTP/1.0 206 Partial Content" CRLF
- * ... header ...
- * "Content-Type: image/jpeg" CRLF
- * "Content-Length: SIZE" CRLF
- * "Content-Range: bytes START-END/SIZE" CRLF
- * CRLF
- * ... data ...
- *
- *
- * the multipart format:
- *
- * "HTTP/1.0 206 Partial Content" CRLF
- * ... header ...
- * "Content-Type: multipart/byteranges; boundary=0123456789" CRLF
- * CRLF
- * CRLF
- * "--0123456789" CRLF
- * "Content-Type: image/jpeg" CRLF
- * "Content-Range: bytes START0-END0/SIZE" CRLF
- * CRLF
- * ... data ...
- * CRLF
- * "--0123456789" CRLF
- * "Content-Type: image/jpeg" CRLF
- * "Content-Range: bytes START1-END1/SIZE" CRLF
- * CRLF
- * ... data ...
- * CRLF
- * "--0123456789--" CRLF
- */
-
-
-typedef struct {
- off_t start;
- off_t end;
- ngx_str_t content_range;
-} ngx_http_range_t;
-
-
-typedef struct {
- off_t offset;
- ngx_str_t boundary_header;
- ngx_array_t ranges;
-} ngx_http_range_filter_ctx_t;
-
-
-static ngx_int_t ngx_http_range_parse(ngx_http_request_t *r,
- ngx_http_range_filter_ctx_t *ctx, ngx_uint_t ranges);
-static ngx_int_t ngx_http_range_singlepart_header(ngx_http_request_t *r,
- ngx_http_range_filter_ctx_t *ctx);
-static ngx_int_t ngx_http_range_multipart_header(ngx_http_request_t *r,
- ngx_http_range_filter_ctx_t *ctx);
-static ngx_int_t ngx_http_range_not_satisfiable(ngx_http_request_t *r);
-static ngx_int_t ngx_http_range_test_overlapped(ngx_http_request_t *r,
- ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in);
-static ngx_int_t ngx_http_range_singlepart_body(ngx_http_request_t *r,
- ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in);
-static ngx_int_t ngx_http_range_multipart_body(ngx_http_request_t *r,
- ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in);
-
-static ngx_int_t ngx_http_range_header_filter_init(ngx_conf_t *cf);
-static ngx_int_t ngx_http_range_body_filter_init(ngx_conf_t *cf);
-
-
-static ngx_http_module_t ngx_http_range_header_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_range_header_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL, /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_range_header_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_range_header_filter_module_ctx, /* module context */
- NULL, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_module_t ngx_http_range_body_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_range_body_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL, /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_range_body_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_range_body_filter_module_ctx, /* module context */
- NULL, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-
-
-static ngx_int_t
-ngx_http_range_header_filter(ngx_http_request_t *r)
-{
- time_t if_range_time;
- ngx_str_t *if_range, *etag;
- ngx_uint_t ranges;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_range_filter_ctx_t *ctx;
-
- if (r->http_version < NGX_HTTP_VERSION_10
- || r->headers_out.status != NGX_HTTP_OK
- || r != r->main
- || r->headers_out.content_length_n == -1
- || !r->allow_ranges)
- {
- return ngx_http_next_header_filter(r);
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->max_ranges == 0) {
- return ngx_http_next_header_filter(r);
- }
-
- if (r->headers_in.range == NULL
- || r->headers_in.range->value.len < 7
- || ngx_strncasecmp(r->headers_in.range->value.data,
- (u_char *) "bytes=", 6)
- != 0)
- {
- goto next_filter;
- }
-
- if (r->headers_in.if_range) {
-
- if_range = &r->headers_in.if_range->value;
-
- if (if_range->len >= 2 && if_range->data[if_range->len - 1] == '"') {
-
- if (r->headers_out.etag == NULL) {
- goto next_filter;
- }
-
- etag = &r->headers_out.etag->value;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http ir:%V etag:%V", if_range, etag);
-
- if (if_range->len != etag->len
- || ngx_strncmp(if_range->data, etag->data, etag->len) != 0)
- {
- goto next_filter;
- }
-
- goto parse;
- }
-
- if (r->headers_out.last_modified_time == (time_t) -1) {
- goto next_filter;
- }
-
- if_range_time = ngx_http_parse_time(if_range->data, if_range->len);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http ir:%d lm:%d",
- if_range_time, r->headers_out.last_modified_time);
-
- if (if_range_time != r->headers_out.last_modified_time) {
- goto next_filter;
- }
- }
-
-parse:
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_range_filter_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_range_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- ranges = r->single_range ? 1 : clcf->max_ranges;
-
- switch (ngx_http_range_parse(r, ctx, ranges)) {
-
- case NGX_OK:
- ngx_http_set_ctx(r, ctx, ngx_http_range_body_filter_module);
-
- r->headers_out.status = NGX_HTTP_PARTIAL_CONTENT;
- r->headers_out.status_line.len = 0;
-
- if (ctx->ranges.nelts == 1) {
- return ngx_http_range_singlepart_header(r, ctx);
- }
-
- return ngx_http_range_multipart_header(r, ctx);
-
- case NGX_HTTP_RANGE_NOT_SATISFIABLE:
- return ngx_http_range_not_satisfiable(r);
-
- case NGX_ERROR:
- return NGX_ERROR;
-
- default: /* NGX_DECLINED */
- break;
- }
-
-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;
- ngx_str_set(&r->headers_out.accept_ranges->key, "Accept-Ranges");
- ngx_str_set(&r->headers_out.accept_ranges->value, "bytes");
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_int_t
-ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx,
- ngx_uint_t ranges)
-{
- u_char *p;
- off_t start, end, size, content_length;
- ngx_uint_t suffix;
- ngx_http_range_t *range;
-
- p = r->headers_in.range->value.data + 6;
- size = 0;
- content_length = r->headers_out.content_length_n;
-
- for ( ;; ) {
- start = 0;
- end = 0;
- suffix = 0;
-
- while (*p == ' ') { p++; }
-
- if (*p != '-') {
- if (*p < '0' || *p > '9') {
- return NGX_HTTP_RANGE_NOT_SATISFIABLE;
- }
-
- while (*p >= '0' && *p <= '9') {
- start = start * 10 + *p++ - '0';
- }
-
- while (*p == ' ') { p++; }
-
- if (*p++ != '-') {
- return NGX_HTTP_RANGE_NOT_SATISFIABLE;
- }
-
- while (*p == ' ') { p++; }
-
- if (*p == ',' || *p == '\0') {
- end = content_length;
- goto found;
- }
-
- } else {
- suffix = 1;
- p++;
- }
-
- if (*p < '0' || *p > '9') {
- return NGX_HTTP_RANGE_NOT_SATISFIABLE;
- }
-
- while (*p >= '0' && *p <= '9') {
- end = end * 10 + *p++ - '0';
- }
-
- while (*p == ' ') { p++; }
-
- if (*p != ',' && *p != '\0') {
- return NGX_HTTP_RANGE_NOT_SATISFIABLE;
- }
-
- if (suffix) {
- start = content_length - end;
- end = content_length - 1;
- }
-
- if (end >= content_length) {
- end = content_length;
-
- } else {
- end++;
- }
-
- found:
-
- if (start < end) {
- range = ngx_array_push(&ctx->ranges);
- if (range == NULL) {
- return NGX_ERROR;
- }
-
- range->start = start;
- range->end = end;
-
- size += end - start;
-
- if (ranges-- == 0) {
- return NGX_DECLINED;
- }
- }
-
- if (*p++ != ',') {
- break;
- }
- }
-
- if (ctx->ranges.nelts == 0) {
- return NGX_HTTP_RANGE_NOT_SATISFIABLE;
- }
-
- if (size > content_length) {
- return NGX_DECLINED;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_range_singlepart_header(ngx_http_request_t *r,
- ngx_http_range_filter_ctx_t *ctx)
-{
- ngx_table_elt_t *content_range;
- ngx_http_range_t *range;
-
- content_range = ngx_list_push(&r->headers_out.headers);
- if (content_range == NULL) {
- return NGX_ERROR;
- }
-
- r->headers_out.content_range = content_range;
-
- content_range->hash = 1;
- ngx_str_set(&content_range->key, "Content-Range");
-
- content_range->value.data = ngx_pnalloc(r->pool,
- sizeof("bytes -/") - 1 + 3 * NGX_OFF_T_LEN);
- if (content_range->value.data == NULL) {
- return NGX_ERROR;
- }
-
- /* "Content-Range: bytes SSSS-EEEE/TTTT" header */
-
- range = ctx->ranges.elts;
-
- content_range->value.len = ngx_sprintf(content_range->value.data,
- "bytes %O-%O/%O",
- range->start, range->end - 1,
- r->headers_out.content_length_n)
- - content_range->value.data;
-
- r->headers_out.content_length_n = range->end - range->start;
-
- if (r->headers_out.content_length) {
- r->headers_out.content_length->hash = 0;
- r->headers_out.content_length = NULL;
- }
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_int_t
-ngx_http_range_multipart_header(ngx_http_request_t *r,
- ngx_http_range_filter_ctx_t *ctx)
-{
- size_t len;
- ngx_uint_t i;
- ngx_http_range_t *range;
- ngx_atomic_uint_t boundary;
-
- len = sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN
- + sizeof(CRLF "Content-Type: ") - 1
- + r->headers_out.content_type.len
- + sizeof(CRLF "Content-Range: bytes ") - 1;
-
- if (r->headers_out.content_type_len == r->headers_out.content_type.len
- && r->headers_out.charset.len)
- {
- len += sizeof("; charset=") - 1 + r->headers_out.charset.len;
- }
-
- ctx->boundary_header.data = ngx_pnalloc(r->pool, len);
- if (ctx->boundary_header.data == NULL) {
- return NGX_ERROR;
- }
-
- boundary = ngx_next_temp_number(0);
-
- /*
- * The boundary header of the range:
- * CRLF
- * "--0123456789" CRLF
- * "Content-Type: image/jpeg" CRLF
- * "Content-Range: bytes "
- */
-
- if (r->headers_out.content_type_len == r->headers_out.content_type.len
- && r->headers_out.charset.len)
- {
- ctx->boundary_header.len = ngx_sprintf(ctx->boundary_header.data,
- CRLF "--%0muA" CRLF
- "Content-Type: %V; charset=%V" CRLF
- "Content-Range: bytes ",
- boundary,
- &r->headers_out.content_type,
- &r->headers_out.charset)
- - ctx->boundary_header.data;
-
- } else if (r->headers_out.content_type.len) {
- ctx->boundary_header.len = ngx_sprintf(ctx->boundary_header.data,
- CRLF "--%0muA" CRLF
- "Content-Type: %V" CRLF
- "Content-Range: bytes ",
- boundary,
- &r->headers_out.content_type)
- - ctx->boundary_header.data;
-
- } else {
- ctx->boundary_header.len = ngx_sprintf(ctx->boundary_header.data,
- CRLF "--%0muA" CRLF
- "Content-Range: bytes ",
- boundary)
- - ctx->boundary_header.data;
- }
-
- r->headers_out.content_type.data =
- ngx_pnalloc(r->pool,
- sizeof("Content-Type: multipart/byteranges; boundary=") - 1
- + NGX_ATOMIC_T_LEN);
-
- if (r->headers_out.content_type.data == NULL) {
- return NGX_ERROR;
- }
-
- r->headers_out.content_type_lowcase = NULL;
-
- /* "Content-Type: multipart/byteranges; boundary=0123456789" */
-
- r->headers_out.content_type.len =
- ngx_sprintf(r->headers_out.content_type.data,
- "multipart/byteranges; boundary=%0muA",
- boundary)
- - r->headers_out.content_type.data;
-
- r->headers_out.content_type_len = r->headers_out.content_type.len;
-
- r->headers_out.charset.len = 0;
-
- /* the size of the last boundary CRLF "--0123456789--" CRLF */
-
- len = sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN + sizeof("--" CRLF) - 1;
-
- range = ctx->ranges.elts;
- for (i = 0; i < ctx->ranges.nelts; i++) {
-
- /* the size of the range: "SSSS-EEEE/TTTT" CRLF CRLF */
-
- range[i].content_range.data =
- ngx_pnalloc(r->pool, 3 * NGX_OFF_T_LEN + 2 + 4);
-
- if (range[i].content_range.data == NULL) {
- return NGX_ERROR;
- }
-
- range[i].content_range.len = ngx_sprintf(range[i].content_range.data,
- "%O-%O/%O" CRLF CRLF,
- range[i].start, range[i].end - 1,
- r->headers_out.content_length_n)
- - range[i].content_range.data;
-
- len += ctx->boundary_header.len + range[i].content_range.len
- + (size_t) (range[i].end - range[i].start);
- }
-
- r->headers_out.content_length_n = len;
-
- if (r->headers_out.content_length) {
- r->headers_out.content_length->hash = 0;
- r->headers_out.content_length = NULL;
- }
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_int_t
-ngx_http_range_not_satisfiable(ngx_http_request_t *r)
-{
- ngx_table_elt_t *content_range;
-
- r->headers_out.status = NGX_HTTP_RANGE_NOT_SATISFIABLE;
-
- content_range = ngx_list_push(&r->headers_out.headers);
- if (content_range == NULL) {
- return NGX_ERROR;
- }
-
- r->headers_out.content_range = content_range;
-
- content_range->hash = 1;
- ngx_str_set(&content_range->key, "Content-Range");
-
- content_range->value.data = ngx_pnalloc(r->pool,
- sizeof("bytes */") - 1 + NGX_OFF_T_LEN);
- if (content_range->value.data == NULL) {
- return NGX_ERROR;
- }
-
- content_range->value.len = ngx_sprintf(content_range->value.data,
- "bytes */%O",
- r->headers_out.content_length_n)
- - content_range->value.data;
-
- ngx_http_clear_content_length(r);
-
- return NGX_HTTP_RANGE_NOT_SATISFIABLE;
-}
-
-
-static ngx_int_t
-ngx_http_range_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- ngx_http_range_filter_ctx_t *ctx;
-
- if (in == NULL) {
- return ngx_http_next_body_filter(r, in);
- }
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_range_body_filter_module);
-
- if (ctx == NULL) {
- return ngx_http_next_body_filter(r, in);
- }
-
- if (ctx->ranges.nelts == 1) {
- return ngx_http_range_singlepart_body(r, ctx, in);
- }
-
- /*
- * multipart ranges are supported only if whole body is in a single buffer
- */
-
- if (ngx_buf_special(in->buf)) {
- return ngx_http_next_body_filter(r, in);
- }
-
- if (ngx_http_range_test_overlapped(r, ctx, in) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return ngx_http_range_multipart_body(r, ctx, in);
-}
-
-
-static ngx_int_t
-ngx_http_range_test_overlapped(ngx_http_request_t *r,
- ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in)
-{
- off_t start, last;
- ngx_buf_t *buf;
- ngx_uint_t i;
- ngx_http_range_t *range;
-
- if (ctx->offset) {
- goto overlapped;
- }
-
- buf = in->buf;
-
- if (!buf->last_buf) {
- start = ctx->offset;
- last = ctx->offset + ngx_buf_size(buf);
-
- range = ctx->ranges.elts;
- for (i = 0; i < ctx->ranges.nelts; i++) {
- if (start > range[i].start || last < range[i].end) {
- goto overlapped;
- }
- }
- }
-
- ctx->offset = ngx_buf_size(buf);
-
- return NGX_OK;
-
-overlapped:
-
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "range in overlapped buffers");
-
- return NGX_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_range_singlepart_body(ngx_http_request_t *r,
- ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in)
-{
- off_t start, last;
- ngx_buf_t *buf;
- ngx_chain_t *out, *cl, **ll;
- ngx_http_range_t *range;
-
- out = NULL;
- ll = &out;
- range = ctx->ranges.elts;
-
- for (cl = in; cl; cl = cl->next) {
-
- buf = cl->buf;
-
- start = ctx->offset;
- last = ctx->offset + ngx_buf_size(buf);
-
- ctx->offset = last;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http range body buf: %O-%O", start, last);
-
- if (ngx_buf_special(buf)) {
- *ll = cl;
- ll = &cl->next;
- continue;
- }
-
- if (range->end <= start || range->start >= last) {
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http range body skip");
-
- if (buf->in_file) {
- buf->file_pos = buf->file_last;
- }
-
- buf->pos = buf->last;
- buf->sync = 1;
-
- continue;
- }
-
- if (range->start > start) {
-
- if (buf->in_file) {
- buf->file_pos += range->start - start;
- }
-
- if (ngx_buf_in_memory(buf)) {
- buf->pos += (size_t) (range->start - start);
- }
- }
-
- if (range->end <= last) {
-
- if (buf->in_file) {
- buf->file_last -= last - range->end;
- }
-
- if (ngx_buf_in_memory(buf)) {
- buf->last -= (size_t) (last - range->end);
- }
-
- buf->last_buf = 1;
- *ll = cl;
- cl->next = NULL;
-
- break;
- }
-
- *ll = cl;
- ll = &cl->next;
- }
-
- if (out == NULL) {
- return NGX_OK;
- }
-
- return ngx_http_next_body_filter(r, out);
-}
-
-
-static ngx_int_t
-ngx_http_range_multipart_body(ngx_http_request_t *r,
- ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in)
-{
- ngx_buf_t *b, *buf;
- ngx_uint_t i;
- ngx_chain_t *out, *hcl, *rcl, *dcl, **ll;
- ngx_http_range_t *range;
-
- ll = &out;
- buf = in->buf;
- range = ctx->ranges.elts;
-
- for (i = 0; i < ctx->ranges.nelts; i++) {
-
- /*
- * The boundary header of the range:
- * CRLF
- * "--0123456789" CRLF
- * "Content-Type: image/jpeg" CRLF
- * "Content-Range: bytes "
- */
-
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- b->memory = 1;
- b->pos = ctx->boundary_header.data;
- b->last = ctx->boundary_header.data + ctx->boundary_header.len;
-
- hcl = ngx_alloc_chain_link(r->pool);
- if (hcl == NULL) {
- return NGX_ERROR;
- }
-
- hcl->buf = b;
-
-
- /* "SSSS-EEEE/TTTT" CRLF CRLF */
-
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- b->temporary = 1;
- b->pos = range[i].content_range.data;
- b->last = range[i].content_range.data + range[i].content_range.len;
-
- rcl = ngx_alloc_chain_link(r->pool);
- if (rcl == NULL) {
- return NGX_ERROR;
- }
-
- rcl->buf = b;
-
-
- /* the range data */
-
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- b->in_file = buf->in_file;
- b->temporary = buf->temporary;
- b->memory = buf->memory;
- b->mmap = buf->mmap;
- b->file = buf->file;
-
- if (buf->in_file) {
- b->file_pos = buf->file_pos + range[i].start;
- b->file_last = buf->file_pos + range[i].end;
- }
-
- if (ngx_buf_in_memory(buf)) {
- b->pos = buf->pos + (size_t) range[i].start;
- b->last = buf->pos + (size_t) range[i].end;
- }
-
- dcl = ngx_alloc_chain_link(r->pool);
- if (dcl == NULL) {
- return NGX_ERROR;
- }
-
- dcl->buf = b;
-
- *ll = hcl;
- hcl->next = rcl;
- rcl->next = dcl;
- ll = &dcl->next;
- }
-
- /* the last boundary CRLF "--0123456789--" CRLF */
-
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- b->temporary = 1;
- b->last_buf = 1;
-
- b->pos = ngx_pnalloc(r->pool, sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN
- + sizeof("--" CRLF) - 1);
- if (b->pos == NULL) {
- return NGX_ERROR;
- }
-
- b->last = ngx_cpymem(b->pos, ctx->boundary_header.data,
- sizeof(CRLF "--") - 1 + NGX_ATOMIC_T_LEN);
- *b->last++ = '-'; *b->last++ = '-';
- *b->last++ = CR; *b->last++ = LF;
-
- hcl = ngx_alloc_chain_link(r->pool);
- if (hcl == NULL) {
- return NGX_ERROR;
- }
-
- hcl->buf = b;
- hcl->next = NULL;
-
- *ll = hcl;
-
- return ngx_http_next_body_filter(r, out);
-}
-
-
-static ngx_int_t
-ngx_http_range_header_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_range_header_filter;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_range_body_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_range_body_filter;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_realip_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_realip_module.c
deleted file mode 100644
index 7a621180379..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_realip_module.c
+++ /dev/null
@@ -1,442 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-#define NGX_HTTP_REALIP_XREALIP 0
-#define NGX_HTTP_REALIP_XFWD 1
-#define NGX_HTTP_REALIP_HEADER 2
-#define NGX_HTTP_REALIP_PROXY 3
-
-
-typedef struct {
- ngx_array_t *from; /* array of ngx_cidr_t */
- ngx_uint_t type;
- ngx_uint_t hash;
- ngx_str_t header;
- ngx_flag_t recursive;
-} ngx_http_realip_loc_conf_t;
-
-
-typedef struct {
- ngx_connection_t *connection;
- struct sockaddr *sockaddr;
- socklen_t socklen;
- ngx_str_t addr_text;
-} ngx_http_realip_ctx_t;
-
-
-static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r);
-static ngx_int_t ngx_http_realip_set_addr(ngx_http_request_t *r,
- ngx_addr_t *addr);
-static void ngx_http_realip_cleanup(void *data);
-static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_realip_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static ngx_int_t ngx_http_realip_init(ngx_conf_t *cf);
-
-
-static ngx_command_t ngx_http_realip_commands[] = {
-
- { ngx_string("set_real_ip_from"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_realip_from,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("real_ip_header"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_realip,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("real_ip_recursive"),
- 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_realip_loc_conf_t, recursive),
- NULL },
-
- ngx_null_command
-};
-
-
-
-static ngx_http_module_t ngx_http_realip_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_realip_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_realip_create_loc_conf, /* create location configuration */
- ngx_http_realip_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_realip_module = {
- NGX_MODULE_V1,
- &ngx_http_realip_module_ctx, /* module context */
- ngx_http_realip_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_realip_handler(ngx_http_request_t *r)
-{
- u_char *p;
- size_t len;
- ngx_str_t *value;
- ngx_uint_t i, hash;
- ngx_addr_t addr;
- ngx_array_t *xfwd;
- ngx_list_part_t *part;
- ngx_table_elt_t *header;
- ngx_connection_t *c;
- ngx_http_realip_ctx_t *ctx;
- ngx_http_realip_loc_conf_t *rlcf;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module);
-
- if (ctx) {
- return NGX_DECLINED;
- }
-
- rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module);
-
- if (rlcf->from == NULL) {
- return NGX_DECLINED;
- }
-
- switch (rlcf->type) {
-
- case NGX_HTTP_REALIP_XREALIP:
-
- if (r->headers_in.x_real_ip == NULL) {
- return NGX_DECLINED;
- }
-
- value = &r->headers_in.x_real_ip->value;
- xfwd = NULL;
-
- break;
-
- case NGX_HTTP_REALIP_XFWD:
-
- xfwd = &r->headers_in.x_forwarded_for;
-
- if (xfwd->elts == NULL) {
- return NGX_DECLINED;
- }
-
- value = NULL;
-
- break;
-
- case NGX_HTTP_REALIP_PROXY:
-
- value = &r->connection->proxy_protocol_addr;
-
- if (value->len == 0) {
- return NGX_DECLINED;
- }
-
- xfwd = NULL;
-
- break;
-
- default: /* NGX_HTTP_REALIP_HEADER */
-
- part = &r->headers_in.headers.part;
- header = part->elts;
-
- hash = rlcf->hash;
- len = rlcf->header.len;
- p = rlcf->header.data;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- if (hash == header[i].hash
- && len == header[i].key.len
- && ngx_strncmp(p, header[i].lowcase_key, len) == 0)
- {
- value = &header[i].value;
- xfwd = NULL;
-
- goto found;
- }
- }
-
- return NGX_DECLINED;
- }
-
-found:
-
- c = r->connection;
-
- addr.sockaddr = c->sockaddr;
- addr.socklen = c->socklen;
- /* addr.name = c->addr_text; */
-
- if (ngx_http_get_forwarded_addr(r, &addr, xfwd, value, rlcf->from,
- rlcf->recursive)
- != NGX_DECLINED)
- {
- return ngx_http_realip_set_addr(r, &addr);
- }
-
- return NGX_DECLINED;
-}
-
-
-static ngx_int_t
-ngx_http_realip_set_addr(ngx_http_request_t *r, ngx_addr_t *addr)
-{
- size_t len;
- u_char *p;
- u_char text[NGX_SOCKADDR_STRLEN];
- ngx_connection_t *c;
- ngx_pool_cleanup_t *cln;
- ngx_http_realip_ctx_t *ctx;
-
- cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_realip_ctx_t));
- if (cln == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ctx = cln->data;
- ngx_http_set_ctx(r, ctx, ngx_http_realip_module);
-
- c = r->connection;
-
- len = ngx_sock_ntop(addr->sockaddr, addr->socklen, text,
- NGX_SOCKADDR_STRLEN, 0);
- if (len == 0) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- p = ngx_pnalloc(c->pool, len);
- if (p == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ngx_memcpy(p, text, len);
-
- cln->handler = ngx_http_realip_cleanup;
-
- ctx->connection = c;
- ctx->sockaddr = c->sockaddr;
- ctx->socklen = c->socklen;
- ctx->addr_text = c->addr_text;
-
- c->sockaddr = addr->sockaddr;
- c->socklen = addr->socklen;
- c->addr_text.len = len;
- c->addr_text.data = p;
-
- return NGX_DECLINED;
-}
-
-
-static void
-ngx_http_realip_cleanup(void *data)
-{
- ngx_http_realip_ctx_t *ctx = data;
-
- ngx_connection_t *c;
-
- c = ctx->connection;
-
- c->sockaddr = ctx->sockaddr;
- c->socklen = ctx->socklen;
- c->addr_text = ctx->addr_text;
-}
-
-
-static char *
-ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_realip_loc_conf_t *rlcf = conf;
-
- ngx_int_t rc;
- ngx_str_t *value;
- ngx_cidr_t *cidr;
-
- value = cf->args->elts;
-
- if (rlcf->from == NULL) {
- rlcf->from = ngx_array_create(cf->pool, 2,
- sizeof(ngx_cidr_t));
- if (rlcf->from == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- cidr = ngx_array_push(rlcf->from);
- if (cidr == NULL) {
- return NGX_CONF_ERROR;
- }
-
-#if (NGX_HAVE_UNIX_DOMAIN)
-
- if (ngx_strcmp(value[1].data, "unix:") == 0) {
- cidr->family = AF_UNIX;
- return NGX_CONF_OK;
- }
-
-#endif
-
- rc = ngx_ptocidr(&value[1], 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]);
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_realip_loc_conf_t *rlcf = conf;
-
- ngx_str_t *value;
-
- value = cf->args->elts;
-
- if (ngx_strcmp(value[1].data, "X-Real-IP") == 0) {
- rlcf->type = NGX_HTTP_REALIP_XREALIP;
- return NGX_CONF_OK;
- }
-
- if (ngx_strcmp(value[1].data, "X-Forwarded-For") == 0) {
- rlcf->type = NGX_HTTP_REALIP_XFWD;
- return NGX_CONF_OK;
- }
-
- if (ngx_strcmp(value[1].data, "proxy_protocol") == 0) {
- rlcf->type = NGX_HTTP_REALIP_PROXY;
- return NGX_CONF_OK;
- }
-
- rlcf->type = NGX_HTTP_REALIP_HEADER;
- rlcf->hash = ngx_hash_strlow(value[1].data, value[1].data, value[1].len);
- rlcf->header = value[1];
-
- return NGX_CONF_OK;
-}
-
-
-static void *
-ngx_http_realip_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_realip_loc_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_realip_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->from = NULL;
- * conf->hash = 0;
- * conf->header = { 0, NULL };
- */
-
- conf->type = NGX_CONF_UNSET_UINT;
- conf->recursive = NGX_CONF_UNSET;
-
- return conf;
-}
-
-
-static char *
-ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_realip_loc_conf_t *prev = parent;
- ngx_http_realip_loc_conf_t *conf = child;
-
- if (conf->from == NULL) {
- conf->from = prev->from;
- }
-
- ngx_conf_merge_uint_value(conf->type, prev->type, NGX_HTTP_REALIP_XREALIP);
- ngx_conf_merge_value(conf->recursive, prev->recursive, 0);
-
- if (conf->header.len == 0) {
- conf->hash = prev->hash;
- conf->header = prev->header;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_realip_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_realip_handler;
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_realip_handler;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_referer_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_referer_module.c
deleted file mode 100644
index b417eb227b0..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_referer_module.c
+++ /dev/null
@@ -1,671 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-#define NGX_HTTP_REFERER_NO_URI_PART ((void *) 4)
-
-
-typedef struct {
- ngx_hash_combined_t hash;
-
-#if (NGX_PCRE)
- ngx_array_t *regex;
- ngx_array_t *server_name_regex;
-#endif
-
- ngx_flag_t no_referer;
- ngx_flag_t blocked_referer;
- ngx_flag_t server_names;
-
- ngx_hash_keys_arrays_t *keys;
-
- ngx_uint_t referer_hash_max_size;
- ngx_uint_t referer_hash_bucket_size;
-} ngx_http_referer_conf_t;
-
-
-static void * ngx_http_referer_create_conf(ngx_conf_t *cf);
-static char * ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static char *ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static ngx_int_t ngx_http_add_referer(ngx_conf_t *cf,
- ngx_hash_keys_arrays_t *keys, ngx_str_t *value, ngx_str_t *uri);
-static ngx_int_t ngx_http_add_regex_referer(ngx_conf_t *cf,
- ngx_http_referer_conf_t *rlcf, ngx_str_t *name);
-#if (NGX_PCRE)
-static ngx_int_t ngx_http_add_regex_server_name(ngx_conf_t *cf,
- ngx_http_referer_conf_t *rlcf, ngx_http_regex_t *regex);
-#endif
-static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one,
- const void *two);
-
-
-static ngx_command_t ngx_http_referer_commands[] = {
-
- { ngx_string("valid_referers"),
- NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_valid_referers,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("referer_hash_max_size"),
- NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_referer_conf_t, referer_hash_max_size),
- NULL },
-
- { ngx_string("referer_hash_bucket_size"),
- NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_referer_conf_t, referer_hash_bucket_size),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_referer_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_referer_create_conf, /* create location configuration */
- ngx_http_referer_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_referer_module = {
- NGX_MODULE_V1,
- &ngx_http_referer_module_ctx, /* module context */
- ngx_http_referer_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_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];
-#if (NGX_PCRE)
- ngx_int_t rc;
- ngx_str_t referer;
-#endif
-
- rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module);
-
- if (rlcf->hash.hash.buckets == NULL
- && rlcf->hash.wc_head == NULL
- && rlcf->hash.wc_tail == NULL
-#if (NGX_PCRE)
- && rlcf->regex == NULL
- && rlcf->server_name_regex == NULL
-#endif
- )
- {
- goto valid;
- }
-
- if (r->headers_in.referer == NULL) {
- if (rlcf->no_referer) {
- goto valid;
- }
-
- goto invalid;
- }
-
- len = r->headers_in.referer->value.len;
- ref = r->headers_in.referer->value.data;
-
- if (len >= sizeof("http://i.ru") - 1) {
- last = ref + len;
-
- if (ngx_strncasecmp(ref, (u_char *) "http://", 7) == 0) {
- ref += 7;
- len -= 7;
- goto valid_scheme;
-
- } else if (ngx_strncasecmp(ref, (u_char *) "https://", 8) == 0) {
- ref += 8;
- len -= 8;
- goto valid_scheme;
- }
- }
-
- if (rlcf->blocked_referer) {
- goto valid;
- }
-
- goto invalid;
-
-valid_scheme:
-
- i = 0;
- key = 0;
-
- for (p = ref; p < last; p++) {
- if (*p == '/' || *p == ':') {
- break;
- }
-
- if (i == 256) {
- goto invalid;
- }
-
- buf[i] = ngx_tolower(*p);
- key = ngx_hash(key, buf[i++]);
- }
-
- uri = ngx_hash_find_combined(&rlcf->hash, key, buf, p - ref);
-
- if (uri) {
- goto uri;
- }
-
-#if (NGX_PCRE)
-
- if (rlcf->server_name_regex) {
- referer.len = p - ref;
- referer.data = buf;
-
- rc = ngx_regex_exec_array(rlcf->server_name_regex, &referer,
- r->connection->log);
-
- if (rc == NGX_OK) {
- goto valid;
- }
-
- if (rc == NGX_ERROR) {
- return rc;
- }
-
- /* NGX_DECLINED */
- }
-
- if (rlcf->regex) {
- referer.len = len;
- referer.data = ref;
-
- rc = ngx_regex_exec_array(rlcf->regex, &referer, r->connection->log);
-
- if (rc == NGX_OK) {
- goto valid;
- }
-
- if (rc == NGX_ERROR) {
- return rc;
- }
-
- /* NGX_DECLINED */
- }
-
-#endif
-
-invalid:
-
- *v = ngx_http_variable_true_value;
-
- return NGX_OK;
-
-uri:
-
- for ( /* void */ ; p < last; p++) {
- if (*p == '/') {
- break;
- }
- }
-
- len = last - p;
-
- if (uri == NGX_HTTP_REFERER_NO_URI_PART) {
- goto valid;
- }
-
- if (len < uri->len || ngx_strncmp(uri->data, p, uri->len) != 0) {
- goto invalid;
- }
-
-valid:
-
- *v = ngx_http_variable_null_value;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_referer_create_conf(ngx_conf_t *cf)
-{
- ngx_http_referer_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_referer_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->hash = { NULL };
- * conf->server_names = 0;
- * conf->keys = NULL;
- */
-
-#if (NGX_PCRE)
- conf->regex = NGX_CONF_UNSET_PTR;
- conf->server_name_regex = NGX_CONF_UNSET_PTR;
-#endif
-
- conf->no_referer = NGX_CONF_UNSET;
- conf->blocked_referer = NGX_CONF_UNSET;
- conf->referer_hash_max_size = NGX_CONF_UNSET_UINT;
- conf->referer_hash_bucket_size = NGX_CONF_UNSET_UINT;
-
- return conf;
-}
-
-
-static char *
-ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_referer_conf_t *prev = parent;
- ngx_http_referer_conf_t *conf = child;
-
- ngx_uint_t n;
- ngx_hash_init_t hash;
- ngx_http_server_name_t *sn;
- ngx_http_core_srv_conf_t *cscf;
-
- if (conf->keys == NULL) {
- conf->hash = prev->hash;
-
-#if (NGX_PCRE)
- ngx_conf_merge_ptr_value(conf->regex, prev->regex, NULL);
- ngx_conf_merge_ptr_value(conf->server_name_regex,
- prev->server_name_regex, NULL);
-#endif
- ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0);
- ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0);
- ngx_conf_merge_uint_value(conf->referer_hash_max_size,
- prev->referer_hash_max_size, 2048);
- ngx_conf_merge_uint_value(conf->referer_hash_bucket_size,
- prev->referer_hash_bucket_size, 64);
-
- return NGX_CONF_OK;
- }
-
- if (conf->server_names == 1) {
- cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
-
- 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_server_name(cf, conf, sn[n].regex)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-#endif
-
- if (ngx_http_add_referer(cf, conf->keys, &sn[n].name, NULL)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
- }
- }
-
- if ((conf->no_referer == 1 || conf->blocked_referer == 1)
- && 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 "
- "in the \"valid_referers\" directive "
- "without any valid referer");
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_uint_value(conf->referer_hash_max_size,
- prev->referer_hash_max_size, 2048);
- ngx_conf_merge_uint_value(conf->referer_hash_bucket_size,
- prev->referer_hash_bucket_size, 64);
- conf->referer_hash_bucket_size = ngx_align(conf->referer_hash_bucket_size,
- ngx_cacheline_size);
-
- hash.key = ngx_hash_key_lc;
- hash.max_size = conf->referer_hash_max_size;
- hash.bucket_size = conf->referer_hash_bucket_size;
- hash.name = "referer_hash";
- hash.pool = cf->pool;
-
- if (conf->keys->keys.nelts) {
- hash.hash = &conf->hash.hash;
- hash.temp_pool = NULL;
-
- if (ngx_hash_init(&hash, conf->keys->keys.elts, conf->keys->keys.nelts)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
- }
-
- if (conf->keys->dns_wc_head.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_wc_head.elts,
- conf->keys->dns_wc_head.nelts)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- 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 (NGX_PCRE)
- ngx_conf_merge_ptr_value(conf->regex, prev->regex, NULL);
- ngx_conf_merge_ptr_value(conf->server_name_regex, prev->server_name_regex,
- NULL);
-#endif
-
- if (conf->no_referer == NGX_CONF_UNSET) {
- conf->no_referer = 0;
- }
-
- if (conf->blocked_referer == NGX_CONF_UNSET) {
- conf->blocked_referer = 0;
- }
-
- conf->keys = NULL;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_referer_conf_t *rlcf = conf;
-
- u_char *p;
- ngx_str_t *value, uri, name;
- ngx_uint_t i;
- ngx_http_variable_t *var;
-
- ngx_str_set(&name, "invalid_referer");
-
- var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
- if (var == NULL) {
- return NGX_CONF_ERROR;
- }
-
- var->get_handler = ngx_http_referer_variable;
-
- if (rlcf->keys == NULL) {
- rlcf->keys = ngx_pcalloc(cf->temp_pool, sizeof(ngx_hash_keys_arrays_t));
- if (rlcf->keys == NULL) {
- return NGX_CONF_ERROR;
- }
-
- rlcf->keys->pool = cf->pool;
- rlcf->keys->temp_pool = cf->pool;
-
- if (ngx_hash_keys_array_init(rlcf->keys, NGX_HASH_SMALL) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
- if (value[i].len == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid referer \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (ngx_strcmp(value[i].data, "none") == 0) {
- rlcf->no_referer = 1;
- continue;
- }
-
- if (ngx_strcmp(value[i].data, "blocked") == 0) {
- rlcf->blocked_referer = 1;
- continue;
- }
-
- if (ngx_strcmp(value[i].data, "server_names") == 0) {
- rlcf->server_names = 1;
- continue;
- }
-
- if (value[i].data[0] == '~') {
- if (ngx_http_add_regex_referer(cf, rlcf, &value[i]) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- ngx_str_null(&uri);
-
- p = (u_char *) ngx_strchr(value[i].data, '/');
-
- if (p) {
- uri.len = (value[i].data + value[i].len) - p;
- uri.data = p;
- value[i].len = p - value[i].data;
- }
-
- if (ngx_http_add_referer(cf, rlcf->keys, &value[i], &uri) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
- ngx_str_t *value, ngx_str_t *uri)
-{
- ngx_int_t rc;
- ngx_str_t *u;
-
- if (uri == NULL || uri->len == 0) {
- u = NGX_HTTP_REFERER_NO_URI_PART;
-
- } else {
- u = ngx_palloc(cf->pool, sizeof(ngx_str_t));
- if (u == NULL) {
- return NGX_ERROR;
- }
-
- *u = *uri;
- }
-
- rc = ngx_hash_add_key(keys, value, u, NGX_HASH_WILDCARD_KEY);
-
- if (rc == NGX_OK) {
- return NGX_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);
- }
-
- return NGX_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
- ngx_str_t *name)
-{
-#if (NGX_PCRE)
- ngx_regex_elt_t *re;
- ngx_regex_compile_t rc;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
-
- if (name->len == 1) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty regex in \"%V\"", name);
- return NGX_ERROR;
- }
-
- if (rlcf->regex == NGX_CONF_UNSET_PTR) {
- rlcf->regex = ngx_array_create(cf->pool, 2, sizeof(ngx_regex_elt_t));
- if (rlcf->regex == NULL) {
- return NGX_ERROR;
- }
- }
-
- re = ngx_array_push(rlcf->regex);
- if (re == NULL) {
- return NGX_ERROR;
- }
-
- name->len--;
- name->data++;
-
- ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
-
- rc.pattern = *name;
- rc.pool = cf->pool;
- rc.options = NGX_REGEX_CASELESS;
- rc.err.len = NGX_MAX_CONF_ERRSTR;
- rc.err.data = errstr;
-
- if (ngx_regex_compile(&rc) != NGX_OK) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
- return NGX_ERROR;
- }
-
- re->regex = rc.regex;
- re->name = name->data;
-
- return NGX_OK;
-
-#else
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the using of the regex \"%V\" requires PCRE library",
- name);
-
- return NGX_ERROR;
-
-#endif
-}
-
-
-#if (NGX_PCRE)
-
-static ngx_int_t
-ngx_http_add_regex_server_name(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
- ngx_http_regex_t *regex)
-{
- ngx_regex_elt_t *re;
-
- if (rlcf->server_name_regex == NGX_CONF_UNSET_PTR) {
- rlcf->server_name_regex = ngx_array_create(cf->pool, 2,
- sizeof(ngx_regex_elt_t));
- if (rlcf->server_name_regex == NULL) {
- return NGX_ERROR;
- }
- }
-
- re = ngx_array_push(rlcf->server_name_regex);
- if (re == NULL) {
- return NGX_ERROR;
- }
-
- re->regex = regex->regex;
- re->name = regex->name.data;
-
- return NGX_OK;
-}
-
-#endif
-
-
-static int ngx_libc_cdecl
-ngx_http_cmp_referer_wildcards(const void *one, const void *two)
-{
- ngx_hash_key_t *first, *second;
-
- first = (ngx_hash_key_t *) one;
- second = (ngx_hash_key_t *) two;
-
- return ngx_dns_strcmp(first->key.data, second->key.data);
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_rewrite_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_rewrite_module.c
deleted file mode 100644
index 4081f877433..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_rewrite_module.c
+++ /dev/null
@@ -1,1025 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_array_t *codes; /* uintptr_t */
-
- ngx_uint_t stack_size;
-
- ngx_flag_t log;
- ngx_flag_t uninitialized_variable_warn;
-} ngx_http_rewrite_loc_conf_t;
-
-
-static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static ngx_int_t ngx_http_rewrite_init(ngx_conf_t *cf);
-static char *ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static char *ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_rewrite_break(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char * ngx_http_rewrite_if_condition(ngx_conf_t *cf,
- ngx_http_rewrite_loc_conf_t *lcf);
-static char *ngx_http_rewrite_variable(ngx_conf_t *cf,
- ngx_http_rewrite_loc_conf_t *lcf, ngx_str_t *value);
-static char *ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char * ngx_http_rewrite_value(ngx_conf_t *cf,
- ngx_http_rewrite_loc_conf_t *lcf, ngx_str_t *value);
-
-
-static ngx_command_t ngx_http_rewrite_commands[] = {
-
- { ngx_string("rewrite"),
- NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_TAKE23,
- ngx_http_rewrite,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("return"),
- NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_TAKE12,
- ngx_http_rewrite_return,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("break"),
- NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_NOARGS,
- ngx_http_rewrite_break,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("if"),
- NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE,
- ngx_http_rewrite_if,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("set"),
- NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_TAKE2,
- ngx_http_rewrite_set,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("rewrite_log"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF
- |NGX_HTTP_LIF_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_rewrite_loc_conf_t, log),
- NULL },
-
- { ngx_string("uninitialized_variable_warn"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF
- |NGX_HTTP_LIF_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_rewrite_loc_conf_t, uninitialized_variable_warn),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_rewrite_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_rewrite_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_rewrite_create_loc_conf, /* create location configuration */
- ngx_http_rewrite_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_rewrite_module = {
- NGX_MODULE_V1,
- &ngx_http_rewrite_module_ctx, /* module context */
- ngx_http_rewrite_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_rewrite_handler(ngx_http_request_t *r)
-{
- ngx_int_t index;
- ngx_http_script_code_pt code;
- ngx_http_script_engine_t *e;
- ngx_http_core_srv_conf_t *cscf;
- ngx_http_core_main_conf_t *cmcf;
- ngx_http_rewrite_loc_conf_t *rlcf;
-
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
- index = cmcf->phase_engine.location_rewrite_index;
-
- if (r->phase_handler == index && r->loc_conf == cscf->ctx->loc_conf) {
- /* skipping location rewrite phase for server null location */
- return NGX_DECLINED;
- }
-
- rlcf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module);
-
- if (rlcf->codes == NULL) {
- return NGX_DECLINED;
- }
-
- e = ngx_pcalloc(r->pool, sizeof(ngx_http_script_engine_t));
- if (e == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- e->sp = ngx_pcalloc(r->pool,
- rlcf->stack_size * sizeof(ngx_http_variable_value_t));
- if (e->sp == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- e->ip = rlcf->codes->elts;
- e->request = r;
- e->quote = 1;
- e->log = rlcf->log;
- e->status = NGX_DECLINED;
-
- while (*(uintptr_t *) e->ip) {
- code = *(ngx_http_script_code_pt *) e->ip;
- code(e);
- }
-
- if (e->status < NGX_HTTP_BAD_REQUEST) {
- return e->status;
- }
-
- if (r->err_status == 0) {
- return e->status;
- }
-
- return r->err_status;
-}
-
-
-static ngx_int_t
-ngx_http_rewrite_var(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- ngx_http_variable_t *var;
- ngx_http_core_main_conf_t *cmcf;
- ngx_http_rewrite_loc_conf_t *rlcf;
-
- rlcf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module);
-
- if (rlcf->uninitialized_variable_warn == 0) {
- *v = ngx_http_variable_null_value;
- return NGX_OK;
- }
-
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
- var = cmcf->variables.elts;
-
- /*
- * the ngx_http_rewrite_module sets variables directly in r->variables,
- * and they should be handled by ngx_http_get_indexed_variable(),
- * so the handler is called only if the variable is not initialized
- */
-
- ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
- "using uninitialized \"%V\" variable", &var[data].name);
-
- *v = ngx_http_variable_null_value;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_rewrite_loc_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_rewrite_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- conf->stack_size = NGX_CONF_UNSET_UINT;
- conf->log = NGX_CONF_UNSET;
- conf->uninitialized_variable_warn = NGX_CONF_UNSET;
-
- return conf;
-}
-
-
-static char *
-ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_rewrite_loc_conf_t *prev = parent;
- ngx_http_rewrite_loc_conf_t *conf = child;
-
- uintptr_t *code;
-
- ngx_conf_merge_value(conf->log, prev->log, 0);
- ngx_conf_merge_value(conf->uninitialized_variable_warn,
- prev->uninitialized_variable_warn, 1);
- ngx_conf_merge_uint_value(conf->stack_size, prev->stack_size, 10);
-
- if (conf->codes == NULL) {
- return NGX_CONF_OK;
- }
-
- if (conf->codes == prev->codes) {
- return NGX_CONF_OK;
- }
-
- code = ngx_array_push_n(conf->codes, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *code = (uintptr_t) NULL;
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_rewrite_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_rewrite_handler;
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_rewrite_handler;
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_rewrite_loc_conf_t *lcf = conf;
-
- ngx_str_t *value;
- ngx_uint_t last;
- ngx_regex_compile_t rc;
- ngx_http_script_code_pt *code;
- ngx_http_script_compile_t sc;
- ngx_http_script_regex_code_t *regex;
- ngx_http_script_regex_end_code_t *regex_end;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
-
- regex = ngx_http_script_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_script_regex_code_t));
- if (regex == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t));
-
- value = cf->args->elts;
-
- ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
-
- rc.pattern = value[1];
- rc.err.len = NGX_MAX_CONF_ERRSTR;
- rc.err.data = errstr;
-
- /* TODO: NGX_REGEX_CASELESS */
-
- regex->regex = ngx_http_regex_compile(cf, &rc);
- if (regex->regex == NULL) {
- return NGX_CONF_ERROR;
- }
-
- regex->code = ngx_http_script_regex_start_code;
- regex->uri = 1;
- regex->name = value[1];
-
- if (value[2].data[value[2].len - 1] == '?') {
-
- /* the last "?" drops the original arguments */
- value[2].len--;
-
- } else {
- regex->add_args = 1;
- }
-
- last = 0;
-
- if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0
- || ngx_strncmp(value[2].data, "https://", sizeof("https://") - 1) == 0
- || ngx_strncmp(value[2].data, "$scheme", sizeof("$scheme") - 1) == 0)
- {
- regex->status = NGX_HTTP_MOVED_TEMPORARILY;
- regex->redirect = 1;
- last = 1;
- }
-
- if (cf->args->nelts == 4) {
- if (ngx_strcmp(value[3].data, "last") == 0) {
- last = 1;
-
- } else if (ngx_strcmp(value[3].data, "break") == 0) {
- regex->break_cycle = 1;
- last = 1;
-
- } else if (ngx_strcmp(value[3].data, "redirect") == 0) {
- regex->status = NGX_HTTP_MOVED_TEMPORARILY;
- regex->redirect = 1;
- last = 1;
-
- } else if (ngx_strcmp(value[3].data, "permanent") == 0) {
- regex->status = NGX_HTTP_MOVED_PERMANENTLY;
- regex->redirect = 1;
- last = 1;
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[3]);
- return NGX_CONF_ERROR;
- }
- }
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = &value[2];
- sc.lengths = &regex->lengths;
- sc.values = &lcf->codes;
- sc.variables = ngx_http_script_variables_count(&value[2]);
- sc.main = regex;
- sc.complete_lengths = 1;
- sc.compile_args = !regex->redirect;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- regex = sc.main;
-
- regex->size = sc.size;
- regex->args = sc.args;
-
- if (sc.variables == 0 && !sc.dup_capture) {
- regex->lengths = NULL;
- }
-
- regex_end = ngx_http_script_add_code(lcf->codes,
- sizeof(ngx_http_script_regex_end_code_t),
- &regex);
- if (regex_end == NULL) {
- return NGX_CONF_ERROR;
- }
-
- regex_end->code = ngx_http_script_regex_end_code;
- regex_end->uri = regex->uri;
- regex_end->args = regex->args;
- regex_end->add_args = regex->add_args;
- regex_end->redirect = regex->redirect;
-
- if (last) {
- code = ngx_http_script_add_code(lcf->codes, sizeof(uintptr_t), &regex);
- if (code == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *code = NULL;
- }
-
- regex->next = (u_char *) lcf->codes->elts + lcf->codes->nelts
- - (u_char *) regex;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_rewrite_loc_conf_t *lcf = conf;
-
- u_char *p;
- ngx_str_t *value, *v;
- ngx_http_script_return_code_t *ret;
- ngx_http_compile_complex_value_t ccv;
-
- ret = ngx_http_script_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_script_return_code_t));
- if (ret == NULL) {
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
-
- ngx_memzero(ret, sizeof(ngx_http_script_return_code_t));
-
- ret->code = ngx_http_script_return_code;
-
- p = value[1].data;
-
- ret->status = ngx_atoi(p, value[1].len);
-
- if (ret->status == (uintptr_t) NGX_ERROR) {
-
- if (cf->args->nelts == 2
- && (ngx_strncmp(p, "http://", sizeof("http://") - 1) == 0
- || ngx_strncmp(p, "https://", sizeof("https://") - 1) == 0
- || ngx_strncmp(p, "$scheme", sizeof("$scheme") - 1) == 0))
- {
- ret->status = NGX_HTTP_MOVED_TEMPORARILY;
- v = &value[1];
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid return code \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- } else {
-
- if (ret->status > 999) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid return code \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- if (cf->args->nelts == 2) {
- return NGX_CONF_OK;
- }
-
- v = &value[2];
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = v;
- ccv.complex_value = &ret->text;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_rewrite_break(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_rewrite_loc_conf_t *lcf = conf;
-
- ngx_http_script_code_pt *code;
-
- code = ngx_http_script_start_code(cf->pool, &lcf->codes, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *code = ngx_http_script_break_code;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_rewrite_loc_conf_t *lcf = conf;
-
- void *mconf;
- char *rv;
- u_char *elts;
- ngx_uint_t i;
- ngx_conf_t save;
- ngx_http_module_t *module;
- ngx_http_conf_ctx_t *ctx, *pctx;
- ngx_http_core_loc_conf_t *clcf, *pclcf;
- ngx_http_script_if_code_t *if_code;
- ngx_http_rewrite_loc_conf_t *nlcf;
-
- ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- pctx = cf->ctx;
- ctx->main_conf = pctx->main_conf;
- ctx->srv_conf = pctx->srv_conf;
-
- ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
- if (ctx->loc_conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
- continue;
- }
-
- module = ngx_modules[i]->ctx;
-
- if (module->create_loc_conf) {
-
- mconf = module->create_loc_conf(cf);
- if (mconf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
- }
- }
-
- pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
-
- clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
- clcf->loc_conf = ctx->loc_conf;
- clcf->name = pclcf->name;
- clcf->noname = 1;
-
- if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (ngx_http_rewrite_if_condition(cf, lcf) != NGX_CONF_OK) {
- return NGX_CONF_ERROR;
- }
-
- if_code = ngx_array_push_n(lcf->codes, sizeof(ngx_http_script_if_code_t));
- if (if_code == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if_code->code = ngx_http_script_if_code;
-
- elts = lcf->codes->elts;
-
-
- /* the inner directives must be compiled to the same code array */
-
- nlcf = ctx->loc_conf[ngx_http_rewrite_module.ctx_index];
- nlcf->codes = lcf->codes;
-
-
- save = *cf;
- cf->ctx = ctx;
-
- if (pclcf->name.len == 0) {
- if_code->loc_conf = NULL;
- cf->cmd_type = NGX_HTTP_SIF_CONF;
-
- } else {
- if_code->loc_conf = ctx->loc_conf;
- cf->cmd_type = NGX_HTTP_LIF_CONF;
- }
-
- rv = ngx_conf_parse(cf, NULL);
-
- *cf = save;
-
- if (rv != NGX_CONF_OK) {
- return rv;
- }
-
-
- if (elts != lcf->codes->elts) {
- if_code = (ngx_http_script_if_code_t *)
- ((u_char *) if_code + ((u_char *) lcf->codes->elts - elts));
- }
-
- if_code->next = (u_char *) lcf->codes->elts + lcf->codes->nelts
- - (u_char *) if_code;
-
- /* the code array belong to parent block */
-
- nlcf->codes = NULL;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf)
-{
- u_char *p;
- size_t len;
- ngx_str_t *value;
- ngx_uint_t cur, last;
- ngx_regex_compile_t rc;
- ngx_http_script_code_pt *code;
- ngx_http_script_file_code_t *fop;
- ngx_http_script_regex_code_t *regex;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
-
- value = cf->args->elts;
- last = cf->args->nelts - 1;
-
- if (value[1].len < 1 || value[1].data[0] != '(') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid condition \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- if (value[1].len == 1) {
- cur = 2;
-
- } else {
- cur = 1;
- value[1].len--;
- value[1].data++;
- }
-
- if (value[last].len < 1 || value[last].data[value[last].len - 1] != ')') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid condition \"%V\"", &value[last]);
- return NGX_CONF_ERROR;
- }
-
- if (value[last].len == 1) {
- last--;
-
- } else {
- value[last].len--;
- value[last].data[value[last].len] = '\0';
- }
-
- len = value[cur].len;
- p = value[cur].data;
-
- if (len > 1 && p[0] == '$') {
-
- if (cur != last && cur + 2 != last) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid condition \"%V\"", &value[cur]);
- return NGX_CONF_ERROR;
- }
-
- if (ngx_http_rewrite_variable(cf, lcf, &value[cur]) != NGX_CONF_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (cur == last) {
- return NGX_CONF_OK;
- }
-
- cur++;
-
- len = value[cur].len;
- p = value[cur].data;
-
- if (len == 1 && p[0] == '=') {
-
- if (ngx_http_rewrite_value(cf, lcf, &value[last]) != NGX_CONF_OK) {
- return NGX_CONF_ERROR;
- }
-
- code = ngx_http_script_start_code(cf->pool, &lcf->codes,
- sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *code = ngx_http_script_equal_code;
-
- return NGX_CONF_OK;
- }
-
- if (len == 2 && p[0] == '!' && p[1] == '=') {
-
- if (ngx_http_rewrite_value(cf, lcf, &value[last]) != NGX_CONF_OK) {
- return NGX_CONF_ERROR;
- }
-
- code = ngx_http_script_start_code(cf->pool, &lcf->codes,
- sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *code = ngx_http_script_not_equal_code;
- return NGX_CONF_OK;
- }
-
- if ((len == 1 && p[0] == '~')
- || (len == 2 && p[0] == '~' && p[1] == '*')
- || (len == 2 && p[0] == '!' && p[1] == '~')
- || (len == 3 && p[0] == '!' && p[1] == '~' && p[2] == '*'))
- {
- regex = ngx_http_script_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_script_regex_code_t));
- if (regex == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t));
-
- ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
-
- rc.pattern = value[last];
- rc.options = (p[len - 1] == '*') ? NGX_REGEX_CASELESS : 0;
- rc.err.len = NGX_MAX_CONF_ERRSTR;
- rc.err.data = errstr;
-
- regex->regex = ngx_http_regex_compile(cf, &rc);
- if (regex->regex == NULL) {
- return NGX_CONF_ERROR;
- }
-
- regex->code = ngx_http_script_regex_start_code;
- regex->next = sizeof(ngx_http_script_regex_code_t);
- regex->test = 1;
- if (p[0] == '!') {
- regex->negative_test = 1;
- }
- regex->name = value[last];
-
- return NGX_CONF_OK;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unexpected \"%V\" in condition", &value[cur]);
- return NGX_CONF_ERROR;
-
- } else if ((len == 2 && p[0] == '-')
- || (len == 3 && p[0] == '!' && p[1] == '-'))
- {
- if (cur + 1 != last) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid condition \"%V\"", &value[cur]);
- return NGX_CONF_ERROR;
- }
-
- value[last].data[value[last].len] = '\0';
- value[last].len++;
-
- if (ngx_http_rewrite_value(cf, lcf, &value[last]) != NGX_CONF_OK) {
- return NGX_CONF_ERROR;
- }
-
- fop = ngx_http_script_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_script_file_code_t));
- if (fop == NULL) {
- return NGX_CONF_ERROR;
- }
-
- fop->code = ngx_http_script_file_code;
-
- if (p[1] == 'f') {
- fop->op = ngx_http_script_file_plain;
- return NGX_CONF_OK;
- }
-
- if (p[1] == 'd') {
- fop->op = ngx_http_script_file_dir;
- return NGX_CONF_OK;
- }
-
- if (p[1] == 'e') {
- fop->op = ngx_http_script_file_exists;
- return NGX_CONF_OK;
- }
-
- if (p[1] == 'x') {
- fop->op = ngx_http_script_file_exec;
- return NGX_CONF_OK;
- }
-
- if (p[0] == '!') {
- if (p[2] == 'f') {
- fop->op = ngx_http_script_file_not_plain;
- return NGX_CONF_OK;
- }
-
- if (p[2] == 'd') {
- fop->op = ngx_http_script_file_not_dir;
- return NGX_CONF_OK;
- }
-
- if (p[2] == 'e') {
- fop->op = ngx_http_script_file_not_exists;
- return NGX_CONF_OK;
- }
-
- if (p[2] == 'x') {
- fop->op = ngx_http_script_file_not_exec;
- return NGX_CONF_OK;
- }
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid condition \"%V\"", &value[cur]);
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid condition \"%V\"", &value[cur]);
-
- return NGX_CONF_ERROR;
-}
-
-
-static char *
-ngx_http_rewrite_variable(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf,
- ngx_str_t *value)
-{
- ngx_int_t index;
- ngx_http_script_var_code_t *var_code;
-
- value->len--;
- value->data++;
-
- index = ngx_http_get_variable_index(cf, value);
-
- if (index == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- var_code = ngx_http_script_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_script_var_code_t));
- if (var_code == NULL) {
- return NGX_CONF_ERROR;
- }
-
- var_code->code = ngx_http_script_var_code;
- var_code->index = index;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_rewrite_loc_conf_t *lcf = conf;
-
- ngx_int_t index;
- ngx_str_t *value;
- ngx_http_variable_t *v;
- ngx_http_script_var_code_t *vcode;
- ngx_http_script_var_handler_code_t *vhcode;
-
- value = cf->args->elts;
-
- if (value[1].data[0] != '$') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid variable name \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- value[1].len--;
- value[1].data++;
-
- v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE);
- if (v == NULL) {
- return NGX_CONF_ERROR;
- }
-
- index = ngx_http_get_variable_index(cf, &value[1]);
- if (index == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- if (v->get_handler == NULL
- && ngx_strncasecmp(value[1].data, (u_char *) "http_", 5) != 0
- && ngx_strncasecmp(value[1].data, (u_char *) "sent_http_", 10) != 0
- && ngx_strncasecmp(value[1].data, (u_char *) "upstream_http_", 14) != 0)
- {
- v->get_handler = ngx_http_rewrite_var;
- v->data = index;
- }
-
- if (ngx_http_rewrite_value(cf, lcf, &value[2]) != NGX_CONF_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (v->set_handler) {
- vhcode = ngx_http_script_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_script_var_handler_code_t));
- if (vhcode == NULL) {
- return NGX_CONF_ERROR;
- }
-
- vhcode->code = ngx_http_script_var_set_handler_code;
- vhcode->handler = v->set_handler;
- vhcode->data = v->data;
-
- return NGX_CONF_OK;
- }
-
- vcode = ngx_http_script_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_script_var_code_t));
- if (vcode == NULL) {
- return NGX_CONF_ERROR;
- }
-
- vcode->code = ngx_http_script_set_var_code;
- vcode->index = (uintptr_t) index;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_rewrite_value(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf,
- ngx_str_t *value)
-{
- ngx_int_t n;
- ngx_http_script_compile_t sc;
- ngx_http_script_value_code_t *val;
- ngx_http_script_complex_value_code_t *complex;
-
- n = ngx_http_script_variables_count(value);
-
- if (n == 0) {
- val = ngx_http_script_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_script_value_code_t));
- if (val == NULL) {
- return NGX_CONF_ERROR;
- }
-
- n = ngx_atoi(value->data, value->len);
-
- if (n == NGX_ERROR) {
- n = 0;
- }
-
- val->code = ngx_http_script_value_code;
- val->value = (uintptr_t) n;
- val->text_len = (uintptr_t) value->len;
- val->text_data = (uintptr_t) value->data;
-
- return NGX_CONF_OK;
- }
-
- complex = ngx_http_script_start_code(cf->pool, &lcf->codes,
- sizeof(ngx_http_script_complex_value_code_t));
- if (complex == NULL) {
- return NGX_CONF_ERROR;
- }
-
- complex->code = ngx_http_script_complex_value_code;
- complex->lengths = NULL;
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = value;
- sc.lengths = &complex->lengths;
- sc.values = &lcf->codes;
- sc.variables = n;
- sc.complete_lengths = 1;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_scgi_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_scgi_module.c
deleted file mode 100644
index 884cb500adf..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_scgi_module.c
+++ /dev/null
@@ -1,1810 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- * Copyright (C) Manlio Perillo (manlio.perillo@gmail.com)
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_http_upstream_conf_t upstream;
-
- ngx_array_t *flushes;
- ngx_array_t *params_len;
- ngx_array_t *params;
- ngx_array_t *params_source;
-
- ngx_hash_t headers_hash;
- ngx_uint_t header_params;
-
- ngx_array_t *scgi_lengths;
- ngx_array_t *scgi_values;
-
-#if (NGX_HTTP_CACHE)
- ngx_http_complex_value_t cache_key;
-#endif
-} ngx_http_scgi_loc_conf_t;
-
-
-static ngx_int_t ngx_http_scgi_eval(ngx_http_request_t *r,
- ngx_http_scgi_loc_conf_t *scf);
-static ngx_int_t ngx_http_scgi_create_request(ngx_http_request_t *r);
-static ngx_int_t ngx_http_scgi_reinit_request(ngx_http_request_t *r);
-static ngx_int_t ngx_http_scgi_process_status_line(ngx_http_request_t *r);
-static ngx_int_t ngx_http_scgi_process_header(ngx_http_request_t *r);
-static void ngx_http_scgi_abort_request(ngx_http_request_t *r);
-static void ngx_http_scgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc);
-
-static void *ngx_http_scgi_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static ngx_int_t ngx_http_scgi_merge_params(ngx_conf_t *cf,
- ngx_http_scgi_loc_conf_t *conf, ngx_http_scgi_loc_conf_t *prev);
-
-static char *ngx_http_scgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static char *ngx_http_scgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-#if (NGX_HTTP_CACHE)
-static ngx_int_t ngx_http_scgi_create_key(ngx_http_request_t *r);
-static char *ngx_http_scgi_cache(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_scgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-#endif
-
-
-static ngx_conf_bitmask_t ngx_http_scgi_next_upstream_masks[] = {
- { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
- { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
- { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
- { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
- { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
- { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
- { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
- { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
- { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
- { ngx_null_string, 0 }
-};
-
-
-ngx_module_t ngx_http_scgi_module;
-
-
-static ngx_command_t ngx_http_scgi_commands[] = {
-
- { ngx_string("scgi_pass"),
- NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
- ngx_http_scgi_pass,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("scgi_store"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_scgi_store,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("scgi_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_scgi_loc_conf_t, upstream.store_access),
- NULL },
-
- { ngx_string("scgi_buffering"),
- 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_scgi_loc_conf_t, upstream.buffering),
- NULL },
-
- { ngx_string("scgi_ignore_client_abort"),
- 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_scgi_loc_conf_t, upstream.ignore_client_abort),
- NULL },
-
- { ngx_string("scgi_bind"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_upstream_bind_set_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.local),
- NULL },
-
- { ngx_string("scgi_connect_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.connect_timeout),
- NULL },
-
- { ngx_string("scgi_send_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.send_timeout),
- NULL },
-
- { ngx_string("scgi_buffer_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.buffer_size),
- NULL },
-
- { ngx_string("scgi_pass_request_headers"),
- 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_scgi_loc_conf_t, upstream.pass_request_headers),
- NULL },
-
- { ngx_string("scgi_pass_request_body"),
- 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_scgi_loc_conf_t, upstream.pass_request_body),
- NULL },
-
- { ngx_string("scgi_intercept_errors"),
- 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_scgi_loc_conf_t, upstream.intercept_errors),
- NULL },
-
- { ngx_string("scgi_read_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.read_timeout),
- NULL },
-
- { ngx_string("scgi_buffers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_conf_set_bufs_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.bufs),
- NULL },
-
- { ngx_string("scgi_busy_buffers_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.busy_buffers_size_conf),
- NULL },
-
-#if (NGX_HTTP_CACHE)
-
- { ngx_string("scgi_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_scgi_cache,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("scgi_cache_key"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_scgi_cache_key,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("scgi_cache_path"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE,
- ngx_http_file_cache_set_slot,
- 0,
- 0,
- &ngx_http_scgi_module },
-
- { ngx_string("scgi_cache_bypass"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_set_predicate_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_bypass),
- NULL },
-
- { ngx_string("scgi_no_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_set_predicate_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.no_cache),
- NULL },
-
- { ngx_string("scgi_cache_valid"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_file_cache_valid_set_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_valid),
- NULL },
-
- { ngx_string("scgi_cache_min_uses"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_min_uses),
- NULL },
-
- { ngx_string("scgi_cache_use_stale"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_use_stale),
- &ngx_http_scgi_next_upstream_masks },
-
- { ngx_string("scgi_cache_methods"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_methods),
- &ngx_http_upstream_cache_method_mask },
-
- { ngx_string("scgi_cache_lock"),
- 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_scgi_loc_conf_t, upstream.cache_lock),
- NULL },
-
- { ngx_string("scgi_cache_lock_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_lock_timeout),
- NULL },
-
- { ngx_string("scgi_cache_revalidate"),
- 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_scgi_loc_conf_t, upstream.cache_revalidate),
- NULL },
-
-#endif
-
- { ngx_string("scgi_temp_path"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
- ngx_conf_set_path_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.temp_path),
- NULL },
-
- { ngx_string("scgi_max_temp_file_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.max_temp_file_size_conf),
- NULL },
-
- { ngx_string("scgi_temp_file_write_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.temp_file_write_size_conf),
- NULL },
-
- { ngx_string("scgi_next_upstream"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.next_upstream),
- &ngx_http_scgi_next_upstream_masks },
-
- { ngx_string("scgi_param"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
- ngx_http_upstream_param_set_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, params_source),
- NULL },
-
- { ngx_string("scgi_pass_header"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_array_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.pass_headers),
- NULL },
-
- { ngx_string("scgi_hide_header"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_array_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.hide_headers),
- NULL },
-
- { ngx_string("scgi_ignore_headers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_scgi_loc_conf_t, upstream.ignore_headers),
- &ngx_http_upstream_ignore_headers_masks },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_scgi_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_scgi_create_loc_conf, /* create location configuration */
- ngx_http_scgi_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_scgi_module = {
- NGX_MODULE_V1,
- &ngx_http_scgi_module_ctx, /* module context */
- ngx_http_scgi_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_str_t ngx_http_scgi_hide_headers[] = {
- ngx_string("Status"),
- ngx_string("X-Accel-Expires"),
- ngx_string("X-Accel-Redirect"),
- ngx_string("X-Accel-Limit-Rate"),
- ngx_string("X-Accel-Buffering"),
- ngx_string("X-Accel-Charset"),
- ngx_null_string
-};
-
-
-#if (NGX_HTTP_CACHE)
-
-static ngx_keyval_t ngx_http_scgi_cache_headers[] = {
- { ngx_string("HTTP_IF_MODIFIED_SINCE"),
- ngx_string("$upstream_cache_last_modified") },
- { ngx_string("HTTP_IF_UNMODIFIED_SINCE"), ngx_string("") },
- { ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("") },
- { ngx_string("HTTP_IF_MATCH"), ngx_string("") },
- { ngx_string("HTTP_RANGE"), ngx_string("") },
- { ngx_string("HTTP_IF_RANGE"), ngx_string("") },
- { ngx_null_string, ngx_null_string }
-};
-
-#endif
-
-
-static ngx_path_init_t ngx_http_scgi_temp_path = {
- ngx_string(NGX_HTTP_SCGI_TEMP_PATH), { 1, 2, 0 }
-};
-
-
-static ngx_int_t
-ngx_http_scgi_handler(ngx_http_request_t *r)
-{
- ngx_int_t rc;
- ngx_http_status_t *status;
- ngx_http_upstream_t *u;
- ngx_http_scgi_loc_conf_t *scf;
-
- if (ngx_http_upstream_create(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- status = ngx_pcalloc(r->pool, sizeof(ngx_http_status_t));
- if (status == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ngx_http_set_ctx(r, status, ngx_http_scgi_module);
-
- scf = ngx_http_get_module_loc_conf(r, ngx_http_scgi_module);
-
- if (scf->scgi_lengths) {
- if (ngx_http_scgi_eval(r, scf) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
- }
-
- u = r->upstream;
-
- ngx_str_set(&u->schema, "scgi://");
- u->output.tag = (ngx_buf_tag_t) &ngx_http_scgi_module;
-
- u->conf = &scf->upstream;
-
-#if (NGX_HTTP_CACHE)
- u->create_key = ngx_http_scgi_create_key;
-#endif
- u->create_request = ngx_http_scgi_create_request;
- u->reinit_request = ngx_http_scgi_reinit_request;
- u->process_header = ngx_http_scgi_process_status_line;
- u->abort_request = ngx_http_scgi_abort_request;
- u->finalize_request = ngx_http_scgi_finalize_request;
- r->state = 0;
-
- u->buffering = scf->upstream.buffering;
-
- u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
- if (u->pipe == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
- u->pipe->input_ctx = r;
-
- rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init);
-
- if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
- return rc;
- }
-
- return NGX_DONE;
-}
-
-
-static ngx_int_t
-ngx_http_scgi_eval(ngx_http_request_t *r, ngx_http_scgi_loc_conf_t * scf)
-{
- ngx_url_t url;
- ngx_http_upstream_t *u;
-
- ngx_memzero(&url, sizeof(ngx_url_t));
-
- if (ngx_http_script_run(r, &url.url, scf->scgi_lengths->elts, 0,
- scf->scgi_values->elts)
- == NULL)
- {
- return NGX_ERROR;
- }
-
- url.no_resolve = 1;
-
- if (ngx_parse_url(r->pool, &url) != NGX_OK) {
- if (url.err) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "%s in upstream \"%V\"", url.err, &url.url);
- }
-
- return NGX_ERROR;
- }
-
- u = r->upstream;
-
- u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
- if (u->resolved == NULL) {
- return NGX_ERROR;
- }
-
- if (url.addrs && url.addrs[0].sockaddr) {
- u->resolved->sockaddr = url.addrs[0].sockaddr;
- u->resolved->socklen = url.addrs[0].socklen;
- u->resolved->naddrs = 1;
- u->resolved->host = url.addrs[0].name;
-
- } else {
- u->resolved->host = url.host;
- u->resolved->port = url.port;
- u->resolved->no_port = url.no_port;
- }
-
- return NGX_OK;
-}
-
-
-#if (NGX_HTTP_CACHE)
-
-static ngx_int_t
-ngx_http_scgi_create_key(ngx_http_request_t *r)
-{
- ngx_str_t *key;
- ngx_http_scgi_loc_conf_t *scf;
-
- key = ngx_array_push(&r->cache->keys);
- if (key == NULL) {
- return NGX_ERROR;
- }
-
- scf = ngx_http_get_module_loc_conf(r, ngx_http_scgi_module);
-
- if (ngx_http_complex_value(r, &scf->cache_key, key) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_scgi_create_request(ngx_http_request_t *r)
-{
- off_t content_length_n;
- u_char ch, *key, *val, *lowcase_key;
- size_t len, key_len, val_len, allocated;
- ngx_buf_t *b;
- ngx_str_t content_length;
- ngx_uint_t i, n, hash, skip_empty, header_params;
- ngx_chain_t *cl, *body;
- ngx_list_part_t *part;
- ngx_table_elt_t *header, **ignored;
- ngx_http_script_code_pt code;
- ngx_http_script_engine_t e, le;
- ngx_http_scgi_loc_conf_t *scf;
- ngx_http_script_len_code_pt lcode;
- u_char buffer[NGX_OFF_T_LEN];
-
- content_length_n = 0;
- body = r->upstream->request_bufs;
-
- while (body) {
- content_length_n += ngx_buf_size(body->buf);
- body = body->next;
- }
-
- content_length.data = buffer;
- content_length.len = ngx_sprintf(buffer, "%O", content_length_n) - buffer;
-
- len = sizeof("CONTENT_LENGTH") + content_length.len + 1;
-
- header_params = 0;
- ignored = NULL;
-
- scf = ngx_http_get_module_loc_conf(r, ngx_http_scgi_module);
-
- if (scf->params_len) {
- ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
-
- ngx_http_script_flush_no_cacheable_variables(r, scf->flushes);
- le.flushed = 1;
-
- le.ip = scf->params_len->elts;
- le.request = r;
-
- while (*(uintptr_t *) le.ip) {
-
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- key_len = lcode(&le);
-
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- skip_empty = lcode(&le);
-
- for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- }
- le.ip += sizeof(uintptr_t);
-
- if (skip_empty && val_len == 0) {
- continue;
- }
-
- len += key_len + val_len + 1;
- }
- }
-
- if (scf->upstream.pass_request_headers) {
-
- allocated = 0;
- lowcase_key = NULL;
-
- if (scf->header_params) {
- n = 0;
- part = &r->headers_in.headers.part;
-
- while (part) {
- n += part->nelts;
- part = part->next;
- }
-
- ignored = ngx_palloc(r->pool, n * sizeof(void *));
- if (ignored == NULL) {
- return NGX_ERROR;
- }
- }
-
- part = &r->headers_in.headers.part;
- header = part->elts;
-
- for (i = 0; /* void */; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- if (scf->header_params) {
- if (allocated < header[i].key.len) {
- allocated = header[i].key.len + 16;
- lowcase_key = ngx_pnalloc(r->pool, allocated);
- if (lowcase_key == NULL) {
- return NGX_ERROR;
- }
- }
-
- hash = 0;
-
- for (n = 0; n < header[i].key.len; n++) {
- ch = header[i].key.data[n];
-
- if (ch >= 'A' && ch <= 'Z') {
- ch |= 0x20;
-
- } else if (ch == '-') {
- ch = '_';
- }
-
- hash = ngx_hash(hash, ch);
- lowcase_key[n] = ch;
- }
-
- if (ngx_hash_find(&scf->headers_hash, hash, lowcase_key, n)) {
- ignored[header_params++] = &header[i];
- continue;
- }
- }
-
- len += sizeof("HTTP_") - 1 + header[i].key.len + 1
- + header[i].value.len + 1;
- }
- }
-
- /* netstring: "length:" + packet + "," */
-
- b = ngx_create_temp_buf(r->pool, NGX_SIZE_T_LEN + 1 + len + 1);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
-
- b->last = ngx_sprintf(b->last, "%ui:CONTENT_LENGTH%Z%V%Z",
- len, &content_length);
-
- if (scf->params_len) {
- ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
-
- e.ip = scf->params->elts;
- e.pos = b->last;
- e.request = r;
- e.flushed = 1;
-
- le.ip = scf->params_len->elts;
-
- while (*(uintptr_t *) le.ip) {
-
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- lcode(&le); /* key length */
-
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- skip_empty = lcode(&le);
-
- for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- }
- le.ip += sizeof(uintptr_t);
-
- if (skip_empty && val_len == 0) {
- e.skip = 1;
-
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
- }
- e.ip += sizeof(uintptr_t);
-
- e.skip = 0;
-
- continue;
- }
-
-#if (NGX_DEBUG)
- key = e.pos;
-#endif
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) & e);
-
-#if (NGX_DEBUG)
- val = e.pos;
-#endif
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
- }
- *e.pos++ = '\0';
- e.ip += sizeof(uintptr_t);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "scgi param: \"%s: %s\"", key, val);
- }
-
- b->last = e.pos;
- }
-
- if (scf->upstream.pass_request_headers) {
-
- part = &r->headers_in.headers.part;
- header = part->elts;
-
- for (i = 0; /* void */; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- for (n = 0; n < header_params; n++) {
- if (&header[i] == ignored[n]) {
- goto next;
- }
- }
-
- key = b->last;
- b->last = ngx_cpymem(key, "HTTP_", sizeof("HTTP_") - 1);
-
- for (n = 0; n < header[i].key.len; n++) {
- ch = header[i].key.data[n];
-
- if (ch >= 'a' && ch <= 'z') {
- ch &= ~0x20;
-
- } else if (ch == '-') {
- ch = '_';
- }
-
- *b->last++ = ch;
- }
-
- *b->last++ = (u_char) 0;
-
- val = b->last;
- b->last = ngx_copy(val, header[i].value.data, header[i].value.len);
- *b->last++ = (u_char) 0;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "scgi param: \"%s: %s\"", key, val);
-
- next:
-
- continue;
- }
- }
-
- *b->last++ = (u_char) ',';
-
- if (scf->upstream.pass_request_body) {
- body = r->upstream->request_bufs;
- r->upstream->request_bufs = cl;
-
- while (body) {
- b = ngx_alloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(b, body->buf, sizeof(ngx_buf_t));
-
- cl->next = ngx_alloc_chain_link(r->pool);
- if (cl->next == NULL) {
- return NGX_ERROR;
- }
-
- cl = cl->next;
- cl->buf = b;
-
- body = body->next;
- }
-
- } else {
- r->upstream->request_bufs = cl;
- }
-
- cl->next = NULL;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_scgi_reinit_request(ngx_http_request_t *r)
-{
- ngx_http_status_t *status;
-
- status = ngx_http_get_module_ctx(r, ngx_http_scgi_module);
-
- if (status == NULL) {
- return NGX_OK;
- }
-
- status->code = 0;
- status->count = 0;
- status->start = NULL;
- status->end = NULL;
-
- r->upstream->process_header = ngx_http_scgi_process_status_line;
- r->state = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_scgi_process_status_line(ngx_http_request_t *r)
-{
- size_t len;
- ngx_int_t rc;
- ngx_http_status_t *status;
- ngx_http_upstream_t *u;
-
- status = ngx_http_get_module_ctx(r, ngx_http_scgi_module);
-
- if (status == NULL) {
- return NGX_ERROR;
- }
-
- u = r->upstream;
-
- rc = ngx_http_parse_status_line(r, &u->buffer, status);
-
- if (rc == NGX_AGAIN) {
- return rc;
- }
-
- if (rc == NGX_ERROR) {
- u->process_header = ngx_http_scgi_process_header;
- return ngx_http_scgi_process_header(r);
- }
-
- if (u->state && u->state->status == 0) {
- u->state->status = status->code;
- }
-
- u->headers_in.status_n = status->code;
-
- len = status->end - status->start;
- u->headers_in.status_line.len = len;
-
- u->headers_in.status_line.data = ngx_pnalloc(r->pool, len);
- if (u->headers_in.status_line.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(u->headers_in.status_line.data, status->start, len);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http scgi status %ui \"%V\"",
- u->headers_in.status_n, &u->headers_in.status_line);
-
- u->process_header = ngx_http_scgi_process_header;
-
- return ngx_http_scgi_process_header(r);
-}
-
-
-static ngx_int_t
-ngx_http_scgi_process_header(ngx_http_request_t *r)
-{
- ngx_str_t *status_line;
- ngx_int_t rc, status;
- ngx_table_elt_t *h;
- ngx_http_upstream_t *u;
- ngx_http_upstream_header_t *hh;
- ngx_http_upstream_main_conf_t *umcf;
-
- umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
-
- for ( ;; ) {
-
- rc = ngx_http_parse_header_line(r, &r->upstream->buffer, 1);
-
- if (rc == NGX_OK) {
-
- /* a header line has been parsed successfully */
-
- h = ngx_list_push(&r->upstream->headers_in.headers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- 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_pnalloc(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_memcpy(h->key.data, r->header_name_start, h->key.len);
- h->key.data[h->key.len] = '\0';
- ngx_memcpy(h->value.data, r->header_start, h->value.len);
- h->value.data[h->value.len] = '\0';
-
- if (h->key.len == r->lowcase_index) {
- ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
-
- } else {
- ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
- }
-
- hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
- h->lowcase_key, h->key.len);
-
- if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http scgi header: \"%V: %V\"", &h->key, &h->value);
-
- continue;
- }
-
- if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
-
- /* a whole header has been parsed successfully */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http scgi header done");
-
- u = r->upstream;
-
- if (u->headers_in.status_n) {
- goto done;
- }
-
- if (u->headers_in.status) {
- status_line = &u->headers_in.status->value;
-
- status = ngx_atoi(status_line->data, 3);
- if (status == NGX_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;
- u->headers_in.status_line = *status_line;
-
- } else if (u->headers_in.location) {
- u->headers_in.status_n = 302;
- ngx_str_set(&u->headers_in.status_line,
- "302 Moved Temporarily");
-
- } else {
- u->headers_in.status_n = 200;
- ngx_str_set(&u->headers_in.status_line, "200 OK");
- }
-
- if (u->state && u->state->status == 0) {
- u->state->status = u->headers_in.status_n;
- }
-
- done:
-
- if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS
- && r->headers_in.upgrade)
- {
- u->upgrade = 1;
- }
-
- return NGX_OK;
- }
-
- if (rc == NGX_AGAIN) {
- return NGX_AGAIN;
- }
-
- /* there was error while a header line parsing */
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream sent invalid header");
-
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
- }
-}
-
-
-static void
-ngx_http_scgi_abort_request(ngx_http_request_t *r)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "abort http scgi request");
-
- return;
-}
-
-
-static void
-ngx_http_scgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "finalize http scgi request");
-
- return;
-}
-
-
-static void *
-ngx_http_scgi_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_scgi_loc_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_scgi_loc_conf_t));
- if (conf == NULL) {
- return 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;
-
- conf->upstream.local = NGX_CONF_UNSET_PTR;
-
- conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
-
- conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
- conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
-
- conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE;
- conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
- conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
-
- conf->upstream.pass_request_headers = NGX_CONF_UNSET;
- conf->upstream.pass_request_body = NGX_CONF_UNSET;
-
-#if (NGX_HTTP_CACHE)
- conf->upstream.cache = NGX_CONF_UNSET_PTR;
- conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
- conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
- conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
- conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
- conf->upstream.cache_lock = NGX_CONF_UNSET;
- conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.cache_revalidate = NGX_CONF_UNSET;
-#endif
-
- conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
- conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
-
- conf->upstream.intercept_errors = NGX_CONF_UNSET;
-
- /* "scgi_cyclic_temp_file" is disabled */
- conf->upstream.cyclic_temp_file = 0;
-
- conf->upstream.change_buffering = 1;
-
- ngx_str_set(&conf->upstream.module, "scgi");
-
- return conf;
-}
-
-
-static char *
-ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_scgi_loc_conf_t *prev = parent;
- ngx_http_scgi_loc_conf_t *conf = child;
-
- size_t size;
- ngx_hash_init_t hash;
- ngx_http_core_loc_conf_t *clcf;
-
- 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);
-
- ngx_conf_merge_value(conf->upstream.ignore_client_abort,
- prev->upstream.ignore_client_abort, 0);
-
- ngx_conf_merge_ptr_value(conf->upstream.local,
- prev->upstream.local, NULL);
-
- ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
- prev->upstream.connect_timeout, 60000);
-
- ngx_conf_merge_msec_value(conf->upstream.send_timeout,
- prev->upstream.send_timeout, 60000);
-
- ngx_conf_merge_msec_value(conf->upstream.read_timeout,
- prev->upstream.read_timeout, 60000);
-
- ngx_conf_merge_size_value(conf->upstream.send_lowat,
- prev->upstream.send_lowat, 0);
-
- ngx_conf_merge_size_value(conf->upstream.buffer_size,
- prev->upstream.buffer_size,
- (size_t) ngx_pagesize);
-
-
- ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs,
- 8, ngx_pagesize);
-
- if (conf->upstream.bufs.num < 2) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "there must be at least 2 \"scgi_buffers\"");
- return NGX_CONF_ERROR;
- }
-
-
- size = conf->upstream.buffer_size;
- if (size < conf->upstream.bufs.size) {
- size = conf->upstream.bufs.size;
- }
-
-
- ngx_conf_merge_size_value(conf->upstream.busy_buffers_size_conf,
- prev->upstream.busy_buffers_size_conf,
- NGX_CONF_UNSET_SIZE);
-
- if (conf->upstream.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) {
- conf->upstream.busy_buffers_size = 2 * size;
- } else {
- conf->upstream.busy_buffers_size =
- conf->upstream.busy_buffers_size_conf;
- }
-
- if (conf->upstream.busy_buffers_size < size) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"scgi_busy_buffers_size\" must be equal to or greater "
- "than the maximum of the value of \"scgi_buffer_size\" and "
- "one of the \"scgi_buffers\"");
-
- return NGX_CONF_ERROR;
- }
-
- if (conf->upstream.busy_buffers_size
- > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size)
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"scgi_busy_buffers_size\" must be less than "
- "the size of all \"scgi_buffers\" minus one buffer");
-
- return NGX_CONF_ERROR;
- }
-
-
- ngx_conf_merge_size_value(conf->upstream.temp_file_write_size_conf,
- prev->upstream.temp_file_write_size_conf,
- NGX_CONF_UNSET_SIZE);
-
- if (conf->upstream.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) {
- conf->upstream.temp_file_write_size = 2 * size;
- } else {
- conf->upstream.temp_file_write_size =
- conf->upstream.temp_file_write_size_conf;
- }
-
- if (conf->upstream.temp_file_write_size < size) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"scgi_temp_file_write_size\" must be equal to or greater than "
- "the maximum of the value of \"scgi_buffer_size\" and "
- "one of the \"scgi_buffers\"");
-
- return NGX_CONF_ERROR;
- }
-
-
- ngx_conf_merge_size_value(conf->upstream.max_temp_file_size_conf,
- prev->upstream.max_temp_file_size_conf,
- NGX_CONF_UNSET_SIZE);
-
- if (conf->upstream.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) {
- conf->upstream.max_temp_file_size = 1024 * 1024 * 1024;
- } else {
- conf->upstream.max_temp_file_size =
- conf->upstream.max_temp_file_size_conf;
- }
-
- if (conf->upstream.max_temp_file_size != 0
- && conf->upstream.max_temp_file_size < size) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"scgi_max_temp_file_size\" must be equal to zero to disable "
- "temporary files usage or must be equal to or greater than "
- "the maximum of the value of \"scgi_buffer_size\" and "
- "one of the \"scgi_buffers\"");
-
- return NGX_CONF_ERROR;
- }
-
-
- ngx_conf_merge_bitmask_value(conf->upstream.ignore_headers,
- prev->upstream.ignore_headers,
- NGX_CONF_BITMASK_SET);
-
-
- ngx_conf_merge_bitmask_value(conf->upstream.next_upstream,
- prev->upstream.next_upstream,
- (NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_ERROR
- |NGX_HTTP_UPSTREAM_FT_TIMEOUT));
-
- if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) {
- conf->upstream.next_upstream = NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_OFF;
- }
-
- if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,
- prev->upstream.temp_path,
- &ngx_http_scgi_temp_path)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
-#if (NGX_HTTP_CACHE)
-
- ngx_conf_merge_ptr_value(conf->upstream.cache,
- prev->upstream.cache, NULL);
-
- if (conf->upstream.cache && conf->upstream.cache->data == NULL) {
- ngx_shm_zone_t *shm_zone;
-
- shm_zone = conf->upstream.cache;
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"scgi_cache\" zone \"%V\" is unknown",
- &shm_zone->shm.name);
-
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_uint_value(conf->upstream.cache_min_uses,
- prev->upstream.cache_min_uses, 1);
-
- ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale,
- prev->upstream.cache_use_stale,
- (NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_OFF));
-
- if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) {
- conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_OFF;
- }
-
- if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_ERROR) {
- conf->upstream.cache_use_stale |= NGX_HTTP_UPSTREAM_FT_NOLIVE;
- }
-
- if (conf->upstream.cache_methods == 0) {
- conf->upstream.cache_methods = prev->upstream.cache_methods;
- }
-
- conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
-
- ngx_conf_merge_ptr_value(conf->upstream.cache_bypass,
- prev->upstream.cache_bypass, NULL);
-
- ngx_conf_merge_ptr_value(conf->upstream.no_cache,
- prev->upstream.no_cache, NULL);
-
- ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
- prev->upstream.cache_valid, NULL);
-
- if (conf->cache_key.value.data == NULL) {
- conf->cache_key = prev->cache_key;
- }
-
- ngx_conf_merge_value(conf->upstream.cache_lock,
- prev->upstream.cache_lock, 0);
-
- ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout,
- prev->upstream.cache_lock_timeout, 5000);
-
- ngx_conf_merge_value(conf->upstream.cache_revalidate,
- prev->upstream.cache_revalidate, 0);
-
-#endif
-
- ngx_conf_merge_value(conf->upstream.pass_request_headers,
- prev->upstream.pass_request_headers, 1);
- ngx_conf_merge_value(conf->upstream.pass_request_body,
- prev->upstream.pass_request_body, 1);
-
- ngx_conf_merge_value(conf->upstream.intercept_errors,
- prev->upstream.intercept_errors, 0);
-
- hash.max_size = 512;
- hash.bucket_size = ngx_align(64, ngx_cacheline_size);
- hash.name = "scgi_hide_headers_hash";
-
- if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
- &prev->upstream, ngx_http_scgi_hide_headers, &hash)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- if (conf->upstream.upstream == NULL) {
- conf->upstream.upstream = prev->upstream.upstream;
- }
-
- if (conf->scgi_lengths == NULL) {
- conf->scgi_lengths = prev->scgi_lengths;
- conf->scgi_values = prev->scgi_values;
- }
-
- if (conf->upstream.upstream || conf->scgi_lengths) {
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
- if (clcf->handler == NULL && clcf->lmt_excpt) {
- clcf->handler = ngx_http_scgi_handler;
- }
- }
-
- if (ngx_http_scgi_merge_params(cf, conf, prev) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_scgi_merge_params(ngx_conf_t *cf, ngx_http_scgi_loc_conf_t *conf,
- ngx_http_scgi_loc_conf_t *prev)
-{
- u_char *p;
- size_t size;
- uintptr_t *code;
- ngx_uint_t i, nsrc;
- ngx_array_t headers_names;
-#if (NGX_HTTP_CACHE)
- ngx_array_t params_merged;
-#endif
- ngx_hash_key_t *hk;
- ngx_hash_init_t hash;
- ngx_http_upstream_param_t *src;
- ngx_http_script_compile_t sc;
- ngx_http_script_copy_code_t *copy;
-
- if (conf->params_source == NULL) {
- conf->params_source = prev->params_source;
-
- if (prev->headers_hash.buckets
-#if (NGX_HTTP_CACHE)
- && ((conf->upstream.cache == NULL)
- == (prev->upstream.cache == NULL))
-#endif
- )
- {
- conf->flushes = prev->flushes;
- conf->params_len = prev->params_len;
- conf->params = prev->params;
- conf->headers_hash = prev->headers_hash;
- conf->header_params = prev->header_params;
-
- return NGX_OK;
- }
- }
-
- if (conf->params_source == NULL
-#if (NGX_HTTP_CACHE)
- && (conf->upstream.cache == NULL)
-#endif
- )
- {
- conf->headers_hash.buckets = (void *) 1;
- return NGX_OK;
- }
-
- conf->params_len = ngx_array_create(cf->pool, 64, 1);
- if (conf->params_len == NULL) {
- return NGX_ERROR;
- }
-
- conf->params = ngx_array_create(cf->pool, 512, 1);
- if (conf->params == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (conf->params_source) {
- src = conf->params_source->elts;
- nsrc = conf->params_source->nelts;
-
- } else {
- src = NULL;
- nsrc = 0;
- }
-
-#if (NGX_HTTP_CACHE)
-
- if (conf->upstream.cache) {
- ngx_keyval_t *h;
- ngx_http_upstream_param_t *s;
-
- if (ngx_array_init(&params_merged, cf->temp_pool, 4,
- sizeof(ngx_http_upstream_param_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- for (i = 0; i < nsrc; i++) {
-
- s = ngx_array_push(&params_merged);
- if (s == NULL) {
- return NGX_ERROR;
- }
-
- *s = src[i];
- }
-
- h = ngx_http_scgi_cache_headers;
-
- while (h->key.len) {
-
- src = params_merged.elts;
- nsrc = params_merged.nelts;
-
- for (i = 0; i < nsrc; i++) {
- if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
- goto next;
- }
- }
-
- s = ngx_array_push(&params_merged);
- if (s == NULL) {
- return NGX_ERROR;
- }
-
- s->key = h->key;
- s->value = h->value;
- s->skip_empty = 1;
-
- next:
-
- h++;
- }
-
- src = params_merged.elts;
- nsrc = params_merged.nelts;
- }
-
-#endif
-
- for (i = 0; i < nsrc; i++) {
-
- if (src[i].key.len > sizeof("HTTP_") - 1
- && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0)
- {
- hk = ngx_array_push(&headers_names);
- if (hk == NULL) {
- return NGX_ERROR;
- }
-
- hk->key.len = src[i].key.len - 5;
- hk->key.data = src[i].key.data + 5;
- hk->key_hash = ngx_hash_key_lc(hk->key.data, hk->key.len);
- hk->value = (void *) 1;
-
- if (src[i].value.len == 0) {
- continue;
- }
- }
-
- copy = ngx_array_push_n(conf->params_len,
- sizeof(ngx_http_script_copy_code_t));
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
- copy->len = src[i].key.len + 1;
-
- copy = ngx_array_push_n(conf->params_len,
- sizeof(ngx_http_script_copy_code_t));
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
- copy->len = src[i].skip_empty;
-
-
- size = (sizeof(ngx_http_script_copy_code_t)
- + src[i].key.len + 1 + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
-
- copy = ngx_array_push_n(conf->params, size);
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = ngx_http_script_copy_code;
- copy->len = src[i].key.len + 1;
-
- p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
- (void) ngx_cpystrn(p, src[i].key.data, src[i].key.len + 1);
-
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = &src[i].value;
- sc.flushes = &conf->flushes;
- sc.lengths = &conf->params_len;
- sc.values = &conf->params;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_ERROR;
- }
-
- code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
-
-
- code = ngx_array_push_n(conf->params, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
- }
-
- code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
-
- code = ngx_array_push_n(conf->params, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
-
- conf->header_params = headers_names.nelts;
-
- hash.hash = &conf->headers_hash;
- hash.key = ngx_hash_key_lc;
- hash.max_size = 512;
- hash.bucket_size = 64;
- hash.name = "scgi_params_hash";
- hash.pool = cf->pool;
- hash.temp_pool = NULL;
-
- return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts);
-}
-
-
-static char *
-ngx_http_scgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_scgi_loc_conf_t *scf = conf;
-
- ngx_url_t u;
- ngx_str_t *value, *url;
- ngx_uint_t n;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_script_compile_t sc;
-
- if (scf->upstream.upstream || scf->scgi_lengths) {
- return "is duplicate";
- }
-
- clcf = ngx_http_conf_get_module_loc_conf (cf, ngx_http_core_module);
- clcf->handler = ngx_http_scgi_handler;
-
- value = cf->args->elts;
-
- url = &value[1];
-
- n = ngx_http_script_variables_count(url);
-
- if (n) {
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = url;
- sc.lengths = &scf->scgi_lengths;
- sc.values = &scf->scgi_values;
- sc.variables = n;
- sc.complete_lengths = 1;
- sc.complete_values = 1;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
- }
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- u.url = value[1];
- u.no_resolve = 1;
-
- scf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
- if (scf->upstream.upstream == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (clcf->name.data[clcf->name.len - 1] == '/') {
- clcf->auto_redirect = 1;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_scgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_scgi_loc_conf_t *scf = conf;
-
- ngx_str_t *value;
- ngx_http_script_compile_t sc;
-
- if (scf->upstream.store != NGX_CONF_UNSET || scf->upstream.store_lengths) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- scf->upstream.store = 0;
- return NGX_CONF_OK;
- }
-
-#if (NGX_HTTP_CACHE)
-
- if (scf->upstream.cache != NGX_CONF_UNSET_PTR
- && scf->upstream.cache != NULL)
- {
- return "is incompatible with \"scgi_cache\"";
- }
-
-#endif
-
- if (ngx_strcmp(value[1].data, "on") == 0) {
- scf->upstream.store = 1;
- 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 = &scf->upstream.store_lengths;
- sc.values = &scf->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;
-}
-
-
-#if (NGX_HTTP_CACHE)
-
-static char *
-ngx_http_scgi_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_scgi_loc_conf_t *scf = conf;
-
- ngx_str_t *value;
-
- value = cf->args->elts;
-
- if (scf->upstream.cache != NGX_CONF_UNSET_PTR) {
- return "is duplicate";
- }
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- scf->upstream.cache = NULL;
- return NGX_CONF_OK;
- }
-
- if (scf->upstream.store > 0 || scf->upstream.store_lengths) {
- return "is incompatible with \"scgi_store\"";
- }
-
- scf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0,
- &ngx_http_scgi_module);
- if (scf->upstream.cache == NULL) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_scgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_scgi_loc_conf_t *scf = conf;
-
- ngx_str_t *value;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- if (scf->cache_key.value.data) {
- return "is duplicate";
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &scf->cache_key;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-#endif
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_secure_link_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_secure_link_module.c
deleted file mode 100644
index 907ba6ef50c..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_secure_link_module.c
+++ /dev/null
@@ -1,368 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-#include <ngx_md5.h>
-
-
-typedef struct {
- ngx_http_complex_value_t *variable;
- ngx_http_complex_value_t *md5;
- ngx_str_t secret;
-} ngx_http_secure_link_conf_t;
-
-
-typedef struct {
- ngx_str_t expires;
-} ngx_http_secure_link_ctx_t;
-
-
-static ngx_int_t ngx_http_secure_link_old_variable(ngx_http_request_t *r,
- ngx_http_secure_link_conf_t *conf, ngx_http_variable_value_t *v,
- uintptr_t data);
-static ngx_int_t ngx_http_secure_link_expires_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static void *ngx_http_secure_link_create_conf(ngx_conf_t *cf);
-static char *ngx_http_secure_link_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static ngx_int_t ngx_http_secure_link_add_variables(ngx_conf_t *cf);
-
-
-static ngx_command_t ngx_http_secure_link_commands[] = {
-
- { ngx_string("secure_link"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_set_complex_value_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_secure_link_conf_t, variable),
- NULL },
-
- { ngx_string("secure_link_md5"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_set_complex_value_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_secure_link_conf_t, md5),
- NULL },
-
- { ngx_string("secure_link_secret"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_secure_link_conf_t, secret),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_secure_link_module_ctx = {
- ngx_http_secure_link_add_variables, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_secure_link_create_conf, /* create location configuration */
- ngx_http_secure_link_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_secure_link_module = {
- NGX_MODULE_V1,
- &ngx_http_secure_link_module_ctx, /* module context */
- ngx_http_secure_link_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_str_t ngx_http_secure_link_name = ngx_string("secure_link");
-static ngx_str_t ngx_http_secure_link_expires_name =
- ngx_string("secure_link_expires");
-
-
-static ngx_int_t
-ngx_http_secure_link_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p, *last;
- ngx_str_t val, hash;
- time_t expires;
- ngx_md5_t md5;
- ngx_http_secure_link_ctx_t *ctx;
- ngx_http_secure_link_conf_t *conf;
- u_char hash_buf[16], md5_buf[16];
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_secure_link_module);
-
- if (conf->secret.data) {
- return ngx_http_secure_link_old_variable(r, conf, v, data);
- }
-
- if (conf->variable == NULL || conf->md5 == NULL) {
- goto not_found;
- }
-
- if (ngx_http_complex_value(r, conf->variable, &val) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "secure link: \"%V\"", &val);
-
- last = val.data + val.len;
-
- p = ngx_strlchr(val.data, last, ',');
- expires = 0;
-
- if (p) {
- val.len = p++ - val.data;
-
- expires = ngx_atotm(p, last - p);
- if (expires <= 0) {
- goto not_found;
- }
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_secure_link_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_secure_link_module);
-
- ctx->expires.len = last - p;
- ctx->expires.data = p;
- }
-
- if (val.len > 24) {
- goto not_found;
- }
-
- hash.len = 16;
- hash.data = hash_buf;
-
- if (ngx_decode_base64url(&hash, &val) != NGX_OK) {
- goto not_found;
- }
-
- if (hash.len != 16) {
- goto not_found;
- }
-
- if (ngx_http_complex_value(r, conf->md5, &val) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "secure link md5: \"%V\"", &val);
-
- ngx_md5_init(&md5);
- ngx_md5_update(&md5, val.data, val.len);
- ngx_md5_final(md5_buf, &md5);
-
- if (ngx_memcmp(hash_buf, md5_buf, 16) != 0) {
- goto not_found;
- }
-
- v->data = (u_char *) ((expires && expires < ngx_time()) ? "0" : "1");
- v->len = 1;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- return NGX_OK;
-
-not_found:
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_secure_link_old_variable(ngx_http_request_t *r,
- ngx_http_secure_link_conf_t *conf, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- u_char *p, *start, *end, *last;
- size_t len;
- ngx_int_t n;
- ngx_uint_t i;
- ngx_md5_t md5;
- u_char hash[16];
-
- p = &r->unparsed_uri.data[1];
- last = r->unparsed_uri.data + r->unparsed_uri.len;
-
- while (p < last) {
- if (*p++ == '/') {
- start = p;
- goto md5_start;
- }
- }
-
- goto not_found;
-
-md5_start:
-
- while (p < last) {
- if (*p++ == '/') {
- end = p - 1;
- goto url_start;
- }
- }
-
- goto not_found;
-
-url_start:
-
- len = last - p;
-
- if (end - start != 32 || len == 0) {
- goto not_found;
- }
-
- ngx_md5_init(&md5);
- ngx_md5_update(&md5, p, len);
- ngx_md5_update(&md5, conf->secret.data, conf->secret.len);
- ngx_md5_final(hash, &md5);
-
- for (i = 0; i < 16; i++) {
- n = ngx_hextoi(&start[2 * i], 2);
- if (n == NGX_ERROR || n != hash[i]) {
- goto not_found;
- }
- }
-
- v->len = len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
-
-not_found:
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_secure_link_expires_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_http_secure_link_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_secure_link_module);
-
- if (ctx) {
- v->len = ctx->expires.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = ctx->expires.data;
-
- } else {
- v->not_found = 1;
- }
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_secure_link_create_conf(ngx_conf_t *cf)
-{
- ngx_http_secure_link_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_secure_link_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->variable = NULL;
- * conf->md5 = NULL;
- * conf->secret = { 0, NULL };
- */
-
- return conf;
-}
-
-
-static char *
-ngx_http_secure_link_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_secure_link_conf_t *prev = parent;
- ngx_http_secure_link_conf_t *conf = child;
-
- if (conf->secret.data) {
- if (conf->variable || conf->md5) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"secure_link_secret\" cannot be mixed with "
- "\"secure_link\" and \"secure_link_md5\"");
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
- }
-
- if (conf->variable == NULL) {
- conf->variable = prev->variable;
- }
-
- if (conf->md5 == NULL) {
- conf->md5 = prev->md5;
- }
-
- if (conf->variable == NULL && conf->md5 == NULL) {
- conf->secret = prev->secret;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_secure_link_add_variables(ngx_conf_t *cf)
-{
- ngx_http_variable_t *var;
-
- var = ngx_http_add_variable(cf, &ngx_http_secure_link_name, 0);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = ngx_http_secure_link_variable;
-
- var = ngx_http_add_variable(cf, &ngx_http_secure_link_expires_name, 0);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = ngx_http_secure_link_expires_variable;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_split_clients_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_split_clients_module.c
deleted file mode 100644
index 2f92c9e1a8f..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_split_clients_module.c
+++ /dev/null
@@ -1,246 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- uint32_t percent;
- ngx_http_variable_value_t value;
-} ngx_http_split_clients_part_t;
-
-
-typedef struct {
- ngx_http_complex_value_t value;
- ngx_array_t parts;
-} ngx_http_split_clients_ctx_t;
-
-
-static char *ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_split_clients(ngx_conf_t *cf, ngx_command_t *dummy,
- void *conf);
-
-static ngx_command_t ngx_http_split_clients_commands[] = {
-
- { ngx_string("split_clients"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2,
- ngx_conf_split_clients_block,
- NGX_HTTP_MAIN_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_split_clients_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_split_clients_module = {
- NGX_MODULE_V1,
- &ngx_http_split_clients_module_ctx, /* module context */
- ngx_http_split_clients_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_split_clients_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_http_split_clients_ctx_t *ctx = (ngx_http_split_clients_ctx_t *) data;
-
- uint32_t hash;
- ngx_str_t val;
- ngx_uint_t i;
- ngx_http_split_clients_part_t *part;
-
- *v = ngx_http_variable_null_value;
-
- if (ngx_http_complex_value(r, &ctx->value, &val) != NGX_OK) {
- return NGX_OK;
- }
-
- hash = ngx_murmur_hash2(val.data, val.len);
-
- part = ctx->parts.elts;
-
- for (i = 0; i < ctx->parts.nelts; i++) {
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http split: %uD %uD", hash, part[i].percent);
-
- if (hash < part[i].percent || part[i].percent == 0) {
- *v = part[i].value;
- return NGX_OK;
- }
- }
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *rv;
- uint32_t sum, last;
- ngx_str_t *value, name;
- ngx_uint_t i;
- ngx_conf_t save;
- ngx_http_variable_t *var;
- ngx_http_split_clients_ctx_t *ctx;
- ngx_http_split_clients_part_t *part;
- ngx_http_compile_complex_value_t ccv;
-
- ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_split_clients_ctx_t));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &ctx->value;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- name = value[2];
-
- if (name.data[0] != '$') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid variable name \"%V\"", &name);
- return NGX_CONF_ERROR;
- }
-
- name.len--;
- name.data++;
-
- var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
- if (var == NULL) {
- return NGX_CONF_ERROR;
- }
-
- var->get_handler = ngx_http_split_clients_variable;
- var->data = (uintptr_t) ctx;
-
- if (ngx_array_init(&ctx->parts, cf->pool, 2,
- sizeof(ngx_http_split_clients_part_t))
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- save = *cf;
- cf->ctx = ctx;
- cf->handler = ngx_http_split_clients;
- cf->handler_conf = conf;
-
- rv = ngx_conf_parse(cf, NULL);
-
- *cf = save;
-
- if (rv != NGX_CONF_OK) {
- return rv;
- }
-
- sum = 0;
- last = 0;
- part = ctx->parts.elts;
-
- for (i = 0; i < ctx->parts.nelts; i++) {
- sum = part[i].percent ? sum + part[i].percent : 10000;
- if (sum > 10000) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "percent total is greater than 100%%");
- return NGX_CONF_ERROR;
- }
-
- if (part[i].percent) {
- last += part[i].percent * (uint64_t) 0xffffffff / 10000;
- part[i].percent = last;
- }
- }
-
- return rv;
-}
-
-
-static char *
-ngx_http_split_clients(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
-{
- ngx_int_t n;
- ngx_str_t *value;
- ngx_http_split_clients_ctx_t *ctx;
- ngx_http_split_clients_part_t *part;
-
- ctx = cf->ctx;
- value = cf->args->elts;
-
- part = ngx_array_push(&ctx->parts);
- if (part == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (value[0].len == 1 && value[0].data[0] == '*') {
- part->percent = 0;
-
- } else {
- if (value[0].len == 0 || value[0].data[value[0].len - 1] != '%') {
- goto invalid;
- }
-
- n = ngx_atofp(value[0].data, value[0].len - 1, 2);
- if (n == NGX_ERROR || n == 0) {
- goto invalid;
- }
-
- part->percent = (uint32_t) n;
- }
-
- part->value.len = value[1].len;
- part->value.valid = 1;
- part->value.no_cacheable = 0;
- part->value.not_found = 0;
- part->value.data = value[1].data;
-
- return NGX_CONF_OK;
-
-invalid:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid percent value \"%V\"", &value[0]);
- return NGX_CONF_ERROR;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_ssi_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_ssi_filter_module.c
deleted file mode 100644
index aeb1376b7bb..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_ssi_filter_module.c
+++ /dev/null
@@ -1,2927 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-#define NGX_HTTP_SSI_ERROR 1
-
-#define NGX_HTTP_SSI_DATE_LEN 2048
-
-#define NGX_HTTP_SSI_ADD_PREFIX 1
-#define NGX_HTTP_SSI_ADD_ZERO 2
-
-
-typedef struct {
- ngx_flag_t enable;
- ngx_flag_t silent_errors;
- ngx_flag_t ignore_recycled_buffers;
- ngx_flag_t last_modified;
-
- ngx_hash_t types;
-
- size_t min_file_chunk;
- size_t value_len;
-
- ngx_array_t *types_keys;
-} ngx_http_ssi_loc_conf_t;
-
-
-typedef struct {
- ngx_str_t name;
- ngx_uint_t key;
- ngx_str_t value;
-} ngx_http_ssi_var_t;
-
-
-typedef struct {
- ngx_str_t name;
- ngx_chain_t *bufs;
- ngx_uint_t count;
-} ngx_http_ssi_block_t;
-
-
-typedef enum {
- ssi_start_state = 0,
- ssi_tag_state,
- ssi_comment0_state,
- ssi_comment1_state,
- ssi_sharp_state,
- ssi_precommand_state,
- ssi_command_state,
- ssi_preparam_state,
- ssi_param_state,
- ssi_preequal_state,
- ssi_prevalue_state,
- ssi_double_quoted_value_state,
- ssi_quoted_value_state,
- ssi_quoted_symbol_state,
- ssi_postparam_state,
- ssi_comment_end0_state,
- ssi_comment_end1_state,
- ssi_error_state,
- ssi_error_end0_state,
- ssi_error_end1_state
-} ngx_http_ssi_state_e;
-
-
-static ngx_int_t ngx_http_ssi_output(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx);
-static void ngx_http_ssi_buffered(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx);
-static ngx_int_t ngx_http_ssi_parse(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx);
-static ngx_str_t *ngx_http_ssi_get_variable(ngx_http_request_t *r,
- ngx_str_t *name, ngx_uint_t key);
-static ngx_int_t ngx_http_ssi_evaluate_string(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx, ngx_str_t *text, ngx_uint_t flags);
-static ngx_int_t ngx_http_ssi_regex_match(ngx_http_request_t *r,
- ngx_str_t *pattern, ngx_str_t *str);
-
-static ngx_int_t ngx_http_ssi_include(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
-static ngx_int_t ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data,
- ngx_int_t rc);
-static ngx_int_t ngx_http_ssi_set_variable(ngx_http_request_t *r, void *data,
- ngx_int_t rc);
-static ngx_int_t ngx_http_ssi_echo(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
-static ngx_int_t ngx_http_ssi_config(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
-static ngx_int_t ngx_http_ssi_set(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
-static ngx_int_t ngx_http_ssi_if(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
-static ngx_int_t ngx_http_ssi_else(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
-static ngx_int_t ngx_http_ssi_endif(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
-static ngx_int_t ngx_http_ssi_block(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
-static ngx_int_t ngx_http_ssi_endblock(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
-
-static ngx_int_t ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t gmt);
-
-static ngx_int_t ngx_http_ssi_preconfiguration(ngx_conf_t *cf);
-static void *ngx_http_ssi_create_main_conf(ngx_conf_t *cf);
-static char *ngx_http_ssi_init_main_conf(ngx_conf_t *cf, void *conf);
-static void *ngx_http_ssi_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_ssi_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static ngx_int_t ngx_http_ssi_filter_init(ngx_conf_t *cf);
-
-
-static ngx_command_t ngx_http_ssi_filter_commands[] = {
-
- { ngx_string("ssi"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_ssi_loc_conf_t, enable),
- NULL },
-
- { ngx_string("ssi_silent_errors"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_ssi_loc_conf_t, silent_errors),
- NULL },
-
- { ngx_string("ssi_ignore_recycled_buffers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_ssi_loc_conf_t, ignore_recycled_buffers),
- NULL },
-
- { ngx_string("ssi_min_file_chunk"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_ssi_loc_conf_t, min_file_chunk),
- NULL },
-
- { ngx_string("ssi_value_length"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_ssi_loc_conf_t, value_len),
- NULL },
-
- { ngx_string("ssi_types"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_types_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_ssi_loc_conf_t, types_keys),
- &ngx_http_html_default_types[0] },
-
- { ngx_string("ssi_last_modified"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_ssi_loc_conf_t, last_modified),
- NULL },
-
- ngx_null_command
-};
-
-
-
-static ngx_http_module_t ngx_http_ssi_filter_module_ctx = {
- ngx_http_ssi_preconfiguration, /* preconfiguration */
- ngx_http_ssi_filter_init, /* postconfiguration */
-
- ngx_http_ssi_create_main_conf, /* create main configuration */
- ngx_http_ssi_init_main_conf, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_ssi_create_loc_conf, /* create location configuration */
- ngx_http_ssi_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_ssi_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_ssi_filter_module_ctx, /* module context */
- ngx_http_ssi_filter_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-
-
-static u_char ngx_http_ssi_string[] = "<!--";
-
-static ngx_str_t ngx_http_ssi_none = ngx_string("(none)");
-static ngx_str_t ngx_http_ssi_timefmt = ngx_string("%A, %d-%b-%Y %H:%M:%S %Z");
-static ngx_str_t ngx_http_ssi_null_string = ngx_null_string;
-
-
-#define NGX_HTTP_SSI_INCLUDE_VIRTUAL 0
-#define NGX_HTTP_SSI_INCLUDE_FILE 1
-#define NGX_HTTP_SSI_INCLUDE_WAIT 2
-#define NGX_HTTP_SSI_INCLUDE_SET 3
-#define NGX_HTTP_SSI_INCLUDE_STUB 4
-
-#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
-
-#define NGX_HTTP_SSI_SET_VAR 0
-#define NGX_HTTP_SSI_SET_VALUE 1
-
-#define NGX_HTTP_SSI_IF_EXPR 0
-
-#define NGX_HTTP_SSI_BLOCK_NAME 0
-
-
-static ngx_http_ssi_param_t ngx_http_ssi_include_params[] = {
- { ngx_string("virtual"), NGX_HTTP_SSI_INCLUDE_VIRTUAL, 0, 0 },
- { ngx_string("file"), NGX_HTTP_SSI_INCLUDE_FILE, 0, 0 },
- { ngx_string("wait"), NGX_HTTP_SSI_INCLUDE_WAIT, 0, 0 },
- { ngx_string("set"), NGX_HTTP_SSI_INCLUDE_SET, 0, 0 },
- { ngx_string("stub"), NGX_HTTP_SSI_INCLUDE_STUB, 0, 0 },
- { ngx_null_string, 0, 0, 0 }
-};
-
-
-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 }
-};
-
-
-static ngx_http_ssi_param_t ngx_http_ssi_config_params[] = {
- { ngx_string("errmsg"), NGX_HTTP_SSI_CONFIG_ERRMSG, 0, 0 },
- { ngx_string("timefmt"), NGX_HTTP_SSI_CONFIG_TIMEFMT, 0, 0 },
- { ngx_null_string, 0, 0, 0 }
-};
-
-
-static ngx_http_ssi_param_t ngx_http_ssi_set_params[] = {
- { ngx_string("var"), NGX_HTTP_SSI_SET_VAR, 1, 0 },
- { ngx_string("value"), NGX_HTTP_SSI_SET_VALUE, 1, 0 },
- { ngx_null_string, 0, 0, 0 }
-};
-
-
-static ngx_http_ssi_param_t ngx_http_ssi_if_params[] = {
- { ngx_string("expr"), NGX_HTTP_SSI_IF_EXPR, 1, 0 },
- { ngx_null_string, 0, 0, 0 }
-};
-
-
-static ngx_http_ssi_param_t ngx_http_ssi_block_params[] = {
- { ngx_string("name"), NGX_HTTP_SSI_BLOCK_NAME, 1, 0 },
- { ngx_null_string, 0, 0, 0 }
-};
-
-
-static ngx_http_ssi_param_t ngx_http_ssi_no_params[] = {
- { ngx_null_string, 0, 0, 0 }
-};
-
-
-static ngx_http_ssi_command_t ngx_http_ssi_commands[] = {
- { ngx_string("include"), ngx_http_ssi_include,
- ngx_http_ssi_include_params, 0, 0, 1 },
- { ngx_string("echo"), ngx_http_ssi_echo,
- ngx_http_ssi_echo_params, 0, 0, 0 },
- { ngx_string("config"), ngx_http_ssi_config,
- ngx_http_ssi_config_params, 0, 0, 0 },
- { ngx_string("set"), ngx_http_ssi_set, ngx_http_ssi_set_params, 0, 0, 0 },
-
- { ngx_string("if"), ngx_http_ssi_if, ngx_http_ssi_if_params, 0, 0, 0 },
- { ngx_string("elif"), ngx_http_ssi_if, ngx_http_ssi_if_params,
- NGX_HTTP_SSI_COND_IF, 0, 0 },
- { ngx_string("else"), ngx_http_ssi_else, ngx_http_ssi_no_params,
- NGX_HTTP_SSI_COND_IF, 0, 0 },
- { ngx_string("endif"), ngx_http_ssi_endif, ngx_http_ssi_no_params,
- NGX_HTTP_SSI_COND_ELSE, 0, 0 },
-
- { ngx_string("block"), ngx_http_ssi_block,
- ngx_http_ssi_block_params, 0, 0, 0 },
- { ngx_string("endblock"), ngx_http_ssi_endblock,
- ngx_http_ssi_no_params, 0, 1, 0 },
-
- { ngx_null_string, NULL, NULL, 0, 0, 0 }
-};
-
-
-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_NOCACHEABLE, 0 },
-
- { ngx_string("date_gmt"), NULL, ngx_http_ssi_date_gmt_local_variable, 1,
- NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_null_string, NULL, NULL, 0, 0, 0 }
-};
-
-
-
-static ngx_int_t
-ngx_http_ssi_header_filter(ngx_http_request_t *r)
-{
- ngx_http_ssi_ctx_t *ctx;
- ngx_http_ssi_loc_conf_t *slcf;
-
- slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
-
- if (!slcf->enable
- || r->headers_out.content_length_n == 0
- || ngx_http_test_content_type(r, &slcf->types) == NULL)
- {
- return ngx_http_next_header_filter(r);
- }
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_ssi_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_ssi_filter_module);
-
-
- 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;
- ctx->params.size = sizeof(ngx_table_elt_t);
- ctx->params.nalloc = NGX_HTTP_SSI_PARAMS_N;
- ctx->params.pool = r->pool;
-
- ctx->timefmt = ngx_http_ssi_timefmt;
- ngx_str_set(&ctx->errmsg,
- "[an error occurred while processing the directive]");
-
- r->filter_need_in_memory = 1;
-
- if (r == r->main) {
- ngx_http_clear_content_length(r);
- ngx_http_clear_accept_ranges(r);
- ngx_http_clear_etag(r);
-
- if (!slcf->last_modified) {
- ngx_http_clear_last_modified(r);
- }
- }
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_int_t
-ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- size_t len;
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_uint_t i, index;
- ngx_chain_t *cl, **ll;
- ngx_table_elt_t *param;
- ngx_http_ssi_ctx_t *ctx, *mctx;
- ngx_http_ssi_block_t *bl;
- ngx_http_ssi_param_t *prm;
- ngx_http_ssi_command_t *cmd;
- ngx_http_ssi_loc_conf_t *slcf;
- ngx_http_ssi_main_conf_t *smcf;
- ngx_str_t *params[NGX_HTTP_SSI_MAX_PARAMS + 1];
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
-
- if (ctx == NULL
- || (in == NULL
- && ctx->buf == NULL
- && ctx->in == NULL
- && ctx->busy == NULL))
- {
- return ngx_http_next_body_filter(r, in);
- }
-
- /* add the incoming chain to the chain ctx->in */
-
- if (in) {
- if (ngx_chain_add_copy(r->pool, &ctx->in, in) != NGX_OK) {
- return NGX_ERROR;
- }
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http ssi filter \"%V?%V\"", &r->uri, &r->args);
-
- if (ctx->wait) {
-
- if (r != r->connection->data) {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http ssi filter wait \"%V?%V\" non-active",
- &ctx->wait->uri, &ctx->wait->args);
-
- return NGX_AGAIN;
- }
-
- if (ctx->wait->done) {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http ssi filter wait \"%V?%V\" done",
- &ctx->wait->uri, &ctx->wait->args);
-
- ctx->wait = NULL;
-
- } else {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http ssi filter wait \"%V?%V\"",
- &ctx->wait->uri, &ctx->wait->args);
-
- return ngx_http_next_body_filter(r, NULL);
- }
- }
-
- slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
-
- while (ctx->in || ctx->buf) {
-
- if (ctx->buf == NULL) {
- ctx->buf = ctx->in->buf;
- ctx->in = ctx->in->next;
- ctx->pos = ctx->buf->pos;
- }
-
- if (ctx->state == ssi_start_state) {
- ctx->copy_start = ctx->pos;
- ctx->copy_end = ctx->pos;
- }
-
- b = NULL;
-
- while (ctx->pos < ctx->buf->last) {
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "saved: %d state: %d", ctx->saved, ctx->state);
-
- rc = ngx_http_ssi_parse(r, ctx);
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "parse: %d, looked: %d %p-%p",
- rc, ctx->looked, ctx->copy_start, ctx->copy_end);
-
- if (rc == NGX_ERROR) {
- return rc;
- }
-
- if (ctx->copy_start != ctx->copy_end) {
-
- if (ctx->output) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "saved: %d", ctx->saved);
-
- if (ctx->saved) {
-
- if (ctx->free) {
- cl = ctx->free;
- ctx->free = ctx->free->next;
- b = cl->buf;
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- } else {
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- }
-
- b->memory = 1;
- b->pos = ngx_http_ssi_string;
- b->last = ngx_http_ssi_string + ctx->saved;
-
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- ctx->saved = 0;
- }
-
- if (ctx->free) {
- cl = ctx->free;
- ctx->free = ctx->free->next;
- b = cl->buf;
-
- } else {
- b = ngx_alloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- }
-
- ngx_memcpy(b, ctx->buf, sizeof(ngx_buf_t));
-
- b->pos = ctx->copy_start;
- b->last = ctx->copy_end;
- b->shadow = NULL;
- b->last_buf = 0;
- b->recycled = 0;
-
- if (b->in_file) {
- if (slcf->min_file_chunk < (size_t) (b->last - b->pos))
- {
- b->file_last = b->file_pos
- + (b->last - ctx->buf->pos);
- b->file_pos += b->pos - ctx->buf->pos;
-
- } else {
- b->in_file = 0;
- }
- }
-
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- } else {
- if (ctx->block
- && ctx->saved + (ctx->copy_end - ctx->copy_start))
- {
- b = ngx_create_temp_buf(r->pool,
- ctx->saved + (ctx->copy_end - ctx->copy_start));
-
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- if (ctx->saved) {
- b->last = ngx_cpymem(b->pos, ngx_http_ssi_string,
- ctx->saved);
- }
-
- b->last = ngx_cpymem(b->last, ctx->copy_start,
- ctx->copy_end - ctx->copy_start);
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- cl->next = NULL;
-
- b = NULL;
-
- mctx = ngx_http_get_module_ctx(r->main,
- ngx_http_ssi_filter_module);
- bl = mctx->blocks->elts;
- for (ll = &bl[mctx->blocks->nelts - 1].bufs;
- *ll;
- ll = &(*ll)->next)
- {
- /* void */
- }
-
- *ll = cl;
- }
-
- ctx->saved = 0;
- }
- }
-
- if (ctx->state == ssi_start_state) {
- ctx->copy_start = ctx->pos;
- ctx->copy_end = ctx->pos;
-
- } else {
- ctx->copy_start = NULL;
- ctx->copy_end = NULL;
- }
-
- if (rc == NGX_AGAIN) {
- continue;
- }
-
-
- b = NULL;
-
- if (rc == NGX_OK) {
-
- smcf = ngx_http_get_module_main_conf(r,
- ngx_http_ssi_filter_module);
-
- cmd = ngx_hash_find(&smcf->hash, ctx->key, ctx->command.data,
- ctx->command.len);
-
- if (cmd == NULL) {
- if (ctx->output) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "invalid SSI command: \"%V\"",
- &ctx->command);
- goto ssi_error;
- }
-
- continue;
- }
-
- if (!ctx->output && !cmd->block) {
-
- if (ctx->block) {
-
- /* reconstruct the SSI command text */
-
- len = 5 + ctx->command.len + 4;
-
- param = ctx->params.elts;
- for (i = 0; i < ctx->params.nelts; i++) {
- len += 1 + param[i].key.len + 2
- + param[i].value.len + 1;
- }
-
- b = ngx_create_temp_buf(r->pool, len);
-
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- cl->next = NULL;
-
- *b->last++ = '<';
- *b->last++ = '!';
- *b->last++ = '-';
- *b->last++ = '-';
- *b->last++ = '#';
-
- b->last = ngx_cpymem(b->last, ctx->command.data,
- ctx->command.len);
-
- for (i = 0; i < ctx->params.nelts; i++) {
- *b->last++ = ' ';
- b->last = ngx_cpymem(b->last, param[i].key.data,
- param[i].key.len);
- *b->last++ = '=';
- *b->last++ = '"';
- b->last = ngx_cpymem(b->last, param[i].value.data,
- param[i].value.len);
- *b->last++ = '"';
- }
-
- *b->last++ = ' ';
- *b->last++ = '-';
- *b->last++ = '-';
- *b->last++ = '>';
-
- mctx = ngx_http_get_module_ctx(r->main,
- ngx_http_ssi_filter_module);
- bl = mctx->blocks->elts;
- for (ll = &bl[mctx->blocks->nelts - 1].bufs;
- *ll;
- ll = &(*ll)->next)
- {
- /* void */
- }
-
- *ll = cl;
-
- b = NULL;
-
- continue;
- }
-
- if (cmd->conditional == 0) {
- continue;
- }
- }
-
- if (cmd->conditional
- && (ctx->conditional == 0
- || ctx->conditional > cmd->conditional))
- {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "invalid context of SSI command: \"%V\"",
- &ctx->command);
- goto ssi_error;
- }
-
- if (ctx->params.nelts > NGX_HTTP_SSI_MAX_PARAMS) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "too many SSI command parameters: \"%V\"",
- &ctx->command);
- goto ssi_error;
- }
-
- ngx_memzero(params,
- (NGX_HTTP_SSI_MAX_PARAMS + 1) * sizeof(ngx_str_t *));
-
- param = ctx->params.elts;
-
- for (i = 0; i < ctx->params.nelts; i++) {
-
- for (prm = cmd->params; prm->name.len; prm++) {
-
- if (param[i].key.len != prm->name.len
- || ngx_strncmp(param[i].key.data, prm->name.data,
- prm->name.len) != 0)
- {
- continue;
- }
-
- if (!prm->multiple) {
- if (params[prm->index]) {
- ngx_log_error(NGX_LOG_ERR,
- r->connection->log, 0,
- "duplicate \"%V\" parameter "
- "in \"%V\" SSI command",
- &param[i].key, &ctx->command);
-
- goto ssi_error;
- }
-
- params[prm->index] = &param[i].value;
-
- break;
- }
-
- for (index = prm->index; params[index]; index++) {
- /* void */
- }
-
- params[index] = &param[i].value;
-
- break;
- }
-
- if (prm->name.len == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "invalid parameter name: \"%V\" "
- "in \"%V\" SSI command",
- &param[i].key, &ctx->command);
-
- goto ssi_error;
- }
- }
-
- for (prm = cmd->params; prm->name.len; prm++) {
- if (prm->mandatory && params[prm->index] == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "mandatory \"%V\" parameter is absent "
- "in \"%V\" SSI command",
- &prm->name, &ctx->command);
-
- goto ssi_error;
- }
- }
-
- if (cmd->flush && ctx->out) {
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "ssi flush");
-
- if (ngx_http_ssi_output(r, ctx) == NGX_ERROR) {
- return NGX_ERROR;
- }
- }
-
- rc = cmd->handler(r, ctx, params);
-
- if (rc == NGX_OK) {
- continue;
- }
-
- if (rc == NGX_DONE || rc == NGX_AGAIN || rc == NGX_ERROR) {
- ngx_http_ssi_buffered(r, ctx);
- return rc;
- }
- }
-
-
- /* rc == NGX_HTTP_SSI_ERROR */
-
- ssi_error:
-
- if (slcf->silent_errors) {
- continue;
- }
-
- if (ctx->free) {
- cl = ctx->free;
- ctx->free = ctx->free->next;
- b = cl->buf;
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- } else {
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- }
-
- b->memory = 1;
- b->pos = ctx->errmsg.data;
- b->last = ctx->errmsg.data + ctx->errmsg.len;
-
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- continue;
- }
-
- if (ctx->buf->last_buf || ngx_buf_in_memory(ctx->buf)) {
- if (b == NULL) {
- if (ctx->free) {
- cl = ctx->free;
- ctx->free = ctx->free->next;
- b = cl->buf;
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- } else {
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- }
-
- b->sync = 1;
-
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
- }
-
- b->last_buf = ctx->buf->last_buf;
- b->shadow = ctx->buf;
-
- if (slcf->ignore_recycled_buffers == 0) {
- b->recycled = ctx->buf->recycled;
- }
- }
-
- ctx->buf = NULL;
-
- ctx->saved = ctx->looked;
- }
-
- if (ctx->out == NULL && ctx->busy == NULL) {
- return NGX_OK;
- }
-
- return ngx_http_ssi_output(r, ctx);
-}
-
-
-static ngx_int_t
-ngx_http_ssi_output(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
-{
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t *cl;
-
-#if 1
- b = NULL;
- for (cl = ctx->out; cl; cl = cl->next) {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "ssi out: %p %p", cl->buf, cl->buf->pos);
- if (cl->buf == b) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "the same buf was used in ssi");
- ngx_debug_point();
- return NGX_ERROR;
- }
- b = cl->buf;
- }
-#endif
-
- rc = ngx_http_next_body_filter(r, ctx->out);
-
- if (ctx->busy == NULL) {
- ctx->busy = ctx->out;
-
- } else {
- for (cl = ctx->busy; cl->next; cl = cl->next) { /* void */ }
- cl->next = ctx->out;
- }
-
- ctx->out = NULL;
- ctx->last_out = &ctx->out;
-
- while (ctx->busy) {
-
- cl = ctx->busy;
- b = cl->buf;
-
- if (ngx_buf_size(b) != 0) {
- break;
- }
-
- if (b->shadow) {
- b->shadow->pos = b->shadow->last;
- }
-
- ctx->busy = cl->next;
-
- if (ngx_buf_in_memory(b) || b->in_file) {
- /* add data bufs only to the free buf chain */
-
- cl->next = ctx->free;
- ctx->free = cl;
- }
- }
-
- ngx_http_ssi_buffered(r, ctx);
-
- return rc;
-}
-
-
-static void
-ngx_http_ssi_buffered(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
-{
- if (ctx->in || ctx->buf) {
- r->buffered |= NGX_HTTP_SSI_BUFFERED;
-
- } else {
- r->buffered &= ~NGX_HTTP_SSI_BUFFERED;
- }
-}
-
-
-static ngx_int_t
-ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
-{
- u_char *p, *value, *last, *copy_end, ch;
- size_t looked;
- ngx_http_ssi_state_e state;
-
- state = ctx->state;
- looked = ctx->looked;
- last = ctx->buf->last;
- copy_end = ctx->copy_end;
-
- for (p = ctx->pos; p < last; p++) {
-
- ch = *p;
-
- if (state == ssi_start_state) {
-
- /* the tight loop */
-
- for ( ;; ) {
- if (ch == '<') {
- copy_end = p;
- looked = 1;
- state = ssi_tag_state;
-
- goto tag_started;
- }
-
- if (++p == last) {
- break;
- }
-
- ch = *p;
- }
-
- ctx->state = state;
- ctx->pos = p;
- ctx->looked = looked;
- ctx->copy_end = p;
-
- if (ctx->copy_start == NULL) {
- ctx->copy_start = ctx->buf->pos;
- }
-
- return NGX_AGAIN;
-
- tag_started:
-
- continue;
- }
-
- switch (state) {
-
- case ssi_start_state:
- /* not reached */
- break;
-
- case ssi_tag_state:
- switch (ch) {
- case '!':
- looked = 2;
- state = ssi_comment0_state;
- break;
-
- case '<':
- copy_end = p;
- break;
-
- default:
- copy_end = p;
- looked = 0;
- state = ssi_start_state;
- break;
- }
-
- break;
-
- case ssi_comment0_state:
- switch (ch) {
- case '-':
- looked = 3;
- state = ssi_comment1_state;
- break;
-
- case '<':
- copy_end = p;
- looked = 1;
- state = ssi_tag_state;
- break;
-
- default:
- copy_end = p;
- looked = 0;
- state = ssi_start_state;
- break;
- }
-
- break;
-
- case ssi_comment1_state:
- switch (ch) {
- case '-':
- looked = 4;
- state = ssi_sharp_state;
- break;
-
- case '<':
- copy_end = p;
- looked = 1;
- state = ssi_tag_state;
- break;
-
- default:
- copy_end = p;
- looked = 0;
- state = ssi_start_state;
- break;
- }
-
- break;
-
- case ssi_sharp_state:
- switch (ch) {
- case '#':
- if (p - ctx->pos < 4) {
- ctx->saved = 0;
- }
- looked = 0;
- state = ssi_precommand_state;
- break;
-
- case '<':
- copy_end = p;
- looked = 1;
- state = ssi_tag_state;
- break;
-
- default:
- copy_end = p;
- looked = 0;
- state = ssi_start_state;
- break;
- }
-
- break;
-
- case ssi_precommand_state:
- switch (ch) {
- case ' ':
- case CR:
- case LF:
- case '\t':
- break;
-
- default:
- ctx->command.len = 1;
- ctx->command.data = ngx_pnalloc(r->pool,
- NGX_HTTP_SSI_COMMAND_LEN);
- if (ctx->command.data == NULL) {
- return NGX_ERROR;
- }
-
- ctx->command.data[0] = ch;
-
- ctx->key = 0;
- ctx->key = ngx_hash(ctx->key, ch);
-
- ctx->params.nelts = 0;
-
- state = ssi_command_state;
- break;
- }
-
- break;
-
- case ssi_command_state:
- switch (ch) {
- case ' ':
- case CR:
- case LF:
- case '\t':
- state = ssi_preparam_state;
- break;
-
- case '-':
- state = ssi_comment_end0_state;
- break;
-
- default:
- if (ctx->command.len == NGX_HTTP_SSI_COMMAND_LEN) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "the \"%V%c...\" SSI command is too long",
- &ctx->command, ch);
-
- state = ssi_error_state;
- break;
- }
-
- ctx->command.data[ctx->command.len++] = ch;
- ctx->key = ngx_hash(ctx->key, ch);
- }
-
- break;
-
- case ssi_preparam_state:
- switch (ch) {
- case ' ':
- case CR:
- case LF:
- case '\t':
- break;
-
- case '-':
- state = ssi_comment_end0_state;
- break;
-
- default:
- ctx->param = ngx_array_push(&ctx->params);
- if (ctx->param == NULL) {
- return NGX_ERROR;
- }
-
- ctx->param->key.len = 1;
- ctx->param->key.data = ngx_pnalloc(r->pool,
- NGX_HTTP_SSI_PARAM_LEN);
- if (ctx->param->key.data == NULL) {
- return NGX_ERROR;
- }
-
- ctx->param->key.data[0] = ch;
-
- ctx->param->value.len = 0;
-
- if (ctx->value_buf == NULL) {
- ctx->param->value.data = ngx_pnalloc(r->pool,
- ctx->value_len + 1);
- if (ctx->param->value.data == NULL) {
- return NGX_ERROR;
- }
-
- } else {
- ctx->param->value.data = ctx->value_buf;
- }
-
- state = ssi_param_state;
- break;
- }
-
- break;
-
- case ssi_param_state:
- switch (ch) {
- case ' ':
- case CR:
- case LF:
- case '\t':
- state = ssi_preequal_state;
- break;
-
- case '=':
- state = ssi_prevalue_state;
- break;
-
- case '-':
- state = ssi_error_end0_state;
-
- ctx->param->key.data[ctx->param->key.len++] = ch;
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "invalid \"%V\" parameter in \"%V\" SSI command",
- &ctx->param->key, &ctx->command);
- break;
-
- default:
- if (ctx->param->key.len == NGX_HTTP_SSI_PARAM_LEN) {
- state = ssi_error_state;
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "too long \"%V%c...\" parameter in "
- "\"%V\" SSI command",
- &ctx->param->key, ch, &ctx->command);
- break;
- }
-
- ctx->param->key.data[ctx->param->key.len++] = ch;
- }
-
- break;
-
- case ssi_preequal_state:
- switch (ch) {
- case ' ':
- case CR:
- case LF:
- case '\t':
- break;
-
- case '=':
- state = ssi_prevalue_state;
- break;
-
- default:
- if (ch == '-') {
- state = ssi_error_end0_state;
- } else {
- state = ssi_error_state;
- }
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "unexpected \"%c\" symbol after \"%V\" "
- "parameter in \"%V\" SSI command",
- ch, &ctx->param->key, &ctx->command);
- break;
- }
-
- break;
-
- case ssi_prevalue_state:
- switch (ch) {
- case ' ':
- case CR:
- case LF:
- case '\t':
- break;
-
- case '"':
- state = ssi_double_quoted_value_state;
- break;
-
- case '\'':
- state = ssi_quoted_value_state;
- break;
-
- default:
- if (ch == '-') {
- state = ssi_error_end0_state;
- } else {
- state = ssi_error_state;
- }
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "unexpected \"%c\" symbol before value of "
- "\"%V\" parameter in \"%V\" SSI command",
- ch, &ctx->param->key, &ctx->command);
- break;
- }
-
- break;
-
- case ssi_double_quoted_value_state:
- switch (ch) {
- case '"':
- state = ssi_postparam_state;
- break;
-
- case '\\':
- ctx->saved_state = ssi_double_quoted_value_state;
- state = ssi_quoted_symbol_state;
-
- /* fall through */
-
- default:
- if (ctx->param->value.len == ctx->value_len) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "too long \"%V%c...\" value of \"%V\" "
- "parameter in \"%V\" SSI command",
- &ctx->param->value, ch, &ctx->param->key,
- &ctx->command);
- state = ssi_error_state;
- break;
- }
-
- ctx->param->value.data[ctx->param->value.len++] = ch;
- }
-
- break;
-
- case ssi_quoted_value_state:
- switch (ch) {
- case '\'':
- state = ssi_postparam_state;
- break;
-
- case '\\':
- ctx->saved_state = ssi_quoted_value_state;
- state = ssi_quoted_symbol_state;
-
- /* fall through */
-
- default:
- if (ctx->param->value.len == ctx->value_len) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "too long \"%V%c...\" value of \"%V\" "
- "parameter in \"%V\" SSI command",
- &ctx->param->value, ch, &ctx->param->key,
- &ctx->command);
- state = ssi_error_state;
- break;
- }
-
- ctx->param->value.data[ctx->param->value.len++] = ch;
- }
-
- break;
-
- case ssi_quoted_symbol_state:
- state = ctx->saved_state;
-
- if (ctx->param->value.len == ctx->value_len) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "too long \"%V%c...\" value of \"%V\" "
- "parameter in \"%V\" SSI command",
- &ctx->param->value, ch, &ctx->param->key,
- &ctx->command);
- state = ssi_error_state;
- break;
- }
-
- ctx->param->value.data[ctx->param->value.len++] = ch;
-
- break;
-
- case ssi_postparam_state:
-
- if (ctx->param->value.len + 1 < ctx->value_len / 2) {
- value = ngx_pnalloc(r->pool, ctx->param->value.len + 1);
- if (value == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(value, ctx->param->value.data,
- ctx->param->value.len);
-
- ctx->value_buf = ctx->param->value.data;
- ctx->param->value.data = value;
-
- } else {
- ctx->value_buf = NULL;
- }
-
- switch (ch) {
- case ' ':
- case CR:
- case LF:
- case '\t':
- state = ssi_preparam_state;
- break;
-
- case '-':
- state = ssi_comment_end0_state;
- break;
-
- default:
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "unexpected \"%c\" symbol after \"%V\" value "
- "of \"%V\" parameter in \"%V\" SSI command",
- ch, &ctx->param->value, &ctx->param->key,
- &ctx->command);
- state = ssi_error_state;
- break;
- }
-
- break;
-
- case ssi_comment_end0_state:
- switch (ch) {
- case '-':
- state = ssi_comment_end1_state;
- break;
-
- default:
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "unexpected \"%c\" symbol in \"%V\" SSI command",
- ch, &ctx->command);
- state = ssi_error_state;
- break;
- }
-
- break;
-
- case ssi_comment_end1_state:
- switch (ch) {
- case '>':
- ctx->state = ssi_start_state;
- ctx->pos = p + 1;
- ctx->looked = looked;
- ctx->copy_end = copy_end;
-
- if (ctx->copy_start == NULL && copy_end) {
- ctx->copy_start = ctx->buf->pos;
- }
-
- return NGX_OK;
-
- default:
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "unexpected \"%c\" symbol in \"%V\" SSI command",
- ch, &ctx->command);
- state = ssi_error_state;
- break;
- }
-
- break;
-
- case ssi_error_state:
- switch (ch) {
- case '-':
- state = ssi_error_end0_state;
- break;
-
- default:
- break;
- }
-
- break;
-
- case ssi_error_end0_state:
- switch (ch) {
- case '-':
- state = ssi_error_end1_state;
- break;
-
- default:
- state = ssi_error_state;
- break;
- }
-
- break;
-
- case ssi_error_end1_state:
- switch (ch) {
- case '>':
- ctx->state = ssi_start_state;
- ctx->pos = p + 1;
- ctx->looked = looked;
- ctx->copy_end = copy_end;
-
- if (ctx->copy_start == NULL && copy_end) {
- ctx->copy_start = ctx->buf->pos;
- }
-
- return NGX_HTTP_SSI_ERROR;
-
- default:
- state = ssi_error_state;
- break;
- }
-
- break;
- }
- }
-
- ctx->state = state;
- ctx->pos = p;
- ctx->looked = looked;
-
- ctx->copy_end = (state == ssi_start_state) ? p : copy_end;
-
- if (ctx->copy_start == NULL && ctx->copy_end) {
- ctx->copy_start = ctx->buf->pos;
- }
-
- return NGX_AGAIN;
-}
-
-
-static ngx_str_t *
-ngx_http_ssi_get_variable(ngx_http_request_t *r, ngx_str_t *name,
- ngx_uint_t key)
-{
- ngx_uint_t i;
- ngx_list_part_t *part;
- ngx_http_ssi_var_t *var;
- ngx_http_ssi_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
-
-#if (NGX_PCRE)
- {
- ngx_str_t *value;
-
- if (key >= '0' && key <= '9') {
- i = key - '0';
-
- if (i < ctx->ncaptures) {
- value = ngx_palloc(r->pool, sizeof(ngx_str_t));
- if (value == NULL) {
- return NULL;
- }
-
- i *= 2;
-
- value->data = ctx->captures_data + ctx->captures[i];
- value->len = ctx->captures[i + 1] - ctx->captures[i];
-
- return value;
- }
- }
- }
-#endif
-
- if (ctx->variables == NULL) {
- return NULL;
- }
-
- part = &ctx->variables->part;
- var = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- var = part->elts;
- i = 0;
- }
-
- if (name->len != var[i].name.len) {
- continue;
- }
-
- if (key != var[i].key) {
- continue;
- }
-
- if (ngx_strncmp(name->data, var[i].name.data, name->len) == 0) {
- return &var[i].value;
- }
- }
-
- return NULL;
-}
-
-
-static ngx_int_t
-ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
- ngx_str_t *text, ngx_uint_t flags)
-{
- u_char ch, *p, **value, *data, *part_data;
- size_t *size, len, prefix, part_len;
- ngx_str_t var, *val;
- ngx_int_t key;
- ngx_uint_t i, n, bracket, quoted;
- ngx_array_t lengths, values;
- ngx_http_variable_value_t *vv;
-
- n = ngx_http_script_variables_count(text);
-
- if (n == 0) {
-
- data = text->data;
- p = data;
-
- if ((flags & NGX_HTTP_SSI_ADD_PREFIX) && text->data[0] != '/') {
-
- for (prefix = r->uri.len; prefix; prefix--) {
- if (r->uri.data[prefix - 1] == '/') {
- break;
- }
- }
-
- if (prefix) {
- len = prefix + text->len;
-
- data = ngx_pnalloc(r->pool, len);
- if (data == NULL) {
- return NGX_ERROR;
- }
-
- p = ngx_copy(data, r->uri.data, prefix);
- }
- }
-
- quoted = 0;
-
- for (i = 0; i < text->len; i++) {
- ch = text->data[i];
-
- if (!quoted) {
-
- if (ch == '\\') {
- quoted = 1;
- continue;
- }
-
- } else {
- quoted = 0;
-
- if (ch != '\\' && ch != '\'' && ch != '"' && ch != '$') {
- *p++ = '\\';
- }
- }
-
- *p++ = ch;
- }
-
- text->len = p - data;
- text->data = data;
-
- return NGX_OK;
- }
-
- if (ngx_array_init(&lengths, r->pool, 8, sizeof(size_t *)) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&values, r->pool, 8, sizeof(u_char *)) != NGX_OK) {
- return NGX_ERROR;
- }
-
- len = 0;
- i = 0;
-
- while (i < text->len) {
-
- if (text->data[i] == '$') {
-
- var.len = 0;
-
- if (++i == text->len) {
- goto invalid_variable;
- }
-
- if (text->data[i] == '{') {
- bracket = 1;
-
- if (++i == text->len) {
- goto invalid_variable;
- }
-
- var.data = &text->data[i];
-
- } else {
- bracket = 0;
- var.data = &text->data[i];
- }
-
- for ( /* void */ ; i < text->len; i++, var.len++) {
- ch = text->data[i];
-
- if (ch == '}' && bracket) {
- i++;
- bracket = 0;
- break;
- }
-
- if ((ch >= 'A' && ch <= 'Z')
- || (ch >= 'a' && ch <= 'z')
- || (ch >= '0' && ch <= '9')
- || ch == '_')
- {
- continue;
- }
-
- break;
- }
-
- if (bracket) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "the closing bracket in \"%V\" "
- "variable is missing", &var);
- return NGX_HTTP_SSI_ERROR;
- }
-
- if (var.len == 0) {
- goto invalid_variable;
- }
-
- key = ngx_hash_strlow(var.data, var.data, var.len);
-
- val = ngx_http_ssi_get_variable(r, &var, key);
-
- if (val == NULL) {
- vv = ngx_http_get_variable(r, &var, key);
- if (vv == NULL) {
- return NGX_ERROR;
- }
-
- if (vv->not_found) {
- continue;
- }
-
- part_data = vv->data;
- part_len = vv->len;
-
- } else {
- part_data = val->data;
- part_len = val->len;
- }
-
- } else {
- part_data = &text->data[i];
- quoted = 0;
-
- for (p = part_data; i < text->len; i++) {
- ch = text->data[i];
-
- if (!quoted) {
-
- if (ch == '\\') {
- quoted = 1;
- continue;
- }
-
- if (ch == '$') {
- break;
- }
-
- } else {
- quoted = 0;
-
- if (ch != '\\' && ch != '\'' && ch != '"' && ch != '$') {
- *p++ = '\\';
- }
- }
-
- *p++ = ch;
- }
-
- part_len = p - part_data;
- }
-
- len += part_len;
-
- size = ngx_array_push(&lengths);
- if (size == NULL) {
- return NGX_ERROR;
- }
-
- *size = part_len;
-
- value = ngx_array_push(&values);
- if (value == NULL) {
- return NGX_ERROR;
- }
-
- *value = part_data;
- }
-
- prefix = 0;
-
- size = lengths.elts;
- value = values.elts;
-
- if (flags & NGX_HTTP_SSI_ADD_PREFIX) {
- for (i = 0; i < values.nelts; i++) {
- if (size[i] != 0) {
- if (*value[i] != '/') {
- for (prefix = r->uri.len; prefix; prefix--) {
- if (r->uri.data[prefix - 1] == '/') {
- len += prefix;
- break;
- }
- }
- }
-
- break;
- }
- }
- }
-
- p = ngx_pnalloc(r->pool, len + ((flags & NGX_HTTP_SSI_ADD_ZERO) ? 1 : 0));
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- text->len = len;
- text->data = p;
-
- p = ngx_copy(p, r->uri.data, prefix);
-
- for (i = 0; i < values.nelts; i++) {
- p = ngx_copy(p, value[i], size[i]);
- }
-
- return NGX_OK;
-
-invalid_variable:
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "invalid variable name in \"%V\"", text);
-
- return NGX_HTTP_SSI_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_ssi_regex_match(ngx_http_request_t *r, ngx_str_t *pattern,
- ngx_str_t *str)
-{
-#if (NGX_PCRE)
- int rc, *captures;
- u_char *p, errstr[NGX_MAX_CONF_ERRSTR];
- size_t size;
- ngx_int_t key;
- ngx_str_t *vv, name, value;
- ngx_uint_t i, n;
- ngx_http_ssi_ctx_t *ctx;
- ngx_http_ssi_var_t *var;
- ngx_regex_compile_t rgc;
-
- ngx_memzero(&rgc, sizeof(ngx_regex_compile_t));
-
- rgc.pattern = *pattern;
- rgc.pool = r->pool;
- rgc.err.len = NGX_MAX_CONF_ERRSTR;
- rgc.err.data = errstr;
-
- if (ngx_regex_compile(&rgc) != NGX_OK) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V", &rgc.err);
- return NGX_HTTP_SSI_ERROR;
- }
-
- n = (rgc.captures + 1) * 3;
-
- captures = ngx_palloc(r->pool, n * sizeof(int));
- if (captures == NULL) {
- return NGX_ERROR;
- }
-
- rc = ngx_regex_exec(rgc.regex, str, captures, n);
-
- if (rc < NGX_REGEX_NO_MATCHED) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
- rc, str, pattern);
- return NGX_HTTP_SSI_ERROR;
- }
-
- if (rc == NGX_REGEX_NO_MATCHED) {
- return NGX_DECLINED;
- }
-
- ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
-
- ctx->ncaptures = rc;
- ctx->captures = captures;
- ctx->captures_data = str->data;
-
- if (rgc.named_captures > 0) {
-
- if (ctx->variables == NULL) {
- ctx->variables = ngx_list_create(r->pool, 4,
- sizeof(ngx_http_ssi_var_t));
- if (ctx->variables == NULL) {
- return NGX_ERROR;
- }
- }
-
- size = rgc.name_size;
- p = rgc.names;
-
- for (i = 0; i < (ngx_uint_t) rgc.named_captures; i++, p += size) {
-
- name.data = &p[2];
- name.len = ngx_strlen(name.data);
-
- n = 2 * ((p[0] << 8) + p[1]);
-
- value.data = &str->data[captures[n]];
- value.len = captures[n + 1] - captures[n];
-
- key = ngx_hash_strlow(name.data, name.data, name.len);
-
- vv = ngx_http_ssi_get_variable(r, &name, key);
-
- if (vv) {
- *vv = value;
- continue;
- }
-
- var = ngx_list_push(ctx->variables);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->name = name;
- var->key = key;
- var->value = value;
- }
- }
-
- return NGX_OK;
-
-#else
-
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "the using of the regex \"%V\" in SSI requires PCRE library",
- pattern);
- return NGX_HTTP_SSI_ERROR;
-
-#endif
-}
-
-
-static ngx_int_t
-ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
- ngx_str_t **params)
-{
- ngx_int_t rc, key;
- ngx_str_t *uri, *file, *wait, *set, *stub, args;
- ngx_buf_t *b;
- ngx_uint_t flags, i;
- ngx_chain_t *cl, *tl, **ll, *out;
- ngx_http_request_t *sr;
- ngx_http_ssi_var_t *var;
- ngx_http_ssi_ctx_t *mctx;
- ngx_http_ssi_block_t *bl;
- ngx_http_post_subrequest_t *psr;
-
- uri = params[NGX_HTTP_SSI_INCLUDE_VIRTUAL];
- file = params[NGX_HTTP_SSI_INCLUDE_FILE];
- wait = params[NGX_HTTP_SSI_INCLUDE_WAIT];
- set = params[NGX_HTTP_SSI_INCLUDE_SET];
- stub = params[NGX_HTTP_SSI_INCLUDE_STUB];
-
- if (uri && file) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "inlcusion may be either virtual=\"%V\" or file=\"%V\"",
- uri, file);
- return NGX_HTTP_SSI_ERROR;
- }
-
- if (uri == NULL && file == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "no parameter in \"include\" SSI command");
- return NGX_HTTP_SSI_ERROR;
- }
-
- if (set && stub) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "\"set\" and \"stub\" cannot be used together "
- "in \"include\" SSI command");
- return NGX_HTTP_SSI_ERROR;
- }
-
- if (wait) {
- if (uri == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "\"wait\" cannot be used with file=\"%V\"", file);
- return NGX_HTTP_SSI_ERROR;
- }
-
- if (wait->len == 2
- && ngx_strncasecmp(wait->data, (u_char *) "no", 2) == 0)
- {
- wait = NULL;
-
- } else if (wait->len != 3
- || ngx_strncasecmp(wait->data, (u_char *) "yes", 3) != 0)
- {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "invalid value \"%V\" in the \"wait\" parameter",
- wait);
- return NGX_HTTP_SSI_ERROR;
- }
- }
-
- if (uri == NULL) {
- uri = file;
- wait = (ngx_str_t *) -1;
- }
-
- rc = ngx_http_ssi_evaluate_string(r, ctx, uri, NGX_HTTP_SSI_ADD_PREFIX);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "ssi include: \"%V\"", uri);
-
- ngx_str_null(&args);
- flags = NGX_HTTP_LOG_UNSAFE;
-
- if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
- return NGX_HTTP_SSI_ERROR;
- }
-
- psr = NULL;
-
- mctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
-
- if (stub) {
- if (mctx->blocks) {
- bl = mctx->blocks->elts;
- for (i = 0; i < mctx->blocks->nelts; i++) {
- if (stub->len == bl[i].name.len
- && ngx_strncmp(stub->data, bl[i].name.data, stub->len) == 0)
- {
- goto found;
- }
- }
- }
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "\"stub\"=\"%V\" for \"include\" not found", stub);
- return NGX_HTTP_SSI_ERROR;
-
- found:
-
- psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
- if (psr == NULL) {
- return NGX_ERROR;
- }
-
- psr->handler = ngx_http_ssi_stub_output;
-
- if (bl[i].count++) {
-
- out = NULL;
- ll = &out;
-
- for (tl = bl[i].bufs; tl; tl = tl->next) {
-
- if (ctx->free) {
- cl = ctx->free;
- ctx->free = ctx->free->next;
- b = cl->buf;
-
- } else {
- b = ngx_alloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- }
-
- ngx_memcpy(b, tl->buf, sizeof(ngx_buf_t));
-
- b->pos = b->start;
-
- *ll = cl;
- cl->next = NULL;
- ll = &cl->next;
- }
-
- psr->data = out;
-
- } else {
- psr->data = bl[i].bufs;
- }
- }
-
- if (wait) {
- flags |= NGX_HTTP_SUBREQUEST_WAITED;
- }
-
- if (set) {
- key = ngx_hash_strlow(set->data, set->data, set->len);
-
- psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
- if (psr == NULL) {
- return NGX_ERROR;
- }
-
- psr->handler = ngx_http_ssi_set_variable;
- psr->data = ngx_http_ssi_get_variable(r, set, key);
-
- if (psr->data == NULL) {
-
- if (mctx->variables == NULL) {
- mctx->variables = ngx_list_create(r->pool, 4,
- sizeof(ngx_http_ssi_var_t));
- if (mctx->variables == NULL) {
- return NGX_ERROR;
- }
- }
-
- var = ngx_list_push(mctx->variables);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->name = *set;
- var->key = key;
- var->value = ngx_http_ssi_null_string;
- psr->data = &var->value;
- }
-
- flags |= NGX_HTTP_SUBREQUEST_IN_MEMORY|NGX_HTTP_SUBREQUEST_WAITED;
- }
-
- if (ngx_http_subrequest(r, uri, &args, &sr, psr, flags) != NGX_OK) {
- return NGX_HTTP_SSI_ERROR;
- }
-
- if (wait == NULL && set == NULL) {
- return NGX_OK;
- }
-
- if (ctx->wait == NULL) {
- ctx->wait = sr;
-
- return NGX_AGAIN;
-
- } else {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "can only wait for one subrequest at a time");
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data, ngx_int_t rc)
-{
- ngx_chain_t *out;
-
- if (rc == NGX_ERROR || r->connection->error || r->request_output) {
- return rc;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "ssi stub output: \"%V?%V\"", &r->uri, &r->args);
-
- out = data;
-
- if (!r->header_sent) {
- r->headers_out.content_type_len =
- r->parent->headers_out.content_type_len;
- r->headers_out.content_type = r->parent->headers_out.content_type;
-
- if (ngx_http_send_header(r) == NGX_ERROR) {
- return NGX_ERROR;
- }
- }
-
- return ngx_http_output_filter(r, out);
-}
-
-
-static ngx_int_t
-ngx_http_ssi_set_variable(ngx_http_request_t *r, void *data, ngx_int_t rc)
-{
- ngx_str_t *value = data;
-
- if (r->upstream) {
- value->len = r->upstream->buffer.last - r->upstream->buffer.pos;
- value->data = r->upstream->buffer.pos;
- }
-
- return rc;
-}
-
-
-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_buf_t *b;
- ngx_str_t *var, *value, *enc, text;
- ngx_chain_t *cl;
- ngx_http_variable_value_t *vv;
-
- var = params[NGX_HTTP_SSI_ECHO_VAR];
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "ssi echo \"%V\"", var);
-
- key = ngx_hash_strlow(var->data, var->data, var->len);
-
- value = ngx_http_ssi_get_variable(r, var, key);
-
- if (value == NULL) {
- vv = ngx_http_get_variable(r, var, key);
-
- if (vv == NULL) {
- return NGX_HTTP_SSI_ERROR;
- }
-
- if (!vv->not_found) {
- text.data = vv->data;
- text.len = vv->len;
- value = &text;
- }
- }
-
- if (value == NULL) {
- value = params[NGX_HTTP_SSI_ECHO_DEFAULT];
-
- if (value == NULL) {
- value = &ngx_http_ssi_none;
-
- } else if (value->len == 0) {
- return NGX_OK;
- }
-
- } else {
- if (value->len == 0) {
- return NGX_OK;
- }
- }
-
- 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);
- }
- }
-
- p = value->data;
-
- switch (ctx->encoding) {
-
- case NGX_HTTP_SSI_URL_ENCODING:
- len = 2 * ngx_escape_uri(NULL, value->data, value->len,
- NGX_ESCAPE_HTML);
-
- if (len) {
- p = ngx_pnalloc(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);
- }
-
- len += value->len;
- break;
-
- case NGX_HTTP_SSI_ENTITY_ENCODING:
- len = ngx_escape_html(NULL, value->data, value->len);
-
- if (len) {
- p = ngx_pnalloc(r->pool, value->len + len);
- if (p == NULL) {
- return NGX_HTTP_SSI_ERROR;
- }
-
- (void) ngx_escape_html(p, value->data, value->len);
- }
-
- len += value->len;
- break;
-
- default: /* NGX_HTTP_SSI_NO_ENCODING */
- len = value->len;
- break;
- }
-
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- return NGX_HTTP_SSI_ERROR;
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_HTTP_SSI_ERROR;
- }
-
- b->memory = 1;
- b->pos = p;
- b->last = p + len;
-
- cl->buf = b;
- cl->next = NULL;
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_ssi_config(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
- ngx_str_t **params)
-{
- ngx_str_t *value;
-
- value = params[NGX_HTTP_SSI_CONFIG_TIMEFMT];
-
- if (value) {
- ctx->timefmt.len = value->len;
- ctx->timefmt.data = ngx_pnalloc(r->pool, value->len + 1);
- if (ctx->timefmt.data == NULL) {
- return NGX_HTTP_SSI_ERROR;
- }
-
- ngx_cpystrn(ctx->timefmt.data, value->data, value->len + 1);
- }
-
- value = params[NGX_HTTP_SSI_CONFIG_ERRMSG];
-
- if (value) {
- ctx->errmsg = *value;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_ssi_set(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
- ngx_str_t **params)
-{
- ngx_int_t key, rc;
- ngx_str_t *name, *value, *vv;
- ngx_http_ssi_var_t *var;
- ngx_http_ssi_ctx_t *mctx;
-
- mctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
-
- if (mctx->variables == NULL) {
- mctx->variables = ngx_list_create(r->pool, 4,
- sizeof(ngx_http_ssi_var_t));
- if (mctx->variables == NULL) {
- return NGX_ERROR;
- }
- }
-
- name = params[NGX_HTTP_SSI_SET_VAR];
- value = params[NGX_HTTP_SSI_SET_VALUE];
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "ssi set \"%V\" \"%V\"", name, value);
-
- rc = ngx_http_ssi_evaluate_string(r, ctx, value, 0);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- key = ngx_hash_strlow(name->data, name->data, name->len);
-
- vv = ngx_http_ssi_get_variable(r, name, key);
-
- if (vv) {
- *vv = *value;
- return NGX_OK;
- }
-
- var = ngx_list_push(mctx->variables);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->name = *name;
- var->key = key;
- var->value = *value;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "set: \"%V\"=\"%V\"", name, value);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_ssi_if(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
- ngx_str_t **params)
-{
- u_char *p, *last;
- ngx_str_t *expr, left, right;
- ngx_int_t rc;
- ngx_uint_t negative, noregex, flags;
-
- if (ctx->command.len == 2) {
- if (ctx->conditional) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "the \"if\" command inside the \"if\" command");
- return NGX_HTTP_SSI_ERROR;
- }
- }
-
- if (ctx->output_chosen) {
- ctx->output = 0;
- return NGX_OK;
- }
-
- expr = params[NGX_HTTP_SSI_IF_EXPR];
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "ssi if expr=\"%V\"", expr);
-
- left.data = expr->data;
- last = expr->data + expr->len;
-
- for (p = left.data; p < last; p++) {
- if (*p >= 'A' && *p <= 'Z') {
- *p |= 0x20;
- continue;
- }
-
- if ((*p >= 'a' && *p <= 'z')
- || (*p >= '0' && *p <= '9')
- || *p == '$' || *p == '{' || *p == '}' || *p == '_'
- || *p == '"' || *p == '\'')
- {
- continue;
- }
-
- break;
- }
-
- left.len = p - left.data;
-
- while (p < last && *p == ' ') {
- p++;
- }
-
- flags = 0;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "left: \"%V\"", &left);
-
- rc = ngx_http_ssi_evaluate_string(r, ctx, &left, flags);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "evaluted left: \"%V\"", &left);
-
- if (p == last) {
- if (left.len) {
- ctx->output = 1;
- ctx->output_chosen = 1;
-
- } else {
- ctx->output = 0;
- }
-
- ctx->conditional = NGX_HTTP_SSI_COND_IF;
-
- return NGX_OK;
- }
-
- if (p < last && *p == '=') {
- negative = 0;
- p++;
-
- } else if (p + 1 < last && *p == '!' && *(p + 1) == '=') {
- negative = 1;
- p += 2;
-
- } else {
- goto invalid_expression;
- }
-
- while (p < last && *p == ' ') {
- p++;
- }
-
- if (p < last - 1 && *p == '/') {
- if (*(last - 1) != '/') {
- goto invalid_expression;
- }
-
- noregex = 0;
- flags = NGX_HTTP_SSI_ADD_ZERO;
- last--;
- p++;
-
- } else {
- noregex = 1;
- flags = 0;
-
- if (p < last - 1 && p[0] == '\\' && p[1] == '/') {
- p++;
- }
- }
-
- right.len = last - p;
- right.data = p;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "right: \"%V\"", &right);
-
- rc = ngx_http_ssi_evaluate_string(r, ctx, &right, flags);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "evaluted right: \"%V\"", &right);
-
- if (noregex) {
- if (left.len != right.len) {
- rc = -1;
-
- } else {
- rc = ngx_strncmp(left.data, right.data, right.len);
- }
-
- } else {
- right.data[right.len] = '\0';
-
- rc = ngx_http_ssi_regex_match(r, &right, &left);
-
- if (rc == NGX_OK) {
- rc = 0;
- } else if (rc == NGX_DECLINED) {
- rc = -1;
- } else {
- return rc;
- }
- }
-
- if ((rc == 0 && !negative) || (rc != 0 && negative)) {
- ctx->output = 1;
- ctx->output_chosen = 1;
-
- } else {
- ctx->output = 0;
- }
-
- ctx->conditional = NGX_HTTP_SSI_COND_IF;
-
- return NGX_OK;
-
-invalid_expression:
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "invalid expression in \"%V\"", expr);
-
- return NGX_HTTP_SSI_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_ssi_else(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
- ngx_str_t **params)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "ssi else");
-
- if (ctx->output_chosen) {
- ctx->output = 0;
- } else {
- ctx->output = 1;
- }
-
- ctx->conditional = NGX_HTTP_SSI_COND_ELSE;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_ssi_endif(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
- ngx_str_t **params)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "ssi endif");
-
- ctx->output = 1;
- ctx->output_chosen = 0;
- ctx->conditional = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_ssi_block(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
- ngx_str_t **params)
-{
- ngx_http_ssi_ctx_t *mctx;
- ngx_http_ssi_block_t *bl;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "ssi block");
-
- mctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
-
- if (mctx->blocks == NULL) {
- mctx->blocks = ngx_array_create(r->pool, 4,
- sizeof(ngx_http_ssi_block_t));
- if (mctx->blocks == NULL) {
- return NGX_HTTP_SSI_ERROR;
- }
- }
-
- bl = ngx_array_push(mctx->blocks);
- if (bl == NULL) {
- return NGX_HTTP_SSI_ERROR;
- }
-
- bl->name = *params[NGX_HTTP_SSI_BLOCK_NAME];
- bl->bufs = NULL;
- bl->count = 0;
-
- ctx->output = 0;
- ctx->block = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_ssi_endblock(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
- ngx_str_t **params)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "ssi endblock");
-
- ctx->output = 1;
- ctx->block = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t gmt)
-{
- ngx_http_ssi_ctx_t *ctx;
- ngx_time_t *tp;
- ngx_str_t *timefmt;
- struct tm tm;
- char buf[NGX_HTTP_SSI_DATE_LEN];
-
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- tp = ngx_timeofday();
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
-
- timefmt = ctx ? &ctx->timefmt : &ngx_http_ssi_timefmt;
-
- if (timefmt->len == sizeof("%s") - 1
- && timefmt->data[0] == '%' && timefmt->data[1] == 's')
- {
- v->data = ngx_pnalloc(r->pool, NGX_TIME_T_LEN);
- if (v->data == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_sprintf(v->data, "%T", tp->sec) - v->data;
-
- return NGX_OK;
- }
-
- if (gmt) {
- ngx_libc_gmtime(tp->sec, &tm);
- } else {
- ngx_libc_localtime(tp->sec, &tm);
- }
-
- v->len = strftime(buf, NGX_HTTP_SSI_DATE_LEN,
- (char *) timefmt->data, &tm);
- if (v->len == 0) {
- return NGX_ERROR;
- }
-
- v->data = ngx_pnalloc(r->pool, v->len);
- if (v->data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(v->data, buf, v->len);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_ssi_preconfiguration(ngx_conf_t *cf)
-{
- ngx_int_t rc;
- ngx_http_variable_t *var, *v;
- ngx_http_ssi_command_t *cmd;
- ngx_http_ssi_main_conf_t *smcf;
-
- for (v = ngx_http_ssi_vars; v->name.len; v++) {
- var = ngx_http_add_variable(cf, &v->name, v->flags);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = v->get_handler;
- var->data = v->data;
- }
-
- smcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_ssi_filter_module);
-
- for (cmd = ngx_http_ssi_commands; cmd->name.len; cmd++) {
- rc = ngx_hash_add_key(&smcf->commands, &cmd->name, cmd,
- NGX_HASH_READONLY_KEY);
-
- if (rc == NGX_OK) {
- continue;
- }
-
- if (rc == NGX_BUSY) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "conflicting SSI command \"%V\"", &cmd->name);
- }
-
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_ssi_create_main_conf(ngx_conf_t *cf)
-{
- ngx_http_ssi_main_conf_t *smcf;
-
- smcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssi_main_conf_t));
- if (smcf == NULL) {
- return NULL;
- }
-
- smcf->commands.pool = cf->pool;
- smcf->commands.temp_pool = cf->temp_pool;
-
- if (ngx_hash_keys_array_init(&smcf->commands, NGX_HASH_SMALL) != NGX_OK) {
- return NULL;
- }
-
- return smcf;
-}
-
-
-static char *
-ngx_http_ssi_init_main_conf(ngx_conf_t *cf, void *conf)
-{
- ngx_http_ssi_main_conf_t *smcf = conf;
-
- ngx_hash_init_t hash;
-
- hash.hash = &smcf->hash;
- hash.key = ngx_hash_key;
- hash.max_size = 1024;
- hash.bucket_size = ngx_cacheline_size;
- hash.name = "ssi_command_hash";
- hash.pool = cf->pool;
- hash.temp_pool = NULL;
-
- if (ngx_hash_init(&hash, smcf->commands.keys.elts,
- smcf->commands.keys.nelts)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static void *
-ngx_http_ssi_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_ssi_loc_conf_t *slcf;
-
- slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssi_loc_conf_t));
- if (slcf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->types = { NULL };
- * conf->types_keys = NULL;
- */
-
- slcf->enable = NGX_CONF_UNSET;
- slcf->silent_errors = NGX_CONF_UNSET;
- slcf->ignore_recycled_buffers = NGX_CONF_UNSET;
- slcf->last_modified = NGX_CONF_UNSET;
-
- slcf->min_file_chunk = NGX_CONF_UNSET_SIZE;
- slcf->value_len = NGX_CONF_UNSET_SIZE;
-
- return slcf;
-}
-
-
-static char *
-ngx_http_ssi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_ssi_loc_conf_t *prev = parent;
- ngx_http_ssi_loc_conf_t *conf = child;
-
- ngx_conf_merge_value(conf->enable, prev->enable, 0);
- ngx_conf_merge_value(conf->silent_errors, prev->silent_errors, 0);
- ngx_conf_merge_value(conf->ignore_recycled_buffers,
- prev->ignore_recycled_buffers, 0);
- ngx_conf_merge_value(conf->last_modified, prev->last_modified, 0);
-
- ngx_conf_merge_size_value(conf->min_file_chunk, prev->min_file_chunk, 1024);
- ngx_conf_merge_size_value(conf->value_len, prev->value_len, 255);
-
- if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
- &prev->types_keys, &prev->types,
- ngx_http_html_default_types)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_ssi_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_ssi_header_filter;
-
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_ssi_body_filter;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_ssi_filter_module.h b/usr.sbin/nginx/src/http/modules/ngx_http_ssi_filter_module.h
deleted file mode 100644
index 0bd01a06775..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_ssi_filter_module.h
+++ /dev/null
@@ -1,114 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HTTP_SSI_FILTER_H_INCLUDED_
-#define _NGX_HTTP_SSI_FILTER_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-#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_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 {
- ngx_hash_t hash;
- ngx_hash_keys_arrays_t commands;
-} ngx_http_ssi_main_conf_t;
-
-
-typedef struct {
- ngx_buf_t *buf;
-
- u_char *pos;
- u_char *copy_start;
- u_char *copy_end;
-
- ngx_uint_t key;
- ngx_str_t command;
- ngx_array_t params;
- ngx_table_elt_t *param;
- ngx_table_elt_t params_array[NGX_HTTP_SSI_PARAMS_N];
-
- ngx_chain_t *in;
- ngx_chain_t *out;
- ngx_chain_t **last_out;
- ngx_chain_t *busy;
- ngx_chain_t *free;
-
- ngx_uint_t state;
- ngx_uint_t saved_state;
- size_t saved;
- size_t looked;
-
- size_t value_len;
-
- ngx_list_t *variables;
- ngx_array_t *blocks;
-
-#if (NGX_PCRE)
- ngx_uint_t ncaptures;
- int *captures;
- u_char *captures_data;
-#endif
-
- unsigned conditional:2;
- unsigned encoding:2;
- unsigned block:1;
- unsigned output:1;
- unsigned output_chosen:1;
-
- ngx_http_request_t *wait;
- void *value_buf;
- ngx_str_t timefmt;
- ngx_str_t errmsg;
-} ngx_http_ssi_ctx_t;
-
-
-typedef ngx_int_t (*ngx_http_ssi_command_pt) (ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ctx, ngx_str_t **);
-
-
-typedef struct {
- ngx_str_t name;
- ngx_uint_t index;
-
- unsigned mandatory:1;
- unsigned multiple:1;
-} ngx_http_ssi_param_t;
-
-
-typedef struct {
- ngx_str_t name;
- ngx_http_ssi_command_pt handler;
- ngx_http_ssi_param_t *params;
-
- unsigned conditional:2;
- unsigned block:1;
- unsigned flush:1;
-} ngx_http_ssi_command_t;
-
-
-extern ngx_module_t ngx_http_ssi_filter_module;
-
-
-#endif /* _NGX_HTTP_SSI_FILTER_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_ssl_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_ssl_module.c
deleted file mode 100644
index 206f58d2537..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_ssl_module.c
+++ /dev/null
@@ -1,921 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
- ngx_pool_t *pool, ngx_str_t *s);
-
-
-#define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5"
-#define NGX_DEFAULT_ECDH_CURVE "prime256v1"
-
-#define NGX_HTTP_NPN_ADVERTISE "\x08http/1.1"
-
-
-#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
-static int ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn,
- const unsigned char **out, unsigned char *outlen,
- const unsigned char *in, unsigned int inlen, void *arg);
-#endif
-
-#ifdef TLSEXT_TYPE_next_proto_neg
-static int ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
- const unsigned char **out, unsigned int *outlen, void *arg);
-#endif
-
-static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_ssl_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-
-static ngx_int_t ngx_http_ssl_add_variables(ngx_conf_t *cf);
-static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf);
-static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf,
- void *parent, void *child);
-
-static char *ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-static ngx_int_t ngx_http_ssl_init(ngx_conf_t *cf);
-
-
-static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = {
- { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
- { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
- { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
- { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
- { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_conf_enum_t ngx_http_ssl_verify[] = {
- { ngx_string("off"), 0 },
- { ngx_string("on"), 1 },
- { ngx_string("optional"), 2 },
- { ngx_string("optional_no_ca"), 3 },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_command_t ngx_http_ssl_commands[] = {
-
- { ngx_string("ssl"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
- ngx_http_ssl_enable,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, enable),
- NULL },
-
- { ngx_string("ssl_certificate"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, certificate),
- NULL },
-
- { ngx_string("ssl_certificate_key"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, certificate_key),
- NULL },
-
- { ngx_string("ssl_dhparam"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, dhparam),
- NULL },
-
- { ngx_string("ssl_ecdh_curve"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, ecdh_curve),
- NULL },
-
- { ngx_string("ssl_protocols"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, protocols),
- &ngx_http_ssl_protocols },
-
- { ngx_string("ssl_ciphers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, ciphers),
- NULL },
-
- { ngx_string("ssl_buffer_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, buffer_size),
- NULL },
-
- { ngx_string("ssl_verify_client"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, verify),
- &ngx_http_ssl_verify },
-
- { ngx_string("ssl_verify_depth"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, verify_depth),
- NULL },
-
- { ngx_string("ssl_client_certificate"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, client_certificate),
- NULL },
-
- { ngx_string("ssl_trusted_certificate"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, trusted_certificate),
- NULL },
-
- { ngx_string("ssl_prefer_server_ciphers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, prefer_server_ciphers),
- NULL },
-
- { ngx_string("ssl_session_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12,
- ngx_http_ssl_session_cache,
- NGX_HTTP_SRV_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("ssl_session_tickets"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, session_tickets),
- NULL },
-
- { ngx_string("ssl_session_ticket_key"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_array_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, session_ticket_keys),
- NULL },
-
- { ngx_string("ssl_session_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_sec_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, session_timeout),
- NULL },
-
- { ngx_string("ssl_crl"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, crl),
- NULL },
-
- { ngx_string("ssl_stapling"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, stapling),
- NULL },
-
- { ngx_string("ssl_stapling_file"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, stapling_file),
- NULL },
-
- { ngx_string("ssl_stapling_responder"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, stapling_responder),
- NULL },
-
- { ngx_string("ssl_stapling_verify"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_ssl_srv_conf_t, stapling_verify),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_ssl_module_ctx = {
- ngx_http_ssl_add_variables, /* preconfiguration */
- ngx_http_ssl_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- ngx_http_ssl_create_srv_conf, /* create server configuration */
- ngx_http_ssl_merge_srv_conf, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_ssl_module = {
- NGX_MODULE_V1,
- &ngx_http_ssl_module_ctx, /* module context */
- ngx_http_ssl_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_variable_t ngx_http_ssl_vars[] = {
-
- { ngx_string("ssl_protocol"), NULL, ngx_http_ssl_static_variable,
- (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_CHANGEABLE, 0 },
-
- { ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable,
- (uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 },
-
- { ngx_string("ssl_session_reused"), NULL, ngx_http_ssl_variable,
- (uintptr_t) ngx_ssl_get_session_reused, NGX_HTTP_VAR_CHANGEABLE, 0 },
-
- { ngx_string("ssl_client_cert"), NULL, ngx_http_ssl_variable,
- (uintptr_t) ngx_ssl_get_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 },
-
- { ngx_string("ssl_client_raw_cert"), NULL, ngx_http_ssl_variable,
- (uintptr_t) ngx_ssl_get_raw_certificate,
- 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_CHANGEABLE, 0 },
-
- { ngx_string("ssl_client_i_dn"), NULL, ngx_http_ssl_variable,
- (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_CHANGEABLE, 0 },
-
- { ngx_string("ssl_client_verify"), NULL, ngx_http_ssl_variable,
- (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 },
-
- { ngx_null_string, NULL, NULL, 0, 0, 0 }
-};
-
-
-static ngx_str_t ngx_http_ssl_sess_id_ctx = ngx_string("HTTP");
-
-
-#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
-
-static int
-ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
- unsigned char *outlen, const unsigned char *in, unsigned int inlen,
- void *arg)
-{
- unsigned int srvlen;
- unsigned char *srv;
-#if (NGX_DEBUG)
- unsigned int i;
-#endif
-#if (NGX_HTTP_SPDY)
- ngx_http_connection_t *hc;
-#endif
-#if (NGX_HTTP_SPDY || NGX_DEBUG)
- ngx_connection_t *c;
-
- c = ngx_ssl_get_connection(ssl_conn);
-#endif
-
-#if (NGX_DEBUG)
- for (i = 0; i < inlen; i += in[i] + 1) {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "SSL ALPN supported by client: %*s", in[i], &in[i + 1]);
- }
-#endif
-
-#if (NGX_HTTP_SPDY)
- hc = c->data;
-
- if (hc->addr_conf->spdy) {
- srv = (unsigned char *) NGX_SPDY_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE;
- srvlen = sizeof(NGX_SPDY_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1;
-
- } else
-#endif
- {
- srv = (unsigned char *) NGX_HTTP_NPN_ADVERTISE;
- srvlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1;
- }
-
- if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen,
- in, inlen)
- != OPENSSL_NPN_NEGOTIATED)
- {
- return SSL_TLSEXT_ERR_NOACK;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "SSL ALPN selected: %*s", *outlen, *out);
-
- return SSL_TLSEXT_ERR_OK;
-}
-
-#endif
-
-
-#ifdef TLSEXT_TYPE_next_proto_neg
-
-static int
-ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
- const unsigned char **out, unsigned int *outlen, void *arg)
-{
-#if (NGX_HTTP_SPDY || NGX_DEBUG)
- ngx_connection_t *c;
-
- c = ngx_ssl_get_connection(ssl_conn);
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL NPN advertised");
-#endif
-
-#if (NGX_HTTP_SPDY)
- {
- ngx_http_connection_t *hc;
-
- hc = c->data;
-
- if (hc->addr_conf->spdy) {
- *out = (unsigned char *) NGX_SPDY_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE;
- *outlen = sizeof(NGX_SPDY_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1;
-
- return SSL_TLSEXT_ERR_OK;
- }
- }
-#endif
-
- *out = (unsigned char *) NGX_HTTP_NPN_ADVERTISE;
- *outlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1;
-
- return SSL_TLSEXT_ERR_OK;
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_ssl_static_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
-
- size_t len;
- ngx_str_t s;
-
- if (r->connection->ssl) {
-
- (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_cacheable = 0;
- v->not_found = 0;
-
- return NGX_OK;
- }
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_ssl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- 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, &s) != NGX_OK) {
- return NGX_ERROR;
- }
-
- v->len = s.len;
- v->data = s.data;
-
- if (v->len) {
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- return NGX_OK;
- }
- }
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_ssl_add_variables(ngx_conf_t *cf)
-{
- ngx_http_variable_t *var, *v;
-
- for (v = ngx_http_ssl_vars; v->name.len; v++) {
- var = ngx_http_add_variable(cf, &v->name, v->flags);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = v->get_handler;
- var->data = v->data;
- }
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
-{
- ngx_http_ssl_srv_conf_t *sscf;
-
- sscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssl_srv_conf_t));
- if (sscf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * sscf->protocols = 0;
- * sscf->certificate = { 0, NULL };
- * sscf->certificate_key = { 0, NULL };
- * sscf->dhparam = { 0, NULL };
- * sscf->ecdh_curve = { 0, NULL };
- * sscf->client_certificate = { 0, NULL };
- * sscf->trusted_certificate = { 0, NULL };
- * sscf->crl = { 0, NULL };
- * sscf->ciphers = { 0, NULL };
- * sscf->shm_zone = NULL;
- * sscf->stapling_file = { 0, NULL };
- * sscf->stapling_responder = { 0, NULL };
- */
-
- sscf->enable = NGX_CONF_UNSET;
- sscf->prefer_server_ciphers = NGX_CONF_UNSET;
- sscf->buffer_size = NGX_CONF_UNSET_SIZE;
- sscf->verify = NGX_CONF_UNSET_UINT;
- sscf->verify_depth = NGX_CONF_UNSET_UINT;
- sscf->builtin_session_cache = NGX_CONF_UNSET;
- sscf->session_timeout = NGX_CONF_UNSET;
- sscf->session_tickets = NGX_CONF_UNSET;
- sscf->session_ticket_keys = NGX_CONF_UNSET_PTR;
- sscf->stapling = NGX_CONF_UNSET;
- sscf->stapling_verify = NGX_CONF_UNSET;
-
- return sscf;
-}
-
-
-static char *
-ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_ssl_srv_conf_t *prev = parent;
- ngx_http_ssl_srv_conf_t *conf = child;
-
- ngx_pool_cleanup_t *cln;
-
- if (conf->enable == NGX_CONF_UNSET) {
- if (prev->enable == NGX_CONF_UNSET) {
- conf->enable = 0;
-
- } else {
- conf->enable = prev->enable;
- conf->file = prev->file;
- conf->line = prev->line;
- }
- }
-
- ngx_conf_merge_value(conf->session_timeout,
- prev->session_timeout, 300);
-
- ngx_conf_merge_value(conf->prefer_server_ciphers,
- prev->prefer_server_ciphers, 0);
-
- ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
- (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3|NGX_SSL_TLSv1
- |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
-
- ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
- NGX_SSL_BUFSIZE);
-
- ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
- ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);
-
- ngx_conf_merge_str_value(conf->certificate, prev->certificate, "");
- ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, "");
-
- ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
-
- ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
- "");
- ngx_conf_merge_str_value(conf->trusted_certificate,
- prev->trusted_certificate, "");
- ngx_conf_merge_str_value(conf->crl, prev->crl, "");
-
- ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
- NGX_DEFAULT_ECDH_CURVE);
-
- ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
-
- ngx_conf_merge_value(conf->stapling, prev->stapling, 0);
- ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0);
- ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, "");
- ngx_conf_merge_str_value(conf->stapling_responder,
- prev->stapling_responder, "");
-
- conf->ssl.log = cf->log;
-
- if (conf->enable) {
-
- if (conf->certificate.len == 0) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"ssl_certificate\" is defined for "
- "the \"ssl\" directive in %s:%ui",
- conf->file, conf->line);
- return NGX_CONF_ERROR;
- }
-
- if (conf->certificate_key.len == 0) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"ssl_certificate_key\" is defined for "
- "the \"ssl\" directive in %s:%ui",
- conf->file, conf->line);
- return NGX_CONF_ERROR;
- }
-
- } else {
-
- if (conf->certificate.len == 0) {
- return NGX_CONF_OK;
- }
-
- if (conf->certificate_key.len == 0) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"ssl_certificate_key\" is defined "
- "for certificate \"%V\"", &conf->certificate);
- return NGX_CONF_ERROR;
- }
- }
-
- if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
-#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
-
- if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
- ngx_http_ssl_servername)
- == 0)
- {
- ngx_log_error(NGX_LOG_WARN, cf->log, 0,
- "nginx was built with SNI support, however, now it is linked "
- "dynamically to an OpenSSL library which has no tlsext support, "
- "therefore SNI is not available");
- }
-
-#endif
-
-#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
- SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_http_ssl_alpn_select, NULL);
-#endif
-
-#ifdef TLSEXT_TYPE_next_proto_neg
- SSL_CTX_set_next_protos_advertised_cb(conf->ssl.ctx,
- ngx_http_ssl_npn_advertised, NULL);
-#endif
-
- cln = ngx_pool_cleanup_add(cf->pool, 0);
- if (cln == NULL) {
- return NGX_CONF_ERROR;
- }
-
- cln->handler = ngx_ssl_cleanup_ctx;
- cln->data = &conf->ssl;
-
- if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate,
- &conf->certificate_key)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- if (SSL_CTX_set_cipher_list(conf->ssl.ctx,
- (const char *) conf->ciphers.data)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
- "SSL_CTX_set_cipher_list(\"%V\") failed",
- &conf->ciphers);
- return NGX_CONF_ERROR;
- }
-
- conf->ssl.buffer_size = conf->buffer_size;
-
- if (conf->verify) {
-
- if (conf->client_certificate.len == 0 && conf->verify != 3) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no ssl_client_certificate for ssl_client_verify");
- return NGX_CONF_ERROR;
- }
-
- if (ngx_ssl_client_certificate(cf, &conf->ssl,
- &conf->client_certificate,
- conf->verify_depth)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
- }
-
- if (ngx_ssl_trusted_certificate(cf, &conf->ssl,
- &conf->trusted_certificate,
- conf->verify_depth)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (conf->prefer_server_ciphers) {
- SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
- }
-
- /* a temporary 512-bit RSA key is required for export versions of MSIE */
- SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback);
-
- if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_value(conf->builtin_session_cache,
- prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);
-
- if (conf->shm_zone == NULL) {
- conf->shm_zone = prev->shm_zone;
- }
-
- if (ngx_ssl_session_cache(&conf->ssl, &ngx_http_ssl_sess_id_ctx,
- conf->builtin_session_cache,
- conf->shm_zone, conf->session_timeout)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_value(conf->session_tickets, prev->session_tickets, 1);
-
-#ifdef SSL_OP_NO_TICKET
- if (!conf->session_tickets) {
- SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_NO_TICKET);
- }
-#endif
-
- ngx_conf_merge_ptr_value(conf->session_ticket_keys,
- prev->session_ticket_keys, NULL);
-
- if (ngx_ssl_session_ticket_keys(cf, &conf->ssl, conf->session_ticket_keys)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- if (conf->stapling) {
-
- if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
- &conf->stapling_responder, conf->stapling_verify)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_ssl_srv_conf_t *sscf = conf;
-
- char *rv;
-
- rv = ngx_conf_set_flag_slot(cf, cmd, conf);
-
- if (rv != NGX_CONF_OK) {
- return rv;
- }
-
- sscf->file = cf->conf_file->file.name.data;
- sscf->line = cf->conf_file->line;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_ssl_srv_conf_t *sscf = conf;
-
- size_t len;
- ngx_str_t *value, name, size;
- ngx_int_t n;
- ngx_uint_t i, j;
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (ngx_strcmp(value[i].data, "off") == 0) {
- sscf->builtin_session_cache = NGX_SSL_NO_SCACHE;
- continue;
- }
-
- if (ngx_strcmp(value[i].data, "none") == 0) {
- sscf->builtin_session_cache = NGX_SSL_NONE_SCACHE;
- continue;
- }
-
- if (ngx_strcmp(value[i].data, "builtin") == 0) {
- sscf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
- continue;
- }
-
- if (value[i].len > sizeof("builtin:") - 1
- && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1)
- == 0)
- {
- n = ngx_atoi(value[i].data + sizeof("builtin:") - 1,
- value[i].len - (sizeof("builtin:") - 1));
-
- if (n == NGX_ERROR) {
- goto invalid;
- }
-
- sscf->builtin_session_cache = n;
-
- continue;
- }
-
- if (value[i].len > sizeof("shared:") - 1
- && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1)
- == 0)
- {
- len = 0;
-
- for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
- if (value[i].data[j] == ':') {
- break;
- }
-
- len++;
- }
-
- if (len == 0) {
- goto invalid;
- }
-
- name.len = len;
- name.data = value[i].data + sizeof("shared:") - 1;
-
- size.len = value[i].len - j - 1;
- size.data = name.data + len + 1;
-
- n = ngx_parse_size(&size);
-
- if (n == NGX_ERROR) {
- goto invalid;
- }
-
- if (n < (ngx_int_t) (8 * ngx_pagesize)) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "session cache \"%V\" is too small",
- &value[i]);
-
- return NGX_CONF_ERROR;
- }
-
- sscf->shm_zone = ngx_shared_memory_add(cf, &name, n,
- &ngx_http_ssl_module);
- if (sscf->shm_zone == NULL) {
- return NGX_CONF_ERROR;
- }
-
- sscf->shm_zone->init = ngx_ssl_session_cache_init;
-
- continue;
- }
-
- goto invalid;
- }
-
- if (sscf->shm_zone && sscf->builtin_session_cache == NGX_CONF_UNSET) {
- sscf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
- }
-
- return NGX_CONF_OK;
-
-invalid:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid session cache \"%V\"", &value[i]);
-
- return NGX_CONF_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_ssl_init(ngx_conf_t *cf)
-{
- ngx_uint_t s;
- ngx_http_ssl_srv_conf_t *sscf;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_core_srv_conf_t **cscfp;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
- cscfp = cmcf->servers.elts;
-
- for (s = 0; s < cmcf->servers.nelts; s++) {
-
- sscf = cscfp[s]->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
-
- if (sscf->ssl.ctx == NULL || !sscf->stapling) {
- continue;
- }
-
- clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
-
- if (ngx_ssl_stapling_resolver(cf, &sscf->ssl, clcf->resolver,
- clcf->resolver_timeout)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_ssl_module.h b/usr.sbin/nginx/src/http/modules/ngx_http_ssl_module.h
deleted file mode 100644
index ec2c62f6fb5..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_ssl_module.h
+++ /dev/null
@@ -1,63 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HTTP_SSL_H_INCLUDED_
-#define _NGX_HTTP_SSL_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_flag_t enable;
-
- ngx_ssl_t ssl;
-
- ngx_flag_t prefer_server_ciphers;
-
- ngx_uint_t protocols;
-
- ngx_uint_t verify;
- ngx_uint_t verify_depth;
-
- size_t buffer_size;
-
- ssize_t builtin_session_cache;
-
- time_t session_timeout;
-
- ngx_str_t certificate;
- ngx_str_t certificate_key;
- ngx_str_t dhparam;
- ngx_str_t ecdh_curve;
- ngx_str_t client_certificate;
- ngx_str_t trusted_certificate;
- ngx_str_t crl;
-
- ngx_str_t ciphers;
-
- ngx_shm_zone_t *shm_zone;
-
- ngx_flag_t session_tickets;
- ngx_array_t *session_ticket_keys;
-
- ngx_flag_t stapling;
- ngx_flag_t stapling_verify;
- ngx_str_t stapling_file;
- ngx_str_t stapling_responder;
-
- u_char *file;
- ngx_uint_t line;
-} ngx_http_ssl_srv_conf_t;
-
-
-extern ngx_module_t ngx_http_ssl_module;
-
-
-#endif /* _NGX_HTTP_SSL_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_static_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_static_module.c
deleted file mode 100644
index 631eb17b267..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_static_module.c
+++ /dev/null
@@ -1,290 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r);
-static ngx_int_t ngx_http_static_init(ngx_conf_t *cf);
-
-
-ngx_http_module_t ngx_http_static_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_static_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_static_module = {
- NGX_MODULE_V1,
- &ngx_http_static_module_ctx, /* module context */
- NULL, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_static_handler(ngx_http_request_t *r)
-{
- u_char *last, *location;
- size_t root, len;
- ngx_str_t path;
- ngx_int_t rc;
- ngx_uint_t level;
- ngx_log_t *log;
- ngx_buf_t *b;
- ngx_chain_t out;
- ngx_open_file_info_t of;
- ngx_http_core_loc_conf_t *clcf;
-
- if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) {
- return NGX_HTTP_NOT_ALLOWED;
- }
-
- if (r->uri.data[r->uri.len - 1] == '/') {
- return NGX_DECLINED;
- }
-
- log = r->connection->log;
-
- /*
- * ngx_http_map_uri_to_path() allocates memory for terminating '\0'
- * so we do not need to reserve memory for '/' for possible redirect
- */
-
- last = ngx_http_map_uri_to_path(r, &path, &root, 0);
- if (last == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- path.len = last - path.data;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
- "http filename: \"%s\"", path.data);
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- ngx_memzero(&of, sizeof(ngx_open_file_info_t));
-
- of.read_ahead = clcf->read_ahead;
- of.directio = clcf->directio;
- of.valid = clcf->open_file_cache_valid;
- of.min_uses = clcf->open_file_cache_min_uses;
- of.errors = clcf->open_file_cache_errors;
- of.events = clcf->open_file_cache_events;
-
- if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
- != NGX_OK)
- {
- switch (of.err) {
-
- case 0:
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
-
- case NGX_ENOENT:
- case NGX_ENOTDIR:
- case NGX_ENAMETOOLONG:
-
- level = NGX_LOG_ERR;
- rc = NGX_HTTP_NOT_FOUND;
- break;
-
- case NGX_EACCES:
-#if (NGX_HAVE_OPENAT)
- case NGX_EMLINK:
- case NGX_ELOOP:
-#endif
-
- level = NGX_LOG_ERR;
- rc = NGX_HTTP_FORBIDDEN;
- break;
-
- default:
-
- level = NGX_LOG_CRIT;
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- break;
- }
-
- if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
- ngx_log_error(level, log, of.err,
- "%s \"%s\" failed", of.failed, path.data);
- }
-
- return rc;
- }
-
- r->root_tested = !r->error_page;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", of.fd);
-
- if (of.is_dir) {
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http dir");
-
- ngx_http_clear_location(r);
-
- r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t));
- if (r->headers_out.location == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- len = r->uri.len + 1;
-
- if (!clcf->alias && clcf->root_lengths == NULL && r->args.len == 0) {
- location = path.data + clcf->root.len;
-
- *last = '/';
-
- } else {
- if (r->args.len) {
- len += r->args.len + 1;
- }
-
- location = ngx_pnalloc(r->pool, len);
- if (location == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- last = ngx_copy(location, r->uri.data, r->uri.len);
-
- *last = '/';
-
- if (r->args.len) {
- *++last = '?';
- ngx_memcpy(++last, r->args.data, r->args.len);
- }
- }
-
- /*
- * we do not need to set the r->headers_out.location->hash and
- * r->headers_out.location->key fields
- */
-
- r->headers_out.location->value.len = len;
- r->headers_out.location->value.data = location;
-
- return NGX_HTTP_MOVED_PERMANENTLY;
- }
-
-#if !(NGX_WIN32) /* the not regular files are probably Unix specific */
-
- if (!of.is_file) {
- ngx_log_error(NGX_LOG_CRIT, log, 0,
- "\"%s\" is not a regular file", path.data);
-
- return NGX_HTTP_NOT_FOUND;
- }
-
-#endif
-
- if (r->method & NGX_HTTP_POST) {
- return NGX_HTTP_NOT_ALLOWED;
- }
-
- rc = ngx_http_discard_request_body(r);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- log->action = "sending response to client";
-
- r->headers_out.status = NGX_HTTP_OK;
- r->headers_out.content_length_n = of.size;
- r->headers_out.last_modified_time = of.mtime;
-
- if (ngx_http_set_etag(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (ngx_http_set_content_type(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (r != r->main && of.size == 0) {
- return ngx_http_send_header(r);
- }
-
- r->allow_ranges = 1;
-
- /* we need to allocate all before the header would be sent */
-
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
- if (b->file == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- rc = ngx_http_send_header(r);
-
- if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
- return rc;
- }
-
- b->file_pos = 0;
- b->file_last = of.size;
-
- b->in_file = b->file_last ? 1: 0;
- b->last_buf = (r == r->main) ? 1: 0;
- b->last_in_chain = 1;
-
- b->file->fd = of.fd;
- b->file->name = path;
- b->file->log = log;
- b->file->directio = of.is_directio;
-
- out.buf = b;
- out.next = NULL;
-
- return ngx_http_output_filter(r, &out);
-}
-
-
-static ngx_int_t
-ngx_http_static_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_static_handler;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_stub_status_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_stub_status_module.c
deleted file mode 100644
index b5ecd6d9e2f..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_stub_status_module.c
+++ /dev/null
@@ -1,234 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static ngx_int_t ngx_http_stub_status_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_stub_status_add_variables(ngx_conf_t *cf);
-
-static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-static ngx_command_t ngx_http_status_commands[] = {
-
- { ngx_string("stub_status"),
- NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_http_set_status,
- 0,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-
-static ngx_http_module_t ngx_http_stub_status_module_ctx = {
- ngx_http_stub_status_add_variables, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_stub_status_module = {
- NGX_MODULE_V1,
- &ngx_http_stub_status_module_ctx, /* module context */
- ngx_http_status_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_variable_t ngx_http_stub_status_vars[] = {
-
- { ngx_string("connections_active"), NULL, ngx_http_stub_status_variable,
- 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("connections_reading"), NULL, ngx_http_stub_status_variable,
- 1, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("connections_writing"), NULL, ngx_http_stub_status_variable,
- 2, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("connections_waiting"), NULL, ngx_http_stub_status_variable,
- 3, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_null_string, NULL, NULL, 0, 0, 0 }
-};
-
-
-static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r)
-{
- size_t size;
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t out;
- ngx_atomic_int_t ap, hn, ac, rq, rd, wr, wa;
-
- if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
- return NGX_HTTP_NOT_ALLOWED;
- }
-
- rc = ngx_http_discard_request_body(r);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- r->headers_out.content_type_len = sizeof("text/plain") - 1;
- ngx_str_set(&r->headers_out.content_type, "text/plain");
- r->headers_out.content_type_lowcase = NULL;
-
- if (r->method == NGX_HTTP_HEAD) {
- r->headers_out.status = NGX_HTTP_OK;
-
- rc = ngx_http_send_header(r);
-
- if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
- return rc;
- }
- }
-
- size = sizeof("Active connections: \n") + NGX_ATOMIC_T_LEN
- + sizeof("server accepts handled requests\n") - 1
- + 6 + 3 * NGX_ATOMIC_T_LEN
- + sizeof("Reading: Writing: Waiting: \n") + 3 * NGX_ATOMIC_T_LEN;
-
- b = ngx_create_temp_buf(r->pool, size);
- if (b == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- out.buf = b;
- out.next = NULL;
-
- ap = *ngx_stat_accepted;
- hn = *ngx_stat_handled;
- ac = *ngx_stat_active;
- rq = *ngx_stat_requests;
- rd = *ngx_stat_reading;
- wr = *ngx_stat_writing;
- wa = *ngx_stat_waiting;
-
- b->last = ngx_sprintf(b->last, "Active connections: %uA \n", ac);
-
- b->last = ngx_cpymem(b->last, "server accepts handled requests\n",
- sizeof("server accepts handled requests\n") - 1);
-
- b->last = ngx_sprintf(b->last, " %uA %uA %uA \n", ap, hn, rq);
-
- b->last = ngx_sprintf(b->last, "Reading: %uA Writing: %uA Waiting: %uA \n",
- rd, wr, wa);
-
- r->headers_out.status = NGX_HTTP_OK;
- r->headers_out.content_length_n = b->last - b->pos;
-
- b->last_buf = (r == r->main) ? 1 : 0;
- b->last_in_chain = 1;
-
- rc = ngx_http_send_header(r);
-
- if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
- return rc;
- }
-
- return ngx_http_output_filter(r, &out);
-}
-
-
-static ngx_int_t
-ngx_http_stub_status_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
- ngx_atomic_int_t value;
-
- p = ngx_pnalloc(r->pool, NGX_ATOMIC_T_LEN);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- switch (data) {
- case 0:
- value = *ngx_stat_active;
- break;
-
- case 1:
- value = *ngx_stat_reading;
- break;
-
- case 2:
- value = *ngx_stat_writing;
- break;
-
- case 3:
- value = *ngx_stat_waiting;
- break;
-
- /* suppress warning */
- default:
- value = 0;
- break;
- }
-
- v->len = ngx_sprintf(p, "%uA", value) - p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_stub_status_add_variables(ngx_conf_t *cf)
-{
- ngx_http_variable_t *var, *v;
-
- for (v = ngx_http_stub_status_vars; v->name.len; v++) {
- var = ngx_http_add_variable(cf, &v->name, v->flags);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = v->get_handler;
- var->data = v->data;
- }
-
- return NGX_OK;
-}
-
-
-static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
- clcf->handler = ngx_http_status_handler;
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_sub_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_sub_filter_module.c
deleted file mode 100644
index a4d666bed2b..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_sub_filter_module.c
+++ /dev/null
@@ -1,749 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_str_t match;
- ngx_http_complex_value_t value;
-
- ngx_hash_t types;
-
- ngx_flag_t once;
- ngx_flag_t last_modified;
-
- ngx_array_t *types_keys;
-} ngx_http_sub_loc_conf_t;
-
-
-typedef enum {
- sub_start_state = 0,
- sub_match_state,
-} ngx_http_sub_state_e;
-
-
-typedef struct {
- ngx_str_t match;
- ngx_str_t saved;
- ngx_str_t looked;
-
- ngx_uint_t once; /* unsigned once:1 */
-
- ngx_buf_t *buf;
-
- u_char *pos;
- u_char *copy_start;
- u_char *copy_end;
-
- ngx_chain_t *in;
- ngx_chain_t *out;
- ngx_chain_t **last_out;
- ngx_chain_t *busy;
- ngx_chain_t *free;
-
- ngx_str_t sub;
-
- ngx_uint_t state;
-} ngx_http_sub_ctx_t;
-
-
-static ngx_int_t ngx_http_sub_output(ngx_http_request_t *r,
- ngx_http_sub_ctx_t *ctx);
-static ngx_int_t ngx_http_sub_parse(ngx_http_request_t *r,
- ngx_http_sub_ctx_t *ctx);
-
-static char * ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static void *ngx_http_sub_create_conf(ngx_conf_t *cf);
-static char *ngx_http_sub_merge_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static ngx_int_t ngx_http_sub_filter_init(ngx_conf_t *cf);
-
-
-static ngx_command_t ngx_http_sub_filter_commands[] = {
-
- { ngx_string("sub_filter"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_http_sub_filter,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("sub_filter_types"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_types_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_sub_loc_conf_t, types_keys),
- &ngx_http_html_default_types[0] },
-
- { ngx_string("sub_filter_once"),
- 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_sub_loc_conf_t, once),
- NULL },
-
- { ngx_string("sub_filter_last_modified"),
- 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_sub_loc_conf_t, last_modified),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_sub_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_sub_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_sub_create_conf, /* create location configuration */
- ngx_http_sub_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_sub_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_sub_filter_module_ctx, /* module context */
- ngx_http_sub_filter_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-
-
-static ngx_int_t
-ngx_http_sub_header_filter(ngx_http_request_t *r)
-{
- ngx_http_sub_ctx_t *ctx;
- ngx_http_sub_loc_conf_t *slcf;
-
- slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module);
-
- if (slcf->match.len == 0
- || r->headers_out.content_length_n == 0
- || ngx_http_test_content_type(r, &slcf->types) == NULL)
- {
- return ngx_http_next_header_filter(r);
- }
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ctx->saved.data = ngx_pnalloc(r->pool, slcf->match.len);
- if (ctx->saved.data == NULL) {
- return NGX_ERROR;
- }
-
- ctx->looked.data = ngx_pnalloc(r->pool, slcf->match.len);
- if (ctx->looked.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module);
-
- ctx->match = slcf->match;
- ctx->last_out = &ctx->out;
-
- r->filter_need_in_memory = 1;
-
- if (r == r->main) {
- ngx_http_clear_content_length(r);
- ngx_http_clear_etag(r);
-
- if (!slcf->last_modified) {
- ngx_http_clear_last_modified(r);
- }
- }
-
- return ngx_http_next_header_filter(r);
-}
-
-
-static ngx_int_t
-ngx_http_sub_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t *cl;
- ngx_http_sub_ctx_t *ctx;
- ngx_http_sub_loc_conf_t *slcf;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_sub_filter_module);
-
- if (ctx == NULL) {
- return ngx_http_next_body_filter(r, in);
- }
-
- if ((in == NULL
- && ctx->buf == NULL
- && ctx->in == NULL
- && ctx->busy == NULL))
- {
- return ngx_http_next_body_filter(r, in);
- }
-
- if (ctx->once && (ctx->buf == NULL || ctx->in == NULL)) {
-
- if (ctx->busy) {
- if (ngx_http_sub_output(r, ctx) == NGX_ERROR) {
- return NGX_ERROR;
- }
- }
-
- return ngx_http_next_body_filter(r, in);
- }
-
- /* add the incoming chain to the chain ctx->in */
-
- if (in) {
- if (ngx_chain_add_copy(r->pool, &ctx->in, in) != NGX_OK) {
- return NGX_ERROR;
- }
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http sub filter \"%V\"", &r->uri);
-
- while (ctx->in || ctx->buf) {
-
- if (ctx->buf == NULL) {
- ctx->buf = ctx->in->buf;
- ctx->in = ctx->in->next;
- ctx->pos = ctx->buf->pos;
- }
-
- if (ctx->state == sub_start_state) {
- ctx->copy_start = ctx->pos;
- ctx->copy_end = ctx->pos;
- }
-
- b = NULL;
-
- while (ctx->pos < ctx->buf->last) {
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "saved: \"%V\" state: %d", &ctx->saved, ctx->state);
-
- rc = ngx_http_sub_parse(r, ctx);
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "parse: %d, looked: \"%V\" %p-%p",
- rc, &ctx->looked, ctx->copy_start, ctx->copy_end);
-
- if (rc == NGX_ERROR) {
- return rc;
- }
-
- if (ctx->saved.len) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "saved: \"%V\"", &ctx->saved);
-
- cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->pos = ngx_pnalloc(r->pool, ctx->saved.len);
- if (b->pos == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(b->pos, ctx->saved.data, ctx->saved.len);
- b->last = b->pos + ctx->saved.len;
- b->memory = 1;
-
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- ctx->saved.len = 0;
- }
-
- if (ctx->copy_start != ctx->copy_end) {
-
- cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memcpy(b, ctx->buf, sizeof(ngx_buf_t));
-
- b->pos = ctx->copy_start;
- b->last = ctx->copy_end;
- b->shadow = NULL;
- b->last_buf = 0;
- b->recycled = 0;
-
- if (b->in_file) {
- b->file_last = b->file_pos + (b->last - ctx->buf->pos);
- b->file_pos += b->pos - ctx->buf->pos;
- }
-
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
- }
-
- if (ctx->state == sub_start_state) {
- ctx->copy_start = ctx->pos;
- ctx->copy_end = ctx->pos;
-
- } else {
- ctx->copy_start = NULL;
- ctx->copy_end = NULL;
- }
-
- if (ctx->looked.len > (size_t) (ctx->pos - ctx->buf->pos)) {
- ctx->saved.len = ctx->looked.len - (ctx->pos - ctx->buf->pos);
- ngx_memcpy(ctx->saved.data, ctx->looked.data, ctx->saved.len);
- }
-
- if (rc == NGX_AGAIN) {
- continue;
- }
-
-
- /* rc == NGX_OK */
-
- cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module);
-
- if (ctx->sub.data == NULL) {
-
- if (ngx_http_complex_value(r, &slcf->value, &ctx->sub)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
- }
-
- if (ctx->sub.len) {
- b->memory = 1;
- b->pos = ctx->sub.data;
- b->last = ctx->sub.data + ctx->sub.len;
-
- } else {
- b->sync = 1;
- }
-
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- ctx->once = slcf->once;
-
- continue;
- }
-
- if (ctx->buf->last_buf && ctx->looked.len) {
- cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->pos = ctx->looked.data;
- b->last = b->pos + ctx->looked.len;
- b->memory = 1;
-
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
-
- ctx->looked.len = 0;
- }
-
- if (ctx->buf->last_buf || ctx->buf->flush
- || ngx_buf_in_memory(ctx->buf))
- {
- if (b == NULL) {
- cl = ngx_chain_get_free_buf(r->pool, &ctx->free);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->sync = 1;
-
- *ctx->last_out = cl;
- ctx->last_out = &cl->next;
- }
-
- b->last_buf = ctx->buf->last_buf;
- b->flush = ctx->buf->flush;
- b->shadow = ctx->buf;
-
- b->recycled = ctx->buf->recycled;
- }
-
- ctx->buf = NULL;
-
- ctx->saved.len = ctx->looked.len;
- ngx_memcpy(ctx->saved.data, ctx->looked.data, ctx->looked.len);
- }
-
- if (ctx->out == NULL && ctx->busy == NULL) {
- return NGX_OK;
- }
-
- return ngx_http_sub_output(r, ctx);
-}
-
-
-static ngx_int_t
-ngx_http_sub_output(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
-{
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t *cl;
-
-#if 1
- b = NULL;
- for (cl = ctx->out; cl; cl = cl->next) {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "sub out: %p %p", cl->buf, cl->buf->pos);
- if (cl->buf == b) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "the same buf was used in sub");
- ngx_debug_point();
- return NGX_ERROR;
- }
- b = cl->buf;
- }
-#endif
-
- rc = ngx_http_next_body_filter(r, ctx->out);
-
- if (ctx->busy == NULL) {
- ctx->busy = ctx->out;
-
- } else {
- for (cl = ctx->busy; cl->next; cl = cl->next) { /* void */ }
- cl->next = ctx->out;
- }
-
- ctx->out = NULL;
- ctx->last_out = &ctx->out;
-
- while (ctx->busy) {
-
- cl = ctx->busy;
- b = cl->buf;
-
- if (ngx_buf_size(b) != 0) {
- break;
- }
-
- if (b->shadow) {
- b->shadow->pos = b->shadow->last;
- }
-
- ctx->busy = cl->next;
-
- if (ngx_buf_in_memory(b) || b->in_file) {
- /* add data bufs only to the free buf chain */
-
- cl->next = ctx->free;
- ctx->free = cl;
- }
- }
-
- if (ctx->in || ctx->buf) {
- r->buffered |= NGX_HTTP_SUB_BUFFERED;
-
- } else {
- r->buffered &= ~NGX_HTTP_SUB_BUFFERED;
- }
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx)
-{
- u_char *p, *last, *copy_end, ch, match;
- size_t looked, i;
- ngx_http_sub_state_e state;
-
- if (ctx->once) {
- ctx->copy_start = ctx->pos;
- ctx->copy_end = ctx->buf->last;
- ctx->pos = ctx->buf->last;
- ctx->looked.len = 0;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "once");
-
- return NGX_AGAIN;
- }
-
- state = ctx->state;
- looked = ctx->looked.len;
- last = ctx->buf->last;
- copy_end = ctx->copy_end;
-
- for (p = ctx->pos; p < last; p++) {
-
- ch = *p;
- ch = ngx_tolower(ch);
-
- if (state == sub_start_state) {
-
- /* the tight loop */
-
- match = ctx->match.data[0];
-
- for ( ;; ) {
- if (ch == match) {
- copy_end = p;
- ctx->looked.data[0] = *p;
- looked = 1;
- state = sub_match_state;
-
- goto match_started;
- }
-
- if (++p == last) {
- break;
- }
-
- ch = *p;
- ch = ngx_tolower(ch);
- }
-
- ctx->state = state;
- ctx->pos = p;
- ctx->looked.len = looked;
- ctx->copy_end = p;
-
- if (ctx->copy_start == NULL) {
- ctx->copy_start = ctx->buf->pos;
- }
-
- return NGX_AGAIN;
-
- match_started:
-
- continue;
- }
-
- /* state == sub_match_state */
-
- if (ch == ctx->match.data[looked]) {
- ctx->looked.data[looked] = *p;
- looked++;
-
- if (looked == ctx->match.len) {
-
- ctx->state = sub_start_state;
- ctx->pos = p + 1;
- ctx->looked.len = 0;
- ctx->saved.len = 0;
- ctx->copy_end = copy_end;
-
- if (ctx->copy_start == NULL && copy_end) {
- ctx->copy_start = ctx->buf->pos;
- }
-
- return NGX_OK;
- }
-
- } else {
- /*
- * check if there is another partial match in previously
- * matched substring to catch cases like "aab" in "aaab"
- */
-
- ctx->looked.data[looked] = *p;
- looked++;
-
- for (i = 1; i < looked; i++) {
- if (ngx_strncasecmp(ctx->looked.data + i,
- ctx->match.data, looked - i)
- == 0)
- {
- break;
- }
- }
-
- if (i < looked) {
- if (ctx->saved.len > i) {
- ctx->saved.len = i;
- }
-
- if ((size_t) (p + 1 - ctx->buf->pos) >= looked - i) {
- copy_end = p + 1 - (looked - i);
- }
-
- ngx_memmove(ctx->looked.data, ctx->looked.data + i, looked - i);
- looked = looked - i;
-
- } else {
- copy_end = p;
- looked = 0;
- state = sub_start_state;
- }
-
- if (ctx->saved.len) {
- p++;
- goto out;
- }
- }
- }
-
- ctx->saved.len = 0;
-
-out:
-
- ctx->state = state;
- ctx->pos = p;
- ctx->looked.len = looked;
-
- ctx->copy_end = (state == sub_start_state) ? p : copy_end;
-
- if (ctx->copy_start == NULL && ctx->copy_end) {
- ctx->copy_start = ctx->buf->pos;
- }
-
- return NGX_AGAIN;
-}
-
-
-static char *
-ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_sub_loc_conf_t *slcf = conf;
-
- ngx_str_t *value;
- ngx_http_compile_complex_value_t ccv;
-
- if (slcf->match.data) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- ngx_strlow(value[1].data, value[1].data, value[1].len);
-
- slcf->match = value[1];
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[2];
- ccv.complex_value = &slcf->value;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static void *
-ngx_http_sub_create_conf(ngx_conf_t *cf)
-{
- ngx_http_sub_loc_conf_t *slcf;
-
- slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_sub_loc_conf_t));
- if (slcf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->match = { 0, NULL };
- * conf->types = { NULL };
- * conf->types_keys = NULL;
- */
-
- slcf->once = NGX_CONF_UNSET;
- slcf->last_modified = NGX_CONF_UNSET;
-
- return slcf;
-}
-
-
-static char *
-ngx_http_sub_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_sub_loc_conf_t *prev = parent;
- ngx_http_sub_loc_conf_t *conf = child;
-
- ngx_conf_merge_value(conf->once, prev->once, 1);
- ngx_conf_merge_str_value(conf->match, prev->match, "");
- ngx_conf_merge_value(conf->last_modified, prev->last_modified, 0);
-
- if (conf->value.value.data == NULL) {
- conf->value = prev->value;
- }
-
- if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
- &prev->types_keys, &prev->types,
- ngx_http_html_default_types)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_sub_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_sub_header_filter;
-
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_sub_body_filter;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c
deleted file mode 100644
index 041883fec82..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c
+++ /dev/null
@@ -1,279 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- /* the round robin data must be first */
- ngx_http_upstream_rr_peer_data_t rrp;
-
- ngx_uint_t hash;
-
- u_char addrlen;
- u_char *addr;
-
- u_char tries;
-
- ngx_event_get_peer_pt get_rr_peer;
-} ngx_http_upstream_ip_hash_peer_data_t;
-
-
-static ngx_int_t ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
- ngx_http_upstream_srv_conf_t *us);
-static ngx_int_t ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc,
- void *data);
-static char *ngx_http_upstream_ip_hash(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_command_t ngx_http_upstream_ip_hash_commands[] = {
-
- { ngx_string("ip_hash"),
- NGX_HTTP_UPS_CONF|NGX_CONF_NOARGS,
- ngx_http_upstream_ip_hash,
- 0,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_upstream_ip_hash_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_upstream_ip_hash_module = {
- NGX_MODULE_V1,
- &ngx_http_upstream_ip_hash_module_ctx, /* module context */
- ngx_http_upstream_ip_hash_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static u_char ngx_http_upstream_ip_hash_pseudo_addr[3];
-
-
-static ngx_int_t
-ngx_http_upstream_init_ip_hash(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
-{
- if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
- return NGX_ERROR;
- }
-
- us->peer.init = ngx_http_upstream_init_ip_hash_peer;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_init_ip_hash_peer(ngx_http_request_t *r,
- ngx_http_upstream_srv_conf_t *us)
-{
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
- ngx_http_upstream_ip_hash_peer_data_t *iphp;
-
- iphp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_ip_hash_peer_data_t));
- if (iphp == NULL) {
- return NGX_ERROR;
- }
-
- r->upstream->peer.data = &iphp->rrp;
-
- if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) {
- return NGX_ERROR;
- }
-
- r->upstream->peer.get = ngx_http_upstream_get_ip_hash_peer;
-
- switch (r->connection->sockaddr->sa_family) {
-
- case AF_INET:
- sin = (struct sockaddr_in *) r->connection->sockaddr;
- iphp->addr = (u_char *) &sin->sin_addr.s_addr;
- iphp->addrlen = 3;
- break;
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
- iphp->addr = (u_char *) &sin6->sin6_addr.s6_addr;
- iphp->addrlen = 16;
- break;
-#endif
-
- default:
- iphp->addr = ngx_http_upstream_ip_hash_pseudo_addr;
- iphp->addrlen = 3;
- }
-
- iphp->hash = 89;
- iphp->tries = 0;
- iphp->get_rr_peer = ngx_http_upstream_get_round_robin_peer;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
-{
- ngx_http_upstream_ip_hash_peer_data_t *iphp = data;
-
- time_t now;
- ngx_int_t w;
- uintptr_t m;
- ngx_uint_t i, n, p, hash;
- ngx_http_upstream_rr_peer_t *peer;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "get ip hash peer, try: %ui", pc->tries);
-
- /* TODO: cached */
-
- if (iphp->tries > 20 || iphp->rrp.peers->single) {
- return iphp->get_rr_peer(pc, &iphp->rrp);
- }
-
- now = ngx_time();
-
- pc->cached = 0;
- pc->connection = NULL;
-
- hash = iphp->hash;
-
- for ( ;; ) {
-
- for (i = 0; i < (ngx_uint_t) iphp->addrlen; i++) {
- hash = (hash * 113 + iphp->addr[i]) % 6271;
- }
-
- if (!iphp->rrp.peers->weighted) {
- p = hash % iphp->rrp.peers->number;
-
- } else {
- w = hash % iphp->rrp.peers->total_weight;
-
- for (i = 0; i < iphp->rrp.peers->number; i++) {
- w -= iphp->rrp.peers->peer[i].weight;
- if (w < 0) {
- break;
- }
- }
-
- p = i;
- }
-
- n = p / (8 * sizeof(uintptr_t));
- m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
-
- if (iphp->rrp.tried[n] & m) {
- goto next;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "get ip hash peer, hash: %ui %04XA", p, m);
-
- peer = &iphp->rrp.peers->peer[p];
-
- /* ngx_lock_mutex(iphp->rrp.peers->mutex); */
-
- if (peer->down) {
- goto next_try;
- }
-
- if (peer->max_fails
- && peer->fails >= peer->max_fails
- && now - peer->checked <= peer->fail_timeout)
- {
- goto next_try;
- }
-
- break;
-
- next_try:
-
- iphp->rrp.tried[n] |= m;
-
- /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
-
- pc->tries--;
-
- next:
-
- if (++iphp->tries >= 20) {
- return iphp->get_rr_peer(pc, &iphp->rrp);
- }
- }
-
- iphp->rrp.current = p;
-
- pc->sockaddr = peer->sockaddr;
- pc->socklen = peer->socklen;
- pc->name = &peer->name;
-
- if (now - peer->checked > peer->fail_timeout) {
- peer->checked = now;
- }
-
- /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */
-
- iphp->rrp.tried[n] |= m;
- iphp->hash = hash;
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_http_upstream_ip_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_upstream_srv_conf_t *uscf;
-
- uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
-
- if (uscf->peer.init_upstream) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "load balancing method redefined");
- }
-
- uscf->peer.init_upstream = ngx_http_upstream_init_ip_hash;
-
- uscf->flags = NGX_HTTP_UPSTREAM_CREATE
- |NGX_HTTP_UPSTREAM_WEIGHT
- |NGX_HTTP_UPSTREAM_MAX_FAILS
- |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
- |NGX_HTTP_UPSTREAM_DOWN;
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c
deleted file mode 100644
index d07ed9edaf2..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c
+++ /dev/null
@@ -1,536 +0,0 @@
-
-/*
- * Copyright (C) Maxim Dounin
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_uint_t max_cached;
-
- ngx_queue_t cache;
- ngx_queue_t free;
-
- ngx_http_upstream_init_pt original_init_upstream;
- ngx_http_upstream_init_peer_pt original_init_peer;
-
-} ngx_http_upstream_keepalive_srv_conf_t;
-
-
-typedef struct {
- ngx_http_upstream_keepalive_srv_conf_t *conf;
-
- ngx_http_upstream_t *upstream;
-
- void *data;
-
- ngx_event_get_peer_pt original_get_peer;
- ngx_event_free_peer_pt original_free_peer;
-
-#if (NGX_HTTP_SSL)
- ngx_event_set_peer_session_pt original_set_session;
- ngx_event_save_peer_session_pt original_save_session;
-#endif
-
-} ngx_http_upstream_keepalive_peer_data_t;
-
-
-typedef struct {
- ngx_http_upstream_keepalive_srv_conf_t *conf;
-
- ngx_queue_t queue;
- ngx_connection_t *connection;
-
- socklen_t socklen;
- u_char sockaddr[NGX_SOCKADDRLEN];
-
-} ngx_http_upstream_keepalive_cache_t;
-
-
-static ngx_int_t ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r,
- ngx_http_upstream_srv_conf_t *us);
-static ngx_int_t ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc,
- void *data);
-static void ngx_http_upstream_free_keepalive_peer(ngx_peer_connection_t *pc,
- void *data, ngx_uint_t state);
-
-static void ngx_http_upstream_keepalive_dummy_handler(ngx_event_t *ev);
-static void ngx_http_upstream_keepalive_close_handler(ngx_event_t *ev);
-static void ngx_http_upstream_keepalive_close(ngx_connection_t *c);
-
-
-#if (NGX_HTTP_SSL)
-static ngx_int_t ngx_http_upstream_keepalive_set_session(
- ngx_peer_connection_t *pc, void *data);
-static void ngx_http_upstream_keepalive_save_session(ngx_peer_connection_t *pc,
- void *data);
-#endif
-
-static void *ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf);
-static char *ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_command_t ngx_http_upstream_keepalive_commands[] = {
-
- { ngx_string("keepalive"),
- NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
- ngx_http_upstream_keepalive,
- NGX_HTTP_SRV_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_upstream_keepalive_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- ngx_http_upstream_keepalive_create_conf, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_upstream_keepalive_module = {
- NGX_MODULE_V1,
- &ngx_http_upstream_keepalive_module_ctx, /* module context */
- ngx_http_upstream_keepalive_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_upstream_init_keepalive(ngx_conf_t *cf,
- ngx_http_upstream_srv_conf_t *us)
-{
- ngx_uint_t i;
- ngx_http_upstream_keepalive_srv_conf_t *kcf;
- ngx_http_upstream_keepalive_cache_t *cached;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0,
- "init keepalive");
-
- kcf = ngx_http_conf_upstream_srv_conf(us,
- ngx_http_upstream_keepalive_module);
-
- if (kcf->original_init_upstream(cf, us) != NGX_OK) {
- return NGX_ERROR;
- }
-
- kcf->original_init_peer = us->peer.init;
-
- us->peer.init = ngx_http_upstream_init_keepalive_peer;
-
- /* allocate cache items and add to free queue */
-
- cached = ngx_pcalloc(cf->pool,
- sizeof(ngx_http_upstream_keepalive_cache_t) * kcf->max_cached);
- if (cached == NULL) {
- return NGX_ERROR;
- }
-
- ngx_queue_init(&kcf->cache);
- ngx_queue_init(&kcf->free);
-
- for (i = 0; i < kcf->max_cached; i++) {
- ngx_queue_insert_head(&kcf->free, &cached[i].queue);
- cached[i].conf = kcf;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r,
- ngx_http_upstream_srv_conf_t *us)
-{
- ngx_http_upstream_keepalive_peer_data_t *kp;
- ngx_http_upstream_keepalive_srv_conf_t *kcf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "init keepalive peer");
-
- kcf = ngx_http_conf_upstream_srv_conf(us,
- ngx_http_upstream_keepalive_module);
-
- kp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_keepalive_peer_data_t));
- if (kp == NULL) {
- return NGX_ERROR;
- }
-
- if (kcf->original_init_peer(r, us) != NGX_OK) {
- return NGX_ERROR;
- }
-
- kp->conf = kcf;
- kp->upstream = r->upstream;
- kp->data = r->upstream->peer.data;
- kp->original_get_peer = r->upstream->peer.get;
- kp->original_free_peer = r->upstream->peer.free;
-
- r->upstream->peer.data = kp;
- r->upstream->peer.get = ngx_http_upstream_get_keepalive_peer;
- r->upstream->peer.free = ngx_http_upstream_free_keepalive_peer;
-
-#if (NGX_HTTP_SSL)
- kp->original_set_session = r->upstream->peer.set_session;
- kp->original_save_session = r->upstream->peer.save_session;
- r->upstream->peer.set_session = ngx_http_upstream_keepalive_set_session;
- r->upstream->peer.save_session = ngx_http_upstream_keepalive_save_session;
-#endif
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc, void *data)
-{
- ngx_http_upstream_keepalive_peer_data_t *kp = data;
- ngx_http_upstream_keepalive_cache_t *item;
-
- ngx_int_t rc;
- ngx_queue_t *q, *cache;
- ngx_connection_t *c;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "get keepalive peer");
-
- /* ask balancer */
-
- rc = kp->original_get_peer(pc, kp->data);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- /* search cache for suitable connection */
-
- cache = &kp->conf->cache;
-
- for (q = ngx_queue_head(cache);
- q != ngx_queue_sentinel(cache);
- q = ngx_queue_next(q))
- {
- item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
- c = item->connection;
-
- if (ngx_memn2cmp((u_char *) &item->sockaddr, (u_char *) pc->sockaddr,
- item->socklen, pc->socklen)
- == 0)
- {
- ngx_queue_remove(q);
- ngx_queue_insert_head(&kp->conf->free, q);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "get keepalive peer: using connection %p", c);
-
- c->idle = 0;
- c->log = pc->log;
- c->read->log = pc->log;
- c->write->log = pc->log;
- c->pool->log = pc->log;
-
- pc->connection = c;
- pc->cached = 1;
-
- return NGX_DONE;
- }
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_upstream_free_keepalive_peer(ngx_peer_connection_t *pc, void *data,
- ngx_uint_t state)
-{
- ngx_http_upstream_keepalive_peer_data_t *kp = data;
- ngx_http_upstream_keepalive_cache_t *item;
-
- ngx_queue_t *q;
- ngx_connection_t *c;
- ngx_http_upstream_t *u;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "free keepalive peer");
-
- /* cache valid connections */
-
- u = kp->upstream;
- c = pc->connection;
-
- if (state & NGX_PEER_FAILED
- || c == NULL
- || c->read->eof
- || c->read->error
- || c->read->timedout
- || c->write->error
- || c->write->timedout)
- {
- goto invalid;
- }
-
- if (!u->keepalive) {
- goto invalid;
- }
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- goto invalid;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "free keepalive peer: saving connection %p", c);
-
- if (ngx_queue_empty(&kp->conf->free)) {
-
- q = ngx_queue_last(&kp->conf->cache);
- ngx_queue_remove(q);
-
- item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
-
- ngx_http_upstream_keepalive_close(item->connection);
-
- } else {
- q = ngx_queue_head(&kp->conf->free);
- ngx_queue_remove(q);
-
- item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
- }
-
- item->connection = c;
- ngx_queue_insert_head(&kp->conf->cache, q);
-
- pc->connection = NULL;
-
- if (c->read->timer_set) {
- ngx_del_timer(c->read);
- }
- if (c->write->timer_set) {
- ngx_del_timer(c->write);
- }
-
- c->write->handler = ngx_http_upstream_keepalive_dummy_handler;
- c->read->handler = ngx_http_upstream_keepalive_close_handler;
-
- c->data = item;
- c->idle = 1;
- c->log = ngx_cycle->log;
- c->read->log = ngx_cycle->log;
- c->write->log = ngx_cycle->log;
- c->pool->log = ngx_cycle->log;
-
- item->socklen = pc->socklen;
- ngx_memcpy(&item->sockaddr, pc->sockaddr, pc->socklen);
-
- if (c->read->ready) {
- ngx_http_upstream_keepalive_close_handler(c->read);
- }
-
-invalid:
-
- kp->original_free_peer(pc, kp->data, state);
-}
-
-
-static void
-ngx_http_upstream_keepalive_dummy_handler(ngx_event_t *ev)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
- "keepalive dummy handler");
-}
-
-
-static void
-ngx_http_upstream_keepalive_close_handler(ngx_event_t *ev)
-{
- ngx_http_upstream_keepalive_srv_conf_t *conf;
- ngx_http_upstream_keepalive_cache_t *item;
-
- int n;
- char buf[1];
- ngx_connection_t *c;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
- "keepalive close handler");
-
- c = ev->data;
-
- if (c->close) {
- goto close;
- }
-
- n = recv(c->fd, buf, 1, MSG_PEEK);
-
- if (n == -1 && ngx_socket_errno == NGX_EAGAIN) {
- /* stale event */
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- goto close;
- }
-
- return;
- }
-
-close:
-
- item = c->data;
- conf = item->conf;
-
- ngx_http_upstream_keepalive_close(c);
-
- ngx_queue_remove(&item->queue);
- ngx_queue_insert_head(&conf->free, &item->queue);
-}
-
-
-static void
-ngx_http_upstream_keepalive_close(ngx_connection_t *c)
-{
-
-#if (NGX_HTTP_SSL)
-
- if (c->ssl) {
- c->ssl->no_wait_shutdown = 1;
- c->ssl->no_send_shutdown = 1;
-
- if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
- c->ssl->handler = ngx_http_upstream_keepalive_close;
- return;
- }
- }
-
-#endif
-
- ngx_destroy_pool(c->pool);
- ngx_close_connection(c);
-}
-
-
-#if (NGX_HTTP_SSL)
-
-static ngx_int_t
-ngx_http_upstream_keepalive_set_session(ngx_peer_connection_t *pc, void *data)
-{
- ngx_http_upstream_keepalive_peer_data_t *kp = data;
-
- return kp->original_set_session(pc, kp->data);
-}
-
-
-static void
-ngx_http_upstream_keepalive_save_session(ngx_peer_connection_t *pc, void *data)
-{
- ngx_http_upstream_keepalive_peer_data_t *kp = data;
-
- kp->original_save_session(pc, kp->data);
- return;
-}
-
-#endif
-
-
-static void *
-ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf)
-{
- ngx_http_upstream_keepalive_srv_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool,
- sizeof(ngx_http_upstream_keepalive_srv_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->original_init_upstream = NULL;
- * conf->original_init_peer = NULL;
- */
-
- conf->max_cached = 1;
-
- return conf;
-}
-
-
-static char *
-ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_upstream_srv_conf_t *uscf;
- ngx_http_upstream_keepalive_srv_conf_t *kcf = conf;
-
- ngx_int_t n;
- ngx_str_t *value;
- ngx_uint_t i;
-
- uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
-
- if (kcf->original_init_upstream) {
- return "is duplicate";
- }
-
- kcf->original_init_upstream = uscf->peer.init_upstream
- ? uscf->peer.init_upstream
- : ngx_http_upstream_init_round_robin;
-
- uscf->peer.init_upstream = ngx_http_upstream_init_keepalive;
-
- /* read options */
-
- value = cf->args->elts;
-
- n = ngx_atoi(value[1].data, value[1].len);
-
- if (n == NGX_ERROR || n == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\" in \"%V\" directive",
- &value[1], &cmd->name);
- return NGX_CONF_ERROR;
- }
-
- kcf->max_cached = n;
-
- for (i = 2; i < cf->args->nelts; i++) {
-
- if (ngx_strcmp(value[i].data, "single") == 0) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "the \"single\" parameter is deprecated");
- continue;
- }
-
- goto invalid;
- }
-
- return NGX_CONF_OK;
-
-invalid:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[i]);
-
- return NGX_CONF_ERROR;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c
deleted file mode 100644
index dbef95d4164..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c
+++ /dev/null
@@ -1,408 +0,0 @@
-
-/*
- * Copyright (C) Maxim Dounin
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_uint_t *conns;
-} ngx_http_upstream_least_conn_conf_t;
-
-
-typedef struct {
- /* the round robin data must be first */
- ngx_http_upstream_rr_peer_data_t rrp;
-
- ngx_uint_t *conns;
-
- ngx_event_get_peer_pt get_rr_peer;
- ngx_event_free_peer_pt free_rr_peer;
-} ngx_http_upstream_lc_peer_data_t;
-
-
-static ngx_int_t ngx_http_upstream_init_least_conn_peer(ngx_http_request_t *r,
- ngx_http_upstream_srv_conf_t *us);
-static ngx_int_t ngx_http_upstream_get_least_conn_peer(
- ngx_peer_connection_t *pc, void *data);
-static void ngx_http_upstream_free_least_conn_peer(ngx_peer_connection_t *pc,
- void *data, ngx_uint_t state);
-static void *ngx_http_upstream_least_conn_create_conf(ngx_conf_t *cf);
-static char *ngx_http_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_command_t ngx_http_upstream_least_conn_commands[] = {
-
- { ngx_string("least_conn"),
- NGX_HTTP_UPS_CONF|NGX_CONF_NOARGS,
- ngx_http_upstream_least_conn,
- 0,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_upstream_least_conn_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- ngx_http_upstream_least_conn_create_conf, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_upstream_least_conn_module = {
- NGX_MODULE_V1,
- &ngx_http_upstream_least_conn_module_ctx, /* module context */
- ngx_http_upstream_least_conn_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_int_t
-ngx_http_upstream_init_least_conn(ngx_conf_t *cf,
- ngx_http_upstream_srv_conf_t *us)
-{
- ngx_uint_t n;
- ngx_http_upstream_rr_peers_t *peers;
- ngx_http_upstream_least_conn_conf_t *lcf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0,
- "init least conn");
-
- if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
- return NGX_ERROR;
- }
-
- peers = us->peer.data;
-
- n = peers->number;
-
- if (peers->next) {
- n += peers->next->number;
- }
-
- lcf = ngx_http_conf_upstream_srv_conf(us,
- ngx_http_upstream_least_conn_module);
-
- lcf->conns = ngx_pcalloc(cf->pool, sizeof(ngx_uint_t) * n);
- if (lcf->conns == NULL) {
- return NGX_ERROR;
- }
-
- us->peer.init = ngx_http_upstream_init_least_conn_peer;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_init_least_conn_peer(ngx_http_request_t *r,
- ngx_http_upstream_srv_conf_t *us)
-{
- ngx_http_upstream_lc_peer_data_t *lcp;
- ngx_http_upstream_least_conn_conf_t *lcf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "init least conn peer");
-
- lcf = ngx_http_conf_upstream_srv_conf(us,
- ngx_http_upstream_least_conn_module);
-
- lcp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_lc_peer_data_t));
- if (lcp == NULL) {
- return NGX_ERROR;
- }
-
- lcp->conns = lcf->conns;
-
- r->upstream->peer.data = &lcp->rrp;
-
- if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) {
- return NGX_ERROR;
- }
-
- r->upstream->peer.get = ngx_http_upstream_get_least_conn_peer;
- r->upstream->peer.free = ngx_http_upstream_free_least_conn_peer;
-
- lcp->get_rr_peer = ngx_http_upstream_get_round_robin_peer;
- lcp->free_rr_peer = ngx_http_upstream_free_round_robin_peer;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data)
-{
- ngx_http_upstream_lc_peer_data_t *lcp = data;
-
- time_t now;
- uintptr_t m;
- ngx_int_t rc, total;
- ngx_uint_t i, n, p, many;
- ngx_http_upstream_rr_peer_t *peer, *best;
- ngx_http_upstream_rr_peers_t *peers;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "get least conn peer, try: %ui", pc->tries);
-
- if (lcp->rrp.peers->single) {
- return lcp->get_rr_peer(pc, &lcp->rrp);
- }
-
- pc->cached = 0;
- pc->connection = NULL;
-
- now = ngx_time();
-
- peers = lcp->rrp.peers;
-
- best = NULL;
- total = 0;
-
-#if (NGX_SUPPRESS_WARN)
- many = 0;
- p = 0;
-#endif
-
- for (i = 0; i < peers->number; i++) {
-
- n = i / (8 * sizeof(uintptr_t));
- m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
-
- if (lcp->rrp.tried[n] & m) {
- continue;
- }
-
- peer = &peers->peer[i];
-
- if (peer->down) {
- continue;
- }
-
- if (peer->max_fails
- && peer->fails >= peer->max_fails
- && now - peer->checked <= peer->fail_timeout)
- {
- continue;
- }
-
- /*
- * select peer with least number of connections; if there are
- * multiple peers with the same number of connections, select
- * based on round-robin
- */
-
- if (best == NULL
- || lcp->conns[i] * best->weight < lcp->conns[p] * peer->weight)
- {
- best = peer;
- many = 0;
- p = i;
-
- } else if (lcp->conns[i] * best->weight
- == lcp->conns[p] * peer->weight)
- {
- many = 1;
- }
- }
-
- if (best == NULL) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "get least conn peer, no peer found");
-
- goto failed;
- }
-
- if (many) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "get least conn peer, many");
-
- for (i = p; i < peers->number; i++) {
-
- n = i / (8 * sizeof(uintptr_t));
- m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
-
- if (lcp->rrp.tried[n] & m) {
- continue;
- }
-
- peer = &peers->peer[i];
-
- if (peer->down) {
- continue;
- }
-
- if (lcp->conns[i] * best->weight != lcp->conns[p] * peer->weight) {
- continue;
- }
-
- if (peer->max_fails
- && peer->fails >= peer->max_fails
- && now - peer->checked <= peer->fail_timeout)
- {
- continue;
- }
-
- peer->current_weight += peer->effective_weight;
- total += peer->effective_weight;
-
- if (peer->effective_weight < peer->weight) {
- peer->effective_weight++;
- }
-
- if (peer->current_weight > best->current_weight) {
- best = peer;
- p = i;
- }
- }
- }
-
- best->current_weight -= total;
-
- if (now - best->checked > best->fail_timeout) {
- best->checked = now;
- }
-
- pc->sockaddr = best->sockaddr;
- pc->socklen = best->socklen;
- pc->name = &best->name;
-
- lcp->rrp.current = p;
-
- n = p / (8 * sizeof(uintptr_t));
- m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
-
- lcp->rrp.tried[n] |= m;
- lcp->conns[p]++;
-
- if (pc->tries == 1 && peers->next) {
- pc->tries += peers->next->number;
- }
-
- return NGX_OK;
-
-failed:
-
- if (peers->next) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "get least conn peer, backup servers");
-
- lcp->conns += peers->number;
-
- lcp->rrp.peers = peers->next;
- pc->tries = lcp->rrp.peers->number;
-
- n = (lcp->rrp.peers->number + (8 * sizeof(uintptr_t) - 1))
- / (8 * sizeof(uintptr_t));
-
- for (i = 0; i < n; i++) {
- lcp->rrp.tried[i] = 0;
- }
-
- rc = ngx_http_upstream_get_least_conn_peer(pc, lcp);
-
- if (rc != NGX_BUSY) {
- return rc;
- }
- }
-
- /* all peers failed, mark them as live for quick recovery */
-
- for (i = 0; i < peers->number; i++) {
- peers->peer[i].fails = 0;
- }
-
- pc->name = peers->name;
-
- return NGX_BUSY;
-}
-
-
-static void
-ngx_http_upstream_free_least_conn_peer(ngx_peer_connection_t *pc,
- void *data, ngx_uint_t state)
-{
- ngx_http_upstream_lc_peer_data_t *lcp = data;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "free least conn peer %ui %ui", pc->tries, state);
-
- if (lcp->rrp.peers->single) {
- lcp->free_rr_peer(pc, &lcp->rrp, state);
- return;
- }
-
- lcp->conns[lcp->rrp.current]--;
-
- lcp->free_rr_peer(pc, &lcp->rrp, state);
-}
-
-
-static void *
-ngx_http_upstream_least_conn_create_conf(ngx_conf_t *cf)
-{
- ngx_http_upstream_least_conn_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool,
- sizeof(ngx_http_upstream_least_conn_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->conns = NULL;
- */
-
- return conf;
-}
-
-
-static char *
-ngx_http_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_upstream_srv_conf_t *uscf;
-
- uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
-
- if (uscf->peer.init_upstream) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "load balancing method redefined");
- }
-
- uscf->peer.init_upstream = ngx_http_upstream_init_least_conn;
-
- uscf->flags = NGX_HTTP_UPSTREAM_CREATE
- |NGX_HTTP_UPSTREAM_WEIGHT
- |NGX_HTTP_UPSTREAM_MAX_FAILS
- |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
- |NGX_HTTP_UPSTREAM_DOWN
- |NGX_HTTP_UPSTREAM_BACKUP;
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_userid_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_userid_filter_module.c
deleted file mode 100644
index 1487c091eee..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_userid_filter_module.c
+++ /dev/null
@@ -1,842 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-#define NGX_HTTP_USERID_OFF 0
-#define NGX_HTTP_USERID_LOG 1
-#define NGX_HTTP_USERID_V1 2
-#define NGX_HTTP_USERID_ON 3
-
-/* 31 Dec 2037 23:55:55 GMT */
-#define NGX_HTTP_USERID_MAX_EXPIRES 2145916555
-
-
-typedef struct {
- ngx_uint_t enable;
-
- ngx_int_t service;
-
- ngx_str_t name;
- ngx_str_t domain;
- ngx_str_t path;
- ngx_str_t p3p;
-
- time_t expires;
-
- u_char mark;
-} ngx_http_userid_conf_t;
-
-
-typedef struct {
- uint32_t uid_got[4];
- uint32_t uid_set[4];
- ngx_str_t cookie;
- ngx_uint_t reset;
-} ngx_http_userid_ctx_t;
-
-
-static ngx_http_userid_ctx_t *ngx_http_userid_get_uid(ngx_http_request_t *r,
- ngx_http_userid_conf_t *conf);
-static ngx_int_t ngx_http_userid_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, ngx_str_t *name, uint32_t *uid);
-static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r,
- ngx_http_userid_ctx_t *ctx, ngx_http_userid_conf_t *conf);
-static ngx_int_t ngx_http_userid_create_uid(ngx_http_request_t *r,
- ngx_http_userid_ctx_t *ctx, ngx_http_userid_conf_t *conf);
-
-static ngx_int_t ngx_http_userid_add_variables(ngx_conf_t *cf);
-static ngx_int_t ngx_http_userid_init(ngx_conf_t *cf);
-static void *ngx_http_userid_create_conf(ngx_conf_t *cf);
-static char *ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static char *ngx_http_userid_domain(ngx_conf_t *cf, void *post, void *data);
-static char *ngx_http_userid_path(ngx_conf_t *cf, void *post, void *data);
-static char *ngx_http_userid_expires(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-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;
-
-
-static u_char expires[] = "; expires=Thu, 31-Dec-37 23:55:55 GMT";
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-
-
-static ngx_conf_enum_t ngx_http_userid_state[] = {
- { ngx_string("off"), NGX_HTTP_USERID_OFF },
- { ngx_string("log"), NGX_HTTP_USERID_LOG },
- { ngx_string("v1"), NGX_HTTP_USERID_V1 },
- { ngx_string("on"), NGX_HTTP_USERID_ON },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_conf_post_handler_pt ngx_http_userid_domain_p =
- ngx_http_userid_domain;
-static ngx_conf_post_handler_pt ngx_http_userid_path_p = ngx_http_userid_path;
-static ngx_conf_post_handler_pt ngx_http_userid_p3p_p = ngx_http_userid_p3p;
-
-
-static ngx_command_t ngx_http_userid_commands[] = {
-
- { ngx_string("userid"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_userid_conf_t, enable),
- ngx_http_userid_state },
-
- { ngx_string("userid_service"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_userid_conf_t, service),
- NULL },
-
- { ngx_string("userid_name"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_userid_conf_t, name),
- NULL },
-
- { ngx_string("userid_domain"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_userid_conf_t, domain),
- &ngx_http_userid_domain_p },
-
- { ngx_string("userid_path"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_userid_conf_t, path),
- &ngx_http_userid_path_p },
-
- { ngx_string("userid_expires"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_userid_expires,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("userid_p3p"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_userid_conf_t, p3p),
- &ngx_http_userid_p3p_p },
-
- { ngx_string("userid_mark"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_userid_mark,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_userid_filter_module_ctx = {
- ngx_http_userid_add_variables, /* preconfiguration */
- ngx_http_userid_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_userid_create_conf, /* create location configuration */
- ngx_http_userid_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_userid_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_userid_filter_module_ctx, /* module context */
- ngx_http_userid_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- ngx_http_userid_init_worker, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_str_t ngx_http_userid_got = ngx_string("uid_got");
-static ngx_str_t ngx_http_userid_set = ngx_string("uid_set");
-static ngx_str_t ngx_http_userid_reset = ngx_string("uid_reset");
-static ngx_uint_t ngx_http_userid_reset_index;
-
-
-static ngx_int_t
-ngx_http_userid_filter(ngx_http_request_t *r)
-{
- ngx_http_userid_ctx_t *ctx;
- ngx_http_userid_conf_t *conf;
-
- if (r != r->main) {
- return ngx_http_next_header_filter(r);
- }
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_userid_filter_module);
-
- if (conf->enable < NGX_HTTP_USERID_V1) {
- return ngx_http_next_header_filter(r);
- }
-
- ctx = ngx_http_userid_get_uid(r, conf);
-
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_http_userid_set_uid(r, ctx, conf) == NGX_OK) {
- return ngx_http_next_header_filter(r);
- }
-
- return NGX_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_userid_got_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_http_userid_ctx_t *ctx;
- ngx_http_userid_conf_t *conf;
-
- conf = ngx_http_get_module_loc_conf(r->main, ngx_http_userid_filter_module);
-
- if (conf->enable == NGX_HTTP_USERID_OFF) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- ctx = ngx_http_userid_get_uid(r->main, conf);
-
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- if (ctx->uid_got[3] != 0) {
- return ngx_http_userid_variable(r->main, v, &conf->name, ctx->uid_got);
- }
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_userid_set_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_http_userid_ctx_t *ctx;
- ngx_http_userid_conf_t *conf;
-
- conf = ngx_http_get_module_loc_conf(r->main, ngx_http_userid_filter_module);
-
- if (conf->enable < NGX_HTTP_USERID_V1) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- ctx = ngx_http_userid_get_uid(r->main, conf);
-
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_http_userid_create_uid(r->main, ctx, conf) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (ctx->uid_set[3] == 0) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- return ngx_http_userid_variable(r->main, v, &conf->name, ctx->uid_set);
-}
-
-
-static ngx_http_userid_ctx_t *
-ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf)
-{
- ngx_int_t n;
- ngx_str_t src, dst;
- ngx_table_elt_t **cookies;
- ngx_http_userid_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module);
-
- if (ctx) {
- return ctx;
- }
-
- if (ctx == NULL) {
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_userid_ctx_t));
- if (ctx == NULL) {
- return NULL;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_userid_filter_module);
- }
-
- n = ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &conf->name,
- &ctx->cookie);
- if (n == NGX_DECLINED) {
- return ctx;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "uid cookie: \"%V\"", &ctx->cookie);
-
- if (ctx->cookie.len < 22) {
- cookies = r->headers_in.cookies.elts;
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client sent too short userid cookie \"%V\"",
- &cookies[n]->value);
- return ctx;
- }
-
- src = ctx->cookie;
-
- /*
- * we have to limit the encoded string to 22 characters because
- * 1) cookie may be marked by "userid_mark",
- * 2) and there are already the millions cookies with a garbage
- * instead of the correct base64 trail "=="
- */
-
- src.len = 22;
-
- dst.data = (u_char *) ctx->uid_got;
-
- if (ngx_decode_base64(&dst, &src) == NGX_ERROR) {
- cookies = r->headers_in.cookies.elts;
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client sent invalid userid cookie \"%V\"",
- &cookies[n]->value);
- return ctx;
- }
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "uid: %08XD%08XD%08XD%08XD",
- ctx->uid_got[0], ctx->uid_got[1],
- ctx->uid_got[2], ctx->uid_got[3]);
-
- return ctx;
-}
-
-
-static ngx_int_t
-ngx_http_userid_set_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
- ngx_http_userid_conf_t *conf)
-{
- u_char *cookie, *p;
- size_t len;
- ngx_str_t src, dst;
- ngx_table_elt_t *set_cookie, *p3p;
-
- if (ngx_http_userid_create_uid(r, ctx, conf) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (ctx->uid_set[3] == 0) {
- return NGX_OK;
- }
-
- len = conf->name.len + 1 + ngx_base64_encoded_length(16) + conf->path.len;
-
- if (conf->expires) {
- len += sizeof(expires) - 1 + 2;
- }
-
- if (conf->domain.len) {
- len += conf->domain.len;
- }
-
- cookie = ngx_pnalloc(r->pool, len);
- if (cookie == NULL) {
- return NGX_ERROR;
- }
-
- p = ngx_copy(cookie, conf->name.data, conf->name.len);
- *p++ = '=';
-
- if (ctx->uid_got[3] == 0 || ctx->reset) {
- src.len = 16;
- src.data = (u_char *) ctx->uid_set;
- dst.data = p;
-
- ngx_encode_base64(&dst, &src);
-
- p += dst.len;
-
- if (conf->mark) {
- *(p - 2) = conf->mark;
- }
-
- } else {
- p = ngx_cpymem(p, ctx->cookie.data, 22);
- *p++ = conf->mark;
- *p++ = '=';
- }
-
- if (conf->expires == NGX_HTTP_USERID_MAX_EXPIRES) {
- p = ngx_cpymem(p, expires, sizeof(expires) - 1);
-
- } else if (conf->expires) {
- p = ngx_cpymem(p, expires, sizeof("; expires=") - 1);
- p = ngx_http_cookie_time(p, ngx_time() + conf->expires);
- }
-
- p = ngx_copy(p, conf->domain.data, conf->domain.len);
-
- p = ngx_copy(p, conf->path.data, conf->path.len);
-
- set_cookie = ngx_list_push(&r->headers_out.headers);
- if (set_cookie == NULL) {
- return NGX_ERROR;
- }
-
- set_cookie->hash = 1;
- ngx_str_set(&set_cookie->key, "Set-Cookie");
- set_cookie->value.len = p - cookie;
- set_cookie->value.data = cookie;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "uid cookie: \"%V\"", &set_cookie->value);
-
- if (conf->p3p.len == 0) {
- return NGX_OK;
- }
-
- p3p = ngx_list_push(&r->headers_out.headers);
- if (p3p == NULL) {
- return NGX_ERROR;
- }
-
- p3p->hash = 1;
- ngx_str_set(&p3p->key, "P3P");
- p3p->value = conf->p3p;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_userid_create_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
- ngx_http_userid_conf_t *conf)
-{
- ngx_connection_t *c;
- struct sockaddr_in *sin;
- ngx_http_variable_value_t *vv;
-#if (NGX_HAVE_INET6)
- u_char *p;
- struct sockaddr_in6 *sin6;
-#endif
-
- if (ctx->uid_set[3] != 0) {
- return NGX_OK;
- }
-
- if (ctx->uid_got[3] != 0) {
-
- vv = ngx_http_get_indexed_variable(r, ngx_http_userid_reset_index);
-
- if (vv->len == 0 || (vv->len == 1 && vv->data[0] == '0')) {
-
- if (conf->mark == '\0'
- || (ctx->cookie.len > 23
- && ctx->cookie.data[22] == conf->mark
- && ctx->cookie.data[23] == '='))
- {
- return NGX_OK;
- }
-
- ctx->uid_set[0] = ctx->uid_got[0];
- ctx->uid_set[1] = ctx->uid_got[1];
- ctx->uid_set[2] = ctx->uid_got[2];
- ctx->uid_set[3] = ctx->uid_got[3];
-
- return NGX_OK;
-
- } else {
- ctx->reset = 1;
-
- if (vv->len == 3 && ngx_strncmp(vv->data, "log", 3) == 0) {
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "userid cookie \"%V=%08XD%08XD%08XD%08XD\" was reset",
- &conf->name, ctx->uid_got[0], ctx->uid_got[1],
- ctx->uid_got[2], ctx->uid_got[3]);
- }
- }
- }
-
- /*
- * TODO: in the threaded mode the sequencers should be in TLS and their
- * ranges should be divided between threads
- */
-
- if (conf->enable == NGX_HTTP_USERID_V1) {
- if (conf->service == NGX_CONF_UNSET) {
- ctx->uid_set[0] = 0;
- } else {
- ctx->uid_set[0] = conf->service;
- }
- ctx->uid_set[1] = (uint32_t) ngx_time();
- ctx->uid_set[2] = start_value;
- ctx->uid_set[3] = sequencer_v1;
- sequencer_v1 += 0x100;
-
- } else {
- if (conf->service == NGX_CONF_UNSET) {
-
- c = r->connection;
-
- if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- switch (c->local_sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
-
- p = (u_char *) &ctx->uid_set[0];
-
- *p++ = sin6->sin6_addr.s6_addr[12];
- *p++ = sin6->sin6_addr.s6_addr[13];
- *p++ = sin6->sin6_addr.s6_addr[14];
- *p = sin6->sin6_addr.s6_addr[15];
-
- break;
-#endif
- default: /* AF_INET */
- sin = (struct sockaddr_in *) c->local_sockaddr;
- ctx->uid_set[0] = sin->sin_addr.s_addr;
- break;
- }
-
- } else {
- ctx->uid_set[0] = htonl(conf->service);
- }
-
- ctx->uid_set[1] = htonl((uint32_t) ngx_time());
- ctx->uid_set[2] = htonl(start_value);
- ctx->uid_set[3] = htonl(sequencer_v2);
- sequencer_v2 += 0x100;
- if (sequencer_v2 < 0x03030302) {
- sequencer_v2 = 0x03030302;
- }
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_userid_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- ngx_str_t *name, uint32_t *uid)
-{
- v->len = name->len + sizeof("=00001111222233334444555566667777") - 1;
- v->data = ngx_pnalloc(r->pool, v->len);
- if (v->data == NULL) {
- return NGX_ERROR;
- }
-
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- ngx_sprintf(v->data, "%V=%08XD%08XD%08XD%08XD",
- name, uid[0], uid[1], uid[2], uid[3]);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_userid_reset_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- *v = ngx_http_variable_null_value;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_userid_add_variables(ngx_conf_t *cf)
-{
- ngx_int_t n;
- ngx_http_variable_t *var;
-
- var = ngx_http_add_variable(cf, &ngx_http_userid_got, 0);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = ngx_http_userid_got_variable;
-
- var = ngx_http_add_variable(cf, &ngx_http_userid_set, 0);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = ngx_http_userid_set_variable;
-
- var = ngx_http_add_variable(cf, &ngx_http_userid_reset,
- NGX_HTTP_VAR_CHANGEABLE);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = ngx_http_userid_reset_variable;
-
- n = ngx_http_get_variable_index(cf, &ngx_http_userid_reset);
- if (n == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- ngx_http_userid_reset_index = n;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_userid_create_conf(ngx_conf_t *cf)
-{
- ngx_http_userid_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_userid_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->name = { 0, NULL };
- * conf->domain = { 0, NULL };
- * conf->path = { 0, NULL };
- * conf->p3p = { 0, NULL };
- */
-
- conf->enable = NGX_CONF_UNSET_UINT;
- conf->service = NGX_CONF_UNSET;
- conf->expires = NGX_CONF_UNSET;
- conf->mark = (u_char) '\xFF';
-
- return conf;
-}
-
-
-static char *
-ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_userid_conf_t *prev = parent;
- ngx_http_userid_conf_t *conf = child;
-
- ngx_conf_merge_uint_value(conf->enable, prev->enable,
- NGX_HTTP_USERID_OFF);
-
- ngx_conf_merge_str_value(conf->name, prev->name, "uid");
- ngx_conf_merge_str_value(conf->domain, prev->domain, "");
- ngx_conf_merge_str_value(conf->path, prev->path, "; path=/");
- ngx_conf_merge_str_value(conf->p3p, prev->p3p, "");
-
- ngx_conf_merge_value(conf->service, prev->service, NGX_CONF_UNSET);
- ngx_conf_merge_sec_value(conf->expires, prev->expires, 0);
-
- if (conf->mark == (u_char) '\xFF') {
- if (prev->mark == (u_char) '\xFF') {
- conf->mark = '\0';
- } else {
- conf->mark = prev->mark;
- }
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_userid_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_userid_filter;
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_http_userid_domain(ngx_conf_t *cf, void *post, void *data)
-{
- ngx_str_t *domain = data;
-
- u_char *p, *new;
-
- if (ngx_strcmp(domain->data, "none") == 0) {
- ngx_str_set(domain, "");
- return NGX_CONF_OK;
- }
-
- new = ngx_pnalloc(cf->pool, sizeof("; domain=") - 1 + domain->len);
- if (new == NULL) {
- return NGX_CONF_ERROR;
- }
-
- p = ngx_cpymem(new, "; domain=", sizeof("; domain=") - 1);
- ngx_memcpy(p, domain->data, domain->len);
-
- domain->len += sizeof("; domain=") - 1;
- domain->data = new;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_userid_path(ngx_conf_t *cf, void *post, void *data)
-{
- ngx_str_t *path = data;
-
- u_char *p, *new;
-
- new = ngx_pnalloc(cf->pool, sizeof("; path=") - 1 + path->len);
- if (new == NULL) {
- return NGX_CONF_ERROR;
- }
-
- p = ngx_cpymem(new, "; path=", sizeof("; path=") - 1);
- ngx_memcpy(p, path->data, path->len);
-
- path->len += sizeof("; path=") - 1;
- path->data = new;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_userid_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_userid_conf_t *ucf = conf;
-
- ngx_str_t *value;
-
- if (ucf->expires != NGX_CONF_UNSET) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- if (ngx_strcmp(value[1].data, "max") == 0) {
- ucf->expires = NGX_HTTP_USERID_MAX_EXPIRES;
- return NGX_CONF_OK;
- }
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- ucf->expires = 0;
- return NGX_CONF_OK;
- }
-
- ucf->expires = ngx_parse_time(&value[1], 1);
- if (ucf->expires == (time_t) NGX_ERROR) {
- return "invalid value";
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_userid_p3p(ngx_conf_t *cf, void *post, void *data)
-{
- ngx_str_t *p3p = data;
-
- if (ngx_strcmp(p3p->data, "none") == 0) {
- ngx_str_set(p3p, "");
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_userid_mark(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_userid_conf_t *ucf = conf;
-
- ngx_str_t *value;
-
- if (ucf->mark != (u_char) '\xFF') {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- ucf->mark = '\0';
- return NGX_CONF_OK;
- }
-
- if (value[1].len != 1
- || !((value[1].data[0] >= '0' && value[1].data[0] <= '9')
- || (value[1].data[0] >= 'A' && value[1].data[0] <= 'Z')
- || (value[1].data[0] >= 'a' && value[1].data[0] <= 'z')
- || value[1].data[0] == '='))
- {
- return "value must be \"off\" or a single letter, digit or \"=\"";
- }
-
- ucf->mark = value[1].data[0];
-
- 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;
-}
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_uwsgi_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_uwsgi_module.c
deleted file mode 100644
index 17dfc3b3ac7..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_uwsgi_module.c
+++ /dev/null
@@ -1,2036 +0,0 @@
-
-/*
- * Copyright (C) Unbit S.a.s. 2009-2010
- * Copyright (C) 2008 Manlio Perillo (manlio.perillo@gmail.com)
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_http_upstream_conf_t upstream;
-
- ngx_array_t *flushes;
- ngx_array_t *params_len;
- ngx_array_t *params;
- ngx_array_t *params_source;
-
- ngx_hash_t headers_hash;
- ngx_uint_t header_params;
-
- ngx_array_t *uwsgi_lengths;
- ngx_array_t *uwsgi_values;
-
-#if (NGX_HTTP_CACHE)
- ngx_http_complex_value_t cache_key;
-#endif
-
- ngx_str_t uwsgi_string;
-
- ngx_uint_t modifier1;
- ngx_uint_t modifier2;
-
-#if (NGX_HTTP_SSL)
- ngx_uint_t ssl;
- ngx_uint_t ssl_protocols;
- ngx_str_t ssl_ciphers;
-#endif
-} ngx_http_uwsgi_loc_conf_t;
-
-
-static ngx_int_t ngx_http_uwsgi_eval(ngx_http_request_t *r,
- ngx_http_uwsgi_loc_conf_t *uwcf);
-static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r);
-static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r);
-static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r);
-static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
-static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r);
-static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r,
- ngx_int_t rc);
-
-static void *ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static ngx_int_t ngx_http_uwsgi_merge_params(ngx_conf_t *cf,
- ngx_http_uwsgi_loc_conf_t *conf, ngx_http_uwsgi_loc_conf_t *prev);
-
-static char *ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-#if (NGX_HTTP_CACHE)
-static ngx_int_t ngx_http_uwsgi_create_key(ngx_http_request_t *r);
-static char *ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-#endif
-
-#if (NGX_HTTP_SSL)
-static ngx_int_t ngx_http_uwsgi_set_ssl(ngx_conf_t *cf,
- ngx_http_uwsgi_loc_conf_t *uwcf);
-#endif
-
-
-static ngx_conf_num_bounds_t ngx_http_uwsgi_modifier_bounds = {
- ngx_conf_check_num_bounds, 0, 255
-};
-
-
-static ngx_conf_bitmask_t ngx_http_uwsgi_next_upstream_masks[] = {
- { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
- { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
- { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
- { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
- { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
- { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
- { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
- { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
- { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
- { ngx_null_string, 0 }
-};
-
-
-#if (NGX_HTTP_SSL)
-
-static ngx_conf_bitmask_t ngx_http_uwsgi_ssl_protocols[] = {
- { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
- { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
- { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
- { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
- { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
- { ngx_null_string, 0 }
-};
-
-#endif
-
-
-ngx_module_t ngx_http_uwsgi_module;
-
-
-static ngx_command_t ngx_http_uwsgi_commands[] = {
-
- { ngx_string("uwsgi_pass"),
- NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
- ngx_http_uwsgi_pass,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("uwsgi_modifier1"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, modifier1),
- &ngx_http_uwsgi_modifier_bounds },
-
- { ngx_string("uwsgi_modifier2"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, modifier2),
- &ngx_http_uwsgi_modifier_bounds },
-
- { ngx_string("uwsgi_store"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_uwsgi_store,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("uwsgi_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_uwsgi_loc_conf_t, upstream.store_access),
- NULL },
-
- { ngx_string("uwsgi_buffering"),
- 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_uwsgi_loc_conf_t, upstream.buffering),
- NULL },
-
- { ngx_string("uwsgi_ignore_client_abort"),
- 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_uwsgi_loc_conf_t, upstream.ignore_client_abort),
- NULL },
-
- { ngx_string("uwsgi_bind"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_upstream_bind_set_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.local),
- NULL },
-
- { ngx_string("uwsgi_connect_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.connect_timeout),
- NULL },
-
- { ngx_string("uwsgi_send_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.send_timeout),
- NULL },
-
- { ngx_string("uwsgi_buffer_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.buffer_size),
- NULL },
-
- { ngx_string("uwsgi_pass_request_headers"),
- 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_uwsgi_loc_conf_t, upstream.pass_request_headers),
- NULL },
-
- { ngx_string("uwsgi_pass_request_body"),
- 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_uwsgi_loc_conf_t, upstream.pass_request_body),
- NULL },
-
- { ngx_string("uwsgi_intercept_errors"),
- 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_uwsgi_loc_conf_t, upstream.intercept_errors),
- NULL },
-
- { ngx_string("uwsgi_read_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.read_timeout),
- NULL },
-
- { ngx_string("uwsgi_buffers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_conf_set_bufs_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.bufs),
- NULL },
-
- { ngx_string("uwsgi_busy_buffers_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.busy_buffers_size_conf),
- NULL },
-
-#if (NGX_HTTP_CACHE)
-
- { ngx_string("uwsgi_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_uwsgi_cache,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("uwsgi_cache_key"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_uwsgi_cache_key,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("uwsgi_cache_path"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE,
- ngx_http_file_cache_set_slot,
- 0,
- 0,
- &ngx_http_uwsgi_module },
-
- { ngx_string("uwsgi_cache_bypass"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_set_predicate_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_bypass),
- NULL },
-
- { ngx_string("uwsgi_no_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_set_predicate_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.no_cache),
- NULL },
-
- { ngx_string("uwsgi_cache_valid"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_file_cache_valid_set_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_valid),
- NULL },
-
- { ngx_string("uwsgi_cache_min_uses"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_min_uses),
- NULL },
-
- { ngx_string("uwsgi_cache_use_stale"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_use_stale),
- &ngx_http_uwsgi_next_upstream_masks },
-
- { ngx_string("uwsgi_cache_methods"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_methods),
- &ngx_http_upstream_cache_method_mask },
-
- { ngx_string("uwsgi_cache_lock"),
- 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_uwsgi_loc_conf_t, upstream.cache_lock),
- NULL },
-
- { ngx_string("uwsgi_cache_lock_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_lock_timeout),
- NULL },
-
- { ngx_string("uwsgi_cache_revalidate"),
- 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_uwsgi_loc_conf_t, upstream.cache_revalidate),
- NULL },
-
-#endif
-
- { ngx_string("uwsgi_temp_path"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
- ngx_conf_set_path_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.temp_path),
- NULL },
-
- { ngx_string("uwsgi_max_temp_file_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.max_temp_file_size_conf),
- NULL },
-
- { ngx_string("uwsgi_temp_file_write_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.temp_file_write_size_conf),
- NULL },
-
- { ngx_string("uwsgi_next_upstream"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.next_upstream),
- &ngx_http_uwsgi_next_upstream_masks },
-
- { ngx_string("uwsgi_param"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
- ngx_http_upstream_param_set_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, params_source),
- NULL },
-
- { ngx_string("uwsgi_string"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, uwsgi_string),
- NULL },
-
- { ngx_string("uwsgi_pass_header"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_array_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_headers),
- NULL },
-
- { ngx_string("uwsgi_hide_header"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_array_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.hide_headers),
- NULL },
-
- { ngx_string("uwsgi_ignore_headers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ignore_headers),
- &ngx_http_upstream_ignore_headers_masks },
-
-#if (NGX_HTTP_SSL)
-
- { ngx_string("uwsgi_ssl_session_reuse"),
- 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_uwsgi_loc_conf_t, upstream.ssl_session_reuse),
- NULL },
-
- { ngx_string("uwsgi_ssl_protocols"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, ssl_protocols),
- &ngx_http_uwsgi_ssl_protocols },
-
- { ngx_string("uwsgi_ssl_ciphers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_uwsgi_loc_conf_t, ssl_ciphers),
- NULL },
-
-#endif
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_uwsgi_module_ctx = {
- NULL, /* preconfiguration */
- NULL, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_uwsgi_create_loc_conf, /* create location configuration */
- ngx_http_uwsgi_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_uwsgi_module = {
- NGX_MODULE_V1,
- &ngx_http_uwsgi_module_ctx, /* module context */
- ngx_http_uwsgi_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_str_t ngx_http_uwsgi_hide_headers[] = {
- ngx_string("X-Accel-Expires"),
- ngx_string("X-Accel-Redirect"),
- ngx_string("X-Accel-Limit-Rate"),
- ngx_string("X-Accel-Buffering"),
- ngx_string("X-Accel-Charset"),
- ngx_null_string
-};
-
-
-#if (NGX_HTTP_CACHE)
-
-static ngx_keyval_t ngx_http_uwsgi_cache_headers[] = {
- { ngx_string("HTTP_IF_MODIFIED_SINCE"),
- ngx_string("$upstream_cache_last_modified") },
- { ngx_string("HTTP_IF_UNMODIFIED_SINCE"), ngx_string("") },
- { ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("") },
- { ngx_string("HTTP_IF_MATCH"), ngx_string("") },
- { ngx_string("HTTP_RANGE"), ngx_string("") },
- { ngx_string("HTTP_IF_RANGE"), ngx_string("") },
- { ngx_null_string, ngx_null_string }
-};
-
-#endif
-
-
-static ngx_path_init_t ngx_http_uwsgi_temp_path = {
- ngx_string(NGX_HTTP_UWSGI_TEMP_PATH), { 1, 2, 0 }
-};
-
-
-static ngx_int_t
-ngx_http_uwsgi_handler(ngx_http_request_t *r)
-{
- ngx_int_t rc;
- ngx_http_status_t *status;
- ngx_http_upstream_t *u;
- ngx_http_uwsgi_loc_conf_t *uwcf;
-
- if (ngx_http_upstream_create(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- status = ngx_pcalloc(r->pool, sizeof(ngx_http_status_t));
- if (status == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ngx_http_set_ctx(r, status, ngx_http_uwsgi_module);
-
- uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
-
- u = r->upstream;
-
- if (uwcf->uwsgi_lengths == NULL) {
-
-#if (NGX_HTTP_SSL)
- u->ssl = (uwcf->upstream.ssl != NULL);
-
- if (u->ssl) {
- ngx_str_set(&u->schema, "suwsgi://");
-
- } else {
- ngx_str_set(&u->schema, "uwsgi://");
- }
-#else
- ngx_str_set(&u->schema, "uwsgi://");
-#endif
-
- } else {
- if (ngx_http_uwsgi_eval(r, uwcf) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
- }
-
- u->output.tag = (ngx_buf_tag_t) &ngx_http_uwsgi_module;
-
- u->conf = &uwcf->upstream;
-
-#if (NGX_HTTP_CACHE)
- u->create_key = ngx_http_uwsgi_create_key;
-#endif
- u->create_request = ngx_http_uwsgi_create_request;
- u->reinit_request = ngx_http_uwsgi_reinit_request;
- u->process_header = ngx_http_uwsgi_process_status_line;
- u->abort_request = ngx_http_uwsgi_abort_request;
- u->finalize_request = ngx_http_uwsgi_finalize_request;
- r->state = 0;
-
- u->buffering = uwcf->upstream.buffering;
-
- u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
- if (u->pipe == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
- u->pipe->input_ctx = r;
-
- rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init);
-
- if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
- return rc;
- }
-
- return NGX_DONE;
-}
-
-
-static ngx_int_t
-ngx_http_uwsgi_eval(ngx_http_request_t *r, ngx_http_uwsgi_loc_conf_t * uwcf)
-{
- size_t add;
- ngx_url_t url;
- ngx_http_upstream_t *u;
-
- ngx_memzero(&url, sizeof(ngx_url_t));
-
- if (ngx_http_script_run(r, &url.url, uwcf->uwsgi_lengths->elts, 0,
- uwcf->uwsgi_values->elts)
- == NULL)
- {
- return NGX_ERROR;
- }
-
- if (url.url.len > 8
- && ngx_strncasecmp(url.url.data, (u_char *) "uwsgi://", 8) == 0)
- {
- add = 8;
-
- } else if (url.url.len > 9
- && ngx_strncasecmp(url.url.data, (u_char *) "suwsgi://", 9) == 0)
- {
-
-#if (NGX_HTTP_SSL)
- add = 9;
- r->upstream->ssl = 1;
-#else
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "suwsgi protocol requires SSL support");
- return NGX_ERROR;
-#endif
-
- } else {
- add = 0;
- }
-
- u = r->upstream;
-
- if (add) {
- u->schema.len = add;
- u->schema.data = url.url.data;
-
- url.url.data += add;
- url.url.len -= add;
-
- } else {
- ngx_str_set(&u->schema, "uwsgi://");
- }
-
- url.no_resolve = 1;
-
- if (ngx_parse_url(r->pool, &url) != NGX_OK) {
- if (url.err) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "%s in upstream \"%V\"", url.err, &url.url);
- }
-
- return NGX_ERROR;
- }
-
- u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
- if (u->resolved == NULL) {
- return NGX_ERROR;
- }
-
- if (url.addrs && url.addrs[0].sockaddr) {
- u->resolved->sockaddr = url.addrs[0].sockaddr;
- u->resolved->socklen = url.addrs[0].socklen;
- u->resolved->naddrs = 1;
- u->resolved->host = url.addrs[0].name;
-
- } else {
- u->resolved->host = url.host;
- u->resolved->port = url.port;
- u->resolved->no_port = url.no_port;
- }
-
- return NGX_OK;
-}
-
-
-#if (NGX_HTTP_CACHE)
-
-static ngx_int_t
-ngx_http_uwsgi_create_key(ngx_http_request_t *r)
-{
- ngx_str_t *key;
- ngx_http_uwsgi_loc_conf_t *uwcf;
-
- key = ngx_array_push(&r->cache->keys);
- if (key == NULL) {
- return NGX_ERROR;
- }
-
- uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
-
- if (ngx_http_complex_value(r, &uwcf->cache_key, key) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_uwsgi_create_request(ngx_http_request_t *r)
-{
- u_char ch, *lowcase_key;
- size_t key_len, val_len, len, allocated;
- ngx_uint_t i, n, hash, skip_empty, header_params;
- ngx_buf_t *b;
- ngx_chain_t *cl, *body;
- ngx_list_part_t *part;
- ngx_table_elt_t *header, **ignored;
- ngx_http_script_code_pt code;
- ngx_http_script_engine_t e, le;
- ngx_http_uwsgi_loc_conf_t *uwcf;
- ngx_http_script_len_code_pt lcode;
-
- len = 0;
- header_params = 0;
- ignored = NULL;
-
- uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
-
- if (uwcf->params_len) {
- ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
-
- ngx_http_script_flush_no_cacheable_variables(r, uwcf->flushes);
- le.flushed = 1;
-
- le.ip = uwcf->params_len->elts;
- le.request = r;
-
- while (*(uintptr_t *) le.ip) {
-
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- key_len = lcode(&le);
-
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- skip_empty = lcode(&le);
-
- for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode (&le)) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- }
- le.ip += sizeof(uintptr_t);
-
- if (skip_empty && val_len == 0) {
- continue;
- }
-
- len += 2 + key_len + 2 + val_len;
- }
- }
-
- if (uwcf->upstream.pass_request_headers) {
-
- allocated = 0;
- lowcase_key = NULL;
-
- if (uwcf->header_params) {
- n = 0;
- part = &r->headers_in.headers.part;
-
- while (part) {
- n += part->nelts;
- part = part->next;
- }
-
- ignored = ngx_palloc(r->pool, n * sizeof(void *));
- if (ignored == NULL) {
- return NGX_ERROR;
- }
- }
-
- part = &r->headers_in.headers.part;
- header = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- if (uwcf->header_params) {
- if (allocated < header[i].key.len) {
- allocated = header[i].key.len + 16;
- lowcase_key = ngx_pnalloc(r->pool, allocated);
- if (lowcase_key == NULL) {
- return NGX_ERROR;
- }
- }
-
- hash = 0;
-
- for (n = 0; n < header[i].key.len; n++) {
- ch = header[i].key.data[n];
-
- if (ch >= 'A' && ch <= 'Z') {
- ch |= 0x20;
-
- } else if (ch == '-') {
- ch = '_';
- }
-
- hash = ngx_hash(hash, ch);
- lowcase_key[n] = ch;
- }
-
- if (ngx_hash_find(&uwcf->headers_hash, hash, lowcase_key, n)) {
- ignored[header_params++] = &header[i];
- continue;
- }
- }
-
- len += 2 + sizeof("HTTP_") - 1 + header[i].key.len
- + 2 + header[i].value.len;
- }
- }
-
- len += uwcf->uwsgi_string.len;
-
-#if 0
- /* allow custom uwsgi packet */
- if (len > 0 && len < 2) {
- ngx_log_error (NGX_LOG_ALERT, r->connection->log, 0,
- "uwsgi request is too little: %uz", len);
- return NGX_ERROR;
- }
-#endif
-
- b = ngx_create_temp_buf(r->pool, len + 4);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
-
- *b->last++ = (u_char) uwcf->modifier1;
- *b->last++ = (u_char) (len & 0xff);
- *b->last++ = (u_char) ((len >> 8) & 0xff);
- *b->last++ = (u_char) uwcf->modifier2;
-
- if (uwcf->params_len) {
- ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
-
- e.ip = uwcf->params->elts;
- e.pos = b->last;
- e.request = r;
- e.flushed = 1;
-
- le.ip = uwcf->params_len->elts;
-
- while (*(uintptr_t *) le.ip) {
-
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- key_len = (u_char) lcode (&le);
-
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- skip_empty = lcode(&le);
-
- for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- }
- le.ip += sizeof(uintptr_t);
-
- if (skip_empty && val_len == 0) {
- e.skip = 1;
-
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
- }
- e.ip += sizeof(uintptr_t);
-
- e.skip = 0;
-
- continue;
- }
-
- *e.pos++ = (u_char) (key_len & 0xff);
- *e.pos++ = (u_char) ((key_len >> 8) & 0xff);
-
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) & e);
-
- *e.pos++ = (u_char) (val_len & 0xff);
- *e.pos++ = (u_char) ((val_len >> 8) & 0xff);
-
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) & e);
- }
-
- e.ip += sizeof(uintptr_t);
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "uwsgi param: \"%*s: %*s\"",
- key_len, e.pos - (key_len + 2 + val_len),
- val_len, e.pos - val_len);
- }
-
- b->last = e.pos;
- }
-
- if (uwcf->upstream.pass_request_headers) {
-
- part = &r->headers_in.headers.part;
- header = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- for (n = 0; n < header_params; n++) {
- if (&header[i] == ignored[n]) {
- goto next;
- }
- }
-
- key_len = sizeof("HTTP_") - 1 + header[i].key.len;
- *b->last++ = (u_char) (key_len & 0xff);
- *b->last++ = (u_char) ((key_len >> 8) & 0xff);
-
- b->last = ngx_cpymem(b->last, "HTTP_", sizeof("HTTP_") - 1);
- for (n = 0; n < header[i].key.len; n++) {
- ch = header[i].key.data[n];
-
- if (ch >= 'a' && ch <= 'z') {
- ch &= ~0x20;
-
- } else if (ch == '-') {
- ch = '_';
- }
-
- *b->last++ = ch;
- }
-
- val_len = header[i].value.len;
- *b->last++ = (u_char) (val_len & 0xff);
- *b->last++ = (u_char) ((val_len >> 8) & 0xff);
- b->last = ngx_copy(b->last, header[i].value.data, val_len);
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "uwsgi param: \"%*s: %*s\"",
- key_len, b->last - (key_len + 2 + val_len),
- val_len, b->last - val_len);
- next:
-
- continue;
- }
- }
-
- b->last = ngx_copy(b->last, uwcf->uwsgi_string.data,
- uwcf->uwsgi_string.len);
-
- if (uwcf->upstream.pass_request_body) {
- body = r->upstream->request_bufs;
- r->upstream->request_bufs = cl;
-
- while (body) {
- b = ngx_alloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(b, body->buf, sizeof(ngx_buf_t));
-
- cl->next = ngx_alloc_chain_link(r->pool);
- if (cl->next == NULL) {
- return NGX_ERROR;
- }
-
- cl = cl->next;
- cl->buf = b;
-
- body = body->next;
- }
-
- } else {
- r->upstream->request_bufs = cl;
- }
-
- cl->next = NULL;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_uwsgi_reinit_request(ngx_http_request_t *r)
-{
- ngx_http_status_t *status;
-
- status = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module);
-
- if (status == NULL) {
- return NGX_OK;
- }
-
- status->code = 0;
- status->count = 0;
- status->start = NULL;
- status->end = NULL;
-
- r->upstream->process_header = ngx_http_uwsgi_process_status_line;
- r->state = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_uwsgi_process_status_line(ngx_http_request_t *r)
-{
- size_t len;
- ngx_int_t rc;
- ngx_http_status_t *status;
- ngx_http_upstream_t *u;
-
- status = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module);
-
- if (status == NULL) {
- return NGX_ERROR;
- }
-
- u = r->upstream;
-
- rc = ngx_http_parse_status_line(r, &u->buffer, status);
-
- if (rc == NGX_AGAIN) {
- return rc;
- }
-
- if (rc == NGX_ERROR) {
- u->process_header = ngx_http_uwsgi_process_header;
- return ngx_http_uwsgi_process_header(r);
- }
-
- if (u->state && u->state->status == 0) {
- u->state->status = status->code;
- }
-
- u->headers_in.status_n = status->code;
-
- len = status->end - status->start;
- u->headers_in.status_line.len = len;
-
- u->headers_in.status_line.data = ngx_pnalloc(r->pool, len);
- if (u->headers_in.status_line.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(u->headers_in.status_line.data, status->start, len);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http uwsgi status %ui \"%V\"",
- u->headers_in.status_n, &u->headers_in.status_line);
-
- u->process_header = ngx_http_uwsgi_process_header;
-
- return ngx_http_uwsgi_process_header(r);
-}
-
-
-static ngx_int_t
-ngx_http_uwsgi_process_header(ngx_http_request_t *r)
-{
- ngx_str_t *status_line;
- ngx_int_t rc, status;
- ngx_table_elt_t *h;
- ngx_http_upstream_t *u;
- ngx_http_upstream_header_t *hh;
- ngx_http_upstream_main_conf_t *umcf;
-
- umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
-
- for ( ;; ) {
-
- rc = ngx_http_parse_header_line(r, &r->upstream->buffer, 1);
-
- if (rc == NGX_OK) {
-
- /* a header line has been parsed successfully */
-
- h = ngx_list_push(&r->upstream->headers_in.headers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- 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_pnalloc(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_memcpy(h->key.data, r->header_name_start, h->key.len);
- h->key.data[h->key.len] = '\0';
- ngx_memcpy(h->value.data, r->header_start, h->value.len);
- h->value.data[h->value.len] = '\0';
-
- if (h->key.len == r->lowcase_index) {
- ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
-
- } else {
- ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
- }
-
- hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
- h->lowcase_key, h->key.len);
-
- if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http uwsgi header: \"%V: %V\"", &h->key, &h->value);
-
- continue;
- }
-
- if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
-
- /* a whole header has been parsed successfully */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http uwsgi header done");
-
- u = r->upstream;
-
- if (u->headers_in.status_n) {
- goto done;
- }
-
- if (u->headers_in.status) {
- status_line = &u->headers_in.status->value;
-
- status = ngx_atoi(status_line->data, 3);
- if (status == NGX_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;
- u->headers_in.status_line = *status_line;
-
- } else if (u->headers_in.location) {
- u->headers_in.status_n = 302;
- ngx_str_set(&u->headers_in.status_line,
- "302 Moved Temporarily");
-
- } else {
- u->headers_in.status_n = 200;
- ngx_str_set(&u->headers_in.status_line, "200 OK");
- }
-
- if (u->state && u->state->status == 0) {
- u->state->status = u->headers_in.status_n;
- }
-
- done:
-
- if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS
- && r->headers_in.upgrade)
- {
- u->upgrade = 1;
- }
-
- return NGX_OK;
- }
-
- if (rc == NGX_AGAIN) {
- return NGX_AGAIN;
- }
-
- /* there was error while a header line parsing */
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream sent invalid header");
-
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
- }
-}
-
-
-static void
-ngx_http_uwsgi_abort_request(ngx_http_request_t *r)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "abort http uwsgi request");
-
- return;
-}
-
-
-static void
-ngx_http_uwsgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "finalize http uwsgi request");
-
- return;
-}
-
-
-static void *
-ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_uwsgi_loc_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_uwsgi_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- conf->modifier1 = NGX_CONF_UNSET_UINT;
- conf->modifier2 = NGX_CONF_UNSET_UINT;
-
- 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;
-
- conf->upstream.local = NGX_CONF_UNSET_PTR;
-
- conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
-
- conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
- conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
-
- conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE;
- conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
- conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
-
- conf->upstream.pass_request_headers = NGX_CONF_UNSET;
- conf->upstream.pass_request_body = NGX_CONF_UNSET;
-
-#if (NGX_HTTP_CACHE)
- conf->upstream.cache = NGX_CONF_UNSET_PTR;
- conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
- conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
- conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
- conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
- conf->upstream.cache_lock = NGX_CONF_UNSET;
- conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
- conf->upstream.cache_revalidate = NGX_CONF_UNSET;
-#endif
-
- conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
- conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
-
- conf->upstream.intercept_errors = NGX_CONF_UNSET;
-#if (NGX_HTTP_SSL)
- conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
-#endif
-
- /* "uwsgi_cyclic_temp_file" is disabled */
- conf->upstream.cyclic_temp_file = 0;
-
- conf->upstream.change_buffering = 1;
-
- ngx_str_set(&conf->upstream.module, "uwsgi");
-
- return conf;
-}
-
-
-static char *
-ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_uwsgi_loc_conf_t *prev = parent;
- ngx_http_uwsgi_loc_conf_t *conf = child;
-
- size_t size;
- ngx_hash_init_t hash;
- ngx_http_core_loc_conf_t *clcf;
-
- 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);
-
- ngx_conf_merge_value(conf->upstream.ignore_client_abort,
- prev->upstream.ignore_client_abort, 0);
-
- ngx_conf_merge_ptr_value(conf->upstream.local,
- prev->upstream.local, NULL);
-
- ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
- prev->upstream.connect_timeout, 60000);
-
- ngx_conf_merge_msec_value(conf->upstream.send_timeout,
- prev->upstream.send_timeout, 60000);
-
- ngx_conf_merge_msec_value(conf->upstream.read_timeout,
- prev->upstream.read_timeout, 60000);
-
- ngx_conf_merge_size_value(conf->upstream.send_lowat,
- prev->upstream.send_lowat, 0);
-
- ngx_conf_merge_size_value(conf->upstream.buffer_size,
- prev->upstream.buffer_size,
- (size_t) ngx_pagesize);
-
-
- ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs,
- 8, ngx_pagesize);
-
- if (conf->upstream.bufs.num < 2) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "there must be at least 2 \"uwsgi_buffers\"");
- return NGX_CONF_ERROR;
- }
-
-
- size = conf->upstream.buffer_size;
- if (size < conf->upstream.bufs.size) {
- size = conf->upstream.bufs.size;
- }
-
-
- ngx_conf_merge_size_value(conf->upstream.busy_buffers_size_conf,
- prev->upstream.busy_buffers_size_conf,
- NGX_CONF_UNSET_SIZE);
-
- if (conf->upstream.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) {
- conf->upstream.busy_buffers_size = 2 * size;
- } else {
- conf->upstream.busy_buffers_size =
- conf->upstream.busy_buffers_size_conf;
- }
-
- if (conf->upstream.busy_buffers_size < size) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"uwsgi_busy_buffers_size\" must be equal to or greater "
- "than the maximum of the value of \"uwsgi_buffer_size\" and "
- "one of the \"uwsgi_buffers\"");
-
- return NGX_CONF_ERROR;
- }
-
- if (conf->upstream.busy_buffers_size
- > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size)
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"uwsgi_busy_buffers_size\" must be less than "
- "the size of all \"uwsgi_buffers\" minus one buffer");
-
- return NGX_CONF_ERROR;
- }
-
-
- ngx_conf_merge_size_value(conf->upstream.temp_file_write_size_conf,
- prev->upstream.temp_file_write_size_conf,
- NGX_CONF_UNSET_SIZE);
-
- if (conf->upstream.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) {
- conf->upstream.temp_file_write_size = 2 * size;
- } else {
- conf->upstream.temp_file_write_size =
- conf->upstream.temp_file_write_size_conf;
- }
-
- if (conf->upstream.temp_file_write_size < size) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"uwsgi_temp_file_write_size\" must be equal to or greater than "
- "the maximum of the value of \"uwsgi_buffer_size\" and "
- "one of the \"uwsgi_buffers\"");
-
- return NGX_CONF_ERROR;
- }
-
-
- ngx_conf_merge_size_value(conf->upstream.max_temp_file_size_conf,
- prev->upstream.max_temp_file_size_conf,
- NGX_CONF_UNSET_SIZE);
-
- if (conf->upstream.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) {
- conf->upstream.max_temp_file_size = 1024 * 1024 * 1024;
- } else {
- conf->upstream.max_temp_file_size =
- conf->upstream.max_temp_file_size_conf;
- }
-
- if (conf->upstream.max_temp_file_size != 0
- && conf->upstream.max_temp_file_size < size) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"uwsgi_max_temp_file_size\" must be equal to zero to disable "
- "temporary files usage or must be equal to or greater than "
- "the maximum of the value of \"uwsgi_buffer_size\" and "
- "one of the \"uwsgi_buffers\"");
-
- return NGX_CONF_ERROR;
- }
-
-
- ngx_conf_merge_bitmask_value(conf->upstream.ignore_headers,
- prev->upstream.ignore_headers,
- NGX_CONF_BITMASK_SET);
-
-
- ngx_conf_merge_bitmask_value(conf->upstream.next_upstream,
- prev->upstream.next_upstream,
- (NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_ERROR
- |NGX_HTTP_UPSTREAM_FT_TIMEOUT));
-
- if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) {
- conf->upstream.next_upstream = NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_OFF;
- }
-
- if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,
- prev->upstream.temp_path,
- &ngx_http_uwsgi_temp_path)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
-#if (NGX_HTTP_CACHE)
-
- ngx_conf_merge_ptr_value(conf->upstream.cache,
- prev->upstream.cache, NULL);
-
- if (conf->upstream.cache && conf->upstream.cache->data == NULL) {
- ngx_shm_zone_t *shm_zone;
-
- shm_zone = conf->upstream.cache;
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"uwsgi_cache\" zone \"%V\" is unknown",
- &shm_zone->shm.name);
-
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_uint_value(conf->upstream.cache_min_uses,
- prev->upstream.cache_min_uses, 1);
-
- ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale,
- prev->upstream.cache_use_stale,
- (NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_OFF));
-
- if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) {
- conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET
- |NGX_HTTP_UPSTREAM_FT_OFF;
- }
-
- if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_ERROR) {
- conf->upstream.cache_use_stale |= NGX_HTTP_UPSTREAM_FT_NOLIVE;
- }
-
- if (conf->upstream.cache_methods == 0) {
- conf->upstream.cache_methods = prev->upstream.cache_methods;
- }
-
- conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
-
- ngx_conf_merge_ptr_value(conf->upstream.cache_bypass,
- prev->upstream.cache_bypass, NULL);
-
- ngx_conf_merge_ptr_value(conf->upstream.no_cache,
- prev->upstream.no_cache, NULL);
-
- ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
- prev->upstream.cache_valid, NULL);
-
- if (conf->cache_key.value.data == NULL) {
- conf->cache_key = prev->cache_key;
- }
-
- ngx_conf_merge_value(conf->upstream.cache_lock,
- prev->upstream.cache_lock, 0);
-
- ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout,
- prev->upstream.cache_lock_timeout, 5000);
-
- ngx_conf_merge_value(conf->upstream.cache_revalidate,
- prev->upstream.cache_revalidate, 0);
-
-#endif
-
- ngx_conf_merge_value(conf->upstream.pass_request_headers,
- prev->upstream.pass_request_headers, 1);
- ngx_conf_merge_value(conf->upstream.pass_request_body,
- prev->upstream.pass_request_body, 1);
-
- ngx_conf_merge_value(conf->upstream.intercept_errors,
- prev->upstream.intercept_errors, 0);
-
-#if (NGX_HTTP_SSL)
- ngx_conf_merge_value(conf->upstream.ssl_session_reuse,
- prev->upstream.ssl_session_reuse, 1);
-
- ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
- (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3
- |NGX_SSL_TLSv1|NGX_SSL_TLSv1_1
- |NGX_SSL_TLSv1_2));
-
- ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
- "DEFAULT");
-
- if (conf->ssl && ngx_http_uwsgi_set_ssl(cf, conf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (conf->upstream.ssl == NULL) {
- conf->upstream.ssl = prev->upstream.ssl;
- }
-#endif
-
- ngx_conf_merge_str_value(conf->uwsgi_string, prev->uwsgi_string, "");
-
- hash.max_size = 512;
- hash.bucket_size = ngx_align(64, ngx_cacheline_size);
- hash.name = "uwsgi_hide_headers_hash";
-
- if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
- &prev->upstream, ngx_http_uwsgi_hide_headers, &hash)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- if (conf->upstream.upstream == NULL) {
- conf->upstream.upstream = prev->upstream.upstream;
- }
-
- if (conf->uwsgi_lengths == NULL) {
- conf->uwsgi_lengths = prev->uwsgi_lengths;
- conf->uwsgi_values = prev->uwsgi_values;
- }
-
- if (conf->upstream.upstream || conf->uwsgi_lengths) {
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
- if (clcf->handler == NULL && clcf->lmt_excpt) {
- clcf->handler = ngx_http_uwsgi_handler;
- }
- }
-
- ngx_conf_merge_uint_value(conf->modifier1, prev->modifier1, 0);
- ngx_conf_merge_uint_value(conf->modifier2, prev->modifier2, 0);
-
- if (ngx_http_uwsgi_merge_params(cf, conf, prev) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_uwsgi_merge_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
- ngx_http_uwsgi_loc_conf_t *prev)
-{
- u_char *p;
- size_t size;
- uintptr_t *code;
- ngx_uint_t i, nsrc;
- ngx_array_t headers_names;
-#if (NGX_HTTP_CACHE)
- ngx_array_t params_merged;
-#endif
- ngx_hash_key_t *hk;
- ngx_hash_init_t hash;
- ngx_http_upstream_param_t *src;
- ngx_http_script_compile_t sc;
- ngx_http_script_copy_code_t *copy;
-
- if (conf->params_source == NULL) {
- conf->params_source = prev->params_source;
-
- if (prev->headers_hash.buckets
-#if (NGX_HTTP_CACHE)
- && ((conf->upstream.cache == NULL)
- == (prev->upstream.cache == NULL))
-#endif
- )
- {
- conf->flushes = prev->flushes;
- conf->params_len = prev->params_len;
- conf->params = prev->params;
- conf->headers_hash = prev->headers_hash;
- conf->header_params = prev->header_params;
-
- return NGX_OK;
- }
- }
-
- if (conf->params_source == NULL
-#if (NGX_HTTP_CACHE)
- && (conf->upstream.cache == NULL)
-#endif
- )
- {
- conf->headers_hash.buckets = (void *) 1;
- return NGX_OK;
- }
-
- conf->params_len = ngx_array_create(cf->pool, 64, 1);
- if (conf->params_len == NULL) {
- return NGX_ERROR;
- }
-
- conf->params = ngx_array_create(cf->pool, 512, 1);
- if (conf->params == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (conf->params_source) {
- src = conf->params_source->elts;
- nsrc = conf->params_source->nelts;
-
- } else {
- src = NULL;
- nsrc = 0;
- }
-
-#if (NGX_HTTP_CACHE)
-
- if (conf->upstream.cache) {
- ngx_keyval_t *h;
- ngx_http_upstream_param_t *s;
-
- if (ngx_array_init(&params_merged, cf->temp_pool, 4,
- sizeof(ngx_http_upstream_param_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- for (i = 0; i < nsrc; i++) {
-
- s = ngx_array_push(&params_merged);
- if (s == NULL) {
- return NGX_ERROR;
- }
-
- *s = src[i];
- }
-
- h = ngx_http_uwsgi_cache_headers;
-
- while (h->key.len) {
-
- src = params_merged.elts;
- nsrc = params_merged.nelts;
-
- for (i = 0; i < nsrc; i++) {
- if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
- goto next;
- }
- }
-
- s = ngx_array_push(&params_merged);
- if (s == NULL) {
- return NGX_ERROR;
- }
-
- s->key = h->key;
- s->value = h->value;
- s->skip_empty = 1;
-
- next:
-
- h++;
- }
-
- src = params_merged.elts;
- nsrc = params_merged.nelts;
- }
-
-#endif
-
- for (i = 0; i < nsrc; i++) {
-
- if (src[i].key.len > sizeof("HTTP_") - 1
- && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0)
- {
- hk = ngx_array_push(&headers_names);
- if (hk == NULL) {
- return NGX_ERROR;
- }
-
- hk->key.len = src[i].key.len - 5;
- hk->key.data = src[i].key.data + 5;
- hk->key_hash = ngx_hash_key_lc(hk->key.data, hk->key.len);
- hk->value = (void *) 1;
-
- if (src[i].value.len == 0) {
- continue;
- }
- }
-
- copy = ngx_array_push_n(conf->params_len,
- sizeof(ngx_http_script_copy_code_t));
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
- copy->len = src[i].key.len;
-
- copy = ngx_array_push_n(conf->params_len,
- sizeof(ngx_http_script_copy_code_t));
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
- copy->len = src[i].skip_empty;
-
-
- size = (sizeof(ngx_http_script_copy_code_t)
- + src[i].key.len + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
-
- copy = ngx_array_push_n(conf->params, size);
- if (copy == NULL) {
- return NGX_ERROR;
- }
-
- copy->code = ngx_http_script_copy_code;
- copy->len = src[i].key.len;
-
- p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
- ngx_memcpy(p, src[i].key.data, src[i].key.len);
-
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = &src[i].value;
- sc.flushes = &conf->flushes;
- sc.lengths = &conf->params_len;
- sc.values = &conf->params;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_ERROR;
- }
-
- code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
-
-
- code = ngx_array_push_n(conf->params, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
- }
-
- code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
-
- conf->header_params = headers_names.nelts;
-
- hash.hash = &conf->headers_hash;
- hash.key = ngx_hash_key_lc;
- hash.max_size = 512;
- hash.bucket_size = 64;
- hash.name = "uwsgi_params_hash";
- hash.pool = cf->pool;
- hash.temp_pool = NULL;
-
- return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts);
-}
-
-
-static char *
-ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_uwsgi_loc_conf_t *uwcf = conf;
-
- size_t add;
- ngx_url_t u;
- ngx_str_t *value, *url;
- ngx_uint_t n;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_script_compile_t sc;
-
- if (uwcf->upstream.upstream || uwcf->uwsgi_lengths) {
- return "is duplicate";
- }
-
- clcf = ngx_http_conf_get_module_loc_conf (cf, ngx_http_core_module);
- clcf->handler = ngx_http_uwsgi_handler;
-
- value = cf->args->elts;
-
- url = &value[1];
-
- n = ngx_http_script_variables_count(url);
-
- if (n) {
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = url;
- sc.lengths = &uwcf->uwsgi_lengths;
- sc.values = &uwcf->uwsgi_values;
- sc.variables = n;
- sc.complete_lengths = 1;
- sc.complete_values = 1;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
-#if (NGX_HTTP_SSL)
- uwcf->ssl = 1;
-#endif
-
- return NGX_CONF_OK;
- }
-
- if (ngx_strncasecmp(url->data, (u_char *) "uwsgi://", 8) == 0) {
- add = 8;
-
- } else if (ngx_strncasecmp(url->data, (u_char *) "suwsgi://", 9) == 0) {
-
-#if (NGX_HTTP_SSL)
- add = 9;
- uwcf->ssl = 1;
-#else
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "suwsgi protocol requires SSL support");
- return NGX_CONF_ERROR;
-#endif
-
- } else {
- add = 0;
- }
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- u.url.len = url->len - add;
- u.url.data = url->data + add;
- u.no_resolve = 1;
-
- uwcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
- if (uwcf->upstream.upstream == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (clcf->name.data[clcf->name.len - 1] == '/') {
- clcf->auto_redirect = 1;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_uwsgi_loc_conf_t *uwcf = conf;
-
- ngx_str_t *value;
- ngx_http_script_compile_t sc;
-
- if (uwcf->upstream.store != NGX_CONF_UNSET || uwcf->upstream.store_lengths)
- {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- uwcf->upstream.store = 0;
- return NGX_CONF_OK;
- }
-
-#if (NGX_HTTP_CACHE)
-
- if (uwcf->upstream.cache != NGX_CONF_UNSET_PTR
- && uwcf->upstream.cache != NULL)
- {
- return "is incompatible with \"uwsgi_cache\"";
- }
-
-#endif
-
- if (ngx_strcmp(value[1].data, "on") == 0) {
- uwcf->upstream.store = 1;
- 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 = &uwcf->upstream.store_lengths;
- sc.values = &uwcf->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;
-}
-
-
-#if (NGX_HTTP_CACHE)
-
-static char *
-ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_uwsgi_loc_conf_t *uwcf = conf;
-
- ngx_str_t *value;
-
- value = cf->args->elts;
-
- if (uwcf->upstream.cache != NGX_CONF_UNSET_PTR) {
- return "is duplicate";
- }
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- uwcf->upstream.cache = NULL;
- return NGX_CONF_OK;
- }
-
- if (uwcf->upstream.store > 0 || uwcf->upstream.store_lengths) {
- return "is incompatible with \"uwsgi_store\"";
- }
-
- uwcf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0,
- &ngx_http_uwsgi_module);
- if (uwcf->upstream.cache == NULL) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_uwsgi_loc_conf_t *uwcf = conf;
-
- ngx_str_t *value;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- if (uwcf->cache_key.value.data) {
- return "is duplicate";
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &uwcf->cache_key;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-#endif
-
-
-#if (NGX_HTTP_SSL)
-
-static ngx_int_t
-ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf)
-{
- ngx_pool_cleanup_t *cln;
-
- uwcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
- if (uwcf->upstream.ssl == NULL) {
- return NGX_ERROR;
- }
-
- uwcf->upstream.ssl->log = cf->log;
-
- if (ngx_ssl_create(uwcf->upstream.ssl, uwcf->ssl_protocols, NULL)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (SSL_CTX_set_cipher_list(uwcf->upstream.ssl->ctx,
- (const char *) uwcf->ssl_ciphers.data)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
- "SSL_CTX_set_cipher_list(\"%V\") failed",
- &uwcf->ssl_ciphers);
- return NGX_ERROR;
- }
-
- cln = ngx_pool_cleanup_add(cf->pool, 0);
- if (cln == NULL) {
- return NGX_ERROR;
- }
-
- cln->handler = ngx_ssl_cleanup_ctx;
- cln->data = uwcf->upstream.ssl;
-
- return NGX_OK;
-}
-
-#endif
diff --git a/usr.sbin/nginx/src/http/modules/ngx_http_xslt_filter_module.c b/usr.sbin/nginx/src/http/modules/ngx_http_xslt_filter_module.c
deleted file mode 100644
index 9e85693bcc4..00000000000
--- a/usr.sbin/nginx/src/http/modules/ngx_http_xslt_filter_module.c
+++ /dev/null
@@ -1,1145 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxslt/xslt.h>
-#include <libxslt/xsltInternals.h>
-#include <libxslt/transform.h>
-#include <libxslt/variables.h>
-#include <libxslt/xsltutils.h>
-
-#if (NGX_HAVE_EXSLT)
-#include <libexslt/exslt.h>
-#endif
-
-
-#ifndef NGX_HTTP_XSLT_REUSE_DTD
-#define NGX_HTTP_XSLT_REUSE_DTD 1
-#endif
-
-
-typedef struct {
- u_char *name;
- void *data;
-} ngx_http_xslt_file_t;
-
-
-typedef struct {
- ngx_array_t dtd_files; /* ngx_http_xslt_file_t */
- ngx_array_t sheet_files; /* ngx_http_xslt_file_t */
-} ngx_http_xslt_filter_main_conf_t;
-
-
-typedef struct {
- u_char *name;
- ngx_http_complex_value_t value;
- ngx_uint_t quote; /* unsigned quote:1; */
-} ngx_http_xslt_param_t;
-
-
-typedef struct {
- xsltStylesheetPtr stylesheet;
- ngx_array_t params; /* ngx_http_xslt_param_t */
-} ngx_http_xslt_sheet_t;
-
-
-typedef struct {
- xmlDtdPtr dtd;
- ngx_array_t sheets; /* ngx_http_xslt_sheet_t */
- ngx_hash_t types;
- ngx_array_t *types_keys;
- ngx_array_t *params; /* ngx_http_xslt_param_t */
- ngx_flag_t last_modified;
-} ngx_http_xslt_filter_loc_conf_t;
-
-
-typedef struct {
- xmlDocPtr doc;
- xmlParserCtxtPtr ctxt;
- xsltTransformContextPtr transform;
- ngx_http_request_t *request;
- ngx_array_t params;
-
- ngx_uint_t done; /* unsigned done:1; */
-} ngx_http_xslt_filter_ctx_t;
-
-
-static ngx_int_t ngx_http_xslt_send(ngx_http_request_t *r,
- ngx_http_xslt_filter_ctx_t *ctx, ngx_buf_t *b);
-static ngx_int_t ngx_http_xslt_add_chunk(ngx_http_request_t *r,
- ngx_http_xslt_filter_ctx_t *ctx, ngx_buf_t *b);
-
-
-static void ngx_http_xslt_sax_external_subset(void *data, const xmlChar *name,
- const xmlChar *externalId, const xmlChar *systemId);
-static void ngx_cdecl ngx_http_xslt_sax_error(void *data, const char *msg, ...);
-
-
-static ngx_buf_t *ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
- ngx_http_xslt_filter_ctx_t *ctx);
-static ngx_int_t ngx_http_xslt_params(ngx_http_request_t *r,
- ngx_http_xslt_filter_ctx_t *ctx, ngx_array_t *params, ngx_uint_t final);
-static u_char *ngx_http_xslt_content_type(xsltStylesheetPtr s);
-static u_char *ngx_http_xslt_encoding(xsltStylesheetPtr s);
-static void ngx_http_xslt_cleanup(void *data);
-
-static char *ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_xslt_param(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static void ngx_http_xslt_cleanup_dtd(void *data);
-static void ngx_http_xslt_cleanup_stylesheet(void *data);
-static void *ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf);
-static void *ngx_http_xslt_filter_create_conf(ngx_conf_t *cf);
-static char *ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static ngx_int_t ngx_http_xslt_filter_preconfiguration(ngx_conf_t *cf);
-static ngx_int_t ngx_http_xslt_filter_init(ngx_conf_t *cf);
-static void ngx_http_xslt_filter_exit(ngx_cycle_t *cycle);
-
-
-ngx_str_t ngx_http_xslt_default_types[] = {
- ngx_string("text/xml"),
- ngx_null_string
-};
-
-
-static ngx_command_t ngx_http_xslt_filter_commands[] = {
-
- { ngx_string("xml_entities"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_xslt_entities,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("xslt_stylesheet"),
- NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_xslt_stylesheet,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("xslt_param"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_http_xslt_param,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("xslt_string_param"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_http_xslt_param,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- (void *) 1 },
-
- { ngx_string("xslt_types"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_types_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_xslt_filter_loc_conf_t, types_keys),
- &ngx_http_xslt_default_types[0] },
-
- { ngx_string("xslt_last_modified"),
- 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_xslt_filter_loc_conf_t, last_modified),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_xslt_filter_module_ctx = {
- ngx_http_xslt_filter_preconfiguration, /* preconfiguration */
- ngx_http_xslt_filter_init, /* postconfiguration */
-
- ngx_http_xslt_filter_create_main_conf, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_xslt_filter_create_conf, /* create location configuration */
- ngx_http_xslt_filter_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_xslt_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_xslt_filter_module_ctx, /* module context */
- ngx_http_xslt_filter_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- ngx_http_xslt_filter_exit, /* exit process */
- ngx_http_xslt_filter_exit, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-
-
-static ngx_int_t
-ngx_http_xslt_header_filter(ngx_http_request_t *r)
-{
- ngx_http_xslt_filter_ctx_t *ctx;
- ngx_http_xslt_filter_loc_conf_t *conf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "xslt filter header");
-
- if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) {
- return ngx_http_next_header_filter(r);
- }
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module);
-
- if (conf->sheets.nelts == 0
- || ngx_http_test_content_type(r, &conf->types) == NULL)
- {
- return ngx_http_next_header_filter(r);
- }
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_xslt_filter_module);
-
- if (ctx) {
- return ngx_http_next_header_filter(r);
- }
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_xslt_filter_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_xslt_filter_module);
-
- r->main_filter_need_in_memory = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_xslt_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- int wellFormed;
- ngx_chain_t *cl;
- ngx_http_xslt_filter_ctx_t *ctx;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "xslt filter body");
-
- if (in == NULL) {
- return ngx_http_next_body_filter(r, in);
- }
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_xslt_filter_module);
-
- if (ctx == NULL || ctx->done) {
- return ngx_http_next_body_filter(r, in);
- }
-
- for (cl = in; cl; cl = cl->next) {
-
- if (ngx_http_xslt_add_chunk(r, ctx, cl->buf) != NGX_OK) {
-
- if (ctx->ctxt->myDoc) {
-
-#if (NGX_HTTP_XSLT_REUSE_DTD)
- ctx->ctxt->myDoc->extSubset = NULL;
-#endif
- xmlFreeDoc(ctx->ctxt->myDoc);
- }
-
- xmlFreeParserCtxt(ctx->ctxt);
-
- return ngx_http_xslt_send(r, ctx, NULL);
- }
-
- if (cl->buf->last_buf || cl->buf->last_in_chain) {
-
- ctx->doc = ctx->ctxt->myDoc;
-
-#if (NGX_HTTP_XSLT_REUSE_DTD)
- ctx->doc->extSubset = NULL;
-#endif
-
- wellFormed = ctx->ctxt->wellFormed;
-
- xmlFreeParserCtxt(ctx->ctxt);
-
- if (wellFormed) {
- return ngx_http_xslt_send(r, ctx,
- ngx_http_xslt_apply_stylesheet(r, ctx));
- }
-
- xmlFreeDoc(ctx->doc);
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "not well formed XML document");
-
- return ngx_http_xslt_send(r, ctx, NULL);
- }
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_xslt_send(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
- ngx_buf_t *b)
-{
- ngx_int_t rc;
- ngx_chain_t out;
- ngx_pool_cleanup_t *cln;
- ngx_http_xslt_filter_loc_conf_t *conf;
-
- ctx->done = 1;
-
- if (b == NULL) {
- return ngx_http_filter_finalize_request(r, &ngx_http_xslt_filter_module,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- }
-
- cln = ngx_pool_cleanup_add(r->pool, 0);
-
- if (cln == NULL) {
- ngx_free(b->pos);
- return ngx_http_filter_finalize_request(r, &ngx_http_xslt_filter_module,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- }
-
- if (r == r->main) {
- r->headers_out.content_length_n = b->last - b->pos;
-
- if (r->headers_out.content_length) {
- r->headers_out.content_length->hash = 0;
- r->headers_out.content_length = NULL;
- }
-
- ngx_http_clear_etag(r);
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module);
-
- if (!conf->last_modified) {
- ngx_http_clear_last_modified(r);
- }
- }
-
- rc = ngx_http_next_header_filter(r);
-
- if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
- ngx_free(b->pos);
- return rc;
- }
-
- cln->handler = ngx_http_xslt_cleanup;
- cln->data = b->pos;
-
- out.buf = b;
- out.next = NULL;
-
- return ngx_http_next_body_filter(r, &out);
-}
-
-
-static ngx_int_t
-ngx_http_xslt_add_chunk(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
- ngx_buf_t *b)
-{
- int err;
- xmlParserCtxtPtr ctxt;
-
- if (ctx->ctxt == NULL) {
-
- ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
- if (ctxt == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "xmlCreatePushParserCtxt() failed");
- return NGX_ERROR;
- }
- xmlCtxtUseOptions(ctxt, XML_PARSE_NOENT|XML_PARSE_DTDLOAD
- |XML_PARSE_NOWARNING);
-
- ctxt->sax->externalSubset = ngx_http_xslt_sax_external_subset;
- ctxt->sax->setDocumentLocator = NULL;
- ctxt->sax->error = ngx_http_xslt_sax_error;
- ctxt->sax->fatalError = ngx_http_xslt_sax_error;
- ctxt->sax->_private = ctx;
-
- ctx->ctxt = ctxt;
- ctx->request = r;
- }
-
- err = xmlParseChunk(ctx->ctxt, (char *) b->pos, (int) (b->last - b->pos),
- (b->last_buf) || (b->last_in_chain));
-
- if (err == 0) {
- b->pos = b->last;
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "xmlParseChunk() failed, error:%d", err);
-
- return NGX_ERROR;
-}
-
-
-static void
-ngx_http_xslt_sax_external_subset(void *data, const xmlChar *name,
- const xmlChar *externalId, const xmlChar *systemId)
-{
- xmlParserCtxtPtr ctxt = data;
-
- xmlDocPtr doc;
- xmlDtdPtr dtd;
- ngx_http_request_t *r;
- ngx_http_xslt_filter_ctx_t *ctx;
- ngx_http_xslt_filter_loc_conf_t *conf;
-
- ctx = ctxt->sax->_private;
- r = ctx->request;
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module);
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "xslt filter extSubset: \"%s\" \"%s\" \"%s\"",
- name ? name : (xmlChar *) "",
- externalId ? externalId : (xmlChar *) "",
- systemId ? systemId : (xmlChar *) "");
-
- doc = ctxt->myDoc;
-
-#if (NGX_HTTP_XSLT_REUSE_DTD)
-
- dtd = conf->dtd;
-
-#else
-
- dtd = xmlCopyDtd(conf->dtd);
- if (dtd == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "xmlCopyDtd() failed");
- return;
- }
-
- if (doc->children == NULL) {
- xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd);
-
- } else {
- xmlAddPrevSibling(doc->children, (xmlNodePtr) dtd);
- }
-
-#endif
-
- doc->extSubset = dtd;
-}
-
-
-static void ngx_cdecl
-ngx_http_xslt_sax_error(void *data, const char *msg, ...)
-{
- xmlParserCtxtPtr ctxt = data;
-
- size_t n;
- va_list args;
- ngx_http_xslt_filter_ctx_t *ctx;
- u_char buf[NGX_MAX_ERROR_STR];
-
- ctx = ctxt->sax->_private;
-
- buf[0] = '\0';
-
- va_start(args, msg);
- n = (size_t) vsnprintf((char *) buf, NGX_MAX_ERROR_STR, msg, args);
- va_end(args);
-
- while (--n && (buf[n] == CR || buf[n] == LF)) { /* void */ }
-
- ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
- "libxml2 error: \"%*s\"", n + 1, buf);
-}
-
-
-static ngx_buf_t *
-ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
- ngx_http_xslt_filter_ctx_t *ctx)
-{
- int len, rc, doc_type;
- u_char *type, *encoding;
- ngx_buf_t *b;
- ngx_uint_t i;
- xmlChar *buf;
- xmlDocPtr doc, res;
- ngx_http_xslt_sheet_t *sheet;
- ngx_http_xslt_filter_loc_conf_t *conf;
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module);
- sheet = conf->sheets.elts;
- doc = ctx->doc;
-
- /* preallocate array for 4 params */
-
- if (ngx_array_init(&ctx->params, r->pool, 4 * 2 + 1, sizeof(char *))
- != NGX_OK)
- {
- xmlFreeDoc(doc);
- return NULL;
- }
-
- for (i = 0; i < conf->sheets.nelts; i++) {
-
- ctx->transform = xsltNewTransformContext(sheet[i].stylesheet, doc);
- if (ctx->transform == NULL) {
- xmlFreeDoc(doc);
- return NULL;
- }
-
- if (conf->params
- && ngx_http_xslt_params(r, ctx, conf->params, 0) != NGX_OK)
- {
- xsltFreeTransformContext(ctx->transform);
- xmlFreeDoc(doc);
- return NULL;
- }
-
- if (ngx_http_xslt_params(r, ctx, &sheet[i].params, 1) != NGX_OK) {
- xsltFreeTransformContext(ctx->transform);
- xmlFreeDoc(doc);
- return NULL;
- }
-
- res = xsltApplyStylesheetUser(sheet[i].stylesheet, doc,
- ctx->params.elts, NULL, NULL,
- ctx->transform);
-
- xsltFreeTransformContext(ctx->transform);
- xmlFreeDoc(doc);
-
- if (res == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "xsltApplyStylesheet() failed");
- return NULL;
- }
-
- doc = res;
-
- /* reset array elements */
- ctx->params.nelts = 0;
- }
-
- /* there must be at least one stylesheet */
-
- if (r == r->main) {
- type = ngx_http_xslt_content_type(sheet[i - 1].stylesheet);
-
- } else {
- type = NULL;
- }
-
- encoding = ngx_http_xslt_encoding(sheet[i - 1].stylesheet);
- doc_type = doc->type;
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "xslt filter type: %d t:%s e:%s",
- doc_type, type ? type : (u_char *) "(null)",
- encoding ? encoding : (u_char *) "(null)");
-
- rc = xsltSaveResultToString(&buf, &len, doc, sheet[i - 1].stylesheet);
-
- xmlFreeDoc(doc);
-
- if (rc != 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "xsltSaveResultToString() failed");
- return NULL;
- }
-
- if (len == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "xsltSaveResultToString() returned zero-length result");
- return NULL;
- }
-
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- ngx_free(buf);
- return NULL;
- }
-
- b->pos = buf;
- b->last = buf + len;
- b->memory = 1;
-
- if (encoding) {
- r->headers_out.charset.len = ngx_strlen(encoding);
- r->headers_out.charset.data = encoding;
- }
-
- if (r != r->main) {
- return b;
- }
-
- b->last_buf = 1;
-
- if (type) {
- len = ngx_strlen(type);
-
- r->headers_out.content_type_len = len;
- r->headers_out.content_type.len = len;
- r->headers_out.content_type.data = type;
-
- } else if (doc_type == XML_HTML_DOCUMENT_NODE) {
-
- r->headers_out.content_type_len = sizeof("text/html") - 1;
- ngx_str_set(&r->headers_out.content_type, "text/html");
- }
-
- r->headers_out.content_type_lowcase = NULL;
-
- return b;
-}
-
-
-static ngx_int_t
-ngx_http_xslt_params(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
- ngx_array_t *params, ngx_uint_t final)
-{
- u_char *p, *last, *value, *dst, *src, **s;
- size_t len;
- ngx_uint_t i;
- ngx_str_t string;
- ngx_http_xslt_param_t *param;
-
- param = params->elts;
-
- for (i = 0; i < params->nelts; i++) {
-
- if (ngx_http_complex_value(r, &param[i].value, &string) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "xslt filter param: \"%s\"", string.data);
-
- if (param[i].name) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "xslt filter param name: \"%s\"", param[i].name);
-
- if (param[i].quote) {
- if (xsltQuoteOneUserParam(ctx->transform, param[i].name,
- string.data)
- != 0)
- {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "xsltQuoteOneUserParam(\"%s\", \"%s\") failed",
- param[i].name, string.data);
- return NGX_ERROR;
- }
-
- continue;
- }
-
- s = ngx_array_push(&ctx->params);
- if (s == NULL) {
- return NGX_ERROR;
- }
-
- *s = param[i].name;
-
- s = ngx_array_push(&ctx->params);
- if (s == NULL) {
- return NGX_ERROR;
- }
-
- *s = string.data;
-
- continue;
- }
-
- /*
- * parse param1=value1:param2=value2 syntax as used by parameters
- * specified in xslt_stylesheet directives
- */
-
- p = string.data;
- last = string.data + string.len;
-
- while (p && *p) {
-
- value = p;
- p = (u_char *) ngx_strchr(p, '=');
- if (p == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "invalid libxslt parameter \"%s\"", value);
- return NGX_ERROR;
- }
- *p++ = '\0';
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "xslt filter param name: \"%s\"", value);
-
- s = ngx_array_push(&ctx->params);
- if (s == NULL) {
- return NGX_ERROR;
- }
-
- *s = value;
-
- value = p;
- p = (u_char *) ngx_strchr(p, ':');
-
- if (p) {
- len = p - value;
- *p++ = '\0';
-
- } else {
- len = last - value;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "xslt filter param value: \"%s\"", value);
-
- dst = value;
- src = value;
-
- ngx_unescape_uri(&dst, &src, len, 0);
-
- *dst = '\0';
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "xslt filter param unescaped: \"%s\"", value);
-
- s = ngx_array_push(&ctx->params);
- if (s == NULL) {
- return NGX_ERROR;
- }
-
- *s = value;
- }
- }
-
- if (final) {
- s = ngx_array_push(&ctx->params);
- if (s == NULL) {
- return NGX_ERROR;
- }
-
- *s = NULL;
- }
-
- return NGX_OK;
-}
-
-
-static u_char *
-ngx_http_xslt_content_type(xsltStylesheetPtr s)
-{
- u_char *type;
-
- if (s->mediaType) {
- return s->mediaType;
- }
-
- for (s = s->imports; s; s = s->next) {
-
- type = ngx_http_xslt_content_type(s);
-
- if (type) {
- return type;
- }
- }
-
- return NULL;
-}
-
-
-static u_char *
-ngx_http_xslt_encoding(xsltStylesheetPtr s)
-{
- u_char *encoding;
-
- if (s->encoding) {
- return s->encoding;
- }
-
- for (s = s->imports; s; s = s->next) {
-
- encoding = ngx_http_xslt_encoding(s);
-
- if (encoding) {
- return encoding;
- }
- }
-
- return NULL;
-}
-
-
-static void
-ngx_http_xslt_cleanup(void *data)
-{
- ngx_free(data);
-}
-
-
-static char *
-ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_xslt_filter_loc_conf_t *xlcf = conf;
-
- ngx_str_t *value;
- ngx_uint_t i;
- ngx_pool_cleanup_t *cln;
- ngx_http_xslt_file_t *file;
- ngx_http_xslt_filter_main_conf_t *xmcf;
-
- if (xlcf->dtd) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- xmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_xslt_filter_module);
-
- file = xmcf->dtd_files.elts;
- for (i = 0; i < xmcf->dtd_files.nelts; i++) {
- if (ngx_strcmp(file[i].name, value[1].data) == 0) {
- xlcf->dtd = file[i].data;
- return NGX_CONF_OK;
- }
- }
-
- cln = ngx_pool_cleanup_add(cf->pool, 0);
- if (cln == NULL) {
- return NGX_CONF_ERROR;
- }
-
- xlcf->dtd = xmlParseDTD(NULL, (xmlChar *) value[1].data);
-
- if (xlcf->dtd == NULL) {
- ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "xmlParseDTD() failed");
- return NGX_CONF_ERROR;
- }
-
- cln->handler = ngx_http_xslt_cleanup_dtd;
- cln->data = xlcf->dtd;
-
- file = ngx_array_push(&xmcf->dtd_files);
- if (file == NULL) {
- return NGX_CONF_ERROR;
- }
-
- file->name = value[1].data;
- file->data = xlcf->dtd;
-
- return NGX_CONF_OK;
-}
-
-
-
-static char *
-ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_xslt_filter_loc_conf_t *xlcf = conf;
-
- ngx_str_t *value;
- ngx_uint_t i, n;
- ngx_pool_cleanup_t *cln;
- ngx_http_xslt_file_t *file;
- ngx_http_xslt_sheet_t *sheet;
- ngx_http_xslt_param_t *param;
- ngx_http_compile_complex_value_t ccv;
- ngx_http_xslt_filter_main_conf_t *xmcf;
-
- value = cf->args->elts;
-
- if (xlcf->sheets.elts == NULL) {
- if (ngx_array_init(&xlcf->sheets, cf->pool, 1,
- sizeof(ngx_http_xslt_sheet_t))
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
- }
-
- sheet = ngx_array_push(&xlcf->sheets);
- if (sheet == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(sheet, sizeof(ngx_http_xslt_sheet_t));
-
- if (ngx_conf_full_name(cf->cycle, &value[1], 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- xmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_xslt_filter_module);
-
- file = xmcf->sheet_files.elts;
- for (i = 0; i < xmcf->sheet_files.nelts; i++) {
- if (ngx_strcmp(file[i].name, value[1].data) == 0) {
- sheet->stylesheet = file[i].data;
- goto found;
- }
- }
-
- cln = ngx_pool_cleanup_add(cf->pool, 0);
- if (cln == NULL) {
- return NGX_CONF_ERROR;
- }
-
- sheet->stylesheet = xsltParseStylesheetFile(value[1].data);
- if (sheet->stylesheet == NULL) {
- ngx_conf_log_error(NGX_LOG_ERR, cf, 0,
- "xsltParseStylesheetFile(\"%s\") failed",
- value[1].data);
- return NGX_CONF_ERROR;
- }
-
- cln->handler = ngx_http_xslt_cleanup_stylesheet;
- cln->data = sheet->stylesheet;
-
- file = ngx_array_push(&xmcf->sheet_files);
- if (file == NULL) {
- return NGX_CONF_ERROR;
- }
-
- file->name = value[1].data;
- file->data = sheet->stylesheet;
-
-found:
-
- n = cf->args->nelts;
-
- if (n == 2) {
- return NGX_CONF_OK;
- }
-
- if (ngx_array_init(&sheet->params, cf->pool, n - 2,
- sizeof(ngx_http_xslt_param_t))
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- for (i = 2; i < n; i++) {
-
- param = ngx_array_push(&sheet->params);
- if (param == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(param, sizeof(ngx_http_xslt_param_t));
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[i];
- ccv.complex_value = &param->value;
- ccv.zero = 1;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_xslt_param(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_xslt_filter_loc_conf_t *xlcf = conf;
-
- ngx_http_xslt_param_t *param;
- ngx_http_compile_complex_value_t ccv;
- ngx_str_t *value;
-
- value = cf->args->elts;
-
- if (xlcf->params == NULL) {
- xlcf->params = ngx_array_create(cf->pool, 2,
- sizeof(ngx_http_xslt_param_t));
- if (xlcf->params == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- param = ngx_array_push(xlcf->params);
- if (param == NULL) {
- return NGX_CONF_ERROR;
- }
-
- param->name = value[1].data;
- param->quote = (cmd->post == NULL) ? 0 : 1;
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[2];
- ccv.complex_value = &param->value;
- ccv.zero = 1;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static void
-ngx_http_xslt_cleanup_dtd(void *data)
-{
- xmlFreeDtd(data);
-}
-
-
-static void
-ngx_http_xslt_cleanup_stylesheet(void *data)
-{
- xsltFreeStylesheet(data);
-}
-
-
-static void *
-ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf)
-{
- ngx_http_xslt_filter_main_conf_t *conf;
-
- conf = ngx_palloc(cf->pool, sizeof(ngx_http_xslt_filter_main_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- if (ngx_array_init(&conf->dtd_files, cf->pool, 1,
- sizeof(ngx_http_xslt_file_t))
- != NGX_OK)
- {
- return NULL;
- }
-
- if (ngx_array_init(&conf->sheet_files, cf->pool, 1,
- sizeof(ngx_http_xslt_file_t))
- != NGX_OK)
- {
- return NULL;
- }
-
- return conf;
-}
-
-
-static void *
-ngx_http_xslt_filter_create_conf(ngx_conf_t *cf)
-{
- ngx_http_xslt_filter_loc_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_xslt_filter_loc_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->dtd = NULL;
- * conf->sheets = { NULL };
- * conf->types = { NULL };
- * conf->types_keys = NULL;
- * conf->params = NULL;
- */
-
- conf->last_modified = NGX_CONF_UNSET;
-
- return conf;
-}
-
-
-static char *
-ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_xslt_filter_loc_conf_t *prev = parent;
- ngx_http_xslt_filter_loc_conf_t *conf = child;
-
- if (conf->dtd == NULL) {
- conf->dtd = prev->dtd;
- }
-
- if (conf->sheets.nelts == 0) {
- conf->sheets = prev->sheets;
- }
-
- if (conf->params == NULL) {
- conf->params = prev->params;
- }
-
- if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
- &prev->types_keys, &prev->types,
- ngx_http_xslt_default_types)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_value(conf->last_modified, prev->last_modified, 0);
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_xslt_filter_preconfiguration(ngx_conf_t *cf)
-{
- xmlInitParser();
-
-#if (NGX_HAVE_EXSLT)
- exsltRegisterAll();
-#endif
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_xslt_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_xslt_header_filter;
-
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_xslt_body_filter;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_xslt_filter_exit(ngx_cycle_t *cycle)
-{
- xsltCleanupGlobals();
- xmlCleanupParser();
-}
diff --git a/usr.sbin/nginx/src/http/modules/perl/Makefile.PL b/usr.sbin/nginx/src/http/modules/perl/Makefile.PL
deleted file mode 100644
index 03348b555fc..00000000000
--- a/usr.sbin/nginx/src/http/modules/perl/Makefile.PL
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# Copyright (C) Igor Sysoev
-# Copyright (C) Nginx, Inc.
-
-use 5.006001;
-use ExtUtils::MakeMaker;
-
-WriteMakefile(
- NAME => 'nginx',
- VERSION_FROM => 'nginx.pm', # finds $VERSION
- PREREQ_PM => {}, # e.g., Module::Name => 1.1
-
- ABSTRACT_FROM => 'nginx.pm', # retrieve abstract from module
- AUTHOR => 'Igor Sysoev',
-
- CCFLAGS => "$ENV{NGX_PM_CFLAGS}",
- OPTIMIZE => '-O',
-
- INC => join(" ", map {
- m#^/# ? "-I $_" : "-I ../../../../../$_"
- } (split /\s+/, $ENV{NGX_INCS})),
-
- depend => {
- 'nginx.c' => join(" ", map {
- m#^/# ? $_ : "../../../../../$_"
- } (split(/\s+/, $ENV{NGX_DEPS}),
- "src/http/modules/perl/ngx_http_perl_module.h"))
- },
-
- PM => {
- 'nginx.pm' => '$(INST_LIBDIR)/nginx.pm'
- }
-);
diff --git a/usr.sbin/nginx/src/http/modules/perl/nginx.pm b/usr.sbin/nginx/src/http/modules/perl/nginx.pm
deleted file mode 100644
index e3f73611025..00000000000
--- a/usr.sbin/nginx/src/http/modules/perl/nginx.pm
+++ /dev/null
@@ -1,138 +0,0 @@
-package nginx;
-
-use 5.006001;
-use strict;
-use warnings;
-
-require Exporter;
-
-our @ISA = qw(Exporter);
-
-our @EXPORT = qw(
- OK
- DECLINED
-
- HTTP_OK
- HTTP_CREATED
- HTTP_ACCEPTED
- HTTP_NO_CONTENT
- HTTP_PARTIAL_CONTENT
-
- HTTP_MOVED_PERMANENTLY
- HTTP_MOVED_TEMPORARILY
- HTTP_REDIRECT
- HTTP_SEE_OTHER
- HTTP_NOT_MODIFIED
- HTTP_TEMPORARY_REDIRECT
-
- HTTP_BAD_REQUEST
- HTTP_UNAUTHORIZED
- HTTP_PAYMENT_REQUIRED
- HTTP_FORBIDDEN
- HTTP_NOT_FOUND
- HTTP_NOT_ALLOWED
- HTTP_NOT_ACCEPTABLE
- HTTP_REQUEST_TIME_OUT
- HTTP_CONFLICT
- HTTP_GONE
- HTTP_LENGTH_REQUIRED
- HTTP_REQUEST_ENTITY_TOO_LARGE
- HTTP_REQUEST_URI_TOO_LARGE
- HTTP_UNSUPPORTED_MEDIA_TYPE
- HTTP_RANGE_NOT_SATISFIABLE
-
- HTTP_INTERNAL_SERVER_ERROR
- HTTP_SERVER_ERROR
- HTTP_NOT_IMPLEMENTED
- HTTP_BAD_GATEWAY
- HTTP_SERVICE_UNAVAILABLE
- HTTP_GATEWAY_TIME_OUT
- HTTP_INSUFFICIENT_STORAGE
-);
-
-our $VERSION = '%%VERSION%%';
-
-require XSLoader;
-XSLoader::load('nginx', $VERSION);
-
-# Preloaded methods go here.
-
-use constant OK => 0;
-use constant DECLINED => -5;
-
-use constant HTTP_OK => 200;
-use constant HTTP_CREATED => 201;
-use constant HTTP_ACCEPTED => 202;
-use constant HTTP_NO_CONTENT => 204;
-use constant HTTP_PARTIAL_CONTENT => 206;
-
-use constant HTTP_MOVED_PERMANENTLY => 301;
-use constant HTTP_MOVED_TEMPORARILY => 302;
-use constant HTTP_REDIRECT => 302;
-use constant HTTP_SEE_OTHER => 303;
-use constant HTTP_NOT_MODIFIED => 304;
-use constant HTTP_TEMPORARY_REDIRECT => 307;
-
-use constant HTTP_BAD_REQUEST => 400;
-use constant HTTP_UNAUTHORIZED => 401;
-use constant HTTP_PAYMENT_REQUIRED => 402;
-use constant HTTP_FORBIDDEN => 403;
-use constant HTTP_NOT_FOUND => 404;
-use constant HTTP_NOT_ALLOWED => 405;
-use constant HTTP_NOT_ACCEPTABLE => 406;
-use constant HTTP_REQUEST_TIME_OUT => 408;
-use constant HTTP_CONFLICT => 409;
-use constant HTTP_GONE => 410;
-use constant HTTP_LENGTH_REQUIRED => 411;
-use constant HTTP_REQUEST_ENTITY_TOO_LARGE => 413;
-use constant HTTP_REQUEST_URI_TOO_LARGE => 414;
-use constant HTTP_UNSUPPORTED_MEDIA_TYPE => 415;
-use constant HTTP_RANGE_NOT_SATISFIABLE => 416;
-
-use constant HTTP_INTERNAL_SERVER_ERROR => 500;
-use constant HTTP_SERVER_ERROR => 500;
-use constant HTTP_NOT_IMPLEMENTED => 501;
-use constant HTTP_BAD_GATEWAY => 502;
-use constant HTTP_SERVICE_UNAVAILABLE => 503;
-use constant HTTP_GATEWAY_TIME_OUT => 504;
-use constant HTTP_INSUFFICIENT_STORAGE => 507;
-
-
-sub rflush {
- my $r = shift;
-
- $r->flush;
-}
-
-
-1;
-__END__
-
-=head1 NAME
-
-nginx - Perl interface to the nginx HTTP server API
-
-=head1 SYNOPSIS
-
- use nginx;
-
-=head1 DESCRIPTION
-
-This module provides a Perl interface to the nginx HTTP server API.
-
-
-=head1 SEE ALSO
-
-http://nginx.org/en/docs/http/ngx_http_perl_module.html
-
-=head1 AUTHOR
-
-Igor Sysoev
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright (C) Igor Sysoev
-Copyright (C) Nginx, Inc.
-
-
-=cut
diff --git a/usr.sbin/nginx/src/http/modules/perl/nginx.xs b/usr.sbin/nginx/src/http/modules/perl/nginx.xs
deleted file mode 100644
index 71f17a8bb45..00000000000
--- a/usr.sbin/nginx/src/http/modules/perl/nginx.xs
+++ /dev/null
@@ -1,1038 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#define PERL_NO_GET_CONTEXT
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-#include <ngx_http_perl_module.h>
-
-#include "XSUB.h"
-
-
-#define ngx_http_perl_set_request(r) \
- r = INT2PTR(ngx_http_request_t *, SvIV((SV *) SvRV(ST(0))))
-
-
-#define ngx_http_perl_set_targ(p, len) \
- \
- SvUPGRADE(TARG, SVt_PV); \
- SvPOK_on(TARG); \
- sv_setpvn(TARG, (char *) p, len)
-
-
-static ngx_int_t
-ngx_http_perl_sv2str(pTHX_ ngx_http_request_t *r, ngx_str_t *s, SV *sv)
-{
- u_char *p;
- STRLEN len;
-
- if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) {
- sv = SvRV(sv);
- }
-
- p = (u_char *) SvPV(sv, len);
-
- s->len = len;
-
- if (SvREADONLY(sv) && SvPOK(sv)) {
- s->data = p;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "perl sv2str: %08XD \"%V\"", sv->sv_flags, s);
-
- return NGX_OK;
- }
-
- s->data = ngx_pnalloc(r->pool, len);
- if (s->data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(s->data, p, len);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "perl sv2str: %08XD \"%V\"", sv->sv_flags, s);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_perl_output(ngx_http_request_t *r, ngx_buf_t *b)
-{
- ngx_chain_t out;
-#if (NGX_HTTP_SSI)
- ngx_chain_t *cl;
- ngx_http_perl_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
-
- if (ctx->ssi) {
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- cl->next = NULL;
- *ctx->ssi->last_out = cl;
- ctx->ssi->last_out = &cl->next;
-
- return NGX_OK;
- }
-#endif
-
- out.buf = b;
- out.next = NULL;
-
- return ngx_http_output_filter(r, &out);
-}
-
-
-MODULE = nginx PACKAGE = nginx
-
-
-void
-status(r, code)
- CODE:
-
- ngx_http_request_t *r;
-
- ngx_http_perl_set_request(r);
-
- r->headers_out.status = SvIV(ST(1));
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "perl status: %d", r->headers_out.status);
-
- XSRETURN_UNDEF;
-
-
-void
-send_http_header(r, ...)
- CODE:
-
- ngx_http_request_t *r;
- SV *sv;
-
- ngx_http_perl_set_request(r);
-
- if (r->headers_out.status == 0) {
- r->headers_out.status = NGX_HTTP_OK;
- }
-
- if (items != 1) {
- sv = ST(1);
-
- if (ngx_http_perl_sv2str(aTHX_ r, &r->headers_out.content_type, sv)
- != NGX_OK)
- {
- 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;
- }
- }
-
- (void) ngx_http_send_header(r);
-
-
-void
-header_only(r)
- CODE:
-
- dXSTARG;
- ngx_http_request_t *r;
-
- ngx_http_perl_set_request(r);
-
- sv_upgrade(TARG, SVt_IV);
- sv_setiv(TARG, r->header_only);
-
- ST(0) = TARG;
-
-
-void
-uri(r)
- CODE:
-
- dXSTARG;
- ngx_http_request_t *r;
-
- ngx_http_perl_set_request(r);
- ngx_http_perl_set_targ(r->uri.data, r->uri.len);
-
- ST(0) = TARG;
-
-
-void
-args(r)
- CODE:
-
- dXSTARG;
- ngx_http_request_t *r;
-
- ngx_http_perl_set_request(r);
- ngx_http_perl_set_targ(r->args.data, r->args.len);
-
- ST(0) = TARG;
-
-
-void
-request_method(r)
- CODE:
-
- dXSTARG;
- ngx_http_request_t *r;
-
- ngx_http_perl_set_request(r);
- ngx_http_perl_set_targ(r->method_name.data, r->method_name.len);
-
- ST(0) = TARG;
-
-
-void
-remote_addr(r)
- CODE:
-
- dXSTARG;
- ngx_http_request_t *r;
-
- ngx_http_perl_set_request(r);
- ngx_http_perl_set_targ(r->connection->addr_text.data,
- r->connection->addr_text.len);
-
- ST(0) = TARG;
-
-
-void
-header_in(r, key)
- CODE:
-
- dXSTARG;
- ngx_http_request_t *r;
- SV *key;
- u_char *p, *lowcase_key, *value, sep;
- STRLEN len;
- ssize_t size;
- ngx_uint_t i, n, hash;
- ngx_array_t *a;
- ngx_list_part_t *part;
- ngx_table_elt_t *h, **ph;
- ngx_http_header_t *hh;
- ngx_http_core_main_conf_t *cmcf;
-
- ngx_http_perl_set_request(r);
-
- key = ST(1);
-
- if (SvROK(key) && SvTYPE(SvRV(key)) == SVt_PV) {
- key = SvRV(key);
- }
-
- p = (u_char *) SvPV(key, len);
-
- /* look up hashed headers */
-
- lowcase_key = ngx_pnalloc(r->pool, len);
- if (lowcase_key == NULL) {
- XSRETURN_UNDEF;
- }
-
- hash = ngx_hash_strlow(lowcase_key, p, len);
-
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
- hh = ngx_hash_find(&cmcf->headers_in_hash, hash, lowcase_key, len);
-
- if (hh) {
-
- if (hh->offset == offsetof(ngx_http_headers_in_t, cookies)) {
- sep = ';';
- goto multi;
- }
-#if (NGX_HTTP_X_FORWARDED_FOR)
- if (hh->offset == offsetof(ngx_http_headers_in_t, x_forwarded_for)) {
- sep = ',';
- goto multi;
- }
-#endif
-
- if (hh->offset) {
-
- ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset);
-
- if (*ph) {
- ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len);
-
- goto done;
- }
-
- XSRETURN_UNDEF;
- }
-
- multi:
-
- /* Cookie, X-Forwarded-For */
-
- a = (ngx_array_t *) ((char *) &r->headers_in + hh->offset);
-
- n = a->nelts;
-
- if (n == 0) {
- XSRETURN_UNDEF;
- }
-
- ph = a->elts;
-
- if (n == 1) {
- ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len);
-
- goto done;
- }
-
- size = - (ssize_t) (sizeof("; ") - 1);
-
- for (i = 0; i < n; i++) {
- size += ph[i]->value.len + sizeof("; ") - 1;
- }
-
- value = ngx_pnalloc(r->pool, size);
- if (value == NULL) {
- XSRETURN_UNDEF;
- }
-
- p = value;
-
- for (i = 0; /* void */ ; i++) {
- p = ngx_copy(p, ph[i]->value.data, ph[i]->value.len);
-
- if (i == n - 1) {
- break;
- }
-
- *p++ = sep; *p++ = ' ';
- }
-
- ngx_http_perl_set_targ(value, size);
-
- goto done;
- }
-
- /* iterate over all headers */
-
- part = &r->headers_in.headers.part;
- h = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- h = part->elts;
- i = 0;
- }
-
- if (len != h[i].key.len
- || ngx_strcasecmp(p, h[i].key.data) != 0)
- {
- continue;
- }
-
- ngx_http_perl_set_targ(h[i].value.data, h[i].value.len);
-
- goto done;
- }
-
- XSRETURN_UNDEF;
-
- done:
-
- ST(0) = TARG;
-
-
-void
-has_request_body(r, next)
- CODE:
-
- dXSTARG;
- ngx_http_request_t *r;
- ngx_http_perl_ctx_t *ctx;
-
- ngx_http_perl_set_request(r);
-
- if (r->headers_in.content_length_n <= 0 && !r->headers_in.chunked) {
- XSRETURN_UNDEF;
- }
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
- ctx->next = SvRV(ST(1));
-
- r->request_body_in_single_buf = 1;
- r->request_body_in_persistent_file = 1;
- r->request_body_in_clean_file = 1;
-
- if (r->request_body_in_file_only) {
- r->request_body_file_log_level = 0;
- }
-
- ngx_http_read_client_request_body(r, ngx_http_perl_handle_request);
-
- sv_upgrade(TARG, SVt_IV);
- sv_setiv(TARG, 1);
-
- ST(0) = TARG;
-
-
-void
-request_body(r)
- CODE:
-
- dXSTARG;
- ngx_http_request_t *r;
- u_char *p, *data;
- size_t len;
- ngx_buf_t *buf;
- ngx_chain_t *cl;
-
- ngx_http_perl_set_request(r);
-
- if (r->request_body == NULL
- || r->request_body->temp_file
- || r->request_body->bufs == NULL)
- {
- XSRETURN_UNDEF;
- }
-
- cl = r->request_body->bufs;
- buf = cl->buf;
-
- if (cl->next == NULL) {
- len = buf->last - buf->pos;
- data = buf->pos;
- goto done;
- }
-
- len = buf->last - buf->pos;
- cl = cl->next;
-
- for ( /* void */ ; cl; cl = cl->next) {
- buf = cl->buf;
- len += buf->last - buf->pos;
- }
-
- p = ngx_pnalloc(r->pool, len);
- if (p == NULL) {
- XSRETURN_UNDEF;
- }
-
- data = p;
- cl = r->request_body->bufs;
-
- for ( /* void */ ; cl; cl = cl->next) {
- buf = cl->buf;
- p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
- }
-
- done:
-
- if (len == 0) {
- XSRETURN_UNDEF;
- }
-
- ngx_http_perl_set_targ(data, len);
-
- ST(0) = TARG;
-
-
-void
-request_body_file(r)
- CODE:
-
- dXSTARG;
- ngx_http_request_t *r;
-
- ngx_http_perl_set_request(r);
-
- if (r->request_body == NULL || r->request_body->temp_file == NULL) {
- XSRETURN_UNDEF;
- }
-
- ngx_http_perl_set_targ(r->request_body->temp_file->file.name.data,
- r->request_body->temp_file->file.name.len);
-
- ST(0) = TARG;
-
-
-void
-discard_request_body(r)
- CODE:
-
- ngx_http_request_t *r;
-
- ngx_http_perl_set_request(r);
-
- ngx_http_discard_request_body(r);
-
-
-void
-header_out(r, key, value)
- CODE:
-
- ngx_http_request_t *r;
- SV *key;
- SV *value;
- ngx_table_elt_t *header;
-
- ngx_http_perl_set_request(r);
-
- key = ST(1);
- value = ST(2);
-
- header = ngx_list_push(&r->headers_out.headers);
- if (header == NULL) {
- XSRETURN_EMPTY;
- }
-
- header->hash = 1;
-
- if (ngx_http_perl_sv2str(aTHX_ r, &header->key, key) != NGX_OK) {
- XSRETURN_EMPTY;
- }
-
- if (ngx_http_perl_sv2str(aTHX_ r, &header->value, value) != NGX_OK) {
- XSRETURN_EMPTY;
- }
-
- if (header->key.len == sizeof("Content-Length") - 1
- && ngx_strncasecmp(header->key.data, (u_char *) "Content-Length",
- sizeof("Content-Length") - 1) == 0)
- {
- r->headers_out.content_length_n = (off_t) SvIV(value);
- r->headers_out.content_length = header;
- }
-
- if (header->key.len == sizeof("Content-Encoding") - 1
- && ngx_strncasecmp(header->key.data, (u_char *) "Content-Encoding",
- sizeof("Content-Encoding") - 1) == 0)
- {
- r->headers_out.content_encoding = header;
- }
-
-
-void
-filename(r)
- CODE:
-
- dXSTARG;
- size_t root;
- ngx_http_request_t *r;
- ngx_http_perl_ctx_t *ctx;
-
- ngx_http_perl_set_request(r);
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
- if (ctx->filename.data) {
- goto done;
- }
-
- if (ngx_http_map_uri_to_path(r, &ctx->filename, &root, 0) == NULL) {
- XSRETURN_UNDEF;
- }
-
- ctx->filename.len--;
- sv_setpv(PL_statname, (char *) ctx->filename.data);
-
- done:
-
- ngx_http_perl_set_targ(ctx->filename.data, ctx->filename.len);
-
- ST(0) = TARG;
-
-
-void
-print(r, ...)
- CODE:
-
- ngx_http_request_t *r;
- SV *sv;
- int i;
- u_char *p;
- size_t size;
- STRLEN len;
- ngx_buf_t *b;
-
- ngx_http_perl_set_request(r);
-
- if (items == 2) {
-
- /*
- * do zero copy for prolate single read-only SV:
- * $r->print("some text\n");
- */
-
- sv = ST(1);
-
- if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) {
- sv = SvRV(sv);
- }
-
- if (SvREADONLY(sv) && SvPOK(sv)) {
-
- p = (u_char *) SvPV(sv, len);
-
- if (len == 0) {
- XSRETURN_EMPTY;
- }
-
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- XSRETURN_EMPTY;
- }
-
- b->memory = 1;
- b->pos = p;
- b->last = p + len;
- b->start = p;
- b->end = b->last;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "$r->print: read-only SV: %z", len);
-
- goto out;
- }
- }
-
- size = 0;
-
- for (i = 1; i < items; i++) {
-
- sv = ST(i);
-
- if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) {
- sv = SvRV(sv);
- }
-
- (void) SvPV(sv, len);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "$r->print: copy SV: %z", len);
-
- size += len;
- }
-
- if (size == 0) {
- XSRETURN_EMPTY;
- }
-
- b = ngx_create_temp_buf(r->pool, size);
- if (b == NULL) {
- XSRETURN_EMPTY;
- }
-
- for (i = 1; i < items; i++) {
- sv = ST(i);
-
- if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PV) {
- sv = SvRV(sv);
- }
-
- p = (u_char *) SvPV(sv, len);
- b->last = ngx_cpymem(b->last, p, len);
- }
-
- out:
-
- (void) ngx_http_perl_output(r, b);
-
-
-void
-sendfile(r, filename, offset = -1, bytes = 0)
- CODE:
-
- ngx_http_request_t *r;
- char *filename;
- off_t offset;
- size_t bytes;
- ngx_str_t path;
- ngx_buf_t *b;
- ngx_open_file_info_t of;
- ngx_http_core_loc_conf_t *clcf;
-
- ngx_http_perl_set_request(r);
-
- filename = SvPV_nolen(ST(1));
-
- if (filename == NULL) {
- croak("sendfile(): NULL filename");
- }
-
- offset = items < 3 ? -1 : SvIV(ST(2));
- bytes = items < 4 ? 0 : SvIV(ST(3));
-
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- XSRETURN_EMPTY;
- }
-
- b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
- if (b->file == NULL) {
- XSRETURN_EMPTY;
- }
-
- path.len = ngx_strlen(filename);
-
- path.data = ngx_pnalloc(r->pool, path.len + 1);
- if (path.data == NULL) {
- XSRETURN_EMPTY;
- }
-
- (void) ngx_cpystrn(path.data, (u_char *) filename, path.len + 1);
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- ngx_memzero(&of, sizeof(ngx_open_file_info_t));
-
- of.read_ahead = clcf->read_ahead;
- of.directio = clcf->directio;
- of.valid = clcf->open_file_cache_valid;
- of.min_uses = clcf->open_file_cache_min_uses;
- of.errors = clcf->open_file_cache_errors;
- of.events = clcf->open_file_cache_events;
-
- if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
- XSRETURN_EMPTY;
- }
-
- if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
- != NGX_OK)
- {
- if (of.err == 0) {
- XSRETURN_EMPTY;
- }
-
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
- "%s \"%s\" failed", of.failed, filename);
- XSRETURN_EMPTY;
- }
-
- if (offset == -1) {
- offset = 0;
- }
-
- if (bytes == 0) {
- bytes = of.size - offset;
- }
-
- b->in_file = 1;
-
- b->file_pos = offset;
- b->file_last = offset + bytes;
-
- b->file->fd = of.fd;
- b->file->log = r->connection->log;
- b->file->directio = of.is_directio;
-
- (void) ngx_http_perl_output(r, b);
-
-
-void
-flush(r)
- CODE:
-
- ngx_http_request_t *r;
- ngx_buf_t *b;
-
- ngx_http_perl_set_request(r);
-
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- XSRETURN_EMPTY;
- }
-
- b->flush = 1;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "$r->flush");
-
- (void) ngx_http_perl_output(r, b);
-
- XSRETURN_EMPTY;
-
-
-void
-internal_redirect(r, uri)
- CODE:
-
- ngx_http_request_t *r;
- SV *uri;
- ngx_uint_t i;
- ngx_http_perl_ctx_t *ctx;
-
- ngx_http_perl_set_request(r);
-
- uri = ST(1);
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
-
- if (ngx_http_perl_sv2str(aTHX_ r, &ctx->redirect_uri, uri) != NGX_OK) {
- XSRETURN_EMPTY;
- }
-
- for (i = 0; i < ctx->redirect_uri.len; i++) {
- if (ctx->redirect_uri.data[i] == '?') {
-
- ctx->redirect_args.len = ctx->redirect_uri.len - (i + 1);
- ctx->redirect_args.data = &ctx->redirect_uri.data[i + 1];
- ctx->redirect_uri.len = i;
-
- XSRETURN_EMPTY;
- }
- }
-
-
-void
-allow_ranges(r)
- CODE:
-
- ngx_http_request_t *r;
-
- ngx_http_perl_set_request(r);
-
- r->allow_ranges = 1;
-
-
-void
-unescape(r, text, type = 0)
- CODE:
-
- dXSTARG;
- ngx_http_request_t *r;
- SV *text;
- int type;
- u_char *p, *dst, *src;
- STRLEN len;
-
- ngx_http_perl_set_request(r);
-
- text = ST(1);
-
- src = (u_char *) SvPV(text, len);
-
- p = ngx_pnalloc(r->pool, len + 1);
- if (p == NULL) {
- XSRETURN_UNDEF;
- }
-
- dst = p;
-
- type = items < 3 ? 0 : SvIV(ST(2));
-
- ngx_unescape_uri(&dst, &src, len, (ngx_uint_t) type);
- *dst = '\0';
-
- ngx_http_perl_set_targ(p, dst - p);
-
- ST(0) = TARG;
-
-
-void
-variable(r, name, value = NULL)
- CODE:
-
- dXSTARG;
- ngx_http_request_t *r;
- SV *name, *value;
- u_char *p, *lowcase;
- STRLEN len;
- ngx_str_t var, val;
- ngx_uint_t i, hash;
- ngx_http_perl_var_t *v;
- ngx_http_perl_ctx_t *ctx;
- ngx_http_variable_value_t *vv;
-
- ngx_http_perl_set_request(r);
-
- name = ST(1);
-
- if (SvROK(name) && SvTYPE(SvRV(name)) == SVt_PV) {
- name = SvRV(name);
- }
-
- if (items == 2) {
- value = NULL;
-
- } else {
- value = ST(2);
-
- if (SvROK(value) && SvTYPE(SvRV(value)) == SVt_PV) {
- value = SvRV(value);
- }
-
- if (ngx_http_perl_sv2str(aTHX_ r, &val, value) != NGX_OK) {
- XSRETURN_UNDEF;
- }
- }
-
- p = (u_char *) SvPV(name, len);
-
- lowcase = ngx_pnalloc(r->pool, len);
- if (lowcase == NULL) {
- XSRETURN_UNDEF;
- }
-
- hash = ngx_hash_strlow(lowcase, p, len);
-
- var.len = len;
- var.data = lowcase;
-#if (NGX_DEBUG)
-
- if (value) {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "perl variable: \"%V\"=\"%V\"", &var, &val);
- } else {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "perl variable: \"%V\"", &var);
- }
-#endif
-
- vv = ngx_http_get_variable(r, &var, hash);
- if (vv == NULL) {
- XSRETURN_UNDEF;
- }
-
- if (vv->not_found) {
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
-
- if (ctx->variables) {
-
- v = ctx->variables->elts;
- for (i = 0; i < ctx->variables->nelts; i++) {
-
- if (hash != v[i].hash
- || len != v[i].name.len
- || ngx_strncmp(lowcase, v[i].name.data, len) != 0)
- {
- continue;
- }
-
- if (value) {
- v[i].value = val;
- XSRETURN_UNDEF;
- }
-
- ngx_http_perl_set_targ(v[i].value.data, v[i].value.len);
-
- goto done;
- }
- }
-
- if (value) {
- if (ctx->variables == NULL) {
- ctx->variables = ngx_array_create(r->pool, 1,
- sizeof(ngx_http_perl_var_t));
- if (ctx->variables == NULL) {
- XSRETURN_UNDEF;
- }
- }
-
- v = ngx_array_push(ctx->variables);
- if (v == NULL) {
- XSRETURN_UNDEF;
- }
-
- v->hash = hash;
- v->name.len = len;
- v->name.data = lowcase;
- v->value = val;
-
- XSRETURN_UNDEF;
- }
-
- XSRETURN_UNDEF;
- }
-
- if (value) {
- vv->len = val.len;
- vv->valid = 1;
- vv->no_cacheable = 0;
- vv->not_found = 0;
- vv->data = val.data;
-
- XSRETURN_UNDEF;
- }
-
- ngx_http_perl_set_targ(vv->data, vv->len);
-
- done:
-
- ST(0) = TARG;
-
-
-void
-sleep(r, sleep, next)
- CODE:
-
- ngx_http_request_t *r;
- ngx_msec_t sleep;
- ngx_http_perl_ctx_t *ctx;
-
- ngx_http_perl_set_request(r);
-
- sleep = (ngx_msec_t) SvIV(ST(1));
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "perl sleep: %M", sleep);
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
-
- ctx->next = SvRV(ST(2));
-
- ngx_add_timer(r->connection->write, sleep);
-
- r->write_event_handler = ngx_http_perl_sleep_handler;
- r->main->count++;
-
-
-void
-log_error(r, err, msg)
- CODE:
-
- ngx_http_request_t *r;
- SV *err, *msg;
- u_char *p;
- STRLEN len;
- ngx_err_t e;
-
- ngx_http_perl_set_request(r);
-
- err = ST(1);
-
- if (SvROK(err) && SvTYPE(SvRV(err)) == SVt_PV) {
- err = SvRV(err);
- }
-
- e = SvIV(err);
-
- msg = ST(2);
-
- if (SvROK(msg) && SvTYPE(SvRV(msg)) == SVt_PV) {
- msg = SvRV(msg);
- }
-
- p = (u_char *) SvPV(msg, len);
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, e, "perl: %s", p);
diff --git a/usr.sbin/nginx/src/http/modules/perl/ngx_http_perl_module.c b/usr.sbin/nginx/src/http/modules/perl/ngx_http_perl_module.c
deleted file mode 100644
index bf4d1fe9ad7..00000000000
--- a/usr.sbin/nginx/src/http/modules/perl/ngx_http_perl_module.c
+++ /dev/null
@@ -1,1076 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-#include <ngx_http_perl_module.h>
-
-
-typedef struct {
- PerlInterpreter *perl;
- HV *nginx;
- ngx_array_t *modules;
- ngx_array_t *requires;
-} ngx_http_perl_main_conf_t;
-
-
-typedef struct {
- SV *sub;
- ngx_str_t handler;
-} ngx_http_perl_loc_conf_t;
-
-
-typedef struct {
- SV *sub;
- ngx_str_t handler;
-} ngx_http_perl_variable_t;
-
-
-#if (NGX_HTTP_SSI)
-static ngx_int_t ngx_http_perl_ssi(ngx_http_request_t *r,
- ngx_http_ssi_ctx_t *ssi_ctx, ngx_str_t **params);
-#endif
-
-static char *ngx_http_perl_init_interpreter(ngx_conf_t *cf,
- ngx_http_perl_main_conf_t *pmcf);
-static PerlInterpreter *ngx_http_perl_create_interpreter(ngx_conf_t *cf,
- ngx_http_perl_main_conf_t *pmcf);
-static ngx_int_t ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires,
- ngx_log_t *log);
-static ngx_int_t ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r,
- HV *nginx, SV *sub, SV **args, ngx_str_t *handler, ngx_str_t *rv);
-static void ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv);
-
-static ngx_int_t ngx_http_perl_preconfiguration(ngx_conf_t *cf);
-static void *ngx_http_perl_create_main_conf(ngx_conf_t *cf);
-static char *ngx_http_perl_init_main_conf(ngx_conf_t *cf, void *conf);
-static void *ngx_http_perl_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_perl_merge_loc_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static char *ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-
-#if (NGX_HAVE_PERL_MULTIPLICITY)
-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);
-
-
-static ngx_command_t ngx_http_perl_commands[] = {
-
- { ngx_string("perl_modules"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_array_slot,
- NGX_HTTP_MAIN_CONF_OFFSET,
- offsetof(ngx_http_perl_main_conf_t, modules),
- NULL },
-
- { ngx_string("perl_require"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_array_slot,
- NGX_HTTP_MAIN_CONF_OFFSET,
- offsetof(ngx_http_perl_main_conf_t, requires),
- NULL },
-
- { ngx_string("perl"),
- NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
- ngx_http_perl,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("perl_set"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE2,
- ngx_http_perl_set,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_perl_module_ctx = {
- ngx_http_perl_preconfiguration, /* preconfiguration */
- NULL, /* postconfiguration */
-
- ngx_http_perl_create_main_conf, /* create main configuration */
- ngx_http_perl_init_main_conf, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_perl_create_loc_conf, /* create location configuration */
- ngx_http_perl_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_perl_module = {
- NGX_MODULE_V1,
- &ngx_http_perl_module_ctx, /* module context */
- ngx_http_perl_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- ngx_http_perl_init_worker, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- ngx_http_perl_exit, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-#if (NGX_HTTP_SSI)
-
-#define NGX_HTTP_PERL_SSI_SUB 0
-#define NGX_HTTP_PERL_SSI_ARG 1
-
-
-static ngx_http_ssi_param_t ngx_http_perl_ssi_params[] = {
- { ngx_string("sub"), NGX_HTTP_PERL_SSI_SUB, 1, 0 },
- { ngx_string("arg"), NGX_HTTP_PERL_SSI_ARG, 0, 1 },
- { ngx_null_string, 0, 0, 0 }
-};
-
-static ngx_http_ssi_command_t ngx_http_perl_ssi_command = {
- ngx_string("perl"), ngx_http_perl_ssi, ngx_http_perl_ssi_params, 0, 0, 1
-};
-
-#endif
-
-
-static ngx_str_t ngx_null_name = ngx_null_string;
-static HV *nginx_stash;
-
-#if (NGX_HAVE_PERL_MULTIPLICITY)
-static ngx_uint_t ngx_perl_term;
-#else
-static PerlInterpreter *perl;
-#endif
-
-
-static void
-ngx_http_perl_xs_init(pTHX)
-{
- newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, __FILE__);
-
- nginx_stash = gv_stashpv("nginx", TRUE);
-}
-
-
-static ngx_int_t
-ngx_http_perl_handler(ngx_http_request_t *r)
-{
- r->main->count++;
-
- ngx_http_perl_handle_request(r);
-
- return NGX_DONE;
-}
-
-
-void
-ngx_http_perl_handle_request(ngx_http_request_t *r)
-{
- SV *sub;
- ngx_int_t rc;
- ngx_str_t uri, args, *handler;
- ngx_http_perl_ctx_t *ctx;
- ngx_http_perl_loc_conf_t *plcf;
- ngx_http_perl_main_conf_t *pmcf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl handler");
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
-
- if (ctx == NULL) {
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_perl_ctx_t));
- if (ctx == NULL) {
- ngx_http_finalize_request(r, NGX_ERROR);
- return;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_perl_module);
- }
-
- pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module);
-
- {
-
- dTHXa(pmcf->perl);
- PERL_SET_CONTEXT(pmcf->perl);
-
- if (ctx->next == NULL) {
- plcf = ngx_http_get_module_loc_conf(r, ngx_http_perl_module);
- sub = plcf->sub;
- handler = &plcf->handler;
-
- } else {
- sub = ctx->next;
- handler = &ngx_null_name;
- ctx->next = NULL;
- }
-
- rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sub, NULL, handler,
- NULL);
-
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "perl handler done: %i", rc);
-
- if (rc == NGX_DONE) {
- ngx_http_finalize_request(r, rc);
- return;
- }
-
- if (rc > 600) {
- rc = NGX_OK;
- }
-
- if (ctx->redirect_uri.len) {
- uri = ctx->redirect_uri;
- args = ctx->redirect_args;
-
- } else {
- uri.len = 0;
- }
-
- ctx->filename.data = NULL;
- ctx->redirect_uri.len = 0;
-
- if (ctx->done || ctx->next) {
- ngx_http_finalize_request(r, NGX_DONE);
- return;
- }
-
- if (uri.len) {
- ngx_http_internal_redirect(r, &uri, &args);
- ngx_http_finalize_request(r, NGX_DONE);
- return;
- }
-
- if (rc == NGX_OK || rc == NGX_HTTP_OK) {
- ngx_http_send_special(r, NGX_HTTP_LAST);
- ctx->done = 1;
- }
-
- ngx_http_finalize_request(r, rc);
-}
-
-
-void
-ngx_http_perl_sleep_handler(ngx_http_request_t *r)
-{
- ngx_event_t *wev;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "perl sleep handler");
-
- wev = r->connection->write;
-
- if (wev->timedout) {
- wev->timedout = 0;
- ngx_http_perl_handle_request(r);
- return;
- }
-
- if (ngx_handle_write_event(wev, 0) != NGX_OK) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- }
-}
-
-
-static ngx_int_t
-ngx_http_perl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- ngx_http_perl_variable_t *pv = (ngx_http_perl_variable_t *) data;
-
- ngx_int_t rc;
- ngx_str_t value;
- ngx_http_perl_ctx_t *ctx;
- ngx_http_perl_main_conf_t *pmcf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "perl variable handler");
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
-
- if (ctx == NULL) {
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_perl_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_perl_module);
- }
-
- pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module);
-
- value.data = NULL;
-
- {
-
- dTHXa(pmcf->perl);
- PERL_SET_CONTEXT(pmcf->perl);
-
- rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, pv->sub, NULL,
- &pv->handler, &value);
-
- }
-
- if (value.data) {
- v->len = value.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = value.data;
-
- } else {
- v->not_found = 1;
- }
-
- ctx->filename.data = NULL;
- ctx->redirect_uri.len = 0;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "perl variable done");
-
- return rc;
-}
-
-
-#if (NGX_HTTP_SSI)
-
-static ngx_int_t
-ngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ssi_ctx,
- ngx_str_t **params)
-{
- SV *sv, **asv;
- ngx_int_t rc;
- ngx_str_t *handler, **args;
- ngx_uint_t i;
- ngx_http_perl_ctx_t *ctx;
- ngx_http_perl_main_conf_t *pmcf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "perl ssi handler");
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);
-
- if (ctx == NULL) {
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_perl_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_perl_module);
- }
-
- pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module);
-
- ctx->ssi = ssi_ctx;
-
- handler = params[NGX_HTTP_PERL_SSI_SUB];
- handler->data[handler->len] = '\0';
-
- {
-
- dTHXa(pmcf->perl);
- PERL_SET_CONTEXT(pmcf->perl);
-
-#if 0
-
- /* the code is disabled to force the precompiled perl code using only */
-
- ngx_http_perl_eval_anon_sub(aTHX_ handler, &sv);
-
- if (sv == &PL_sv_undef) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "eval_pv(\"%V\") failed", handler);
- return NGX_ERROR;
- }
-
- if (sv == NULL) {
- sv = newSVpvn((char *) handler->data, handler->len);
- }
-
-#endif
-
- sv = newSVpvn((char *) handler->data, handler->len);
-
- args = &params[NGX_HTTP_PERL_SSI_ARG];
-
- if (args) {
-
- for (i = 0; args[i]; i++) { /* void */ }
-
- asv = ngx_pcalloc(r->pool, (i + 1) * sizeof(SV *));
-
- if (asv == NULL) {
- SvREFCNT_dec(sv);
- return NGX_ERROR;
- }
-
- asv[0] = (SV *) (uintptr_t) i;
-
- for (i = 0; args[i]; i++) {
- asv[i + 1] = newSVpvn((char *) args[i]->data, args[i]->len);
- }
-
- } else {
- asv = NULL;
- }
-
- rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sv, asv, handler,
- NULL);
-
- SvREFCNT_dec(sv);
-
- }
-
- ctx->filename.data = NULL;
- ctx->redirect_uri.len = 0;
- ctx->ssi = NULL;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl ssi done");
-
- return rc;
-}
-
-#endif
-
-
-static char *
-ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
-{
- ngx_str_t *m;
- ngx_uint_t i;
-#if (NGX_HAVE_PERL_MULTIPLICITY)
- ngx_pool_cleanup_t *cln;
-
- cln = ngx_pool_cleanup_add(cf->pool, 0);
- if (cln == NULL) {
- return NGX_CONF_ERROR;
- }
-
-#endif
-
-#ifdef NGX_PERL_MODULES
- if (pmcf->modules == NGX_CONF_UNSET_PTR) {
-
- pmcf->modules = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
- if (pmcf->modules == NULL) {
- return NGX_CONF_ERROR;
- }
-
- m = ngx_array_push(pmcf->modules);
- if (m == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_str_set(m, NGX_PERL_MODULES);
- }
-#endif
-
- if (pmcf->modules != NGX_CONF_UNSET_PTR) {
- m = pmcf->modules->elts;
- for (i = 0; i < pmcf->modules->nelts; i++) {
- if (ngx_conf_full_name(cf->cycle, &m[i], 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
- }
-
-#if !(NGX_HAVE_PERL_MULTIPLICITY)
-
- if (perl) {
-
- if (ngx_set_environment(cf->cycle, NULL) == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- pmcf->perl = perl;
- pmcf->nginx = nginx_stash;
-
- return NGX_CONF_OK;
- }
-
-#endif
-
- if (nginx_stash == NULL) {
- PERL_SYS_INIT(&ngx_argc, &ngx_argv);
- }
-
- pmcf->perl = ngx_http_perl_create_interpreter(cf, pmcf);
-
- if (pmcf->perl == NULL) {
- return NGX_CONF_ERROR;
- }
-
- pmcf->nginx = nginx_stash;
-
-#if (NGX_HAVE_PERL_MULTIPLICITY)
-
- cln->handler = ngx_http_perl_cleanup_perl;
- cln->data = pmcf->perl;
-
-#else
-
- perl = pmcf->perl;
-
-#endif
-
- return NGX_CONF_OK;
-}
-
-
-static PerlInterpreter *
-ngx_http_perl_create_interpreter(ngx_conf_t *cf,
- ngx_http_perl_main_conf_t *pmcf)
-{
- int n;
- STRLEN len;
- SV *sv;
- char *ver, **embedding;
- ngx_str_t *m;
- ngx_uint_t i;
- PerlInterpreter *perl;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "create perl interpreter");
-
- if (ngx_set_environment(cf->cycle, NULL) == NULL) {
- return NULL;
- }
-
- perl = perl_alloc();
- if (perl == NULL) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, 0, "perl_alloc() failed");
- return NULL;
- }
-
- {
-
- dTHXa(perl);
- PERL_SET_CONTEXT(perl);
-
- perl_construct(perl);
-
-#ifdef PERL_EXIT_DESTRUCT_END
- PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
-#endif
-
- n = (pmcf->modules != NGX_CONF_UNSET_PTR) ? pmcf->modules->nelts * 2 : 0;
-
- embedding = ngx_palloc(cf->pool, (4 + n) * sizeof(char *));
- if (embedding == NULL) {
- goto fail;
- }
-
- embedding[0] = "";
-
- if (n++) {
- m = pmcf->modules->elts;
- for (i = 0; i < pmcf->modules->nelts; i++) {
- embedding[2 * i + 1] = "-I";
- embedding[2 * i + 2] = (char *) m[i].data;
- }
- }
-
- embedding[n++] = "-Mnginx";
- embedding[n++] = "-e";
- embedding[n++] = "0";
-
- n = perl_parse(perl, ngx_http_perl_xs_init, n, embedding, NULL);
-
- if (n != 0) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, 0, "perl_parse() failed: %d", n);
- goto fail;
- }
-
- sv = get_sv("nginx::VERSION", FALSE);
- ver = SvPV(sv, len);
-
- if (ngx_strcmp(ver, NGINX_VERSION) != 0) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
- "version " NGINX_VERSION " of nginx.pm is required, "
- "but %s was found", ver);
- goto fail;
- }
-
- if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log) != NGX_OK) {
- goto fail;
- }
-
- }
-
- return perl;
-
-fail:
-
- (void) perl_destruct(perl);
-
- perl_free(perl);
-
- return NULL;
-}
-
-
-static ngx_int_t
-ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log)
-{
- u_char *err;
- STRLEN len;
- ngx_str_t *script;
- ngx_uint_t i;
-
- if (requires == NGX_CONF_UNSET_PTR) {
- return NGX_OK;
- }
-
- script = requires->elts;
- for (i = 0; i < requires->nelts; i++) {
-
- require_pv((char *) script[i].data);
-
- if (SvTRUE(ERRSV)) {
-
- err = (u_char *) SvPV(ERRSV, len);
- while (--len && (err[len] == CR || err[len] == LF)) { /* void */ }
-
- ngx_log_error(NGX_LOG_EMERG, log, 0,
- "require_pv(\"%s\") failed: \"%*s\"",
- script[i].data, len + 1, err);
-
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, HV *nginx, SV *sub,
- SV **args, ngx_str_t *handler, ngx_str_t *rv)
-{
- SV *sv;
- int n, status;
- char *line;
- u_char *err;
- STRLEN len, n_a;
- ngx_uint_t i;
- ngx_connection_t *c;
-
- dSP;
-
- status = 0;
-
- ENTER;
- SAVETMPS;
-
- PUSHMARK(sp);
-
- sv = sv_2mortal(sv_bless(newRV_noinc(newSViv(PTR2IV(r))), nginx));
- XPUSHs(sv);
-
- if (args) {
- EXTEND(sp, (intptr_t) args[0]);
-
- for (i = 1; i <= (uintptr_t) args[0]; i++) {
- PUSHs(sv_2mortal(args[i]));
- }
- }
-
- PUTBACK;
-
- c = r->connection;
-
- n = call_sv(sub, G_EVAL);
-
- SPAGAIN;
-
- if (n) {
- if (rv == NULL) {
- status = POPi;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "call_sv: %d", status);
-
- } else {
- line = SvPVx(POPs, n_a);
- rv->len = n_a;
-
- rv->data = ngx_pnalloc(r->pool, n_a);
- if (rv->data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(rv->data, line, n_a);
- }
- }
-
- PUTBACK;
-
- FREETMPS;
- LEAVE;
-
- /* check $@ */
-
- if (SvTRUE(ERRSV)) {
-
- err = (u_char *) SvPV(ERRSV, len);
- while (--len && (err[len] == CR || err[len] == LF)) { /* void */ }
-
- ngx_log_error(NGX_LOG_ERR, c->log, 0,
- "call_sv(\"%V\") failed: \"%*s\"", handler, len + 1, err);
-
- if (rv) {
- return NGX_ERROR;
- }
-
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (n != 1) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "call_sv(\"%V\") returned %d results", handler, n);
- status = NGX_OK;
- }
-
- if (rv) {
- return NGX_OK;
- }
-
- return (ngx_int_t) status;
-}
-
-
-static void
-ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv)
-{
- u_char *p;
-
- for (p = handler->data; *p; p++) {
- if (*p != ' ' && *p != '\t' && *p != CR && *p != LF) {
- break;
- }
- }
-
- if (ngx_strncmp(p, "sub ", 4) == 0
- || ngx_strncmp(p, "sub{", 4) == 0
- || ngx_strncmp(p, "use ", 4) == 0)
- {
- *sv = eval_pv((char *) p, FALSE);
-
- /* eval_pv() does not set ERRSV on failure */
-
- return;
- }
-
- *sv = NULL;
-}
-
-
-static void *
-ngx_http_perl_create_main_conf(ngx_conf_t *cf)
-{
- ngx_http_perl_main_conf_t *pmcf;
-
- pmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_main_conf_t));
- if (pmcf == NULL) {
- return NULL;
- }
-
- pmcf->modules = NGX_CONF_UNSET_PTR;
- pmcf->requires = NGX_CONF_UNSET_PTR;
-
- return pmcf;
-}
-
-
-static char *
-ngx_http_perl_init_main_conf(ngx_conf_t *cf, void *conf)
-{
- ngx_http_perl_main_conf_t *pmcf = conf;
-
- if (pmcf->perl == NULL) {
- if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- return NGX_CONF_OK;
-}
-
-
-#if (NGX_HAVE_PERL_MULTIPLICITY)
-
-static void
-ngx_http_perl_cleanup_perl(void *data)
-{
- PerlInterpreter *perl = data;
-
- PERL_SET_CONTEXT(perl);
-
- (void) perl_destruct(perl);
-
- perl_free(perl);
-
- if (ngx_perl_term) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "perl term");
-
- PERL_SYS_TERM();
- }
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_perl_preconfiguration(ngx_conf_t *cf)
-{
-#if (NGX_HTTP_SSI)
- ngx_int_t rc;
- ngx_http_ssi_main_conf_t *smcf;
-
- smcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_ssi_filter_module);
-
- rc = ngx_hash_add_key(&smcf->commands, &ngx_http_perl_ssi_command.name,
- &ngx_http_perl_ssi_command, NGX_HASH_READONLY_KEY);
-
- if (rc != NGX_OK) {
- if (rc == NGX_BUSY) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "conflicting SSI command \"%V\"",
- &ngx_http_perl_ssi_command.name);
- }
-
- return NGX_ERROR;
- }
-#endif
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_perl_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_perl_loc_conf_t *plcf;
-
- plcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_loc_conf_t));
- if (plcf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * plcf->handler = { 0, NULL };
- */
-
- return plcf;
-}
-
-
-static char *
-ngx_http_perl_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_perl_loc_conf_t *prev = parent;
- ngx_http_perl_loc_conf_t *conf = child;
-
- if (conf->sub == NULL) {
- conf->sub = prev->sub;
- conf->handler = prev->handler;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_perl_loc_conf_t *plcf = conf;
-
- ngx_str_t *value;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_perl_main_conf_t *pmcf;
-
- value = cf->args->elts;
-
- if (plcf->handler.data) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate perl handler \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- pmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_perl_module);
-
- if (pmcf->perl == NULL) {
- if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- plcf->handler = value[1];
-
- {
-
- dTHXa(pmcf->perl);
- PERL_SET_CONTEXT(pmcf->perl);
-
- ngx_http_perl_eval_anon_sub(aTHX_ &value[1], &plcf->sub);
-
- if (plcf->sub == &PL_sv_undef) {
- ngx_conf_log_error(NGX_LOG_ERR, cf, 0,
- "eval_pv(\"%V\") failed", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- if (plcf->sub == NULL) {
- plcf->sub = newSVpvn((char *) value[1].data, value[1].len);
- }
-
- }
-
- clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
- clcf->handler = ngx_http_perl_handler;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_int_t index;
- ngx_str_t *value;
- ngx_http_variable_t *v;
- ngx_http_perl_variable_t *pv;
- ngx_http_perl_main_conf_t *pmcf;
-
- value = cf->args->elts;
-
- if (value[1].data[0] != '$') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid variable name \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- value[1].len--;
- value[1].data++;
-
- v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE);
- if (v == NULL) {
- return NGX_CONF_ERROR;
- }
-
- pv = ngx_palloc(cf->pool, sizeof(ngx_http_perl_variable_t));
- if (pv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- index = ngx_http_get_variable_index(cf, &value[1]);
- if (index == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- pmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_perl_module);
-
- if (pmcf->perl == NULL) {
- if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- pv->handler = value[2];
-
- {
-
- dTHXa(pmcf->perl);
- PERL_SET_CONTEXT(pmcf->perl);
-
- ngx_http_perl_eval_anon_sub(aTHX_ &value[2], &pv->sub);
-
- if (pv->sub == &PL_sv_undef) {
- ngx_conf_log_error(NGX_LOG_ERR, cf, 0,
- "eval_pv(\"%V\") failed", &value[2]);
- return NGX_CONF_ERROR;
- }
-
- if (pv->sub == NULL) {
- pv->sub = newSVpvn((char *) value[2].data, value[2].len);
- }
-
- }
-
- v->get_handler = ngx_http_perl_variable;
- v->data = (uintptr_t) pv;
-
- return NGX_CONF_OK;
-}
-
-
-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);
-
- if (pmcf) {
- 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)
-{
-#if (NGX_HAVE_PERL_MULTIPLICITY)
-
- /*
- * the master exit hook is run before global pool cleanup,
- * therefore just set flag here
- */
-
- ngx_perl_term = 1;
-
-#else
-
- if (nginx_stash) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cycle->log, 0, "perl term");
-
- (void) perl_destruct(perl);
-
- perl_free(perl);
-
- PERL_SYS_TERM();
- }
-
-#endif
-}
diff --git a/usr.sbin/nginx/src/http/modules/perl/ngx_http_perl_module.h b/usr.sbin/nginx/src/http/modules/perl/ngx_http_perl_module.h
deleted file mode 100644
index 5e60b031ec2..00000000000
--- a/usr.sbin/nginx/src/http/modules/perl/ngx_http_perl_module.h
+++ /dev/null
@@ -1,67 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HTTP_PERL_MODULE_H_INCLUDED_
-#define _NGX_HTTP_PERL_MODULE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-#include <nginx.h>
-
-#include <EXTERN.h>
-#include <perl.h>
-
-
-typedef ngx_http_request_t *nginx;
-
-typedef struct {
- ngx_str_t filename;
- ngx_str_t redirect_uri;
- ngx_str_t redirect_args;
-
- SV *next;
-
- ngx_uint_t done; /* unsigned done:1; */
-
- ngx_array_t *variables; /* array of ngx_http_perl_var_t */
-
-#if (NGX_HTTP_SSI)
- ngx_http_ssi_ctx_t *ssi;
-#endif
-} ngx_http_perl_ctx_t;
-
-
-typedef struct {
- ngx_uint_t hash;
- ngx_str_t name;
- ngx_str_t value;
-} ngx_http_perl_var_t;
-
-
-extern ngx_module_t ngx_http_perl_module;
-
-
-/*
- * workaround for "unused variable `Perl___notused'" warning
- * when building with perl 5.6.1
- */
-#ifndef PERL_IMPLICIT_CONTEXT
-#undef dTHXa
-#define dTHXa(a)
-#endif
-
-
-extern void boot_DynaLoader(pTHX_ CV* cv);
-
-
-void ngx_http_perl_handle_request(ngx_http_request_t *r);
-void ngx_http_perl_sleep_handler(ngx_http_request_t *r);
-
-
-#endif /* _NGX_HTTP_PERL_MODULE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/modules/perl/typemap b/usr.sbin/nginx/src/http/modules/perl/typemap
deleted file mode 100644
index e2f1a4c6af6..00000000000
--- a/usr.sbin/nginx/src/http/modules/perl/typemap
+++ /dev/null
@@ -1,3 +0,0 @@
-TYPEMAP
-
-nginx T_PTROBJ
diff --git a/usr.sbin/nginx/src/http/ngx_http.c b/usr.sbin/nginx/src/http/ngx_http.c
deleted file mode 100644
index ce5adb7374a..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http.c
+++ /dev/null
@@ -1,2118 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static ngx_int_t ngx_http_init_phases(ngx_conf_t *cf,
- ngx_http_core_main_conf_t *cmcf);
-static ngx_int_t ngx_http_init_headers_in_hash(ngx_conf_t *cf,
- ngx_http_core_main_conf_t *cmcf);
-static ngx_int_t ngx_http_init_phase_handlers(ngx_conf_t *cf,
- ngx_http_core_main_conf_t *cmcf);
-
-static ngx_int_t ngx_http_add_addresses(ngx_conf_t *cf,
- ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port,
- ngx_http_listen_opt_t *lsopt);
-static ngx_int_t ngx_http_add_address(ngx_conf_t *cf,
- ngx_http_core_srv_conf_t *cscf, ngx_http_conf_port_t *port,
- ngx_http_listen_opt_t *lsopt);
-static ngx_int_t ngx_http_add_server(ngx_conf_t *cf,
- ngx_http_core_srv_conf_t *cscf, ngx_http_conf_addr_t *addr);
-
-static char *ngx_http_merge_servers(ngx_conf_t *cf,
- ngx_http_core_main_conf_t *cmcf, ngx_http_module_t *module,
- ngx_uint_t ctx_index);
-static char *ngx_http_merge_locations(ngx_conf_t *cf,
- ngx_queue_t *locations, void **loc_conf, ngx_http_module_t *module,
- ngx_uint_t ctx_index);
-static ngx_int_t ngx_http_init_locations(ngx_conf_t *cf,
- ngx_http_core_srv_conf_t *cscf, ngx_http_core_loc_conf_t *pclcf);
-static ngx_int_t ngx_http_init_static_location_trees(ngx_conf_t *cf,
- ngx_http_core_loc_conf_t *pclcf);
-static ngx_int_t ngx_http_cmp_locations(const ngx_queue_t *one,
- const ngx_queue_t *two);
-static ngx_int_t ngx_http_join_exact_locations(ngx_conf_t *cf,
- ngx_queue_t *locations);
-static void ngx_http_create_locations_list(ngx_queue_t *locations,
- ngx_queue_t *q);
-static ngx_http_location_tree_node_t *
- ngx_http_create_locations_tree(ngx_conf_t *cf, ngx_queue_t *locations,
- size_t prefix);
-
-static ngx_int_t ngx_http_optimize_servers(ngx_conf_t *cf,
- ngx_http_core_main_conf_t *cmcf, ngx_array_t *ports);
-static ngx_int_t ngx_http_server_names(ngx_conf_t *cf,
- ngx_http_core_main_conf_t *cmcf, ngx_http_conf_addr_t *addr);
-static ngx_int_t ngx_http_cmp_conf_addrs(const void *one, const void *two);
-static int ngx_libc_cdecl ngx_http_cmp_dns_wildcards(const void *one,
- const void *two);
-
-static ngx_int_t ngx_http_init_listening(ngx_conf_t *cf,
- ngx_http_conf_port_t *port);
-static ngx_listening_t *ngx_http_add_listening(ngx_conf_t *cf,
- ngx_http_conf_addr_t *addr);
-static ngx_int_t ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport,
- ngx_http_conf_addr_t *addr);
-#if (NGX_HAVE_INET6)
-static ngx_int_t ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport,
- ngx_http_conf_addr_t *addr);
-#endif
-
-ngx_uint_t ngx_http_max_module;
-
-
-ngx_int_t (*ngx_http_top_header_filter) (ngx_http_request_t *r);
-ngx_int_t (*ngx_http_top_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
-
-
-ngx_str_t ngx_http_html_default_types[] = {
- ngx_string("text/html"),
- ngx_null_string
-};
-
-
-static ngx_command_t ngx_http_commands[] = {
-
- { ngx_string("http"),
- NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
- ngx_http_block,
- 0,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_core_module_t ngx_http_module_ctx = {
- ngx_string("http"),
- NULL,
- NULL
-};
-
-
-ngx_module_t ngx_http_module = {
- NGX_MODULE_V1,
- &ngx_http_module_ctx, /* module context */
- ngx_http_commands, /* module directives */
- NGX_CORE_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static char *
-ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *rv;
- ngx_uint_t mi, m, s;
- ngx_conf_t pcf;
- ngx_http_module_t *module;
- ngx_http_conf_ctx_t *ctx;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_core_srv_conf_t **cscfp;
- ngx_http_core_main_conf_t *cmcf;
-
- /* the main http context */
-
- ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *(ngx_http_conf_ctx_t **) conf = ctx;
-
-
- /* count the number of the http modules and set up their indices */
-
- ngx_http_max_module = 0;
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
- continue;
- }
-
- ngx_modules[m]->ctx_index = ngx_http_max_module++;
- }
-
-
- /* the http main_conf context, it is the same in the all http contexts */
-
- ctx->main_conf = ngx_pcalloc(cf->pool,
- sizeof(void *) * ngx_http_max_module);
- if (ctx->main_conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
-
- /*
- * the http null srv_conf context, it is used to merge
- * the server{}s' srv_conf's
- */
-
- ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
- if (ctx->srv_conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
-
- /*
- * the http null loc_conf context, it is used to merge
- * the server{}s' loc_conf's
- */
-
- ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
- if (ctx->loc_conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
-
- /*
- * create the main_conf's, the null srv_conf's, and the null loc_conf's
- * of the all http modules
- */
-
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
- continue;
- }
-
- module = ngx_modules[m]->ctx;
- mi = ngx_modules[m]->ctx_index;
-
- if (module->create_main_conf) {
- ctx->main_conf[mi] = module->create_main_conf(cf);
- if (ctx->main_conf[mi] == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- if (module->create_srv_conf) {
- ctx->srv_conf[mi] = module->create_srv_conf(cf);
- if (ctx->srv_conf[mi] == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- if (module->create_loc_conf) {
- ctx->loc_conf[mi] = module->create_loc_conf(cf);
- if (ctx->loc_conf[mi] == NULL) {
- return NGX_CONF_ERROR;
- }
- }
- }
-
- pcf = *cf;
- cf->ctx = ctx;
-
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
- continue;
- }
-
- module = ngx_modules[m]->ctx;
-
- if (module->preconfiguration) {
- if (module->preconfiguration(cf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
- }
-
- /* parse inside the http{} block */
-
- cf->module_type = NGX_HTTP_MODULE;
- cf->cmd_type = NGX_HTTP_MAIN_CONF;
- rv = ngx_conf_parse(cf, NULL);
-
- if (rv != NGX_CONF_OK) {
- goto failed;
- }
-
- /*
- * init http{} main_conf's, merge the server{}s' srv_conf's
- * and its location{}s' loc_conf's
- */
-
- cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
- cscfp = cmcf->servers.elts;
-
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
- continue;
- }
-
- module = ngx_modules[m]->ctx;
- mi = ngx_modules[m]->ctx_index;
-
- /* init http{} main_conf's */
-
- if (module->init_main_conf) {
- rv = module->init_main_conf(cf, ctx->main_conf[mi]);
- if (rv != NGX_CONF_OK) {
- goto failed;
- }
- }
-
- rv = ngx_http_merge_servers(cf, cmcf, module, mi);
- if (rv != NGX_CONF_OK) {
- goto failed;
- }
- }
-
-
- /* create location trees */
-
- for (s = 0; s < cmcf->servers.nelts; s++) {
-
- clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
-
- if (ngx_http_init_locations(cf, cscfp[s], clcf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (ngx_http_init_static_location_trees(cf, clcf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
-
- if (ngx_http_init_phases(cf, cmcf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (ngx_http_init_headers_in_hash(cf, cmcf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
-
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
- continue;
- }
-
- module = ngx_modules[m]->ctx;
-
- if (module->postconfiguration) {
- if (module->postconfiguration(cf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
- }
-
- if (ngx_http_variables_init_vars(cf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- /*
- * http{}'s cf->ctx was needed while the configuration merging
- * and in postconfiguration process
- */
-
- *cf = pcf;
-
-
- if (ngx_http_init_phase_handlers(cf, cmcf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
-
- /* optimize the lists of ports, addresses and server names */
-
- if (ngx_http_optimize_servers(cf, cmcf, cmcf->ports) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-
-failed:
-
- *cf = pcf;
-
- return rv;
-}
-
-
-static ngx_int_t
-ngx_http_init_phases(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
-{
- if (ngx_array_init(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers,
- cf->pool, 1, sizeof(ngx_http_handler_pt))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers,
- cf->pool, 1, sizeof(ngx_http_handler_pt))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers,
- cf->pool, 1, sizeof(ngx_http_handler_pt))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers,
- cf->pool, 1, sizeof(ngx_http_handler_pt))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers,
- cf->pool, 2, sizeof(ngx_http_handler_pt))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers,
- cf->pool, 4, sizeof(ngx_http_handler_pt))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers,
- cf->pool, 1, sizeof(ngx_http_handler_pt))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_init_headers_in_hash(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
-{
- ngx_array_t headers_in;
- ngx_hash_key_t *hk;
- ngx_hash_init_t hash;
- ngx_http_header_t *header;
-
- if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- for (header = ngx_http_headers_in; header->name.len; header++) {
- hk = ngx_array_push(&headers_in);
- if (hk == NULL) {
- return NGX_ERROR;
- }
-
- hk->key = header->name;
- hk->key_hash = ngx_hash_key_lc(header->name.data, header->name.len);
- hk->value = header;
- }
-
- hash.hash = &cmcf->headers_in_hash;
- hash.key = ngx_hash_key_lc;
- hash.max_size = 512;
- hash.bucket_size = ngx_align(64, ngx_cacheline_size);
- hash.name = "headers_in_hash";
- hash.pool = cf->pool;
- hash.temp_pool = NULL;
-
- if (ngx_hash_init(&hash, headers_in.elts, headers_in.nelts) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_init_phase_handlers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
-{
- ngx_int_t j;
- ngx_uint_t i, n;
- ngx_uint_t find_config_index, use_rewrite, use_access;
- ngx_http_handler_pt *h;
- ngx_http_phase_handler_t *ph;
- ngx_http_phase_handler_pt checker;
-
- 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;
-
- n = use_rewrite + use_access + cmcf->try_files + 1 /* find config phase */;
-
- for (i = 0; i < NGX_HTTP_LOG_PHASE; i++) {
- n += cmcf->phases[i].handlers.nelts;
- }
-
- ph = ngx_pcalloc(cf->pool,
- n * sizeof(ngx_http_phase_handler_t) + sizeof(void *));
- if (ph == NULL) {
- return NGX_ERROR;
- }
-
- cmcf->phase_engine.handlers = ph;
- n = 0;
-
- for (i = 0; i < NGX_HTTP_LOG_PHASE; i++) {
- h = cmcf->phases[i].handlers.elts;
-
- switch (i) {
-
- case NGX_HTTP_SERVER_REWRITE_PHASE:
- if (cmcf->phase_engine.server_rewrite_index == (ngx_uint_t) -1) {
- cmcf->phase_engine.server_rewrite_index = n;
- }
- checker = ngx_http_core_rewrite_phase;
-
- break;
-
- case NGX_HTTP_FIND_CONFIG_PHASE:
- find_config_index = n;
-
- ph->checker = ngx_http_core_find_config_phase;
- n++;
- ph++;
-
- 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_rewrite_phase;
-
- break;
-
- case NGX_HTTP_POST_REWRITE_PHASE:
- if (use_rewrite) {
- ph->checker = ngx_http_core_post_rewrite_phase;
- ph->next = find_config_index;
- n++;
- ph++;
- }
-
- continue;
-
- case NGX_HTTP_ACCESS_PHASE:
- checker = ngx_http_core_access_phase;
- n++;
- break;
-
- case NGX_HTTP_POST_ACCESS_PHASE:
- if (use_access) {
- ph->checker = ngx_http_core_post_access_phase;
- ph->next = n;
- ph++;
- }
-
- continue;
-
- case NGX_HTTP_TRY_FILES_PHASE:
- if (cmcf->try_files) {
- ph->checker = ngx_http_core_try_files_phase;
- n++;
- ph++;
- }
-
- continue;
-
- case NGX_HTTP_CONTENT_PHASE:
- checker = ngx_http_core_content_phase;
- break;
-
- default:
- checker = ngx_http_core_generic_phase;
- }
-
- n += cmcf->phases[i].handlers.nelts;
-
- for (j = cmcf->phases[i].handlers.nelts - 1; j >=0; j--) {
- ph->checker = checker;
- ph->handler = h[j];
- ph->next = n;
- ph++;
- }
- }
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_http_merge_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
- ngx_http_module_t *module, ngx_uint_t ctx_index)
-{
- char *rv;
- ngx_uint_t s;
- ngx_http_conf_ctx_t *ctx, saved;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_core_srv_conf_t **cscfp;
-
- cscfp = cmcf->servers.elts;
- ctx = (ngx_http_conf_ctx_t *) cf->ctx;
- saved = *ctx;
- rv = NGX_CONF_OK;
-
- for (s = 0; s < cmcf->servers.nelts; s++) {
-
- /* merge the server{}s' srv_conf's */
-
- ctx->srv_conf = cscfp[s]->ctx->srv_conf;
-
- if (module->merge_srv_conf) {
- rv = module->merge_srv_conf(cf, saved.srv_conf[ctx_index],
- cscfp[s]->ctx->srv_conf[ctx_index]);
- if (rv != NGX_CONF_OK) {
- goto failed;
- }
- }
-
- if (module->merge_loc_conf) {
-
- /* merge the server{}'s loc_conf */
-
- ctx->loc_conf = cscfp[s]->ctx->loc_conf;
-
- rv = module->merge_loc_conf(cf, saved.loc_conf[ctx_index],
- cscfp[s]->ctx->loc_conf[ctx_index]);
- if (rv != NGX_CONF_OK) {
- goto failed;
- }
-
- /* merge the locations{}' loc_conf's */
-
- clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
-
- rv = ngx_http_merge_locations(cf, clcf->locations,
- cscfp[s]->ctx->loc_conf,
- module, ctx_index);
- if (rv != NGX_CONF_OK) {
- goto failed;
- }
- }
- }
-
-failed:
-
- *ctx = saved;
-
- return rv;
-}
-
-
-static char *
-ngx_http_merge_locations(ngx_conf_t *cf, ngx_queue_t *locations,
- void **loc_conf, ngx_http_module_t *module, ngx_uint_t ctx_index)
-{
- char *rv;
- ngx_queue_t *q;
- ngx_http_conf_ctx_t *ctx, saved;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_location_queue_t *lq;
-
- if (locations == NULL) {
- return NGX_CONF_OK;
- }
-
- ctx = (ngx_http_conf_ctx_t *) cf->ctx;
- saved = *ctx;
-
- for (q = ngx_queue_head(locations);
- q != ngx_queue_sentinel(locations);
- q = ngx_queue_next(q))
- {
- lq = (ngx_http_location_queue_t *) q;
-
- clcf = lq->exact ? lq->exact : lq->inclusive;
- ctx->loc_conf = clcf->loc_conf;
-
- rv = module->merge_loc_conf(cf, loc_conf[ctx_index],
- clcf->loc_conf[ctx_index]);
- if (rv != NGX_CONF_OK) {
- return rv;
- }
-
- rv = ngx_http_merge_locations(cf, clcf->locations, clcf->loc_conf,
- module, ctx_index);
- if (rv != NGX_CONF_OK) {
- return rv;
- }
- }
-
- *ctx = saved;
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_init_locations(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
- ngx_http_core_loc_conf_t *pclcf)
-{
- ngx_uint_t n;
- ngx_queue_t *q, *locations, *named, tail;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_location_queue_t *lq;
- ngx_http_core_loc_conf_t **clcfp;
-#if (NGX_PCRE)
- ngx_uint_t r;
- ngx_queue_t *regex;
-#endif
-
- locations = pclcf->locations;
-
- if (locations == NULL) {
- return NGX_OK;
- }
-
- ngx_queue_sort(locations, ngx_http_cmp_locations);
-
- named = NULL;
- n = 0;
-#if (NGX_PCRE)
- regex = NULL;
- r = 0;
-#endif
-
- for (q = ngx_queue_head(locations);
- q != ngx_queue_sentinel(locations);
- q = ngx_queue_next(q))
- {
- lq = (ngx_http_location_queue_t *) q;
-
- clcf = lq->exact ? lq->exact : lq->inclusive;
-
- if (ngx_http_init_locations(cf, NULL, clcf) != NGX_OK) {
- return NGX_ERROR;
- }
-
-#if (NGX_PCRE)
-
- if (clcf->regex) {
- r++;
-
- if (regex == NULL) {
- regex = q;
- }
-
- continue;
- }
-
-#endif
-
- if (clcf->named) {
- n++;
-
- if (named == NULL) {
- named = q;
- }
-
- continue;
- }
-
- if (clcf->noname) {
- break;
- }
- }
-
- if (q != ngx_queue_sentinel(locations)) {
- ngx_queue_split(locations, q, &tail);
- }
-
- if (named) {
- clcfp = ngx_palloc(cf->pool,
- (n + 1) * sizeof(ngx_http_core_loc_conf_t **));
- if (clcfp == NULL) {
- return NGX_ERROR;
- }
-
- cscf->named_locations = clcfp;
-
- for (q = named;
- q != ngx_queue_sentinel(locations);
- q = ngx_queue_next(q))
- {
- lq = (ngx_http_location_queue_t *) q;
-
- *(clcfp++) = lq->exact;
- }
-
- *clcfp = NULL;
-
- ngx_queue_split(locations, named, &tail);
- }
-
-#if (NGX_PCRE)
-
- if (regex) {
-
- clcfp = ngx_palloc(cf->pool,
- (r + 1) * sizeof(ngx_http_core_loc_conf_t **));
- if (clcfp == NULL) {
- return NGX_ERROR;
- }
-
- pclcf->regex_locations = clcfp;
-
- for (q = regex;
- q != ngx_queue_sentinel(locations);
- q = ngx_queue_next(q))
- {
- lq = (ngx_http_location_queue_t *) q;
-
- *(clcfp++) = lq->exact;
- }
-
- *clcfp = NULL;
-
- ngx_queue_split(locations, regex, &tail);
- }
-
-#endif
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_init_static_location_trees(ngx_conf_t *cf,
- ngx_http_core_loc_conf_t *pclcf)
-{
- ngx_queue_t *q, *locations;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_location_queue_t *lq;
-
- locations = pclcf->locations;
-
- if (locations == NULL) {
- return NGX_OK;
- }
-
- if (ngx_queue_empty(locations)) {
- return NGX_OK;
- }
-
- for (q = ngx_queue_head(locations);
- q != ngx_queue_sentinel(locations);
- q = ngx_queue_next(q))
- {
- lq = (ngx_http_location_queue_t *) q;
-
- clcf = lq->exact ? lq->exact : lq->inclusive;
-
- if (ngx_http_init_static_location_trees(cf, clcf) != NGX_OK) {
- return NGX_ERROR;
- }
- }
-
- if (ngx_http_join_exact_locations(cf, locations) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ngx_http_create_locations_list(locations, ngx_queue_head(locations));
-
- pclcf->static_locations = ngx_http_create_locations_tree(cf, locations, 0);
- if (pclcf->static_locations == NULL) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
- ngx_http_core_loc_conf_t *clcf)
-{
- ngx_http_location_queue_t *lq;
-
- if (*locations == NULL) {
- *locations = ngx_palloc(cf->temp_pool,
- sizeof(ngx_http_location_queue_t));
- if (*locations == NULL) {
- return NGX_ERROR;
- }
-
- ngx_queue_init(*locations);
- }
-
- lq = ngx_palloc(cf->temp_pool, sizeof(ngx_http_location_queue_t));
- if (lq == NULL) {
- return NGX_ERROR;
- }
-
- if (clcf->exact_match
-#if (NGX_PCRE)
- || clcf->regex
-#endif
- || clcf->named || clcf->noname)
- {
- lq->exact = clcf;
- lq->inclusive = NULL;
-
- } else {
- lq->exact = NULL;
- lq->inclusive = clcf;
- }
-
- lq->name = &clcf->name;
- lq->file_name = cf->conf_file->file.name.data;
- lq->line = cf->conf_file->line;
-
- ngx_queue_init(&lq->list);
-
- ngx_queue_insert_tail(*locations, &lq->queue);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_cmp_locations(const ngx_queue_t *one, const ngx_queue_t *two)
-{
- ngx_int_t rc;
- ngx_http_core_loc_conf_t *first, *second;
- ngx_http_location_queue_t *lq1, *lq2;
-
- lq1 = (ngx_http_location_queue_t *) one;
- lq2 = (ngx_http_location_queue_t *) two;
-
- first = lq1->exact ? lq1->exact : lq1->inclusive;
- second = lq2->exact ? lq2->exact : lq2->inclusive;
-
- if (first->noname && !second->noname) {
- /* shift no named locations to the end */
- return 1;
- }
-
- if (!first->noname && second->noname) {
- /* shift no named locations to the end */
- return -1;
- }
-
- if (first->noname || second->noname) {
- /* do not sort no named locations */
- return 0;
- }
-
- 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 (NGX_PCRE)
-
- if (first->regex && !second->regex) {
- /* shift the regex matches to the end */
- return 1;
- }
-
- if (!first->regex && second->regex) {
- /* shift the regex matches to the end */
- return -1;
- }
-
- if (first->regex || second->regex) {
- /* do not sort the regex matches */
- return 0;
- }
-
-#endif
-
- rc = ngx_filename_cmp(first->name.data, second->name.data,
- ngx_min(first->name.len, second->name.len) + 1);
-
- if (rc == 0 && !first->exact_match && second->exact_match) {
- /* an exact match must be before the same inclusive one */
- return 1;
- }
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_join_exact_locations(ngx_conf_t *cf, ngx_queue_t *locations)
-{
- ngx_queue_t *q, *x;
- ngx_http_location_queue_t *lq, *lx;
-
- q = ngx_queue_head(locations);
-
- while (q != ngx_queue_last(locations)) {
-
- x = ngx_queue_next(q);
-
- lq = (ngx_http_location_queue_t *) q;
- lx = (ngx_http_location_queue_t *) x;
-
- if (lq->name->len == lx->name->len
- && ngx_filename_cmp(lq->name->data, lx->name->data, lx->name->len)
- == 0)
- {
- if ((lq->exact && lx->exact) || (lq->inclusive && lx->inclusive)) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "duplicate location \"%V\" in %s:%ui",
- lx->name, lx->file_name, lx->line);
-
- return NGX_ERROR;
- }
-
- lq->inclusive = lx->inclusive;
-
- ngx_queue_remove(x);
-
- continue;
- }
-
- q = ngx_queue_next(q);
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_create_locations_list(ngx_queue_t *locations, ngx_queue_t *q)
-{
- u_char *name;
- size_t len;
- ngx_queue_t *x, tail;
- ngx_http_location_queue_t *lq, *lx;
-
- if (q == ngx_queue_last(locations)) {
- return;
- }
-
- lq = (ngx_http_location_queue_t *) q;
-
- if (lq->inclusive == NULL) {
- ngx_http_create_locations_list(locations, ngx_queue_next(q));
- return;
- }
-
- len = lq->name->len;
- name = lq->name->data;
-
- for (x = ngx_queue_next(q);
- x != ngx_queue_sentinel(locations);
- x = ngx_queue_next(x))
- {
- lx = (ngx_http_location_queue_t *) x;
-
- if (len > lx->name->len
- || ngx_filename_cmp(name, lx->name->data, len) != 0)
- {
- break;
- }
- }
-
- q = ngx_queue_next(q);
-
- if (q == x) {
- ngx_http_create_locations_list(locations, x);
- return;
- }
-
- ngx_queue_split(locations, q, &tail);
- ngx_queue_add(&lq->list, &tail);
-
- if (x == ngx_queue_sentinel(locations)) {
- ngx_http_create_locations_list(&lq->list, ngx_queue_head(&lq->list));
- return;
- }
-
- ngx_queue_split(&lq->list, x, &tail);
- ngx_queue_add(locations, &tail);
-
- ngx_http_create_locations_list(&lq->list, ngx_queue_head(&lq->list));
-
- ngx_http_create_locations_list(locations, x);
-}
-
-
-/*
- * to keep cache locality for left leaf nodes, allocate nodes in following
- * order: node, left subtree, right subtree, inclusive subtree
- */
-
-static ngx_http_location_tree_node_t *
-ngx_http_create_locations_tree(ngx_conf_t *cf, ngx_queue_t *locations,
- size_t prefix)
-{
- size_t len;
- ngx_queue_t *q, tail;
- ngx_http_location_queue_t *lq;
- ngx_http_location_tree_node_t *node;
-
- q = ngx_queue_middle(locations);
-
- lq = (ngx_http_location_queue_t *) q;
- len = lq->name->len - prefix;
-
- node = ngx_palloc(cf->pool,
- offsetof(ngx_http_location_tree_node_t, name) + len);
- if (node == NULL) {
- return NULL;
- }
-
- node->left = NULL;
- node->right = NULL;
- node->tree = NULL;
- node->exact = lq->exact;
- node->inclusive = lq->inclusive;
-
- node->auto_redirect = (u_char) ((lq->exact && lq->exact->auto_redirect)
- || (lq->inclusive && lq->inclusive->auto_redirect));
-
- node->len = (u_char) len;
- ngx_memcpy(node->name, &lq->name->data[prefix], len);
-
- ngx_queue_split(locations, q, &tail);
-
- if (ngx_queue_empty(locations)) {
- /*
- * ngx_queue_split() insures that if left part is empty,
- * then right one is empty too
- */
- goto inclusive;
- }
-
- node->left = ngx_http_create_locations_tree(cf, locations, prefix);
- if (node->left == NULL) {
- return NULL;
- }
-
- ngx_queue_remove(q);
-
- if (ngx_queue_empty(&tail)) {
- goto inclusive;
- }
-
- node->right = ngx_http_create_locations_tree(cf, &tail, prefix);
- if (node->right == NULL) {
- return NULL;
- }
-
-inclusive:
-
- if (ngx_queue_empty(&lq->list)) {
- return node;
- }
-
- node->tree = ngx_http_create_locations_tree(cf, &lq->list, prefix + len);
- if (node->tree == NULL) {
- return NULL;
- }
-
- return node;
-}
-
-
-ngx_int_t
-ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
- ngx_http_listen_opt_t *lsopt)
-{
- in_port_t p;
- ngx_uint_t i;
- struct sockaddr *sa;
- struct sockaddr_in *sin;
- ngx_http_conf_port_t *port;
- ngx_http_core_main_conf_t *cmcf;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- if (cmcf->ports == NULL) {
- cmcf->ports = ngx_array_create(cf->temp_pool, 2,
- sizeof(ngx_http_conf_port_t));
- if (cmcf->ports == NULL) {
- return NGX_ERROR;
- }
- }
-
- sa = &lsopt->u.sockaddr;
-
- switch (sa->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = &lsopt->u.sockaddr_in6;
- p = sin6->sin6_port;
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- p = 0;
- break;
-#endif
-
- default: /* AF_INET */
- sin = &lsopt->u.sockaddr_in;
- p = sin->sin_port;
- break;
- }
-
- port = cmcf->ports->elts;
- for (i = 0; i < cmcf->ports->nelts; i++) {
-
- if (p != port[i].port || sa->sa_family != port[i].family) {
- continue;
- }
-
- /* a port is already in the port list */
-
- return ngx_http_add_addresses(cf, cscf, &port[i], lsopt);
- }
-
- /* add a port to the port list */
-
- port = ngx_array_push(cmcf->ports);
- if (port == NULL) {
- return NGX_ERROR;
- }
-
- port->family = sa->sa_family;
- port->port = p;
- port->addrs.elts = NULL;
-
- return ngx_http_add_address(cf, cscf, port, lsopt);
-}
-
-
-static ngx_int_t
-ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
- ngx_http_conf_port_t *port, ngx_http_listen_opt_t *lsopt)
-{
- u_char *p;
- size_t len, off;
- ngx_uint_t i, default_server;
- struct sockaddr *sa;
- ngx_http_conf_addr_t *addr;
-#if (NGX_HAVE_UNIX_DOMAIN)
- struct sockaddr_un *saun;
-#endif
-#if (NGX_HTTP_SSL)
- ngx_uint_t ssl;
-#endif
-#if (NGX_HTTP_SPDY)
- ngx_uint_t spdy;
-#endif
-
- /*
- * we cannot compare whole sockaddr struct's as kernel
- * may fill some fields in inherited sockaddr struct's
- */
-
- sa = &lsopt->u.sockaddr;
-
- switch (sa->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- off = offsetof(struct sockaddr_in6, sin6_addr);
- len = 16;
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- off = offsetof(struct sockaddr_un, sun_path);
- len = sizeof(saun->sun_path);
- break;
-#endif
-
- default: /* AF_INET */
- off = offsetof(struct sockaddr_in, sin_addr);
- len = 4;
- break;
- }
-
- p = lsopt->u.sockaddr_data + off;
-
- addr = port->addrs.elts;
-
- for (i = 0; i < port->addrs.nelts; i++) {
-
- if (ngx_memcmp(p, addr[i].opt.u.sockaddr_data + off, len) != 0) {
- continue;
- }
-
- /* the address is already in the address list */
-
- if (ngx_http_add_server(cf, cscf, &addr[i]) != NGX_OK) {
- return NGX_ERROR;
- }
-
- /* preserve default_server bit during listen options overwriting */
- default_server = addr[i].opt.default_server;
-
-#if (NGX_HTTP_SSL)
- ssl = lsopt->ssl || addr[i].opt.ssl;
-#endif
-#if (NGX_HTTP_SPDY)
- spdy = lsopt->spdy || addr[i].opt.spdy;
-#endif
-
- if (lsopt->set) {
-
- if (addr[i].opt.set) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate listen options for %s", addr[i].opt.addr);
- return NGX_ERROR;
- }
-
- addr[i].opt = *lsopt;
- }
-
- /* check the duplicate "default" server for this address:port */
-
- if (lsopt->default_server) {
-
- if (default_server) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "a duplicate default server for %s", addr[i].opt.addr);
- return NGX_ERROR;
- }
-
- default_server = 1;
- addr[i].default_server = cscf;
- }
-
- addr[i].opt.default_server = default_server;
-#if (NGX_HTTP_SSL)
- addr[i].opt.ssl = ssl;
-#endif
-#if (NGX_HTTP_SPDY)
- addr[i].opt.spdy = spdy;
-#endif
-
- return NGX_OK;
- }
-
- /* add the address to the addresses list that bound to this port */
-
- return ngx_http_add_address(cf, cscf, port, lsopt);
-}
-
-
-/*
- * add the server address, the server names and the server core module
- * configurations to the port list
- */
-
-static ngx_int_t
-ngx_http_add_address(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
- ngx_http_conf_port_t *port, ngx_http_listen_opt_t *lsopt)
-{
- ngx_http_conf_addr_t *addr;
-
- if (port->addrs.elts == NULL) {
- if (ngx_array_init(&port->addrs, cf->temp_pool, 4,
- sizeof(ngx_http_conf_addr_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
- }
-
-#if (NGX_HTTP_SPDY && NGX_HTTP_SSL \
- && !defined TLSEXT_TYPE_application_layer_protocol_negotiation \
- && !defined TLSEXT_TYPE_next_proto_neg)
- if (lsopt->spdy && lsopt->ssl) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "nginx was built without OpenSSL ALPN or NPN "
- "support, SPDY is not enabled for %s", lsopt->addr);
- }
-#endif
-
- addr = ngx_array_push(&port->addrs);
- if (addr == NULL) {
- return NGX_ERROR;
- }
-
- addr->opt = *lsopt;
- addr->hash.buckets = NULL;
- addr->hash.size = 0;
- addr->wc_head = NULL;
- addr->wc_tail = NULL;
-#if (NGX_PCRE)
- addr->nregex = 0;
- addr->regex = NULL;
-#endif
- addr->default_server = cscf;
- addr->servers.elts = NULL;
-
- return ngx_http_add_server(cf, cscf, addr);
-}
-
-
-/* add the server core module configuration to the address:port */
-
-static ngx_int_t
-ngx_http_add_server(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
- ngx_http_conf_addr_t *addr)
-{
- ngx_uint_t i;
- ngx_http_core_srv_conf_t **server;
-
- if (addr->servers.elts == NULL) {
- if (ngx_array_init(&addr->servers, cf->temp_pool, 4,
- sizeof(ngx_http_core_srv_conf_t *))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- } else {
- server = addr->servers.elts;
- for (i = 0; i < addr->servers.nelts; i++) {
- if (server[i] == cscf) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "a duplicate listen %s", addr->opt.addr);
- return NGX_ERROR;
- }
- }
- }
-
- server = ngx_array_push(&addr->servers);
- if (server == NULL) {
- return NGX_ERROR;
- }
-
- *server = cscf;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_optimize_servers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
- ngx_array_t *ports)
-{
- ngx_uint_t p, a;
- ngx_http_conf_port_t *port;
- ngx_http_conf_addr_t *addr;
-
- if (ports == NULL) {
- return NGX_OK;
- }
-
- port = ports->elts;
- for (p = 0; p < ports->nelts; p++) {
-
- ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts,
- sizeof(ngx_http_conf_addr_t), ngx_http_cmp_conf_addrs);
-
- /*
- * check whether all name-based servers have the same
- * configuration as a default server for given address:port
- */
-
- addr = port[p].addrs.elts;
- for (a = 0; a < port[p].addrs.nelts; a++) {
-
- if (addr[a].servers.nelts > 1
-#if (NGX_PCRE)
- || addr[a].default_server->captures
-#endif
- )
- {
- if (ngx_http_server_names(cf, cmcf, &addr[a]) != NGX_OK) {
- return NGX_ERROR;
- }
- }
- }
-
- if (ngx_http_init_listening(cf, &port[p]) != NGX_OK) {
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
- ngx_http_conf_addr_t *addr)
-{
- ngx_int_t rc;
- ngx_uint_t n, s;
- ngx_hash_init_t hash;
- ngx_hash_keys_arrays_t ha;
- ngx_http_server_name_t *name;
- ngx_http_core_srv_conf_t **cscfp;
-#if (NGX_PCRE)
- ngx_uint_t regex, i;
-
- regex = 0;
-#endif
-
- ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t));
-
- ha.temp_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
- if (ha.temp_pool == NULL) {
- return NGX_ERROR;
- }
-
- ha.pool = cf->pool;
-
- if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) {
- goto failed;
- }
-
- cscfp = addr->servers.elts;
-
- for (s = 0; s < addr->servers.nelts; s++) {
-
- name = cscfp[s]->server_names.elts;
-
- for (n = 0; n < cscfp[s]->server_names.nelts; n++) {
-
-#if (NGX_PCRE)
- if (name[n].regex) {
- regex++;
- continue;
- }
-#endif
-
- rc = ngx_hash_add_key(&ha, &name[n].name, name[n].server,
- NGX_HASH_WILDCARD_KEY);
-
- if (rc == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- if (rc == NGX_DECLINED) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "invalid server name or wildcard \"%V\" on %s",
- &name[n].name, addr->opt.addr);
- return NGX_ERROR;
- }
-
- if (rc == NGX_BUSY) {
- ngx_log_error(NGX_LOG_WARN, cf->log, 0,
- "conflicting server name \"%V\" on %s, ignored",
- &name[n].name, addr->opt.addr);
- }
- }
- }
-
- hash.key = ngx_hash_key_lc;
- hash.max_size = cmcf->server_names_hash_max_size;
- hash.bucket_size = cmcf->server_names_hash_bucket_size;
- hash.name = "server_names_hash";
- hash.pool = cf->pool;
-
- if (ha.keys.nelts) {
- hash.hash = &addr->hash;
- hash.temp_pool = NULL;
-
- if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK) {
- goto failed;
- }
- }
-
- if (ha.dns_wc_head.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_wc_head.elts,
- ha.dns_wc_head.nelts)
- != NGX_OK)
- {
- goto failed;
- }
-
- addr->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)
- {
- goto failed;
- }
-
- addr->wc_tail = (ngx_hash_wildcard_t *) hash.hash;
- }
-
- ngx_destroy_pool(ha.temp_pool);
-
-#if (NGX_PCRE)
-
- if (regex == 0) {
- return NGX_OK;
- }
-
- addr->nregex = regex;
- addr->regex = ngx_palloc(cf->pool, regex * sizeof(ngx_http_server_name_t));
- if (addr->regex == NULL) {
- return NGX_ERROR;
- }
-
- i = 0;
-
- for (s = 0; s < addr->servers.nelts; s++) {
-
- name = cscfp[s]->server_names.elts;
-
- for (n = 0; n < cscfp[s]->server_names.nelts; n++) {
- if (name[n].regex) {
- addr->regex[i++] = name[n];
- }
- }
- }
-
-#endif
-
- return NGX_OK;
-
-failed:
-
- ngx_destroy_pool(ha.temp_pool);
-
- return NGX_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_cmp_conf_addrs(const void *one, const void *two)
-{
- ngx_http_conf_addr_t *first, *second;
-
- first = (ngx_http_conf_addr_t *) one;
- second = (ngx_http_conf_addr_t *) two;
-
- if (first->opt.wildcard) {
- /* a wildcard address must be the last resort, shift it to the end */
- return 1;
- }
-
- if (second->opt.wildcard) {
- /* a wildcard address must be the last resort, shift it to the end */
- return -1;
- }
-
- if (first->opt.bind && !second->opt.bind) {
- /* shift explicit bind()ed addresses to the start */
- return -1;
- }
-
- if (!first->opt.bind && second->opt.bind) {
- /* shift explicit bind()ed addresses to the start */
- return 1;
- }
-
- /* do not sort by default */
-
- return 0;
-}
-
-
-static int ngx_libc_cdecl
-ngx_http_cmp_dns_wildcards(const void *one, const void *two)
-{
- ngx_hash_key_t *first, *second;
-
- first = (ngx_hash_key_t *) one;
- second = (ngx_hash_key_t *) two;
-
- return ngx_dns_strcmp(first->key.data, second->key.data);
-}
-
-
-static ngx_int_t
-ngx_http_init_listening(ngx_conf_t *cf, ngx_http_conf_port_t *port)
-{
- ngx_uint_t i, last, bind_wildcard;
- ngx_listening_t *ls;
- ngx_http_port_t *hport;
- ngx_http_conf_addr_t *addr;
-
- addr = port->addrs.elts;
- last = port->addrs.nelts;
-
- /*
- * If there is a binding to an "*:port" then we need to bind() to
- * the "*:port" only and ignore other implicit bindings. The bindings
- * have been already sorted: explicit bindings are on the start, then
- * implicit bindings go, and wildcard binding is in the end.
- */
-
- if (addr[last - 1].opt.wildcard) {
- addr[last - 1].opt.bind = 1;
- bind_wildcard = 1;
-
- } else {
- bind_wildcard = 0;
- }
-
- i = 0;
-
- while (i < last) {
-
- if (bind_wildcard && !addr[i].opt.bind) {
- i++;
- continue;
- }
-
- ls = ngx_http_add_listening(cf, &addr[i]);
- if (ls == NULL) {
- return NGX_ERROR;
- }
-
- hport = ngx_pcalloc(cf->pool, sizeof(ngx_http_port_t));
- if (hport == NULL) {
- return NGX_ERROR;
- }
-
- ls->servers = hport;
-
- if (i == last - 1) {
- hport->naddrs = last;
-
- } else {
- hport->naddrs = 1;
- i = 0;
- }
-
- switch (ls->sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- if (ngx_http_add_addrs6(cf, hport, addr) != NGX_OK) {
- return NGX_ERROR;
- }
- break;
-#endif
- default: /* AF_INET */
- if (ngx_http_add_addrs(cf, hport, addr) != NGX_OK) {
- return NGX_ERROR;
- }
- break;
- }
-
- addr++;
- last--;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_listening_t *
-ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
-{
- ngx_listening_t *ls;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_core_srv_conf_t *cscf;
-
- ls = ngx_create_listening(cf, &addr->opt.u.sockaddr, addr->opt.socklen);
- if (ls == NULL) {
- return NULL;
- }
-
- ls->addr_ntop = 1;
-
- ls->handler = ngx_http_init_connection;
-
- cscf = addr->default_server;
- ls->pool_size = cscf->connection_pool_size;
- ls->post_accept_timeout = cscf->client_header_timeout;
-
- clcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
-
- ls->logp = clcf->error_log;
- ls->log.data = &ls->addr_text;
- ls->log.handler = ngx_accept_log_error;
-
-#if (NGX_WIN32)
- {
- ngx_iocp_conf_t *iocpcf = NULL;
-
- if (ngx_get_conf(cf->cycle->conf_ctx, ngx_events_module)) {
- iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module);
- }
- if (iocpcf && iocpcf->acceptex_read) {
- ls->post_accept_buffer_size = cscf->client_header_buffer_size;
- }
- }
-#endif
-
- ls->backlog = addr->opt.backlog;
- ls->rcvbuf = addr->opt.rcvbuf;
- ls->sndbuf = addr->opt.sndbuf;
-
- ls->keepalive = addr->opt.so_keepalive;
-#if (NGX_HAVE_KEEPALIVE_TUNABLE)
- ls->keepidle = addr->opt.tcp_keepidle;
- ls->keepintvl = addr->opt.tcp_keepintvl;
- ls->keepcnt = addr->opt.tcp_keepcnt;
-#endif
-
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
- ls->accept_filter = addr->opt.accept_filter;
-#endif
-
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
- ls->deferred_accept = addr->opt.deferred_accept;
-#endif
-
-#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- ls->ipv6only = addr->opt.ipv6only;
-#endif
-
-#if (NGX_HAVE_SETFIB)
- ls->setfib = addr->opt.setfib;
-#endif
-
-#if (NGX_HAVE_TCP_FASTOPEN)
- ls->fastopen = addr->opt.fastopen;
-#endif
-
- return ls;
-}
-
-
-static ngx_int_t
-ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport,
- ngx_http_conf_addr_t *addr)
-{
- ngx_uint_t i;
- ngx_http_in_addr_t *addrs;
- struct sockaddr_in *sin;
- ngx_http_virtual_names_t *vn;
-
- hport->addrs = ngx_pcalloc(cf->pool,
- hport->naddrs * sizeof(ngx_http_in_addr_t));
- if (hport->addrs == NULL) {
- return NGX_ERROR;
- }
-
- addrs = hport->addrs;
-
- for (i = 0; i < hport->naddrs; i++) {
-
- sin = &addr[i].opt.u.sockaddr_in;
- addrs[i].addr = sin->sin_addr.s_addr;
- addrs[i].conf.default_server = addr[i].default_server;
-#if (NGX_HTTP_SSL)
- addrs[i].conf.ssl = addr[i].opt.ssl;
-#endif
-#if (NGX_HTTP_SPDY)
- addrs[i].conf.spdy = addr[i].opt.spdy;
-#endif
- addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
-
- if (addr[i].hash.buckets == NULL
- && (addr[i].wc_head == NULL
- || addr[i].wc_head->hash.buckets == NULL)
- && (addr[i].wc_tail == NULL
- || addr[i].wc_tail->hash.buckets == NULL)
-#if (NGX_PCRE)
- && addr[i].nregex == 0
-#endif
- )
- {
- continue;
- }
-
- vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
- if (vn == NULL) {
- return NGX_ERROR;
- }
-
- addrs[i].conf.virtual_names = vn;
-
- vn->names.hash = addr[i].hash;
- vn->names.wc_head = addr[i].wc_head;
- vn->names.wc_tail = addr[i].wc_tail;
-#if (NGX_PCRE)
- vn->nregex = addr[i].nregex;
- vn->regex = addr[i].regex;
-#endif
- }
-
- return NGX_OK;
-}
-
-
-#if (NGX_HAVE_INET6)
-
-static ngx_int_t
-ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport,
- ngx_http_conf_addr_t *addr)
-{
- ngx_uint_t i;
- ngx_http_in6_addr_t *addrs6;
- struct sockaddr_in6 *sin6;
- ngx_http_virtual_names_t *vn;
-
- hport->addrs = ngx_pcalloc(cf->pool,
- hport->naddrs * sizeof(ngx_http_in6_addr_t));
- if (hport->addrs == NULL) {
- return NGX_ERROR;
- }
-
- addrs6 = hport->addrs;
-
- for (i = 0; i < hport->naddrs; i++) {
-
- sin6 = &addr[i].opt.u.sockaddr_in6;
- addrs6[i].addr6 = sin6->sin6_addr;
- addrs6[i].conf.default_server = addr[i].default_server;
-#if (NGX_HTTP_SSL)
- addrs6[i].conf.ssl = addr[i].opt.ssl;
-#endif
-#if (NGX_HTTP_SPDY)
- addrs6[i].conf.spdy = addr[i].opt.spdy;
-#endif
-
- if (addr[i].hash.buckets == NULL
- && (addr[i].wc_head == NULL
- || addr[i].wc_head->hash.buckets == NULL)
- && (addr[i].wc_tail == NULL
- || addr[i].wc_tail->hash.buckets == NULL)
-#if (NGX_PCRE)
- && addr[i].nregex == 0
-#endif
- )
- {
- continue;
- }
-
- vn = ngx_palloc(cf->pool, sizeof(ngx_http_virtual_names_t));
- if (vn == NULL) {
- return NGX_ERROR;
- }
-
- addrs6[i].conf.virtual_names = vn;
-
- vn->names.hash = addr[i].hash;
- vn->names.wc_head = addr[i].wc_head;
- vn->names.wc_tail = addr[i].wc_tail;
-#if (NGX_PCRE)
- vn->nregex = addr[i].nregex;
- vn->regex = addr[i].regex;
-#endif
- }
-
- return NGX_OK;
-}
-
-#endif
-
-
-char *
-ngx_http_types_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_array_t **types;
- ngx_str_t *value, *default_type;
- ngx_uint_t i, n, hash;
- ngx_hash_key_t *type;
-
- types = (ngx_array_t **) (p + cmd->offset);
-
- if (*types == (void *) -1) {
- return NGX_CONF_OK;
- }
-
- default_type = cmd->post;
-
- if (*types == NULL) {
- *types = ngx_array_create(cf->temp_pool, 1, sizeof(ngx_hash_key_t));
- if (*types == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (default_type) {
- type = ngx_array_push(*types);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type->key = *default_type;
- type->key_hash = ngx_hash_key(default_type->data,
- default_type->len);
- type->value = (void *) 4;
- }
- }
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (value[i].len == 1 && value[i].data[0] == '*') {
- *types = (void *) -1;
- return NGX_CONF_OK;
- }
-
- hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len);
- value[i].data[value[i].len] = '\0';
-
- type = (*types)->elts;
- for (n = 0; n < (*types)->nelts; n++) {
-
- if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "duplicate MIME type \"%V\"", &value[i]);
- continue;
- }
- }
-
- type = ngx_array_push(*types);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type->key = value[i];
- type->key_hash = hash;
- type->value = (void *) 4;
- }
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_http_merge_types(ngx_conf_t *cf, ngx_array_t **keys, ngx_hash_t *types_hash,
- ngx_array_t **prev_keys, ngx_hash_t *prev_types_hash,
- ngx_str_t *default_types)
-{
- ngx_hash_init_t hash;
-
- if (*keys) {
-
- if (*keys == (void *) -1) {
- return NGX_CONF_OK;
- }
-
- hash.hash = types_hash;
- hash.key = NULL;
- hash.max_size = 2048;
- hash.bucket_size = 64;
- hash.name = "test_types_hash";
- hash.pool = cf->pool;
- hash.temp_pool = NULL;
-
- if (ngx_hash_init(&hash, (*keys)->elts, (*keys)->nelts) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
- }
-
- if (prev_types_hash->buckets == NULL) {
-
- if (*prev_keys == NULL) {
-
- if (ngx_http_set_default_types(cf, prev_keys, default_types)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- } else if (*prev_keys == (void *) -1) {
- *keys = *prev_keys;
- return NGX_CONF_OK;
- }
-
- hash.hash = prev_types_hash;
- hash.key = NULL;
- hash.max_size = 2048;
- hash.bucket_size = 64;
- hash.name = "test_types_hash";
- hash.pool = cf->pool;
- hash.temp_pool = NULL;
-
- if (ngx_hash_init(&hash, (*prev_keys)->elts, (*prev_keys)->nelts)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
- }
-
- *types_hash = *prev_types_hash;
-
- return NGX_CONF_OK;
-
-}
-
-
-ngx_int_t
-ngx_http_set_default_types(ngx_conf_t *cf, ngx_array_t **types,
- ngx_str_t *default_type)
-{
- ngx_hash_key_t *type;
-
- *types = ngx_array_create(cf->temp_pool, 1, sizeof(ngx_hash_key_t));
- if (*types == NULL) {
- return NGX_ERROR;
- }
-
- while (default_type->len) {
-
- type = ngx_array_push(*types);
- if (type == NULL) {
- return NGX_ERROR;
- }
-
- type->key = *default_type;
- type->key_hash = ngx_hash_key(default_type->data,
- default_type->len);
- type->value = (void *) 4;
-
- default_type++;
- }
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http.h b/usr.sbin/nginx/src/http/ngx_http.h
deleted file mode 100644
index d4dc1bd94e9..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http.h
+++ /dev/null
@@ -1,184 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HTTP_H_INCLUDED_
-#define _NGX_HTTP_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef struct ngx_http_request_s ngx_http_request_t;
-typedef struct ngx_http_upstream_s ngx_http_upstream_t;
-typedef struct ngx_http_cache_s ngx_http_cache_t;
-typedef struct ngx_http_file_cache_s ngx_http_file_cache_t;
-typedef struct ngx_http_log_ctx_s ngx_http_log_ctx_t;
-typedef struct ngx_http_chunked_s ngx_http_chunked_t;
-
-#if (NGX_HTTP_SPDY)
-typedef struct ngx_http_spdy_stream_s ngx_http_spdy_stream_t;
-#endif
-
-typedef ngx_int_t (*ngx_http_header_handler_pt)(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-typedef u_char *(*ngx_http_log_handler_pt)(ngx_http_request_t *r,
- ngx_http_request_t *sr, u_char *buf, size_t len);
-
-
-#include <ngx_http_variables.h>
-#include <ngx_http_config.h>
-#include <ngx_http_request.h>
-#include <ngx_http_script.h>
-#include <ngx_http_upstream.h>
-#include <ngx_http_upstream_round_robin.h>
-#include <ngx_http_busy_lock.h>
-#include <ngx_http_core_module.h>
-
-#if (NGX_HTTP_SPDY)
-#include <ngx_http_spdy.h>
-#endif
-#if (NGX_HTTP_CACHE)
-#include <ngx_http_cache.h>
-#endif
-#if (NGX_HTTP_SSI)
-#include <ngx_http_ssi_filter_module.h>
-#endif
-#if (NGX_HTTP_SSL)
-#include <ngx_http_ssl_module.h>
-#endif
-
-
-struct ngx_http_log_ctx_s {
- ngx_connection_t *connection;
- ngx_http_request_t *request;
- ngx_http_request_t *current_request;
-};
-
-
-struct ngx_http_chunked_s {
- ngx_uint_t state;
- off_t size;
- off_t length;
-};
-
-
-typedef struct {
- ngx_uint_t http_version;
- ngx_uint_t code;
- ngx_uint_t count;
- u_char *start;
- u_char *end;
-} ngx_http_status_t;
-
-
-#define ngx_http_get_module_ctx(r, module) (r)->ctx[module.ctx_index]
-#define ngx_http_set_ctx(r, c, module) r->ctx[module.ctx_index] = c;
-
-
-ngx_int_t ngx_http_add_location(ngx_conf_t *cf, ngx_queue_t **locations,
- ngx_http_core_loc_conf_t *clcf);
-ngx_int_t ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
- ngx_http_listen_opt_t *lsopt);
-
-
-void ngx_http_init_connection(ngx_connection_t *c);
-void ngx_http_close_connection(ngx_connection_t *c);
-
-#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
-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_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_status_line(ngx_http_request_t *r, ngx_buf_t *b,
- ngx_http_status_t *status);
-ngx_int_t ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
- ngx_str_t *args, ngx_uint_t *flags);
-ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
- ngx_uint_t allow_underscores);
-ngx_int_t ngx_http_parse_multi_header_lines(ngx_array_t *headers,
- ngx_str_t *name, ngx_str_t *value);
-ngx_int_t ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len,
- ngx_str_t *value);
-void ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri,
- ngx_str_t *args);
-ngx_int_t ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
- ngx_http_chunked_t *ctx);
-
-
-ngx_http_request_t *ngx_http_create_request(ngx_connection_t *c);
-ngx_int_t ngx_http_process_request_uri(ngx_http_request_t *r);
-ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
-void ngx_http_process_request(ngx_http_request_t *r);
-void ngx_http_update_location_config(ngx_http_request_t *r);
-void ngx_http_handler(ngx_http_request_t *r);
-void ngx_http_run_posted_requests(ngx_connection_t *c);
-ngx_int_t ngx_http_post_request(ngx_http_request_t *r,
- ngx_http_posted_request_t *pr);
-void ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc);
-void ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc);
-
-void ngx_http_empty_handler(ngx_event_t *wev);
-void ngx_http_request_empty_handler(ngx_http_request_t *r);
-
-
-#define ngx_http_ephemeral(r) (void *) (&r->uri_start)
-
-
-#define NGX_HTTP_LAST 1
-#define NGX_HTTP_FLUSH 2
-
-ngx_int_t ngx_http_send_special(ngx_http_request_t *r, ngx_uint_t flags);
-
-
-ngx_int_t ngx_http_read_client_request_body(ngx_http_request_t *r,
- ngx_http_client_body_handler_pt post_handler);
-
-ngx_int_t ngx_http_send_header(ngx_http_request_t *r);
-ngx_int_t ngx_http_special_response_handler(ngx_http_request_t *r,
- ngx_int_t error);
-ngx_int_t ngx_http_filter_finalize_request(ngx_http_request_t *r,
- ngx_module_t *m, ngx_int_t error);
-void ngx_http_clean_header(ngx_http_request_t *r);
-
-
-time_t ngx_http_parse_time(u_char *value, size_t len);
-size_t ngx_http_get_time(char *buf, time_t t);
-
-
-
-ngx_int_t ngx_http_discard_request_body(ngx_http_request_t *r);
-void ngx_http_discarded_request_body_handler(ngx_http_request_t *r);
-void ngx_http_block_reading(ngx_http_request_t *r);
-void ngx_http_test_reading(ngx_http_request_t *r);
-
-
-char *ngx_http_types_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-char *ngx_http_merge_types(ngx_conf_t *cf, ngx_array_t **keys,
- ngx_hash_t *types_hash, ngx_array_t **prev_keys,
- ngx_hash_t *prev_types_hash, ngx_str_t *default_types);
-ngx_int_t ngx_http_set_default_types(ngx_conf_t *cf, ngx_array_t **types,
- ngx_str_t *default_type);
-
-#if (NGX_HTTP_DEGRADATION)
-ngx_uint_t ngx_http_degraded(ngx_http_request_t *);
-#endif
-
-
-extern ngx_module_t ngx_http_module;
-
-extern ngx_str_t ngx_http_html_default_types[];
-
-
-extern ngx_http_output_header_filter_pt ngx_http_top_header_filter;
-extern ngx_http_output_body_filter_pt ngx_http_top_body_filter;
-
-
-#endif /* _NGX_HTTP_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/ngx_http_busy_lock.c b/usr.sbin/nginx/src/http/ngx_http_busy_lock.c
deleted file mode 100644
index 3b4b28c8b32..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_busy_lock.c
+++ /dev/null
@@ -1,307 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-
-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)
-{
- if (bl->busy < bl->max_busy) {
- bl->busy++;
-
- if (bc->time) {
- bc->time = 0;
- bl->waiting--;
- }
-
- return NGX_OK;
- }
-
- if (bc->time) {
- if (bc->time < bl->timeout) {
- ngx_add_timer(bc->event, 1000);
- return NGX_AGAIN;
- }
-
- bl->waiting--;
- return NGX_DONE;
-
- }
-
- if (bl->timeout == 0) {
- return NGX_DONE;
- }
-
- if (bl->waiting < bl->max_waiting) {
- bl->waiting++;
-
-#if 0
- ngx_add_timer(bc->event, 1000);
- bc->event->event_handler = bc->event_handler;
-#endif
-
- /* TODO: ngx_handle_level_read_event() */
-
- return NGX_AGAIN;
- }
-
- return NGX_ERROR;
-}
-
-
-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_cacheable(bl, bc, lock);
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, bc->event->log, 0,
- "http busylock: %d w:%d mw::%d",
- rc, bl->waiting, bl->max_waiting);
-
- if (rc == NGX_OK) { /* no the same request, there's free slot */
- return NGX_OK;
- }
-
- if (rc == NGX_ERROR && !lock) { /* no the same request, no free slot */
- return NGX_OK;
- }
-
- /* rc == NGX_AGAIN: the same request */
-
- if (bc->time) {
- if (bc->time < bl->timeout) {
- ngx_add_timer(bc->event, 1000);
- return NGX_AGAIN;
- }
-
- bl->waiting--;
- return NGX_DONE;
-
- }
-
- if (bl->timeout == 0) {
- return NGX_DONE;
- }
-
- if (bl->waiting < bl->max_waiting) {
-#if 0
- bl->waiting++;
- ngx_add_timer(bc->event, 1000);
- bc->event->event_handler = bc->event_handler;
-#endif
-
- /* TODO: ngx_handle_level_read_event() */
-
- return NGX_AGAIN;
- }
-
- return NGX_ERROR;
-}
-
-
-void ngx_http_busy_unlock(ngx_http_busy_lock_t *bl,
- ngx_http_busy_lock_ctx_t *bc)
-{
- if (bl == NULL) {
- return;
- }
-
- if (bl->md5) {
- bl->md5_mask[bc->slot / 8] &= ~(1 << (bc->slot & 7));
- bl->cacheable--;
- }
-
- bl->busy--;
-}
-
-
-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, cacheable, free;
- u_int mask;
-
- b = 0;
- cacheable = 0;
- free = -1;
-
-#if (NGX_SUPPRESS_WARN)
- mask = 0;
-#endif
-
- for (i = 0; i < bl->max_busy; i++) {
-
- if ((b & 7) == 0) {
- mask = bl->md5_mask[i / 8];
- }
-
- if (mask & 1) {
- if (ngx_memcmp(&bl->md5[i * 16], bc->md5, 16) == 0) {
- return NGX_AGAIN;
- }
- cacheable++;
-
- } else if (free == -1) {
- free = i;
- }
-
-#if 1
- if (cacheable == bl->cacheable) {
- if (free == -1 && cacheable < bl->max_busy) {
- free = i + 1;
- }
-
- break;
- }
-#endif
-
- mask >>= 1;
- b++;
- }
-
- if (free == -1) {
- return NGX_ERROR;
- }
-
- if (lock) {
- if (bl->busy == bl->max_busy) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(&bl->md5[free * 16], bc->md5, 16);
- bl->md5_mask[free / 8] |= 1 << (free & 7);
- bc->slot = free;
-
- bl->cacheable++;
- bl->busy++;
- }
-
- return NGX_OK;
-}
-
-
-char *ngx_http_set_busy_lock_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf)
-{
- char *p = conf;
-
- ngx_uint_t i, dup, invalid;
- ngx_str_t *value, line;
- ngx_http_busy_lock_t *bl, **blp;
-
- blp = (ngx_http_busy_lock_t **) (p + cmd->offset);
- if (*blp) {
- return "is duplicate";
- }
-
- /* ngx_calloc_shared() */
- bl = ngx_pcalloc(cf->pool, sizeof(ngx_http_busy_lock_t));
- if (bl == NULL) {
- return NGX_CONF_ERROR;
- }
- *blp = bl;
-
- /* ngx_calloc_shared() */
- bl->mutex = ngx_pcalloc(cf->pool, sizeof(ngx_event_mutex_t));
- if (bl->mutex == NULL) {
- return NGX_CONF_ERROR;
- }
-
- dup = 0;
- invalid = 0;
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (value[i].data[1] != '=') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%s\"", value[i].data);
- return NGX_CONF_ERROR;
- }
-
- switch (value[i].data[0]) {
-
- case 'b':
- if (bl->max_busy) {
- dup = 1;
- break;
- }
-
- bl->max_busy = ngx_atoi(value[i].data + 2, value[i].len - 2);
- if (bl->max_busy == NGX_ERROR) {
- invalid = 1;
- break;
- }
-
- continue;
-
- case 'w':
- if (bl->max_waiting) {
- dup = 1;
- break;
- }
-
- bl->max_waiting = ngx_atoi(value[i].data + 2, value[i].len - 2);
- if (bl->max_waiting == NGX_ERROR) {
- invalid = 1;
- break;
- }
-
- continue;
-
- case 't':
- if (bl->timeout) {
- dup = 1;
- break;
- }
-
- line.len = value[i].len - 2;
- line.data = value[i].data + 2;
-
- bl->timeout = ngx_parse_time(&line, 1);
- if (bl->timeout == (time_t) NGX_ERROR) {
- invalid = 1;
- break;
- }
-
- continue;
-
- default:
- invalid = 1;
- }
-
- if (dup) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate value \"%s\"", value[i].data);
- return NGX_CONF_ERROR;
- }
-
- if (invalid) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%s\"", value[i].data);
- return NGX_CONF_ERROR;
- }
- }
-
- if (bl->timeout == 0 && bl->max_waiting) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "busy lock waiting is useless with zero timeout, ignoring");
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_busy_lock.h b/usr.sbin/nginx/src/http/ngx_http_busy_lock.h
deleted file mode 100644
index c676382f29d..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_busy_lock.h
+++ /dev/null
@@ -1,54 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HTTP_BUSY_LOCK_H_INCLUDED_
-#define _NGX_HTTP_BUSY_LOCK_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- u_char *md5_mask;
- char *md5;
- int cacheable;
-
- int busy;
- int max_busy;
-
- int waiting;
- int max_waiting;
-
- time_t timeout;
-
- ngx_event_mutex_t *mutex;
-} ngx_http_busy_lock_t;
-
-
-typedef struct {
- time_t time;
- ngx_event_t *event;
- void (*event_handler)(ngx_event_t *ev);
- u_char *md5;
- int slot;
-} ngx_http_busy_lock_ctx_t;
-
-
-int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc);
-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);
-
-char *ngx_http_set_busy_lock_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-#endif /* _NGX_HTTP_BUSY_LOCK_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/ngx_http_cache.h b/usr.sbin/nginx/src/http/ngx_http_cache.h
deleted file mode 100644
index 193a35322b5..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_cache.h
+++ /dev/null
@@ -1,161 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HTTP_CACHE_H_INCLUDED_
-#define _NGX_HTTP_CACHE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-#define NGX_HTTP_CACHE_MISS 1
-#define NGX_HTTP_CACHE_BYPASS 2
-#define NGX_HTTP_CACHE_EXPIRED 3
-#define NGX_HTTP_CACHE_STALE 4
-#define NGX_HTTP_CACHE_UPDATING 5
-#define NGX_HTTP_CACHE_REVALIDATED 6
-#define NGX_HTTP_CACHE_HIT 7
-#define NGX_HTTP_CACHE_SCARCE 8
-
-#define NGX_HTTP_CACHE_KEY_LEN 16
-
-
-typedef struct {
- ngx_uint_t status;
- time_t valid;
-} ngx_http_cache_valid_t;
-
-
-typedef struct {
- ngx_rbtree_node_t node;
- ngx_queue_t queue;
-
- u_char key[NGX_HTTP_CACHE_KEY_LEN
- - sizeof(ngx_rbtree_key_t)];
-
- unsigned count:20;
- unsigned uses:10;
- unsigned valid_msec:10;
- unsigned error:10;
- unsigned exists:1;
- unsigned updating:1;
- unsigned deleting:1;
- /* 11 unused bits */
-
- ngx_file_uniq_t uniq;
- time_t expire;
- time_t valid_sec;
- size_t body_start;
- off_t fs_size;
-} ngx_http_file_cache_node_t;
-
-
-struct ngx_http_cache_s {
- ngx_file_t file;
- ngx_array_t keys;
- uint32_t crc32;
- u_char key[NGX_HTTP_CACHE_KEY_LEN];
-
- ngx_file_uniq_t uniq;
- time_t valid_sec;
- time_t last_modified;
- time_t date;
-
- size_t header_start;
- size_t body_start;
- off_t length;
- off_t fs_size;
-
- ngx_uint_t min_uses;
- ngx_uint_t error;
- ngx_uint_t valid_msec;
-
- ngx_buf_t *buf;
-
- ngx_http_file_cache_t *file_cache;
- ngx_http_file_cache_node_t *node;
-
- ngx_msec_t lock_timeout;
- ngx_msec_t wait_time;
-
- ngx_event_t wait_event;
-
- unsigned lock:1;
- unsigned waiting:1;
-
- unsigned updated:1;
- unsigned updating:1;
- unsigned exists:1;
- unsigned temp_file:1;
-};
-
-
-typedef struct {
- time_t valid_sec;
- time_t last_modified;
- time_t date;
- uint32_t crc32;
- u_short valid_msec;
- u_short header_start;
- u_short body_start;
-} ngx_http_file_cache_header_t;
-
-
-typedef struct {
- ngx_rbtree_t rbtree;
- ngx_rbtree_node_t sentinel;
- ngx_queue_t queue;
- ngx_atomic_t cold;
- ngx_atomic_t loading;
- off_t size;
-} ngx_http_file_cache_sh_t;
-
-
-struct ngx_http_file_cache_s {
- ngx_http_file_cache_sh_t *sh;
- ngx_slab_pool_t *shpool;
-
- ngx_path_t *path;
-
- off_t max_size;
- size_t bsize;
-
- time_t inactive;
-
- ngx_uint_t files;
- ngx_uint_t loader_files;
- ngx_msec_t last;
- ngx_msec_t loader_sleep;
- ngx_msec_t loader_threshold;
-
- ngx_shm_zone_t *shm_zone;
-};
-
-
-ngx_int_t ngx_http_file_cache_new(ngx_http_request_t *r);
-ngx_int_t ngx_http_file_cache_create(ngx_http_request_t *r);
-void ngx_http_file_cache_create_key(ngx_http_request_t *r);
-ngx_int_t ngx_http_file_cache_open(ngx_http_request_t *r);
-void ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf);
-void ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf);
-void ngx_http_file_cache_update_header(ngx_http_request_t *r);
-ngx_int_t ngx_http_cache_send(ngx_http_request_t *);
-void ngx_http_file_cache_free(ngx_http_cache_t *c, ngx_temp_file_t *tf);
-time_t ngx_http_file_cache_valid(ngx_array_t *cache_valid, ngx_uint_t status);
-
-char *ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-char *ngx_http_file_cache_valid_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-extern ngx_str_t ngx_http_cache_status[];
-
-
-#endif /* _NGX_HTTP_CACHE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/ngx_http_config.h b/usr.sbin/nginx/src/http/ngx_http_config.h
deleted file mode 100644
index 2208c601b96..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_config.h
+++ /dev/null
@@ -1,75 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HTTP_CONFIG_H_INCLUDED_
-#define _NGX_HTTP_CONFIG_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- void **main_conf;
- void **srv_conf;
- void **loc_conf;
-} ngx_http_conf_ctx_t;
-
-
-typedef struct {
- ngx_int_t (*preconfiguration)(ngx_conf_t *cf);
- ngx_int_t (*postconfiguration)(ngx_conf_t *cf);
-
- void *(*create_main_conf)(ngx_conf_t *cf);
- char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
-
- void *(*create_srv_conf)(ngx_conf_t *cf);
- char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);
-
- void *(*create_loc_conf)(ngx_conf_t *cf);
- char *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
-} ngx_http_module_t;
-
-
-#define NGX_HTTP_MODULE 0x50545448 /* "HTTP" */
-
-#define NGX_HTTP_MAIN_CONF 0x02000000
-#define NGX_HTTP_SRV_CONF 0x04000000
-#define NGX_HTTP_LOC_CONF 0x08000000
-#define NGX_HTTP_UPS_CONF 0x10000000
-#define NGX_HTTP_SIF_CONF 0x20000000
-#define NGX_HTTP_LIF_CONF 0x40000000
-#define NGX_HTTP_LMT_CONF 0x80000000
-
-
-#define NGX_HTTP_MAIN_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, main_conf)
-#define NGX_HTTP_SRV_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, srv_conf)
-#define NGX_HTTP_LOC_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, loc_conf)
-
-
-#define ngx_http_get_module_main_conf(r, module) \
- (r)->main_conf[module.ctx_index]
-#define ngx_http_get_module_srv_conf(r, module) (r)->srv_conf[module.ctx_index]
-#define ngx_http_get_module_loc_conf(r, module) (r)->loc_conf[module.ctx_index]
-
-
-#define ngx_http_conf_get_module_main_conf(cf, module) \
- ((ngx_http_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
-#define ngx_http_conf_get_module_srv_conf(cf, module) \
- ((ngx_http_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index]
-#define ngx_http_conf_get_module_loc_conf(cf, module) \
- ((ngx_http_conf_ctx_t *) cf->ctx)->loc_conf[module.ctx_index]
-
-#define ngx_http_cycle_get_module_main_conf(cycle, module) \
- (cycle->conf_ctx[ngx_http_module.index] ? \
- ((ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]) \
- ->main_conf[module.ctx_index]: \
- NULL)
-
-
-#endif /* _NGX_HTTP_CONFIG_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/ngx_http_copy_filter_module.c b/usr.sbin/nginx/src/http/ngx_http_copy_filter_module.c
deleted file mode 100644
index 3ad27b0425b..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_copy_filter_module.c
+++ /dev/null
@@ -1,303 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- ngx_bufs_t bufs;
-} ngx_http_copy_filter_conf_t;
-
-
-#if (NGX_HAVE_FILE_AIO)
-static void ngx_http_copy_aio_handler(ngx_output_chain_ctx_t *ctx,
- ngx_file_t *file);
-static void ngx_http_copy_aio_event_handler(ngx_event_t *ev);
-#if (NGX_HAVE_AIO_SENDFILE)
-static void ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev);
-#endif
-#endif
-
-static void *ngx_http_copy_filter_create_conf(ngx_conf_t *cf);
-static char *ngx_http_copy_filter_merge_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static ngx_int_t ngx_http_copy_filter_init(ngx_conf_t *cf);
-
-
-static ngx_command_t ngx_http_copy_filter_commands[] = {
-
- { ngx_string("output_buffers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_conf_set_bufs_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_copy_filter_conf_t, bufs),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_copy_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_copy_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_copy_filter_create_conf, /* create location configuration */
- ngx_http_copy_filter_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_copy_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_copy_filter_module_ctx, /* module context */
- ngx_http_copy_filter_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-
-
-static ngx_int_t
-ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- ngx_int_t rc;
- ngx_connection_t *c;
- ngx_output_chain_ctx_t *ctx;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_copy_filter_conf_t *conf;
-
- c = r->connection;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http copy filter: \"%V?%V\"", &r->uri, &r->args);
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module);
-
- if (ctx == NULL) {
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_copy_filter_module);
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_copy_filter_module);
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- ctx->sendfile = c->sendfile;
- ctx->need_in_memory = r->main_filter_need_in_memory
- || r->filter_need_in_memory;
- ctx->need_in_temp = r->filter_need_temporary;
-
- ctx->alignment = clcf->directio_alignment;
-
- ctx->pool = r->pool;
- ctx->bufs = conf->bufs;
- ctx->tag = (ngx_buf_tag_t) &ngx_http_copy_filter_module;
-
- ctx->output_filter = (ngx_output_chain_filter_pt)
- ngx_http_next_body_filter;
- ctx->filter_ctx = r;
-
-#if (NGX_HAVE_FILE_AIO)
- if (ngx_file_aio) {
- if (clcf->aio) {
- ctx->aio_handler = ngx_http_copy_aio_handler;
- }
-#if (NGX_HAVE_AIO_SENDFILE)
- c->aio_sendfile = (clcf->aio == NGX_HTTP_AIO_SENDFILE);
-#endif
- }
-#endif
-
- if (in && in->buf && ngx_buf_size(in->buf)) {
- r->request_output = 1;
- }
- }
-
-#if (NGX_HAVE_FILE_AIO)
- ctx->aio = r->aio;
-#endif
-
- for ( ;; ) {
- rc = ngx_output_chain(ctx, in);
-
- if (ctx->in == NULL) {
- r->buffered &= ~NGX_HTTP_COPY_BUFFERED;
-
- } else {
- r->buffered |= NGX_HTTP_COPY_BUFFERED;
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args);
-
-#if (NGX_HAVE_FILE_AIO && NGX_HAVE_AIO_SENDFILE)
-
- if (c->busy_sendfile) {
- ssize_t n;
- off_t offset;
- ngx_file_t *file;
- ngx_http_ephemeral_t *e;
-
- if (r->aio) {
- c->busy_sendfile = NULL;
- return rc;
- }
-
- file = c->busy_sendfile->file;
- offset = c->busy_sendfile->file_pos;
-
- if (file->aio) {
- c->busy_count = (offset == file->aio->last_offset) ?
- c->busy_count + 1 : 0;
- file->aio->last_offset = offset;
-
- if (c->busy_count > 2) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "sendfile(%V) returned busy again",
- &file->name);
- c->aio_sendfile = 0;
- }
- }
-
- c->busy_sendfile = NULL;
- e = (ngx_http_ephemeral_t *) &r->uri_start;
-
- n = ngx_file_aio_read(file, &e->aio_preload, 1, offset, r->pool);
-
- if (n > 0) {
- in = NULL;
- continue;
- }
-
- rc = n;
-
- if (rc == NGX_AGAIN) {
- file->aio->data = r;
- file->aio->handler = ngx_http_copy_aio_sendfile_event_handler;
-
- r->main->blocked++;
- r->aio = 1;
- }
- }
-#endif
-
- return rc;
- }
-}
-
-
-#if (NGX_HAVE_FILE_AIO)
-
-static void
-ngx_http_copy_aio_handler(ngx_output_chain_ctx_t *ctx, ngx_file_t *file)
-{
- ngx_http_request_t *r;
-
- r = ctx->filter_ctx;
-
- file->aio->data = r;
- file->aio->handler = ngx_http_copy_aio_event_handler;
-
- r->main->blocked++;
- r->aio = 1;
- ctx->aio = 1;
-}
-
-
-static void
-ngx_http_copy_aio_event_handler(ngx_event_t *ev)
-{
- ngx_event_aio_t *aio;
- ngx_http_request_t *r;
-
- aio = ev->data;
- r = aio->data;
-
- r->main->blocked--;
- r->aio = 0;
-
- r->connection->write->handler(r->connection->write);
-}
-
-
-#if (NGX_HAVE_AIO_SENDFILE)
-
-static void
-ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev)
-{
- ngx_event_aio_t *aio;
- ngx_http_request_t *r;
-
- aio = ev->data;
- r = aio->data;
-
- r->main->blocked--;
- r->aio = 0;
- ev->complete = 0;
-
- r->connection->write->handler(r->connection->write);
-}
-
-#endif
-#endif
-
-
-static void *
-ngx_http_copy_filter_create_conf(ngx_conf_t *cf)
-{
- ngx_http_copy_filter_conf_t *conf;
-
- conf = ngx_palloc(cf->pool, sizeof(ngx_http_copy_filter_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- conf->bufs.num = 0;
-
- return conf;
-}
-
-
-static char *
-ngx_http_copy_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_copy_filter_conf_t *prev = parent;
- ngx_http_copy_filter_conf_t *conf = child;
-
- ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 1, 32768);
-
- return NULL;
-}
-
-
-static ngx_int_t
-ngx_http_copy_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_copy_filter;
-
- return NGX_OK;
-}
-
diff --git a/usr.sbin/nginx/src/http/ngx_http_core_module.c b/usr.sbin/nginx/src/http/ngx_http_core_module.c
deleted file mode 100644
index a77ac3b20e1..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_core_module.c
+++ /dev/null
@@ -1,5254 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- u_char *name;
- uint32_t method;
-} ngx_http_method_name_t;
-
-
-#define NGX_HTTP_REQUEST_BODY_FILE_OFF 0
-#define NGX_HTTP_REQUEST_BODY_FILE_ON 1
-#define NGX_HTTP_REQUEST_BODY_FILE_CLEAN 2
-
-
-static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r);
-static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r,
- ngx_http_location_tree_node_t *node);
-
-static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
-static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
-static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
-static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf);
-static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf,
- void *parent, void *child);
-static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child);
-
-static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
- void *dummy);
-static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd,
- void *dummy);
-static ngx_int_t ngx_http_core_regex_location(ngx_conf_t *cf,
- ngx_http_core_loc_conf_t *clcf, ngx_str_t *regex, ngx_uint_t caseless);
-
-static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy,
- void *conf);
-
-static char *ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-#if (NGX_HTTP_GZIP)
-static ngx_int_t ngx_http_gzip_accept_encoding(ngx_str_t *ae);
-static ngx_uint_t ngx_http_gzip_quantity(u_char *p, u_char *last);
-static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-#endif
-static ngx_int_t ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r,
- ngx_addr_t *addr, u_char *xff, size_t xfflen, ngx_array_t *proxies,
- int recursive);
-#if (NGX_HAVE_OPENAT)
-static char *ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-#endif
-
-static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data);
-static char *ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data);
-
-static ngx_conf_post_t ngx_http_core_lowat_post =
- { ngx_http_core_lowat_check };
-
-static ngx_conf_post_handler_pt ngx_http_core_pool_size_p =
- ngx_http_core_pool_size;
-
-static ngx_conf_deprecated_t ngx_conf_deprecated_optimize_server_names = {
- ngx_conf_deprecated, "optimize_server_names", "server_name_in_redirect"
-};
-
-static ngx_conf_deprecated_t ngx_conf_deprecated_open_file_cache_retest = {
- ngx_conf_deprecated, "open_file_cache_retest", "open_file_cache_valid"
-};
-
-static ngx_conf_deprecated_t ngx_conf_deprecated_satisfy_any = {
- ngx_conf_deprecated, "satisfy_any", "satisfy"
-};
-
-
-static ngx_conf_enum_t ngx_http_core_request_body_in_file[] = {
- { ngx_string("off"), NGX_HTTP_REQUEST_BODY_FILE_OFF },
- { ngx_string("on"), NGX_HTTP_REQUEST_BODY_FILE_ON },
- { ngx_string("clean"), NGX_HTTP_REQUEST_BODY_FILE_CLEAN },
- { ngx_null_string, 0 }
-};
-
-
-#if (NGX_HAVE_FILE_AIO)
-
-static ngx_conf_enum_t ngx_http_core_aio[] = {
- { ngx_string("off"), NGX_HTTP_AIO_OFF },
- { ngx_string("on"), NGX_HTTP_AIO_ON },
-#if (NGX_HAVE_AIO_SENDFILE)
- { ngx_string("sendfile"), NGX_HTTP_AIO_SENDFILE },
-#endif
- { ngx_null_string, 0 }
-};
-
-#endif
-
-
-static ngx_conf_enum_t ngx_http_core_satisfy[] = {
- { ngx_string("all"), NGX_HTTP_SATISFY_ALL },
- { ngx_string("any"), NGX_HTTP_SATISFY_ANY },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_conf_enum_t ngx_http_core_lingering_close[] = {
- { ngx_string("off"), NGX_HTTP_LINGERING_OFF },
- { ngx_string("on"), NGX_HTTP_LINGERING_ON },
- { ngx_string("always"), NGX_HTTP_LINGERING_ALWAYS },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_conf_enum_t ngx_http_core_if_modified_since[] = {
- { ngx_string("off"), NGX_HTTP_IMS_OFF },
- { ngx_string("exact"), NGX_HTTP_IMS_EXACT },
- { ngx_string("before"), NGX_HTTP_IMS_BEFORE },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_conf_bitmask_t ngx_http_core_keepalive_disable[] = {
- { ngx_string("none"), NGX_HTTP_KEEPALIVE_DISABLE_NONE },
- { ngx_string("msie6"), NGX_HTTP_KEEPALIVE_DISABLE_MSIE6 },
- { ngx_string("safari"), NGX_HTTP_KEEPALIVE_DISABLE_SAFARI },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_path_init_t ngx_http_client_temp_path = {
- ngx_string(NGX_HTTP_CLIENT_TEMP_PATH), { 0, 0, 0 }
-};
-
-
-#if (NGX_HTTP_GZIP)
-
-static ngx_conf_enum_t ngx_http_gzip_http_version[] = {
- { ngx_string("1.0"), NGX_HTTP_VERSION_10 },
- { ngx_string("1.1"), NGX_HTTP_VERSION_11 },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_conf_bitmask_t ngx_http_gzip_proxied_mask[] = {
- { ngx_string("off"), NGX_HTTP_GZIP_PROXIED_OFF },
- { ngx_string("expired"), NGX_HTTP_GZIP_PROXIED_EXPIRED },
- { ngx_string("no-cache"), NGX_HTTP_GZIP_PROXIED_NO_CACHE },
- { ngx_string("no-store"), NGX_HTTP_GZIP_PROXIED_NO_STORE },
- { ngx_string("private"), NGX_HTTP_GZIP_PROXIED_PRIVATE },
- { ngx_string("no_last_modified"), NGX_HTTP_GZIP_PROXIED_NO_LM },
- { ngx_string("no_etag"), NGX_HTTP_GZIP_PROXIED_NO_ETAG },
- { ngx_string("auth"), NGX_HTTP_GZIP_PROXIED_AUTH },
- { ngx_string("any"), NGX_HTTP_GZIP_PROXIED_ANY },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_str_t ngx_http_gzip_no_cache = ngx_string("no-cache");
-static ngx_str_t ngx_http_gzip_no_store = ngx_string("no-store");
-static ngx_str_t ngx_http_gzip_private = ngx_string("private");
-
-#endif
-
-
-static ngx_command_t ngx_http_core_commands[] = {
-
- { ngx_string("variables_hash_max_size"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_MAIN_CONF_OFFSET,
- offsetof(ngx_http_core_main_conf_t, variables_hash_max_size),
- NULL },
-
- { ngx_string("variables_hash_bucket_size"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_MAIN_CONF_OFFSET,
- offsetof(ngx_http_core_main_conf_t, variables_hash_bucket_size),
- NULL },
-
- { ngx_string("server_names_hash_max_size"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_MAIN_CONF_OFFSET,
- offsetof(ngx_http_core_main_conf_t, server_names_hash_max_size),
- NULL },
-
- { ngx_string("server_names_hash_bucket_size"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_MAIN_CONF_OFFSET,
- offsetof(ngx_http_core_main_conf_t, server_names_hash_bucket_size),
- NULL },
-
- { ngx_string("server"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
- ngx_http_core_server,
- 0,
- 0,
- NULL },
-
- { ngx_string("connection_pool_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_core_srv_conf_t, connection_pool_size),
- &ngx_http_core_pool_size_p },
-
- { ngx_string("request_pool_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_core_srv_conf_t, request_pool_size),
- &ngx_http_core_pool_size_p },
-
- { ngx_string("client_header_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_core_srv_conf_t, client_header_timeout),
- NULL },
-
- { ngx_string("client_header_buffer_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_core_srv_conf_t, client_header_buffer_size),
- NULL },
-
- { ngx_string("large_client_header_buffers"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2,
- ngx_conf_set_bufs_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers),
- NULL },
-
- { ngx_string("optimize_server_names"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, server_name_in_redirect),
- &ngx_conf_deprecated_optimize_server_names },
-
- { ngx_string("ignore_invalid_headers"),
- 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, 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("underscores_in_headers"),
- 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, underscores_in_headers),
- NULL },
-
- { ngx_string("location"),
- NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
- ngx_http_core_location,
- NGX_HTTP_SRV_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("listen"),
- NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
- ngx_http_core_listen,
- NGX_HTTP_SRV_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("server_name"),
- NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
- ngx_http_core_server_name,
- NGX_HTTP_SRV_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("types_hash_max_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, types_hash_max_size),
- NULL },
-
- { ngx_string("types_hash_bucket_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, types_hash_bucket_size),
- NULL },
-
- { ngx_string("types"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
- |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
- ngx_http_core_types,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("default_type"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, default_type),
- NULL },
-
- { ngx_string("root"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_TAKE1,
- ngx_http_core_root,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("alias"),
- NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_core_root,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("limit_except"),
- NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE,
- ngx_http_core_limit_except,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("client_max_body_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_off_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, client_max_body_size),
- NULL },
-
- { ngx_string("client_body_buffer_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, client_body_buffer_size),
- NULL },
-
- { ngx_string("client_body_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, client_body_timeout),
- NULL },
-
- { ngx_string("client_body_temp_path"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
- ngx_conf_set_path_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, client_body_temp_path),
- NULL },
-
- { ngx_string("client_body_in_file_only"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, client_body_in_file_only),
- &ngx_http_core_request_body_in_file },
-
- { ngx_string("client_body_in_single_buffer"),
- 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, client_body_in_single_buffer),
- NULL },
-
- { ngx_string("sendfile"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, sendfile),
- NULL },
-
- { ngx_string("sendfile_max_chunk"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, sendfile_max_chunk),
- NULL },
-
-#if (NGX_HAVE_FILE_AIO)
-
- { ngx_string("aio"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, aio),
- &ngx_http_core_aio },
-
-#endif
-
- { ngx_string("read_ahead"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, read_ahead),
- NULL },
-
- { ngx_string("directio"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_core_directio,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("directio_alignment"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_off_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, directio_alignment),
- NULL },
-
- { ngx_string("tcp_nopush"),
- 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, tcp_nopush),
- NULL },
-
- { ngx_string("tcp_nodelay"),
- 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, tcp_nodelay),
- NULL },
-
- { ngx_string("send_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, send_timeout),
- NULL },
-
- { ngx_string("send_lowat"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, send_lowat),
- &ngx_http_core_lowat_post },
-
- { ngx_string("postpone_output"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, postpone_output),
- NULL },
-
- { ngx_string("limit_rate"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, limit_rate),
- NULL },
-
- { ngx_string("limit_rate_after"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, limit_rate_after),
- NULL },
-
- { ngx_string("keepalive_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
- ngx_http_core_keepalive,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("keepalive_requests"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, keepalive_requests),
- NULL },
-
- { ngx_string("keepalive_disable"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, keepalive_disable),
- &ngx_http_core_keepalive_disable },
-
- { ngx_string("satisfy"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, satisfy),
- &ngx_http_core_satisfy },
-
- { ngx_string("satisfy_any"),
- 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, satisfy),
- &ngx_conf_deprecated_satisfy_any },
-
- { ngx_string("internal"),
- NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
- ngx_http_core_internal,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("lingering_close"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, lingering_close),
- &ngx_http_core_lingering_close },
-
- { ngx_string("lingering_time"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, lingering_time),
- NULL },
-
- { ngx_string("lingering_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, lingering_timeout),
- NULL },
-
- { ngx_string("reset_timedout_connection"),
- 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, reset_timedout_connection),
- NULL },
-
- { ngx_string("server_name_in_redirect"),
- 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_name_in_redirect),
- NULL },
-
- { ngx_string("port_in_redirect"),
- 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, port_in_redirect),
- NULL },
-
- { ngx_string("msie_padding"),
- 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, msie_padding),
- NULL },
-
- { ngx_string("msie_refresh"),
- 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, msie_refresh),
- NULL },
-
- { ngx_string("log_not_found"),
- 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, log_not_found),
- NULL },
-
- { ngx_string("log_subrequest"),
- 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, log_subrequest),
- NULL },
-
- { ngx_string("recursive_error_pages"),
- 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, 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("if_modified_since"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, if_modified_since),
- &ngx_http_core_if_modified_since },
-
- { ngx_string("max_ranges"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, max_ranges),
- NULL },
-
- { ngx_string("chunked_transfer_encoding"),
- 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, chunked_transfer_encoding),
- NULL },
-
- { ngx_string("etag"),
- 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, etag),
- NULL },
-
- { ngx_string("error_page"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_2MORE,
- ngx_http_core_error_page,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("try_files"),
- NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
- ngx_http_core_try_files,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("post_action"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
- |NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, post_action),
- NULL },
-
- { ngx_string("error_log"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_core_error_log,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("open_file_cache"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
- ngx_http_core_open_file_cache,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, open_file_cache),
- NULL },
-
- { ngx_string("open_file_cache_valid"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_sec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
- NULL },
-
- { ngx_string("open_file_cache_retest"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_sec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
- &ngx_conf_deprecated_open_file_cache_retest },
-
- { ngx_string("open_file_cache_min_uses"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, open_file_cache_min_uses),
- NULL },
-
- { ngx_string("open_file_cache_errors"),
- 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, open_file_cache_errors),
- NULL },
-
- { ngx_string("open_file_cache_events"),
- 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, open_file_cache_events),
- NULL },
-
- { ngx_string("resolver"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_core_resolver,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("resolver_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, resolver_timeout),
- NULL },
-
-#if (NGX_HTTP_GZIP)
-
- { 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_core_loc_conf_t, gzip_vary),
- NULL },
-
- { ngx_string("gzip_http_version"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, gzip_http_version),
- &ngx_http_gzip_http_version },
-
- { ngx_string("gzip_proxied"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_core_loc_conf_t, gzip_proxied),
- &ngx_http_gzip_proxied_mask },
-
- { ngx_string("gzip_disable"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_gzip_disable,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
-#endif
-
-#if (NGX_HAVE_OPENAT)
-
- { ngx_string("disable_symlinks"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
- ngx_http_disable_symlinks,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
-#endif
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_core_module_ctx = {
- ngx_http_core_preconfiguration, /* preconfiguration */
- NULL, /* postconfiguration */
-
- ngx_http_core_create_main_conf, /* create main configuration */
- ngx_http_core_init_main_conf, /* init main configuration */
-
- ngx_http_core_create_srv_conf, /* create server configuration */
- ngx_http_core_merge_srv_conf, /* merge server configuration */
-
- ngx_http_core_create_loc_conf, /* create location configuration */
- ngx_http_core_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_core_module = {
- NGX_MODULE_V1,
- &ngx_http_core_module_ctx, /* module context */
- ngx_http_core_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-ngx_str_t ngx_http_core_get_method = { 3, (u_char *) "GET " };
-
-
-void
-ngx_http_handler(ngx_http_request_t *r)
-{
- ngx_http_core_main_conf_t *cmcf;
-
- r->connection->log->action = NULL;
-
- r->connection->unexpected_eof = 0;
-
- if (!r->internal) {
- switch (r->headers_in.connection_type) {
- case 0:
- r->keepalive = (r->http_version > NGX_HTTP_VERSION_10);
- break;
-
- case NGX_HTTP_CONNECTION_CLOSE:
- r->keepalive = 0;
- break;
-
- case NGX_HTTP_CONNECTION_KEEP_ALIVE:
- r->keepalive = 1;
- break;
- }
-
- r->lingering_close = (r->headers_in.content_length_n > 0
- || r->headers_in.chunked);
- r->phase_handler = 0;
-
- } else {
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
- r->phase_handler = cmcf->phase_engine.server_rewrite_index;
- }
-
- r->valid_location = 1;
-#if (NGX_HTTP_GZIP)
- r->gzip_tested = 0;
- r->gzip_ok = 0;
- r->gzip_vary = 0;
-#endif
-
- r->write_event_handler = ngx_http_core_run_phases;
- ngx_http_core_run_phases(r);
-}
-
-
-void
-ngx_http_core_run_phases(ngx_http_request_t *r)
-{
- ngx_int_t rc;
- ngx_http_phase_handler_t *ph;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
- ph = cmcf->phase_engine.handlers;
-
- while (ph[r->phase_handler].checker) {
-
- rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);
-
- if (rc == NGX_OK) {
- return;
- }
- }
-}
-
-
-ngx_int_t
-ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
-{
- ngx_int_t rc;
-
- /*
- * generic phase checker,
- * used by the post read and pre-access phases
- */
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "generic phase: %ui", r->phase_handler);
-
- rc = ph->handler(r);
-
- if (rc == NGX_OK) {
- r->phase_handler = ph->next;
- return NGX_AGAIN;
- }
-
- if (rc == NGX_DECLINED) {
- r->phase_handler++;
- return NGX_AGAIN;
- }
-
- if (rc == NGX_AGAIN || rc == NGX_DONE) {
- return NGX_OK;
- }
-
- /* rc == NGX_ERROR || rc == NGX_HTTP_... */
-
- ngx_http_finalize_request(r, rc);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_core_rewrite_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
-{
- ngx_int_t rc;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "rewrite phase: %ui", r->phase_handler);
-
- rc = ph->handler(r);
-
- if (rc == NGX_DECLINED) {
- r->phase_handler++;
- return NGX_AGAIN;
- }
-
- if (rc == NGX_DONE) {
- return NGX_OK;
- }
-
- /* NGX_OK, NGX_AGAIN, NGX_ERROR, NGX_HTTP_... */
-
- ngx_http_finalize_request(r, rc);
-
- return NGX_OK;
-}
-
-
-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;
-
- r->content_handler = NULL;
- r->uri_changed = 0;
-
- rc = ngx_http_core_find_location(r);
-
- if (rc == NGX_ERROR) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_OK;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (!r->internal && clcf->internal) {
- ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
- return NGX_OK;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "using configuration \"%s%V\"",
- (clcf->noname ? "*" : (clcf->exact_match ? "=" : "")),
- &clcf->name);
-
- ngx_http_update_location_config(r);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http cl:%O max:%O",
- r->headers_in.content_length_n, clcf->client_max_body_size);
-
- if (r->headers_in.content_length_n != -1
- && !r->discard_body
- && clcf->client_max_body_size
- && clcf->client_max_body_size < r->headers_in.content_length_n)
- {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client intended to send too large body: %O bytes",
- r->headers_in.content_length_n);
-
- r->expect_tested = 1;
- (void) ngx_http_discard_request_body(r);
- ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
- return NGX_OK;
- }
-
- if (rc == NGX_DONE) {
- ngx_http_clear_location(r);
-
- r->headers_out.location = ngx_list_push(&r->headers_out.headers);
- if (r->headers_out.location == NULL) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_OK;
- }
-
- /*
- * we do not need to set the r->headers_out.location->hash and
- * r->headers_out.location->key fields
- */
-
- if (r->args.len == 0) {
- r->headers_out.location->value = clcf->name;
-
- } else {
- len = clcf->name.len + 1 + r->args.len;
- p = ngx_pnalloc(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;
- }
-
- r->phase_handler++;
- return NGX_AGAIN;
-}
-
-
-ngx_int_t
-ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
- ngx_http_phase_handler_t *ph)
-{
- ngx_http_core_srv_conf_t *cscf;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "post rewrite phase: %ui", r->phase_handler);
-
- if (!r->uri_changed) {
- r->phase_handler++;
- return NGX_AGAIN;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "uri changes: %d", r->uri_changes);
-
- /*
- * gcc before 3.3 compiles the broken code for
- * if (r->uri_changes-- == 0)
- * if the r->uri_changes is defined as
- * unsigned uri_changes:4
- */
-
- r->uri_changes--;
-
- if (r->uri_changes == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "rewrite or internal redirection cycle "
- "while processing \"%V\"", &r->uri);
-
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_OK;
- }
-
- r->phase_handler = ph->next;
-
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
- r->loc_conf = cscf->ctx->loc_conf;
-
- return NGX_AGAIN;
-}
-
-
-ngx_int_t
-ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
-{
- ngx_int_t rc;
- ngx_http_core_loc_conf_t *clcf;
-
- if (r != r->main) {
- r->phase_handler = ph->next;
- return NGX_AGAIN;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "access phase: %ui", r->phase_handler);
-
- rc = ph->handler(r);
-
- if (rc == NGX_DECLINED) {
- r->phase_handler++;
- return NGX_AGAIN;
- }
-
- if (rc == NGX_AGAIN || rc == NGX_DONE) {
- return NGX_OK;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->satisfy == NGX_HTTP_SATISFY_ALL) {
-
- if (rc == NGX_OK) {
- r->phase_handler++;
- return NGX_AGAIN;
- }
-
- } else {
- if (rc == NGX_OK) {
- r->access_code = 0;
-
- if (r->headers_out.www_authenticate) {
- r->headers_out.www_authenticate->hash = 0;
- }
-
- r->phase_handler = ph->next;
- return NGX_AGAIN;
- }
-
- if (rc == NGX_HTTP_FORBIDDEN || rc == NGX_HTTP_UNAUTHORIZED) {
- if (r->access_code != NGX_HTTP_UNAUTHORIZED) {
- r->access_code = rc;
- }
-
- r->phase_handler++;
- return NGX_AGAIN;
- }
- }
-
- /* rc == NGX_ERROR || rc == NGX_HTTP_... */
-
- ngx_http_finalize_request(r, rc);
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_core_post_access_phase(ngx_http_request_t *r,
- ngx_http_phase_handler_t *ph)
-{
- ngx_int_t access_code;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "post access phase: %ui", r->phase_handler);
-
- access_code = r->access_code;
-
- if (access_code) {
- if (access_code == NGX_HTTP_FORBIDDEN) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "access forbidden by rule");
- }
-
- r->access_code = 0;
- ngx_http_finalize_request(r, access_code);
- return NGX_OK;
- }
-
- r->phase_handler++;
- return NGX_AGAIN;
-}
-
-
-ngx_int_t
-ngx_http_core_try_files_phase(ngx_http_request_t *r,
- ngx_http_phase_handler_t *ph)
-{
- size_t len, root, alias, reserve, allocated;
- u_char *p, *name;
- ngx_str_t path, args;
- ngx_uint_t test_dir;
- ngx_http_try_file_t *tf;
- ngx_open_file_info_t of;
- ngx_http_script_code_pt code;
- ngx_http_script_engine_t e;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_script_len_code_pt lcode;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "try files phase: %ui", r->phase_handler);
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->try_files == NULL) {
- r->phase_handler++;
- return NGX_AGAIN;
- }
-
- allocated = 0;
- root = 0;
- name = NULL;
- /* suppress MSVC warning */
- path.data = NULL;
-
- tf = clcf->try_files;
-
- alias = clcf->alias;
-
- for ( ;; ) {
-
- if (tf->lengths) {
- ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
-
- e.ip = tf->lengths->elts;
- e.request = r;
-
- /* 1 is for terminating '\0' as in static names */
- len = 1;
-
- while (*(uintptr_t *) e.ip) {
- lcode = *(ngx_http_script_len_code_pt *) e.ip;
- len += lcode(&e);
- }
-
- } else {
- len = tf->name.len;
- }
-
- if (!alias) {
- reserve = len > r->uri.len ? len - r->uri.len : 0;
-
-#if (NGX_PCRE)
- } else if (clcf->regex) {
- reserve = len;
-#endif
-
- } else {
- reserve = len > r->uri.len - alias ? len - (r->uri.len - alias) : 0;
- }
-
- if (reserve > allocated || !allocated) {
-
- /* 16 bytes are preallocation */
- allocated = reserve + 16;
-
- if (ngx_http_map_uri_to_path(r, &path, &root, allocated) == NULL) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_OK;
- }
-
- name = path.data + root;
- }
-
- if (tf->values == NULL) {
-
- /* tf->name.len includes the terminating '\0' */
-
- ngx_memcpy(name, tf->name.data, tf->name.len);
-
- path.len = (name + tf->name.len - 1) - path.data;
-
- } else {
- e.ip = tf->values->elts;
- e.pos = name;
- e.flushed = 1;
-
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
- }
-
- path.len = e.pos - path.data;
-
- *e.pos = '\0';
-
- if (alias && ngx_strncmp(name, clcf->name.data, alias) == 0) {
- ngx_memmove(name, name + alias, len - alias);
- path.len -= alias;
- }
- }
-
- test_dir = tf->test_dir;
-
- tf++;
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "trying to use %s: \"%s\" \"%s\"",
- test_dir ? "dir" : "file", name, path.data);
-
- if (tf->lengths == NULL && tf->name.len == 0) {
-
- if (tf->code) {
- ngx_http_finalize_request(r, tf->code);
- return NGX_OK;
- }
-
- path.len -= root;
- path.data += root;
-
- if (path.data[0] == '@') {
- (void) ngx_http_named_location(r, &path);
-
- } else {
- ngx_http_split_args(r, &path, &args);
-
- (void) ngx_http_internal_redirect(r, &path, &args);
- }
-
- ngx_http_finalize_request(r, NGX_DONE);
- return NGX_OK;
- }
-
- ngx_memzero(&of, sizeof(ngx_open_file_info_t));
-
- of.read_ahead = clcf->read_ahead;
- of.directio = clcf->directio;
- of.valid = clcf->open_file_cache_valid;
- of.min_uses = clcf->open_file_cache_min_uses;
- of.test_only = 1;
- of.errors = clcf->open_file_cache_errors;
- of.events = clcf->open_file_cache_events;
-
- if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_OK;
- }
-
- if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
- != NGX_OK)
- {
- if (of.err != NGX_ENOENT
- && of.err != NGX_ENOTDIR
- && of.err != NGX_ENAMETOOLONG)
- {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
- "%s \"%s\" failed", of.failed, path.data);
- }
-
- continue;
- }
-
- if (of.is_dir && !test_dir) {
- continue;
- }
-
- path.len -= root;
- path.data += root;
-
- if (!alias) {
- r->uri = path;
-
-#if (NGX_PCRE)
- } else if (clcf->regex) {
- if (!test_dir) {
- r->uri = path;
- r->add_uri_to_alias = 1;
- }
-#endif
- } else {
- r->uri.len = alias + path.len;
- r->uri.data = ngx_pnalloc(r->pool, r->uri.len);
- if (r->uri.data == NULL) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_OK;
- }
-
- p = ngx_copy(r->uri.data, clcf->name.data, alias);
- ngx_memcpy(p, name, path.len);
- }
-
- ngx_http_set_exten(r);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "try file uri: \"%V\"", &r->uri);
-
- r->phase_handler++;
- return NGX_AGAIN;
- }
-
- /* not reached */
-}
-
-
-ngx_int_t
-ngx_http_core_content_phase(ngx_http_request_t *r,
- ngx_http_phase_handler_t *ph)
-{
- size_t root;
- ngx_int_t rc;
- ngx_str_t path;
-
- if (r->content_handler) {
- r->write_event_handler = ngx_http_request_empty_handler;
- ngx_http_finalize_request(r, r->content_handler(r));
- return NGX_OK;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "content phase: %ui", r->phase_handler);
-
- rc = ph->handler(r);
-
- if (rc != NGX_DECLINED) {
- ngx_http_finalize_request(r, rc);
- return NGX_OK;
- }
-
- /* rc == NGX_DECLINED */
-
- ph++;
-
- if (ph->checker) {
- r->phase_handler++;
- return NGX_AGAIN;
- }
-
- /* no content handler was found */
-
- if (r->uri.data[r->uri.len - 1] == '/') {
-
- 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 \"%s\" is forbidden", path.data);
- }
-
- ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no handler found");
-
- ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
- return NGX_OK;
-}
-
-
-void
-ngx_http_update_location_config(ngx_http_request_t *r)
-{
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (r->method & clcf->limit_except) {
- r->loc_conf = clcf->limit_except_loc_conf;
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- }
-
- if (r == r->main) {
- ngx_http_set_connection_log(r->connection, clcf->error_log);
- }
-
- if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) {
- r->connection->sendfile = 1;
-
- } else {
- r->connection->sendfile = 0;
- }
-
- if (clcf->client_body_in_file_only) {
- r->request_body_in_file_only = 1;
- r->request_body_in_persistent_file = 1;
- r->request_body_in_clean_file =
- clcf->client_body_in_file_only == NGX_HTTP_REQUEST_BODY_FILE_CLEAN;
- r->request_body_file_log_level = NGX_LOG_NOTICE;
-
- } else {
- r->request_body_file_log_level = NGX_LOG_WARN;
- }
-
- r->request_body_in_single_buf = clcf->client_body_in_single_buffer;
-
- if (r->keepalive) {
- if (clcf->keepalive_timeout == 0) {
- r->keepalive = 0;
-
- } else if (r->connection->requests >= clcf->keepalive_requests) {
- r->keepalive = 0;
-
- } else if (r->headers_in.msie6
- && r->method == NGX_HTTP_POST
- && (clcf->keepalive_disable
- & NGX_HTTP_KEEPALIVE_DISABLE_MSIE6))
- {
- /*
- * MSIE may wait for some time if an response for
- * a POST request was sent over a keepalive connection
- */
- r->keepalive = 0;
-
- } else if (r->headers_in.safari
- && (clcf->keepalive_disable
- & NGX_HTTP_KEEPALIVE_DISABLE_SAFARI))
- {
- /*
- * Safari may send a POST request to a closed keepalive
- * connection and may stall for some time, see
- * https://bugs.webkit.org/show_bug.cgi?id=5760
- */
- r->keepalive = 0;
- }
- }
-
- if (!clcf->tcp_nopush) {
- /* disable TCP_NOPUSH/TCP_CORK use */
- r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
- }
-
- if (r->limit_rate == 0) {
- r->limit_rate = clcf->limit_rate;
- }
-
- if (clcf->handler) {
- r->content_handler = clcf->handler;
- }
-}
-
-
-/*
- * NGX_OK - exact or regex match
- * NGX_DONE - auto redirect
- * NGX_AGAIN - inclusive match
- * NGX_ERROR - regex error
- * NGX_DECLINED - no match
- */
-
-static ngx_int_t
-ngx_http_core_find_location(ngx_http_request_t *r)
-{
- ngx_int_t rc;
- ngx_http_core_loc_conf_t *pclcf;
-#if (NGX_PCRE)
- ngx_int_t n;
- ngx_uint_t noregex;
- ngx_http_core_loc_conf_t *clcf, **clcfp;
-
- noregex = 0;
-#endif
-
- pclcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- rc = ngx_http_core_find_static_location(r, pclcf->static_locations);
-
- if (rc == NGX_AGAIN) {
-
-#if (NGX_PCRE)
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- noregex = clcf->noregex;
-#endif
-
- /* look up nested locations */
-
- rc = ngx_http_core_find_location(r);
- }
-
- if (rc == NGX_OK || rc == NGX_DONE) {
- return rc;
- }
-
- /* rc == NGX_DECLINED or rc == NGX_AGAIN in nested location */
-
-#if (NGX_PCRE)
-
- if (noregex == 0 && pclcf->regex_locations) {
-
- for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "test location: ~ \"%V\"", &(*clcfp)->name);
-
- n = ngx_http_regex_exec(r, (*clcfp)->regex, &r->uri);
-
- if (n == NGX_OK) {
- r->loc_conf = (*clcfp)->loc_conf;
-
- /* look up nested locations */
-
- rc = ngx_http_core_find_location(r);
-
- return (rc == NGX_ERROR) ? rc : NGX_OK;
- }
-
- if (n == NGX_DECLINED) {
- continue;
- }
-
- return NGX_ERROR;
- }
- }
-#endif
-
- return rc;
-}
-
-
-/*
- * NGX_OK - exact match
- * NGX_DONE - auto redirect
- * NGX_AGAIN - inclusive match
- * NGX_DECLINED - no match
- */
-
-static ngx_int_t
-ngx_http_core_find_static_location(ngx_http_request_t *r,
- ngx_http_location_tree_node_t *node)
-{
- u_char *uri;
- size_t len, n;
- ngx_int_t rc, rv;
-
- len = r->uri.len;
- uri = r->uri.data;
-
- rv = NGX_DECLINED;
-
- for ( ;; ) {
-
- if (node == NULL) {
- return rv;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "test location: \"%*s\"", node->len, node->name);
-
- n = (len <= (size_t) node->len) ? len : node->len;
-
- rc = ngx_filename_cmp(uri, node->name, n);
-
- if (rc != 0) {
- node = (rc < 0) ? node->left : node->right;
-
- continue;
- }
-
- if (len > (size_t) node->len) {
-
- if (node->inclusive) {
-
- r->loc_conf = node->inclusive->loc_conf;
- rv = NGX_AGAIN;
-
- node = node->tree;
- uri += n;
- len -= n;
-
- continue;
- }
-
- /* exact only */
-
- node = node->right;
-
- continue;
- }
-
- if (len == (size_t) node->len) {
-
- if (node->exact) {
- r->loc_conf = node->exact->loc_conf;
- return NGX_OK;
-
- } else {
- r->loc_conf = node->inclusive->loc_conf;
- return NGX_AGAIN;
- }
- }
-
- /* len < node->len */
-
- if (len + 1 == (size_t) node->len && node->auto_redirect) {
-
- r->loc_conf = (node->exact) ? node->exact->loc_conf:
- node->inclusive->loc_conf;
- rv = NGX_DONE;
- }
-
- node = node->left;
- }
-}
-
-
-void *
-ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash)
-{
- u_char c, *lowcase;
- size_t len;
- ngx_uint_t i, hash;
-
- if (types_hash->size == 0) {
- return (void *) 4;
- }
-
- if (r->headers_out.content_type.len == 0) {
- return NULL;
- }
-
- len = r->headers_out.content_type_len;
-
- if (r->headers_out.content_type_lowcase == NULL) {
-
- lowcase = ngx_pnalloc(r->pool, len);
- if (lowcase == NULL) {
- return NULL;
- }
-
- r->headers_out.content_type_lowcase = lowcase;
-
- hash = 0;
-
- for (i = 0; i < len; i++) {
- c = ngx_tolower(r->headers_out.content_type.data[i]);
- hash = ngx_hash(hash, c);
- lowcase[i] = c;
- }
-
- r->headers_out.content_type_hash = hash;
- }
-
- return ngx_hash_find(types_hash, r->headers_out.content_type_hash,
- r->headers_out.content_type_lowcase, len);
-}
-
-
-ngx_int_t
-ngx_http_set_content_type(ngx_http_request_t *r)
-{
- u_char c, *exten;
- ngx_str_t *type;
- ngx_uint_t i, hash;
- ngx_http_core_loc_conf_t *clcf;
-
- if (r->headers_out.content_type.len) {
- return NGX_OK;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (r->exten.len) {
-
- hash = 0;
-
- for (i = 0; i < r->exten.len; i++) {
- c = r->exten.data[i];
-
- if (c >= 'A' && c <= 'Z') {
-
- exten = ngx_pnalloc(r->pool, r->exten.len);
- if (exten == NULL) {
- return NGX_ERROR;
- }
-
- hash = ngx_hash_strlow(exten, r->exten.data, r->exten.len);
-
- r->exten.data = exten;
-
- break;
- }
-
- hash = ngx_hash(hash, c);
- }
-
- type = ngx_hash_find(&clcf->types_hash, hash,
- r->exten.data, r->exten.len);
-
- if (type) {
- r->headers_out.content_type_len = type->len;
- r->headers_out.content_type = *type;
-
- return NGX_OK;
- }
- }
-
- r->headers_out.content_type_len = clcf->default_type.len;
- r->headers_out.content_type = clcf->default_type;
-
- return NGX_OK;
-}
-
-
-void
-ngx_http_set_exten(ngx_http_request_t *r)
-{
- ngx_int_t i;
-
- ngx_str_null(&r->exten);
-
- for (i = r->uri.len - 1; i > 1; i--) {
- if (r->uri.data[i] == '.' && r->uri.data[i - 1] != '/') {
-
- r->exten.len = r->uri.len - i - 1;
- r->exten.data = &r->uri.data[i + 1];
-
- return;
-
- } else if (r->uri.data[i] == '/') {
- return;
- }
- }
-
- return;
-}
-
-
-ngx_int_t
-ngx_http_set_etag(ngx_http_request_t *r)
-{
- ngx_table_elt_t *etag;
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (!clcf->etag) {
- return NGX_OK;
- }
-
- etag = ngx_list_push(&r->headers_out.headers);
- if (etag == NULL) {
- return NGX_ERROR;
- }
-
- etag->hash = 1;
- ngx_str_set(&etag->key, "ETag");
-
- etag->value.data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + NGX_TIME_T_LEN + 3);
- if (etag->value.data == NULL) {
- return NGX_ERROR;
- }
-
- etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"",
- r->headers_out.last_modified_time,
- r->headers_out.content_length_n)
- - etag->value.data;
-
- r->headers_out.etag = etag;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
- ngx_str_t *ct, ngx_http_complex_value_t *cv)
-{
- ngx_int_t rc;
- ngx_str_t val;
- ngx_buf_t *b;
- ngx_chain_t out;
-
- if (ngx_http_discard_request_body(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- r->headers_out.status = status;
-
- if (ngx_http_complex_value(r, cv, &val) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (status == NGX_HTTP_MOVED_PERMANENTLY
- || status == NGX_HTTP_MOVED_TEMPORARILY
- || status == NGX_HTTP_SEE_OTHER
- || status == NGX_HTTP_TEMPORARY_REDIRECT)
- {
- ngx_http_clear_location(r);
-
- r->headers_out.location = ngx_list_push(&r->headers_out.headers);
- if (r->headers_out.location == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- r->headers_out.location->hash = 1;
- ngx_str_set(&r->headers_out.location->key, "Location");
- r->headers_out.location->value = val;
-
- return status;
- }
-
- r->headers_out.content_length_n = val.len;
-
- if (ct) {
- r->headers_out.content_type_len = ct->len;
- r->headers_out.content_type = *ct;
-
- } else {
- if (ngx_http_set_content_type(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
- }
-
- if (r->method == NGX_HTTP_HEAD || (r != r->main && val.len == 0)) {
- return ngx_http_send_header(r);
- }
-
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- b->pos = val.data;
- b->last = val.data + val.len;
- b->memory = val.len ? 1 : 0;
- b->last_buf = (r == r->main) ? 1 : 0;
- b->last_in_chain = 1;
-
- out.buf = b;
- out.next = NULL;
-
- rc = ngx_http_send_header(r);
-
- if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
- return rc;
- }
-
- return ngx_http_output_filter(r, &out);
-}
-
-
-ngx_int_t
-ngx_http_send_header(ngx_http_request_t *r)
-{
- if (r->header_sent) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "header already sent");
- return NGX_ERROR;
- }
-
- if (r->err_status) {
- r->headers_out.status = r->err_status;
- r->headers_out.status_line.len = 0;
- }
-
- return ngx_http_top_header_filter(r);
-}
-
-
-ngx_int_t
-ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- ngx_int_t rc;
- ngx_connection_t *c;
-
- c = r->connection;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http output filter \"%V?%V\"", &r->uri, &r->args);
-
- rc = ngx_http_top_body_filter(r, in);
-
- if (rc == NGX_ERROR) {
- /* NGX_ERROR may be returned by any filter */
- c->error = 1;
- }
-
- return rc;
-}
-
-
-u_char *
-ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
- size_t *root_length, size_t reserved)
-{
- u_char *last;
- size_t alias;
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- alias = clcf->alias;
-
- if (alias && !r->valid_location) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "\"alias\" cannot be used in location \"%V\" "
- "where URI was rewritten", &clcf->name);
- return NULL;
- }
-
- if (clcf->root_lengths == NULL) {
-
- *root_length = clcf->root.len;
-
- path->len = clcf->root.len + reserved + r->uri.len - alias + 1;
-
- path->data = ngx_pnalloc(r->pool, path->len);
- if (path->data == NULL) {
- return NULL;
- }
-
- last = ngx_copy(path->data, clcf->root.data, clcf->root.len);
-
- } else {
-
-#if (NGX_PCRE)
- ngx_uint_t captures;
-
- captures = alias && clcf->regex;
-
- reserved += captures ? r->add_uri_to_alias ? r->uri.len + 1 : 1
- : r->uri.len - alias + 1;
-#else
- reserved += r->uri.len - alias + 1;
-#endif
-
- if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved,
- clcf->root_values->elts)
- == NULL)
- {
- return NULL;
- }
-
- if (ngx_get_full_name(r->pool, (ngx_str_t *) &ngx_cycle->prefix, path)
- != NGX_OK)
- {
- return NULL;
- }
-
- *root_length = path->len - reserved;
- last = path->data + *root_length;
-
-#if (NGX_PCRE)
- if (captures) {
- if (!r->add_uri_to_alias) {
- *last = '\0';
- return last;
- }
-
- alias = 0;
- }
-#endif
- }
-
- last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1);
-
- return last;
-}
-
-
-ngx_int_t
-ngx_http_auth_basic_user(ngx_http_request_t *r)
-{
- ngx_str_t auth, encoded;
- ngx_uint_t len;
-
- if (r->headers_in.user.len == 0 && r->headers_in.user.data != NULL) {
- return NGX_DECLINED;
- }
-
- if (r->headers_in.authorization == NULL) {
- r->headers_in.user.data = (u_char *) "";
- return NGX_DECLINED;
- }
-
- encoded = r->headers_in.authorization->value;
-
- if (encoded.len < sizeof("Basic ") - 1
- || ngx_strncasecmp(encoded.data, (u_char *) "Basic ",
- sizeof("Basic ") - 1)
- != 0)
- {
- r->headers_in.user.data = (u_char *) "";
- return NGX_DECLINED;
- }
-
- encoded.len -= sizeof("Basic ") - 1;
- encoded.data += sizeof("Basic ") - 1;
-
- while (encoded.len && encoded.data[0] == ' ') {
- encoded.len--;
- encoded.data++;
- }
-
- if (encoded.len == 0) {
- r->headers_in.user.data = (u_char *) "";
- return NGX_DECLINED;
- }
-
- auth.len = ngx_base64_decoded_length(encoded.len);
- auth.data = ngx_pnalloc(r->pool, auth.len + 1);
- if (auth.data == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_decode_base64(&auth, &encoded) != NGX_OK) {
- r->headers_in.user.data = (u_char *) "";
- return NGX_DECLINED;
- }
-
- auth.data[auth.len] = '\0';
-
- for (len = 0; len < auth.len; len++) {
- if (auth.data[len] == ':') {
- break;
- }
- }
-
- if (len == 0 || len == auth.len) {
- r->headers_in.user.data = (u_char *) "";
- return NGX_DECLINED;
- }
-
- r->headers_in.user.len = len;
- r->headers_in.user.data = auth.data;
- r->headers_in.passwd.len = auth.len - len - 1;
- r->headers_in.passwd.data = &auth.data[len + 1];
-
- return NGX_OK;
-}
-
-
-#if (NGX_HTTP_GZIP)
-
-ngx_int_t
-ngx_http_gzip_ok(ngx_http_request_t *r)
-{
- time_t date, expires;
- ngx_uint_t p;
- ngx_array_t *cc;
- ngx_table_elt_t *e, *d, *ae;
- ngx_http_core_loc_conf_t *clcf;
-
- r->gzip_tested = 1;
-
- if (r != r->main) {
- return NGX_DECLINED;
- }
-
-#if (NGX_HTTP_SPDY)
- if (r->spdy_stream) {
- r->gzip_ok = 1;
- return NGX_OK;
- }
-#endif
-
- ae = r->headers_in.accept_encoding;
- if (ae == NULL) {
- return NGX_DECLINED;
- }
-
- if (ae->value.len < sizeof("gzip") - 1) {
- return NGX_DECLINED;
- }
-
- /*
- * test first for the most common case "gzip,...":
- * MSIE: "gzip, deflate"
- * Firefox: "gzip,deflate"
- * Chrome: "gzip,deflate,sdch"
- * Safari: "gzip, deflate"
- * Opera: "gzip, deflate"
- */
-
- if (ngx_memcmp(ae->value.data, "gzip,", 5) != 0
- && ngx_http_gzip_accept_encoding(&ae->value) != NGX_OK)
- {
- return NGX_DECLINED;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (r->headers_in.msie6 && clcf->gzip_disable_msie6) {
- return NGX_DECLINED;
- }
-
- if (r->http_version < clcf->gzip_http_version) {
- return NGX_DECLINED;
- }
-
- if (r->headers_in.via == NULL) {
- goto ok;
- }
-
- p = clcf->gzip_proxied;
-
- if (p & NGX_HTTP_GZIP_PROXIED_OFF) {
- return NGX_DECLINED;
- }
-
- if (p & NGX_HTTP_GZIP_PROXIED_ANY) {
- goto ok;
- }
-
- if (r->headers_in.authorization && (p & NGX_HTTP_GZIP_PROXIED_AUTH)) {
- goto ok;
- }
-
- e = r->headers_out.expires;
-
- if (e) {
-
- if (!(p & NGX_HTTP_GZIP_PROXIED_EXPIRED)) {
- return NGX_DECLINED;
- }
-
- expires = ngx_http_parse_time(e->value.data, e->value.len);
- if (expires == NGX_ERROR) {
- return NGX_DECLINED;
- }
-
- d = r->headers_out.date;
-
- if (d) {
- date = ngx_http_parse_time(d->value.data, d->value.len);
- if (date == NGX_ERROR) {
- return NGX_DECLINED;
- }
-
- } else {
- date = ngx_time();
- }
-
- if (expires < date) {
- goto ok;
- }
-
- return NGX_DECLINED;
- }
-
- cc = &r->headers_out.cache_control;
-
- if (cc->elts) {
-
- if ((p & NGX_HTTP_GZIP_PROXIED_NO_CACHE)
- && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_cache,
- NULL)
- >= 0)
- {
- goto ok;
- }
-
- if ((p & NGX_HTTP_GZIP_PROXIED_NO_STORE)
- && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_store,
- NULL)
- >= 0)
- {
- goto ok;
- }
-
- if ((p & NGX_HTTP_GZIP_PROXIED_PRIVATE)
- && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_private,
- NULL)
- >= 0)
- {
- goto ok;
- }
-
- return NGX_DECLINED;
- }
-
- if ((p & NGX_HTTP_GZIP_PROXIED_NO_LM) && r->headers_out.last_modified) {
- return NGX_DECLINED;
- }
-
- if ((p & NGX_HTTP_GZIP_PROXIED_NO_ETAG) && r->headers_out.etag) {
- return NGX_DECLINED;
- }
-
-ok:
-
-#if (NGX_PCRE)
-
- if (clcf->gzip_disable && r->headers_in.user_agent) {
-
- if (ngx_regex_exec_array(clcf->gzip_disable,
- &r->headers_in.user_agent->value,
- r->connection->log)
- != NGX_DECLINED)
- {
- return NGX_DECLINED;
- }
- }
-
-#endif
-
- r->gzip_ok = 1;
-
- return NGX_OK;
-}
-
-
-/*
- * gzip is enabled for the following quantities:
- * "gzip; q=0.001" ... "gzip; q=1.000"
- * gzip is disabled for the following quantities:
- * "gzip; q=0" ... "gzip; q=0.000", and for any invalid cases
- */
-
-static ngx_int_t
-ngx_http_gzip_accept_encoding(ngx_str_t *ae)
-{
- u_char *p, *start, *last;
-
- start = ae->data;
- last = start + ae->len;
-
- for ( ;; ) {
- p = ngx_strcasestrn(start, "gzip", 4 - 1);
- if (p == NULL) {
- return NGX_DECLINED;
- }
-
- if (p == start || (*(p - 1) == ',' || *(p - 1) == ' ')) {
- break;
- }
-
- start = p + 4;
- }
-
- p += 4;
-
- while (p < last) {
- switch(*p++) {
- case ',':
- return NGX_OK;
- case ';':
- goto quantity;
- case ' ':
- continue;
- default:
- return NGX_DECLINED;
- }
- }
-
- return NGX_OK;
-
-quantity:
-
- while (p < last) {
- switch(*p++) {
- case 'q':
- case 'Q':
- goto equal;
- case ' ':
- continue;
- default:
- return NGX_DECLINED;
- }
- }
-
- return NGX_OK;
-
-equal:
-
- if (p + 2 > last || *p++ != '=') {
- return NGX_DECLINED;
- }
-
- if (ngx_http_gzip_quantity(p, last) == 0) {
- return NGX_DECLINED;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_uint_t
-ngx_http_gzip_quantity(u_char *p, u_char *last)
-{
- u_char c;
- ngx_uint_t n, q;
-
- c = *p++;
-
- if (c != '0' && c != '1') {
- return 0;
- }
-
- q = (c - '0') * 100;
-
- if (p == last) {
- return q;
- }
-
- c = *p++;
-
- if (c == ',' || c == ' ') {
- return q;
- }
-
- if (c != '.') {
- return 0;
- }
-
- n = 0;
-
- while (p < last) {
- c = *p++;
-
- if (c == ',' || c == ' ') {
- break;
- }
-
- if (c >= '0' && c <= '9') {
- q += c - '0';
- n++;
- continue;
- }
-
- return 0;
- }
-
- if (q > 100 || n > 3) {
- return 0;
- }
-
- return q;
-}
-
-#endif
-
-
-ngx_int_t
-ngx_http_subrequest(ngx_http_request_t *r,
- ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
- ngx_http_post_subrequest_t *ps, ngx_uint_t flags)
-{
- ngx_time_t *tp;
- ngx_connection_t *c;
- ngx_http_request_t *sr;
- ngx_http_core_srv_conf_t *cscf;
- ngx_http_postponed_request_t *pr, *p;
-
- r->main->subrequests--;
-
- if (r->main->subrequests == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "subrequests cycle while processing \"%V\"", uri);
- r->main->subrequests = 1;
- return NGX_ERROR;
- }
-
- sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
- if (sr == NULL) {
- return NGX_ERROR;
- }
-
- sr->signature = NGX_HTTP_MODULE;
-
- c = r->connection;
- sr->connection = c;
-
- sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
- if (sr->ctx == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
- sizeof(ngx_table_elt_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
- sr->main_conf = cscf->ctx->main_conf;
- sr->srv_conf = cscf->ctx->srv_conf;
- sr->loc_conf = cscf->ctx->loc_conf;
-
- sr->pool = r->pool;
-
- sr->headers_in = r->headers_in;
-
- ngx_http_clear_content_length(sr);
- ngx_http_clear_accept_ranges(sr);
- ngx_http_clear_last_modified(sr);
-
- sr->request_body = r->request_body;
-
-#if (NGX_HTTP_SPDY)
- sr->spdy_stream = r->spdy_stream;
-#endif
-
- sr->method = NGX_HTTP_GET;
- sr->http_version = r->http_version;
-
- sr->request_line = r->request_line;
- sr->uri = *uri;
-
- if (args) {
- sr->args = *args;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http subrequest \"%V?%V\"", uri, &sr->args);
-
- sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
- sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;
-
- sr->unparsed_uri = r->unparsed_uri;
- sr->method_name = ngx_http_core_get_method;
- sr->http_protocol = r->http_protocol;
-
- ngx_http_set_exten(sr);
-
- sr->main = r->main;
- sr->parent = r;
- sr->post_subrequest = ps;
- sr->read_event_handler = ngx_http_request_empty_handler;
- sr->write_event_handler = ngx_http_handler;
-
- if (c->data == r && r->postponed == NULL) {
- c->data = sr;
- }
-
- sr->variables = r->variables;
-
- sr->log_handler = r->log_handler;
-
- pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
- if (pr == NULL) {
- return NGX_ERROR;
- }
-
- pr->request = sr;
- pr->out = NULL;
- pr->next = NULL;
-
- if (r->postponed) {
- for (p = r->postponed; p->next; p = p->next) { /* void */ }
- p->next = pr;
-
- } else {
- r->postponed = pr;
- }
-
- sr->internal = 1;
-
- sr->discard_body = r->discard_body;
- sr->expect_tested = 1;
- sr->main_filter_need_in_memory = r->main_filter_need_in_memory;
-
- sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
-
- tp = ngx_timeofday();
- sr->start_sec = tp->sec;
- sr->start_msec = tp->msec;
-
- r->main->count++;
-
- *psr = sr;
-
- return ngx_http_post_request(sr, NULL);
-}
-
-
-ngx_int_t
-ngx_http_internal_redirect(ngx_http_request_t *r,
- ngx_str_t *uri, ngx_str_t *args)
-{
- ngx_http_core_srv_conf_t *cscf;
-
- r->uri_changes--;
-
- if (r->uri_changes == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "rewrite or internal redirection cycle "
- "while internally redirecting to \"%V\"", uri);
-
- r->main->count++;
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_DONE;
- }
-
- r->uri = *uri;
-
- if (args) {
- r->args = *args;
-
- } else {
- ngx_str_null(&r->args);
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "internal redirect: \"%V?%V\"", uri, &r->args);
-
- ngx_http_set_exten(r);
-
- /* clear the modules contexts */
- ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
-
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
- r->loc_conf = cscf->ctx->loc_conf;
-
- ngx_http_update_location_config(r);
-
-#if (NGX_HTTP_CACHE)
- r->cache = NULL;
-#endif
-
- r->internal = 1;
- r->valid_unparsed_uri = 0;
- r->add_uri_to_alias = 0;
- r->main->count++;
-
- ngx_http_handler(r);
-
- return NGX_DONE;
-}
-
-
-ngx_int_t
-ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
-{
- ngx_http_core_srv_conf_t *cscf;
- ngx_http_core_loc_conf_t **clcfp;
- ngx_http_core_main_conf_t *cmcf;
-
- r->main->count++;
- r->uri_changes--;
-
- if (r->uri_changes == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "rewrite or internal redirection cycle "
- "while redirect to named location \"%V\"", name);
-
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_DONE;
- }
-
- if (r->uri.len == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "empty URI in redirect to named location \"%V\"", name);
-
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_DONE;
- }
-
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
- if (cscf->named_locations) {
-
- for (clcfp = cscf->named_locations; *clcfp; clcfp++) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "test location: \"%V\"", &(*clcfp)->name);
-
- if (name->len != (*clcfp)->name.len
- || ngx_strncmp(name->data, (*clcfp)->name.data, name->len) != 0)
- {
- continue;
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "using location: %V \"%V?%V\"",
- name, &r->uri, &r->args);
-
- r->internal = 1;
- r->content_handler = NULL;
- r->uri_changed = 0;
- r->loc_conf = (*clcfp)->loc_conf;
-
- /* clear the modules contexts */
- ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
-
- 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;
-
- r->write_event_handler = ngx_http_core_run_phases;
- 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)
-{
- ngx_http_cleanup_t *cln;
-
- r = r->main;
-
- cln = ngx_palloc(r->pool, sizeof(ngx_http_cleanup_t));
- if (cln == NULL) {
- return NULL;
- }
-
- if (size) {
- cln->data = ngx_palloc(r->pool, size);
- if (cln->data == NULL) {
- return NULL;
- }
-
- } else {
- cln->data = NULL;
- }
-
- cln->handler = NULL;
- cln->next = r->cleanup;
-
- r->cleanup = cln;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http cleanup add: %p", cln);
-
- return cln;
-}
-
-
-ngx_int_t
-ngx_http_set_disable_symlinks(ngx_http_request_t *r,
- ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of)
-{
-#if (NGX_HAVE_OPENAT)
- u_char *p;
- ngx_str_t from;
-
- of->disable_symlinks = clcf->disable_symlinks;
-
- if (clcf->disable_symlinks_from == NULL) {
- return NGX_OK;
- }
-
- if (ngx_http_complex_value(r, clcf->disable_symlinks_from, &from)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- if (from.len == 0
- || from.len > path->len
- || ngx_memcmp(path->data, from.data, from.len) != 0)
- {
- return NGX_OK;
- }
-
- if (from.len == path->len) {
- of->disable_symlinks = NGX_DISABLE_SYMLINKS_OFF;
- return NGX_OK;
- }
-
- p = path->data + from.len;
-
- if (*p == '/') {
- of->disable_symlinks_from = from.len;
- return NGX_OK;
- }
-
- p--;
-
- if (*p == '/') {
- of->disable_symlinks_from = from.len - 1;
- }
-#endif
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
- ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies,
- int recursive)
-{
- ngx_int_t rc;
- ngx_uint_t i, found;
- ngx_table_elt_t **h;
-
- if (headers == NULL) {
- return ngx_http_get_forwarded_addr_internal(r, addr, value->data,
- value->len, proxies,
- recursive);
- }
-
- i = headers->nelts;
- h = headers->elts;
-
- rc = NGX_DECLINED;
-
- found = 0;
-
- while (i-- > 0) {
- rc = ngx_http_get_forwarded_addr_internal(r, addr, h[i]->value.data,
- h[i]->value.len, proxies,
- recursive);
-
- if (!recursive) {
- break;
- }
-
- if (rc == NGX_DECLINED && found) {
- rc = NGX_DONE;
- break;
- }
-
- if (rc != NGX_OK) {
- break;
- }
-
- found = 1;
- }
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
- u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive)
-{
- u_char *p;
- in_addr_t inaddr;
- ngx_int_t rc;
- ngx_addr_t paddr;
- ngx_cidr_t *cidr;
- ngx_uint_t family, i;
-#if (NGX_HAVE_INET6)
- ngx_uint_t n;
- struct in6_addr *inaddr6;
-#endif
-
-#if (NGX_SUPPRESS_WARN)
- inaddr = 0;
-#if (NGX_HAVE_INET6)
- inaddr6 = NULL;
-#endif
-#endif
-
- family = addr->sockaddr->sa_family;
-
- if (family == AF_INET) {
- inaddr = ((struct sockaddr_in *) addr->sockaddr)->sin_addr.s_addr;
- }
-
-#if (NGX_HAVE_INET6)
- else if (family == AF_INET6) {
- inaddr6 = &((struct sockaddr_in6 *) addr->sockaddr)->sin6_addr;
-
- if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
- family = AF_INET;
-
- p = inaddr6->s6_addr;
-
- inaddr = p[12] << 24;
- inaddr += p[13] << 16;
- inaddr += p[14] << 8;
- inaddr += p[15];
-
- inaddr = htonl(inaddr);
- }
- }
-#endif
-
- for (cidr = proxies->elts, i = 0; i < proxies->nelts; i++) {
- if (cidr[i].family != family) {
- goto next;
- }
-
- switch (family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- for (n = 0; n < 16; n++) {
- if ((inaddr6->s6_addr[n] & cidr[i].u.in6.mask.s6_addr[n])
- != cidr[i].u.in6.addr.s6_addr[n])
- {
- goto next;
- }
- }
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- break;
-#endif
-
- default: /* AF_INET */
- if ((inaddr & cidr[i].u.in.mask) != cidr[i].u.in.addr) {
- goto next;
- }
- break;
- }
-
- for (p = xff + xfflen - 1; p > xff; p--, xfflen--) {
- if (*p != ' ' && *p != ',') {
- break;
- }
- }
-
- for ( /* void */ ; p > xff; p--) {
- if (*p == ' ' || *p == ',') {
- p++;
- break;
- }
- }
-
- if (ngx_parse_addr(r->pool, &paddr, p, xfflen - (p - xff)) != NGX_OK) {
- return NGX_DECLINED;
- }
-
- *addr = paddr;
-
- if (recursive && p > xff) {
- rc = ngx_http_get_forwarded_addr_internal(r, addr, xff, p - 1 - xff,
- proxies, 1);
-
- if (rc == NGX_DECLINED) {
- return NGX_DONE;
- }
-
- /* rc == NGX_OK || rc == NGX_DONE */
- return rc;
- }
-
- return NGX_OK;
-
- next:
- continue;
- }
-
- return NGX_DECLINED;
-}
-
-
-static char *
-ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
-{
- char *rv;
- void *mconf;
- ngx_uint_t i;
- ngx_conf_t pcf;
- ngx_http_module_t *module;
- struct sockaddr_in *sin;
- ngx_http_conf_ctx_t *ctx, *http_ctx;
- ngx_http_listen_opt_t lsopt;
- ngx_http_core_srv_conf_t *cscf, **cscfp;
- ngx_http_core_main_conf_t *cmcf;
-
- ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- http_ctx = cf->ctx;
- ctx->main_conf = http_ctx->main_conf;
-
- /* the server{}'s srv_conf */
-
- ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
- if (ctx->srv_conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- /* the server{}'s loc_conf */
-
- ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
- if (ctx->loc_conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
- continue;
- }
-
- module = ngx_modules[i]->ctx;
-
- if (module->create_srv_conf) {
- mconf = module->create_srv_conf(cf);
- if (mconf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->srv_conf[ngx_modules[i]->ctx_index] = mconf;
- }
-
- if (module->create_loc_conf) {
- mconf = module->create_loc_conf(cf);
- if (mconf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
- }
- }
-
-
- /* the server configuration context */
-
- cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
- cscf->ctx = ctx;
-
-
- cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
-
- cscfp = ngx_array_push(&cmcf->servers);
- if (cscfp == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *cscfp = cscf;
-
-
- /* parse inside server{} */
-
- pcf = *cf;
- cf->ctx = ctx;
- cf->cmd_type = NGX_HTTP_SRV_CONF;
-
- rv = ngx_conf_parse(cf, NULL);
-
- *cf = pcf;
-
- if (rv == NGX_CONF_OK && !cscf->listen) {
- ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));
-
- sin = &lsopt.u.sockaddr_in;
-
- sin->sin_family = AF_INET;
-#if (NGX_WIN32)
- sin->sin_port = htons(80);
-#else
- sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
-#endif
- sin->sin_addr.s_addr = INADDR_ANY;
-
- lsopt.socklen = sizeof(struct sockaddr_in);
-
- lsopt.backlog = NGX_LISTEN_BACKLOG;
- lsopt.rcvbuf = -1;
- lsopt.sndbuf = -1;
-#if (NGX_HAVE_SETFIB)
- lsopt.setfib = -1;
-#endif
-#if (NGX_HAVE_TCP_FASTOPEN)
- lsopt.fastopen = -1;
-#endif
- lsopt.wildcard = 1;
-
- (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.socklen, lsopt.addr,
- NGX_SOCKADDR_STRLEN, 1);
-
- if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- return rv;
-}
-
-
-static char *
-ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
-{
- char *rv;
- u_char *mod;
- size_t len;
- ngx_str_t *value, *name;
- ngx_uint_t i;
- ngx_conf_t save;
- ngx_http_module_t *module;
- ngx_http_conf_ctx_t *ctx, *pctx;
- ngx_http_core_loc_conf_t *clcf, *pclcf;
-
- ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- pctx = cf->ctx;
- ctx->main_conf = pctx->main_conf;
- ctx->srv_conf = pctx->srv_conf;
-
- ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
- if (ctx->loc_conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
- continue;
- }
-
- module = ngx_modules[i]->ctx;
-
- if (module->create_loc_conf) {
- ctx->loc_conf[ngx_modules[i]->ctx_index] =
- module->create_loc_conf(cf);
- if (ctx->loc_conf[ngx_modules[i]->ctx_index] == NULL) {
- return NGX_CONF_ERROR;
- }
- }
- }
-
- clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
- clcf->loc_conf = ctx->loc_conf;
-
- value = cf->args->elts;
-
- if (cf->args->nelts == 3) {
-
- len = value[1].len;
- mod = value[1].data;
- name = &value[2];
-
- if (len == 1 && mod[0] == '=') {
-
- clcf->name = *name;
- clcf->exact_match = 1;
-
- } else if (len == 2 && mod[0] == '^' && mod[1] == '~') {
-
- clcf->name = *name;
- clcf->noregex = 1;
-
- } else if (len == 1 && mod[0] == '~') {
-
- if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- } else if (len == 2 && mod[0] == '~' && mod[1] == '*') {
-
- if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid location modifier \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- } else {
-
- name = &value[1];
-
- if (name->data[0] == '=') {
-
- clcf->name.len = name->len - 1;
- clcf->name.data = name->data + 1;
- clcf->exact_match = 1;
-
- } else if (name->data[0] == '^' && name->data[1] == '~') {
-
- clcf->name.len = name->len - 2;
- clcf->name.data = name->data + 2;
- clcf->noregex = 1;
-
- } else if (name->data[0] == '~') {
-
- name->len--;
- name->data++;
-
- if (name->data[0] == '*') {
-
- name->len--;
- name->data++;
-
- if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- } else {
- if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- } else {
-
- clcf->name = *name;
-
- if (name->data[0] == '@') {
- clcf->named = 1;
- }
- }
- }
-
- pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
-
- if (pclcf->name.len) {
-
- /* nested location */
-
-#if 0
- clcf->prev_location = pclcf;
-#endif
-
- if (pclcf->exact_match) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "location \"%V\" cannot be inside "
- "the exact location \"%V\"",
- &clcf->name, &pclcf->name);
- return NGX_CONF_ERROR;
- }
-
- if (pclcf->named) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "location \"%V\" cannot be inside "
- "the named location \"%V\"",
- &clcf->name, &pclcf->name);
- return NGX_CONF_ERROR;
- }
-
- if (clcf->named) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "named location \"%V\" can be "
- "on the server level only",
- &clcf->name);
- return NGX_CONF_ERROR;
- }
-
- len = pclcf->name.len;
-
-#if (NGX_PCRE)
- if (clcf->regex == NULL
- && ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)
-#else
- if (ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)
-#endif
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "location \"%V\" is outside location \"%V\"",
- &clcf->name, &pclcf->name);
- return NGX_CONF_ERROR;
- }
- }
-
- if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- save = *cf;
- cf->ctx = ctx;
- cf->cmd_type = NGX_HTTP_LOC_CONF;
-
- rv = ngx_conf_parse(cf, NULL);
-
- *cf = save;
-
- return rv;
-}
-
-
-static ngx_int_t
-ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf,
- ngx_str_t *regex, ngx_uint_t caseless)
-{
-#if (NGX_PCRE)
- ngx_regex_compile_t rc;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
-
- ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
-
- rc.pattern = *regex;
- rc.err.len = NGX_MAX_CONF_ERRSTR;
- rc.err.data = errstr;
-
-#if (NGX_HAVE_CASELESS_FILESYSTEM)
- rc.options = NGX_REGEX_CASELESS;
-#else
- rc.options = caseless ? NGX_REGEX_CASELESS : 0;
-#endif
-
- clcf->regex = ngx_http_regex_compile(cf, &rc);
- if (clcf->regex == NULL) {
- return NGX_ERROR;
- }
-
- clcf->name = *regex;
-
- return NGX_OK;
-
-#else
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "using regex \"%V\" requires PCRE library",
- regex);
- return NGX_ERROR;
-
-#endif
-}
-
-
-static char *
-ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf = conf;
-
- char *rv;
- ngx_conf_t save;
-
- if (clcf->types == NULL) {
- clcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
- if (clcf->types == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- save = *cf;
- cf->handler = ngx_http_core_type;
- cf->handler_conf = conf;
-
- rv = ngx_conf_parse(cf, NULL);
-
- *cf = save;
-
- return rv;
-}
-
-
-static char *
-ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf = conf;
-
- ngx_str_t *value, *content_type, *old;
- ngx_uint_t i, n, hash;
- ngx_hash_key_t *type;
-
- value = cf->args->elts;
-
- if (ngx_strcmp(value[0].data, "include") == 0) {
- if (cf->args->nelts != 2) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid number of arguments"
- " in \"include\" directive");
- return NGX_CONF_ERROR;
- }
-
- return ngx_conf_include(cf, dummy, conf);
- }
-
- content_type = ngx_palloc(cf->pool, sizeof(ngx_str_t));
- if (content_type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *content_type = value[0];
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len);
-
- type = clcf->types->elts;
- for (n = 0; n < clcf->types->nelts; n++) {
- if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
- old = type[n].value;
- type[n].value = content_type;
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "duplicate extension \"%V\", "
- "content type: \"%V\", "
- "previous content type: \"%V\"",
- &value[i], content_type, old);
- goto next;
- }
- }
-
-
- type = ngx_array_push(clcf->types);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type->key = value[i];
- type->key_hash = hash;
- type->value = content_type;
-
- next:
- continue;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_core_preconfiguration(ngx_conf_t *cf)
-{
- return ngx_http_variables_add_core_vars(cf);
-}
-
-
-static void *
-ngx_http_core_create_main_conf(ngx_conf_t *cf)
-{
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t));
- if (cmcf == NULL) {
- return NULL;
- }
-
- if (ngx_array_init(&cmcf->servers, cf->pool, 4,
- sizeof(ngx_http_core_srv_conf_t *))
- != NGX_OK)
- {
- return NULL;
- }
-
- cmcf->server_names_hash_max_size = NGX_CONF_UNSET_UINT;
- cmcf->server_names_hash_bucket_size = NGX_CONF_UNSET_UINT;
-
- cmcf->variables_hash_max_size = NGX_CONF_UNSET_UINT;
- cmcf->variables_hash_bucket_size = NGX_CONF_UNSET_UINT;
-
- return cmcf;
-}
-
-
-static char *
-ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
-{
- ngx_http_core_main_conf_t *cmcf = conf;
-
- ngx_conf_init_uint_value(cmcf->server_names_hash_max_size, 512);
- ngx_conf_init_uint_value(cmcf->server_names_hash_bucket_size,
- ngx_cacheline_size);
-
- cmcf->server_names_hash_bucket_size =
- ngx_align(cmcf->server_names_hash_bucket_size, ngx_cacheline_size);
-
-
- ngx_conf_init_uint_value(cmcf->variables_hash_max_size, 1024);
- ngx_conf_init_uint_value(cmcf->variables_hash_bucket_size, 64);
-
- cmcf->variables_hash_bucket_size =
- ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size);
-
- if (cmcf->ncaptures) {
- cmcf->ncaptures = (cmcf->ncaptures + 1) * 3;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static void *
-ngx_http_core_create_srv_conf(ngx_conf_t *cf)
-{
- ngx_http_core_srv_conf_t *cscf;
-
- cscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_srv_conf_t));
- if (cscf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->client_large_buffers.num = 0;
- */
-
- if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
- sizeof(ngx_http_server_name_t))
- != NGX_OK)
- {
- return NULL;
- }
-
- cscf->connection_pool_size = NGX_CONF_UNSET_SIZE;
- cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
- cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
- cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
- cscf->ignore_invalid_headers = NGX_CONF_UNSET;
- cscf->merge_slashes = NGX_CONF_UNSET;
- cscf->underscores_in_headers = NGX_CONF_UNSET;
-
- return cscf;
-}
-
-
-static char *
-ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_core_srv_conf_t *prev = parent;
- ngx_http_core_srv_conf_t *conf = child;
-
- ngx_str_t name;
- ngx_http_server_name_t *sn;
-
- /* TODO: it does not merge, it inits only */
-
- ngx_conf_merge_size_value(conf->connection_pool_size,
- prev->connection_pool_size, 256);
- ngx_conf_merge_size_value(conf->request_pool_size,
- prev->request_pool_size, 4096);
- ngx_conf_merge_msec_value(conf->client_header_timeout,
- prev->client_header_timeout, 60000);
- ngx_conf_merge_size_value(conf->client_header_buffer_size,
- prev->client_header_buffer_size, 1024);
- ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
- prev->large_client_header_buffers,
- 4, 8192);
-
- if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the \"large_client_header_buffers\" size must be "
- "equal to or greater than \"connection_pool_size\"");
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_value(conf->ignore_invalid_headers,
- prev->ignore_invalid_headers, 1);
-
- ngx_conf_merge_value(conf->merge_slashes, prev->merge_slashes, 1);
-
- ngx_conf_merge_value(conf->underscores_in_headers,
- prev->underscores_in_headers, 0);
-
- if (conf->server_names.nelts == 0) {
- /* the array has 4 empty preallocated elements, so push cannot fail */
- sn = ngx_array_push(&conf->server_names);
-#if (NGX_PCRE)
- sn->regex = NULL;
-#endif
- sn->server = conf;
- ngx_str_set(&sn->name, "");
- }
-
- sn = conf->server_names.elts;
- name = sn[0].name;
-
-#if (NGX_PCRE)
- if (sn->regex) {
- name.len++;
- name.data--;
- } else
-#endif
-
- if (name.data[0] == '.') {
- name.len--;
- name.data++;
- }
-
- conf->server_name.len = name.len;
- conf->server_name.data = ngx_pstrdup(cf->pool, &name);
- if (conf->server_name.data == NULL) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static void *
-ngx_http_core_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t));
- if (clcf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * clcf->root = { 0, NULL };
- * clcf->limit_except = 0;
- * clcf->post_action = { 0, NULL };
- * clcf->types = NULL;
- * clcf->default_type = { 0, NULL };
- * clcf->error_log = NULL;
- * clcf->error_pages = NULL;
- * clcf->try_files = NULL;
- * clcf->client_body_path = NULL;
- * clcf->regex = NULL;
- * clcf->exact_match = 0;
- * clcf->auto_redirect = 0;
- * clcf->alias = 0;
- * clcf->gzip_proxied = 0;
- * clcf->keepalive_disable = 0;
- */
-
- clcf->client_max_body_size = NGX_CONF_UNSET;
- clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
- clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
- clcf->satisfy = NGX_CONF_UNSET_UINT;
- clcf->if_modified_since = NGX_CONF_UNSET_UINT;
- clcf->max_ranges = NGX_CONF_UNSET_UINT;
- clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
- clcf->client_body_in_single_buffer = NGX_CONF_UNSET;
- clcf->internal = NGX_CONF_UNSET;
- clcf->sendfile = NGX_CONF_UNSET;
- clcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
-#if (NGX_HAVE_FILE_AIO)
- clcf->aio = NGX_CONF_UNSET;
-#endif
- clcf->read_ahead = NGX_CONF_UNSET_SIZE;
- clcf->directio = NGX_CONF_UNSET;
- clcf->directio_alignment = NGX_CONF_UNSET;
- clcf->tcp_nopush = NGX_CONF_UNSET;
- clcf->tcp_nodelay = NGX_CONF_UNSET;
- clcf->send_timeout = NGX_CONF_UNSET_MSEC;
- clcf->send_lowat = NGX_CONF_UNSET_SIZE;
- clcf->postpone_output = NGX_CONF_UNSET_SIZE;
- clcf->limit_rate = NGX_CONF_UNSET_SIZE;
- clcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
- clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
- clcf->keepalive_header = NGX_CONF_UNSET;
- clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
- clcf->lingering_close = NGX_CONF_UNSET_UINT;
- clcf->lingering_time = NGX_CONF_UNSET_MSEC;
- clcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
- clcf->resolver_timeout = NGX_CONF_UNSET_MSEC;
- clcf->reset_timedout_connection = NGX_CONF_UNSET;
- clcf->server_name_in_redirect = NGX_CONF_UNSET;
- clcf->port_in_redirect = NGX_CONF_UNSET;
- clcf->msie_padding = NGX_CONF_UNSET;
- clcf->msie_refresh = NGX_CONF_UNSET;
- clcf->log_not_found = NGX_CONF_UNSET;
- clcf->log_subrequest = NGX_CONF_UNSET;
- clcf->recursive_error_pages = NGX_CONF_UNSET;
- clcf->server_tokens = NGX_CONF_UNSET;
- clcf->chunked_transfer_encoding = NGX_CONF_UNSET;
- clcf->etag = NGX_CONF_UNSET;
- clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
- clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
-
- clcf->open_file_cache = NGX_CONF_UNSET_PTR;
- clcf->open_file_cache_valid = NGX_CONF_UNSET;
- clcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT;
- clcf->open_file_cache_errors = NGX_CONF_UNSET;
- clcf->open_file_cache_events = NGX_CONF_UNSET;
-
-#if (NGX_HTTP_GZIP)
- clcf->gzip_vary = NGX_CONF_UNSET;
- clcf->gzip_http_version = NGX_CONF_UNSET_UINT;
-#if (NGX_PCRE)
- clcf->gzip_disable = NGX_CONF_UNSET_PTR;
-#endif
- clcf->gzip_disable_msie6 = 3;
-#if (NGX_HTTP_DEGRADATION)
- clcf->gzip_disable_degradation = 3;
-#endif
-#endif
-
-#if (NGX_HAVE_OPENAT)
- clcf->disable_symlinks = NGX_CONF_UNSET_UINT;
- clcf->disable_symlinks_from = NGX_CONF_UNSET_PTR;
-#endif
-
- return clcf;
-}
-
-
-static ngx_str_t ngx_http_core_text_html_type = ngx_string("text/html");
-static ngx_str_t ngx_http_core_image_gif_type = ngx_string("image/gif");
-static ngx_str_t ngx_http_core_image_jpeg_type = ngx_string("image/jpeg");
-
-static ngx_hash_key_t ngx_http_core_default_types[] = {
- { ngx_string("html"), 0, &ngx_http_core_text_html_type },
- { ngx_string("gif"), 0, &ngx_http_core_image_gif_type },
- { ngx_string("jpg"), 0, &ngx_http_core_image_jpeg_type },
- { ngx_null_string, 0, NULL }
-};
-
-
-static char *
-ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_core_loc_conf_t *prev = parent;
- ngx_http_core_loc_conf_t *conf = child;
-
- ngx_uint_t i;
- ngx_hash_key_t *type;
- ngx_hash_init_t types_hash;
-
- if (conf->root.data == NULL) {
-
- conf->alias = prev->alias;
- conf->root = prev->root;
- conf->root_lengths = prev->root_lengths;
- conf->root_values = prev->root_values;
-
- if (prev->root.data == NULL) {
- ngx_str_set(&conf->root, "html");
-
- if (ngx_conf_full_name(cf->cycle, &conf->root, 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
- }
-
- if (conf->post_action.data == NULL) {
- conf->post_action = prev->post_action;
- }
-
- ngx_conf_merge_uint_value(conf->types_hash_max_size,
- prev->types_hash_max_size, 1024);
-
- ngx_conf_merge_uint_value(conf->types_hash_bucket_size,
- prev->types_hash_bucket_size, 64);
-
- conf->types_hash_bucket_size = ngx_align(conf->types_hash_bucket_size,
- ngx_cacheline_size);
-
- /*
- * the special handling of the "types" directive in the "http" section
- * to inherit the http's conf->types_hash to all servers
- */
-
- if (prev->types && prev->types_hash.buckets == NULL) {
-
- types_hash.hash = &prev->types_hash;
- types_hash.key = ngx_hash_key_lc;
- types_hash.max_size = conf->types_hash_max_size;
- types_hash.bucket_size = conf->types_hash_bucket_size;
- types_hash.name = "types_hash";
- types_hash.pool = cf->pool;
- types_hash.temp_pool = NULL;
-
- if (ngx_hash_init(&types_hash, prev->types->elts, prev->types->nelts)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
- }
-
- if (conf->types == NULL) {
- conf->types = prev->types;
- conf->types_hash = prev->types_hash;
- }
-
- if (conf->types == NULL) {
- conf->types = ngx_array_create(cf->pool, 3, sizeof(ngx_hash_key_t));
- if (conf->types == NULL) {
- return NGX_CONF_ERROR;
- }
-
- for (i = 0; ngx_http_core_default_types[i].key.len; i++) {
- type = ngx_array_push(conf->types);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type->key = ngx_http_core_default_types[i].key;
- type->key_hash =
- ngx_hash_key_lc(ngx_http_core_default_types[i].key.data,
- ngx_http_core_default_types[i].key.len);
- type->value = ngx_http_core_default_types[i].value;
- }
- }
-
- if (conf->types_hash.buckets == NULL) {
-
- types_hash.hash = &conf->types_hash;
- types_hash.key = ngx_hash_key_lc;
- types_hash.max_size = conf->types_hash_max_size;
- types_hash.bucket_size = conf->types_hash_bucket_size;
- types_hash.name = "types_hash";
- types_hash.pool = cf->pool;
- types_hash.temp_pool = NULL;
-
- if (ngx_hash_init(&types_hash, conf->types->elts, conf->types->nelts)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
- }
-
- if (conf->error_log == NULL) {
- if (prev->error_log) {
- conf->error_log = prev->error_log;
- } else {
- conf->error_log = &cf->cycle->new_log;
- }
- }
-
- if (conf->error_pages == NULL && prev->error_pages) {
- conf->error_pages = prev->error_pages;
- }
-
- ngx_conf_merge_str_value(conf->default_type,
- prev->default_type, "text/plain");
-
- ngx_conf_merge_off_value(conf->client_max_body_size,
- prev->client_max_body_size, 1 * 1024 * 1024);
- ngx_conf_merge_size_value(conf->client_body_buffer_size,
- prev->client_body_buffer_size,
- (size_t) 2 * ngx_pagesize);
- ngx_conf_merge_msec_value(conf->client_body_timeout,
- prev->client_body_timeout, 60000);
-
- ngx_conf_merge_bitmask_value(conf->keepalive_disable,
- prev->keepalive_disable,
- (NGX_CONF_BITMASK_SET
- |NGX_HTTP_KEEPALIVE_DISABLE_MSIE6));
- ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy,
- NGX_HTTP_SATISFY_ALL);
- ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
- NGX_HTTP_IMS_EXACT);
- ngx_conf_merge_uint_value(conf->max_ranges, prev->max_ranges,
- NGX_MAX_INT32_VALUE);
- ngx_conf_merge_uint_value(conf->client_body_in_file_only,
- prev->client_body_in_file_only,
- NGX_HTTP_REQUEST_BODY_FILE_OFF);
- ngx_conf_merge_value(conf->client_body_in_single_buffer,
- prev->client_body_in_single_buffer, 0);
- ngx_conf_merge_value(conf->internal, prev->internal, 0);
- ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
- ngx_conf_merge_size_value(conf->sendfile_max_chunk,
- prev->sendfile_max_chunk, 0);
-#if (NGX_HAVE_FILE_AIO)
- ngx_conf_merge_value(conf->aio, prev->aio, NGX_HTTP_AIO_OFF);
-#endif
- ngx_conf_merge_size_value(conf->read_ahead, prev->read_ahead, 0);
- ngx_conf_merge_off_value(conf->directio, prev->directio,
- NGX_OPEN_FILE_DIRECTIO_OFF);
- ngx_conf_merge_off_value(conf->directio_alignment, prev->directio_alignment,
- 512);
- ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
- ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1);
-
- ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
- ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
- ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
- 1460);
- ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
- ngx_conf_merge_size_value(conf->limit_rate_after, prev->limit_rate_after,
- 0);
- ngx_conf_merge_msec_value(conf->keepalive_timeout,
- prev->keepalive_timeout, 75000);
- ngx_conf_merge_sec_value(conf->keepalive_header,
- prev->keepalive_header, 0);
- ngx_conf_merge_uint_value(conf->keepalive_requests,
- prev->keepalive_requests, 100);
- ngx_conf_merge_uint_value(conf->lingering_close,
- prev->lingering_close, NGX_HTTP_LINGERING_ON);
- ngx_conf_merge_msec_value(conf->lingering_time,
- prev->lingering_time, 30000);
- ngx_conf_merge_msec_value(conf->lingering_timeout,
- prev->lingering_timeout, 5000);
- ngx_conf_merge_msec_value(conf->resolver_timeout,
- prev->resolver_timeout, 30000);
-
- if (conf->resolver == NULL) {
-
- if (prev->resolver == NULL) {
-
- /*
- * create dummy resolver in http {} context
- * to inherit it in all servers
- */
-
- prev->resolver = ngx_resolver_create(cf, NULL, 0);
- if (prev->resolver == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- conf->resolver = prev->resolver;
- }
-
- if (ngx_conf_merge_path_value(cf, &conf->client_body_temp_path,
- prev->client_body_temp_path,
- &ngx_http_client_temp_path)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_value(conf->reset_timedout_connection,
- prev->reset_timedout_connection, 0);
- ngx_conf_merge_value(conf->server_name_in_redirect,
- prev->server_name_in_redirect, 0);
- ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
- ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
- ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
- ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
- ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0);
- ngx_conf_merge_value(conf->recursive_error_pages,
- prev->recursive_error_pages, 0);
- ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
- ngx_conf_merge_value(conf->chunked_transfer_encoding,
- prev->chunked_transfer_encoding, 1);
- ngx_conf_merge_value(conf->etag, prev->etag, 1);
-
- ngx_conf_merge_ptr_value(conf->open_file_cache,
- prev->open_file_cache, NULL);
-
- ngx_conf_merge_sec_value(conf->open_file_cache_valid,
- prev->open_file_cache_valid, 60);
-
- ngx_conf_merge_uint_value(conf->open_file_cache_min_uses,
- prev->open_file_cache_min_uses, 1);
-
- ngx_conf_merge_sec_value(conf->open_file_cache_errors,
- prev->open_file_cache_errors, 0);
-
- ngx_conf_merge_sec_value(conf->open_file_cache_events,
- prev->open_file_cache_events, 0);
-#if (NGX_HTTP_GZIP)
-
- ngx_conf_merge_value(conf->gzip_vary, prev->gzip_vary, 0);
- ngx_conf_merge_uint_value(conf->gzip_http_version, prev->gzip_http_version,
- NGX_HTTP_VERSION_11);
- ngx_conf_merge_bitmask_value(conf->gzip_proxied, prev->gzip_proxied,
- (NGX_CONF_BITMASK_SET|NGX_HTTP_GZIP_PROXIED_OFF));
-
-#if (NGX_PCRE)
- ngx_conf_merge_ptr_value(conf->gzip_disable, prev->gzip_disable, NULL);
-#endif
-
- if (conf->gzip_disable_msie6 == 3) {
- conf->gzip_disable_msie6 =
- (prev->gzip_disable_msie6 == 3) ? 0 : prev->gzip_disable_msie6;
- }
-
-#if (NGX_HTTP_DEGRADATION)
-
- if (conf->gzip_disable_degradation == 3) {
- conf->gzip_disable_degradation =
- (prev->gzip_disable_degradation == 3) ?
- 0 : prev->gzip_disable_degradation;
- }
-
-#endif
-#endif
-
-#if (NGX_HAVE_OPENAT)
- ngx_conf_merge_uint_value(conf->disable_symlinks, prev->disable_symlinks,
- NGX_DISABLE_SYMLINKS_OFF);
- ngx_conf_merge_ptr_value(conf->disable_symlinks_from,
- prev->disable_symlinks_from, NULL);
-#endif
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_srv_conf_t *cscf = conf;
-
- ngx_str_t *value, size;
- ngx_url_t u;
- ngx_uint_t n;
- ngx_http_listen_opt_t lsopt;
-
- cscf->listen = 1;
-
- value = cf->args->elts;
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- u.url = value[1];
- u.listen = 1;
- u.default_port = 80;
-
- 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",
- u.err, &u.url);
- }
-
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));
-
- ngx_memcpy(&lsopt.u.sockaddr, u.sockaddr, u.socklen);
-
- lsopt.socklen = u.socklen;
- lsopt.backlog = NGX_LISTEN_BACKLOG;
- lsopt.rcvbuf = -1;
- lsopt.sndbuf = -1;
-#if (NGX_HAVE_SETFIB)
- lsopt.setfib = -1;
-#endif
-#if (NGX_HAVE_TCP_FASTOPEN)
- lsopt.fastopen = -1;
-#endif
- lsopt.wildcard = u.wildcard;
-#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- lsopt.ipv6only = 1;
-#endif
-
- (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.socklen, lsopt.addr,
- NGX_SOCKADDR_STRLEN, 1);
-
- for (n = 2; n < cf->args->nelts; n++) {
-
- if (ngx_strcmp(value[n].data, "default_server") == 0
- || ngx_strcmp(value[n].data, "default") == 0)
- {
- lsopt.default_server = 1;
- continue;
- }
-
- if (ngx_strcmp(value[n].data, "bind") == 0) {
- lsopt.set = 1;
- lsopt.bind = 1;
- continue;
- }
-
-#if (NGX_HAVE_SETFIB)
- if (ngx_strncmp(value[n].data, "setfib=", 7) == 0) {
- lsopt.setfib = ngx_atoi(value[n].data + 7, value[n].len - 7);
- lsopt.set = 1;
- lsopt.bind = 1;
-
- if (lsopt.setfib == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid setfib \"%V\"", &value[n]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-#endif
-
-#if (NGX_HAVE_TCP_FASTOPEN)
- if (ngx_strncmp(value[n].data, "fastopen=", 9) == 0) {
- lsopt.fastopen = ngx_atoi(value[n].data + 9, value[n].len - 9);
- lsopt.set = 1;
- lsopt.bind = 1;
-
- if (lsopt.fastopen == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid fastopen \"%V\"", &value[n]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-#endif
-
- if (ngx_strncmp(value[n].data, "backlog=", 8) == 0) {
- lsopt.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8);
- lsopt.set = 1;
- lsopt.bind = 1;
-
- if (lsopt.backlog == NGX_ERROR || lsopt.backlog == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid backlog \"%V\"", &value[n]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[n].data, "rcvbuf=", 7) == 0) {
- size.len = value[n].len - 7;
- size.data = value[n].data + 7;
-
- lsopt.rcvbuf = ngx_parse_size(&size);
- lsopt.set = 1;
- lsopt.bind = 1;
-
- if (lsopt.rcvbuf == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid rcvbuf \"%V\"", &value[n]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[n].data, "sndbuf=", 7) == 0) {
- size.len = value[n].len - 7;
- size.data = value[n].data + 7;
-
- lsopt.sndbuf = ngx_parse_size(&size);
- lsopt.set = 1;
- lsopt.bind = 1;
-
- if (lsopt.sndbuf == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid sndbuf \"%V\"", &value[n]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[n].data, "accept_filter=", 14) == 0) {
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
- lsopt.accept_filter = (char *) &value[n].data[14];
- lsopt.set = 1;
- lsopt.bind = 1;
-#else
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "accept filters \"%V\" are not supported "
- "on this platform, ignored",
- &value[n]);
-#endif
- continue;
- }
-
- if (ngx_strcmp(value[n].data, "deferred") == 0) {
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
- lsopt.deferred_accept = 1;
- lsopt.set = 1;
- lsopt.bind = 1;
-#else
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the deferred accept is not supported "
- "on this platform, ignored");
-#endif
- continue;
- }
-
- if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) {
-#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- struct sockaddr *sa;
-
- sa = &lsopt.u.sockaddr;
-
- if (sa->sa_family == AF_INET6) {
-
- if (ngx_strcmp(&value[n].data[10], "n") == 0) {
- lsopt.ipv6only = 1;
-
- } else if (ngx_strcmp(&value[n].data[10], "ff") == 0) {
- lsopt.ipv6only = 0;
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid ipv6only flags \"%s\"",
- &value[n].data[9]);
- return NGX_CONF_ERROR;
- }
-
- lsopt.set = 1;
- lsopt.bind = 1;
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "ipv6only is not supported "
- "on addr \"%s\", ignored", lsopt.addr);
- }
-
- continue;
-#else
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "ipv6only is not supported "
- "on this platform");
- return NGX_CONF_ERROR;
-#endif
- }
-
- if (ngx_strcmp(value[n].data, "ssl") == 0) {
-#if (NGX_HTTP_SSL)
- lsopt.ssl = 1;
- continue;
-#else
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the \"ssl\" parameter requires "
- "ngx_http_ssl_module");
- return NGX_CONF_ERROR;
-#endif
- }
-
- if (ngx_strcmp(value[n].data, "spdy") == 0) {
-#if (NGX_HTTP_SPDY)
- lsopt.spdy = 1;
- continue;
-#else
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the \"spdy\" parameter requires "
- "ngx_http_spdy_module");
- return NGX_CONF_ERROR;
-#endif
- }
-
- if (ngx_strncmp(value[n].data, "so_keepalive=", 13) == 0) {
-
- if (ngx_strcmp(&value[n].data[13], "on") == 0) {
- lsopt.so_keepalive = 1;
-
- } else if (ngx_strcmp(&value[n].data[13], "off") == 0) {
- lsopt.so_keepalive = 2;
-
- } else {
-
-#if (NGX_HAVE_KEEPALIVE_TUNABLE)
- u_char *p, *end;
- ngx_str_t s;
-
- end = value[n].data + value[n].len;
- s.data = value[n].data + 13;
-
- p = ngx_strlchr(s.data, end, ':');
- if (p == NULL) {
- p = end;
- }
-
- if (p > s.data) {
- s.len = p - s.data;
-
- lsopt.tcp_keepidle = ngx_parse_time(&s, 1);
- if (lsopt.tcp_keepidle == (time_t) NGX_ERROR) {
- goto invalid_so_keepalive;
- }
- }
-
- s.data = (p < end) ? (p + 1) : end;
-
- p = ngx_strlchr(s.data, end, ':');
- if (p == NULL) {
- p = end;
- }
-
- if (p > s.data) {
- s.len = p - s.data;
-
- lsopt.tcp_keepintvl = ngx_parse_time(&s, 1);
- if (lsopt.tcp_keepintvl == (time_t) NGX_ERROR) {
- goto invalid_so_keepalive;
- }
- }
-
- s.data = (p < end) ? (p + 1) : end;
-
- if (s.data < end) {
- s.len = end - s.data;
-
- lsopt.tcp_keepcnt = ngx_atoi(s.data, s.len);
- if (lsopt.tcp_keepcnt == NGX_ERROR) {
- goto invalid_so_keepalive;
- }
- }
-
- if (lsopt.tcp_keepidle == 0 && lsopt.tcp_keepintvl == 0
- && lsopt.tcp_keepcnt == 0)
- {
- goto invalid_so_keepalive;
- }
-
- lsopt.so_keepalive = 1;
-
-#else
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the \"so_keepalive\" parameter accepts "
- "only \"on\" or \"off\" on this platform");
- return NGX_CONF_ERROR;
-
-#endif
- }
-
- lsopt.set = 1;
- lsopt.bind = 1;
-
- continue;
-
-#if (NGX_HAVE_KEEPALIVE_TUNABLE)
- invalid_so_keepalive:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid so_keepalive value: \"%s\"",
- &value[n].data[13]);
- return NGX_CONF_ERROR;
-#endif
- }
-
- if (ngx_strcmp(value[n].data, "proxy_protocol") == 0) {
- lsopt.proxy_protocol = 1;
- continue;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[n]);
- return NGX_CONF_ERROR;
- }
-
- if (ngx_http_add_listen(cf, cscf, &lsopt) == NGX_OK) {
- return NGX_CONF_OK;
- }
-
- return NGX_CONF_ERROR;
-}
-
-
-static char *
-ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_srv_conf_t *cscf = conf;
-
- u_char ch;
- ngx_str_t *value;
- ngx_uint_t i;
- ngx_http_server_name_t *sn;
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- ch = value[i].data[0];
-
- if ((ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
- || (ch == '.' && value[i].len < 2))
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "server name \"%V\" is invalid", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (ngx_strchr(value[i].data, '/')) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "server name \"%V\" has suspicious symbols",
- &value[i]);
- }
-
- sn = ngx_array_push(&cscf->server_names);
- if (sn == NULL) {
- return NGX_CONF_ERROR;
- }
-
-#if (NGX_PCRE)
- sn->regex = NULL;
-#endif
- sn->server = cscf;
-
- if (ngx_strcasecmp(value[i].data, (u_char *) "$hostname") == 0) {
- sn->name = cf->cycle->hostname;
-
- } else {
- sn->name = value[i];
- }
-
- if (value[i].data[0] != '~') {
- ngx_strlow(sn->name.data, sn->name.data, sn->name.len);
- continue;
- }
-
-#if (NGX_PCRE)
- {
- u_char *p;
- ngx_regex_compile_t rc;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
-
- if (value[i].len == 1) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "empty regex in server name \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- value[i].len--;
- value[i].data++;
-
- ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
-
- rc.pattern = value[i];
- rc.err.len = NGX_MAX_CONF_ERRSTR;
- rc.err.data = errstr;
-
- for (p = value[i].data; p < value[i].data + value[i].len; p++) {
- if (*p >= 'A' && *p <= 'Z') {
- rc.options = NGX_REGEX_CASELESS;
- break;
- }
- }
-
- sn->regex = ngx_http_regex_compile(cf, &rc);
- if (sn->regex == NULL) {
- return NGX_CONF_ERROR;
- }
-
- sn->name = value[i];
- cscf->captures = (rc.captures > 0);
- }
-#else
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "using regex \"%V\" "
- "requires PCRE library", &value[i]);
-
- return NGX_CONF_ERROR;
-#endif
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf = conf;
-
- ngx_str_t *value;
- ngx_int_t alias;
- ngx_uint_t n;
- ngx_http_script_compile_t sc;
-
- alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0;
-
- if (clcf->root.data) {
-
- if ((clcf->alias != 0) == alias) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%V\" directive is duplicate",
- &cmd->name);
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%V\" directive is duplicate, "
- "\"%s\" directive was specified earlier",
- &cmd->name, clcf->alias ? "alias" : "root");
- }
-
- return NGX_CONF_ERROR;
- }
-
- if (clcf->named && alias) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the \"alias\" directive cannot be used "
- "inside the named location");
-
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
-
- if (ngx_chrooted && value[1].data != NULL) {
- ngx_strip_chroot(&value[1]);
- }
-
- if (ngx_strstr(value[1].data, "$document_root")
- || ngx_strstr(value[1].data, "${document_root}"))
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the $document_root variable cannot be used "
- "in the \"%V\" directive",
- &cmd->name);
-
- return NGX_CONF_ERROR;
- }
-
- if (ngx_strstr(value[1].data, "$realpath_root")
- || ngx_strstr(value[1].data, "${realpath_root}"))
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the $realpath_root variable cannot be used "
- "in the \"%V\" directive",
- &cmd->name);
-
- return NGX_CONF_ERROR;
- }
-
- clcf->alias = alias ? clcf->name.len : 0;
- clcf->root = value[1];
-
- if (!alias && clcf->root.data[clcf->root.len - 1] == '/') {
- clcf->root.len--;
- }
-
- if (clcf->root.data[0] != '$') {
- if (ngx_conf_full_name(cf->cycle, &clcf->root, 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- n = ngx_http_script_variables_count(&clcf->root);
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
- sc.variables = n;
-
-#if (NGX_PCRE)
- if (alias && clcf->regex) {
- n = 1;
- }
-#endif
-
- if (n) {
- sc.cf = cf;
- sc.source = &clcf->root;
- sc.lengths = &clcf->root_lengths;
- sc.values = &clcf->root_values;
- 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 ngx_http_method_name_t ngx_methods_names[] = {
- { (u_char *) "GET", (uint32_t) ~NGX_HTTP_GET },
- { (u_char *) "HEAD", (uint32_t) ~NGX_HTTP_HEAD },
- { (u_char *) "POST", (uint32_t) ~NGX_HTTP_POST },
- { (u_char *) "PUT", (uint32_t) ~NGX_HTTP_PUT },
- { (u_char *) "DELETE", (uint32_t) ~NGX_HTTP_DELETE },
- { (u_char *) "MKCOL", (uint32_t) ~NGX_HTTP_MKCOL },
- { (u_char *) "COPY", (uint32_t) ~NGX_HTTP_COPY },
- { (u_char *) "MOVE", (uint32_t) ~NGX_HTTP_MOVE },
- { (u_char *) "OPTIONS", (uint32_t) ~NGX_HTTP_OPTIONS },
- { (u_char *) "PROPFIND", (uint32_t) ~NGX_HTTP_PROPFIND },
- { (u_char *) "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH },
- { (u_char *) "LOCK", (uint32_t) ~NGX_HTTP_LOCK },
- { (u_char *) "UNLOCK", (uint32_t) ~NGX_HTTP_UNLOCK },
- { (u_char *) "PATCH", (uint32_t) ~NGX_HTTP_PATCH },
- { NULL, 0 }
-};
-
-
-static char *
-ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *pclcf = conf;
-
- char *rv;
- void *mconf;
- ngx_str_t *value;
- ngx_uint_t i;
- ngx_conf_t save;
- ngx_http_module_t *module;
- ngx_http_conf_ctx_t *ctx, *pctx;
- ngx_http_method_name_t *name;
- ngx_http_core_loc_conf_t *clcf;
-
- if (pclcf->limit_except) {
- return "duplicate";
- }
-
- pclcf->limit_except = 0xffffffff;
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
- for (name = ngx_methods_names; name->name; name++) {
-
- if (ngx_strcasecmp(value[i].data, name->name) == 0) {
- pclcf->limit_except &= name->method;
- goto next;
- }
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid method \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
-
- next:
- continue;
- }
-
- if (!(pclcf->limit_except & NGX_HTTP_GET)) {
- pclcf->limit_except &= (uint32_t) ~NGX_HTTP_HEAD;
- }
-
- ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- pctx = cf->ctx;
- ctx->main_conf = pctx->main_conf;
- ctx->srv_conf = pctx->srv_conf;
-
- ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
- if (ctx->loc_conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
- continue;
- }
-
- module = ngx_modules[i]->ctx;
-
- if (module->create_loc_conf) {
-
- mconf = module->create_loc_conf(cf);
- if (mconf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
- }
- }
-
-
- clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
- pclcf->limit_except_loc_conf = ctx->loc_conf;
- clcf->loc_conf = ctx->loc_conf;
- clcf->name = pclcf->name;
- clcf->noname = 1;
- clcf->lmt_excpt = 1;
-
- if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- save = *cf;
- cf->ctx = ctx;
- cf->cmd_type = NGX_HTTP_LMT_CONF;
-
- rv = ngx_conf_parse(cf, NULL);
-
- *cf = save;
-
- return rv;
-}
-
-
-static char *
-ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf = conf;
-
- ngx_str_t *value;
-
- if (clcf->directio != NGX_CONF_UNSET) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- clcf->directio = NGX_OPEN_FILE_DIRECTIO_OFF;
- return NGX_CONF_OK;
- }
-
- clcf->directio = ngx_parse_offset(&value[1]);
- if (clcf->directio == (off_t) NGX_ERROR) {
- return "invalid value";
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf = conf;
-
- u_char *p;
- ngx_int_t overwrite;
- ngx_str_t *value, uri, args;
- ngx_uint_t i, n;
- ngx_http_err_page_t *err;
- ngx_http_complex_value_t cv;
- ngx_http_compile_complex_value_t ccv;
-
- if (clcf->error_pages == NULL) {
- clcf->error_pages = ngx_array_create(cf->pool, 4,
- sizeof(ngx_http_err_page_t));
- if (clcf->error_pages == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- value = cf->args->elts;
-
- i = cf->args->nelts - 2;
-
- if (value[i].data[0] == '=') {
- if (i == 1) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (value[i].len > 1) {
- overwrite = ngx_atoi(&value[i].data[1], value[i].len - 1);
-
- if (overwrite == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- } else {
- overwrite = 0;
- }
-
- n = 2;
-
- } else {
- overwrite = -1;
- n = 1;
- }
-
- uri = value[cf->args->nelts - 1];
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &uri;
- ccv.complex_value = &cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- ngx_str_null(&args);
-
- if (cv.lengths == NULL && uri.len && uri.data[0] == '/') {
- p = (u_char *) ngx_strchr(uri.data, '?');
-
- if (p) {
- cv.value.len = p - uri.data;
- cv.value.data = uri.data;
- p++;
- args.len = (uri.data + uri.len) - p;
- args.data = p;
- }
- }
-
- for (i = 1; i < cf->args->nelts - n; i++) {
- err = ngx_array_push(clcf->error_pages);
- if (err == NULL) {
- return NGX_CONF_ERROR;
- }
-
- err->status = ngx_atoi(value[i].data, value[i].len);
-
- if (err->status == NGX_ERROR || err->status == 499) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (err->status < 300 || err->status > 599) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "value \"%V\" must be between 300 and 599",
- &value[i]);
- return NGX_CONF_ERROR;
- }
-
- err->overwrite = overwrite;
-
- if (overwrite == -1) {
- switch (err->status) {
- case NGX_HTTP_TO_HTTPS:
- case NGX_HTTPS_CERT_ERROR:
- case NGX_HTTPS_NO_CERT:
- err->overwrite = NGX_HTTP_BAD_REQUEST;
- default:
- break;
- }
- }
-
- err->value = cv;
- err->args = args;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf = conf;
-
- ngx_str_t *value;
- ngx_int_t code;
- ngx_uint_t i, n;
- ngx_http_try_file_t *tf;
- ngx_http_script_compile_t sc;
- ngx_http_core_main_conf_t *cmcf;
-
- if (clcf->try_files) {
- return "is duplicate";
- }
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- cmcf->try_files = 1;
-
- tf = ngx_pcalloc(cf->pool, cf->args->nelts * sizeof(ngx_http_try_file_t));
- if (tf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- clcf->try_files = tf;
-
- value = cf->args->elts;
-
- for (i = 0; i < cf->args->nelts - 1; i++) {
-
- tf[i].name = value[i + 1];
-
- if (tf[i].name.len > 0
- && tf[i].name.data[tf[i].name.len - 1] == '/')
- {
- tf[i].test_dir = 1;
- tf[i].name.len--;
- tf[i].name.data[tf[i].name.len] = '\0';
- }
-
- n = ngx_http_script_variables_count(&tf[i].name);
-
- if (n) {
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = cf;
- sc.source = &tf[i].name;
- sc.lengths = &tf[i].lengths;
- sc.values = &tf[i].values;
- sc.variables = n;
- sc.complete_lengths = 1;
- sc.complete_values = 1;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- } else {
- /* add trailing '\0' to length */
- tf[i].name.len++;
- }
- }
-
- if (tf[i - 1].name.data[0] == '=') {
-
- code = ngx_atoi(tf[i - 1].name.data + 1, tf[i - 1].name.len - 2);
-
- if (code == NGX_ERROR || code > 999) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid code \"%*s\"",
- tf[i - 1].name.len - 1, tf[i - 1].name.data);
- return NGX_CONF_ERROR;
- }
-
- tf[i].code = code;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf = conf;
-
- time_t inactive;
- ngx_str_t *value, s;
- ngx_int_t max;
- ngx_uint_t i;
-
- if (clcf->open_file_cache != NGX_CONF_UNSET_PTR) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- max = 0;
- inactive = 60;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (ngx_strncmp(value[i].data, "max=", 4) == 0) {
-
- max = ngx_atoi(value[i].data + 4, value[i].len - 4);
- if (max <= 0) {
- goto failed;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
-
- s.len = value[i].len - 9;
- s.data = value[i].data + 9;
-
- inactive = ngx_parse_time(&s, 1);
- if (inactive == (time_t) NGX_ERROR) {
- goto failed;
- }
-
- continue;
- }
-
- if (ngx_strcmp(value[i].data, "off") == 0) {
-
- clcf->open_file_cache = NULL;
-
- continue;
- }
-
- failed:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid \"open_file_cache\" parameter \"%V\"",
- &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (clcf->open_file_cache == NULL) {
- return NGX_CONF_OK;
- }
-
- if (max == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"open_file_cache\" must have the \"max\" parameter");
- return NGX_CONF_ERROR;
- }
-
- clcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
- if (clcf->open_file_cache) {
- return NGX_CONF_OK;
- }
-
- return NGX_CONF_ERROR;
-}
-
-
-static char *
-ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf = conf;
-
- return ngx_log_set_log(cf, &clcf->error_log);
-}
-
-
-static char *
-ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf = conf;
-
- ngx_str_t *value;
-
- if (clcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- clcf->keepalive_timeout = ngx_parse_time(&value[1], 0);
-
- if (clcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) {
- return "invalid value";
- }
-
- if (cf->args->nelts == 2) {
- return NGX_CONF_OK;
- }
-
- clcf->keepalive_header = ngx_parse_time(&value[2], 1);
-
- if (clcf->keepalive_header == (time_t) NGX_ERROR) {
- return "invalid value";
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf = conf;
-
- if (clcf->internal != NGX_CONF_UNSET) {
- return "is duplicate";
- }
-
- clcf->internal = 1;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf = conf;
-
- ngx_str_t *value;
-
- if (clcf->resolver) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- clcf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1);
- if (clcf->resolver == NULL) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-#if (NGX_HTTP_GZIP)
-
-static char *
-ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf = conf;
-
-#if (NGX_PCRE)
-
- ngx_str_t *value;
- ngx_uint_t i;
- ngx_regex_elt_t *re;
- ngx_regex_compile_t rc;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
-
- if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) {
- clcf->gzip_disable = ngx_array_create(cf->pool, 2,
- sizeof(ngx_regex_elt_t));
- if (clcf->gzip_disable == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- value = cf->args->elts;
-
- ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
-
- rc.pool = cf->pool;
- rc.err.len = NGX_MAX_CONF_ERRSTR;
- rc.err.data = errstr;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (ngx_strcmp(value[i].data, "msie6") == 0) {
- clcf->gzip_disable_msie6 = 1;
- continue;
- }
-
-#if (NGX_HTTP_DEGRADATION)
-
- if (ngx_strcmp(value[i].data, "degradation") == 0) {
- clcf->gzip_disable_degradation = 1;
- continue;
- }
-
-#endif
-
- re = ngx_array_push(clcf->gzip_disable);
- if (re == NULL) {
- return NGX_CONF_ERROR;
- }
-
- rc.pattern = value[i];
- rc.options = NGX_REGEX_CASELESS;
-
- if (ngx_regex_compile(&rc) != NGX_OK) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
- return NGX_CONF_ERROR;
- }
-
- re->regex = rc.regex;
- re->name = value[i].data;
- }
-
- return NGX_CONF_OK;
-
-#else
- ngx_str_t *value;
- ngx_uint_t i;
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
- if (ngx_strcmp(value[i].data, "msie6") == 0) {
- clcf->gzip_disable_msie6 = 1;
- continue;
- }
-
-#if (NGX_HTTP_DEGRADATION)
-
- if (ngx_strcmp(value[i].data, "degradation") == 0) {
- clcf->gzip_disable_degradation = 1;
- continue;
- }
-
-#endif
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "without PCRE library \"gzip_disable\" supports "
- "builtin \"msie6\" and \"degradation\" mask only");
-
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-
-#endif
-}
-
-#endif
-
-
-#if (NGX_HAVE_OPENAT)
-
-static char *
-ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_core_loc_conf_t *clcf = conf;
-
- ngx_str_t *value;
- ngx_uint_t i;
- ngx_http_compile_complex_value_t ccv;
-
- if (clcf->disable_symlinks != NGX_CONF_UNSET_UINT) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (ngx_strcmp(value[i].data, "off") == 0) {
- clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_OFF;
- continue;
- }
-
- if (ngx_strcmp(value[i].data, "if_not_owner") == 0) {
- clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_NOTOWNER;
- continue;
- }
-
- if (ngx_strcmp(value[i].data, "on") == 0) {
- clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_ON;
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "from=", 5) == 0) {
- value[i].len -= 5;
- value[i].data += 5;
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[i];
- ccv.complex_value = ngx_palloc(cf->pool,
- sizeof(ngx_http_complex_value_t));
- if (ccv.complex_value == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- clcf->disable_symlinks_from = ccv.complex_value;
-
- continue;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (clcf->disable_symlinks == NGX_CONF_UNSET_UINT) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%V\" must have \"off\", \"on\" "
- "or \"if_not_owner\" parameter",
- &cmd->name);
- return NGX_CONF_ERROR;
- }
-
- if (cf->args->nelts == 2) {
- clcf->disable_symlinks_from = NULL;
- return NGX_CONF_OK;
- }
-
- if (clcf->disable_symlinks_from == NGX_CONF_UNSET_PTR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate parameters \"%V %V\"",
- &value[1], &value[2]);
- return NGX_CONF_ERROR;
- }
-
- if (clcf->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"from=\" cannot be used with \"off\" parameter");
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-#endif
-
-
-static char *
-ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data)
-{
-#if (NGX_FREEBSD)
- ssize_t *np = data;
-
- if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"send_lowat\" must be less than %d "
- "(sysctl net.inet.tcp.sendspace)",
- ngx_freebsd_net_inet_tcp_sendspace);
-
- return NGX_CONF_ERROR;
- }
-
-#elif !(NGX_HAVE_SO_SNDLOWAT)
- ssize_t *np = data;
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "\"send_lowat\" is not supported, ignored");
-
- *np = 0;
-
-#endif
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data)
-{
- size_t *sp = data;
-
- if (*sp < NGX_MIN_POOL_SIZE) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the pool size must be no less than %uz",
- NGX_MIN_POOL_SIZE);
- return NGX_CONF_ERROR;
- }
-
- if (*sp % NGX_POOL_ALIGNMENT) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the pool size must be a multiple of %uz",
- NGX_POOL_ALIGNMENT);
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_core_module.h b/usr.sbin/nginx/src/http/ngx_http_core_module.h
deleted file mode 100644
index 799d2fe0dd5..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_core_module.h
+++ /dev/null
@@ -1,588 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HTTP_CORE_H_INCLUDED_
-#define _NGX_HTTP_CORE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-#define NGX_HTTP_GZIP_PROXIED_OFF 0x0002
-#define NGX_HTTP_GZIP_PROXIED_EXPIRED 0x0004
-#define NGX_HTTP_GZIP_PROXIED_NO_CACHE 0x0008
-#define NGX_HTTP_GZIP_PROXIED_NO_STORE 0x0010
-#define NGX_HTTP_GZIP_PROXIED_PRIVATE 0x0020
-#define NGX_HTTP_GZIP_PROXIED_NO_LM 0x0040
-#define NGX_HTTP_GZIP_PROXIED_NO_ETAG 0x0080
-#define NGX_HTTP_GZIP_PROXIED_AUTH 0x0100
-#define NGX_HTTP_GZIP_PROXIED_ANY 0x0200
-
-
-#define NGX_HTTP_AIO_OFF 0
-#define NGX_HTTP_AIO_ON 1
-#define NGX_HTTP_AIO_SENDFILE 2
-
-
-#define NGX_HTTP_SATISFY_ALL 0
-#define NGX_HTTP_SATISFY_ANY 1
-
-
-#define NGX_HTTP_LINGERING_OFF 0
-#define NGX_HTTP_LINGERING_ON 1
-#define NGX_HTTP_LINGERING_ALWAYS 2
-
-
-#define NGX_HTTP_IMS_OFF 0
-#define NGX_HTTP_IMS_EXACT 1
-#define NGX_HTTP_IMS_BEFORE 2
-
-
-#define NGX_HTTP_KEEPALIVE_DISABLE_NONE 0x0002
-#define NGX_HTTP_KEEPALIVE_DISABLE_MSIE6 0x0004
-#define NGX_HTTP_KEEPALIVE_DISABLE_SAFARI 0x0008
-
-
-typedef struct ngx_http_location_tree_node_s ngx_http_location_tree_node_t;
-typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t;
-
-
-typedef struct {
- union {
- struct sockaddr sockaddr;
- struct sockaddr_in sockaddr_in;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 sockaddr_in6;
-#endif
-#if (NGX_HAVE_UNIX_DOMAIN)
- struct sockaddr_un sockaddr_un;
-#endif
- u_char sockaddr_data[NGX_SOCKADDRLEN];
- } u;
-
- socklen_t socklen;
-
- unsigned set:1;
- unsigned default_server:1;
- unsigned bind:1;
- unsigned wildcard:1;
-#if (NGX_HTTP_SSL)
- unsigned ssl:1;
-#endif
-#if (NGX_HTTP_SPDY)
- unsigned spdy:1;
-#endif
-#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- unsigned ipv6only:1;
-#endif
- unsigned so_keepalive:2;
- unsigned proxy_protocol:1;
-
- int backlog;
- int rcvbuf;
- int sndbuf;
-#if (NGX_HAVE_SETFIB)
- int setfib;
-#endif
-#if (NGX_HAVE_TCP_FASTOPEN)
- int fastopen;
-#endif
-#if (NGX_HAVE_KEEPALIVE_TUNABLE)
- int tcp_keepidle;
- int tcp_keepintvl;
- int tcp_keepcnt;
-#endif
-
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
- char *accept_filter;
-#endif
-#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
- ngx_uint_t deferred_accept;
-#endif
-
- u_char addr[NGX_SOCKADDR_STRLEN + 1];
-} ngx_http_listen_opt_t;
-
-
-typedef enum {
- NGX_HTTP_POST_READ_PHASE = 0,
-
- NGX_HTTP_SERVER_REWRITE_PHASE,
-
- NGX_HTTP_FIND_CONFIG_PHASE,
- NGX_HTTP_REWRITE_PHASE,
- NGX_HTTP_POST_REWRITE_PHASE,
-
- NGX_HTTP_PREACCESS_PHASE,
-
- NGX_HTTP_ACCESS_PHASE,
- NGX_HTTP_POST_ACCESS_PHASE,
-
- NGX_HTTP_TRY_FILES_PHASE,
- NGX_HTTP_CONTENT_PHASE,
-
- NGX_HTTP_LOG_PHASE
-} ngx_http_phases;
-
-typedef struct ngx_http_phase_handler_s ngx_http_phase_handler_t;
-
-typedef ngx_int_t (*ngx_http_phase_handler_pt)(ngx_http_request_t *r,
- ngx_http_phase_handler_t *ph);
-
-struct ngx_http_phase_handler_s {
- ngx_http_phase_handler_pt checker;
- ngx_http_handler_pt handler;
- ngx_uint_t next;
-};
-
-
-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;
-
-
-typedef struct {
- ngx_array_t handlers;
-} ngx_http_phase_t;
-
-
-typedef struct {
- ngx_array_t servers; /* ngx_http_core_srv_conf_t */
-
- ngx_http_phase_engine_t phase_engine;
-
- ngx_hash_t headers_in_hash;
-
- ngx_hash_t variables_hash;
-
- ngx_array_t variables; /* ngx_http_variable_t */
- ngx_uint_t ncaptures;
-
- ngx_uint_t server_names_hash_max_size;
- ngx_uint_t server_names_hash_bucket_size;
-
- ngx_uint_t variables_hash_max_size;
- ngx_uint_t variables_hash_bucket_size;
-
- ngx_hash_keys_arrays_t *variables_keys;
-
- ngx_array_t *ports;
-
- ngx_uint_t try_files; /* unsigned try_files:1 */
-
- ngx_http_phase_t phases[NGX_HTTP_LOG_PHASE + 1];
-} ngx_http_core_main_conf_t;
-
-
-typedef struct {
- /* array of the ngx_http_server_name_t, "server_name" directive */
- ngx_array_t server_names;
-
- /* server ctx */
- ngx_http_conf_ctx_t *ctx;
-
- ngx_str_t server_name;
-
- size_t connection_pool_size;
- size_t request_pool_size;
- size_t client_header_buffer_size;
-
- ngx_bufs_t large_client_header_buffers;
-
- ngx_msec_t client_header_timeout;
-
- ngx_flag_t ignore_invalid_headers;
- ngx_flag_t merge_slashes;
- ngx_flag_t underscores_in_headers;
-
- unsigned listen:1;
-#if (NGX_PCRE)
- unsigned captures:1;
-#endif
-
- ngx_http_core_loc_conf_t **named_locations;
-} ngx_http_core_srv_conf_t;
-
-
-/* list of structures to find core_srv_conf quickly at run time */
-
-
-typedef struct {
-#if (NGX_PCRE)
- ngx_http_regex_t *regex;
-#endif
- ngx_http_core_srv_conf_t *server; /* virtual name server conf */
- ngx_str_t name;
-} ngx_http_server_name_t;
-
-
-typedef struct {
- ngx_hash_combined_t names;
-
- ngx_uint_t nregex;
- ngx_http_server_name_t *regex;
-} ngx_http_virtual_names_t;
-
-
-struct ngx_http_addr_conf_s {
- /* the default server configuration for this address:port */
- ngx_http_core_srv_conf_t *default_server;
-
- ngx_http_virtual_names_t *virtual_names;
-
-#if (NGX_HTTP_SSL)
- unsigned ssl:1;
-#endif
-#if (NGX_HTTP_SPDY)
- unsigned spdy:1;
-#endif
- unsigned proxy_protocol:1;
-};
-
-
-typedef struct {
- in_addr_t addr;
- ngx_http_addr_conf_t conf;
-} ngx_http_in_addr_t;
-
-
-#if (NGX_HAVE_INET6)
-
-typedef struct {
- struct in6_addr addr6;
- ngx_http_addr_conf_t conf;
-} ngx_http_in6_addr_t;
-
-#endif
-
-
-typedef struct {
- /* ngx_http_in_addr_t or ngx_http_in6_addr_t */
- void *addrs;
- ngx_uint_t naddrs;
-} ngx_http_port_t;
-
-
-typedef struct {
- ngx_int_t family;
- in_port_t port;
- ngx_array_t addrs; /* array of ngx_http_conf_addr_t */
-} ngx_http_conf_port_t;
-
-
-typedef struct {
- ngx_http_listen_opt_t opt;
-
- ngx_hash_t hash;
- ngx_hash_wildcard_t *wc_head;
- ngx_hash_wildcard_t *wc_tail;
-
-#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 *default_server;
- ngx_array_t servers; /* array of ngx_http_core_srv_conf_t */
-} ngx_http_conf_addr_t;
-
-
-typedef struct {
- ngx_int_t status;
- ngx_int_t overwrite;
- ngx_http_complex_value_t value;
- ngx_str_t args;
-} ngx_http_err_page_t;
-
-
-typedef struct {
- ngx_array_t *lengths;
- ngx_array_t *values;
- ngx_str_t name;
-
- unsigned code:10;
- unsigned test_dir:1;
-} ngx_http_try_file_t;
-
-
-struct ngx_http_core_loc_conf_s {
- ngx_str_t name; /* location name */
-
-#if (NGX_PCRE)
- ngx_http_regex_t *regex;
-#endif
-
- unsigned noname:1; /* "if () {}" block or limit_except */
- unsigned lmt_excpt:1;
- unsigned named:1;
-
- unsigned exact_match:1;
- unsigned noregex:1;
-
- unsigned auto_redirect:1;
-#if (NGX_HTTP_GZIP)
- unsigned gzip_disable_msie6:2;
-#if (NGX_HTTP_DEGRADATION)
- unsigned gzip_disable_degradation:2;
-#endif
-#endif
-
- ngx_http_location_tree_node_t *static_locations;
-#if (NGX_PCRE)
- ngx_http_core_loc_conf_t **regex_locations;
-#endif
-
- /* pointer to the modules' loc_conf */
- void **loc_conf;
-
- uint32_t limit_except;
- void **limit_except_loc_conf;
-
- ngx_http_handler_pt handler;
-
- /* location name length for inclusive location with inherited alias */
- size_t alias;
- ngx_str_t root; /* root, alias */
- ngx_str_t post_action;
-
- ngx_array_t *root_lengths;
- ngx_array_t *root_values;
-
- ngx_array_t *types;
- ngx_hash_t types_hash;
- ngx_str_t default_type;
-
- off_t client_max_body_size; /* client_max_body_size */
- off_t directio; /* directio */
- off_t directio_alignment; /* directio_alignment */
-
- size_t client_body_buffer_size; /* client_body_buffer_size */
- size_t send_lowat; /* send_lowat */
- size_t postpone_output; /* postpone_output */
- size_t limit_rate; /* limit_rate */
- size_t limit_rate_after; /* limit_rate_after */
- size_t sendfile_max_chunk; /* sendfile_max_chunk */
- size_t read_ahead; /* read_ahead */
-
- ngx_msec_t client_body_timeout; /* client_body_timeout */
- ngx_msec_t send_timeout; /* send_timeout */
- ngx_msec_t keepalive_timeout; /* keepalive_timeout */
- ngx_msec_t lingering_time; /* lingering_time */
- ngx_msec_t lingering_timeout; /* lingering_timeout */
- ngx_msec_t resolver_timeout; /* resolver_timeout */
-
- ngx_resolver_t *resolver; /* resolver */
-
- time_t keepalive_header; /* keepalive_timeout */
-
- ngx_uint_t keepalive_requests; /* keepalive_requests */
- ngx_uint_t keepalive_disable; /* keepalive_disable */
- ngx_uint_t satisfy; /* satisfy */
- ngx_uint_t lingering_close; /* lingering_close */
- ngx_uint_t if_modified_since; /* if_modified_since */
- ngx_uint_t max_ranges; /* max_ranges */
- ngx_uint_t client_body_in_file_only; /* client_body_in_file_only */
-
- ngx_flag_t client_body_in_single_buffer;
- /* client_body_in_singe_buffer */
- ngx_flag_t internal; /* internal */
- ngx_flag_t sendfile; /* sendfile */
-#if (NGX_HAVE_FILE_AIO)
- ngx_flag_t aio; /* aio */
-#endif
- ngx_flag_t tcp_nopush; /* tcp_nopush */
- ngx_flag_t tcp_nodelay; /* tcp_nodelay */
- ngx_flag_t reset_timedout_connection; /* reset_timedout_connection */
- ngx_flag_t server_name_in_redirect; /* server_name_in_redirect */
- ngx_flag_t port_in_redirect; /* port_in_redirect */
- ngx_flag_t msie_padding; /* msie_padding */
- ngx_flag_t msie_refresh; /* msie_refresh */
- ngx_flag_t log_not_found; /* log_not_found */
- ngx_flag_t log_subrequest; /* log_subrequest */
- ngx_flag_t recursive_error_pages; /* recursive_error_pages */
- ngx_flag_t server_tokens; /* server_tokens */
- ngx_flag_t chunked_transfer_encoding; /* chunked_transfer_encoding */
- ngx_flag_t etag; /* etag */
-
-#if (NGX_HTTP_GZIP)
- ngx_flag_t gzip_vary; /* gzip_vary */
-
- ngx_uint_t gzip_http_version; /* gzip_http_version */
- ngx_uint_t gzip_proxied; /* gzip_proxied */
-
-#if (NGX_PCRE)
- ngx_array_t *gzip_disable; /* gzip_disable */
-#endif
-#endif
-
-#if (NGX_HAVE_OPENAT)
- ngx_uint_t disable_symlinks; /* disable_symlinks */
- ngx_http_complex_value_t *disable_symlinks_from;
-#endif
-
- ngx_array_t *error_pages; /* error_page */
- ngx_http_try_file_t *try_files; /* try_files */
-
- ngx_path_t *client_body_temp_path; /* client_body_temp_path */
-
- ngx_open_file_cache_t *open_file_cache;
- time_t open_file_cache_valid;
- ngx_uint_t open_file_cache_min_uses;
- ngx_flag_t open_file_cache_errors;
- ngx_flag_t open_file_cache_events;
-
- ngx_log_t *error_log;
-
- ngx_uint_t types_hash_max_size;
- ngx_uint_t types_hash_bucket_size;
-
- ngx_queue_t *locations;
-
-#if 0
- ngx_http_core_loc_conf_t *prev_location;
-#endif
-};
-
-
-typedef struct {
- ngx_queue_t queue;
- ngx_http_core_loc_conf_t *exact;
- ngx_http_core_loc_conf_t *inclusive;
- ngx_str_t *name;
- u_char *file_name;
- ngx_uint_t line;
- ngx_queue_t list;
-} ngx_http_location_queue_t;
-
-
-struct ngx_http_location_tree_node_s {
- ngx_http_location_tree_node_t *left;
- ngx_http_location_tree_node_t *right;
- ngx_http_location_tree_node_t *tree;
-
- ngx_http_core_loc_conf_t *exact;
- ngx_http_core_loc_conf_t *inclusive;
-
- u_char auto_redirect;
- u_char len;
- u_char name[1];
-};
-
-
-void ngx_http_core_run_phases(ngx_http_request_t *r);
-ngx_int_t ngx_http_core_generic_phase(ngx_http_request_t *r,
- ngx_http_phase_handler_t *ph);
-ngx_int_t ngx_http_core_rewrite_phase(ngx_http_request_t *r,
- ngx_http_phase_handler_t *ph);
-ngx_int_t ngx_http_core_find_config_phase(ngx_http_request_t *r,
- ngx_http_phase_handler_t *ph);
-ngx_int_t ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
- ngx_http_phase_handler_t *ph);
-ngx_int_t ngx_http_core_access_phase(ngx_http_request_t *r,
- ngx_http_phase_handler_t *ph);
-ngx_int_t ngx_http_core_post_access_phase(ngx_http_request_t *r,
- ngx_http_phase_handler_t *ph);
-ngx_int_t ngx_http_core_try_files_phase(ngx_http_request_t *r,
- ngx_http_phase_handler_t *ph);
-ngx_int_t ngx_http_core_content_phase(ngx_http_request_t *r,
- ngx_http_phase_handler_t *ph);
-
-
-void *ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash);
-ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r);
-void ngx_http_set_exten(ngx_http_request_t *r);
-ngx_int_t ngx_http_set_etag(ngx_http_request_t *r);
-ngx_int_t ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
- ngx_str_t *ct, ngx_http_complex_value_t *cv);
-u_char *ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *name,
- size_t *root_length, size_t reserved);
-ngx_int_t ngx_http_auth_basic_user(ngx_http_request_t *r);
-#if (NGX_HTTP_GZIP)
-ngx_int_t ngx_http_gzip_ok(ngx_http_request_t *r);
-#endif
-
-
-ngx_int_t ngx_http_subrequest(ngx_http_request_t *r,
- ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **sr,
- ngx_http_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);
-
-
-typedef ngx_int_t (*ngx_http_output_header_filter_pt)(ngx_http_request_t *r);
-typedef ngx_int_t (*ngx_http_output_body_filter_pt)
- (ngx_http_request_t *r, ngx_chain_t *chain);
-
-
-ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *chain);
-ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *chain);
-
-
-ngx_int_t ngx_http_set_disable_symlinks(ngx_http_request_t *r,
- ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of);
-
-ngx_int_t ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
- ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies,
- int recursive);
-
-
-extern ngx_module_t ngx_http_core_module;
-
-extern ngx_uint_t ngx_http_max_module;
-
-extern ngx_str_t ngx_http_core_get_method;
-
-
-#define ngx_http_clear_content_length(r) \
- \
- r->headers_out.content_length_n = -1; \
- if (r->headers_out.content_length) { \
- r->headers_out.content_length->hash = 0; \
- r->headers_out.content_length = NULL; \
- }
- \
-#define ngx_http_clear_accept_ranges(r) \
- \
- r->allow_ranges = 0; \
- if (r->headers_out.accept_ranges) { \
- r->headers_out.accept_ranges->hash = 0; \
- r->headers_out.accept_ranges = NULL; \
- }
-
-#define ngx_http_clear_last_modified(r) \
- \
- r->headers_out.last_modified_time = -1; \
- if (r->headers_out.last_modified) { \
- r->headers_out.last_modified->hash = 0; \
- r->headers_out.last_modified = NULL; \
- }
-
-#define ngx_http_clear_location(r) \
- \
- if (r->headers_out.location) { \
- r->headers_out.location->hash = 0; \
- r->headers_out.location = NULL; \
- }
-
-#define ngx_http_clear_etag(r) \
- \
- if (r->headers_out.etag) { \
- r->headers_out.etag->hash = 0; \
- r->headers_out.etag = NULL; \
- }
-
-
-#endif /* _NGX_HTTP_CORE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/ngx_http_file_cache.c b/usr.sbin/nginx/src/http/ngx_http_file_cache.c
deleted file mode 100644
index 9e6be15844a..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_file_cache.c
+++ /dev/null
@@ -1,1999 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-#include <ngx_md5.h>
-
-
-static ngx_int_t ngx_http_file_cache_lock(ngx_http_request_t *r,
- ngx_http_cache_t *c);
-static void ngx_http_file_cache_lock_wait_handler(ngx_event_t *ev);
-static ngx_int_t ngx_http_file_cache_read(ngx_http_request_t *r,
- ngx_http_cache_t *c);
-static ssize_t ngx_http_file_cache_aio_read(ngx_http_request_t *r,
- ngx_http_cache_t *c);
-#if (NGX_HAVE_FILE_AIO)
-static void ngx_http_cache_aio_event_handler(ngx_event_t *ev);
-#endif
-static ngx_int_t ngx_http_file_cache_exists(ngx_http_file_cache_t *cache,
- ngx_http_cache_t *c);
-static ngx_int_t ngx_http_file_cache_name(ngx_http_request_t *r,
- ngx_path_t *path);
-static ngx_http_file_cache_node_t *
- ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key);
-static void ngx_http_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
-static void ngx_http_file_cache_cleanup(void *data);
-static time_t ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache);
-static time_t ngx_http_file_cache_expire(ngx_http_file_cache_t *cache);
-static void ngx_http_file_cache_delete(ngx_http_file_cache_t *cache,
- ngx_queue_t *q, u_char *name);
-static void ngx_http_file_cache_loader_sleep(ngx_http_file_cache_t *cache);
-static ngx_int_t ngx_http_file_cache_noop(ngx_tree_ctx_t *ctx,
- ngx_str_t *path);
-static ngx_int_t ngx_http_file_cache_manage_file(ngx_tree_ctx_t *ctx,
- ngx_str_t *path);
-static ngx_int_t ngx_http_file_cache_add_file(ngx_tree_ctx_t *ctx,
- ngx_str_t *path);
-static ngx_int_t ngx_http_file_cache_add(ngx_http_file_cache_t *cache,
- ngx_http_cache_t *c);
-static ngx_int_t ngx_http_file_cache_delete_file(ngx_tree_ctx_t *ctx,
- ngx_str_t *path);
-
-
-ngx_str_t ngx_http_cache_status[] = {
- ngx_string("MISS"),
- ngx_string("BYPASS"),
- ngx_string("EXPIRED"),
- ngx_string("STALE"),
- ngx_string("UPDATING"),
- ngx_string("REVALIDATED"),
- ngx_string("HIT")
-};
-
-
-static u_char ngx_http_file_cache_key[] = { LF, 'K', 'E', 'Y', ':', ' ' };
-
-
-static ngx_int_t
-ngx_http_file_cache_init(ngx_shm_zone_t *shm_zone, void *data)
-{
- ngx_http_file_cache_t *ocache = data;
-
- size_t len;
- ngx_uint_t n;
- ngx_http_file_cache_t *cache;
-
- cache = shm_zone->data;
-
- if (ocache) {
- if (ngx_strcmp(cache->path->name.data, ocache->path->name.data) != 0) {
- ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
- "cache \"%V\" uses the \"%V\" cache path "
- "while previously it used the \"%V\" cache path",
- &shm_zone->shm.name, &cache->path->name,
- &ocache->path->name);
-
- return NGX_ERROR;
- }
-
- for (n = 0; n < 3; n++) {
- if (cache->path->level[n] != ocache->path->level[n]) {
- ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
- "cache \"%V\" had previously different levels",
- &shm_zone->shm.name);
- return NGX_ERROR;
- }
- }
-
- cache->sh = ocache->sh;
-
- cache->shpool = ocache->shpool;
- cache->bsize = ocache->bsize;
-
- cache->max_size /= cache->bsize;
-
- if (!cache->sh->cold || cache->sh->loading) {
- cache->path->loader = NULL;
- }
-
- return NGX_OK;
- }
-
- cache->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
-
- if (shm_zone->shm.exists) {
- cache->sh = cache->shpool->data;
- cache->bsize = ngx_fs_bsize(cache->path->name.data);
-
- return NGX_OK;
- }
-
- cache->sh = ngx_slab_alloc(cache->shpool, sizeof(ngx_http_file_cache_sh_t));
- if (cache->sh == NULL) {
- return NGX_ERROR;
- }
-
- cache->shpool->data = cache->sh;
-
- ngx_rbtree_init(&cache->sh->rbtree, &cache->sh->sentinel,
- ngx_http_file_cache_rbtree_insert_value);
-
- ngx_queue_init(&cache->sh->queue);
-
- cache->sh->cold = 1;
- cache->sh->loading = 0;
- cache->sh->size = 0;
-
- cache->bsize = ngx_fs_bsize(cache->path->name.data);
-
- cache->max_size /= cache->bsize;
-
- len = sizeof(" in cache keys zone \"\"") + shm_zone->shm.name.len;
-
- cache->shpool->log_ctx = ngx_slab_alloc(cache->shpool, len);
- if (cache->shpool->log_ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_sprintf(cache->shpool->log_ctx, " in cache keys zone \"%V\"%Z",
- &shm_zone->shm.name);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_file_cache_new(ngx_http_request_t *r)
-{
- ngx_http_cache_t *c;
-
- c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t));
- if (c == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) {
- return NGX_ERROR;
- }
-
- r->cache = c;
- c->file.log = r->connection->log;
- c->file.fd = NGX_INVALID_FILE;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_file_cache_create(ngx_http_request_t *r)
-{
- ngx_http_cache_t *c;
- ngx_pool_cleanup_t *cln;
- ngx_http_file_cache_t *cache;
-
- c = r->cache;
- cache = c->file_cache;
-
- cln = ngx_pool_cleanup_add(r->pool, 0);
- if (cln == NULL) {
- return NGX_ERROR;
- }
-
- cln->handler = ngx_http_file_cache_cleanup;
- cln->data = c;
-
- if (ngx_http_file_cache_exists(cache, c) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-void
-ngx_http_file_cache_create_key(ngx_http_request_t *r)
-{
- size_t len;
- ngx_str_t *key;
- ngx_uint_t i;
- ngx_md5_t md5;
- ngx_http_cache_t *c;
-
- c = r->cache;
-
- len = 0;
-
- ngx_crc32_init(c->crc32);
- ngx_md5_init(&md5);
-
- key = c->keys.elts;
- for (i = 0; i < c->keys.nelts; i++) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http cache key: \"%V\"", &key[i]);
-
- len += key[i].len;
-
- ngx_crc32_update(&c->crc32, key[i].data, key[i].len);
- ngx_md5_update(&md5, key[i].data, key[i].len);
- }
-
- c->header_start = sizeof(ngx_http_file_cache_header_t)
- + sizeof(ngx_http_file_cache_key) + len + 1;
-
- ngx_crc32_final(c->crc32);
- ngx_md5_final(c->key, &md5);
-}
-
-
-ngx_int_t
-ngx_http_file_cache_open(ngx_http_request_t *r)
-{
- ngx_int_t rc, rv;
- ngx_uint_t cold, test;
- ngx_http_cache_t *c;
- ngx_pool_cleanup_t *cln;
- ngx_open_file_info_t of;
- ngx_http_file_cache_t *cache;
- ngx_http_core_loc_conf_t *clcf;
-
- c = r->cache;
-
- if (c->waiting) {
- return NGX_AGAIN;
- }
-
- if (c->buf) {
- return ngx_http_file_cache_read(r, c);
- }
-
- cache = c->file_cache;
-
- if (c->node == NULL) {
- cln = ngx_pool_cleanup_add(r->pool, 0);
- if (cln == NULL) {
- return NGX_ERROR;
- }
-
- cln->handler = ngx_http_file_cache_cleanup;
- cln->data = c;
- }
-
- rc = ngx_http_file_cache_exists(cache, c);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http file cache exists: %i e:%d", rc, c->exists);
-
- if (rc == NGX_ERROR) {
- return rc;
- }
-
- if (rc == NGX_AGAIN) {
- return NGX_HTTP_CACHE_SCARCE;
- }
-
- cold = cache->sh->cold;
-
- if (rc == NGX_OK) {
-
- if (c->error) {
- return c->error;
- }
-
- c->temp_file = 1;
- test = c->exists ? 1 : 0;
- rv = NGX_DECLINED;
-
- } else { /* rc == NGX_DECLINED */
-
- if (c->min_uses > 1) {
-
- if (!cold) {
- return NGX_HTTP_CACHE_SCARCE;
- }
-
- test = 1;
- rv = NGX_HTTP_CACHE_SCARCE;
-
- } else {
- c->temp_file = 1;
- test = cold ? 1 : 0;
- rv = NGX_DECLINED;
- }
- }
-
- if (ngx_http_file_cache_name(r, cache->path) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (!test) {
- goto done;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- ngx_memzero(&of, sizeof(ngx_open_file_info_t));
-
- of.uniq = c->uniq;
- of.valid = clcf->open_file_cache_valid;
- of.min_uses = clcf->open_file_cache_min_uses;
- of.events = clcf->open_file_cache_events;
- of.directio = NGX_OPEN_FILE_DIRECTIO_OFF;
- of.read_ahead = clcf->read_ahead;
-
- if (ngx_open_cached_file(clcf->open_file_cache, &c->file.name, &of, r->pool)
- != NGX_OK)
- {
- switch (of.err) {
-
- case 0:
- return NGX_ERROR;
-
- case NGX_ENOENT:
- case NGX_ENOTDIR:
- goto done;
-
- default:
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
- ngx_open_file_n " \"%s\" failed", c->file.name.data);
- return NGX_ERROR;
- }
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http file cache fd: %d", of.fd);
-
- c->file.fd = of.fd;
- c->file.log = r->connection->log;
- c->uniq = of.uniq;
- c->length = of.size;
- c->fs_size = (of.fs_size + cache->bsize - 1) / cache->bsize;
-
- c->buf = ngx_create_temp_buf(r->pool, c->body_start);
- if (c->buf == NULL) {
- return NGX_ERROR;
- }
-
- return ngx_http_file_cache_read(r, c);
-
-done:
-
- if (rv == NGX_DECLINED) {
- return ngx_http_file_cache_lock(r, c);
- }
-
- return rv;
-}
-
-
-static ngx_int_t
-ngx_http_file_cache_lock(ngx_http_request_t *r, ngx_http_cache_t *c)
-{
- ngx_msec_t now, timer;
- ngx_http_file_cache_t *cache;
-
- if (!c->lock) {
- return NGX_DECLINED;
- }
-
- cache = c->file_cache;
-
- ngx_shmtx_lock(&cache->shpool->mutex);
-
- if (!c->node->updating) {
- c->node->updating = 1;
- c->updating = 1;
- }
-
- ngx_shmtx_unlock(&cache->shpool->mutex);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http file cache lock u:%d wt:%M",
- c->updating, c->wait_time);
-
- if (c->updating) {
- return NGX_DECLINED;
- }
-
- c->waiting = 1;
-
- now = ngx_current_msec;
-
- if (c->wait_time == 0) {
- c->wait_time = now + c->lock_timeout;
-
- c->wait_event.handler = ngx_http_file_cache_lock_wait_handler;
- c->wait_event.data = r;
- c->wait_event.log = r->connection->log;
- }
-
- timer = c->wait_time - now;
-
- ngx_add_timer(&c->wait_event, (timer > 500) ? 500 : timer);
-
- r->main->blocked++;
-
- return NGX_AGAIN;
-}
-
-
-static void
-ngx_http_file_cache_lock_wait_handler(ngx_event_t *ev)
-{
- ngx_uint_t wait;
- ngx_msec_t timer;
- ngx_http_cache_t *c;
- ngx_http_request_t *r;
- ngx_http_file_cache_t *cache;
-
- r = ev->data;
- c = r->cache;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ev->log, 0,
- "http file cache wait handler wt:%M cur:%M",
- c->wait_time, ngx_current_msec);
-
- timer = c->wait_time - ngx_current_msec;
-
- if ((ngx_msec_int_t) timer <= 0) {
- ngx_log_error(NGX_LOG_INFO, ev->log, 0, "cache lock timeout");
- c->lock = 0;
- goto wakeup;
- }
-
- cache = c->file_cache;
- wait = 0;
-
- ngx_shmtx_lock(&cache->shpool->mutex);
-
- if (c->node->updating) {
- wait = 1;
- }
-
- ngx_shmtx_unlock(&cache->shpool->mutex);
-
- if (wait) {
- ngx_add_timer(ev, (timer > 500) ? 500 : timer);
- return;
- }
-
-wakeup:
-
- c->waiting = 0;
- r->main->blocked--;
- r->connection->write->handler(r->connection->write);
-}
-
-
-static ngx_int_t
-ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
-{
- time_t now;
- ssize_t n;
- ngx_int_t rc;
- ngx_http_file_cache_t *cache;
- ngx_http_file_cache_header_t *h;
-
- n = ngx_http_file_cache_aio_read(r, c);
-
- if (n < 0) {
- return n;
- }
-
- if ((size_t) n < c->header_start) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
- "cache file \"%s\" is too small", c->file.name.data);
- return NGX_DECLINED;
- }
-
- h = (ngx_http_file_cache_header_t *) c->buf->pos;
-
- if (h->crc32 != c->crc32) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
- "cache file \"%s\" has md5 collision", c->file.name.data);
- return NGX_DECLINED;
- }
-
- if ((size_t) h->body_start > c->body_start) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
- "cache file \"%s\" has too long header",
- c->file.name.data);
- return NGX_DECLINED;
- }
-
- c->buf->last += n;
-
- c->valid_sec = h->valid_sec;
- c->last_modified = h->last_modified;
- c->date = h->date;
- c->valid_msec = h->valid_msec;
- c->header_start = h->header_start;
- c->body_start = h->body_start;
-
- r->cached = 1;
-
- cache = c->file_cache;
-
- if (cache->sh->cold) {
-
- ngx_shmtx_lock(&cache->shpool->mutex);
-
- if (!c->node->exists) {
- c->node->uses = 1;
- c->node->body_start = c->body_start;
- c->node->exists = 1;
- c->node->uniq = c->uniq;
- c->node->fs_size = c->fs_size;
-
- cache->sh->size += c->fs_size;
- }
-
- ngx_shmtx_unlock(&cache->shpool->mutex);
- }
-
- now = ngx_time();
-
- if (c->valid_sec < now) {
-
- ngx_shmtx_lock(&cache->shpool->mutex);
-
- if (c->node->updating) {
- rc = NGX_HTTP_CACHE_UPDATING;
-
- } else {
- c->node->updating = 1;
- c->updating = 1;
- rc = NGX_HTTP_CACHE_STALE;
- }
-
- ngx_shmtx_unlock(&cache->shpool->mutex);
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http file cache expired: %i %T %T",
- rc, c->valid_sec, now);
-
- return rc;
- }
-
- return NGX_OK;
-}
-
-
-static ssize_t
-ngx_http_file_cache_aio_read(ngx_http_request_t *r, ngx_http_cache_t *c)
-{
-#if (NGX_HAVE_FILE_AIO)
- ssize_t n;
- ngx_http_core_loc_conf_t *clcf;
-
- if (!ngx_file_aio) {
- goto noaio;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (!clcf->aio) {
- goto noaio;
- }
-
- n = ngx_file_aio_read(&c->file, c->buf->pos, c->body_start, 0, r->pool);
-
- if (n != NGX_AGAIN) {
- return n;
- }
-
- c->file.aio->data = r;
- c->file.aio->handler = ngx_http_cache_aio_event_handler;
-
- r->main->blocked++;
- r->aio = 1;
-
- return NGX_AGAIN;
-
-noaio:
-
-#endif
-
- return ngx_read_file(&c->file, c->buf->pos, c->body_start, 0);
-}
-
-
-#if (NGX_HAVE_FILE_AIO)
-
-static void
-ngx_http_cache_aio_event_handler(ngx_event_t *ev)
-{
- ngx_event_aio_t *aio;
- ngx_http_request_t *r;
-
- aio = ev->data;
- r = aio->data;
-
- r->main->blocked--;
- r->aio = 0;
-
- r->connection->write->handler(r->connection->write);
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_file_cache_exists(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
-{
- ngx_int_t rc;
- ngx_http_file_cache_node_t *fcn;
-
- ngx_shmtx_lock(&cache->shpool->mutex);
-
- fcn = c->node;
-
- if (fcn == NULL) {
- fcn = ngx_http_file_cache_lookup(cache, c->key);
- }
-
- if (fcn) {
- ngx_queue_remove(&fcn->queue);
-
- if (c->node == NULL) {
- fcn->uses++;
- fcn->count++;
- }
-
- if (fcn->error) {
-
- if (fcn->valid_sec < ngx_time()) {
- goto renew;
- }
-
- rc = NGX_OK;
-
- goto done;
- }
-
- if (fcn->exists || fcn->uses >= c->min_uses) {
-
- c->exists = fcn->exists;
- if (fcn->body_start) {
- c->body_start = fcn->body_start;
- }
-
- rc = NGX_OK;
-
- goto done;
- }
-
- rc = NGX_AGAIN;
-
- goto done;
- }
-
- fcn = ngx_slab_alloc_locked(cache->shpool,
- sizeof(ngx_http_file_cache_node_t));
- if (fcn == NULL) {
- ngx_shmtx_unlock(&cache->shpool->mutex);
-
- (void) ngx_http_file_cache_forced_expire(cache);
-
- ngx_shmtx_lock(&cache->shpool->mutex);
-
- fcn = ngx_slab_alloc_locked(cache->shpool,
- sizeof(ngx_http_file_cache_node_t));
- if (fcn == NULL) {
- rc = NGX_ERROR;
- goto failed;
- }
- }
-
- ngx_memcpy((u_char *) &fcn->node.key, c->key, sizeof(ngx_rbtree_key_t));
-
- ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)],
- NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
-
- ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node);
-
- fcn->uses = 1;
- fcn->count = 1;
- fcn->updating = 0;
- fcn->deleting = 0;
-
-renew:
-
- rc = NGX_DECLINED;
-
- fcn->valid_msec = 0;
- fcn->error = 0;
- fcn->exists = 0;
- fcn->valid_sec = 0;
- fcn->uniq = 0;
- fcn->body_start = 0;
- fcn->fs_size = 0;
-
-done:
-
- fcn->expire = ngx_time() + cache->inactive;
-
- ngx_queue_insert_head(&cache->sh->queue, &fcn->queue);
-
- c->uniq = fcn->uniq;
- c->error = fcn->error;
- c->node = fcn;
-
-failed:
-
- ngx_shmtx_unlock(&cache->shpool->mutex);
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_file_cache_name(ngx_http_request_t *r, ngx_path_t *path)
-{
- u_char *p;
- ngx_http_cache_t *c;
-
- c = r->cache;
-
- if (c->file.name.len) {
- return NGX_OK;
- }
-
- c->file.name.len = path->name.len + 1 + path->len
- + 2 * NGX_HTTP_CACHE_KEY_LEN;
-
- c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1);
- if (c->file.name.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(c->file.name.data, path->name.data, path->name.len);
-
- p = c->file.name.data + path->name.len + 1 + path->len;
- p = ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN);
- *p = '\0';
-
- ngx_create_hashed_filename(path, c->file.name.data, c->file.name.len);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "cache file: \"%s\"", c->file.name.data);
-
- return NGX_OK;
-}
-
-
-static ngx_http_file_cache_node_t *
-ngx_http_file_cache_lookup(ngx_http_file_cache_t *cache, u_char *key)
-{
- ngx_int_t rc;
- ngx_rbtree_key_t node_key;
- ngx_rbtree_node_t *node, *sentinel;
- ngx_http_file_cache_node_t *fcn;
-
- ngx_memcpy((u_char *) &node_key, key, sizeof(ngx_rbtree_key_t));
-
- node = cache->sh->rbtree.root;
- sentinel = cache->sh->rbtree.sentinel;
-
- while (node != sentinel) {
-
- if (node_key < node->key) {
- node = node->left;
- continue;
- }
-
- if (node_key > node->key) {
- node = node->right;
- continue;
- }
-
- /* node_key == node->key */
-
- fcn = (ngx_http_file_cache_node_t *) node;
-
- rc = ngx_memcmp(&key[sizeof(ngx_rbtree_key_t)], fcn->key,
- NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
-
- if (rc == 0) {
- return fcn;
- }
-
- node = (rc < 0) ? node->left : node->right;
- }
-
- /* not found */
-
- return NULL;
-}
-
-
-static void
-ngx_http_file_cache_rbtree_insert_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
-{
- ngx_rbtree_node_t **p;
- ngx_http_file_cache_node_t *cn, *cnt;
-
- for ( ;; ) {
-
- if (node->key < temp->key) {
-
- p = &temp->left;
-
- } else if (node->key > temp->key) {
-
- p = &temp->right;
-
- } else { /* node->key == temp->key */
-
- cn = (ngx_http_file_cache_node_t *) node;
- cnt = (ngx_http_file_cache_node_t *) temp;
-
- p = (ngx_memcmp(cn->key, cnt->key,
- NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t))
- < 0)
- ? &temp->left : &temp->right;
- }
-
- if (*p == sentinel) {
- break;
- }
-
- temp = *p;
- }
-
- *p = node;
- node->parent = temp;
- node->left = sentinel;
- node->right = sentinel;
- ngx_rbt_red(node);
-}
-
-
-void
-ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf)
-{
- ngx_http_file_cache_header_t *h = (ngx_http_file_cache_header_t *) buf;
-
- u_char *p;
- ngx_str_t *key;
- ngx_uint_t i;
- ngx_http_cache_t *c;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http file cache set header");
-
- c = r->cache;
-
- ngx_memzero(h, sizeof(ngx_http_file_cache_header_t));
-
- h->valid_sec = c->valid_sec;
- h->last_modified = c->last_modified;
- h->date = c->date;
- h->crc32 = c->crc32;
- h->valid_msec = (u_short) c->valid_msec;
- h->header_start = (u_short) c->header_start;
- h->body_start = (u_short) c->body_start;
-
- p = buf + sizeof(ngx_http_file_cache_header_t);
-
- p = ngx_cpymem(p, ngx_http_file_cache_key, sizeof(ngx_http_file_cache_key));
-
- key = c->keys.elts;
- for (i = 0; i < c->keys.nelts; i++) {
- p = ngx_copy(p, key[i].data, key[i].len);
- }
-
- *p = LF;
-}
-
-
-void
-ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf)
-{
- off_t fs_size;
- ngx_int_t rc;
- ngx_file_uniq_t uniq;
- ngx_file_info_t fi;
- ngx_http_cache_t *c;
- ngx_ext_rename_file_t ext;
- ngx_http_file_cache_t *cache;
-
- c = r->cache;
-
- if (c->updated) {
- return;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http file cache update");
-
- c->updated = 1;
- c->updating = 0;
-
- cache = c->file_cache;
-
- uniq = 0;
- fs_size = 0;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http file cache rename: \"%s\" to \"%s\"",
- tf->file.name.data, c->file.name.data);
-
- ext.access = NGX_FILE_OWNER_ACCESS;
- ext.path_access = NGX_FILE_OWNER_ACCESS;
- ext.time = -1;
- ext.create_path = 1;
- ext.delete_file = 1;
- ext.log = r->connection->log;
-
- rc = ngx_ext_rename_file(&tf->file.name, &c->file.name, &ext);
-
- if (rc == NGX_OK) {
-
- if (ngx_fd_info(tf->file.fd, &fi) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
- ngx_fd_info_n " \"%s\" failed", tf->file.name.data);
-
- rc = NGX_ERROR;
-
- } else {
- uniq = ngx_file_uniq(&fi);
- fs_size = (ngx_file_fs_size(&fi) + cache->bsize - 1) / cache->bsize;
- }
- }
-
- ngx_shmtx_lock(&cache->shpool->mutex);
-
- c->node->count--;
- c->node->uniq = uniq;
- c->node->body_start = c->body_start;
-
- cache->sh->size += fs_size - c->node->fs_size;
- c->node->fs_size = fs_size;
-
- if (rc == NGX_OK) {
- c->node->exists = 1;
- }
-
- c->node->updating = 0;
-
- ngx_shmtx_unlock(&cache->shpool->mutex);
-}
-
-
-void
-ngx_http_file_cache_update_header(ngx_http_request_t *r)
-{
- ssize_t n;
- ngx_err_t err;
- ngx_file_t file;
- ngx_file_info_t fi;
- ngx_http_cache_t *c;
- ngx_http_file_cache_header_t h;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http file cache update header");
-
- c = r->cache;
-
- ngx_memzero(&file, sizeof(ngx_file_t));
-
- file.name = c->file.name;
- file.log = r->connection->log;
- file.fd = ngx_open_file(file.name.data, NGX_FILE_RDWR, NGX_FILE_OPEN, 0);
-
- if (file.fd == NGX_INVALID_FILE) {
- err = ngx_errno;
-
- /* cache file may have been deleted */
-
- if (err == NGX_ENOENT) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http file cache \"%s\" not found",
- file.name.data);
- return;
- }
-
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
- ngx_open_file_n " \"%s\" failed", file.name.data);
- return;
- }
-
- /*
- * make sure cache file wasn't replaced;
- * if it was, do nothing
- */
-
- if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
- ngx_fd_info_n " \"%s\" failed", file.name.data);
- goto done;
- }
-
- if (c->uniq != ngx_file_uniq(&fi)
- || c->length != ngx_file_size(&fi))
- {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http file cache \"%s\" changed",
- file.name.data);
- goto done;
- }
-
- n = ngx_read_file(&file, (u_char *) &h,
- sizeof(ngx_http_file_cache_header_t), 0);
-
- if (n == NGX_ERROR) {
- goto done;
- }
-
- if ((size_t) n != sizeof(ngx_http_file_cache_header_t)) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
- ngx_read_file_n " read only %z of %z from \"%s\"",
- n, sizeof(ngx_http_file_cache_header_t), file.name.data);
- goto done;
- }
-
- if (h.last_modified != c->last_modified
- || h.crc32 != c->crc32
- || h.header_start != c->header_start
- || h.body_start != c->body_start)
- {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http file cache \"%s\" content changed",
- file.name.data);
- goto done;
- }
-
- /*
- * update cache file header with new data,
- * notably h.valid_sec and h.date
- */
-
- ngx_memzero(&h, sizeof(ngx_http_file_cache_header_t));
-
- h.valid_sec = c->valid_sec;
- h.last_modified = c->last_modified;
- h.date = c->date;
- h.crc32 = c->crc32;
- h.valid_msec = (u_short) c->valid_msec;
- h.header_start = (u_short) c->header_start;
- h.body_start = (u_short) c->body_start;
-
- (void) ngx_write_file(&file, (u_char *) &h,
- sizeof(ngx_http_file_cache_header_t), 0);
-
-done:
-
- if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", file.name.data);
- }
-}
-
-
-ngx_int_t
-ngx_http_cache_send(ngx_http_request_t *r)
-{
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t out;
- ngx_http_cache_t *c;
-
- c = r->cache;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http file cache send: %s", c->file.name.data);
-
- if (r != r->main && c->length - c->body_start == 0) {
- return ngx_http_send_header(r);
- }
-
- /* we need to allocate all before the header would be sent */
-
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
- if (b->file == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- rc = ngx_http_send_header(r);
-
- if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
- return rc;
- }
-
- b->file_pos = c->body_start;
- b->file_last = c->length;
-
- b->in_file = (c->length - c->body_start) ? 1: 0;
- b->last_buf = (r == r->main) ? 1: 0;
- b->last_in_chain = 1;
-
- b->file->fd = c->file.fd;
- b->file->name = c->file.name;
- b->file->log = r->connection->log;
-
- out.buf = b;
- out.next = NULL;
-
- return ngx_http_output_filter(r, &out);
-}
-
-
-void
-ngx_http_file_cache_free(ngx_http_cache_t *c, ngx_temp_file_t *tf)
-{
- ngx_http_file_cache_t *cache;
- ngx_http_file_cache_node_t *fcn;
-
- if (c->updated || c->node == NULL) {
- return;
- }
-
- cache = c->file_cache;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->file.log, 0,
- "http file cache free, fd: %d", c->file.fd);
-
- ngx_shmtx_lock(&cache->shpool->mutex);
-
- fcn = c->node;
- fcn->count--;
-
- if (c->updating) {
- fcn->updating = 0;
- }
-
- if (c->error) {
- fcn->error = c->error;
-
- if (c->valid_sec) {
- fcn->valid_sec = c->valid_sec;
- fcn->valid_msec = c->valid_msec;
- }
-
- } else if (!fcn->exists && fcn->count == 0 && c->min_uses == 1) {
- ngx_queue_remove(&fcn->queue);
- ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
- ngx_slab_free_locked(cache->shpool, fcn);
- c->node = NULL;
- }
-
- ngx_shmtx_unlock(&cache->shpool->mutex);
-
- c->updated = 1;
- c->updating = 0;
-
- if (c->temp_file) {
- if (tf && tf->file.fd != NGX_INVALID_FILE) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->file.log, 0,
- "http file cache incomplete: \"%s\"",
- tf->file.name.data);
-
- if (ngx_delete_file(tf->file.name.data) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, c->file.log, ngx_errno,
- ngx_delete_file_n " \"%s\" failed",
- tf->file.name.data);
- }
- }
- }
-
- if (c->wait_event.timer_set) {
- ngx_del_timer(&c->wait_event);
- }
-}
-
-
-static void
-ngx_http_file_cache_cleanup(void *data)
-{
- ngx_http_cache_t *c = data;
-
- if (c->updated) {
- return;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->file.log, 0,
- "http file cache cleanup");
-
- if (c->updating) {
- ngx_log_error(NGX_LOG_ALERT, c->file.log, 0,
- "stalled cache updating, error:%ui", c->error);
- }
-
- ngx_http_file_cache_free(c, NULL);
-}
-
-
-static time_t
-ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache)
-{
- u_char *name;
- size_t len;
- time_t wait;
- ngx_uint_t tries;
- ngx_path_t *path;
- ngx_queue_t *q;
- ngx_http_file_cache_node_t *fcn;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
- "http file cache forced expire");
-
- path = cache->path;
- len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN;
-
- name = ngx_alloc(len + 1, ngx_cycle->log);
- if (name == NULL) {
- return 10;
- }
-
- ngx_memcpy(name, path->name.data, path->name.len);
-
- wait = 10;
- tries = 20;
-
- ngx_shmtx_lock(&cache->shpool->mutex);
-
- for (q = ngx_queue_last(&cache->sh->queue);
- q != ngx_queue_sentinel(&cache->sh->queue);
- q = ngx_queue_prev(q))
- {
- fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue);
-
- ngx_log_debug6(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
- "http file cache forced expire: #%d %d %02xd%02xd%02xd%02xd",
- fcn->count, fcn->exists,
- fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]);
-
- if (fcn->count == 0) {
- ngx_http_file_cache_delete(cache, q, name);
- wait = 0;
-
- } else {
- if (--tries) {
- continue;
- }
-
- wait = 1;
- }
-
- break;
- }
-
- ngx_shmtx_unlock(&cache->shpool->mutex);
-
- ngx_free(name);
-
- return wait;
-}
-
-
-static time_t
-ngx_http_file_cache_expire(ngx_http_file_cache_t *cache)
-{
- u_char *name, *p;
- size_t len;
- time_t now, wait;
- ngx_path_t *path;
- ngx_queue_t *q;
- ngx_http_file_cache_node_t *fcn;
- u_char key[2 * NGX_HTTP_CACHE_KEY_LEN];
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
- "http file cache expire");
-
- path = cache->path;
- len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN;
-
- name = ngx_alloc(len + 1, ngx_cycle->log);
- if (name == NULL) {
- return 10;
- }
-
- ngx_memcpy(name, path->name.data, path->name.len);
-
- now = ngx_time();
-
- ngx_shmtx_lock(&cache->shpool->mutex);
-
- for ( ;; ) {
-
- if (ngx_queue_empty(&cache->sh->queue)) {
- wait = 10;
- break;
- }
-
- q = ngx_queue_last(&cache->sh->queue);
-
- fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue);
-
- wait = fcn->expire - now;
-
- if (wait > 0) {
- wait = wait > 10 ? 10 : wait;
- break;
- }
-
- ngx_log_debug6(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
- "http file cache expire: #%d %d %02xd%02xd%02xd%02xd",
- fcn->count, fcn->exists,
- fcn->key[0], fcn->key[1], fcn->key[2], fcn->key[3]);
-
- if (fcn->count == 0) {
- ngx_http_file_cache_delete(cache, q, name);
- continue;
- }
-
- if (fcn->deleting) {
- wait = 1;
- break;
- }
-
- p = ngx_hex_dump(key, (u_char *) &fcn->node.key,
- sizeof(ngx_rbtree_key_t));
- len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
- (void) ngx_hex_dump(p, fcn->key, len);
-
- /*
- * abnormally exited workers may leave locked cache entries,
- * and although it may be safe to remove them completely,
- * we prefer to just move them to the top of the inactive queue
- */
-
- ngx_queue_remove(q);
- fcn->expire = ngx_time() + cache->inactive;
- ngx_queue_insert_head(&cache->sh->queue, &fcn->queue);
-
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
- "ignore long locked inactive cache entry %*s, count:%d",
- 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count);
- }
-
- ngx_shmtx_unlock(&cache->shpool->mutex);
-
- ngx_free(name);
-
- return wait;
-}
-
-
-static void
-ngx_http_file_cache_delete(ngx_http_file_cache_t *cache, ngx_queue_t *q,
- u_char *name)
-{
- u_char *p;
- size_t len;
- ngx_path_t *path;
- ngx_http_file_cache_node_t *fcn;
-
- fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue);
-
- if (fcn->exists) {
- cache->sh->size -= fcn->fs_size;
-
- path = cache->path;
- p = name + path->name.len + 1 + path->len;
- p = ngx_hex_dump(p, (u_char *) &fcn->node.key,
- sizeof(ngx_rbtree_key_t));
- len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
- p = ngx_hex_dump(p, fcn->key, len);
- *p = '\0';
-
- fcn->count++;
- fcn->deleting = 1;
- ngx_shmtx_unlock(&cache->shpool->mutex);
-
- len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN;
- ngx_create_hashed_filename(path, name, len);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
- "http file cache expire: \"%s\"", name);
-
- if (ngx_delete_file(name) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno,
- ngx_delete_file_n " \"%s\" failed", name);
- }
-
- ngx_shmtx_lock(&cache->shpool->mutex);
- fcn->count--;
- fcn->deleting = 0;
- }
-
- if (fcn->count == 0) {
- ngx_queue_remove(q);
- ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
- ngx_slab_free_locked(cache->shpool, fcn);
- }
-}
-
-
-static time_t
-ngx_http_file_cache_manager(void *data)
-{
- ngx_http_file_cache_t *cache = data;
-
- off_t size;
- time_t next, wait;
-
- next = ngx_http_file_cache_expire(cache);
-
- cache->last = ngx_current_msec;
- cache->files = 0;
-
- for ( ;; ) {
- ngx_shmtx_lock(&cache->shpool->mutex);
-
- size = cache->sh->size;
-
- ngx_shmtx_unlock(&cache->shpool->mutex);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
- "http file cache size: %O", size);
-
- if (size < cache->max_size) {
- return next;
- }
-
- wait = ngx_http_file_cache_forced_expire(cache);
-
- if (wait > 0) {
- return wait;
- }
-
- if (ngx_quit || ngx_terminate) {
- return next;
- }
- }
-}
-
-
-static void
-ngx_http_file_cache_loader(void *data)
-{
- ngx_http_file_cache_t *cache = data;
-
- ngx_tree_ctx_t tree;
-
- if (!cache->sh->cold || cache->sh->loading) {
- return;
- }
-
- if (!ngx_atomic_cmp_set(&cache->sh->loading, 0, ngx_pid)) {
- return;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
- "http file cache loader");
-
- tree.init_handler = NULL;
- tree.file_handler = ngx_http_file_cache_manage_file;
- tree.pre_tree_handler = ngx_http_file_cache_noop;
- tree.post_tree_handler = ngx_http_file_cache_noop;
- tree.spec_handler = ngx_http_file_cache_delete_file;
- tree.data = cache;
- tree.alloc = 0;
- tree.log = ngx_cycle->log;
-
- cache->last = ngx_current_msec;
- cache->files = 0;
-
- if (ngx_walk_tree(&tree, &cache->path->name) == NGX_ABORT) {
- cache->sh->loading = 0;
- return;
- }
-
- cache->sh->cold = 0;
- cache->sh->loading = 0;
-
- ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
- "http file cache: %V %.3fM, bsize: %uz",
- &cache->path->name,
- ((double) cache->sh->size * cache->bsize) / (1024 * 1024),
- cache->bsize);
-}
-
-
-static ngx_int_t
-ngx_http_file_cache_noop(ngx_tree_ctx_t *ctx, ngx_str_t *path)
-{
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_file_cache_manage_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
-{
- ngx_msec_t elapsed;
- ngx_http_file_cache_t *cache;
-
- cache = ctx->data;
-
- if (ngx_http_file_cache_add_file(ctx, path) != NGX_OK) {
- (void) ngx_http_file_cache_delete_file(ctx, path);
- }
-
- if (++cache->files >= cache->loader_files) {
- ngx_http_file_cache_loader_sleep(cache);
-
- } else {
- ngx_time_update();
-
- elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last));
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
- "http file cache loader time elapsed: %M", elapsed);
-
- if (elapsed >= cache->loader_threshold) {
- ngx_http_file_cache_loader_sleep(cache);
- }
- }
-
- return (ngx_quit || ngx_terminate) ? NGX_ABORT : NGX_OK;
-}
-
-
-static void
-ngx_http_file_cache_loader_sleep(ngx_http_file_cache_t *cache)
-{
- ngx_msleep(cache->loader_sleep);
-
- ngx_time_update();
-
- cache->last = ngx_current_msec;
- cache->files = 0;
-}
-
-
-static ngx_int_t
-ngx_http_file_cache_add_file(ngx_tree_ctx_t *ctx, ngx_str_t *name)
-{
- u_char *p;
- ngx_int_t n;
- ngx_uint_t i;
- ngx_http_cache_t c;
- ngx_http_file_cache_t *cache;
-
- if (name->len < 2 * NGX_HTTP_CACHE_KEY_LEN) {
- return NGX_ERROR;
- }
-
- if (ctx->size < (off_t) sizeof(ngx_http_file_cache_header_t)) {
- ngx_log_error(NGX_LOG_CRIT, ctx->log, 0,
- "cache file \"%s\" is too small", name->data);
- return NGX_ERROR;
- }
-
- ngx_memzero(&c, sizeof(ngx_http_cache_t));
- cache = ctx->data;
-
- c.length = ctx->size;
- c.fs_size = (ctx->fs_size + cache->bsize - 1) / cache->bsize;
-
- p = &name->data[name->len - 2 * NGX_HTTP_CACHE_KEY_LEN];
-
- for (i = 0; i < NGX_HTTP_CACHE_KEY_LEN; i++) {
- n = ngx_hextoi(p, 2);
-
- if (n == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- p += 2;
-
- c.key[i] = (u_char) n;
- }
-
- return ngx_http_file_cache_add(cache, &c);
-}
-
-
-static ngx_int_t
-ngx_http_file_cache_add(ngx_http_file_cache_t *cache, ngx_http_cache_t *c)
-{
- ngx_http_file_cache_node_t *fcn;
-
- ngx_shmtx_lock(&cache->shpool->mutex);
-
- fcn = ngx_http_file_cache_lookup(cache, c->key);
-
- if (fcn == NULL) {
-
- fcn = ngx_slab_alloc_locked(cache->shpool,
- sizeof(ngx_http_file_cache_node_t));
- if (fcn == NULL) {
- ngx_shmtx_unlock(&cache->shpool->mutex);
- return NGX_ERROR;
- }
-
- ngx_memcpy((u_char *) &fcn->node.key, c->key, sizeof(ngx_rbtree_key_t));
-
- ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)],
- NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t));
-
- ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node);
-
- fcn->uses = 1;
- fcn->count = 0;
- fcn->valid_msec = 0;
- fcn->error = 0;
- fcn->exists = 1;
- fcn->updating = 0;
- fcn->deleting = 0;
- fcn->uniq = 0;
- fcn->valid_sec = 0;
- fcn->body_start = 0;
- fcn->fs_size = c->fs_size;
-
- cache->sh->size += c->fs_size;
-
- } else {
- ngx_queue_remove(&fcn->queue);
- }
-
- fcn->expire = ngx_time() + cache->inactive;
-
- ngx_queue_insert_head(&cache->sh->queue, &fcn->queue);
-
- ngx_shmtx_unlock(&cache->shpool->mutex);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_file_cache_delete_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
-{
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
- "http file cache delete: \"%s\"", path->data);
-
- if (ngx_delete_file(path->data) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,
- ngx_delete_file_n " \"%s\" failed", path->data);
- }
-
- return NGX_OK;
-}
-
-
-time_t
-ngx_http_file_cache_valid(ngx_array_t *cache_valid, ngx_uint_t status)
-{
- ngx_uint_t i;
- ngx_http_cache_valid_t *valid;
-
- if (cache_valid == NULL) {
- return 0;
- }
-
- valid = cache_valid->elts;
- for (i = 0; i < cache_valid->nelts; i++) {
-
- if (valid[i].status == 0) {
- return valid[i].valid;
- }
-
- if (valid[i].status == status) {
- return valid[i].valid;
- }
- }
-
- return 0;
-}
-
-
-char *
-ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- off_t max_size;
- u_char *last, *p;
- time_t inactive;
- ssize_t size;
- ngx_str_t s, name, *value;
- ngx_int_t loader_files;
- ngx_msec_t loader_sleep, loader_threshold;
- ngx_uint_t i, n;
- ngx_http_file_cache_t *cache;
-
- cache = ngx_pcalloc(cf->pool, sizeof(ngx_http_file_cache_t));
- if (cache == NULL) {
- return NGX_CONF_ERROR;
- }
-
- cache->path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));
- if (cache->path == NULL) {
- return NGX_CONF_ERROR;
- }
-
- inactive = 600;
- loader_files = 100;
- loader_sleep = 50;
- loader_threshold = 200;
-
- name.len = 0;
- size = 0;
- max_size = NGX_MAX_OFF_T_VALUE;
-
- value = cf->args->elts;
-
- cache->path->name = value[1];
-
- if (cache->path->name.data[cache->path->name.len - 1] == '/') {
- cache->path->name.len--;
- }
-
- if (ngx_conf_full_name(cf->cycle, &cache->path->name, 0) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- for (i = 2; i < cf->args->nelts; i++) {
-
- if (ngx_strncmp(value[i].data, "levels=", 7) == 0) {
-
- p = value[i].data + 7;
- last = value[i].data + value[i].len;
-
- for (n = 0; n < 3 && p < last; n++) {
-
- if (*p > '0' && *p < '3') {
-
- cache->path->level[n] = *p++ - '0';
- cache->path->len += cache->path->level[n] + 1;
-
- if (p == last) {
- break;
- }
-
- if (*p++ == ':' && n < 2 && p != last) {
- continue;
- }
-
- goto invalid_levels;
- }
-
- goto invalid_levels;
- }
-
- if (cache->path->len < 10 + 3) {
- continue;
- }
-
- invalid_levels:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid \"levels\" \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (ngx_strncmp(value[i].data, "keys_zone=", 10) == 0) {
-
- name.data = value[i].data + 10;
-
- p = (u_char *) ngx_strchr(name.data, ':');
-
- if (p) {
- name.len = p - name.data;
-
- p++;
-
- s.len = value[i].data + value[i].len - p;
- s.data = p;
-
- size = ngx_parse_size(&s);
- if (size > 8191) {
- continue;
- }
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid keys zone size \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {
-
- s.len = value[i].len - 9;
- s.data = value[i].data + 9;
-
- inactive = ngx_parse_time(&s, 1);
- if (inactive == (time_t) NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid inactive value \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "max_size=", 9) == 0) {
-
- s.len = value[i].len - 9;
- s.data = value[i].data + 9;
-
- max_size = ngx_parse_offset(&s);
- if (max_size < 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid max_size value \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "loader_files=", 13) == 0) {
-
- loader_files = ngx_atoi(value[i].data + 13, value[i].len - 13);
- if (loader_files == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid loader_files value \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "loader_sleep=", 13) == 0) {
-
- s.len = value[i].len - 13;
- s.data = value[i].data + 13;
-
- loader_sleep = ngx_parse_time(&s, 0);
- if (loader_sleep == (ngx_msec_t) NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid loader_sleep value \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "loader_threshold=", 17) == 0) {
-
- s.len = value[i].len - 17;
- s.data = value[i].data + 17;
-
- loader_threshold = ngx_parse_time(&s, 0);
- if (loader_threshold == (ngx_msec_t) NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid loader_threshold value \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- if (name.len == 0 || size == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%V\" must have \"keys_zone\" parameter",
- &cmd->name);
- return NGX_CONF_ERROR;
- }
-
- cache->path->manager = ngx_http_file_cache_manager;
- cache->path->loader = ngx_http_file_cache_loader;
- cache->path->data = cache;
- cache->path->conf_file = cf->conf_file->file.name.data;
- cache->path->line = cf->conf_file->line;
- cache->loader_files = loader_files;
- cache->loader_sleep = loader_sleep;
- cache->loader_threshold = loader_threshold;
-
- if (ngx_add_path(cf, &cache->path) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- cache->shm_zone = ngx_shared_memory_add(cf, &name, size, cmd->post);
- if (cache->shm_zone == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (cache->shm_zone->data) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate zone \"%V\"", &name);
- return NGX_CONF_ERROR;
- }
-
-
- cache->shm_zone->init = ngx_http_file_cache_init;
- cache->shm_zone->data = cache;
-
- cache->inactive = inactive;
- cache->max_size = max_size;
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_http_file_cache_valid_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf)
-{
- char *p = conf;
-
- time_t valid;
- ngx_str_t *value;
- ngx_uint_t i, n, status;
- ngx_array_t **a;
- ngx_http_cache_valid_t *v;
- static ngx_uint_t statuses[] = { 200, 301, 302 };
-
- a = (ngx_array_t **) (p + cmd->offset);
-
- if (*a == NGX_CONF_UNSET_PTR) {
- *a = ngx_array_create(cf->pool, 1, sizeof(ngx_http_cache_valid_t));
- if (*a == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- value = cf->args->elts;
- n = cf->args->nelts - 1;
-
- valid = ngx_parse_time(&value[n], 1);
- if (valid == (time_t) NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid time value \"%V\"", &value[n]);
- return NGX_CONF_ERROR;
- }
-
- if (n == 1) {
-
- for (i = 0; i < 3; i++) {
- v = ngx_array_push(*a);
- if (v == NULL) {
- return NGX_CONF_ERROR;
- }
-
- v->status = statuses[i];
- v->valid = valid;
- }
-
- return NGX_CONF_OK;
- }
-
- for (i = 1; i < n; i++) {
-
- if (ngx_strcmp(value[i].data, "any") == 0) {
-
- status = 0;
-
- } else {
-
- status = ngx_atoi(value[i].data, value[i].len);
- if (status < 100) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid status \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
- }
- }
-
- v = ngx_array_push(*a);
- if (v == NULL) {
- return NGX_CONF_ERROR;
- }
-
- v->status = status;
- v->valid = valid;
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_header_filter_module.c b/usr.sbin/nginx/src/http/ngx_http_header_filter_module.c
deleted file mode 100644
index 507dc939c78..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_header_filter_module.c
+++ /dev/null
@@ -1,633 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-#include <nginx.h>
-
-
-static ngx_int_t ngx_http_header_filter_init(ngx_conf_t *cf);
-static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r);
-
-
-static ngx_http_module_t ngx_http_header_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_header_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL, /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_header_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_header_filter_module_ctx, /* module context */
- NULL, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static 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[] = {
-
- ngx_string("200 OK"),
- ngx_string("201 Created"),
- ngx_string("202 Accepted"),
- ngx_null_string, /* "203 Non-Authoritative Information" */
- ngx_string("204 No Content"),
- ngx_null_string, /* "205 Reset Content" */
- ngx_string("206 Partial Content"),
-
- /* ngx_null_string, */ /* "207 Multi-Status" */
-
-#define NGX_HTTP_LAST_2XX 207
-#define NGX_HTTP_OFF_3XX (NGX_HTTP_LAST_2XX - 200)
-
- /* ngx_null_string, */ /* "300 Multiple Choices" */
-
- ngx_string("301 Moved Permanently"),
- ngx_string("302 Moved Temporarily"),
- ngx_string("303 See Other"),
- ngx_string("304 Not Modified"),
- ngx_null_string, /* "305 Use Proxy" */
- ngx_null_string, /* "306 unused" */
- ngx_string("307 Temporary Redirect"),
-
-#define NGX_HTTP_LAST_3XX 308
-#define NGX_HTTP_OFF_4XX (NGX_HTTP_LAST_3XX - 301 + NGX_HTTP_OFF_3XX)
-
- ngx_string("400 Bad Request"),
- ngx_string("401 Unauthorized"),
- ngx_string("402 Payment Required"),
- ngx_string("403 Forbidden"),
- ngx_string("404 Not Found"),
- ngx_string("405 Not Allowed"),
- ngx_string("406 Not Acceptable"),
- ngx_null_string, /* "407 Proxy Authentication Required" */
- ngx_string("408 Request Time-out"),
- ngx_string("409 Conflict"),
- ngx_string("410 Gone"),
- ngx_string("411 Length Required"),
- ngx_string("412 Precondition Failed"),
- ngx_string("413 Request Entity Too Large"),
- ngx_string("414 Request-URI Too Large"),
- ngx_string("415 Unsupported Media Type"),
- ngx_string("416 Requested Range Not Satisfiable"),
-
- /* ngx_null_string, */ /* "417 Expectation Failed" */
- /* ngx_null_string, */ /* "418 unused" */
- /* ngx_null_string, */ /* "419 unused" */
- /* ngx_null_string, */ /* "420 unused" */
- /* ngx_null_string, */ /* "421 unused" */
- /* ngx_null_string, */ /* "422 Unprocessable Entity" */
- /* ngx_null_string, */ /* "423 Locked" */
- /* ngx_null_string, */ /* "424 Failed Dependency" */
-
-#define NGX_HTTP_LAST_4XX 417
-#define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX)
-
- ngx_string("500 Internal Server Error"),
- ngx_string("501 Not Implemented"),
- ngx_string("502 Bad Gateway"),
- ngx_string("503 Service Temporarily Unavailable"),
- ngx_string("504 Gateway Time-out"),
-
- ngx_null_string, /* "505 HTTP Version Not Supported" */
- ngx_null_string, /* "506 Variant Also Negotiates" */
- ngx_string("507 Insufficient Storage"),
- /* ngx_null_string, */ /* "508 unused" */
- /* ngx_null_string, */ /* "509 unused" */
- /* ngx_null_string, */ /* "510 Not Extended" */
-
-#define NGX_HTTP_LAST_5XX 508
-
-};
-
-
-ngx_http_header_out_t ngx_http_headers_out[] = {
- { ngx_string("Server"), offsetof(ngx_http_headers_out_t, server) },
- { ngx_string("Date"), offsetof(ngx_http_headers_out_t, date) },
- { ngx_string("Content-Length"),
- offsetof(ngx_http_headers_out_t, content_length) },
- { ngx_string("Content-Encoding"),
- offsetof(ngx_http_headers_out_t, content_encoding) },
- { ngx_string("Location"), offsetof(ngx_http_headers_out_t, location) },
- { ngx_string("Last-Modified"),
- offsetof(ngx_http_headers_out_t, last_modified) },
- { ngx_string("Accept-Ranges"),
- offsetof(ngx_http_headers_out_t, accept_ranges) },
- { ngx_string("Expires"), offsetof(ngx_http_headers_out_t, expires) },
- { ngx_string("Cache-Control"),
- offsetof(ngx_http_headers_out_t, cache_control) },
- { ngx_string("ETag"), offsetof(ngx_http_headers_out_t, etag) },
-
- { ngx_null_string, 0 }
-};
-
-
-static ngx_int_t
-ngx_http_header_filter(ngx_http_request_t *r)
-{
- u_char *p;
- size_t len;
- ngx_str_t host, *status_line;
- ngx_buf_t *b;
- ngx_uint_t status, i, port;
- ngx_chain_t out;
- ngx_list_part_t *part;
- ngx_table_elt_t *header;
- ngx_connection_t *c;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_core_srv_conf_t *cscf;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
- u_char addr[NGX_SOCKADDR_STRLEN];
-
- if (r->header_sent) {
- return NGX_OK;
- }
-
- r->header_sent = 1;
-
- if (r != r->main) {
- return NGX_OK;
- }
-
- if (r->http_version < NGX_HTTP_VERSION_10) {
- return NGX_OK;
- }
-
- if (r->method == NGX_HTTP_HEAD) {
- r->header_only = 1;
- }
-
- if (r->headers_out.last_modified_time != -1) {
- if (r->headers_out.status != NGX_HTTP_OK
- && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT
- && r->headers_out.status != NGX_HTTP_NOT_MODIFIED)
- {
- r->headers_out.last_modified_time = -1;
- r->headers_out.last_modified = NULL;
- }
- }
-
- len = sizeof("HTTP/1.x ") - 1 + sizeof(CRLF) - 1
- /* the end of the header */
- + sizeof(CRLF) - 1;
-
- /* status line */
-
- if (r->headers_out.status_line.len) {
- len += r->headers_out.status_line.len;
- status_line = &r->headers_out.status_line;
-#if (NGX_SUPPRESS_WARN)
- status = 0;
-#endif
-
- } else {
-
- status = r->headers_out.status;
-
- if (status >= NGX_HTTP_OK
- && status < NGX_HTTP_LAST_2XX)
- {
- /* 2XX */
-
- if (status == NGX_HTTP_NO_CONTENT) {
- r->header_only = 1;
- ngx_str_null(&r->headers_out.content_type);
- r->headers_out.last_modified_time = -1;
- r->headers_out.last_modified = NULL;
- r->headers_out.content_length = NULL;
- r->headers_out.content_length_n = -1;
- }
-
- status -= NGX_HTTP_OK;
- status_line = &ngx_http_status_lines[status];
- len += ngx_http_status_lines[status].len;
-
- } else if (status >= NGX_HTTP_MOVED_PERMANENTLY
- && status < NGX_HTTP_LAST_3XX)
- {
- /* 3XX */
-
- if (status == NGX_HTTP_NOT_MODIFIED) {
- r->header_only = 1;
- }
-
- status = status - NGX_HTTP_MOVED_PERMANENTLY + NGX_HTTP_OFF_3XX;
- status_line = &ngx_http_status_lines[status];
- len += ngx_http_status_lines[status].len;
-
- } else if (status >= NGX_HTTP_BAD_REQUEST
- && status < NGX_HTTP_LAST_4XX)
- {
- /* 4XX */
- status = status - NGX_HTTP_BAD_REQUEST
- + NGX_HTTP_OFF_4XX;
-
- status_line = &ngx_http_status_lines[status];
- len += ngx_http_status_lines[status].len;
-
- } else if (status >= NGX_HTTP_INTERNAL_SERVER_ERROR
- && status < NGX_HTTP_LAST_5XX)
- {
- /* 5XX */
- status = status - NGX_HTTP_INTERNAL_SERVER_ERROR
- + NGX_HTTP_OFF_5XX;
-
- status_line = &ngx_http_status_lines[status];
- len += ngx_http_status_lines[status].len;
-
- } else {
- len += NGX_INT_T_LEN + 1 /* SP */;
- status_line = NULL;
- }
-
- if (status_line && status_line->len == 0) {
- status = r->headers_out.status;
- len += NGX_INT_T_LEN + 1 /* SP */;
- status_line = NULL;
- }
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (r->headers_out.server == NULL) {
- len += clcf->server_tokens ? sizeof(ngx_http_server_full_string) - 1:
- sizeof(ngx_http_server_string) - 1;
- }
-
- if (r->headers_out.date == NULL) {
- len += sizeof("Date: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1;
- }
-
- if (r->headers_out.content_type.len) {
- len += sizeof("Content-Type: ") - 1
- + r->headers_out.content_type.len + 2;
-
- if (r->headers_out.content_type_len == r->headers_out.content_type.len
- && r->headers_out.charset.len)
- {
- len += sizeof("; charset=") - 1 + r->headers_out.charset.len;
- }
- }
-
- if (r->headers_out.content_length == NULL
- && r->headers_out.content_length_n >= 0)
- {
- len += sizeof("Content-Length: ") - 1 + NGX_OFF_T_LEN + 2;
- }
-
- if (r->headers_out.last_modified == NULL
- && r->headers_out.last_modified_time != -1)
- {
- len += sizeof("Last-Modified: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1;
- }
-
- c = r->connection;
-
- if (r->headers_out.location
- && r->headers_out.location->value.len
- && r->headers_out.location->value.data[0] == '/')
- {
- r->headers_out.location->hash = 0;
-
- if (clcf->server_name_in_redirect) {
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
- host = cscf->server_name;
-
- } else if (r->headers_in.server.len) {
- host = r->headers_in.server;
-
- } else {
- host.len = NGX_SOCKADDR_STRLEN;
- host.data = addr;
-
- if (ngx_connection_local_sockaddr(c, &host, 0) != NGX_OK) {
- return NGX_ERROR;
- }
- }
-
- switch (c->local_sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
- port = ntohs(sin6->sin6_port);
- break;
-#endif
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- port = 0;
- break;
-#endif
- default: /* AF_INET */
- sin = (struct sockaddr_in *) c->local_sockaddr;
- port = ntohs(sin->sin_port);
- break;
- }
-
- len += sizeof("Location: https://") - 1
- + host.len
- + r->headers_out.location->value.len + 2;
-
- if (clcf->port_in_redirect) {
-
-#if (NGX_HTTP_SSL)
- if (c->ssl)
- port = (port == 443) ? 0 : port;
- else
-#endif
- port = (port == 80) ? 0 : port;
-
- } else {
- port = 0;
- }
-
- if (port) {
- len += sizeof(":65535") - 1;
- }
-
- } else {
- ngx_str_null(&host);
- port = 0;
- }
-
- if (r->chunked) {
- len += sizeof("Transfer-Encoding: chunked" CRLF) - 1;
- }
-
- if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {
- len += sizeof("Connection: upgrade" CRLF) - 1;
-
- } else if (r->keepalive) {
- len += sizeof("Connection: keep-alive" CRLF) - 1;
-
- /*
- * MSIE and Opera ignore the "Keep-Alive: timeout=<N>" header.
- * MSIE keeps the connection alive for about 60-65 seconds.
- * Opera keeps the connection alive very long.
- * Mozilla keeps the connection alive for N plus about 1-10 seconds.
- * Konqueror keeps the connection alive for about N seconds.
- */
-
- if (clcf->keepalive_header) {
- len += sizeof("Keep-Alive: timeout=") - 1 + NGX_TIME_T_LEN + 2;
- }
-
- } else {
- len += sizeof("Connection: close" CRLF) - 1;
- }
-
-#if (NGX_HTTP_GZIP)
- if (r->gzip_vary) {
- if (clcf->gzip_vary) {
- len += sizeof("Vary: Accept-Encoding" CRLF) - 1;
-
- } else {
- r->gzip_vary = 0;
- }
- }
-#endif
-
- part = &r->headers_out.headers.part;
- header = part->elts;
-
- for (i = 0; /* void */; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- if (header[i].hash == 0) {
- continue;
- }
-
- len += header[i].key.len + sizeof(": ") - 1 + header[i].value.len
- + sizeof(CRLF) - 1;
- }
-
- b = ngx_create_temp_buf(r->pool, len);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- /* "HTTP/1.x " */
- b->last = ngx_cpymem(b->last, "HTTP/1.1 ", sizeof("HTTP/1.x ") - 1);
-
- /* status line */
- if (status_line) {
- b->last = ngx_copy(b->last, status_line->data, status_line->len);
-
- } else {
- b->last = ngx_sprintf(b->last, "%03ui ", status);
- }
- *b->last++ = CR; *b->last++ = LF;
-
- if (r->headers_out.server == NULL) {
- 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) {
- b->last = ngx_cpymem(b->last, "Date: ", sizeof("Date: ") - 1);
- b->last = ngx_cpymem(b->last, ngx_cached_http_time.data,
- ngx_cached_http_time.len);
-
- *b->last++ = CR; *b->last++ = LF;
- }
-
- if (r->headers_out.content_type.len) {
- b->last = ngx_cpymem(b->last, "Content-Type: ",
- sizeof("Content-Type: ") - 1);
- p = b->last;
- b->last = ngx_copy(b->last, r->headers_out.content_type.data,
- r->headers_out.content_type.len);
-
- if (r->headers_out.content_type_len == r->headers_out.content_type.len
- && r->headers_out.charset.len)
- {
- b->last = ngx_cpymem(b->last, "; charset=",
- sizeof("; charset=") - 1);
- b->last = ngx_copy(b->last, r->headers_out.charset.data,
- r->headers_out.charset.len);
-
- /* update r->headers_out.content_type for possible logging */
-
- r->headers_out.content_type.len = b->last - p;
- r->headers_out.content_type.data = p;
- }
-
- *b->last++ = CR; *b->last++ = LF;
- }
-
- if (r->headers_out.content_length == NULL
- && r->headers_out.content_length_n >= 0)
- {
- b->last = ngx_sprintf(b->last, "Content-Length: %O" CRLF,
- r->headers_out.content_length_n);
- }
-
- if (r->headers_out.last_modified == NULL
- && r->headers_out.last_modified_time != -1)
- {
- b->last = ngx_cpymem(b->last, "Last-Modified: ",
- sizeof("Last-Modified: ") - 1);
- b->last = ngx_http_time(b->last, r->headers_out.last_modified_time);
-
- *b->last++ = CR; *b->last++ = LF;
- }
-
- if (host.data) {
-
- p = b->last + sizeof("Location: ") - 1;
-
- b->last = ngx_cpymem(b->last, "Location: http",
- sizeof("Location: http") - 1);
-
-#if (NGX_HTTP_SSL)
- if (c->ssl) {
- *b->last++ ='s';
- }
-#endif
-
- *b->last++ = ':'; *b->last++ = '/'; *b->last++ = '/';
- b->last = ngx_copy(b->last, host.data, host.len);
-
- if (port) {
- b->last = ngx_sprintf(b->last, ":%ui", port);
- }
-
- b->last = ngx_copy(b->last, r->headers_out.location->value.data,
- r->headers_out.location->value.len);
-
- /* update r->headers_out.location->value for possible logging */
-
- r->headers_out.location->value.len = b->last - p;
- r->headers_out.location->value.data = p;
- ngx_str_set(&r->headers_out.location->key, "Location");
-
- *b->last++ = CR; *b->last++ = LF;
- }
-
- if (r->chunked) {
- b->last = ngx_cpymem(b->last, "Transfer-Encoding: chunked" CRLF,
- sizeof("Transfer-Encoding: chunked" CRLF) - 1);
- }
-
- if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {
- b->last = ngx_cpymem(b->last, "Connection: upgrade" CRLF,
- sizeof("Connection: upgrade" CRLF) - 1);
-
- } else if (r->keepalive) {
- b->last = ngx_cpymem(b->last, "Connection: keep-alive" CRLF,
- sizeof("Connection: keep-alive" CRLF) - 1);
-
- if (clcf->keepalive_header) {
- b->last = ngx_sprintf(b->last, "Keep-Alive: timeout=%T" CRLF,
- clcf->keepalive_header);
- }
-
- } else {
- b->last = ngx_cpymem(b->last, "Connection: close" CRLF,
- sizeof("Connection: close" CRLF) - 1);
- }
-
-#if (NGX_HTTP_GZIP)
- if (r->gzip_vary) {
- b->last = ngx_cpymem(b->last, "Vary: Accept-Encoding" CRLF,
- sizeof("Vary: Accept-Encoding" CRLF) - 1);
- }
-#endif
-
- part = &r->headers_out.headers.part;
- header = part->elts;
-
- for (i = 0; /* void */; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- if (header[i].hash == 0) {
- continue;
- }
-
- b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len);
- *b->last++ = ':'; *b->last++ = ' ';
-
- b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len);
- *b->last++ = CR; *b->last++ = LF;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "%*s", (size_t) (b->last - b->pos), b->pos);
-
- /* the end of HTTP header */
- *b->last++ = CR; *b->last++ = LF;
-
- r->header_size = b->last - b->pos;
-
- if (r->header_only) {
- b->last_buf = 1;
- }
-
- out.buf = b;
- out.next = NULL;
-
- return ngx_http_write_filter(r, &out);
-}
-
-
-static ngx_int_t
-ngx_http_header_filter_init(ngx_conf_t *cf)
-{
- ngx_http_top_header_filter = ngx_http_header_filter;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_parse.c b/usr.sbin/nginx/src/http/ngx_http_parse.c
deleted file mode 100644
index 02b4a0fd109..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_parse.c
+++ /dev/null
@@ -1,2308 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static uint32_t usual[] = {
- 0xffffdbfe, /* 1111 1111 1111 1111 1101 1011 1111 1110 */
-
- /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
- 0x7fff37d6, /* 0111 1111 1111 1111 0011 0111 1101 0110 */
-
- /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
-#if (NGX_WIN32)
- 0xefffffff, /* 1110 1111 1111 1111 1111 1111 1111 1111 */
-#else
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
-#endif
-
- /* ~}| {zyx wvut srqp onml kjih gfed cba` */
- 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 */
- 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
-};
-
-
-#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED)
-
-#define ngx_str3_cmp(m, c0, c1, c2, c3) \
- *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0)
-
-#define ngx_str3Ocmp(m, c0, c1, c2, c3) \
- *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0)
-
-#define ngx_str4cmp(m, c0, c1, c2, c3) \
- *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0)
-
-#define ngx_str5cmp(m, c0, c1, c2, c3, c4) \
- *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0) \
- && m[4] == c4
-
-#define ngx_str6cmp(m, c0, c1, c2, c3, c4, c5) \
- *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0) \
- && (((uint32_t *) m)[1] & 0xffff) == ((c5 << 8) | c4)
-
-#define ngx_str7_cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) \
- *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0) \
- && ((uint32_t *) m)[1] == ((c7 << 24) | (c6 << 16) | (c5 << 8) | c4)
-
-#define ngx_str8cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) \
- *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0) \
- && ((uint32_t *) m)[1] == ((c7 << 24) | (c6 << 16) | (c5 << 8) | c4)
-
-#define ngx_str9cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8) \
- *(uint32_t *) m == ((c3 << 24) | (c2 << 16) | (c1 << 8) | c0) \
- && ((uint32_t *) m)[1] == ((c7 << 24) | (c6 << 16) | (c5 << 8) | c4) \
- && m[8] == c8
-
-#else /* !(NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED) */
-
-#define ngx_str3_cmp(m, c0, c1, c2, c3) \
- m[0] == c0 && m[1] == c1 && m[2] == c2
-
-#define ngx_str3Ocmp(m, c0, c1, c2, c3) \
- m[0] == c0 && m[2] == c2 && m[3] == c3
-
-#define ngx_str4cmp(m, c0, c1, c2, c3) \
- m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3
-
-#define ngx_str5cmp(m, c0, c1, c2, c3, c4) \
- m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3 && m[4] == c4
-
-#define ngx_str6cmp(m, c0, c1, c2, c3, c4, c5) \
- m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3 \
- && m[4] == c4 && m[5] == c5
-
-#define ngx_str7_cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) \
- m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3 \
- && m[4] == c4 && m[5] == c5 && m[6] == c6
-
-#define ngx_str8cmp(m, c0, c1, c2, c3, c4, c5, c6, c7) \
- m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3 \
- && m[4] == c4 && m[5] == c5 && m[6] == c6 && m[7] == c7
-
-#define ngx_str9cmp(m, c0, c1, c2, c3, c4, c5, c6, c7, c8) \
- m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3 \
- && m[4] == c4 && m[5] == c5 && m[6] == c6 && m[7] == c7 && m[8] == c8
-
-#endif
-
-
-/* gcc, icc, msvc and others compile these switches as an jump table */
-
-ngx_int_t
-ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
-{
- u_char c, ch, *p, *m;
- enum {
- sw_start = 0,
- sw_method,
- sw_spaces_before_uri,
- sw_schema,
- sw_schema_slash,
- sw_schema_slash_slash,
- sw_host_start,
- sw_host,
- sw_host_end,
- sw_host_ip_literal,
- sw_port,
- sw_host_http_09,
- sw_after_slash_in_uri,
- sw_check_uri,
- sw_check_uri_http_09,
- sw_uri,
- sw_http_09,
- sw_http_H,
- sw_http_HT,
- sw_http_HTT,
- sw_http_HTTP,
- sw_first_major_digit,
- sw_major_digit,
- sw_first_minor_digit,
- sw_minor_digit,
- sw_spaces_after_digit,
- sw_almost_done
- } state;
-
- state = r->state;
-
- for (p = b->pos; p < b->last; p++) {
- ch = *p;
-
- switch (state) {
-
- /* HTTP methods: GET, HEAD, POST */
- case sw_start:
- r->request_start = p;
-
- if (ch == CR || ch == LF) {
- break;
- }
-
- if ((ch < 'A' || ch > 'Z') && ch != '_') {
- return NGX_HTTP_PARSE_INVALID_METHOD;
- }
-
- state = sw_method;
- break;
-
- case sw_method:
- if (ch == ' ') {
- r->method_end = p - 1;
- m = r->request_start;
-
- switch (p - m) {
-
- case 3:
- if (ngx_str3_cmp(m, 'G', 'E', 'T', ' ')) {
- r->method = NGX_HTTP_GET;
- break;
- }
-
- if (ngx_str3_cmp(m, 'P', 'U', 'T', ' ')) {
- r->method = NGX_HTTP_PUT;
- break;
- }
-
- break;
-
- case 4:
- if (m[1] == 'O') {
-
- if (ngx_str3Ocmp(m, 'P', 'O', 'S', 'T')) {
- r->method = NGX_HTTP_POST;
- break;
- }
-
- if (ngx_str3Ocmp(m, 'C', 'O', 'P', 'Y')) {
- r->method = NGX_HTTP_COPY;
- break;
- }
-
- if (ngx_str3Ocmp(m, 'M', 'O', 'V', 'E')) {
- r->method = NGX_HTTP_MOVE;
- break;
- }
-
- if (ngx_str3Ocmp(m, 'L', 'O', 'C', 'K')) {
- r->method = NGX_HTTP_LOCK;
- break;
- }
-
- } else {
-
- if (ngx_str4cmp(m, 'H', 'E', 'A', 'D')) {
- r->method = NGX_HTTP_HEAD;
- break;
- }
- }
-
- break;
-
- case 5:
- if (ngx_str5cmp(m, 'M', 'K', 'C', 'O', 'L')) {
- r->method = NGX_HTTP_MKCOL;
- break;
- }
-
- if (ngx_str5cmp(m, 'P', 'A', 'T', 'C', 'H')) {
- r->method = NGX_HTTP_PATCH;
- break;
- }
-
- if (ngx_str5cmp(m, 'T', 'R', 'A', 'C', 'E')) {
- r->method = NGX_HTTP_TRACE;
- break;
- }
-
- break;
-
- case 6:
- if (ngx_str6cmp(m, 'D', 'E', 'L', 'E', 'T', 'E')) {
- r->method = NGX_HTTP_DELETE;
- break;
- }
-
- if (ngx_str6cmp(m, 'U', 'N', 'L', 'O', 'C', 'K')) {
- r->method = NGX_HTTP_UNLOCK;
- break;
- }
-
- break;
-
- case 7:
- if (ngx_str7_cmp(m, 'O', 'P', 'T', 'I', 'O', 'N', 'S', ' '))
- {
- r->method = NGX_HTTP_OPTIONS;
- }
-
- break;
-
- case 8:
- if (ngx_str8cmp(m, 'P', 'R', 'O', 'P', 'F', 'I', 'N', 'D'))
- {
- r->method = NGX_HTTP_PROPFIND;
- }
-
- break;
-
- case 9:
- if (ngx_str9cmp(m,
- 'P', 'R', 'O', 'P', 'P', 'A', 'T', 'C', 'H'))
- {
- r->method = NGX_HTTP_PROPPATCH;
- }
-
- break;
- }
-
- state = sw_spaces_before_uri;
- break;
- }
-
- if ((ch < 'A' || ch > 'Z') && ch != '_') {
- return NGX_HTTP_PARSE_INVALID_METHOD;
- }
-
- break;
-
- /* space* before URI */
- case sw_spaces_before_uri:
-
- if (ch == '/') {
- r->uri_start = p;
- state = sw_after_slash_in_uri;
- break;
- }
-
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'z') {
- r->schema_start = p;
- state = sw_schema;
- break;
- }
-
- switch (ch) {
- case ' ':
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
- case sw_schema:
-
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'z') {
- break;
- }
-
- switch (ch) {
- case ':':
- r->schema_end = p;
- state = sw_schema_slash;
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
- case sw_schema_slash:
- switch (ch) {
- case '/':
- state = sw_schema_slash_slash;
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
- case sw_schema_slash_slash:
- switch (ch) {
- case '/':
- state = sw_host_start;
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
- case sw_host_start:
-
- r->host_start = p;
-
- if (ch == '[') {
- state = sw_host_ip_literal;
- break;
- }
-
- state = sw_host;
-
- /* fall through */
-
- case sw_host:
-
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'z') {
- break;
- }
-
- if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '-') {
- break;
- }
-
- /* fall through */
-
- case sw_host_end:
-
- r->host_end = p;
-
- switch (ch) {
- case ':':
- state = sw_port;
- break;
- case '/':
- 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_host_http_09;
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
- case sw_host_ip_literal:
-
- if (ch >= '0' && ch <= '9') {
- break;
- }
-
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'z') {
- break;
- }
-
- switch (ch) {
- case ':':
- break;
- case ']':
- state = sw_host_end;
- break;
- case '-':
- case '.':
- case '_':
- case '~':
- /* unreserved */
- break;
- case '!':
- case '$':
- case '&':
- case '\'':
- case '(':
- case ')':
- case '*':
- case '+':
- case ',':
- case ';':
- case '=':
- /* sub-delims */
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
- case sw_port:
- if (ch >= '0' && ch <= '9') {
- break;
- }
-
- switch (ch) {
- case '/':
- r->port_end = p;
- 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_host_http_09;
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
- /* space+ after "http://host[:port] " */
- case sw_host_http_09:
- switch (ch) {
- case ' ':
- break;
- case CR:
- r->http_minor = 9;
- state = sw_almost_done;
- break;
- case LF:
- r->http_minor = 9;
- goto done;
- case 'H':
- r->http_protocol.data = p;
- state = sw_http_H;
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
-
- /* check "/.", "//", "%", and "\" (Win32) in URI */
- case sw_after_slash_in_uri:
-
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
- state = sw_check_uri;
- break;
- }
-
- switch (ch) {
- case ' ':
- r->uri_end = p;
- state = sw_check_uri_http_09;
- break;
- case CR:
- r->uri_end = p;
- r->http_minor = 9;
- state = sw_almost_done;
- break;
- case LF:
- r->uri_end = p;
- r->http_minor = 9;
- goto done;
- case '.':
- r->complex_uri = 1;
- state = sw_uri;
- break;
- case '%':
- r->quoted_uri = 1;
- state = sw_uri;
- break;
- case '/':
- r->complex_uri = 1;
- state = sw_uri;
- break;
-#if (NGX_WIN32)
- case '\\':
- r->complex_uri = 1;
- state = sw_uri;
- break;
-#endif
- case '?':
- r->args_start = p + 1;
- state = sw_uri;
- break;
- case '#':
- r->complex_uri = 1;
- state = sw_uri;
- break;
- case '+':
- r->plus_in_uri = 1;
- break;
- case '\0':
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- default:
- state = sw_check_uri;
- break;
- }
- break;
-
- /* check "/", "%" and "\" (Win32) in URI */
- case sw_check_uri:
-
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
- break;
- }
-
- switch (ch) {
- case '/':
-#if (NGX_WIN32)
- if (r->uri_ext == p) {
- r->complex_uri = 1;
- state = sw_uri;
- break;
- }
-#endif
- r->uri_ext = NULL;
- state = sw_after_slash_in_uri;
- break;
- case '.':
- r->uri_ext = p + 1;
- break;
- case ' ':
- r->uri_end = p;
- state = sw_check_uri_http_09;
- break;
- case CR:
- r->uri_end = p;
- r->http_minor = 9;
- state = sw_almost_done;
- break;
- case LF:
- r->uri_end = p;
- r->http_minor = 9;
- goto done;
-#if (NGX_WIN32)
- case '\\':
- r->complex_uri = 1;
- state = sw_after_slash_in_uri;
- break;
-#endif
- case '%':
- r->quoted_uri = 1;
- state = sw_uri;
- break;
- case '?':
- r->args_start = p + 1;
- state = sw_uri;
- break;
- case '#':
- r->complex_uri = 1;
- state = sw_uri;
- break;
- case '+':
- r->plus_in_uri = 1;
- break;
- case '\0':
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
- /* space+ after URI */
- case sw_check_uri_http_09:
- switch (ch) {
- case ' ':
- break;
- case CR:
- r->http_minor = 9;
- state = sw_almost_done;
- break;
- case LF:
- r->http_minor = 9;
- goto done;
- case 'H':
- r->http_protocol.data = p;
- state = sw_http_H;
- break;
- default:
- r->space_in_uri = 1;
- state = sw_check_uri;
- p--;
- break;
- }
- break;
-
-
- /* URI */
- case sw_uri:
-
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
- break;
- }
-
- switch (ch) {
- case ' ':
- r->uri_end = p;
- state = sw_http_09;
- break;
- case CR:
- r->uri_end = p;
- r->http_minor = 9;
- state = sw_almost_done;
- break;
- case LF:
- r->uri_end = p;
- r->http_minor = 9;
- goto done;
- case '#':
- r->complex_uri = 1;
- break;
- case '\0':
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
- /* space+ after URI */
- case sw_http_09:
- switch (ch) {
- case ' ':
- break;
- case CR:
- r->http_minor = 9;
- state = sw_almost_done;
- break;
- case LF:
- r->http_minor = 9;
- goto done;
- case 'H':
- r->http_protocol.data = p;
- state = sw_http_H;
- break;
- default:
- r->space_in_uri = 1;
- state = sw_uri;
- p--;
- break;
- }
- break;
-
- case sw_http_H:
- switch (ch) {
- case 'T':
- state = sw_http_HT;
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
- case sw_http_HT:
- switch (ch) {
- case 'T':
- state = sw_http_HTT;
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
- case sw_http_HTT:
- switch (ch) {
- case 'P':
- state = sw_http_HTTP;
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
- case sw_http_HTTP:
- switch (ch) {
- case '/':
- state = sw_first_major_digit;
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- break;
-
- /* first digit of major HTTP version */
- case sw_first_major_digit:
- if (ch < '1' || ch > '9') {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- r->http_major = ch - '0';
- state = sw_major_digit;
- break;
-
- /* major HTTP version or dot */
- case sw_major_digit:
- if (ch == '.') {
- state = sw_first_minor_digit;
- break;
- }
-
- if (ch < '0' || ch > '9') {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- r->http_major = r->http_major * 10 + ch - '0';
- break;
-
- /* first digit of minor HTTP version */
- case sw_first_minor_digit:
- if (ch < '0' || ch > '9') {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- r->http_minor = ch - '0';
- state = sw_minor_digit;
- break;
-
- /* minor HTTP version or end of request line */
- case sw_minor_digit:
- if (ch == CR) {
- state = sw_almost_done;
- break;
- }
-
- if (ch == LF) {
- goto done;
- }
-
- if (ch == ' ') {
- state = sw_spaces_after_digit;
- break;
- }
-
- if (ch < '0' || ch > '9') {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- 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;
- switch (ch) {
- case LF:
- goto done;
- default:
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- }
- }
-
- b->pos = p;
- r->state = state;
-
- return NGX_AGAIN;
-
-done:
-
- b->pos = p + 1;
-
- if (r->request_end == NULL) {
- r->request_end = p;
- }
-
- r->http_version = r->http_major * 1000 + r->http_minor;
- r->state = sw_start;
-
- if (r->http_version == 9 && r->method != NGX_HTTP_GET) {
- return NGX_HTTP_PARSE_INVALID_09_METHOD;
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
- ngx_uint_t allow_underscores)
-{
- u_char c, ch, *p;
- ngx_uint_t hash, i;
- enum {
- sw_start = 0,
- sw_name,
- sw_space_before_value,
- sw_value,
- sw_space_after_value,
- sw_ignore_line,
- sw_almost_done,
- sw_header_almost_done
- } state;
-
- /* the last '\0' is not needed because string is zero terminated */
-
- static u_char lowcase[] =
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0\0\0\0\0\0-\0\0" "0123456789\0\0\0\0\0\0"
- "\0abcdefghijklmnopqrstuvwxyz\0\0\0\0\0"
- "\0abcdefghijklmnopqrstuvwxyz\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-
- state = r->state;
- hash = r->header_hash;
- i = r->lowcase_index;
-
- for (p = b->pos; p < b->last; p++) {
- ch = *p;
-
- switch (state) {
-
- /* first char */
- case sw_start:
- r->header_name_start = p;
- r->invalid_header = 0;
-
- switch (ch) {
- case CR:
- r->header_end = p;
- state = sw_header_almost_done;
- break;
- case LF:
- r->header_end = p;
- goto header_done;
- default:
- state = sw_name;
-
- c = lowcase[ch];
-
- if (c) {
- hash = ngx_hash(0, c);
- r->lowcase_header[0] = c;
- i = 1;
- break;
- }
-
- if (ch == '_') {
- if (allow_underscores) {
- hash = ngx_hash(0, ch);
- r->lowcase_header[0] = ch;
- i = 1;
-
- } else {
- r->invalid_header = 1;
- }
-
- break;
- }
-
- if (ch == '\0') {
- return NGX_HTTP_PARSE_INVALID_HEADER;
- }
-
- r->invalid_header = 1;
-
- break;
-
- }
- break;
-
- /* header name */
- case sw_name:
- c = lowcase[ch];
-
- if (c) {
- hash = ngx_hash(hash, c);
- r->lowcase_header[i++] = c;
- i &= (NGX_HTTP_LC_HEADER_LEN - 1);
- break;
- }
-
- if (ch == '_') {
- if (allow_underscores) {
- hash = ngx_hash(hash, ch);
- r->lowcase_header[i++] = ch;
- i &= (NGX_HTTP_LC_HEADER_LEN - 1);
-
- } else {
- r->invalid_header = 1;
- }
-
- break;
- }
-
- if (ch == ':') {
- r->header_name_end = p;
- state = sw_space_before_value;
- break;
- }
-
- if (ch == CR) {
- r->header_name_end = p;
- r->header_start = p;
- r->header_end = p;
- state = sw_almost_done;
- break;
- }
-
- if (ch == LF) {
- r->header_name_end = p;
- r->header_start = p;
- r->header_end = p;
- goto done;
- }
-
- /* IIS may send the duplicate "HTTP/1.1 ..." lines */
- if (ch == '/'
- && r->upstream
- && p - r->header_name_start == 4
- && ngx_strncmp(r->header_name_start, "HTTP", 4) == 0)
- {
- state = sw_ignore_line;
- break;
- }
-
- if (ch == '\0') {
- return NGX_HTTP_PARSE_INVALID_HEADER;
- }
-
- r->invalid_header = 1;
-
- break;
-
- /* space* before header value */
- case sw_space_before_value:
- switch (ch) {
- case ' ':
- break;
- case CR:
- r->header_start = p;
- r->header_end = p;
- state = sw_almost_done;
- break;
- case LF:
- r->header_start = p;
- r->header_end = p;
- goto done;
- case '\0':
- return NGX_HTTP_PARSE_INVALID_HEADER;
- default:
- r->header_start = p;
- state = sw_value;
- break;
- }
- break;
-
- /* header value */
- case sw_value:
- switch (ch) {
- case ' ':
- r->header_end = p;
- state = sw_space_after_value;
- break;
- case CR:
- r->header_end = p;
- state = sw_almost_done;
- break;
- case LF:
- r->header_end = p;
- goto done;
- case '\0':
- return NGX_HTTP_PARSE_INVALID_HEADER;
- }
- break;
-
- /* space* before end of header line */
- case sw_space_after_value:
- switch (ch) {
- case ' ':
- break;
- case CR:
- state = sw_almost_done;
- break;
- case LF:
- goto done;
- case '\0':
- return NGX_HTTP_PARSE_INVALID_HEADER;
- default:
- state = sw_value;
- break;
- }
- break;
-
- /* ignore header line */
- case sw_ignore_line:
- switch (ch) {
- case LF:
- state = sw_start;
- break;
- default:
- break;
- }
- break;
-
- /* end of header line */
- case sw_almost_done:
- switch (ch) {
- case LF:
- goto done;
- case CR:
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_HEADER;
- }
- break;
-
- /* end of header */
- case sw_header_almost_done:
- switch (ch) {
- case LF:
- goto header_done;
- default:
- return NGX_HTTP_PARSE_INVALID_HEADER;
- }
- }
- }
-
- b->pos = p;
- r->state = state;
- r->header_hash = hash;
- r->lowcase_index = i;
-
- return NGX_AGAIN;
-
-done:
-
- b->pos = p + 1;
- r->state = sw_start;
- r->header_hash = hash;
- r->lowcase_index = i;
-
- return NGX_OK;
-
-header_done:
-
- b->pos = p + 1;
- r->state = sw_start;
-
- return NGX_HTTP_PARSE_HEADER_DONE;
-}
-
-
-ngx_int_t
-ngx_http_parse_uri(ngx_http_request_t *r)
-{
- u_char *p, ch;
- enum {
- sw_start = 0,
- sw_after_slash_in_uri,
- sw_check_uri,
- sw_uri
- } state;
-
- state = sw_start;
-
- for (p = r->uri_start; p != r->uri_end; p++) {
-
- ch = *p;
-
- switch (state) {
-
- case sw_start:
-
- if (ch != '/') {
- return NGX_ERROR;
- }
-
- state = sw_after_slash_in_uri;
- break;
-
- /* check "/.", "//", "%", and "\" (Win32) in URI */
- case sw_after_slash_in_uri:
-
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
- state = sw_check_uri;
- break;
- }
-
- switch (ch) {
- case ' ':
- r->space_in_uri = 1;
- state = sw_check_uri;
- break;
- case '.':
- r->complex_uri = 1;
- state = sw_uri;
- break;
- case '%':
- r->quoted_uri = 1;
- state = sw_uri;
- break;
- case '/':
- r->complex_uri = 1;
- state = sw_uri;
- break;
-#if (NGX_WIN32)
- case '\\':
- r->complex_uri = 1;
- state = sw_uri;
- break;
-#endif
- case '?':
- r->args_start = p + 1;
- state = sw_uri;
- break;
- case '#':
- r->complex_uri = 1;
- state = sw_uri;
- break;
- case '+':
- r->plus_in_uri = 1;
- break;
- default:
- state = sw_check_uri;
- break;
- }
- break;
-
- /* check "/", "%" and "\" (Win32) in URI */
- case sw_check_uri:
-
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
- break;
- }
-
- switch (ch) {
- case '/':
-#if (NGX_WIN32)
- if (r->uri_ext == p) {
- r->complex_uri = 1;
- state = sw_uri;
- break;
- }
-#endif
- r->uri_ext = NULL;
- state = sw_after_slash_in_uri;
- break;
- case '.':
- r->uri_ext = p + 1;
- break;
- case ' ':
- r->space_in_uri = 1;
- break;
-#if (NGX_WIN32)
- case '\\':
- r->complex_uri = 1;
- state = sw_after_slash_in_uri;
- break;
-#endif
- case '%':
- r->quoted_uri = 1;
- state = sw_uri;
- break;
- case '?':
- r->args_start = p + 1;
- state = sw_uri;
- break;
- case '#':
- r->complex_uri = 1;
- state = sw_uri;
- break;
- case '+':
- r->plus_in_uri = 1;
- break;
- }
- break;
-
- /* URI */
- case sw_uri:
-
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
- break;
- }
-
- switch (ch) {
- case ' ':
- r->space_in_uri = 1;
- break;
- case '#':
- r->complex_uri = 1;
- break;
- }
- break;
- }
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
-{
- u_char c, ch, decoded, *p, *u;
- enum {
- sw_usual = 0,
- sw_slash,
- sw_dot,
- sw_dot_dot,
- sw_quoted,
- sw_quoted_second
- } state, quoted_state;
-
-#if (NGX_SUPPRESS_WARN)
- decoded = '\0';
- quoted_state = sw_usual;
-#endif
-
- state = sw_usual;
- p = r->uri_start;
- u = r->uri.data;
- r->uri_ext = NULL;
- r->args_start = NULL;
-
- ch = *p++;
-
- while (p <= r->uri_end) {
-
- /*
- * we use "ch = *p++" inside the cycle, but this operation is safe,
- * because after the URI there is always at least one character:
- * the line feed
- */
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "s:%d in:'%Xd:%c'", state, ch, ch);
-
- switch (state) {
-
- case sw_usual:
-
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
- *u++ = ch;
- ch = *p++;
- break;
- }
-
- switch(ch) {
-#if (NGX_WIN32)
- case '\\':
- if (u - 2 >= r->uri.data
- && *(u - 1) == '.' && *(u - 2) != '.')
- {
- u--;
- }
-
- r->uri_ext = NULL;
-
- if (p == r->uri_start + r->uri.len) {
-
- /*
- * we omit the last "\" to cause redirect because
- * the browsers do not treat "\" as "/" in relative URL path
- */
-
- break;
- }
-
- state = sw_slash;
- *u++ = '/';
- break;
-#endif
- case '/':
-#if (NGX_WIN32)
- if (u - 2 >= r->uri.data
- && *(u - 1) == '.' && *(u - 2) != '.')
- {
- u--;
- }
-#endif
- r->uri_ext = NULL;
- state = sw_slash;
- *u++ = ch;
- break;
- case '%':
- quoted_state = state;
- state = sw_quoted;
- break;
- case '?':
- r->args_start = p;
- goto args;
- case '#':
- goto done;
- case '.':
- r->uri_ext = u + 1;
- *u++ = ch;
- break;
- case '+':
- r->plus_in_uri = 1;
- /* fall through */
- default:
- *u++ = ch;
- break;
- }
-
- ch = *p++;
- break;
-
- case sw_slash:
-
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
- state = sw_usual;
- *u++ = ch;
- ch = *p++;
- break;
- }
-
- switch(ch) {
-#if (NGX_WIN32)
- case '\\':
- break;
-#endif
- case '/':
- if (!merge_slashes) {
- *u++ = ch;
- }
- break;
- case '.':
- state = sw_dot;
- *u++ = ch;
- break;
- case '%':
- quoted_state = state;
- state = sw_quoted;
- break;
- case '?':
- r->args_start = p;
- goto args;
- case '#':
- goto done;
- case '+':
- r->plus_in_uri = 1;
- default:
- state = sw_usual;
- *u++ = ch;
- break;
- }
-
- ch = *p++;
- break;
-
- case sw_dot:
-
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
- state = sw_usual;
- *u++ = ch;
- ch = *p++;
- break;
- }
-
- switch(ch) {
-#if (NGX_WIN32)
- case '\\':
-#endif
- case '/':
- state = sw_slash;
- u--;
- break;
- case '.':
- state = sw_dot_dot;
- *u++ = ch;
- break;
- case '%':
- quoted_state = state;
- state = sw_quoted;
- break;
- case '?':
- r->args_start = p;
- goto args;
- case '#':
- goto done;
- case '+':
- r->plus_in_uri = 1;
- default:
- state = sw_usual;
- *u++ = ch;
- break;
- }
-
- ch = *p++;
- break;
-
- case sw_dot_dot:
-
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
- state = sw_usual;
- *u++ = ch;
- ch = *p++;
- break;
- }
-
- switch(ch) {
-#if (NGX_WIN32)
- case '\\':
-#endif
- case '/':
- state = sw_slash;
- u -= 5;
- for ( ;; ) {
- if (u < r->uri.data) {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- if (*u == '/') {
- u++;
- break;
- }
- u--;
- }
- break;
- case '%':
- quoted_state = state;
- state = sw_quoted;
- break;
- case '?':
- r->args_start = p;
- goto args;
- case '#':
- goto done;
- case '+':
- r->plus_in_uri = 1;
- default:
- state = sw_usual;
- *u++ = ch;
- break;
- }
-
- ch = *p++;
- break;
-
- case sw_quoted:
- r->quoted_uri = 1;
-
- if (ch >= '0' && ch <= '9') {
- decoded = (u_char) (ch - '0');
- state = sw_quoted_second;
- ch = *p++;
- break;
- }
-
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'f') {
- decoded = (u_char) (c - 'a' + 10);
- state = sw_quoted_second;
- ch = *p++;
- break;
- }
-
- return NGX_HTTP_PARSE_INVALID_REQUEST;
-
- case sw_quoted_second:
- if (ch >= '0' && ch <= '9') {
- ch = (u_char) ((decoded << 4) + ch - '0');
-
- if (ch == '%' || ch == '#') {
- state = sw_usual;
- *u++ = ch;
- ch = *p++;
- break;
-
- } else if (ch == '\0') {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- state = quoted_state;
- break;
- }
-
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'f') {
- ch = (u_char) ((decoded << 4) + c - 'a' + 10);
-
- if (ch == '?') {
- state = sw_usual;
- *u++ = ch;
- ch = *p++;
- break;
-
- } else if (ch == '+') {
- r->plus_in_uri = 1;
- }
-
- state = quoted_state;
- break;
- }
-
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
- }
-
-done:
-
- r->uri.len = u - r->uri.data;
-
- if (r->uri_ext) {
- r->exten.len = u - r->uri_ext;
- r->exten.data = r->uri_ext;
- }
-
- r->uri_ext = NULL;
-
- return NGX_OK;
-
-args:
-
- while (p < r->uri_end) {
- if (*p++ != '#') {
- continue;
- }
-
- r->args.len = p - 1 - r->args_start;
- r->args.data = r->args_start;
- r->args_start = NULL;
-
- break;
- }
-
- r->uri.len = u - r->uri.data;
-
- if (r->uri_ext) {
- r->exten.len = u - r->uri_ext;
- r->exten.data = r->uri_ext;
- }
-
- r->uri_ext = NULL;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_parse_status_line(ngx_http_request_t *r, ngx_buf_t *b,
- ngx_http_status_t *status)
-{
- u_char ch;
- u_char *p;
- enum {
- sw_start = 0,
- sw_H,
- sw_HT,
- sw_HTT,
- sw_HTTP,
- sw_first_major_digit,
- sw_major_digit,
- sw_first_minor_digit,
- sw_minor_digit,
- sw_status,
- sw_space_after_status,
- sw_status_text,
- sw_almost_done
- } state;
-
- state = r->state;
-
- for (p = b->pos; p < b->last; p++) {
- ch = *p;
-
- switch (state) {
-
- /* "HTTP/" */
- case sw_start:
- switch (ch) {
- case 'H':
- state = sw_H;
- break;
- default:
- return NGX_ERROR;
- }
- break;
-
- case sw_H:
- switch (ch) {
- case 'T':
- state = sw_HT;
- break;
- default:
- return NGX_ERROR;
- }
- break;
-
- case sw_HT:
- switch (ch) {
- case 'T':
- state = sw_HTT;
- break;
- default:
- return NGX_ERROR;
- }
- break;
-
- case sw_HTT:
- switch (ch) {
- case 'P':
- state = sw_HTTP;
- break;
- default:
- return NGX_ERROR;
- }
- break;
-
- case sw_HTTP:
- switch (ch) {
- case '/':
- state = sw_first_major_digit;
- break;
- default:
- return NGX_ERROR;
- }
- break;
-
- /* the first digit of major HTTP version */
- case sw_first_major_digit:
- if (ch < '1' || ch > '9') {
- return NGX_ERROR;
- }
-
- r->http_major = ch - '0';
- state = sw_major_digit;
- break;
-
- /* the major HTTP version or dot */
- case sw_major_digit:
- if (ch == '.') {
- state = sw_first_minor_digit;
- break;
- }
-
- if (ch < '0' || ch > '9') {
- return NGX_ERROR;
- }
-
- r->http_major = r->http_major * 10 + ch - '0';
- break;
-
- /* the first digit of minor HTTP version */
- case sw_first_minor_digit:
- if (ch < '0' || ch > '9') {
- return NGX_ERROR;
- }
-
- r->http_minor = ch - '0';
- state = sw_minor_digit;
- break;
-
- /* the minor HTTP version or the end of the request line */
- case sw_minor_digit:
- if (ch == ' ') {
- state = sw_status;
- break;
- }
-
- if (ch < '0' || ch > '9') {
- return NGX_ERROR;
- }
-
- r->http_minor = r->http_minor * 10 + ch - '0';
- break;
-
- /* HTTP status code */
- case sw_status:
- if (ch == ' ') {
- break;
- }
-
- if (ch < '0' || ch > '9') {
- return NGX_ERROR;
- }
-
- status->code = status->code * 10 + ch - '0';
-
- if (++status->count == 3) {
- state = sw_space_after_status;
- status->start = p - 2;
- }
-
- break;
-
- /* space or end of line */
- case sw_space_after_status:
- switch (ch) {
- case ' ':
- state = sw_status_text;
- break;
- case '.': /* IIS may send 403.1, 403.2, etc */
- state = sw_status_text;
- break;
- case CR:
- state = sw_almost_done;
- break;
- case LF:
- goto done;
- default:
- return NGX_ERROR;
- }
- break;
-
- /* any text until end of line */
- case sw_status_text:
- switch (ch) {
- case CR:
- state = sw_almost_done;
-
- break;
- case LF:
- goto done;
- }
- break;
-
- /* end of status line */
- case sw_almost_done:
- status->end = p - 1;
- switch (ch) {
- case LF:
- goto done;
- default:
- return NGX_ERROR;
- }
- }
- }
-
- b->pos = p;
- r->state = state;
-
- return NGX_AGAIN;
-
-done:
-
- b->pos = p + 1;
-
- if (status->end == NULL) {
- status->end = p;
- }
-
- status->http_version = r->http_major * 1000 + r->http_minor;
- r->state = sw_start;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
- ngx_str_t *args, ngx_uint_t *flags)
-{
- u_char ch, *p, *src, *dst;
- size_t len;
- ngx_uint_t quoted;
-
- len = uri->len;
- p = uri->data;
- quoted = 0;
-
- if (len == 0 || p[0] == '?') {
- goto unsafe;
- }
-
- if (p[0] == '.' && len > 1 && p[1] == '.'
- && (len == 2 || ngx_path_separator(p[2])))
- {
- goto unsafe;
- }
-
- for ( /* void */ ; len; len--) {
-
- ch = *p++;
-
- if (ch == '%') {
- quoted = 1;
- continue;
- }
-
- if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
- continue;
- }
-
- if (ch == '?') {
- args->len = len - 1;
- args->data = p;
- uri->len -= len;
-
- break;
- }
-
- if (ch == '\0') {
- goto unsafe;
- }
-
- if (ngx_path_separator(ch) && len > 2) {
-
- /* detect "/../" and "/.." */
-
- if (p[0] == '.' && p[1] == '.'
- && (len == 3 || ngx_path_separator(p[2])))
- {
- goto unsafe;
- }
- }
- }
-
- if (quoted) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "escaped URI: \"%V\"", uri);
-
- src = uri->data;
-
- dst = ngx_pnalloc(r->pool, uri->len);
- if (dst == NULL) {
- return NGX_ERROR;
- }
-
- uri->data = dst;
-
- ngx_unescape_uri(&dst, &src, uri->len, 0);
-
- uri->len = dst - uri->data;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "unescaped URI: \"%V\"", uri);
-
- len = uri->len;
- p = uri->data;
-
- if (p[0] == '.' && len > 1 && p[1] == '.'
- && (len == 2 || ngx_path_separator(p[2])))
- {
- goto unsafe;
- }
-
- for ( /* void */ ; len; len--) {
-
- ch = *p++;
-
- if (ch == '\0') {
- goto unsafe;
- }
-
- if (ngx_path_separator(ch) && len > 2) {
-
- /* detect "/../" and "/.." */
-
- if (p[0] == '.' && p[1] == '.'
- && (len == 3 || ngx_path_separator(p[2])))
- {
- goto unsafe;
- }
- }
- }
- }
-
- return NGX_OK;
-
-unsafe:
-
- if (*flags & NGX_HTTP_LOG_UNSAFE) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "unsafe URI \"%V\" was detected", uri);
- }
-
- return NGX_ERROR;
-}
-
-
-ngx_int_t
-ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name,
- ngx_str_t *value)
-{
- ngx_uint_t i;
- u_char *start, *last, *end, ch;
- ngx_table_elt_t **h;
-
- h = headers->elts;
-
- for (i = 0; i < headers->nelts; i++) {
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, headers->pool->log, 0,
- "parse header: \"%V: %V\"", &h[i]->key, &h[i]->value);
-
- if (name->len > h[i]->value.len) {
- continue;
- }
-
- start = h[i]->value.data;
- end = h[i]->value.data + h[i]->value.len;
-
- while (start < end) {
-
- if (ngx_strncasecmp(start, name->data, name->len) != 0) {
- goto skip;
- }
-
- for (start += name->len; start < end && *start == ' '; start++) {
- /* void */
- }
-
- if (value == NULL) {
- if (start == end || *start == ',') {
- return i;
- }
-
- goto skip;
- }
-
- if (start == end || *start++ != '=') {
- /* the invalid header value */
- goto skip;
- }
-
- while (start < end && *start == ' ') { start++; }
-
- for (last = start; last < end && *last != ';'; last++) {
- /* void */
- }
-
- value->len = last - start;
- value->data = start;
-
- return i;
-
- skip:
-
- while (start < end) {
- ch = *start++;
- if (ch == ';' || ch == ',') {
- break;
- }
- }
-
- while (start < end && *start == ' ') { start++; }
- }
- }
-
- return NGX_DECLINED;
-}
-
-
-ngx_int_t
-ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len, ngx_str_t *value)
-{
- u_char *p, *last;
-
- if (r->args.len == 0) {
- return NGX_DECLINED;
- }
-
- p = r->args.data;
- last = p + r->args.len;
-
- for ( /* void */ ; p < last; p++) {
-
- /* we need '=' after name, so drop one char from last */
-
- p = ngx_strlcasestrn(p, last - 1, name, len - 1);
-
- if (p == NULL) {
- return NGX_DECLINED;
- }
-
- if ((p == r->args.data || *(p - 1) == '&') && *(p + len) == '=') {
-
- value->data = p + len + 1;
-
- p = ngx_strlchr(p, last, '&');
-
- if (p == NULL) {
- p = r->args.data + r->args.len;
- }
-
- value->len = p - value->data;
-
- return NGX_OK;
- }
- }
-
- return NGX_DECLINED;
-}
-
-
-void
-ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args)
-{
- u_char *p, *last;
-
- last = uri->data + uri->len;
-
- p = ngx_strlchr(uri->data, last, '?');
-
- if (p) {
- uri->len = p - uri->data;
- p++;
- args->len = last - p;
- args->data = p;
-
- } else {
- args->len = 0;
- }
-}
-
-
-ngx_int_t
-ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
- ngx_http_chunked_t *ctx)
-{
- u_char *pos, ch, c;
- ngx_int_t rc;
- enum {
- sw_chunk_start = 0,
- sw_chunk_size,
- sw_chunk_extension,
- sw_chunk_extension_almost_done,
- sw_chunk_data,
- sw_after_data,
- sw_after_data_almost_done,
- sw_last_chunk_extension,
- sw_last_chunk_extension_almost_done,
- sw_trailer,
- sw_trailer_almost_done,
- sw_trailer_header,
- sw_trailer_header_almost_done
- } state;
-
- state = ctx->state;
-
- if (state == sw_chunk_data && ctx->size == 0) {
- state = sw_after_data;
- }
-
- rc = NGX_AGAIN;
-
- for (pos = b->pos; pos < b->last; pos++) {
-
- ch = *pos;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http chunked byte: %02Xd s:%d", ch, state);
-
- switch (state) {
-
- case sw_chunk_start:
- if (ch >= '0' && ch <= '9') {
- state = sw_chunk_size;
- ctx->size = ch - '0';
- break;
- }
-
- c = (u_char) (ch | 0x20);
-
- if (c >= 'a' && c <= 'f') {
- state = sw_chunk_size;
- ctx->size = c - 'a' + 10;
- break;
- }
-
- goto invalid;
-
- case sw_chunk_size:
- if (ch >= '0' && ch <= '9') {
- ctx->size = ctx->size * 16 + (ch - '0');
- break;
- }
-
- c = (u_char) (ch | 0x20);
-
- if (c >= 'a' && c <= 'f') {
- ctx->size = ctx->size * 16 + (c - 'a' + 10);
- break;
- }
-
- if (ctx->size == 0) {
-
- switch (ch) {
- case CR:
- state = sw_last_chunk_extension_almost_done;
- break;
- case LF:
- state = sw_trailer;
- break;
- case ';':
- case ' ':
- case '\t':
- state = sw_last_chunk_extension;
- break;
- default:
- goto invalid;
- }
-
- break;
- }
-
- switch (ch) {
- case CR:
- state = sw_chunk_extension_almost_done;
- break;
- case LF:
- state = sw_chunk_data;
- break;
- case ';':
- case ' ':
- case '\t':
- state = sw_chunk_extension;
- break;
- default:
- goto invalid;
- }
-
- break;
-
- case sw_chunk_extension:
- switch (ch) {
- case CR:
- state = sw_chunk_extension_almost_done;
- break;
- case LF:
- state = sw_chunk_data;
- }
- break;
-
- case sw_chunk_extension_almost_done:
- if (ch == LF) {
- state = sw_chunk_data;
- break;
- }
- goto invalid;
-
- case sw_chunk_data:
- rc = NGX_OK;
- goto data;
-
- case sw_after_data:
- switch (ch) {
- case CR:
- state = sw_after_data_almost_done;
- break;
- case LF:
- state = sw_chunk_start;
- }
- break;
-
- case sw_after_data_almost_done:
- if (ch == LF) {
- state = sw_chunk_start;
- break;
- }
- goto invalid;
-
- case sw_last_chunk_extension:
- switch (ch) {
- case CR:
- state = sw_last_chunk_extension_almost_done;
- break;
- case LF:
- state = sw_trailer;
- }
- break;
-
- case sw_last_chunk_extension_almost_done:
- if (ch == LF) {
- state = sw_trailer;
- break;
- }
- goto invalid;
-
- case sw_trailer:
- switch (ch) {
- case CR:
- state = sw_trailer_almost_done;
- break;
- case LF:
- goto done;
- default:
- state = sw_trailer_header;
- }
- break;
-
- case sw_trailer_almost_done:
- if (ch == LF) {
- goto done;
- }
- goto invalid;
-
- case sw_trailer_header:
- switch (ch) {
- case CR:
- state = sw_trailer_header_almost_done;
- break;
- case LF:
- state = sw_trailer;
- }
- break;
-
- case sw_trailer_header_almost_done:
- if (ch == LF) {
- state = sw_trailer;
- break;
- }
- goto invalid;
-
- }
- }
-
-data:
-
- ctx->state = state;
- b->pos = pos;
-
- switch (state) {
-
- case sw_chunk_start:
- ctx->length = 3 /* "0" LF LF */;
- break;
- case sw_chunk_size:
- ctx->length = 1 /* LF */
- + (ctx->size ? ctx->size + 4 /* LF "0" LF LF */
- : 1 /* LF */);
- break;
- case sw_chunk_extension:
- case sw_chunk_extension_almost_done:
- ctx->length = 1 /* LF */ + ctx->size + 4 /* LF "0" LF LF */;
- break;
- case sw_chunk_data:
- ctx->length = ctx->size + 4 /* LF "0" LF LF */;
- break;
- case sw_after_data:
- case sw_after_data_almost_done:
- ctx->length = 4 /* LF "0" LF LF */;
- break;
- case sw_last_chunk_extension:
- case sw_last_chunk_extension_almost_done:
- ctx->length = 2 /* LF LF */;
- break;
- case sw_trailer:
- case sw_trailer_almost_done:
- ctx->length = 1 /* LF */;
- break;
- case sw_trailer_header:
- case sw_trailer_header_almost_done:
- ctx->length = 2 /* LF LF */;
- break;
-
- }
-
- if (ctx->size < 0 || ctx->length < 0) {
- goto invalid;
- }
-
- return rc;
-
-done:
-
- ctx->state = 0;
- b->pos = pos + 1;
-
- return NGX_DONE;
-
-invalid:
-
- return NGX_ERROR;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_parse_time.c b/usr.sbin/nginx/src/http/ngx_http_parse_time.c
deleted file mode 100644
index 985af31725b..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_parse_time.c
+++ /dev/null
@@ -1,277 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static ngx_uint_t 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)
-{
- u_char *p, *end;
- ngx_int_t month;
- ngx_uint_t day, year, hour, min, sec;
- uint64_t time;
- enum {
- no = 0,
- rfc822, /* Tue, 10 Nov 2002 23:50:13 */
- rfc850, /* Tuesday, 10-Dec-02 23:50:13 */
- isoc /* Tue Dec 10 23:50:13 2002 */
- } fmt;
-
- fmt = 0;
- end = value + len;
-
-#if (NGX_SUPPRESS_WARN)
- day = 32;
- year = 2038;
-#endif
-
- for (p = value; p < end; p++) {
- if (*p == ',') {
- break;
- }
-
- if (*p == ' ') {
- fmt = isoc;
- break;
- }
- }
-
- for (p++; p < end; p++)
- if (*p != ' ') {
- break;
- }
-
- if (end - p < 18) {
- return NGX_ERROR;
- }
-
- if (fmt != isoc) {
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
- return NGX_ERROR;
- }
-
- day = (*p - '0') * 10 + *(p + 1) - '0';
- p += 2;
-
- if (*p == ' ') {
- if (end - p < 18) {
- return NGX_ERROR;
- }
- fmt = rfc822;
-
- } else if (*p == '-') {
- fmt = rfc850;
-
- } else {
- return NGX_ERROR;
- }
-
- p++;
- }
-
- switch (*p) {
-
- case 'J':
- month = *(p + 1) == 'a' ? 0 : *(p + 2) == 'n' ? 5 : 6;
- break;
-
- case 'F':
- month = 1;
- break;
-
- case 'M':
- month = *(p + 2) == 'r' ? 2 : 4;
- break;
-
- case 'A':
- month = *(p + 1) == 'p' ? 3 : 7;
- break;
-
- case 'S':
- month = 8;
- break;
-
- case 'O':
- month = 9;
- break;
-
- case 'N':
- month = 10;
- break;
-
- case 'D':
- month = 11;
- break;
-
- default:
- return NGX_ERROR;
- }
-
- p += 3;
-
- if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) {
- return NGX_ERROR;
- }
-
- p++;
-
- if (fmt == rfc822) {
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
- || *(p + 2) < '0' || *(p + 2) > '9'
- || *(p + 3) < '0' || *(p + 3) > '9')
- {
- return NGX_ERROR;
- }
-
- year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
- + (*(p + 2) - '0') * 10 + *(p + 3) - '0';
- p += 4;
-
- } else if (fmt == rfc850) {
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
- return NGX_ERROR;
- }
-
- year = (*p - '0') * 10 + *(p + 1) - '0';
- year += (year < 70) ? 2000 : 1900;
- p += 2;
- }
-
- if (fmt == isoc) {
- if (*p == ' ') {
- p++;
- }
-
- if (*p < '0' || *p > '9') {
- return NGX_ERROR;
- }
-
- day = *p++ - '0';
-
- if (*p != ' ') {
- if (*p < '0' || *p > '9') {
- return NGX_ERROR;
- }
-
- day = day * 10 + *p++ - '0';
- }
-
- if (end - p < 14) {
- return NGX_ERROR;
- }
- }
-
- if (*p++ != ' ') {
- return NGX_ERROR;
- }
-
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
- return NGX_ERROR;
- }
-
- hour = (*p - '0') * 10 + *(p + 1) - '0';
- p += 2;
-
- if (*p++ != ':') {
- return NGX_ERROR;
- }
-
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
- return NGX_ERROR;
- }
-
- min = (*p - '0') * 10 + *(p + 1) - '0';
- p += 2;
-
- if (*p++ != ':') {
- return NGX_ERROR;
- }
-
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
- return NGX_ERROR;
- }
-
- sec = (*p - '0') * 10 + *(p + 1) - '0';
-
- if (fmt == isoc) {
- p += 2;
-
- if (*p++ != ' ') {
- return NGX_ERROR;
- }
-
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
- || *(p + 2) < '0' || *(p + 2) > '9'
- || *(p + 3) < '0' || *(p + 3) > '9')
- {
- return NGX_ERROR;
- }
-
- year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
- + (*(p + 2) - '0') * 10 + *(p + 3) - '0';
- }
-
- if (hour > 23 || min > 59 || sec > 59) {
- return NGX_ERROR;
- }
-
- if (day == 29 && month == 1) {
- if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) {
- return NGX_ERROR;
- }
-
- } else if (day > mday[month]) {
- return NGX_ERROR;
- }
-
- /*
- * shift new year to March 1 and start months from 1 (not 0),
- * it is needed for Gauss' formula
- */
-
- if (--month <= 0) {
- month += 12;
- year -= 1;
- }
-
- /* Gauss' formula for Gregorian days since March 1, 1 BC */
-
- time = (uint64_t) (
- /* days in years including leap years since March 1, 1 BC */
-
- 365 * year + year / 4 - year / 100 + year / 400
-
- /* days before the month */
-
- + 367 * month / 12 - 30
-
- /* days before the day */
-
- + day - 1
-
- /*
- * 719527 days were between March 1, 1 BC and March 1, 1970,
- * 31 and 28 days were in January and February 1970
- */
-
- - 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec;
-
-#if (NGX_TIME_T_SIZE <= 4)
-
- if (time > 0x7fffffff) {
- return NGX_ERROR;
- }
-
-#endif
-
- return (time_t) time;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_postpone_filter_module.c b/usr.sbin/nginx/src/http/ngx_http_postpone_filter_module.c
deleted file mode 100644
index e893b836488..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_postpone_filter_module.c
+++ /dev/null
@@ -1,176 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static ngx_int_t ngx_http_postpone_filter_add(ngx_http_request_t *r,
- ngx_chain_t *in);
-static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf);
-
-
-static ngx_http_module_t ngx_http_postpone_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_postpone_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_postpone_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_postpone_filter_module_ctx, /* module context */
- NULL, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-
-
-static ngx_int_t
-ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- ngx_connection_t *c;
- ngx_http_postponed_request_t *pr;
-
- c = r->connection;
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in);
-
- if (r != c->data) {
-
- if (in) {
- ngx_http_postpone_filter_add(r, in);
- return NGX_OK;
- }
-
-#if 0
- /* TODO: SSI may pass NULL */
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "http postpone filter NULL inactive request");
-#endif
-
- return NGX_OK;
- }
-
- if (r->postponed == NULL) {
-
- if (in || c->buffered) {
- return ngx_http_next_body_filter(r->main, in);
- }
-
- return NGX_OK;
- }
-
- if (in) {
- ngx_http_postpone_filter_add(r, in);
- }
-
- do {
- pr = r->postponed;
-
- if (pr->request) {
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http postpone filter wake \"%V?%V\"",
- &pr->request->uri, &pr->request->args);
-
- r->postponed = pr->next;
-
- c->data = pr->request;
-
- return ngx_http_post_request(pr->request, NULL);
- }
-
- if (pr->out == NULL) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "http postpone filter NULL output");
-
- } else {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http postpone filter output \"%V?%V\"",
- &r->uri, &r->args);
-
- if (ngx_http_next_body_filter(r->main, pr->out) == NGX_ERROR) {
- return NGX_ERROR;
- }
- }
-
- r->postponed = pr->next;
-
- } while (r->postponed);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_postpone_filter_add(ngx_http_request_t *r, ngx_chain_t *in)
-{
- ngx_http_postponed_request_t *pr, **ppr;
-
- if (r->postponed) {
- for (pr = r->postponed; pr->next; pr = pr->next) { /* void */ }
-
- if (pr->request == NULL) {
- goto found;
- }
-
- ppr = &pr->next;
-
- } else {
- ppr = &r->postponed;
- }
-
- pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
- if (pr == NULL) {
- return NGX_ERROR;
- }
-
- *ppr = pr;
-
- pr->request = NULL;
- pr->out = NULL;
- pr->next = NULL;
-
-found:
-
- if (ngx_chain_add_copy(r->pool, &pr->out, in) == NGX_OK) {
- return NGX_OK;
- }
-
- return NGX_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_postpone_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_postpone_filter;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_request.c b/usr.sbin/nginx/src/http/ngx_http_request.c
deleted file mode 100644
index 4bf9d1fcf1c..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_request.c
+++ /dev/null
@@ -1,3648 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static void ngx_http_wait_request_handler(ngx_event_t *ev);
-static void ngx_http_process_request_line(ngx_event_t *rev);
-static void ngx_http_process_request_headers(ngx_event_t *rev);
-static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
-static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
- ngx_uint_t request_line);
-
-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_multi_header_lines(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_process_host(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_user_agent(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-
-static ngx_int_t ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool,
- ngx_uint_t alloc);
-static ngx_int_t ngx_http_set_virtual_server(ngx_http_request_t *r,
- ngx_str_t *host);
-static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c,
- ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
- ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp);
-
-static void ngx_http_request_handler(ngx_event_t *ev);
-static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc);
-static void ngx_http_terminate_handler(ngx_http_request_t *r);
-static void ngx_http_finalize_connection(ngx_http_request_t *r);
-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_request_finalizer(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);
-static void ngx_http_lingering_close_handler(ngx_event_t *ev);
-static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
-static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error);
-static void ngx_http_log_request(ngx_http_request_t *r);
-
-static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len);
-static u_char *ngx_http_log_error_handler(ngx_http_request_t *r,
- ngx_http_request_t *sr, u_char *buf, size_t len);
-
-#if (NGX_HTTP_SSL)
-static void ngx_http_ssl_handshake(ngx_event_t *rev);
-static void ngx_http_ssl_handshake_handler(ngx_connection_t *c);
-#endif
-
-
-static char *ngx_http_client_errors[] = {
-
- /* NGX_HTTP_PARSE_INVALID_METHOD */
- "client sent invalid method",
-
- /* NGX_HTTP_PARSE_INVALID_REQUEST */
- "client sent invalid request",
-
- /* NGX_HTTP_PARSE_INVALID_09_METHOD */
- "client sent invalid method in HTTP/0.9 request"
-};
-
-
-ngx_http_header_t ngx_http_headers_in[] = {
- { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host),
- ngx_http_process_host },
-
- { ngx_string("Connection"), offsetof(ngx_http_headers_in_t, connection),
- ngx_http_process_connection },
-
- { ngx_string("If-Modified-Since"),
- offsetof(ngx_http_headers_in_t, if_modified_since),
- ngx_http_process_unique_header_line },
-
- { ngx_string("If-Unmodified-Since"),
- offsetof(ngx_http_headers_in_t, if_unmodified_since),
- ngx_http_process_unique_header_line },
-
- { ngx_string("If-Match"),
- offsetof(ngx_http_headers_in_t, if_match),
- ngx_http_process_unique_header_line },
-
- { ngx_string("If-None-Match"),
- offsetof(ngx_http_headers_in_t, if_none_match),
- ngx_http_process_unique_header_line },
-
- { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
- ngx_http_process_user_agent },
-
- { ngx_string("Referer"), offsetof(ngx_http_headers_in_t, referer),
- ngx_http_process_header_line },
-
- { ngx_string("Content-Length"),
- offsetof(ngx_http_headers_in_t, content_length),
- ngx_http_process_unique_header_line },
-
- { ngx_string("Content-Type"),
- offsetof(ngx_http_headers_in_t, content_type),
- ngx_http_process_header_line },
-
- { 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 },
-
- { ngx_string("Expect"),
- offsetof(ngx_http_headers_in_t, expect),
- ngx_http_process_unique_header_line },
-
- { ngx_string("Upgrade"),
- offsetof(ngx_http_headers_in_t, upgrade),
- ngx_http_process_header_line },
-
-#if (NGX_HTTP_GZIP)
- { ngx_string("Accept-Encoding"),
- offsetof(ngx_http_headers_in_t, accept_encoding),
- ngx_http_process_header_line },
-
- { ngx_string("Via"), offsetof(ngx_http_headers_in_t, via),
- ngx_http_process_header_line },
-#endif
-
- { ngx_string("Authorization"),
- offsetof(ngx_http_headers_in_t, authorization),
- ngx_http_process_unique_header_line },
-
- { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive),
- ngx_http_process_header_line },
-
-#if (NGX_HTTP_X_FORWARDED_FOR)
- { ngx_string("X-Forwarded-For"),
- offsetof(ngx_http_headers_in_t, x_forwarded_for),
- ngx_http_process_multi_header_lines },
-#endif
-
-#if (NGX_HTTP_REALIP)
- { ngx_string("X-Real-IP"),
- offsetof(ngx_http_headers_in_t, x_real_ip),
- ngx_http_process_header_line },
-#endif
-
-#if (NGX_HTTP_HEADERS)
- { ngx_string("Accept"), offsetof(ngx_http_headers_in_t, accept),
- ngx_http_process_header_line },
-
- { ngx_string("Accept-Language"),
- offsetof(ngx_http_headers_in_t, accept_language),
- ngx_http_process_header_line },
-#endif
-
-#if (NGX_HTTP_DAV)
- { ngx_string("Depth"), offsetof(ngx_http_headers_in_t, depth),
- ngx_http_process_header_line },
-
- { ngx_string("Destination"), offsetof(ngx_http_headers_in_t, destination),
- ngx_http_process_header_line },
-
- { ngx_string("Overwrite"), offsetof(ngx_http_headers_in_t, overwrite),
- ngx_http_process_header_line },
-
- { ngx_string("Date"), offsetof(ngx_http_headers_in_t, date),
- ngx_http_process_header_line },
-#endif
-
- { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookies),
- ngx_http_process_multi_header_lines },
-
- { ngx_null_string, 0, NULL }
-};
-
-
-void
-ngx_http_init_connection(ngx_connection_t *c)
-{
- ngx_uint_t i;
- ngx_event_t *rev;
- struct sockaddr_in *sin;
- ngx_http_port_t *port;
- ngx_http_in_addr_t *addr;
- ngx_http_log_ctx_t *ctx;
- ngx_http_connection_t *hc;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
- ngx_http_in6_addr_t *addr6;
-#endif
-
- hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
- if (hc == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- c->data = hc;
-
- /* find the server configuration for the address:port */
-
- port = c->listening->servers;
-
- if (port->naddrs > 1) {
-
- /*
- * there are several addresses on this port and one of them
- * is an "*:port" wildcard so getsockname() in ngx_http_server_addr()
- * is required to determine a server address
- */
-
- if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
- ngx_http_close_connection(c);
- return;
- }
-
- switch (c->local_sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
-
- addr6 = port->addrs;
-
- /* the last address is "*" */
-
- for (i = 0; i < port->naddrs - 1; i++) {
- if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) {
- break;
- }
- }
-
- hc->addr_conf = &addr6[i].conf;
-
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) c->local_sockaddr;
-
- addr = port->addrs;
-
- /* the last address is "*" */
-
- for (i = 0; i < port->naddrs - 1; i++) {
- if (addr[i].addr == sin->sin_addr.s_addr) {
- break;
- }
- }
-
- hc->addr_conf = &addr[i].conf;
-
- break;
- }
-
- } else {
-
- switch (c->local_sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- addr6 = port->addrs;
- hc->addr_conf = &addr6[0].conf;
- break;
-#endif
-
- default: /* AF_INET */
- addr = port->addrs;
- hc->addr_conf = &addr[0].conf;
- break;
- }
- }
-
- /* the default server configuration for the address:port */
- hc->conf_ctx = hc->addr_conf->default_server->ctx;
-
- ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
- if (ctx == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- ctx->connection = c;
- ctx->request = NULL;
- ctx->current_request = NULL;
-
- c->log->connection = c->number;
- c->log->handler = ngx_http_log_error;
- c->log->data = ctx;
- c->log->action = "waiting for request";
-
- c->log_error = NGX_ERROR_INFO;
-
- rev = c->read;
- rev->handler = ngx_http_wait_request_handler;
- c->write->handler = ngx_http_empty_handler;
-
-#if (NGX_HTTP_SPDY)
- if (hc->addr_conf->spdy) {
- rev->handler = ngx_http_spdy_init;
- }
-#endif
-
-#if (NGX_HTTP_SSL)
- {
- ngx_http_ssl_srv_conf_t *sscf;
-
- sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
-
- if (sscf->enable || hc->addr_conf->ssl) {
-
- c->log->action = "SSL handshaking";
-
- if (hc->addr_conf->ssl && sscf->ssl.ctx == NULL) {
- ngx_log_error(NGX_LOG_ERR, c->log, 0,
- "no \"ssl_certificate\" is defined "
- "in server listening on SSL port");
- ngx_http_close_connection(c);
- return;
- }
-
- hc->ssl = 1;
-
- rev->handler = ngx_http_ssl_handshake;
- }
- }
-#endif
-
- if (hc->addr_conf->proxy_protocol) {
- hc->proxy_protocol = 1;
- c->log->action = "reading PROXY protocol";
- }
-
- if (rev->ready) {
- /* the deferred accept(), rtsig, aio, iocp */
-
- if (ngx_use_accept_mutex) {
- ngx_post_event(rev, &ngx_posted_events);
- return;
- }
-
- rev->handler(rev);
- return;
- }
-
- ngx_add_timer(rev, c->listening->post_accept_timeout);
- ngx_reusable_connection(c, 1);
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- ngx_http_close_connection(c);
- return;
- }
-}
-
-
-static void
-ngx_http_wait_request_handler(ngx_event_t *rev)
-{
- u_char *p;
- size_t size;
- ssize_t n;
- ngx_buf_t *b;
- ngx_connection_t *c;
- ngx_http_connection_t *hc;
- ngx_http_core_srv_conf_t *cscf;
-
- c = rev->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http wait request handler");
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
- ngx_http_close_connection(c);
- return;
- }
-
- if (c->close) {
- ngx_http_close_connection(c);
- return;
- }
-
- hc = c->data;
- cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);
-
- size = cscf->client_header_buffer_size;
-
- b = c->buffer;
-
- if (b == NULL) {
- b = ngx_create_temp_buf(c->pool, size);
- if (b == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- c->buffer = b;
-
- } else if (b->start == NULL) {
-
- b->start = ngx_palloc(c->pool, size);
- if (b->start == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- b->pos = b->start;
- b->last = b->start;
- b->end = b->last + size;
- }
-
- n = c->recv(c, b->last, size);
-
- if (n == NGX_AGAIN) {
-
- if (!rev->timer_set) {
- ngx_add_timer(rev, c->listening->post_accept_timeout);
- ngx_reusable_connection(c, 1);
- }
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- ngx_http_close_connection(c);
- return;
- }
-
- /*
- * We are trying to not hold c->buffer's memory for an idle connection.
- */
-
- if (ngx_pfree(c->pool, b->start) == NGX_OK) {
- b->start = NULL;
- }
-
- return;
- }
-
- if (n == NGX_ERROR) {
- ngx_http_close_connection(c);
- return;
- }
-
- if (n == 0) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client closed connection");
- ngx_http_close_connection(c);
- return;
- }
-
- b->last += n;
-
- if (hc->proxy_protocol) {
- hc->proxy_protocol = 0;
-
- p = ngx_proxy_protocol_parse(c, b->pos, b->last);
-
- if (p == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- b->pos = p;
-
- if (b->pos == b->last) {
- c->log->action = "waiting for request";
- b->pos = b->start;
- b->last = b->start;
- ngx_post_event(rev, &ngx_posted_events);
- return;
- }
- }
-
- c->log->action = "reading client request line";
-
- ngx_reusable_connection(c, 0);
-
- c->data = ngx_http_create_request(c);
- if (c->data == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- rev->handler = ngx_http_process_request_line;
- ngx_http_process_request_line(rev);
-}
-
-
-ngx_http_request_t *
-ngx_http_create_request(ngx_connection_t *c)
-{
- ngx_pool_t *pool;
- ngx_time_t *tp;
- ngx_http_request_t *r;
- ngx_http_log_ctx_t *ctx;
- ngx_http_connection_t *hc;
- ngx_http_core_srv_conf_t *cscf;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_core_main_conf_t *cmcf;
-
- c->requests++;
-
- hc = c->data;
-
- cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);
-
- pool = ngx_create_pool(cscf->request_pool_size, c->log);
- if (pool == NULL) {
- return NULL;
- }
-
- r = ngx_pcalloc(pool, sizeof(ngx_http_request_t));
- if (r == NULL) {
- ngx_destroy_pool(pool);
- return NULL;
- }
-
- r->pool = pool;
-
- r->http_connection = hc;
- r->signature = NGX_HTTP_MODULE;
- r->connection = c;
-
- r->main_conf = hc->conf_ctx->main_conf;
- r->srv_conf = hc->conf_ctx->srv_conf;
- r->loc_conf = hc->conf_ctx->loc_conf;
-
- r->read_event_handler = ngx_http_block_reading;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- ngx_http_set_connection_log(r->connection, clcf->error_log);
-
- r->header_in = hc->nbusy ? hc->busy[0] : c->buffer;
-
- if (ngx_list_init(&r->headers_out.headers, r->pool, 20,
- sizeof(ngx_table_elt_t))
- != NGX_OK)
- {
- ngx_destroy_pool(r->pool);
- return NULL;
- }
-
- r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
- if (r->ctx == NULL) {
- ngx_destroy_pool(r->pool);
- return NULL;
- }
-
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
- r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
- * sizeof(ngx_http_variable_value_t));
- if (r->variables == NULL) {
- ngx_destroy_pool(r->pool);
- return NULL;
- }
-
-#if (NGX_HTTP_SSL)
- if (c->ssl) {
- r->main_filter_need_in_memory = 1;
- }
-#endif
-
- r->main = r;
- r->count = 1;
-
- tp = ngx_timeofday();
- r->start_sec = tp->sec;
- r->start_msec = tp->msec;
-
- r->method = NGX_HTTP_UNKNOWN;
- r->http_version = NGX_HTTP_VERSION_10;
-
- r->headers_in.content_length_n = -1;
- r->headers_in.keep_alive_n = -1;
- r->headers_out.content_length_n = -1;
- r->headers_out.last_modified_time = -1;
-
- r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
- r->subrequests = NGX_HTTP_MAX_SUBREQUESTS + 1;
-
- r->http_state = NGX_HTTP_READING_REQUEST_STATE;
-
- ctx = c->log->data;
- ctx->request = r;
- ctx->current_request = r;
- r->log_handler = ngx_http_log_error_handler;
-
-#if (NGX_STAT_STUB)
- (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
- r->stat_reading = 1;
- (void) ngx_atomic_fetch_add(ngx_stat_requests, 1);
-#endif
-
- return r;
-}
-
-
-#if (NGX_HTTP_SSL)
-
-static void
-ngx_http_ssl_handshake(ngx_event_t *rev)
-{
- u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1];
- size_t size;
- ssize_t n;
- ngx_err_t err;
- ngx_int_t rc;
- ngx_connection_t *c;
- ngx_http_connection_t *hc;
- ngx_http_ssl_srv_conf_t *sscf;
-
- c = rev->data;
- hc = c->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
- "http check ssl handshake");
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
- ngx_http_close_connection(c);
- return;
- }
-
- if (c->close) {
- ngx_http_close_connection(c);
- return;
- }
-
- size = hc->proxy_protocol ? sizeof(buf) : 1;
-
- n = recv(c->fd, (char *) buf, size, MSG_PEEK);
-
- err = ngx_socket_errno;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %d", n);
-
- if (n == -1) {
- if (err == NGX_EAGAIN) {
-
- if (!rev->timer_set) {
- ngx_add_timer(rev, c->listening->post_accept_timeout);
- ngx_reusable_connection(c, 1);
- }
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- ngx_http_close_connection(c);
- }
-
- return;
- }
-
- ngx_connection_error(c, err, "recv() failed");
- ngx_http_close_connection(c);
-
- return;
- }
-
- if (hc->proxy_protocol) {
- hc->proxy_protocol = 0;
-
- p = ngx_proxy_protocol_parse(c, buf, buf + n);
-
- if (p == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- size = p - buf;
-
- if (c->recv(c, buf, size) != (ssize_t) size) {
- ngx_http_close_connection(c);
- return;
- }
-
- c->log->action = "SSL handshaking";
-
- if (n == (ssize_t) size) {
- ngx_post_event(rev, &ngx_posted_events);
- return;
- }
-
- n = 1;
- buf[0] = *p;
- }
-
- if (n == 1) {
- if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0,
- "https ssl handshake: 0x%02Xd", buf[0]);
-
- sscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
- ngx_http_ssl_module);
-
- if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER)
- != NGX_OK)
- {
- ngx_http_close_connection(c);
- return;
- }
-
- rc = ngx_ssl_handshake(c);
-
- if (rc == NGX_AGAIN) {
-
- if (!rev->timer_set) {
- ngx_add_timer(rev, c->listening->post_accept_timeout);
- }
-
- ngx_reusable_connection(c, 0);
-
- c->ssl->handler = ngx_http_ssl_handshake_handler;
- return;
- }
-
- ngx_http_ssl_handshake_handler(c);
-
- return;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "plain http");
-
- c->log->action = "waiting for request";
-
- rev->handler = ngx_http_wait_request_handler;
- ngx_http_wait_request_handler(rev);
-
- return;
- }
-
- ngx_log_error(NGX_LOG_INFO, c->log, 0, "client closed connection");
- ngx_http_close_connection(c);
-}
-
-
-static void
-ngx_http_ssl_handshake_handler(ngx_connection_t *c)
-{
- if (c->ssl->handshaked) {
-
- /*
- * The majority of browsers do not send the "close notify" alert.
- * Among them are MSIE, old Mozilla, Netscape 4, Konqueror,
- * and Links. And what is more, MSIE ignores the server's alert.
- *
- * Opera and recent Mozilla send the alert.
- */
-
- c->ssl->no_wait_shutdown = 1;
-
-#if (NGX_HTTP_SPDY \
- && (defined TLSEXT_TYPE_application_layer_protocol_negotiation \
- || defined TLSEXT_TYPE_next_proto_neg))
- {
- unsigned int len;
- const unsigned char *data;
- static const ngx_str_t spdy = ngx_string(NGX_SPDY_NPN_NEGOTIATED);
-
-#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
- SSL_get0_alpn_selected(c->ssl->connection, &data, &len);
-
-#ifdef TLSEXT_TYPE_next_proto_neg
- if (len == 0) {
- SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
- }
-#endif
-
-#else /* TLSEXT_TYPE_next_proto_neg */
- SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
-#endif
-
- if (len == spdy.len && ngx_strncmp(data, spdy.data, spdy.len) == 0) {
- ngx_http_spdy_init(c->read);
- return;
- }
- }
-#endif
-
- c->log->action = "waiting for request";
-
- c->read->handler = ngx_http_wait_request_handler;
- /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler;
-
- ngx_reusable_connection(c, 1);
-
- ngx_http_wait_request_handler(c->read);
-
- return;
- }
-
- if (c->read->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
- }
-
- ngx_http_close_connection(c);
-}
-
-#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
-
-int
-ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
-{
- ngx_str_t host;
- const char *servername;
- ngx_connection_t *c;
- ngx_http_connection_t *hc;
- ngx_http_ssl_srv_conf_t *sscf;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_core_srv_conf_t *cscf;
-
- servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
-
- if (servername == NULL) {
- return SSL_TLSEXT_ERR_NOACK;
- }
-
- c = ngx_ssl_get_connection(ssl_conn);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "SSL server name: \"%s\"", servername);
-
- host.len = ngx_strlen(servername);
-
- if (host.len == 0) {
- return SSL_TLSEXT_ERR_NOACK;
- }
-
- host.data = (u_char *) servername;
-
- if (ngx_http_validate_host(&host, c->pool, 1) != NGX_OK) {
- return SSL_TLSEXT_ERR_NOACK;
- }
-
- hc = c->data;
-
- if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host,
- NULL, &cscf)
- != NGX_OK)
- {
- return SSL_TLSEXT_ERR_NOACK;
- }
-
- hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
- if (hc->ssl_servername == NULL) {
- return SSL_TLSEXT_ERR_NOACK;
- }
-
- *hc->ssl_servername = host;
-
- hc->conf_ctx = cscf->ctx;
-
- clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module);
-
- ngx_http_set_connection_log(c, clcf->error_log);
-
- sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
-
- if (sscf->ssl.ctx) {
- SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx);
-
- /*
- * SSL_set_SSL_CTX() only changes certs as of 1.0.0d
- * adjust other things we care about
- */
-
- SSL_set_verify(ssl_conn, SSL_CTX_get_verify_mode(sscf->ssl.ctx),
- SSL_CTX_get_verify_callback(sscf->ssl.ctx));
-
- SSL_set_verify_depth(ssl_conn, SSL_CTX_get_verify_depth(sscf->ssl.ctx));
-
-#ifdef SSL_CTRL_CLEAR_OPTIONS
- /* only in 0.9.8m+ */
- SSL_clear_options(ssl_conn, SSL_get_options(ssl_conn) &
- ~SSL_CTX_get_options(sscf->ssl.ctx));
-#endif
-
- SSL_set_options(ssl_conn, SSL_CTX_get_options(sscf->ssl.ctx));
- }
-
- return SSL_TLSEXT_ERR_OK;
-}
-
-#endif
-
-#endif
-
-
-static void
-ngx_http_process_request_line(ngx_event_t *rev)
-{
- ssize_t n;
- ngx_int_t rc, rv;
- ngx_str_t host;
- ngx_connection_t *c;
- ngx_http_request_t *r;
-
- c = rev->data;
- r = c->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
- "http process request line");
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
- c->timedout = 1;
- ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
- return;
- }
-
- rc = NGX_AGAIN;
-
- for ( ;; ) {
-
- if (rc == NGX_AGAIN) {
- n = ngx_http_read_request_header(r);
-
- if (n == NGX_AGAIN || n == NGX_ERROR) {
- return;
- }
- }
-
- rc = ngx_http_parse_request_line(r, r->header_in);
-
- if (rc == NGX_OK) {
-
- /* the request line has been parsed successfully */
-
- r->request_line.len = r->request_end - r->request_start;
- r->request_line.data = r->request_start;
- r->request_length = r->header_in->pos - r->request_start;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http request line: \"%V\"", &r->request_line);
-
- r->method_name.len = r->method_end - r->request_start + 1;
- r->method_name.data = r->request_line.data;
-
- if (r->http_protocol.data) {
- r->http_protocol.len = r->request_end - r->http_protocol.data;
- }
-
- if (ngx_http_process_request_uri(r) != NGX_OK) {
- return;
- }
-
- if (r->host_start && r->host_end) {
-
- host.len = r->host_end - r->host_start;
- host.data = r->host_start;
-
- rc = ngx_http_validate_host(&host, r->pool, 0);
-
- if (rc == NGX_DECLINED) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent invalid host in request line");
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return;
- }
-
- if (rc == NGX_ERROR) {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
- return;
- }
-
- r->headers_in.server = host;
- }
-
- if (r->http_version < NGX_HTTP_VERSION_10) {
-
- if (r->headers_in.server.len == 0
- && ngx_http_set_virtual_server(r, &r->headers_in.server)
- == NGX_ERROR)
- {
- return;
- }
-
- ngx_http_process_request(r);
- return;
- }
-
-
- if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
- sizeof(ngx_table_elt_t))
- != NGX_OK)
- {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- c->log->action = "reading client request headers";
-
- rev->handler = ngx_http_process_request_headers;
- ngx_http_process_request_headers(rev);
-
- return;
- }
-
- if (rc != NGX_AGAIN) {
-
- /* there was error while a request line parsing */
-
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return;
- }
-
- /* NGX_AGAIN: a request line parsing is still incomplete */
-
- if (r->header_in->pos == r->header_in->end) {
-
- rv = ngx_http_alloc_large_header_buffer(r, 1);
-
- if (rv == NGX_ERROR) {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- if (rv == NGX_DECLINED) {
- r->request_line.len = r->header_in->end - r->request_start;
- r->request_line.data = r->request_start;
-
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent too long URI");
- ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
- return;
- }
- }
- }
-}
-
-
-ngx_int_t
-ngx_http_process_request_uri(ngx_http_request_t *r)
-{
- ngx_http_core_srv_conf_t *cscf;
-
- if (r->args_start) {
- r->uri.len = r->args_start - 1 - r->uri_start;
- } else {
- r->uri.len = r->uri_end - r->uri_start;
- }
-
- if (r->complex_uri || r->quoted_uri) {
-
- r->uri.data = ngx_pnalloc(r->pool, r->uri.len + 1);
- if (r->uri.data == NULL) {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_ERROR;
- }
-
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
- if (ngx_http_parse_complex_uri(r, cscf->merge_slashes) != NGX_OK) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent invalid request");
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return NGX_ERROR;
- }
-
- } else {
- r->uri.data = r->uri_start;
- }
-
- r->unparsed_uri.len = r->uri_end - r->uri_start;
- r->unparsed_uri.data = r->uri_start;
-
- r->valid_unparsed_uri = r->space_in_uri ? 0 : 1;
-
- if (r->uri_ext) {
- if (r->args_start) {
- r->exten.len = r->args_start - 1 - r->uri_ext;
- } else {
- r->exten.len = r->uri_end - r->uri_ext;
- }
-
- r->exten.data = r->uri_ext;
- }
-
- if (r->args_start && r->uri_end > r->args_start) {
- r->args.len = r->uri_end - r->args_start;
- r->args.data = r->args_start;
- }
-
-#if (NGX_WIN32)
- {
- u_char *p, *last;
-
- p = r->uri.data;
- last = r->uri.data + r->uri.len;
-
- while (p < last) {
-
- if (*p++ == ':') {
-
- /*
- * this check covers "::$data", "::$index_allocation" and
- * ":$i30:$index_allocation"
- */
-
- if (p < last && *p == '$') {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent unsafe win32 URI");
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return NGX_ERROR;
- }
- }
- }
-
- p = r->uri.data + r->uri.len - 1;
-
- while (p > r->uri.data) {
-
- if (*p == ' ') {
- p--;
- continue;
- }
-
- if (*p == '.') {
- p--;
- continue;
- }
-
- break;
- }
-
- if (p != r->uri.data + r->uri.len - 1) {
- r->uri.len = p + 1 - r->uri.data;
- ngx_http_set_exten(r);
- }
-
- }
-#endif
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http uri: \"%V\"", &r->uri);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http args: \"%V\"", &r->args);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http exten: \"%V\"", &r->exten);
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_process_request_headers(ngx_event_t *rev)
-{
- u_char *p;
- size_t len;
- ssize_t n;
- ngx_int_t rc, rv;
- ngx_table_elt_t *h;
- ngx_connection_t *c;
- ngx_http_header_t *hh;
- ngx_http_request_t *r;
- ngx_http_core_srv_conf_t *cscf;
- ngx_http_core_main_conf_t *cmcf;
-
- c = rev->data;
- r = c->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
- "http process request header line");
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
- c->timedout = 1;
- ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
- return;
- }
-
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
- rc = NGX_AGAIN;
-
- for ( ;; ) {
-
- if (rc == NGX_AGAIN) {
-
- if (r->header_in->pos == r->header_in->end) {
-
- rv = ngx_http_alloc_large_header_buffer(r, 0);
-
- if (rv == NGX_ERROR) {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- if (rv == NGX_DECLINED) {
- p = r->header_name_start;
-
- r->lingering_close = 1;
-
- if (p == NULL) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent too large request");
- ngx_http_finalize_request(r,
- NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
- return;
- }
-
- len = r->header_in->end - p;
-
- if (len > NGX_MAX_ERROR_STR - 300) {
- len = NGX_MAX_ERROR_STR - 300;
- p[len++] = '.'; p[len++] = '.'; p[len++] = '.';
- }
-
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent too long header line: \"%*s\"",
- len, r->header_name_start);
-
- ngx_http_finalize_request(r,
- NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
- return;
- }
- }
-
- n = ngx_http_read_request_header(r);
-
- if (n == NGX_AGAIN || n == NGX_ERROR) {
- return;
- }
- }
-
- /* the host header could change the server configuration context */
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
- rc = ngx_http_parse_header_line(r, r->header_in,
- cscf->underscores_in_headers);
-
- if (rc == NGX_OK) {
-
- r->request_length += r->header_in->pos - r->header_name_start;
-
- if (r->invalid_header && cscf->ignore_invalid_headers) {
-
- /* there was error while a header line parsing */
-
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent invalid header line: \"%*s\"",
- r->header_end - r->header_name_start,
- r->header_name_start);
- continue;
- }
-
- /* a header line has been parsed successfully */
-
- h = ngx_list_push(&r->headers_in.headers);
- if (h == NULL) {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- h->hash = r->header_hash;
-
- 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_pnalloc(r->pool, h->key.len);
- if (h->lowcase_key == NULL) {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- if (h->key.len == r->lowcase_index) {
- ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
-
- } else {
- ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
- }
-
- hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
- h->lowcase_key, h->key.len);
-
- if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
- return;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http header: \"%V: %V\"",
- &h->key, &h->value);
-
- continue;
- }
-
- if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
-
- /* a whole header has been parsed successfully */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http header done");
-
- r->request_length += r->header_in->pos - r->header_name_start;
-
- r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
-
- rc = ngx_http_process_request_header(r);
-
- if (rc != NGX_OK) {
- return;
- }
-
- ngx_http_process_request(r);
-
- return;
- }
-
- if (rc == NGX_AGAIN) {
-
- /* a header line parsing is still not complete */
-
- continue;
- }
-
- /* rc == NGX_HTTP_PARSE_INVALID_HEADER: "\r" is not followed by "\n" */
-
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent invalid header line: \"%*s\\r...\"",
- r->header_end - r->header_name_start,
- r->header_name_start);
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return;
- }
-}
-
-
-static ssize_t
-ngx_http_read_request_header(ngx_http_request_t *r)
-{
- ssize_t n;
- ngx_event_t *rev;
- ngx_connection_t *c;
- ngx_http_core_srv_conf_t *cscf;
-
- c = r->connection;
- rev = c->read;
-
- n = r->header_in->last - r->header_in->pos;
-
- if (n > 0) {
- return n;
- }
-
- if (rev->ready) {
- n = c->recv(c, r->header_in->last,
- r->header_in->end - r->header_in->last);
- } else {
- n = NGX_AGAIN;
- }
-
- if (n == NGX_AGAIN) {
- if (!rev->timer_set) {
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
- ngx_add_timer(rev, cscf->client_header_timeout);
- }
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_ERROR;
- }
-
- return NGX_AGAIN;
- }
-
- if (n == 0) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client prematurely closed connection");
- }
-
- if (n == 0 || n == NGX_ERROR) {
- c->error = 1;
- c->log->action = "reading client request headers";
-
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return NGX_ERROR;
- }
-
- r->header_in->last += n;
-
- return n;
-}
-
-
-static ngx_int_t
-ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
- ngx_uint_t request_line)
-{
- u_char *old, *new;
- ngx_buf_t *b;
- ngx_http_connection_t *hc;
- ngx_http_core_srv_conf_t *cscf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http alloc large header buffer");
-
- if (request_line && r->state == 0) {
-
- /* the client fills up the buffer with "\r\n" */
-
- r->header_in->pos = r->header_in->start;
- r->header_in->last = r->header_in->start;
-
- return NGX_OK;
- }
-
- old = request_line ? r->request_start : r->header_name_start;
-
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
- if (r->state != 0
- && (size_t) (r->header_in->pos - old)
- >= cscf->large_client_header_buffers.size)
- {
- return NGX_DECLINED;
- }
-
- hc = r->http_connection;
-
- if (hc->nfree) {
- b = hc->free[--hc->nfree];
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http large header free: %p %uz",
- b->pos, b->end - b->last);
-
- } else if (hc->nbusy < cscf->large_client_header_buffers.num) {
-
- if (hc->busy == NULL) {
- hc->busy = ngx_palloc(r->connection->pool,
- cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
- if (hc->busy == NULL) {
- return NGX_ERROR;
- }
- }
-
- b = ngx_create_temp_buf(r->connection->pool,
- cscf->large_client_header_buffers.size);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http large header alloc: %p %uz",
- b->pos, b->end - b->last);
-
- } else {
- return NGX_DECLINED;
- }
-
- hc->busy[hc->nbusy++] = b;
-
- if (r->state == 0) {
- /*
- * r->state == 0 means that a header line was parsed successfully
- * and we do not need to copy incomplete header line and
- * to relocate the parser header pointers
- */
-
- r->header_in = b;
-
- return NGX_OK;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http large header copy: %d", r->header_in->pos - old);
-
- new = b->start;
-
- ngx_memcpy(new, old, r->header_in->pos - old);
-
- b->pos = new + (r->header_in->pos - old);
- b->last = new + (r->header_in->pos - old);
-
- if (request_line) {
- r->request_start = new;
-
- if (r->request_end) {
- r->request_end = new + (r->request_end - old);
- }
-
- r->method_end = new + (r->method_end - old);
-
- r->uri_start = new + (r->uri_start - old);
- r->uri_end = new + (r->uri_end - old);
-
- if (r->schema_start) {
- r->schema_start = new + (r->schema_start - old);
- r->schema_end = new + (r->schema_end - old);
- }
-
- if (r->host_start) {
- r->host_start = new + (r->host_start - old);
- if (r->host_end) {
- r->host_end = new + (r->host_end - old);
- }
- }
-
- if (r->port_start) {
- r->port_start = new + (r->port_start - old);
- r->port_end = new + (r->port_end - old);
- }
-
- if (r->uri_ext) {
- r->uri_ext = new + (r->uri_ext - old);
- }
-
- if (r->args_start) {
- 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);
- r->header_start = new + (r->header_start - old);
- r->header_end = new + (r->header_end - old);
- }
-
- r->header_in = b;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- ngx_table_elt_t **ph;
-
- ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
-
- if (*ph == NULL) {
- *ph = h;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- ngx_table_elt_t **ph;
-
- ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
-
- if (*ph == NULL) {
- *ph = h;
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent duplicate header line: \"%V: %V\", "
- "previous value: \"%V: %V\"",
- &h->key, &h->value, &(*ph)->key, &(*ph)->value);
-
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
-
- return NGX_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- ngx_int_t rc;
- ngx_str_t host;
-
- if (r->headers_in.host == NULL) {
- r->headers_in.host = h;
- }
-
- host = h->value;
-
- rc = ngx_http_validate_host(&host, r->pool, 0);
-
- if (rc == NGX_DECLINED) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent invalid host header");
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return NGX_ERROR;
- }
-
- if (rc == NGX_ERROR) {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_ERROR;
- }
-
- if (r->headers_in.server.len) {
- return NGX_OK;
- }
-
- if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- r->headers_in.server = host;
-
- return NGX_OK;
-}
-
-
-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_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- u_char *user_agent, *msie;
-
- if (r->headers_in.user_agent) {
- return NGX_OK;
- }
-
- r->headers_in.user_agent = h;
-
- /* check some widespread browsers while the header is in CPU cache */
-
- user_agent = h->value.data;
-
- msie = ngx_strstrn(user_agent, "MSIE ", 5 - 1);
-
- if (msie && msie + 7 < user_agent + h->value.len) {
-
- r->headers_in.msie = 1;
-
- if (msie[6] == '.') {
-
- switch (msie[5]) {
- case '4':
- case '5':
- r->headers_in.msie6 = 1;
- break;
- case '6':
- if (ngx_strstrn(msie + 8, "SV1", 3 - 1) == NULL) {
- r->headers_in.msie6 = 1;
- }
- break;
- }
- }
-
-#if 0
- /* MSIE ignores the SSL "close notify" alert */
- if (c->ssl) {
- c->ssl->no_send_shutdown = 1;
- }
-#endif
- }
-
- if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
- r->headers_in.opera = 1;
- r->headers_in.msie = 0;
- r->headers_in.msie6 = 0;
- }
-
- if (!r->headers_in.msie && !r->headers_in.opera) {
-
- if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
- r->headers_in.gecko = 1;
-
- } else if (ngx_strstrn(user_agent, "Chrome/", 7 - 1)) {
- r->headers_in.chrome = 1;
-
- } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)
- && ngx_strstrn(user_agent, "Mac OS X", 8 - 1))
- {
- r->headers_in.safari = 1;
-
- } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
- r->headers_in.konqueror = 1;
- }
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- ngx_array_t *headers;
- ngx_table_elt_t **ph;
-
- headers = (ngx_array_t *) ((char *) &r->headers_in + offset);
-
- if (headers->elts == NULL) {
- if (ngx_array_init(headers, r->pool, 1, sizeof(ngx_table_elt_t *))
- != NGX_OK)
- {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_ERROR;
- }
- }
-
- ph = ngx_array_push(headers);
- if (ph == NULL) {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_ERROR;
- }
-
- *ph = h;
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_process_request_header(ngx_http_request_t *r)
-{
- if (r->headers_in.server.len == 0
- && ngx_http_set_virtual_server(r, &r->headers_in.server)
- == NGX_ERROR)
- {
- return NGX_ERROR;
- }
-
- if (r->headers_in.host == NULL && r->http_version > NGX_HTTP_VERSION_10) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent HTTP/1.1 request without \"Host\" header");
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return NGX_ERROR;
- }
-
- if (r->headers_in.content_length) {
- r->headers_in.content_length_n =
- ngx_atoof(r->headers_in.content_length->value.data,
- r->headers_in.content_length->value.len);
-
- if (r->headers_in.content_length_n == NGX_ERROR) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent invalid \"Content-Length\" header");
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return NGX_ERROR;
- }
- }
-
- 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);
- return NGX_ERROR;
- }
-
- if (r->headers_in.transfer_encoding) {
- if (r->headers_in.transfer_encoding->value.len == 7
- && ngx_strncasecmp(r->headers_in.transfer_encoding->value.data,
- (u_char *) "chunked", 7) == 0)
- {
- r->headers_in.content_length = NULL;
- r->headers_in.content_length_n = -1;
- r->headers_in.chunked = 1;
-
- } else if (r->headers_in.transfer_encoding->value.len != 8
- || ngx_strncasecmp(r->headers_in.transfer_encoding->value.data,
- (u_char *) "identity", 8) != 0)
- {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent unknown \"Transfer-Encoding\": \"%V\"",
- &r->headers_in.transfer_encoding->value);
- ngx_http_finalize_request(r, NGX_HTTP_NOT_IMPLEMENTED);
- return NGX_ERROR;
- }
- }
-
- 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);
- }
- }
-
- return NGX_OK;
-}
-
-
-void
-ngx_http_process_request(ngx_http_request_t *r)
-{
- ngx_connection_t *c;
-
- c = r->connection;
-
-#if (NGX_HTTP_SSL)
-
- if (r->http_connection->ssl) {
- long rc;
- X509 *cert;
- ngx_http_ssl_srv_conf_t *sscf;
-
- if (c->ssl == NULL) {
- 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;
- }
-
- sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
-
- if (sscf->verify) {
- rc = SSL_get_verify_result(c->ssl->connection);
-
- if (rc != X509_V_OK
- && (sscf->verify != 3 || !ngx_ssl_verify_error_optional(rc)))
- {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client SSL certificate verify error: (%l:%s)",
- rc, X509_verify_cert_error_string(rc));
-
- ngx_ssl_remove_cached_session(sscf->ssl.ctx,
- (SSL_get0_session(c->ssl->connection)));
-
- ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
- return;
- }
-
- if (sscf->verify == 1) {
- cert = SSL_get_peer_certificate(c->ssl->connection);
-
- if (cert == NULL) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent no required SSL certificate");
-
- ngx_ssl_remove_cached_session(sscf->ssl.ctx,
- (SSL_get0_session(c->ssl->connection)));
-
- ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
- return;
- }
-
- X509_free(cert);
- }
- }
- }
-
-#endif
-
- if (c->read->timer_set) {
- ngx_del_timer(c->read);
- }
-
-#if (NGX_STAT_STUB)
- (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
- r->stat_reading = 0;
- (void) ngx_atomic_fetch_add(ngx_stat_writing, 1);
- r->stat_writing = 1;
-#endif
-
- c->read->handler = ngx_http_request_handler;
- c->write->handler = ngx_http_request_handler;
- r->read_event_handler = ngx_http_block_reading;
-
- ngx_http_handler(r);
-
- ngx_http_run_posted_requests(c);
-}
-
-
-static ngx_int_t
-ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc)
-{
- u_char *h, ch;
- size_t i, dot_pos, host_len;
-
- enum {
- sw_usual = 0,
- sw_literal,
- sw_rest
- } state;
-
- dot_pos = host->len;
- host_len = host->len;
-
- h = host->data;
-
- state = sw_usual;
-
- for (i = 0; i < host->len; i++) {
- ch = h[i];
-
- switch (ch) {
-
- case '.':
- if (dot_pos == i - 1) {
- return NGX_DECLINED;
- }
- dot_pos = i;
- break;
-
- case ':':
- if (state == sw_usual) {
- host_len = i;
- state = sw_rest;
- }
- break;
-
- case '[':
- if (i == 0) {
- state = sw_literal;
- }
- break;
-
- case ']':
- if (state == sw_literal) {
- host_len = i + 1;
- state = sw_rest;
- }
- break;
-
- case '\0':
- return NGX_DECLINED;
-
- default:
-
- if (ngx_path_separator(ch)) {
- return NGX_DECLINED;
- }
-
- if (ch >= 'A' && ch <= 'Z') {
- alloc = 1;
- }
-
- break;
- }
- }
-
- if (dot_pos == host_len - 1) {
- host_len--;
- }
-
- if (host_len == 0) {
- return NGX_DECLINED;
- }
-
- if (alloc) {
- host->data = ngx_pnalloc(pool, host_len);
- if (host->data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_strlow(host->data, h, host_len);
- }
-
- host->len = host_len;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host)
-{
- ngx_int_t rc;
- ngx_http_connection_t *hc;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_core_srv_conf_t *cscf;
-
-#if (NGX_SUPPRESS_WARN)
- cscf = NULL;
-#endif
-
- hc = r->http_connection;
-
-#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
-
- if (hc->ssl_servername) {
- if (hc->ssl_servername->len == host->len
- && ngx_strncmp(hc->ssl_servername->data,
- host->data, host->len) == 0)
- {
-#if (NGX_PCRE)
- if (hc->ssl_servername_regex
- && ngx_http_regex_exec(r, hc->ssl_servername_regex,
- hc->ssl_servername) != NGX_OK)
- {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_ERROR;
- }
-#endif
- return NGX_OK;
- }
- }
-
-#endif
-
- rc = ngx_http_find_virtual_server(r->connection,
- hc->addr_conf->virtual_names,
- host, r, &cscf);
-
- if (rc == NGX_ERROR) {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_ERROR;
- }
-
-#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
-
- if (hc->ssl_servername) {
- ngx_http_ssl_srv_conf_t *sscf;
-
- if (rc == NGX_DECLINED) {
- cscf = hc->addr_conf->default_server;
- rc = NGX_OK;
- }
-
- sscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_ssl_module);
-
- if (sscf->verify) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client attempted to request the server name "
- "different from that one was negotiated");
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return NGX_ERROR;
- }
- }
-
-#endif
-
- if (rc == NGX_DECLINED) {
- return NGX_OK;
- }
-
- r->srv_conf = cscf->ctx->srv_conf;
- r->loc_conf = cscf->ctx->loc_conf;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- ngx_http_set_connection_log(r->connection, clcf->error_log);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_find_virtual_server(ngx_connection_t *c,
- ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
- ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp)
-{
- ngx_http_core_srv_conf_t *cscf;
-
- if (virtual_names == NULL) {
- return NGX_DECLINED;
- }
-
- cscf = ngx_hash_find_combined(&virtual_names->names,
- ngx_hash_key(host->data, host->len),
- host->data, host->len);
-
- if (cscf) {
- *cscfp = cscf;
- return NGX_OK;
- }
-
-#if (NGX_PCRE)
-
- if (host->len && virtual_names->nregex) {
- ngx_int_t n;
- ngx_uint_t i;
- ngx_http_server_name_t *sn;
-
- sn = virtual_names->regex;
-
-#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
-
- if (r == NULL) {
- ngx_http_connection_t *hc;
-
- for (i = 0; i < virtual_names->nregex; i++) {
-
- n = ngx_regex_exec(sn[i].regex->regex, host, NULL, 0);
-
- if (n == NGX_REGEX_NO_MATCHED) {
- continue;
- }
-
- if (n >= 0) {
- hc = c->data;
- hc->ssl_servername_regex = sn[i].regex;
-
- *cscfp = sn[i].server;
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- ngx_regex_exec_n " failed: %i "
- "on \"%V\" using \"%V\"",
- n, host, &sn[i].regex->name);
-
- return NGX_ERROR;
- }
-
- return NGX_DECLINED;
- }
-
-#endif /* NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME */
-
- for (i = 0; i < virtual_names->nregex; i++) {
-
- n = ngx_http_regex_exec(r, sn[i].regex, host);
-
- if (n == NGX_DECLINED) {
- continue;
- }
-
- if (n == NGX_OK) {
- *cscfp = sn[i].server;
- return NGX_OK;
- }
-
- return NGX_ERROR;
- }
- }
-
-#endif /* NGX_PCRE */
-
- return NGX_DECLINED;
-}
-
-
-static void
-ngx_http_request_handler(ngx_event_t *ev)
-{
- ngx_connection_t *c;
- ngx_http_request_t *r;
- ngx_http_log_ctx_t *ctx;
-
- c = ev->data;
- r = c->data;
-
- ctx = c->log->data;
- ctx->current_request = r;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http run request: \"%V?%V\"", &r->uri, &r->args);
-
- if (ev->write) {
- r->write_event_handler(r);
-
- } else {
- r->read_event_handler(r);
- }
-
- ngx_http_run_posted_requests(c);
-}
-
-
-void
-ngx_http_run_posted_requests(ngx_connection_t *c)
-{
- ngx_http_request_t *r;
- ngx_http_log_ctx_t *ctx;
- ngx_http_posted_request_t *pr;
-
- for ( ;; ) {
-
- if (c->destroyed) {
- return;
- }
-
- r = c->data;
- pr = r->main->posted_requests;
-
- if (pr == NULL) {
- return;
- }
-
- r->main->posted_requests = pr->next;
-
- r = pr->request;
-
- ctx = c->log->data;
- ctx->current_request = r;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http posted request: \"%V?%V\"", &r->uri, &r->args);
-
- r->write_event_handler(r);
- }
-}
-
-
-ngx_int_t
-ngx_http_post_request(ngx_http_request_t *r, ngx_http_posted_request_t *pr)
-{
- ngx_http_posted_request_t **p;
-
- if (pr == NULL) {
- pr = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
- if (pr == NULL) {
- return NGX_ERROR;
- }
- }
-
- pr->request = r;
- pr->next = NULL;
-
- for (p = &r->main->posted_requests; *p; p = &(*p)->next) { /* void */ }
-
- *p = pr;
-
- return NGX_OK;
-}
-
-
-void
-ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
-{
- ngx_connection_t *c;
- ngx_http_request_t *pr;
- ngx_http_core_loc_conf_t *clcf;
-
- c = r->connection;
-
- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http finalize request: %d, \"%V?%V\" a:%d, c:%d",
- rc, &r->uri, &r->args, r == c->data, r->main->count);
-
- if (rc == NGX_DONE) {
- ngx_http_finalize_connection(r);
- return;
- }
-
- if (rc == NGX_OK && r->filter_finalize) {
- c->error = 1;
- }
-
- if (rc == NGX_DECLINED) {
- r->content_handler = NULL;
- r->write_event_handler = ngx_http_core_run_phases;
- ngx_http_core_run_phases(r);
- return;
- }
-
- if (r != r->main && r->post_subrequest) {
- rc = r->post_subrequest->handler(r, r->post_subrequest->data, rc);
- }
-
- if (rc == NGX_ERROR
- || rc == NGX_HTTP_REQUEST_TIME_OUT
- || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST
- || c->error)
- {
- if (ngx_http_post_action(r) == NGX_OK) {
- return;
- }
-
- if (r->main->blocked) {
- r->write_event_handler = ngx_http_request_finalizer;
- }
-
- ngx_http_terminate_request(r, rc);
- return;
- }
-
- if (rc >= NGX_HTTP_SPECIAL_RESPONSE
- || rc == NGX_HTTP_CREATED
- || rc == NGX_HTTP_NO_CONTENT)
- {
- if (rc == NGX_HTTP_CLOSE) {
- ngx_http_terminate_request(r, rc);
- return;
- }
-
- if (r == r->main) {
- if (c->read->timer_set) {
- ngx_del_timer(c->read);
- }
-
- if (c->write->timer_set) {
- ngx_del_timer(c->write);
- }
- }
-
- c->read->handler = ngx_http_request_handler;
- c->write->handler = ngx_http_request_handler;
-
- ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));
- return;
- }
-
- if (r != r->main) {
-
- if (r->buffered || r->postponed) {
-
- if (ngx_http_set_write_handler(r) != NGX_OK) {
- ngx_http_terminate_request(r, 0);
- }
-
- return;
- }
-
- pr = r->parent;
-
- if (r == c->data) {
-
- r->main->count--;
- r->main->subrequests++;
-
- if (!r->logged) {
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->log_subrequest) {
- ngx_http_log_request(r);
- }
-
- r->logged = 1;
-
- } else {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "subrequest: \"%V?%V\" logged again",
- &r->uri, &r->args);
- }
-
- r->done = 1;
-
- if (pr->postponed && pr->postponed->request == r) {
- pr->postponed = pr->postponed->next;
- }
-
- c->data = pr;
-
- } else {
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http finalize non-active request: \"%V?%V\"",
- &r->uri, &r->args);
-
- r->write_event_handler = ngx_http_request_finalizer;
-
- if (r->waited) {
- r->done = 1;
- }
- }
-
- if (ngx_http_post_request(pr, NULL) != NGX_OK) {
- r->main->count++;
- ngx_http_terminate_request(r, 0);
- return;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http wake parent request: \"%V?%V\"",
- &pr->uri, &pr->args);
-
- return;
- }
-
- if (r->buffered || c->buffered || r->postponed || r->blocked) {
-
- if (ngx_http_set_write_handler(r) != NGX_OK) {
- ngx_http_terminate_request(r, 0);
- }
-
- return;
- }
-
- if (r != c->data) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "http finalize non-active request: \"%V?%V\"",
- &r->uri, &r->args);
- return;
- }
-
- r->done = 1;
- r->write_event_handler = ngx_http_request_empty_handler;
-
- if (!r->post_action) {
- r->request_complete = 1;
- }
-
- if (ngx_http_post_action(r) == NGX_OK) {
- return;
- }
-
- if (c->read->timer_set) {
- ngx_del_timer(c->read);
- }
-
- if (c->write->timer_set) {
- c->write->delayed = 0;
- ngx_del_timer(c->write);
- }
-
- if (c->read->eof) {
- ngx_http_close_request(r, 0);
- return;
- }
-
- ngx_http_finalize_connection(r);
-}
-
-
-static void
-ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc)
-{
- ngx_http_cleanup_t *cln;
- ngx_http_request_t *mr;
- ngx_http_ephemeral_t *e;
-
- mr = r->main;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http terminate request count:%d", mr->count);
-
- if (rc > 0 && (mr->headers_out.status == 0 || mr->connection->sent == 0)) {
- mr->headers_out.status = rc;
- }
-
- cln = mr->cleanup;
- mr->cleanup = NULL;
-
- while (cln) {
- if (cln->handler) {
- cln->handler(cln->data);
- }
-
- cln = cln->next;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http terminate cleanup count:%d blk:%d",
- mr->count, mr->blocked);
-
- if (mr->write_event_handler) {
-
- if (mr->blocked) {
- return;
- }
-
- e = ngx_http_ephemeral(mr);
- mr->posted_requests = NULL;
- mr->write_event_handler = ngx_http_terminate_handler;
- (void) ngx_http_post_request(mr, &e->terminal_posted_request);
- return;
- }
-
- ngx_http_close_request(mr, rc);
-}
-
-
-static void
-ngx_http_terminate_handler(ngx_http_request_t *r)
-{
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http terminate handler count:%d", r->count);
-
- r->count = 1;
-
- ngx_http_close_request(r, 0);
-}
-
-
-static void
-ngx_http_finalize_connection(ngx_http_request_t *r)
-{
- ngx_http_core_loc_conf_t *clcf;
-
-#if (NGX_HTTP_SPDY)
- if (r->spdy_stream) {
- ngx_http_close_request(r, 0);
- return;
- }
-#endif
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (r->main->count != 1) {
-
- if (r->discard_body) {
- r->read_event_handler = ngx_http_discarded_request_body_handler;
- ngx_add_timer(r->connection->read, clcf->lingering_timeout);
-
- if (r->lingering_time == 0) {
- r->lingering_time = ngx_time()
- + (time_t) (clcf->lingering_time / 1000);
- }
- }
-
- ngx_http_close_request(r, 0);
- return;
- }
-
- if (!ngx_terminate
- && !ngx_exiting
- && r->keepalive
- && clcf->keepalive_timeout > 0)
- {
- ngx_http_set_keepalive(r);
- return;
- }
-
- if (clcf->lingering_close == NGX_HTTP_LINGERING_ALWAYS
- || (clcf->lingering_close == NGX_HTTP_LINGERING_ON
- && (r->lingering_close
- || r->header_in->pos < r->header_in->last
- || r->connection->read->ready)))
- {
- ngx_http_set_lingering_close(r);
- return;
- }
-
- ngx_http_close_request(r, 0);
-}
-
-
-static ngx_int_t
-ngx_http_set_write_handler(ngx_http_request_t *r)
-{
- ngx_event_t *wev;
- ngx_http_core_loc_conf_t *clcf;
-
- r->http_state = NGX_HTTP_WRITING_REQUEST_STATE;
-
- r->read_event_handler = r->discard_body ?
- ngx_http_discarded_request_body_handler:
- ngx_http_test_reading;
- r->write_event_handler = ngx_http_writer;
-
-#if (NGX_HTTP_SPDY)
- if (r->spdy_stream) {
- return NGX_OK;
- }
-#endif
-
- wev = r->connection->write;
-
- if (wev->ready && wev->delayed) {
- return NGX_OK;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- if (!wev->delayed) {
- ngx_add_timer(wev, clcf->send_timeout);
- }
-
- if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
- ngx_http_close_request(r, 0);
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_writer(ngx_http_request_t *r)
-{
- int rc;
- ngx_event_t *wev;
- ngx_connection_t *c;
- ngx_http_core_loc_conf_t *clcf;
-
- c = r->connection;
- wev = c->write;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0,
- "http writer handler: \"%V?%V\"", &r->uri, &r->args);
-
- clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module);
-
- if (wev->timedout) {
- if (!wev->delayed) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
- "client timed out");
- c->timedout = 1;
-
- ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
- return;
- }
-
- wev->timedout = 0;
- wev->delayed = 0;
-
- if (!wev->ready) {
- ngx_add_timer(wev, clcf->send_timeout);
-
- if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
- ngx_http_close_request(r, 0);
- }
-
- return;
- }
-
- }
-
- if (wev->delayed || r->aio) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
- "http writer delayed");
-
- if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
- ngx_http_close_request(r, 0);
- }
-
- return;
- }
-
- rc = ngx_http_output_filter(r, NULL);
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http writer output filter: %d, \"%V?%V\"",
- rc, &r->uri, &r->args);
-
- if (rc == NGX_ERROR) {
- ngx_http_finalize_request(r, rc);
- return;
- }
-
- if (r->buffered || r->postponed || (r == r->main && c->buffered)) {
-
- if (!wev->delayed) {
- ngx_add_timer(wev, clcf->send_timeout);
- }
-
- if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
- ngx_http_close_request(r, 0);
- }
-
- return;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, wev->log, 0,
- "http writer done: \"%V?%V\"", &r->uri, &r->args);
-
- r->write_event_handler = ngx_http_request_empty_handler;
-
- ngx_http_finalize_request(r, rc);
-}
-
-
-static void
-ngx_http_request_finalizer(ngx_http_request_t *r)
-{
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http finalizer done: \"%V?%V\"", &r->uri, &r->args);
-
- ngx_http_finalize_request(r, 0);
-}
-
-
-void
-ngx_http_block_reading(ngx_http_request_t *r)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http reading 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_OK) {
- ngx_http_close_request(r, 0);
- }
- }
-}
-
-
-void
-ngx_http_test_reading(ngx_http_request_t *r)
-{
- int n;
- char buf[1];
- ngx_err_t err;
- ngx_event_t *rev;
- ngx_connection_t *c;
-
- c = r->connection;
- rev = c->read;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http test reading");
-
-#if (NGX_HTTP_SPDY)
-
- if (r->spdy_stream) {
- if (c->error) {
- err = 0;
- goto closed;
- }
-
- return;
- }
-
-#endif
-
-#if (NGX_HAVE_KQUEUE)
-
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
-
- if (!rev->pending_eof) {
- return;
- }
-
- rev->eof = 1;
- c->error = 1;
- err = rev->kq_errno;
-
- goto closed;
- }
-
-#endif
-
-#if (NGX_HAVE_EPOLLRDHUP)
-
- if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) && rev->pending_eof) {
- socklen_t len;
-
- rev->eof = 1;
- c->error = 1;
-
- err = 0;
- len = sizeof(ngx_err_t);
-
- /*
- * BSDs and Linux return 0 and set a pending error in err
- * Solaris returns -1 and sets errno
- */
-
- if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
- == -1)
- {
- err = ngx_socket_errno;
- }
-
- goto closed;
- }
-
-#endif
-
- n = recv(c->fd, buf, 1, MSG_PEEK);
-
- if (n == 0) {
- rev->eof = 1;
- c->error = 1;
- err = 0;
-
- goto closed;
-
- } else if (n == -1) {
- err = ngx_socket_errno;
-
- if (err != NGX_EAGAIN) {
- rev->eof = 1;
- c->error = 1;
-
- goto closed;
- }
- }
-
- /* aio does not call this handler */
-
- if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && rev->active) {
-
- if (ngx_del_event(rev, NGX_READ_EVENT, 0) != NGX_OK) {
- ngx_http_close_request(r, 0);
- }
- }
-
- return;
-
-closed:
-
- if (err) {
- rev->error = 1;
- }
-
- ngx_log_error(NGX_LOG_INFO, c->log, err,
- "client prematurely closed connection");
-
- ngx_http_finalize_request(r, NGX_HTTP_CLIENT_CLOSED_REQUEST);
-}
-
-
-static void
-ngx_http_set_keepalive(ngx_http_request_t *r)
-{
- int tcp_nodelay;
- ngx_int_t i;
- ngx_buf_t *b, *f;
- ngx_event_t *rev, *wev;
- ngx_connection_t *c;
- ngx_http_connection_t *hc;
- ngx_http_core_srv_conf_t *cscf;
- ngx_http_core_loc_conf_t *clcf;
-
- c = r->connection;
- rev = c->read;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "set http keepalive handler");
-
- if (r->discard_body) {
- r->write_event_handler = ngx_http_request_empty_handler;
- r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
- ngx_add_timer(rev, clcf->lingering_timeout);
- return;
- }
-
- c->log->action = "closing request";
-
- hc = r->http_connection;
- b = r->header_in;
-
- if (b->pos < b->last) {
-
- /* the pipelined request */
-
- if (b != c->buffer) {
-
- /*
- * If the large header buffers were allocated while the previous
- * request processing then we do not use c->buffer for
- * the pipelined request (see ngx_http_create_request()).
- *
- * Now we would move the large header buffers to the free list.
- */
-
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
- if (hc->free == NULL) {
- hc->free = ngx_palloc(c->pool,
- cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
-
- if (hc->free == NULL) {
- ngx_http_close_request(r, 0);
- return;
- }
- }
-
- for (i = 0; i < hc->nbusy - 1; i++) {
- f = hc->busy[i];
- hc->free[hc->nfree++] = f;
- f->pos = f->start;
- f->last = f->start;
- }
-
- hc->busy[0] = b;
- hc->nbusy = 1;
- }
- }
-
- /* guard against recursive call from ngx_http_finalize_connection() */
- r->keepalive = 0;
-
- ngx_http_free_request(r, 0);
-
- c->data = hc;
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- ngx_http_close_connection(c);
- return;
- }
-
- wev = c->write;
- wev->handler = ngx_http_empty_handler;
-
- if (b->pos < b->last) {
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request");
-
- c->log->action = "reading client pipelined request line";
-
- r = ngx_http_create_request(c);
- if (r == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- r->pipeline = 1;
-
- c->data = r;
-
- c->sent = 0;
- c->destroyed = 0;
-
- if (rev->timer_set) {
- ngx_del_timer(rev);
- }
-
- rev->handler = ngx_http_process_request_line;
- ngx_post_event(rev, &ngx_posted_events);
- return;
- }
-
- /*
- * To keep a memory footprint as small as possible for an idle keepalive
- * connection we try to free c->buffer's memory if it was allocated outside
- * the c->pool. The large header buffers are always allocated outside the
- * c->pool and are freed too.
- */
-
- b = c->buffer;
-
- if (ngx_pfree(c->pool, b->start) == NGX_OK) {
-
- /*
- * the special note for ngx_http_keepalive_handler() that
- * c->buffer's memory was freed
- */
-
- b->pos = NULL;
-
- } else {
- b->pos = b->start;
- b->last = b->start;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p %d",
- hc->free, hc->nfree);
-
- if (hc->free) {
- for (i = 0; i < hc->nfree; i++) {
- ngx_pfree(c->pool, hc->free[i]->start);
- hc->free[i] = NULL;
- }
-
- hc->nfree = 0;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %d",
- hc->busy, hc->nbusy);
-
- if (hc->busy) {
- for (i = 0; i < hc->nbusy; i++) {
- ngx_pfree(c->pool, hc->busy[i]->start);
- hc->busy[i] = NULL;
- }
-
- hc->nbusy = 0;
- }
-
-#if (NGX_HTTP_SSL)
- if (c->ssl) {
- ngx_ssl_free_buffer(c);
- }
-#endif
-
- rev->handler = ngx_http_keepalive_handler;
-
- if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
- if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
- ngx_http_close_connection(c);
- return;
- }
- }
-
- c->log->action = "keepalive";
-
- if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
- if (ngx_tcp_push(c->fd) == -1) {
- ngx_connection_error(c, ngx_socket_errno, ngx_tcp_push_n " failed");
- ngx_http_close_connection(c);
- return;
- }
-
- c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
- tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
-
- } else {
- tcp_nodelay = 1;
- }
-
- if (tcp_nodelay
- && clcf->tcp_nodelay
- && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
- {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
-
- if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
- (const void *) &tcp_nodelay, sizeof(int))
- == -1)
- {
-#if (NGX_SOLARIS)
- /* Solaris returns EINVAL if a socket has been shut down */
- c->log_error = NGX_ERROR_IGNORE_EINVAL;
-#endif
-
- ngx_connection_error(c, ngx_socket_errno,
- "setsockopt(TCP_NODELAY) failed");
-
- c->log_error = NGX_ERROR_INFO;
- ngx_http_close_connection(c);
- return;
- }
-
- c->tcp_nodelay = NGX_TCP_NODELAY_SET;
- }
-
-#if 0
- /* if ngx_http_request_t was freed then we need some other place */
- r->http_state = NGX_HTTP_KEEPALIVE_STATE;
-#endif
-
- c->idle = 1;
- ngx_reusable_connection(c, 1);
-
- ngx_add_timer(rev, clcf->keepalive_timeout);
-
- if (rev->ready) {
- ngx_post_event(rev, &ngx_posted_events);
- }
-}
-
-
-static void
-ngx_http_keepalive_handler(ngx_event_t *rev)
-{
- size_t size;
- ssize_t n;
- ngx_buf_t *b;
- ngx_connection_t *c;
-
- c = rev->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http keepalive handler");
-
- if (rev->timedout || c->close) {
- ngx_http_close_connection(c);
- return;
- }
-
-#if (NGX_HAVE_KQUEUE)
-
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
- if (rev->pending_eof) {
- c->log->handler = NULL;
- ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
- "kevent() reported that client %V closed "
- "keepalive connection", &c->addr_text);
-#if (NGX_HTTP_SSL)
- if (c->ssl) {
- c->ssl->no_send_shutdown = 1;
- }
-#endif
- ngx_http_close_connection(c);
- return;
- }
- }
-
-#endif
-
- b = c->buffer;
- size = b->end - b->start;
-
- if (b->pos == NULL) {
-
- /*
- * The c->buffer's memory was freed by ngx_http_set_keepalive().
- * However, the c->buffer->start and c->buffer->end were not changed
- * to keep the buffer size.
- */
-
- b->pos = ngx_palloc(c->pool, size);
- if (b->pos == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- b->start = b->pos;
- b->last = b->pos;
- b->end = b->pos + size;
- }
-
- /*
- * MSIE closes a keepalive connection with RST flag
- * so we ignore ECONNRESET here.
- */
-
- c->log_error = NGX_ERROR_IGNORE_ECONNRESET;
- ngx_set_socket_errno(0);
-
- n = c->recv(c, b->last, size);
- c->log_error = NGX_ERROR_INFO;
-
- if (n == NGX_AGAIN) {
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- ngx_http_close_connection(c);
- return;
- }
-
- /*
- * Like ngx_http_set_keepalive() we are trying to not hold
- * c->buffer's memory for a keepalive connection.
- */
-
- if (ngx_pfree(c->pool, b->start) == NGX_OK) {
-
- /*
- * the special note that c->buffer's memory was freed
- */
-
- b->pos = NULL;
- }
-
- return;
- }
-
- if (n == NGX_ERROR) {
- ngx_http_close_connection(c);
- return;
- }
-
- c->log->handler = NULL;
-
- if (n == 0) {
- ngx_log_error(NGX_LOG_INFO, c->log, ngx_socket_errno,
- "client %V closed keepalive connection", &c->addr_text);
- ngx_http_close_connection(c);
- return;
- }
-
- b->last += n;
-
- c->log->handler = ngx_http_log_error;
- c->log->action = "reading client request line";
-
- c->idle = 0;
- ngx_reusable_connection(c, 0);
-
- c->data = ngx_http_create_request(c);
- if (c->data == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- c->sent = 0;
- c->destroyed = 0;
-
- ngx_del_timer(rev);
-
- rev->handler = ngx_http_process_request_line;
- ngx_http_process_request_line(rev);
-}
-
-
-static void
-ngx_http_set_lingering_close(ngx_http_request_t *r)
-{
- ngx_event_t *rev, *wev;
- ngx_connection_t *c;
- ngx_http_core_loc_conf_t *clcf;
-
- c = r->connection;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- rev = c->read;
- rev->handler = ngx_http_lingering_close_handler;
-
- r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
- ngx_add_timer(rev, clcf->lingering_timeout);
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- ngx_http_close_request(r, 0);
- return;
- }
-
- wev = c->write;
- wev->handler = ngx_http_empty_handler;
-
- if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
- if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
- ngx_http_close_request(r, 0);
- return;
- }
- }
-
- if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
- ngx_connection_error(c, ngx_socket_errno,
- ngx_shutdown_socket_n " failed");
- ngx_http_close_request(r, 0);
- return;
- }
-
- if (rev->ready) {
- ngx_http_lingering_close_handler(rev);
- }
-}
-
-
-static void
-ngx_http_lingering_close_handler(ngx_event_t *rev)
-{
- ssize_t n;
- ngx_msec_t timer;
- ngx_connection_t *c;
- ngx_http_request_t *r;
- ngx_http_core_loc_conf_t *clcf;
- u_char buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];
-
- c = rev->data;
- r = c->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http lingering close handler");
-
- if (rev->timedout) {
- ngx_http_close_request(r, 0);
- return;
- }
-
- timer = (ngx_msec_t) r->lingering_time - (ngx_msec_t) ngx_time();
- if ((ngx_msec_int_t) timer <= 0) {
- ngx_http_close_request(r, 0);
- return;
- }
-
- do {
- n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %d", n);
-
- if (n == NGX_ERROR || n == 0) {
- ngx_http_close_request(r, 0);
- return;
- }
-
- } while (rev->ready);
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- ngx_http_close_request(r, 0);
- return;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- timer *= 1000;
-
- if (timer > clcf->lingering_timeout) {
- timer = clcf->lingering_timeout;
- }
-
- ngx_add_timer(rev, timer);
-}
-
-
-void
-ngx_http_empty_handler(ngx_event_t *wev)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http empty handler");
-
- return;
-}
-
-
-void
-ngx_http_request_empty_handler(ngx_http_request_t *r)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http request empty handler");
-
- return;
-}
-
-
-ngx_int_t
-ngx_http_send_special(ngx_http_request_t *r, ngx_uint_t flags)
-{
- ngx_buf_t *b;
- ngx_chain_t out;
-
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- if (flags & NGX_HTTP_LAST) {
-
- if (r == r->main && !r->post_action) {
- b->last_buf = 1;
-
- } else {
- b->sync = 1;
- b->last_in_chain = 1;
- }
- }
-
- if (flags & NGX_HTTP_FLUSH) {
- b->flush = 1;
- }
-
- out.buf = b;
- out.next = NULL;
-
- return ngx_http_output_filter(r, &out);
-}
-
-
-static ngx_int_t
-ngx_http_post_action(ngx_http_request_t *r)
-{
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->post_action.data == NULL) {
- return NGX_DECLINED;
- }
-
- if (r->post_action && r->uri_changes == 0) {
- return NGX_DECLINED;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "post action: \"%V\"", &clcf->post_action);
-
- r->main->count--;
-
- r->http_version = NGX_HTTP_VERSION_9;
- r->header_only = 1;
- r->post_action = 1;
-
- r->read_event_handler = ngx_http_block_reading;
-
- if (clcf->post_action.data[0] == '/') {
- ngx_http_internal_redirect(r, &clcf->post_action, NULL);
-
- } else {
- ngx_http_named_location(r, &clcf->post_action);
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
-{
- ngx_connection_t *c;
-
- r = r->main;
- c = r->connection;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http request count:%d blk:%d", r->count, r->blocked);
-
- if (r->count == 0) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0, "http request count is zero");
- }
-
- r->count--;
-
- if (r->count || r->blocked) {
- return;
- }
-
-#if (NGX_HTTP_SPDY)
- if (r->spdy_stream) {
- ngx_http_spdy_close_stream(r->spdy_stream, rc);
- return;
- }
-#endif
-
- ngx_http_free_request(r, rc);
- ngx_http_close_connection(c);
-}
-
-
-void
-ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
-{
- ngx_log_t *log;
- ngx_pool_t *pool;
- struct linger linger;
- ngx_http_cleanup_t *cln;
- ngx_http_log_ctx_t *ctx;
- ngx_http_core_loc_conf_t *clcf;
-
- log = r->connection->log;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http close request");
-
- if (r->pool == NULL) {
- ngx_log_error(NGX_LOG_ALERT, log, 0, "http request already closed");
- return;
- }
-
- cln = r->cleanup;
- r->cleanup = NULL;
-
- while (cln) {
- if (cln->handler) {
- cln->handler(cln->data);
- }
-
- cln = cln->next;
- }
-
-#if (NGX_STAT_STUB)
-
- if (r->stat_reading) {
- (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
- }
-
- if (r->stat_writing) {
- (void) ngx_atomic_fetch_add(ngx_stat_writing, -1);
- }
-
-#endif
-
- if (rc > 0 && (r->headers_out.status == 0 || r->connection->sent == 0)) {
- r->headers_out.status = rc;
- }
-
- log->action = "logging request";
-
- ngx_http_log_request(r);
-
- log->action = "closing request";
-
- if (r->connection->timedout) {
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->reset_timedout_connection) {
- linger.l_onoff = 1;
- linger.l_linger = 0;
-
- if (setsockopt(r->connection->fd, SOL_SOCKET, SO_LINGER,
- (const void *) &linger, sizeof(struct linger)) == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno,
- "setsockopt(SO_LINGER) failed");
- }
- }
- }
-
- /* the various request strings were allocated from r->pool */
- ctx = log->data;
- ctx->request = NULL;
-
- r->request_line.len = 0;
-
- r->connection->destroyed = 1;
-
- /*
- * Setting r->pool to NULL will increase probability to catch double close
- * of request since the request object is allocated from its own pool.
- */
-
- pool = r->pool;
- r->pool = NULL;
-
- ngx_destroy_pool(pool);
-}
-
-
-static void
-ngx_http_log_request(ngx_http_request_t *r)
-{
- ngx_uint_t i, n;
- ngx_http_handler_pt *log_handler;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
- log_handler = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.elts;
- n = cmcf->phases[NGX_HTTP_LOG_PHASE].handlers.nelts;
-
- for (i = 0; i < n; i++) {
- log_handler[i](r);
- }
-}
-
-
-void
-ngx_http_close_connection(ngx_connection_t *c)
-{
- ngx_pool_t *pool;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "close http connection: %d", c->fd);
-
-#if (NGX_HTTP_SSL)
-
- if (c->ssl) {
- if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
- c->ssl->handler = ngx_http_close_connection;
- return;
- }
- }
-
-#endif
-
-#if (NGX_STAT_STUB)
- (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
-#endif
-
- c->destroyed = 1;
-
- pool = c->pool;
-
- ngx_close_connection(c);
-
- ngx_destroy_pool(pool);
-}
-
-
-static u_char *
-ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len)
-{
- u_char *p;
- ngx_http_request_t *r;
- ngx_http_log_ctx_t *ctx;
-
- if (log->action) {
- p = ngx_snprintf(buf, len, " while %s", log->action);
- len -= p - buf;
- buf = p;
- }
-
- ctx = log->data;
-
- p = ngx_snprintf(buf, len, ", client: %V", &ctx->connection->addr_text);
- len -= p - buf;
-
- r = ctx->request;
-
- if (r) {
- return r->log_handler(r, ctx->current_request, p, len);
-
- } else {
- p = ngx_snprintf(p, len, ", server: %V",
- &ctx->connection->listening->addr_text);
- }
-
- return p;
-}
-
-
-static u_char *
-ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr,
- u_char *buf, size_t len)
-{
- char *uri_separator;
- u_char *p;
- ngx_http_upstream_t *u;
- ngx_http_core_srv_conf_t *cscf;
-
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
- p = ngx_snprintf(buf, len, ", server: %V", &cscf->server_name);
- len -= p - buf;
- buf = p;
-
- 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) {
- p = ngx_snprintf(buf, len, ", subrequest: \"%V\"", &sr->uri);
- len -= p - buf;
- buf = p;
- }
-
- u = sr->upstream;
-
- if (u && u->peer.name) {
-
- uri_separator = "";
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- if (u->peer.sockaddr && u->peer.sockaddr->sa_family == AF_UNIX) {
- uri_separator = ":";
- }
-#endif
-
- p = ngx_snprintf(buf, len, ", upstream: \"%V%V%s%V\"",
- &u->schema, u->peer.name,
- uri_separator, &u->uri);
- len -= p - buf;
- buf = p;
- }
-
- if (r->headers_in.host) {
- p = ngx_snprintf(buf, len, ", host: \"%V\"",
- &r->headers_in.host->value);
- len -= p - buf;
- buf = p;
- }
-
- if (r->headers_in.referer) {
- p = ngx_snprintf(buf, len, ", referrer: \"%V\"",
- &r->headers_in.referer->value);
- buf = p;
- }
-
- return buf;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_request.h b/usr.sbin/nginx/src/http/ngx_http_request.h
deleted file mode 100644
index e4a4944fe44..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_request.h
+++ /dev/null
@@ -1,598 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HTTP_REQUEST_H_INCLUDED_
-#define _NGX_HTTP_REQUEST_H_INCLUDED_
-
-
-#define NGX_HTTP_MAX_URI_CHANGES 10
-#define NGX_HTTP_MAX_SUBREQUESTS 200
-
-/* must be 2^n */
-#define NGX_HTTP_LC_HEADER_LEN 32
-
-
-#define NGX_HTTP_DISCARD_BUFFER_SIZE 4096
-#define NGX_HTTP_LINGERING_BUFFER_SIZE 4096
-
-
-#define NGX_HTTP_VERSION_9 9
-#define NGX_HTTP_VERSION_10 1000
-#define NGX_HTTP_VERSION_11 1001
-
-#define NGX_HTTP_UNKNOWN 0x0001
-#define NGX_HTTP_GET 0x0002
-#define NGX_HTTP_HEAD 0x0004
-#define NGX_HTTP_POST 0x0008
-#define NGX_HTTP_PUT 0x0010
-#define NGX_HTTP_DELETE 0x0020
-#define NGX_HTTP_MKCOL 0x0040
-#define NGX_HTTP_COPY 0x0080
-#define NGX_HTTP_MOVE 0x0100
-#define NGX_HTTP_OPTIONS 0x0200
-#define NGX_HTTP_PROPFIND 0x0400
-#define NGX_HTTP_PROPPATCH 0x0800
-#define NGX_HTTP_LOCK 0x1000
-#define NGX_HTTP_UNLOCK 0x2000
-#define NGX_HTTP_PATCH 0x4000
-#define NGX_HTTP_TRACE 0x8000
-
-#define NGX_HTTP_CONNECTION_CLOSE 1
-#define NGX_HTTP_CONNECTION_KEEP_ALIVE 2
-
-
-#define NGX_NONE 1
-
-
-#define NGX_HTTP_PARSE_HEADER_DONE 1
-
-#define NGX_HTTP_CLIENT_ERROR 10
-#define NGX_HTTP_PARSE_INVALID_METHOD 10
-#define NGX_HTTP_PARSE_INVALID_REQUEST 11
-#define NGX_HTTP_PARSE_INVALID_09_METHOD 12
-
-#define NGX_HTTP_PARSE_INVALID_HEADER 13
-
-
-/* unused 1 */
-#define NGX_HTTP_SUBREQUEST_IN_MEMORY 2
-#define NGX_HTTP_SUBREQUEST_WAITED 4
-#define NGX_HTTP_LOG_UNSAFE 8
-
-
-#define NGX_HTTP_CONTINUE 100
-#define NGX_HTTP_SWITCHING_PROTOCOLS 101
-#define NGX_HTTP_PROCESSING 102
-
-#define NGX_HTTP_OK 200
-#define NGX_HTTP_CREATED 201
-#define NGX_HTTP_ACCEPTED 202
-#define NGX_HTTP_NO_CONTENT 204
-#define NGX_HTTP_PARTIAL_CONTENT 206
-
-#define NGX_HTTP_SPECIAL_RESPONSE 300
-#define NGX_HTTP_MOVED_PERMANENTLY 301
-#define NGX_HTTP_MOVED_TEMPORARILY 302
-#define NGX_HTTP_SEE_OTHER 303
-#define NGX_HTTP_NOT_MODIFIED 304
-#define NGX_HTTP_TEMPORARY_REDIRECT 307
-
-#define NGX_HTTP_BAD_REQUEST 400
-#define NGX_HTTP_UNAUTHORIZED 401
-#define NGX_HTTP_FORBIDDEN 403
-#define NGX_HTTP_NOT_FOUND 404
-#define NGX_HTTP_NOT_ALLOWED 405
-#define NGX_HTTP_REQUEST_TIME_OUT 408
-#define NGX_HTTP_CONFLICT 409
-#define NGX_HTTP_LENGTH_REQUIRED 411
-#define NGX_HTTP_PRECONDITION_FAILED 412
-#define NGX_HTTP_REQUEST_ENTITY_TOO_LARGE 413
-#define NGX_HTTP_REQUEST_URI_TOO_LARGE 414
-#define NGX_HTTP_UNSUPPORTED_MEDIA_TYPE 415
-#define NGX_HTTP_RANGE_NOT_SATISFIABLE 416
-
-
-/* Our own HTTP codes */
-
-/* The special code to close connection without any response */
-#define NGX_HTTP_CLOSE 444
-
-#define NGX_HTTP_NGINX_CODES 494
-
-#define NGX_HTTP_REQUEST_HEADER_TOO_LARGE 494
-
-#define NGX_HTTPS_CERT_ERROR 495
-#define NGX_HTTPS_NO_CERT 496
-
-/*
- * We use the special code for the plain HTTP requests that are sent to
- * HTTPS port to distinguish it from 4XX in an error page redirection
- */
-#define NGX_HTTP_TO_HTTPS 497
-
-/* 498 is the canceled code for the requests with invalid host name */
-
-/*
- * HTTP does not define the code for the case when a client closed
- * the connection while we are processing its request so we introduce
- * own code to log such situation when a client has closed the connection
- * before we even try to send the HTTP header to it
- */
-#define NGX_HTTP_CLIENT_CLOSED_REQUEST 499
-
-
-#define NGX_HTTP_INTERNAL_SERVER_ERROR 500
-#define NGX_HTTP_NOT_IMPLEMENTED 501
-#define NGX_HTTP_BAD_GATEWAY 502
-#define NGX_HTTP_SERVICE_UNAVAILABLE 503
-#define NGX_HTTP_GATEWAY_TIME_OUT 504
-#define NGX_HTTP_INSUFFICIENT_STORAGE 507
-
-
-#define NGX_HTTP_LOWLEVEL_BUFFERED 0xf0
-#define NGX_HTTP_WRITE_BUFFERED 0x10
-#define NGX_HTTP_GZIP_BUFFERED 0x20
-#define NGX_HTTP_SSI_BUFFERED 0x01
-#define NGX_HTTP_SUB_BUFFERED 0x02
-#define NGX_HTTP_COPY_BUFFERED 0x04
-
-
-typedef enum {
- NGX_HTTP_INITING_REQUEST_STATE = 0,
- NGX_HTTP_READING_REQUEST_STATE,
- NGX_HTTP_PROCESS_REQUEST_STATE,
-
- NGX_HTTP_CONNECT_UPSTREAM_STATE,
- NGX_HTTP_WRITING_UPSTREAM_STATE,
- NGX_HTTP_READING_UPSTREAM_STATE,
-
- NGX_HTTP_WRITING_REQUEST_STATE,
- NGX_HTTP_LINGERING_CLOSE_STATE,
- NGX_HTTP_KEEPALIVE_STATE
-} ngx_http_state_e;
-
-
-typedef struct {
- ngx_str_t name;
- ngx_uint_t offset;
- ngx_http_header_handler_pt handler;
-} ngx_http_header_t;
-
-
-typedef struct {
- ngx_str_t name;
- ngx_uint_t offset;
-} ngx_http_header_out_t;
-
-
-typedef struct {
- ngx_list_t headers;
-
- ngx_table_elt_t *host;
- ngx_table_elt_t *connection;
- ngx_table_elt_t *if_modified_since;
- ngx_table_elt_t *if_unmodified_since;
- ngx_table_elt_t *if_match;
- ngx_table_elt_t *if_none_match;
- ngx_table_elt_t *user_agent;
- ngx_table_elt_t *referer;
- ngx_table_elt_t *content_length;
- ngx_table_elt_t *content_type;
-
- ngx_table_elt_t *range;
- ngx_table_elt_t *if_range;
-
- ngx_table_elt_t *transfer_encoding;
- ngx_table_elt_t *expect;
- ngx_table_elt_t *upgrade;
-
-#if (NGX_HTTP_GZIP)
- ngx_table_elt_t *accept_encoding;
- ngx_table_elt_t *via;
-#endif
-
- ngx_table_elt_t *authorization;
-
- ngx_table_elt_t *keep_alive;
-
-#if (NGX_HTTP_X_FORWARDED_FOR)
- ngx_array_t x_forwarded_for;
-#endif
-
-#if (NGX_HTTP_REALIP)
- ngx_table_elt_t *x_real_ip;
-#endif
-
-#if (NGX_HTTP_HEADERS)
- ngx_table_elt_t *accept;
- ngx_table_elt_t *accept_language;
-#endif
-
-#if (NGX_HTTP_DAV)
- ngx_table_elt_t *depth;
- ngx_table_elt_t *destination;
- ngx_table_elt_t *overwrite;
- ngx_table_elt_t *date;
-#endif
-
- ngx_str_t user;
- ngx_str_t passwd;
-
- ngx_array_t cookies;
-
- ngx_str_t server;
- off_t content_length_n;
- time_t keep_alive_n;
-
- unsigned connection_type:2;
- unsigned chunked:1;
- unsigned msie:1;
- unsigned msie6:1;
- unsigned opera:1;
- unsigned gecko:1;
- unsigned chrome:1;
- unsigned safari:1;
- unsigned konqueror:1;
-} ngx_http_headers_in_t;
-
-
-typedef struct {
- ngx_list_t headers;
-
- ngx_uint_t status;
- ngx_str_t status_line;
-
- ngx_table_elt_t *server;
- ngx_table_elt_t *date;
- ngx_table_elt_t *content_length;
- ngx_table_elt_t *content_encoding;
- ngx_table_elt_t *location;
- ngx_table_elt_t *refresh;
- ngx_table_elt_t *last_modified;
- ngx_table_elt_t *content_range;
- ngx_table_elt_t *accept_ranges;
- ngx_table_elt_t *www_authenticate;
- ngx_table_elt_t *expires;
- ngx_table_elt_t *etag;
-
- ngx_str_t *override_charset;
-
- size_t content_type_len;
- ngx_str_t content_type;
- ngx_str_t charset;
- u_char *content_type_lowcase;
- ngx_uint_t content_type_hash;
-
- ngx_array_t cache_control;
-
- off_t content_length_n;
- time_t date_time;
- time_t last_modified_time;
-} ngx_http_headers_out_t;
-
-
-typedef void (*ngx_http_client_body_handler_pt)(ngx_http_request_t *r);
-
-typedef struct {
- ngx_temp_file_t *temp_file;
- ngx_chain_t *bufs;
- ngx_buf_t *buf;
- off_t rest;
- ngx_chain_t *free;
- ngx_chain_t *busy;
- ngx_http_chunked_t *chunked;
- ngx_http_client_body_handler_pt post_handler;
-} ngx_http_request_body_t;
-
-
-typedef struct ngx_http_addr_conf_s ngx_http_addr_conf_t;
-
-typedef struct {
- ngx_http_addr_conf_t *addr_conf;
- ngx_http_conf_ctx_t *conf_ctx;
-
-#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
- ngx_str_t *ssl_servername;
-#if (NGX_PCRE)
- ngx_http_regex_t *ssl_servername_regex;
-#endif
-#endif
-
- ngx_buf_t **busy;
- ngx_int_t nbusy;
-
- ngx_buf_t **free;
- ngx_int_t nfree;
-
-#if (NGX_HTTP_SSL)
- unsigned ssl:1;
-#endif
- unsigned proxy_protocol:1;
-} ngx_http_connection_t;
-
-
-typedef void (*ngx_http_cleanup_pt)(void *data);
-
-typedef struct ngx_http_cleanup_s ngx_http_cleanup_t;
-
-struct ngx_http_cleanup_s {
- ngx_http_cleanup_pt handler;
- void *data;
- ngx_http_cleanup_t *next;
-};
-
-
-typedef ngx_int_t (*ngx_http_post_subrequest_pt)(ngx_http_request_t *r,
- void *data, ngx_int_t rc);
-
-typedef struct {
- ngx_http_post_subrequest_pt handler;
- void *data;
-} ngx_http_post_subrequest_t;
-
-
-typedef struct ngx_http_postponed_request_s ngx_http_postponed_request_t;
-
-struct ngx_http_postponed_request_s {
- ngx_http_request_t *request;
- ngx_chain_t *out;
- ngx_http_postponed_request_t *next;
-};
-
-
-typedef struct ngx_http_posted_request_s ngx_http_posted_request_t;
-
-struct ngx_http_posted_request_s {
- ngx_http_request_t *request;
- ngx_http_posted_request_t *next;
-};
-
-
-typedef ngx_int_t (*ngx_http_handler_pt)(ngx_http_request_t *r);
-typedef void (*ngx_http_event_handler_pt)(ngx_http_request_t *r);
-
-
-struct ngx_http_request_s {
- uint32_t signature; /* "HTTP" */
-
- ngx_connection_t *connection;
-
- void **ctx;
- void **main_conf;
- void **srv_conf;
- void **loc_conf;
-
- ngx_http_event_handler_pt read_event_handler;
- ngx_http_event_handler_pt write_event_handler;
-
-#if (NGX_HTTP_CACHE)
- ngx_http_cache_t *cache;
-#endif
-
- ngx_http_upstream_t *upstream;
- ngx_array_t *upstream_states;
- /* of ngx_http_upstream_state_t */
-
- ngx_pool_t *pool;
- ngx_buf_t *header_in;
-
- ngx_http_headers_in_t headers_in;
- ngx_http_headers_out_t headers_out;
-
- ngx_http_request_body_t *request_body;
-
- time_t lingering_time;
- time_t start_sec;
- ngx_msec_t start_msec;
-
- ngx_uint_t method;
- ngx_uint_t http_version;
-
- ngx_str_t request_line;
- ngx_str_t uri;
- ngx_str_t args;
- ngx_str_t exten;
- ngx_str_t unparsed_uri;
-
- ngx_str_t method_name;
- ngx_str_t http_protocol;
-
- ngx_chain_t *out;
- ngx_http_request_t *main;
- ngx_http_request_t *parent;
- ngx_http_postponed_request_t *postponed;
- ngx_http_post_subrequest_t *post_subrequest;
- ngx_http_posted_request_t *posted_requests;
-
- ngx_int_t phase_handler;
- ngx_http_handler_pt content_handler;
- ngx_uint_t access_code;
-
- ngx_http_variable_value_t *variables;
-
-#if (NGX_PCRE)
- ngx_uint_t ncaptures;
- int *captures;
- u_char *captures_data;
-#endif
-
- size_t limit_rate;
- size_t limit_rate_after;
-
- /* used to learn the Apache compatible response length without a header */
- size_t header_size;
-
- off_t request_length;
-
- ngx_uint_t err_status;
-
- ngx_http_connection_t *http_connection;
-#if (NGX_HTTP_SPDY)
- ngx_http_spdy_stream_t *spdy_stream;
-#endif
-
- ngx_http_log_handler_pt log_handler;
-
- ngx_http_cleanup_t *cleanup;
-
- unsigned subrequests:8;
- unsigned count:8;
- unsigned blocked:8;
-
- unsigned aio:1;
-
- unsigned http_state:4;
-
- /* URI with "/." and on Win32 with "//" */
- unsigned complex_uri:1;
-
- /* URI with "%" */
- unsigned quoted_uri:1;
-
- /* URI with "+" */
- unsigned plus_in_uri:1;
-
- /* URI with " " */
- unsigned space_in_uri:1;
-
- unsigned invalid_header:1;
-
- unsigned add_uri_to_alias:1;
- unsigned valid_location:1;
- unsigned valid_unparsed_uri:1;
- unsigned uri_changed:1;
- unsigned uri_changes:4;
-
- unsigned request_body_in_single_buf:1;
- unsigned request_body_in_file_only:1;
- unsigned request_body_in_persistent_file:1;
- unsigned request_body_in_clean_file:1;
- unsigned request_body_file_group_access:1;
- unsigned request_body_file_log_level:3;
-
- unsigned subrequest_in_memory:1;
- unsigned waited:1;
-
-#if (NGX_HTTP_CACHE)
- unsigned cached:1;
-#endif
-
-#if (NGX_HTTP_GZIP)
- unsigned gzip_tested:1;
- unsigned gzip_ok:1;
- unsigned gzip_vary:1;
-#endif
-
- unsigned proxy:1;
- unsigned bypass_cache:1;
- unsigned no_cache:1;
-
- /*
- * instead of using the request context data in
- * ngx_http_limit_conn_module and ngx_http_limit_req_module
- * we use the single bits in the request structure
- */
- unsigned limit_conn_set:1;
- unsigned limit_req_set:1;
-
-#if 0
- unsigned cacheable:1;
-#endif
-
- unsigned pipeline:1;
- unsigned chunked:1;
- unsigned header_only:1;
- unsigned keepalive:1;
- unsigned lingering_close:1;
- unsigned discard_body:1;
- unsigned internal:1;
- unsigned error_page:1;
- unsigned ignore_content_encoding:1;
- unsigned filter_finalize:1;
- unsigned post_action:1;
- unsigned request_complete:1;
- unsigned request_output:1;
- unsigned header_sent:1;
- unsigned expect_tested:1;
- unsigned root_tested:1;
- unsigned done:1;
- unsigned logged:1;
-
- unsigned buffered:4;
-
- unsigned main_filter_need_in_memory:1;
- unsigned filter_need_in_memory:1;
- unsigned filter_need_temporary:1;
- unsigned allow_ranges:1;
- unsigned single_range:1;
-
-#if (NGX_STAT_STUB)
- unsigned stat_reading:1;
- unsigned stat_writing:1;
-#endif
-
- /* used to parse HTTP headers */
-
- ngx_uint_t state;
-
- ngx_uint_t header_hash;
- ngx_uint_t lowcase_index;
- u_char lowcase_header[NGX_HTTP_LC_HEADER_LEN];
-
- u_char *header_name_start;
- u_char *header_name_end;
- u_char *header_start;
- u_char *header_end;
-
- /*
- * a memory that can be reused after parsing a request line
- * via ngx_http_ephemeral_t
- */
-
- u_char *uri_start;
- u_char *uri_end;
- u_char *uri_ext;
- u_char *args_start;
- u_char *request_start;
- u_char *request_end;
- u_char *method_end;
- u_char *schema_start;
- u_char *schema_end;
- u_char *host_start;
- u_char *host_end;
- u_char *port_start;
- u_char *port_end;
-
- unsigned http_minor:16;
- unsigned http_major:16;
-};
-
-
-typedef struct {
- ngx_http_posted_request_t terminal_posted_request;
-#if (NGX_HAVE_AIO_SENDFILE)
- u_char aio_preload;
-#endif
-} ngx_http_ephemeral_t;
-
-
-extern ngx_http_header_t ngx_http_headers_in[];
-extern ngx_http_header_out_t ngx_http_headers_out[];
-
-
-#define ngx_http_set_connection_log(c, l) \
- \
- c->log->file = l->file; \
- c->log->next = l->next; \
- c->log->writer = l->writer; \
- c->log->wdata = l->wdata; \
- if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { \
- c->log->log_level = l->log_level; \
- }
-
-
-#endif /* _NGX_HTTP_REQUEST_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/ngx_http_request_body.c b/usr.sbin/nginx/src/http/ngx_http_request_body.c
deleted file mode 100644
index bbf16fd2576..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_request_body.c
+++ /dev/null
@@ -1,1099 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static void ngx_http_read_client_request_body_handler(ngx_http_request_t *r);
-static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r);
-static ngx_int_t ngx_http_write_request_body(ngx_http_request_t *r);
-static ngx_int_t ngx_http_read_discarded_request_body(ngx_http_request_t *r);
-static ngx_int_t ngx_http_discard_request_body_filter(ngx_http_request_t *r,
- ngx_buf_t *b);
-static ngx_int_t ngx_http_test_expect(ngx_http_request_t *r);
-
-static ngx_int_t ngx_http_request_body_filter(ngx_http_request_t *r,
- ngx_chain_t *in);
-static ngx_int_t ngx_http_request_body_length_filter(ngx_http_request_t *r,
- ngx_chain_t *in);
-static ngx_int_t ngx_http_request_body_chunked_filter(ngx_http_request_t *r,
- ngx_chain_t *in);
-static ngx_int_t ngx_http_request_body_save_filter(ngx_http_request_t *r,
- ngx_chain_t *in);
-
-
-ngx_int_t
-ngx_http_read_client_request_body(ngx_http_request_t *r,
- ngx_http_client_body_handler_pt post_handler)
-{
- size_t preread;
- ssize_t size;
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t out, *cl;
- ngx_http_request_body_t *rb;
- ngx_http_core_loc_conf_t *clcf;
-
- r->main->count++;
-
-#if (NGX_HTTP_SPDY)
- if (r->spdy_stream && r == r->main) {
- rc = ngx_http_spdy_read_request_body(r, post_handler);
- goto done;
- }
-#endif
-
- if (r != r->main || r->request_body || r->discard_body) {
- post_handler(r);
- return NGX_OK;
- }
-
- if (ngx_http_test_expect(r) != NGX_OK) {
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- goto done;
- }
-
- rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
- if (rb == NULL) {
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- goto done;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * rb->bufs = NULL;
- * rb->buf = NULL;
- * rb->free = NULL;
- * rb->busy = NULL;
- * rb->chunked = NULL;
- */
-
- rb->rest = -1;
- rb->post_handler = post_handler;
-
- r->request_body = rb;
-
- if (r->headers_in.content_length_n < 0 && !r->headers_in.chunked) {
- post_handler(r);
- return NGX_OK;
- }
-
- preread = r->header_in->last - r->header_in->pos;
-
- if (preread) {
-
- /* there is the pre-read part of the request body */
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http client request body preread %uz", preread);
-
- out.buf = r->header_in;
- out.next = NULL;
-
- rc = ngx_http_request_body_filter(r, &out);
-
- if (rc != NGX_OK) {
- goto done;
- }
-
- r->request_length += preread - (r->header_in->last - r->header_in->pos);
-
- if (!r->headers_in.chunked
- && rb->rest > 0
- && rb->rest <= (off_t) (r->header_in->end - r->header_in->last))
- {
- /* the whole request body may be placed in r->header_in */
-
- b = ngx_calloc_buf(r->pool);
- if (b == NULL) {
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- goto done;
- }
-
- b->temporary = 1;
- b->start = r->header_in->pos;
- b->pos = r->header_in->pos;
- b->last = r->header_in->last;
- b->end = r->header_in->end;
-
- rb->buf = b;
-
- r->read_event_handler = ngx_http_read_client_request_body_handler;
- r->write_event_handler = ngx_http_request_empty_handler;
-
- rc = ngx_http_do_read_client_request_body(r);
- goto done;
- }
-
- } else {
- /* set rb->rest */
-
- if (ngx_http_request_body_filter(r, NULL) != NGX_OK) {
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- goto done;
- }
- }
-
- if (rb->rest == 0) {
- /* the whole request body was pre-read */
-
- if (r->request_body_in_file_only) {
- if (ngx_http_write_request_body(r) != NGX_OK) {
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- goto done;
- }
-
- if (rb->temp_file->file.offset != 0) {
-
- cl = ngx_chain_get_free_buf(r->pool, &rb->free);
- if (cl == NULL) {
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- goto done;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->in_file = 1;
- b->file_last = rb->temp_file->file.offset;
- b->file = &rb->temp_file->file;
-
- rb->bufs = cl;
-
- } else {
- rb->bufs = NULL;
- }
- }
-
- post_handler(r);
-
- return NGX_OK;
- }
-
- if (rb->rest < 0) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "negative request body rest");
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- goto done;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- size = clcf->client_body_buffer_size;
- size += size >> 2;
-
- /* TODO: honor r->request_body_in_single_buf */
-
- if (!r->headers_in.chunked && rb->rest < size) {
- size = (ssize_t) rb->rest;
-
- if (r->request_body_in_single_buf) {
- size += preread;
- }
-
- } else {
- size = clcf->client_body_buffer_size;
- }
-
- rb->buf = ngx_create_temp_buf(r->pool, size);
- if (rb->buf == NULL) {
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- goto done;
- }
-
- r->read_event_handler = ngx_http_read_client_request_body_handler;
- r->write_event_handler = ngx_http_request_empty_handler;
-
- rc = ngx_http_do_read_client_request_body(r);
-
-done:
-
- if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
- r->main->count--;
- }
-
- return rc;
-}
-
-
-static void
-ngx_http_read_client_request_body_handler(ngx_http_request_t *r)
-{
- ngx_int_t rc;
-
- if (r->connection->read->timedout) {
- r->connection->timedout = 1;
- ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
- return;
- }
-
- rc = ngx_http_do_read_client_request_body(r);
-
- if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
- ngx_http_finalize_request(r, rc);
- }
-}
-
-
-static ngx_int_t
-ngx_http_do_read_client_request_body(ngx_http_request_t *r)
-{
- off_t rest;
- size_t size;
- ssize_t n;
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t *cl, out;
- ngx_connection_t *c;
- ngx_http_request_body_t *rb;
- ngx_http_core_loc_conf_t *clcf;
-
- c = r->connection;
- rb = r->request_body;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http read client request body");
-
- for ( ;; ) {
- for ( ;; ) {
- if (rb->buf->last == rb->buf->end) {
-
- /* pass buffer to request body filter chain */
-
- out.buf = rb->buf;
- out.next = NULL;
-
- rc = ngx_http_request_body_filter(r, &out);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- /* write to file */
-
- if (ngx_http_write_request_body(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- /* update chains */
-
- rc = ngx_http_request_body_filter(r, NULL);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- if (rb->busy != NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- rb->buf->pos = rb->buf->start;
- rb->buf->last = rb->buf->start;
- }
-
- size = rb->buf->end - rb->buf->last;
- rest = rb->rest - (rb->buf->last - rb->buf->pos);
-
- if ((off_t) size > rest) {
- size = (size_t) rest;
- }
-
- n = c->recv(c, rb->buf->last, size);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http client request body recv %z", n);
-
- if (n == NGX_AGAIN) {
- break;
- }
-
- if (n == 0) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client prematurely closed connection");
- }
-
- if (n == 0 || n == NGX_ERROR) {
- c->error = 1;
- return NGX_HTTP_BAD_REQUEST;
- }
-
- rb->buf->last += n;
- r->request_length += n;
-
- if (n == rest) {
- /* pass buffer to request body filter chain */
-
- out.buf = rb->buf;
- out.next = NULL;
-
- rc = ngx_http_request_body_filter(r, &out);
-
- if (rc != NGX_OK) {
- return rc;
- }
- }
-
- if (rb->rest == 0) {
- break;
- }
-
- if (rb->buf->last < rb->buf->end) {
- break;
- }
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http client request body rest %O", rb->rest);
-
- if (rb->rest == 0) {
- break;
- }
-
- if (!c->read->ready) {
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- ngx_add_timer(c->read, clcf->client_body_timeout);
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- return NGX_AGAIN;
- }
- }
-
- if (c->read->timer_set) {
- ngx_del_timer(c->read);
- }
-
- if (rb->temp_file || r->request_body_in_file_only) {
-
- /* save the last part */
-
- if (ngx_http_write_request_body(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (rb->temp_file->file.offset != 0) {
-
- cl = ngx_chain_get_free_buf(r->pool, &rb->free);
- if (cl == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- b = cl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->in_file = 1;
- b->file_last = rb->temp_file->file.offset;
- b->file = &rb->temp_file->file;
-
- rb->bufs = cl;
-
- } else {
- rb->bufs = NULL;
- }
- }
-
- r->read_event_handler = ngx_http_block_reading;
-
- rb->post_handler(r);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_write_request_body(ngx_http_request_t *r)
-{
- ssize_t n;
- ngx_chain_t *cl;
- ngx_temp_file_t *tf;
- ngx_http_request_body_t *rb;
- ngx_http_core_loc_conf_t *clcf;
-
- rb = r->request_body;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http write client request body, bufs %p", rb->bufs);
-
- if (rb->temp_file == NULL) {
- tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
- if (tf == NULL) {
- return NGX_ERROR;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- tf->file.fd = NGX_INVALID_FILE;
- tf->file.log = r->connection->log;
- tf->path = clcf->client_body_temp_path;
- tf->pool = r->pool;
- tf->warn = "a client request body is buffered to a temporary file";
- tf->log_level = r->request_body_file_log_level;
- tf->persistent = r->request_body_in_persistent_file;
- tf->clean = r->request_body_in_clean_file;
-
- if (r->request_body_file_group_access) {
- tf->access = 0660;
- }
-
- rb->temp_file = tf;
-
- if (rb->bufs == NULL) {
- /* empty body with r->request_body_in_file_only */
-
- if (ngx_create_temp_file(&tf->file, tf->path, tf->pool,
- tf->persistent, tf->clean, tf->access)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- return NGX_OK;
- }
- }
-
- if (rb->bufs == NULL) {
- return NGX_OK;
- }
-
- n = ngx_write_chain_to_temp_file(rb->temp_file, rb->bufs);
-
- /* TODO: n == 0 or not complete and level event */
-
- if (n == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- rb->temp_file->offset += n;
-
- /* mark all buffers as written */
-
- for (cl = rb->bufs; cl; cl = cl->next) {
- cl->buf->pos = cl->buf->last;
- }
-
- rb->bufs = NULL;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_discard_request_body(ngx_http_request_t *r)
-{
- ssize_t size;
- ngx_int_t rc;
- ngx_event_t *rev;
-
-#if (NGX_HTTP_SPDY)
- if (r->spdy_stream && r == r->main) {
- r->spdy_stream->skip_data = NGX_SPDY_DATA_DISCARD;
- return NGX_OK;
- }
-#endif
-
- if (r != r->main || r->discard_body || r->request_body) {
- return NGX_OK;
- }
-
- if (ngx_http_test_expect(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- rev = r->connection->read;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http set discard body");
-
- if (rev->timer_set) {
- ngx_del_timer(rev);
- }
-
- if (r->headers_in.content_length_n <= 0 && !r->headers_in.chunked) {
- return NGX_OK;
- }
-
- size = r->header_in->last - r->header_in->pos;
-
- if (size || r->headers_in.chunked) {
- rc = ngx_http_discard_request_body_filter(r, r->header_in);
-
- if (rc != NGX_OK) {
- return rc;
- }
-
- if (r->headers_in.content_length_n == 0) {
- return NGX_OK;
- }
- }
-
- rc = ngx_http_read_discarded_request_body(r);
-
- if (rc == NGX_OK) {
- r->lingering_close = 0;
- return NGX_OK;
- }
-
- if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
- return rc;
- }
-
- /* rc == NGX_AGAIN */
-
- r->read_event_handler = ngx_http_discarded_request_body_handler;
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- r->count++;
- r->discard_body = 1;
-
- return NGX_OK;
-}
-
-
-void
-ngx_http_discarded_request_body_handler(ngx_http_request_t *r)
-{
- ngx_int_t rc;
- ngx_msec_t timer;
- ngx_event_t *rev;
- ngx_connection_t *c;
- ngx_http_core_loc_conf_t *clcf;
-
- c = r->connection;
- rev = c->read;
-
- if (rev->timedout) {
- c->timedout = 1;
- c->error = 1;
- ngx_http_finalize_request(r, NGX_ERROR);
- return;
- }
-
- if (r->lingering_time) {
- timer = (ngx_msec_t) r->lingering_time - (ngx_msec_t) ngx_time();
-
- if ((ngx_msec_int_t) timer <= 0) {
- r->discard_body = 0;
- r->lingering_close = 0;
- ngx_http_finalize_request(r, NGX_ERROR);
- return;
- }
-
- } else {
- timer = 0;
- }
-
- rc = ngx_http_read_discarded_request_body(r);
-
- if (rc == NGX_OK) {
- r->discard_body = 0;
- r->lingering_close = 0;
- ngx_http_finalize_request(r, NGX_DONE);
- return;
- }
-
- if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
- c->error = 1;
- ngx_http_finalize_request(r, NGX_ERROR);
- return;
- }
-
- /* rc == NGX_AGAIN */
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- c->error = 1;
- ngx_http_finalize_request(r, NGX_ERROR);
- return;
- }
-
- if (timer) {
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- timer *= 1000;
-
- if (timer > clcf->lingering_timeout) {
- timer = clcf->lingering_timeout;
- }
-
- ngx_add_timer(rev, timer);
- }
-}
-
-
-static ngx_int_t
-ngx_http_read_discarded_request_body(ngx_http_request_t *r)
-{
- size_t size;
- ssize_t n;
- ngx_int_t rc;
- ngx_buf_t b;
- u_char buffer[NGX_HTTP_DISCARD_BUFFER_SIZE];
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http read discarded body");
-
- ngx_memzero(&b, sizeof(ngx_buf_t));
-
- b.temporary = 1;
-
- for ( ;; ) {
- if (r->headers_in.content_length_n == 0) {
- r->read_event_handler = ngx_http_block_reading;
- return NGX_OK;
- }
-
- if (!r->connection->read->ready) {
- return NGX_AGAIN;
- }
-
- size = (size_t) ngx_min(r->headers_in.content_length_n,
- NGX_HTTP_DISCARD_BUFFER_SIZE);
-
- n = r->connection->recv(r->connection, buffer, size);
-
- if (n == NGX_ERROR) {
- r->connection->error = 1;
- return NGX_OK;
- }
-
- if (n == NGX_AGAIN) {
- return NGX_AGAIN;
- }
-
- if (n == 0) {
- return NGX_OK;
- }
-
- b.pos = buffer;
- b.last = buffer + n;
-
- rc = ngx_http_discard_request_body_filter(r, &b);
-
- if (rc != NGX_OK) {
- return rc;
- }
- }
-}
-
-
-static ngx_int_t
-ngx_http_discard_request_body_filter(ngx_http_request_t *r, ngx_buf_t *b)
-{
- size_t size;
- ngx_int_t rc;
- ngx_http_request_body_t *rb;
-
- if (r->headers_in.chunked) {
-
- rb = r->request_body;
-
- if (rb == NULL) {
-
- rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
- if (rb == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- rb->chunked = ngx_pcalloc(r->pool, sizeof(ngx_http_chunked_t));
- if (rb->chunked == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- r->request_body = rb;
- }
-
- for ( ;; ) {
-
- rc = ngx_http_parse_chunked(r, b, rb->chunked);
-
- if (rc == NGX_OK) {
-
- /* a chunk has been parsed successfully */
-
- size = b->last - b->pos;
-
- if ((off_t) size > rb->chunked->size) {
- b->pos += (size_t) rb->chunked->size;
- rb->chunked->size = 0;
-
- } else {
- rb->chunked->size -= size;
- b->pos = b->last;
- }
-
- continue;
- }
-
- if (rc == NGX_DONE) {
-
- /* a whole response has been parsed successfully */
-
- r->headers_in.content_length_n = 0;
- break;
- }
-
- if (rc == NGX_AGAIN) {
-
- /* set amount of data we want to see next time */
-
- r->headers_in.content_length_n = rb->chunked->length;
- break;
- }
-
- /* invalid */
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client sent invalid chunked body");
-
- return NGX_HTTP_BAD_REQUEST;
- }
-
- } else {
- size = b->last - b->pos;
-
- if ((off_t) size > r->headers_in.content_length_n) {
- b->pos += (size_t) r->headers_in.content_length_n;
- r->headers_in.content_length_n = 0;
-
- } else {
- b->pos = b->last;
- r->headers_in.content_length_n -= size;
- }
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_test_expect(ngx_http_request_t *r)
-{
- ngx_int_t n;
- ngx_str_t *expect;
-
- if (r->expect_tested
- || r->headers_in.expect == NULL
- || r->http_version < NGX_HTTP_VERSION_11)
- {
- return NGX_OK;
- }
-
- r->expect_tested = 1;
-
- expect = &r->headers_in.expect->value;
-
- if (expect->len != sizeof("100-continue") - 1
- || ngx_strncasecmp(expect->data, (u_char *) "100-continue",
- sizeof("100-continue") - 1)
- != 0)
- {
- return NGX_OK;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "send 100 Continue");
-
- n = r->connection->send(r->connection,
- (u_char *) "HTTP/1.1 100 Continue" CRLF CRLF,
- sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1);
-
- if (n == sizeof("HTTP/1.1 100 Continue" CRLF CRLF) - 1) {
- return NGX_OK;
- }
-
- /* we assume that such small packet should be send successfully */
-
- return NGX_ERROR;
-}
-
-
-static ngx_int_t
-ngx_http_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- if (r->headers_in.chunked) {
- return ngx_http_request_body_chunked_filter(r, in);
-
- } else {
- return ngx_http_request_body_length_filter(r, in);
- }
-}
-
-
-static ngx_int_t
-ngx_http_request_body_length_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- size_t size;
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t *cl, *tl, *out, **ll;
- ngx_http_request_body_t *rb;
-
- rb = r->request_body;
-
- if (rb->rest == -1) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http request body content length filter");
-
- rb->rest = r->headers_in.content_length_n;
- }
-
- out = NULL;
- ll = &out;
-
- for (cl = in; cl; cl = cl->next) {
-
- if (rb->rest == 0) {
- break;
- }
-
- tl = ngx_chain_get_free_buf(r->pool, &rb->free);
- if (tl == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- b = tl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->temporary = 1;
- b->tag = (ngx_buf_tag_t) &ngx_http_read_client_request_body;
- b->start = cl->buf->pos;
- b->pos = cl->buf->pos;
- b->last = cl->buf->last;
- b->end = cl->buf->end;
-
- size = cl->buf->last - cl->buf->pos;
-
- if ((off_t) size < rb->rest) {
- cl->buf->pos = cl->buf->last;
- rb->rest -= size;
-
- } else {
- cl->buf->pos += (size_t) rb->rest;
- rb->rest = 0;
- b->last = cl->buf->pos;
- b->last_buf = 1;
- }
-
- *ll = tl;
- ll = &tl->next;
- }
-
- rc = ngx_http_request_body_save_filter(r, out);
-
- ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out,
- (ngx_buf_tag_t) &ngx_http_read_client_request_body);
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- size_t size;
- ngx_int_t rc;
- ngx_buf_t *b;
- ngx_chain_t *cl, *out, *tl, **ll;
- ngx_http_request_body_t *rb;
- ngx_http_core_loc_conf_t *clcf;
-
- rb = r->request_body;
-
- if (rb->rest == -1) {
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http request body chunked filter");
-
- rb->chunked = ngx_pcalloc(r->pool, sizeof(ngx_http_chunked_t));
- if (rb->chunked == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- r->headers_in.content_length_n = 0;
- rb->rest = 3;
- }
-
- out = NULL;
- ll = &out;
-
- for (cl = in; cl; cl = cl->next) {
-
- for ( ;; ) {
-
- ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
- "http body chunked buf "
- "t:%d f:%d %p, pos %p, size: %z file: %O, size: %z",
- cl->buf->temporary, cl->buf->in_file,
- cl->buf->start, cl->buf->pos,
- cl->buf->last - cl->buf->pos,
- cl->buf->file_pos,
- cl->buf->file_last - cl->buf->file_pos);
-
- rc = ngx_http_parse_chunked(r, cl->buf, rb->chunked);
-
- if (rc == NGX_OK) {
-
- /* a chunk has been parsed successfully */
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->client_max_body_size
- && clcf->client_max_body_size
- - r->headers_in.content_length_n < rb->chunked->size)
- {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client intended to send too large chunked "
- "body: %O+%O bytes",
- r->headers_in.content_length_n,
- rb->chunked->size);
-
- r->lingering_close = 1;
-
- return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
- }
-
- tl = ngx_chain_get_free_buf(r->pool, &rb->free);
- if (tl == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- b = tl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->temporary = 1;
- b->tag = (ngx_buf_tag_t) &ngx_http_read_client_request_body;
- b->start = cl->buf->pos;
- b->pos = cl->buf->pos;
- b->last = cl->buf->last;
- b->end = cl->buf->end;
-
- *ll = tl;
- ll = &tl->next;
-
- size = cl->buf->last - cl->buf->pos;
-
- if ((off_t) size > rb->chunked->size) {
- cl->buf->pos += (size_t) rb->chunked->size;
- r->headers_in.content_length_n += rb->chunked->size;
- rb->chunked->size = 0;
-
- } else {
- rb->chunked->size -= size;
- r->headers_in.content_length_n += size;
- cl->buf->pos = cl->buf->last;
- }
-
- b->last = cl->buf->pos;
-
- continue;
- }
-
- if (rc == NGX_DONE) {
-
- /* a whole response has been parsed successfully */
-
- rb->rest = 0;
-
- tl = ngx_chain_get_free_buf(r->pool, &rb->free);
- if (tl == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- b = tl->buf;
-
- ngx_memzero(b, sizeof(ngx_buf_t));
-
- b->last_buf = 1;
-
- *ll = tl;
- ll = &tl->next;
-
- break;
- }
-
- if (rc == NGX_AGAIN) {
-
- /* set rb->rest, amount of data we want to see next time */
-
- rb->rest = rb->chunked->length;
-
- break;
- }
-
- /* invalid */
-
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client sent invalid chunked body");
-
- return NGX_HTTP_BAD_REQUEST;
- }
- }
-
- rc = ngx_http_request_body_save_filter(r, out);
-
- ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out,
- (ngx_buf_tag_t) &ngx_http_read_client_request_body);
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
-#if (NGX_DEBUG)
- ngx_chain_t *cl;
-#endif
- ngx_http_request_body_t *rb;
-
- rb = r->request_body;
-
-#if (NGX_DEBUG)
-
- for (cl = rb->bufs; cl; cl = cl->next) {
- ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
- "http body old buf t:%d f:%d %p, pos %p, size: %z "
- "file: %O, size: %z",
- cl->buf->temporary, cl->buf->in_file,
- cl->buf->start, cl->buf->pos,
- cl->buf->last - cl->buf->pos,
- cl->buf->file_pos,
- cl->buf->file_last - cl->buf->file_pos);
- }
-
- for (cl = in; cl; cl = cl->next) {
- ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
- "http body new buf t:%d f:%d %p, pos %p, size: %z "
- "file: %O, size: %z",
- cl->buf->temporary, cl->buf->in_file,
- cl->buf->start, cl->buf->pos,
- cl->buf->last - cl->buf->pos,
- cl->buf->file_pos,
- cl->buf->file_last - cl->buf->file_pos);
- }
-
-#endif
-
- /* TODO: coalesce neighbouring buffers */
-
- if (ngx_chain_add_copy(r->pool, &rb->bufs, in) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_script.c b/usr.sbin/nginx/src/http/ngx_http_script.c
deleted file mode 100644
index 02e2be3bb80..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_script.c
+++ /dev/null
@@ -1,1754 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static ngx_int_t ngx_http_script_init_arrays(ngx_http_script_compile_t *sc);
-static ngx_int_t ngx_http_script_done(ngx_http_script_compile_t *sc);
-static ngx_int_t ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc,
- ngx_str_t *value, ngx_uint_t last);
-static ngx_int_t ngx_http_script_add_var_code(ngx_http_script_compile_t *sc,
- ngx_str_t *name);
-static ngx_int_t ngx_http_script_add_args_code(ngx_http_script_compile_t *sc);
-#if (NGX_PCRE)
-static ngx_int_t ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc,
- ngx_uint_t n);
-#endif
-static ngx_int_t
- ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc);
-static size_t ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e);
-static void ngx_http_script_full_name_code(ngx_http_script_engine_t *e);
-
-
-#define ngx_http_script_exit (u_char *) &ngx_http_script_exit_code
-
-static uintptr_t ngx_http_script_exit_code = (uintptr_t) NULL;
-
-
-void
-ngx_http_script_flush_complex_value(ngx_http_request_t *r,
- ngx_http_complex_value_t *val)
-{
- ngx_uint_t *index;
-
- index = val->flushes;
-
- if (index) {
- while (*index != (ngx_uint_t) -1) {
-
- if (r->variables[*index].no_cacheable) {
- r->variables[*index].valid = 0;
- r->variables[*index].not_found = 0;
- }
-
- index++;
- }
- }
-}
-
-
-ngx_int_t
-ngx_http_complex_value(ngx_http_request_t *r, ngx_http_complex_value_t *val,
- ngx_str_t *value)
-{
- size_t len;
- ngx_http_script_code_pt code;
- ngx_http_script_len_code_pt lcode;
- ngx_http_script_engine_t e;
-
- if (val->lengths == NULL) {
- *value = val->value;
- return NGX_OK;
- }
-
- ngx_http_script_flush_complex_value(r, val);
-
- ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
-
- e.ip = val->lengths;
- e.request = r;
- e.flushed = 1;
-
- len = 0;
-
- while (*(uintptr_t *) e.ip) {
- lcode = *(ngx_http_script_len_code_pt *) e.ip;
- len += lcode(&e);
- }
-
- value->len = len;
- value->data = ngx_pnalloc(r->pool, len);
- if (value->data == NULL) {
- return NGX_ERROR;
- }
-
- e.ip = val->values;
- e.pos = value->data;
- e.buf = *value;
-
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
- }
-
- *value = e.buf;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv)
-{
- ngx_str_t *v;
- ngx_uint_t i, n, nv, nc;
- ngx_array_t flushes, lengths, values, *pf, *pl, *pv;
- ngx_http_script_compile_t sc;
-
- v = ccv->value;
-
- nv = 0;
- nc = 0;
-
- for (i = 0; i < v->len; i++) {
- if (v->data[i] == '$') {
- if (v->data[i + 1] >= '1' && v->data[i + 1] <= '9') {
- nc++;
-
- } else {
- nv++;
- }
- }
- }
-
- if ((v->len == 0 || v->data[0] != '$')
- && (ccv->conf_prefix || ccv->root_prefix))
- {
- if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) {
- return NGX_ERROR;
- }
-
- ccv->conf_prefix = 0;
- ccv->root_prefix = 0;
- }
-
- ccv->complex_value->value = *v;
- ccv->complex_value->flushes = NULL;
- ccv->complex_value->lengths = NULL;
- ccv->complex_value->values = NULL;
-
- if (nv == 0 && nc == 0) {
- return NGX_OK;
- }
-
- n = nv + 1;
-
- if (ngx_array_init(&flushes, ccv->cf->pool, n, sizeof(ngx_uint_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- n = nv * (2 * sizeof(ngx_http_script_copy_code_t)
- + sizeof(ngx_http_script_var_code_t))
- + sizeof(uintptr_t);
-
- if (ngx_array_init(&lengths, ccv->cf->pool, n, 1) != NGX_OK) {
- return NGX_ERROR;
- }
-
- n = (nv * (2 * sizeof(ngx_http_script_copy_code_t)
- + sizeof(ngx_http_script_var_code_t))
- + sizeof(uintptr_t)
- + v->len
- + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
-
- if (ngx_array_init(&values, ccv->cf->pool, n, 1) != NGX_OK) {
- return NGX_ERROR;
- }
-
- pf = &flushes;
- pl = &lengths;
- pv = &values;
-
- ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
-
- sc.cf = ccv->cf;
- sc.source = v;
- sc.flushes = &pf;
- sc.lengths = &pl;
- sc.values = &pv;
- sc.complete_lengths = 1;
- sc.complete_values = 1;
- sc.zero = ccv->zero;
- sc.conf_prefix = ccv->conf_prefix;
- sc.root_prefix = ccv->root_prefix;
-
- if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (flushes.nelts) {
- ccv->complex_value->flushes = flushes.elts;
- ccv->complex_value->flushes[flushes.nelts] = (ngx_uint_t) -1;
- }
-
- ccv->complex_value->lengths = lengths.elts;
- ccv->complex_value->values = values.elts;
-
- return NGX_OK;
-}
-
-
-char *
-ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_str_t *value;
- ngx_http_complex_value_t **cv;
- ngx_http_compile_complex_value_t ccv;
-
- cv = (ngx_http_complex_value_t **) (p + cmd->offset);
-
- if (*cv != NULL) {
- return "duplicate";
- }
-
- *cv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (*cv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = *cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-ngx_int_t
-ngx_http_test_predicates(ngx_http_request_t *r, ngx_array_t *predicates)
-{
- ngx_str_t val;
- ngx_uint_t i;
- ngx_http_complex_value_t *cv;
-
- if (predicates == NULL) {
- return NGX_OK;
- }
-
- cv = predicates->elts;
-
- for (i = 0; i < predicates->nelts; i++) {
- if (ngx_http_complex_value(r, &cv[i], &val) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (val.len && (val.len != 1 || val.data[0] != '0')) {
- return NGX_DECLINED;
- }
- }
-
- return NGX_OK;
-}
-
-
-char *
-ngx_http_set_predicate_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_str_t *value;
- ngx_uint_t i;
- ngx_array_t **a;
- ngx_http_complex_value_t *cv;
- ngx_http_compile_complex_value_t ccv;
-
- a = (ngx_array_t **) (p + cmd->offset);
-
- if (*a == NGX_CONF_UNSET_PTR) {
- *a = ngx_array_create(cf->pool, 1, sizeof(ngx_http_complex_value_t));
- if (*a == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
- cv = ngx_array_push(*a);
- if (cv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[i];
- ccv.complex_value = cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- return NGX_CONF_OK;
-}
-
-
-ngx_uint_t
-ngx_http_script_variables_count(ngx_str_t *value)
-{
- ngx_uint_t i, n;
-
- for (n = 0, i = 0; i < value->len; i++) {
- if (value->data[i] == '$') {
- n++;
- }
- }
-
- return n;
-}
-
-
-ngx_int_t
-ngx_http_script_compile(ngx_http_script_compile_t *sc)
-{
- u_char ch;
- ngx_str_t name;
- ngx_uint_t i, bracket;
-
- if (ngx_http_script_init_arrays(sc) != NGX_OK) {
- return NGX_ERROR;
- }
-
- for (i = 0; i < sc->source->len; /* void */ ) {
-
- name.len = 0;
-
- if (sc->source->data[i] == '$') {
-
- if (++i == sc->source->len) {
- goto invalid_variable;
- }
-
-#if (NGX_PCRE)
- {
- ngx_uint_t n;
-
- if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {
-
- n = sc->source->data[i] - '0';
-
- if (sc->captures_mask & (1 << n)) {
- sc->dup_capture = 1;
- }
-
- sc->captures_mask |= 1 << n;
-
- if (ngx_http_script_add_capture_code(sc, n) != NGX_OK) {
- return NGX_ERROR;
- }
-
- i++;
-
- continue;
- }
- }
-#endif
-
- if (sc->source->data[i] == '{') {
- bracket = 1;
-
- if (++i == sc->source->len) {
- goto invalid_variable;
- }
-
- name.data = &sc->source->data[i];
-
- } else {
- bracket = 0;
- name.data = &sc->source->data[i];
- }
-
- for ( /* void */ ; i < sc->source->len; i++, name.len++) {
- ch = sc->source->data[i];
-
- if (ch == '}' && bracket) {
- i++;
- bracket = 0;
- break;
- }
-
- if ((ch >= 'A' && ch <= 'Z')
- || (ch >= 'a' && ch <= 'z')
- || (ch >= '0' && ch <= '9')
- || ch == '_')
- {
- continue;
- }
-
- break;
- }
-
- if (bracket) {
- ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0,
- "the closing bracket in \"%V\" "
- "variable is missing", &name);
- return NGX_ERROR;
- }
-
- if (name.len == 0) {
- goto invalid_variable;
- }
-
- sc->variables++;
-
- if (ngx_http_script_add_var_code(sc, &name) != NGX_OK) {
- return NGX_ERROR;
- }
-
- continue;
- }
-
- if (sc->source->data[i] == '?' && sc->compile_args) {
- sc->args = 1;
- sc->compile_args = 0;
-
- if (ngx_http_script_add_args_code(sc) != NGX_OK) {
- return NGX_ERROR;
- }
-
- i++;
-
- continue;
- }
-
- name.data = &sc->source->data[i];
-
- while (i < sc->source->len) {
-
- if (sc->source->data[i] == '$') {
- break;
- }
-
- if (sc->source->data[i] == '?') {
-
- sc->args = 1;
-
- if (sc->compile_args) {
- break;
- }
- }
-
- i++;
- name.len++;
- }
-
- sc->size += name.len;
-
- if (ngx_http_script_add_copy_code(sc, &name, (i == sc->source->len))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
- }
-
- return ngx_http_script_done(sc);
-
-invalid_variable:
-
- ngx_conf_log_error(NGX_LOG_EMERG, sc->cf, 0, "invalid variable name");
-
- return NGX_ERROR;
-}
-
-
-u_char *
-ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
- void *code_lengths, size_t len, void *code_values)
-{
- ngx_uint_t i;
- ngx_http_script_code_pt code;
- ngx_http_script_len_code_pt lcode;
- ngx_http_script_engine_t e;
- ngx_http_core_main_conf_t *cmcf;
-
- 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_cacheable) {
- r->variables[i].valid = 0;
- r->variables[i].not_found = 0;
- }
- }
-
- ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
-
- e.ip = code_lengths;
- e.request = r;
- e.flushed = 1;
-
- while (*(uintptr_t *) e.ip) {
- lcode = *(ngx_http_script_len_code_pt *) e.ip;
- len += lcode(&e);
- }
-
-
- value->len = len;
- value->data = ngx_pnalloc(r->pool, len);
- if (value->data == NULL) {
- return NULL;
- }
-
- e.ip = code_values;
- e.pos = value->data;
-
- while (*(uintptr_t *) e.ip) {
- code = *(ngx_http_script_code_pt *) e.ip;
- code((ngx_http_script_engine_t *) &e);
- }
-
- return e.pos;
-}
-
-
-void
-ngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r,
- ngx_array_t *indices)
-{
- ngx_uint_t n, *index;
-
- if (indices) {
- index = indices->elts;
- for (n = 0; n < indices->nelts; n++) {
- if (r->variables[index[n]].no_cacheable) {
- r->variables[index[n]].valid = 0;
- r->variables[index[n]].not_found = 0;
- }
- }
- }
-}
-
-
-static ngx_int_t
-ngx_http_script_init_arrays(ngx_http_script_compile_t *sc)
-{
- ngx_uint_t n;
-
- if (sc->flushes && *sc->flushes == NULL) {
- n = sc->variables ? sc->variables : 1;
- *sc->flushes = ngx_array_create(sc->cf->pool, n, sizeof(ngx_uint_t));
- if (*sc->flushes == NULL) {
- return NGX_ERROR;
- }
- }
-
- if (*sc->lengths == NULL) {
- n = sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
- + sizeof(ngx_http_script_var_code_t))
- + sizeof(uintptr_t);
-
- *sc->lengths = ngx_array_create(sc->cf->pool, n, 1);
- if (*sc->lengths == NULL) {
- return NGX_ERROR;
- }
- }
-
- if (*sc->values == NULL) {
- n = (sc->variables * (2 * sizeof(ngx_http_script_copy_code_t)
- + sizeof(ngx_http_script_var_code_t))
- + sizeof(uintptr_t)
- + sc->source->len
- + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
-
- *sc->values = ngx_array_create(sc->cf->pool, n, 1);
- if (*sc->values == NULL) {
- return NGX_ERROR;
- }
- }
-
- sc->variables = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_script_done(ngx_http_script_compile_t *sc)
-{
- ngx_str_t zero;
- uintptr_t *code;
-
- if (sc->zero) {
-
- zero.len = 1;
- zero.data = (u_char *) "\0";
-
- if (ngx_http_script_add_copy_code(sc, &zero, 0) != NGX_OK) {
- return NGX_ERROR;
- }
- }
-
- if (sc->conf_prefix || sc->root_prefix) {
- if (ngx_http_script_add_full_name_code(sc) != NGX_OK) {
- return NGX_ERROR;
- }
- }
-
- if (sc->complete_lengths) {
- code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
- }
-
- if (sc->complete_values) {
- code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t),
- &sc->main);
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) NULL;
- }
-
- return NGX_OK;
-}
-
-
-void *
-ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size)
-{
- if (*codes == NULL) {
- *codes = ngx_array_create(pool, 256, 1);
- if (*codes == NULL) {
- return NULL;
- }
- }
-
- return ngx_array_push_n(*codes, size);
-}
-
-
-void *
-ngx_http_script_add_code(ngx_array_t *codes, size_t size, void *code)
-{
- u_char *elts, **p;
- void *new;
-
- elts = codes->elts;
-
- new = ngx_array_push_n(codes, size);
- if (new == NULL) {
- return NULL;
- }
-
- if (code) {
- if (elts != codes->elts) {
- p = code;
- *p += (u_char *) codes->elts - elts;
- }
- }
-
- return new;
-}
-
-
-static ngx_int_t
-ngx_http_script_add_copy_code(ngx_http_script_compile_t *sc, ngx_str_t *value,
- ngx_uint_t last)
-{
- u_char *p;
- size_t size, len, zero;
- ngx_http_script_copy_code_t *code;
-
- zero = (sc->zero && last);
- len = value->len + zero;
-
- code = ngx_http_script_add_code(*sc->lengths,
- sizeof(ngx_http_script_copy_code_t), NULL);
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- code->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
- code->len = len;
-
- size = (sizeof(ngx_http_script_copy_code_t) + len + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
-
- code = ngx_http_script_add_code(*sc->values, size, &sc->main);
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- code->code = ngx_http_script_copy_code;
- code->len = len;
-
- p = ngx_cpymem((u_char *) code + sizeof(ngx_http_script_copy_code_t),
- value->data, value->len);
-
- if (zero) {
- *p = '\0';
- sc->zero = 0;
- }
-
- return NGX_OK;
-}
-
-
-size_t
-ngx_http_script_copy_len_code(ngx_http_script_engine_t *e)
-{
- ngx_http_script_copy_code_t *code;
-
- code = (ngx_http_script_copy_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_script_copy_code_t);
-
- return code->len;
-}
-
-
-void
-ngx_http_script_copy_code(ngx_http_script_engine_t *e)
-{
- u_char *p;
- ngx_http_script_copy_code_t *code;
-
- code = (ngx_http_script_copy_code_t *) e->ip;
-
- p = e->pos;
-
- if (!e->skip) {
- e->pos = ngx_copy(p, e->ip + sizeof(ngx_http_script_copy_code_t),
- code->len);
- }
-
- e->ip += sizeof(ngx_http_script_copy_code_t)
- + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1));
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script copy: \"%*s\"", e->pos - p, p);
-}
-
-
-static ngx_int_t
-ngx_http_script_add_var_code(ngx_http_script_compile_t *sc, ngx_str_t *name)
-{
- ngx_int_t index, *p;
- ngx_http_script_var_code_t *code;
-
- index = ngx_http_get_variable_index(sc->cf, name);
-
- if (index == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- if (sc->flushes) {
- p = ngx_array_push(*sc->flushes);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- *p = index;
- }
-
- code = ngx_http_script_add_code(*sc->lengths,
- sizeof(ngx_http_script_var_code_t), NULL);
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- code->code = (ngx_http_script_code_pt) ngx_http_script_copy_var_len_code;
- code->index = (uintptr_t) index;
-
- code = ngx_http_script_add_code(*sc->values,
- sizeof(ngx_http_script_var_code_t),
- &sc->main);
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- code->code = ngx_http_script_copy_var_code;
- code->index = (uintptr_t) index;
-
- return NGX_OK;
-}
-
-
-size_t
-ngx_http_script_copy_var_len_code(ngx_http_script_engine_t *e)
-{
- ngx_http_variable_value_t *value;
- ngx_http_script_var_code_t *code;
-
- code = (ngx_http_script_var_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_script_var_code_t);
-
- if (e->flushed) {
- value = ngx_http_get_indexed_variable(e->request, code->index);
-
- } else {
- value = ngx_http_get_flushed_variable(e->request, code->index);
- }
-
- if (value && !value->not_found) {
- return value->len;
- }
-
- return 0;
-}
-
-
-void
-ngx_http_script_copy_var_code(ngx_http_script_engine_t *e)
-{
- u_char *p;
- ngx_http_variable_value_t *value;
- ngx_http_script_var_code_t *code;
-
- code = (ngx_http_script_var_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_script_var_code_t);
-
- if (!e->skip) {
-
- if (e->flushed) {
- value = ngx_http_get_indexed_variable(e->request, code->index);
-
- } else {
- value = ngx_http_get_flushed_variable(e->request, code->index);
- }
-
- if (value && !value->not_found) {
- p = e->pos;
- e->pos = ngx_copy(p, value->data, value->len);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP,
- e->request->connection->log, 0,
- "http script var: \"%*s\"", e->pos - p, p);
- }
- }
-}
-
-
-static ngx_int_t
-ngx_http_script_add_args_code(ngx_http_script_compile_t *sc)
-{
- uintptr_t *code;
-
- code = ngx_http_script_add_code(*sc->lengths, sizeof(uintptr_t), NULL);
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) ngx_http_script_mark_args_code;
-
- code = ngx_http_script_add_code(*sc->values, sizeof(uintptr_t), &sc->main);
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- *code = (uintptr_t) ngx_http_script_start_args_code;
-
- return NGX_OK;
-}
-
-
-size_t
-ngx_http_script_mark_args_code(ngx_http_script_engine_t *e)
-{
- e->is_args = 1;
- e->ip += sizeof(uintptr_t);
-
- return 1;
-}
-
-
-void
-ngx_http_script_start_args_code(ngx_http_script_engine_t *e)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script args");
-
- e->is_args = 1;
- e->args = e->pos;
- e->ip += sizeof(uintptr_t);
-}
-
-
-#if (NGX_PCRE)
-
-void
-ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
-{
- size_t len;
- ngx_int_t rc;
- ngx_uint_t n;
- ngx_http_request_t *r;
- ngx_http_script_engine_t le;
- ngx_http_script_len_code_pt lcode;
- ngx_http_script_regex_code_t *code;
-
- code = (ngx_http_script_regex_code_t *) e->ip;
-
- r = e->request;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http script regex: \"%V\"", &code->name);
-
- if (code->uri) {
- e->line = r->uri;
- } else {
- e->sp--;
- e->line.len = e->sp->len;
- e->line.data = e->sp->data;
- }
-
- rc = ngx_http_regex_exec(r, code->regex, &e->line);
-
- if (rc == NGX_DECLINED) {
- if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "\"%V\" does not match \"%V\"",
- &code->name, &e->line);
- }
-
- r->ncaptures = 0;
-
- if (code->test) {
- if (code->negative_test) {
- e->sp->len = 1;
- e->sp->data = (u_char *) "1";
-
- } else {
- e->sp->len = 0;
- e->sp->data = (u_char *) "";
- }
-
- e->sp++;
-
- e->ip += sizeof(ngx_http_script_regex_code_t);
- return;
- }
-
- e->ip += code->next;
- return;
- }
-
- if (rc == NGX_ERROR) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
-
- if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "\"%V\" matches \"%V\"", &code->name, &e->line);
- }
-
- if (code->test) {
- if (code->negative_test) {
- e->sp->len = 0;
- e->sp->data = (u_char *) "";
-
- } else {
- e->sp->len = 1;
- e->sp->data = (u_char *) "1";
- }
-
- e->sp++;
-
- e->ip += sizeof(ngx_http_script_regex_code_t);
- return;
- }
-
- if (code->status) {
- e->status = code->status;
-
- if (!code->redirect) {
- e->ip = ngx_http_script_exit;
- return;
- }
- }
-
- if (code->uri) {
- r->internal = 1;
- r->valid_unparsed_uri = 0;
-
- if (code->break_cycle) {
- r->valid_location = 0;
- r->uri_changed = 0;
-
- } else {
- r->uri_changed = 1;
- }
- }
-
- if (code->lengths == NULL) {
- e->buf.len = code->size;
-
- if (code->uri) {
- if (r->ncaptures && (r->quoted_uri || r->plus_in_uri)) {
- e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len,
- NGX_ESCAPE_ARGS);
- }
- }
-
- for (n = 2; n < r->ncaptures; n += 2) {
- e->buf.len += r->captures[n + 1] - r->captures[n];
- }
-
- } else {
- ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
-
- le.ip = code->lengths->elts;
- le.line = e->line;
- le.request = r;
- le.quote = code->redirect;
-
- len = 0;
-
- while (*(uintptr_t *) le.ip) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- len += lcode(&le);
- }
-
- e->buf.len = len;
- }
-
- if (code->add_args && r->args.len) {
- e->buf.len += r->args.len + 1;
- }
-
- e->buf.data = ngx_pnalloc(r->pool, e->buf.len);
- if (e->buf.data == NULL) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
-
- e->quote = code->redirect;
-
- e->pos = e->buf.data;
-
- e->ip += sizeof(ngx_http_script_regex_code_t);
-}
-
-
-void
-ngx_http_script_regex_end_code(ngx_http_script_engine_t *e)
-{
- u_char *dst, *src;
- ngx_http_request_t *r;
- ngx_http_script_regex_end_code_t *code;
-
- code = (ngx_http_script_regex_end_code_t *) e->ip;
-
- r = e->request;
-
- e->quote = 0;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http script regex end");
-
- if (code->redirect) {
-
- dst = e->buf.data;
- src = e->buf.data;
-
- ngx_unescape_uri(&dst, &src, e->pos - e->buf.data,
- NGX_UNESCAPE_REDIRECT);
-
- if (src < e->pos) {
- dst = ngx_movemem(dst, src, e->pos - src);
- }
-
- e->pos = dst;
-
- if (code->add_args && r->args.len) {
- *e->pos++ = (u_char) (code->args ? '&' : '?');
- e->pos = ngx_copy(e->pos, r->args.data, r->args.len);
- }
-
- e->buf.len = e->pos - e->buf.data;
-
- if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "rewritten redirect: \"%V\"", &e->buf);
- }
-
- ngx_http_clear_location(r);
-
- r->headers_out.location = ngx_list_push(&r->headers_out.headers);
- if (r->headers_out.location == NULL) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
-
- r->headers_out.location->hash = 1;
- ngx_str_set(&r->headers_out.location->key, "Location");
- r->headers_out.location->value = e->buf;
-
- e->ip += sizeof(ngx_http_script_regex_end_code_t);
- return;
- }
-
- if (e->args) {
- e->buf.len = e->args - e->buf.data;
-
- if (code->add_args && r->args.len) {
- *e->pos++ = '&';
- e->pos = ngx_copy(e->pos, r->args.data, r->args.len);
- }
-
- r->args.len = e->pos - e->args;
- r->args.data = e->args;
-
- e->args = NULL;
-
- } else {
- e->buf.len = e->pos - e->buf.data;
-
- if (!code->add_args) {
- r->args.len = 0;
- }
- }
-
- if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
- ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
- "rewritten data: \"%V\", args: \"%V\"",
- &e->buf, &r->args);
- }
-
- if (code->uri) {
- r->uri = e->buf;
-
- if (r->uri.len == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "the rewritten URI has a zero length");
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
-
- ngx_http_set_exten(r);
- }
-
- e->ip += sizeof(ngx_http_script_regex_end_code_t);
-}
-
-
-static ngx_int_t
-ngx_http_script_add_capture_code(ngx_http_script_compile_t *sc, ngx_uint_t n)
-{
- ngx_http_script_copy_capture_code_t *code;
-
- code = ngx_http_script_add_code(*sc->lengths,
- sizeof(ngx_http_script_copy_capture_code_t),
- NULL);
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- code->code = (ngx_http_script_code_pt)
- ngx_http_script_copy_capture_len_code;
- code->n = 2 * n;
-
-
- code = ngx_http_script_add_code(*sc->values,
- sizeof(ngx_http_script_copy_capture_code_t),
- &sc->main);
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- code->code = ngx_http_script_copy_capture_code;
- code->n = 2 * n;
-
- if (sc->ncaptures < n) {
- sc->ncaptures = n;
- }
-
- return NGX_OK;
-}
-
-
-size_t
-ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e)
-{
- int *cap;
- u_char *p;
- ngx_uint_t n;
- ngx_http_request_t *r;
- ngx_http_script_copy_capture_code_t *code;
-
- r = e->request;
-
- code = (ngx_http_script_copy_capture_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_script_copy_capture_code_t);
-
- n = code->n;
-
- if (n < r->ncaptures) {
-
- cap = r->captures;
-
- if ((e->is_args || e->quote)
- && (e->request->quoted_uri || e->request->plus_in_uri))
- {
- p = r->captures_data;
-
- return cap[n + 1] - cap[n]
- + 2 * ngx_escape_uri(NULL, &p[cap[n]], cap[n + 1] - cap[n],
- NGX_ESCAPE_ARGS);
- } else {
- return cap[n + 1] - cap[n];
- }
- }
-
- return 0;
-}
-
-
-void
-ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e)
-{
- int *cap;
- u_char *p, *pos;
- ngx_uint_t n;
- ngx_http_request_t *r;
- ngx_http_script_copy_capture_code_t *code;
-
- r = e->request;
-
- code = (ngx_http_script_copy_capture_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_script_copy_capture_code_t);
-
- n = code->n;
-
- pos = e->pos;
-
- if (n < r->ncaptures) {
-
- cap = r->captures;
- p = r->captures_data;
-
- if ((e->is_args || e->quote)
- && (e->request->quoted_uri || e->request->plus_in_uri))
- {
- e->pos = (u_char *) ngx_escape_uri(pos, &p[cap[n]],
- cap[n + 1] - cap[n],
- NGX_ESCAPE_ARGS);
- } else {
- e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]);
- }
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script capture: \"%*s\"", e->pos - pos, pos);
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_script_add_full_name_code(ngx_http_script_compile_t *sc)
-{
- ngx_http_script_full_name_code_t *code;
-
- code = ngx_http_script_add_code(*sc->lengths,
- sizeof(ngx_http_script_full_name_code_t),
- NULL);
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- code->code = (ngx_http_script_code_pt) ngx_http_script_full_name_len_code;
- code->conf_prefix = sc->conf_prefix;
-
- code = ngx_http_script_add_code(*sc->values,
- sizeof(ngx_http_script_full_name_code_t),
- &sc->main);
- if (code == NULL) {
- return NGX_ERROR;
- }
-
- code->code = ngx_http_script_full_name_code;
- code->conf_prefix = sc->conf_prefix;
-
- return NGX_OK;
-}
-
-
-static size_t
-ngx_http_script_full_name_len_code(ngx_http_script_engine_t *e)
-{
- ngx_http_script_full_name_code_t *code;
-
- code = (ngx_http_script_full_name_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_script_full_name_code_t);
-
- return code->conf_prefix ? ngx_cycle->conf_prefix.len:
- ngx_cycle->prefix.len;
-}
-
-
-static void
-ngx_http_script_full_name_code(ngx_http_script_engine_t *e)
-{
- ngx_http_script_full_name_code_t *code;
-
- ngx_str_t value, *prefix;
-
- code = (ngx_http_script_full_name_code_t *) e->ip;
-
- value.data = e->buf.data;
- value.len = e->pos - e->buf.data;
-
- prefix = code->conf_prefix ? (ngx_str_t *) &ngx_cycle->conf_prefix:
- (ngx_str_t *) &ngx_cycle->prefix;
-
- if (ngx_get_full_name(e->request->pool, prefix, &value) != NGX_OK) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
-
- e->buf = value;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script fullname: \"%V\"", &value);
-
- e->ip += sizeof(ngx_http_script_full_name_code_t);
-}
-
-
-void
-ngx_http_script_return_code(ngx_http_script_engine_t *e)
-{
- ngx_http_script_return_code_t *code;
-
- code = (ngx_http_script_return_code_t *) e->ip;
-
- if (code->status < NGX_HTTP_BAD_REQUEST
- || code->text.value.len
- || code->text.lengths)
- {
- e->status = ngx_http_send_response(e->request, code->status, NULL,
- &code->text);
- } else {
- e->status = code->status;
- }
-
- e->ip = ngx_http_script_exit;
-}
-
-
-void
-ngx_http_script_break_code(ngx_http_script_engine_t *e)
-{
- e->request->uri_changed = 0;
-
- e->ip = ngx_http_script_exit;
-}
-
-
-void
-ngx_http_script_if_code(ngx_http_script_engine_t *e)
-{
- ngx_http_script_if_code_t *code;
-
- code = (ngx_http_script_if_code_t *) e->ip;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script if");
-
- e->sp--;
-
- if (e->sp->len && (e->sp->len != 1 || e->sp->data[0] != '0')) {
- if (code->loc_conf) {
- e->request->loc_conf = code->loc_conf;
- ngx_http_update_location_config(e->request);
- }
-
- e->ip += sizeof(ngx_http_script_if_code_t);
- return;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script if: false");
-
- e->ip += code->next;
-}
-
-
-void
-ngx_http_script_equal_code(ngx_http_script_engine_t *e)
-{
- ngx_http_variable_value_t *val, *res;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script equal");
-
- e->sp--;
- val = e->sp;
- res = e->sp - 1;
-
- e->ip += sizeof(uintptr_t);
-
- if (val->len == res->len
- && ngx_strncmp(val->data, res->data, res->len) == 0)
- {
- *res = ngx_http_variable_true_value;
- return;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script equal: no");
-
- *res = ngx_http_variable_null_value;
-}
-
-
-void
-ngx_http_script_not_equal_code(ngx_http_script_engine_t *e)
-{
- ngx_http_variable_value_t *val, *res;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script not equal");
-
- e->sp--;
- val = e->sp;
- res = e->sp - 1;
-
- e->ip += sizeof(uintptr_t);
-
- if (val->len == res->len
- && ngx_strncmp(val->data, res->data, res->len) == 0)
- {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script not equal: no");
-
- *res = ngx_http_variable_null_value;
- return;
- }
-
- *res = ngx_http_variable_true_value;
-}
-
-
-void
-ngx_http_script_file_code(ngx_http_script_engine_t *e)
-{
- ngx_str_t path;
- ngx_http_request_t *r;
- ngx_open_file_info_t of;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_variable_value_t *value;
- ngx_http_script_file_code_t *code;
-
- value = e->sp - 1;
-
- code = (ngx_http_script_file_code_t *) e->ip;
- e->ip += sizeof(ngx_http_script_file_code_t);
-
- path.len = value->len - 1;
- path.data = value->data;
-
- r = e->request;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http script file op %p \"%V\"", code->op, &path);
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- ngx_memzero(&of, sizeof(ngx_open_file_info_t));
-
- of.read_ahead = clcf->read_ahead;
- of.directio = clcf->directio;
- of.valid = clcf->open_file_cache_valid;
- of.min_uses = clcf->open_file_cache_min_uses;
- of.test_only = 1;
- of.errors = clcf->open_file_cache_errors;
- of.events = clcf->open_file_cache_events;
-
- if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
-
- if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
- != NGX_OK)
- {
- if (of.err != NGX_ENOENT
- && of.err != NGX_ENOTDIR
- && of.err != NGX_ENAMETOOLONG)
- {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
- "%s \"%s\" failed", of.failed, value->data);
- }
-
- switch (code->op) {
-
- case ngx_http_script_file_plain:
- case ngx_http_script_file_dir:
- case ngx_http_script_file_exists:
- case ngx_http_script_file_exec:
- goto false_value;
-
- case ngx_http_script_file_not_plain:
- case ngx_http_script_file_not_dir:
- case ngx_http_script_file_not_exists:
- case ngx_http_script_file_not_exec:
- goto true_value;
- }
-
- goto false_value;
- }
-
- switch (code->op) {
- case ngx_http_script_file_plain:
- if (of.is_file) {
- goto true_value;
- }
- goto false_value;
-
- case ngx_http_script_file_not_plain:
- if (of.is_file) {
- goto false_value;
- }
- goto true_value;
-
- case ngx_http_script_file_dir:
- if (of.is_dir) {
- goto true_value;
- }
- goto false_value;
-
- case ngx_http_script_file_not_dir:
- if (of.is_dir) {
- goto false_value;
- }
- goto true_value;
-
- case ngx_http_script_file_exists:
- if (of.is_file || of.is_dir || of.is_link) {
- goto true_value;
- }
- goto false_value;
-
- case ngx_http_script_file_not_exists:
- if (of.is_file || of.is_dir || of.is_link) {
- goto false_value;
- }
- goto true_value;
-
- case ngx_http_script_file_exec:
- if (of.is_exec) {
- goto true_value;
- }
- goto false_value;
-
- case ngx_http_script_file_not_exec:
- if (of.is_exec) {
- goto false_value;
- }
- goto true_value;
- }
-
-false_value:
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http script file op false");
-
- *value = ngx_http_variable_null_value;
- return;
-
-true_value:
-
- *value = ngx_http_variable_true_value;
- return;
-}
-
-
-void
-ngx_http_script_complex_value_code(ngx_http_script_engine_t *e)
-{
- size_t len;
- ngx_http_script_engine_t le;
- ngx_http_script_len_code_pt lcode;
- ngx_http_script_complex_value_code_t *code;
-
- code = (ngx_http_script_complex_value_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_script_complex_value_code_t);
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script complex value");
-
- ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
-
- le.ip = code->lengths->elts;
- le.line = e->line;
- le.request = e->request;
- le.quote = e->quote;
-
- for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) {
- lcode = *(ngx_http_script_len_code_pt *) le.ip;
- }
-
- e->buf.len = len;
- e->buf.data = ngx_pnalloc(e->request->pool, len);
- if (e->buf.data == NULL) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
-
- e->pos = e->buf.data;
-
- e->sp->len = e->buf.len;
- e->sp->data = e->buf.data;
- e->sp++;
-}
-
-
-void
-ngx_http_script_value_code(ngx_http_script_engine_t *e)
-{
- ngx_http_script_value_code_t *code;
-
- code = (ngx_http_script_value_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_script_value_code_t);
-
- e->sp->len = code->text_len;
- 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);
-
- e->sp++;
-}
-
-
-void
-ngx_http_script_set_var_code(ngx_http_script_engine_t *e)
-{
- ngx_http_request_t *r;
- ngx_http_script_var_code_t *code;
-
- code = (ngx_http_script_var_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_script_var_code_t);
-
- r = e->request;
-
- e->sp--;
-
- r->variables[code->index].len = e->sp->len;
- r->variables[code->index].valid = 1;
- r->variables[code->index].no_cacheable = 0;
- r->variables[code->index].not_found = 0;
- r->variables[code->index].data = e->sp->data;
-
-#if (NGX_DEBUG)
- {
- ngx_http_variable_t *v;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
- v = cmcf->variables.elts;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script set $%V", &v[code->index].name);
- }
-#endif
-}
-
-
-void
-ngx_http_script_var_set_handler_code(ngx_http_script_engine_t *e)
-{
- ngx_http_script_var_handler_code_t *code;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script set var handler");
-
- code = (ngx_http_script_var_handler_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_script_var_handler_code_t);
-
- e->sp--;
-
- code->handler(e->request, e->sp, code->data);
-}
-
-
-void
-ngx_http_script_var_code(ngx_http_script_engine_t *e)
-{
- ngx_http_variable_value_t *value;
- ngx_http_script_var_code_t *code;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script var");
-
- code = (ngx_http_script_var_code_t *) e->ip;
-
- e->ip += sizeof(ngx_http_script_var_code_t);
-
- value = ngx_http_get_flushed_variable(e->request, code->index);
-
- if (value && !value->not_found) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
- "http script var: \"%v\"", value);
-
- *e->sp = *value;
- e->sp++;
-
- return;
- }
-
- *e->sp = ngx_http_variable_null_value;
- e->sp++;
-}
-
-
-void
-ngx_http_script_nop_code(ngx_http_script_engine_t *e)
-{
- e->ip += sizeof(uintptr_t);
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_script.h b/usr.sbin/nginx/src/http/ngx_http_script.h
deleted file mode 100644
index 46592ab0155..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_script.h
+++ /dev/null
@@ -1,257 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HTTP_SCRIPT_H_INCLUDED_
-#define _NGX_HTTP_SCRIPT_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- u_char *ip;
- u_char *pos;
- ngx_http_variable_value_t *sp;
-
- ngx_str_t buf;
- ngx_str_t line;
-
- /* the start of the rewritten arguments */
- u_char *args;
-
- unsigned flushed:1;
- unsigned skip:1;
- unsigned quote:1;
- unsigned is_args:1;
- unsigned log:1;
-
- ngx_int_t status;
- ngx_http_request_t *request;
-} ngx_http_script_engine_t;
-
-
-typedef struct {
- ngx_conf_t *cf;
- ngx_str_t *source;
-
- ngx_array_t **flushes;
- ngx_array_t **lengths;
- ngx_array_t **values;
-
- ngx_uint_t variables;
- ngx_uint_t ncaptures;
- ngx_uint_t captures_mask;
- ngx_uint_t size;
-
- void *main;
-
- unsigned compile_args:1;
- unsigned complete_lengths:1;
- unsigned complete_values:1;
- unsigned zero:1;
- unsigned conf_prefix:1;
- unsigned root_prefix:1;
-
- unsigned dup_capture:1;
- unsigned args:1;
-} ngx_http_script_compile_t;
-
-
-typedef struct {
- ngx_str_t value;
- ngx_uint_t *flushes;
- void *lengths;
- void *values;
-} ngx_http_complex_value_t;
-
-
-typedef struct {
- ngx_conf_t *cf;
- ngx_str_t *value;
- ngx_http_complex_value_t *complex_value;
-
- unsigned zero:1;
- unsigned conf_prefix:1;
- unsigned root_prefix:1;
-} ngx_http_compile_complex_value_t;
-
-
-typedef void (*ngx_http_script_code_pt) (ngx_http_script_engine_t *e);
-typedef size_t (*ngx_http_script_len_code_pt) (ngx_http_script_engine_t *e);
-
-
-typedef struct {
- ngx_http_script_code_pt code;
- uintptr_t len;
-} ngx_http_script_copy_code_t;
-
-
-typedef struct {
- ngx_http_script_code_pt code;
- uintptr_t index;
-} ngx_http_script_var_code_t;
-
-
-typedef struct {
- ngx_http_script_code_pt code;
- ngx_http_set_variable_pt handler;
- uintptr_t data;
-} ngx_http_script_var_handler_code_t;
-
-
-typedef struct {
- ngx_http_script_code_pt code;
- uintptr_t n;
-} ngx_http_script_copy_capture_code_t;
-
-
-#if (NGX_PCRE)
-
-typedef struct {
- ngx_http_script_code_pt code;
- ngx_http_regex_t *regex;
- ngx_array_t *lengths;
- uintptr_t size;
- uintptr_t status;
- uintptr_t next;
-
- uintptr_t test:1;
- uintptr_t negative_test:1;
- uintptr_t uri:1;
- uintptr_t args:1;
-
- /* add the r->args to the new arguments */
- uintptr_t add_args:1;
-
- uintptr_t redirect:1;
- uintptr_t break_cycle:1;
-
- ngx_str_t name;
-} ngx_http_script_regex_code_t;
-
-
-typedef struct {
- ngx_http_script_code_pt code;
-
- uintptr_t uri:1;
- uintptr_t args:1;
-
- /* add the r->args to the new arguments */
- uintptr_t add_args:1;
-
- uintptr_t redirect:1;
-} ngx_http_script_regex_end_code_t;
-
-#endif
-
-
-typedef struct {
- ngx_http_script_code_pt code;
- uintptr_t conf_prefix;
-} ngx_http_script_full_name_code_t;
-
-
-typedef struct {
- ngx_http_script_code_pt code;
- uintptr_t status;
- ngx_http_complex_value_t text;
-} ngx_http_script_return_code_t;
-
-
-typedef enum {
- ngx_http_script_file_plain = 0,
- ngx_http_script_file_not_plain,
- ngx_http_script_file_dir,
- ngx_http_script_file_not_dir,
- ngx_http_script_file_exists,
- ngx_http_script_file_not_exists,
- ngx_http_script_file_exec,
- ngx_http_script_file_not_exec
-} ngx_http_script_file_op_e;
-
-
-typedef struct {
- ngx_http_script_code_pt code;
- uintptr_t op;
-} ngx_http_script_file_code_t;
-
-
-typedef struct {
- ngx_http_script_code_pt code;
- uintptr_t next;
- void **loc_conf;
-} ngx_http_script_if_code_t;
-
-
-typedef struct {
- ngx_http_script_code_pt code;
- ngx_array_t *lengths;
-} ngx_http_script_complex_value_code_t;
-
-
-typedef struct {
- ngx_http_script_code_pt code;
- uintptr_t value;
- uintptr_t text_len;
- uintptr_t text_data;
-} ngx_http_script_value_code_t;
-
-
-void ngx_http_script_flush_complex_value(ngx_http_request_t *r,
- ngx_http_complex_value_t *val);
-ngx_int_t ngx_http_complex_value(ngx_http_request_t *r,
- ngx_http_complex_value_t *val, ngx_str_t *value);
-ngx_int_t ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv);
-char *ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-ngx_int_t ngx_http_test_predicates(ngx_http_request_t *r,
- ngx_array_t *predicates);
-char *ngx_http_set_predicate_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-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_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,
- size_t size);
-void *ngx_http_script_add_code(ngx_array_t *codes, size_t size, void *code);
-
-size_t ngx_http_script_copy_len_code(ngx_http_script_engine_t *e);
-void ngx_http_script_copy_code(ngx_http_script_engine_t *e);
-size_t ngx_http_script_copy_var_len_code(ngx_http_script_engine_t *e);
-void ngx_http_script_copy_var_code(ngx_http_script_engine_t *e);
-size_t ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e);
-void ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e);
-size_t ngx_http_script_mark_args_code(ngx_http_script_engine_t *e);
-void ngx_http_script_start_args_code(ngx_http_script_engine_t *e);
-#if (NGX_PCRE)
-void ngx_http_script_regex_start_code(ngx_http_script_engine_t *e);
-void ngx_http_script_regex_end_code(ngx_http_script_engine_t *e);
-#endif
-void ngx_http_script_return_code(ngx_http_script_engine_t *e);
-void ngx_http_script_break_code(ngx_http_script_engine_t *e);
-void ngx_http_script_if_code(ngx_http_script_engine_t *e);
-void ngx_http_script_equal_code(ngx_http_script_engine_t *e);
-void ngx_http_script_not_equal_code(ngx_http_script_engine_t *e);
-void ngx_http_script_file_code(ngx_http_script_engine_t *e);
-void ngx_http_script_complex_value_code(ngx_http_script_engine_t *e);
-void ngx_http_script_value_code(ngx_http_script_engine_t *e);
-void ngx_http_script_set_var_code(ngx_http_script_engine_t *e);
-void ngx_http_script_var_set_handler_code(ngx_http_script_engine_t *e);
-void ngx_http_script_var_code(ngx_http_script_engine_t *e);
-void ngx_http_script_nop_code(ngx_http_script_engine_t *e);
-
-
-#endif /* _NGX_HTTP_SCRIPT_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/ngx_http_spdy.c b/usr.sbin/nginx/src/http/ngx_http_spdy.c
deleted file mode 100644
index 9bd624c82bc..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_spdy.c
+++ /dev/null
@@ -1,3497 +0,0 @@
-
-/*
- * Copyright (C) Nginx, Inc.
- * Copyright (C) Valentin V. Bartenev
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-#include <ngx_http_spdy_module.h>
-
-#include <zlib.h>
-
-
-#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED)
-
-#define ngx_str5cmp(m, c0, c1, c2, c3, c4) \
- *(uint32_t *) m == (c3 << 24 | c2 << 16 | c1 << 8 | c0) \
- && m[4] == c4
-
-#else
-
-#define ngx_str5cmp(m, c0, c1, c2, c3, c4) \
- m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3 && m[4] == c4
-
-#endif
-
-
-#if (NGX_HAVE_NONALIGNED)
-
-#define ngx_spdy_frame_parse_uint16(p) ntohs(*(uint16_t *) (p))
-#define ngx_spdy_frame_parse_uint32(p) ntohl(*(uint32_t *) (p))
-
-#else
-
-#define ngx_spdy_frame_parse_uint16(p) ((p)[0] << 8 | (p)[1])
-#define ngx_spdy_frame_parse_uint32(p) \
- ((p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3])
-
-#endif
-
-#define ngx_spdy_frame_parse_sid(p) \
- (ngx_spdy_frame_parse_uint32(p) & 0x7fffffff)
-#define ngx_spdy_frame_parse_delta(p) \
- (ngx_spdy_frame_parse_uint32(p) & 0x7fffffff)
-
-
-#define ngx_spdy_ctl_frame_check(h) \
- (((h) & 0xffff0000) == ngx_spdy_ctl_frame_head(0))
-#define ngx_spdy_data_frame_check(h) \
- (!((h) & (uint32_t) NGX_SPDY_CTL_BIT << 31))
-
-#define ngx_spdy_ctl_frame_type(h) ((h) & 0x0000ffff)
-#define ngx_spdy_frame_flags(p) ((p) >> 24)
-#define ngx_spdy_frame_length(p) ((p) & 0x00ffffff)
-#define ngx_spdy_frame_id(p) ((p) & 0x00ffffff)
-
-
-#define NGX_SPDY_SKIP_HEADERS_BUFFER_SIZE 4096
-#define NGX_SPDY_CTL_FRAME_BUFFER_SIZE 16
-
-#define NGX_SPDY_PROTOCOL_ERROR 1
-#define NGX_SPDY_INVALID_STREAM 2
-#define NGX_SPDY_REFUSED_STREAM 3
-#define NGX_SPDY_UNSUPPORTED_VERSION 4
-#define NGX_SPDY_CANCEL 5
-#define NGX_SPDY_INTERNAL_ERROR 6
-#define NGX_SPDY_FLOW_CONTROL_ERROR 7
-#define NGX_SPDY_STREAM_IN_USE 8
-#define NGX_SPDY_STREAM_ALREADY_CLOSED 9
-/* deprecated 10 */
-#define NGX_SPDY_FRAME_TOO_LARGE 11
-
-#define NGX_SPDY_SETTINGS_MAX_STREAMS 4
-#define NGX_SPDY_SETTINGS_INIT_WINDOW 7
-
-#define NGX_SPDY_SETTINGS_FLAG_PERSIST 0x01
-#define NGX_SPDY_SETTINGS_FLAG_PERSISTED 0x02
-
-#define NGX_SPDY_MAX_WINDOW NGX_MAX_INT32_VALUE
-#define NGX_SPDY_CONNECTION_WINDOW 65536
-#define NGX_SPDY_INIT_STREAM_WINDOW 65536
-#define NGX_SPDY_STREAM_WINDOW NGX_SPDY_MAX_WINDOW
-
-typedef struct {
- ngx_uint_t hash;
- u_char len;
- u_char header[7];
- ngx_int_t (*handler)(ngx_http_request_t *r);
-} ngx_http_spdy_request_header_t;
-
-
-static void ngx_http_spdy_read_handler(ngx_event_t *rev);
-static void ngx_http_spdy_write_handler(ngx_event_t *wev);
-static void ngx_http_spdy_handle_connection(ngx_http_spdy_connection_t *sc);
-
-static u_char *ngx_http_spdy_proxy_protocol(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_headers_error(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_window_update(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_read_data(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_rst_stream(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_ping(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_skip(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_complete(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-static u_char *ngx_http_spdy_state_save(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end, ngx_http_spdy_handler_pt handler);
-static u_char *ngx_http_spdy_state_protocol_error(
- ngx_http_spdy_connection_t *sc);
-static u_char *ngx_http_spdy_state_internal_error(
- ngx_http_spdy_connection_t *sc);
-
-static ngx_int_t ngx_http_spdy_send_window_update(
- ngx_http_spdy_connection_t *sc, ngx_uint_t sid, ngx_uint_t delta);
-static ngx_int_t ngx_http_spdy_send_rst_stream(ngx_http_spdy_connection_t *sc,
- ngx_uint_t sid, ngx_uint_t status, ngx_uint_t priority);
-static ngx_int_t ngx_http_spdy_send_settings(ngx_http_spdy_connection_t *sc);
-static ngx_int_t ngx_http_spdy_settings_frame_handler(
- ngx_http_spdy_connection_t *sc, ngx_http_spdy_out_frame_t *frame);
-static ngx_http_spdy_out_frame_t *ngx_http_spdy_get_ctl_frame(
- ngx_http_spdy_connection_t *sc, size_t size, ngx_uint_t priority);
-static ngx_int_t ngx_http_spdy_ctl_frame_handler(
- ngx_http_spdy_connection_t *sc, ngx_http_spdy_out_frame_t *frame);
-
-static ngx_http_spdy_stream_t *ngx_http_spdy_create_stream(
- ngx_http_spdy_connection_t *sc, ngx_uint_t id, ngx_uint_t priority);
-static ngx_http_spdy_stream_t *ngx_http_spdy_get_stream_by_id(
- ngx_http_spdy_connection_t *sc, ngx_uint_t sid);
-#define ngx_http_spdy_streams_index_size(sscf) (sscf->streams_index_mask + 1)
-#define ngx_http_spdy_stream_index(sscf, sid) \
- ((sid >> 1) & sscf->streams_index_mask)
-
-static ngx_int_t ngx_http_spdy_parse_header(ngx_http_request_t *r);
-static ngx_int_t ngx_http_spdy_alloc_large_header_buffer(ngx_http_request_t *r);
-
-static ngx_int_t ngx_http_spdy_handle_request_header(ngx_http_request_t *r);
-static ngx_int_t ngx_http_spdy_parse_method(ngx_http_request_t *r);
-static ngx_int_t ngx_http_spdy_parse_scheme(ngx_http_request_t *r);
-static ngx_int_t ngx_http_spdy_parse_host(ngx_http_request_t *r);
-static ngx_int_t ngx_http_spdy_parse_path(ngx_http_request_t *r);
-static ngx_int_t ngx_http_spdy_parse_version(ngx_http_request_t *r);
-
-static ngx_int_t ngx_http_spdy_construct_request_line(ngx_http_request_t *r);
-static void ngx_http_spdy_run_request(ngx_http_request_t *r);
-static ngx_int_t ngx_http_spdy_init_request_body(ngx_http_request_t *r);
-
-static ngx_int_t ngx_http_spdy_terminate_stream(ngx_http_spdy_connection_t *sc,
- ngx_http_spdy_stream_t *stream, ngx_uint_t status);
-
-static void ngx_http_spdy_close_stream_handler(ngx_event_t *ev);
-
-static void ngx_http_spdy_handle_connection_handler(ngx_event_t *rev);
-static void ngx_http_spdy_keepalive_handler(ngx_event_t *rev);
-static void ngx_http_spdy_finalize_connection(ngx_http_spdy_connection_t *sc,
- ngx_int_t rc);
-
-static ngx_int_t ngx_http_spdy_adjust_windows(ngx_http_spdy_connection_t *sc,
- ssize_t delta);
-
-static void ngx_http_spdy_pool_cleanup(void *data);
-
-static void *ngx_http_spdy_zalloc(void *opaque, u_int items, u_int size);
-static void ngx_http_spdy_zfree(void *opaque, void *address);
-
-
-static const u_char ngx_http_spdy_dict[] = {
- 0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69, /* - - - - o p t i */
- 0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68, /* o n s - - - - h */
- 0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70, /* e a d - - - - p */
- 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70, /* o s t - - - - p */
- 0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65, /* u t - - - - d e */
- 0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05, /* l e t e - - - - */
- 0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00, /* t r a c e - - - */
- 0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00, /* - a c c e p t - */
- 0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, /* - - - a c c e p */
- 0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, /* t - c h a r s e */
- 0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63, /* t - - - - a c c */
- 0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, /* e p t - e n c o */
- 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f, /* d i n g - - - - */
- 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c, /* a c c e p t - l */
- 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00, /* a n g u a g e - */
- 0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70, /* - - - a c c e p */
- 0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, /* t - r a n g e s */
- 0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00, /* - - - - a g e - */
- 0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, /* - - - a l l o w */
- 0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68, /* - - - - a u t h */
- 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, /* o r i z a t i o */
- 0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63, /* n - - - - c a c */
- 0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, /* h e - c o n t r */
- 0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f, /* o l - - - - c o */
- 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, /* n n e c t i o n */
- 0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, /* - - - - c o n t */
- 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65, /* e n t - b a s e */
- 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74, /* - - - - c o n t */
- 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f, /* e n t - e n c o */
- 0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, /* d i n g - - - - */
- 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, /* c o n t e n t - */
- 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, /* l a n g u a g e */
- 0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74, /* - - - - c o n t */
- 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67, /* e n t - l e n g */
- 0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, /* t h - - - - c o */
- 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f, /* n t e n t - l o */
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, /* c a t i o n - - */
- 0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, /* - - c o n t e n */
- 0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00, /* t - m d 5 - - - */
- 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, /* - c o n t e n t */
- 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, /* - r a n g e - - */
- 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, /* - - c o n t e n */
- 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, /* t - t y p e - - */
- 0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00, /* - - d a t e - - */
- 0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00, /* - - e t a g - - */
- 0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, /* - - e x p e c t */
- 0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69, /* - - - - e x p i */
- 0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66, /* r e s - - - - f */
- 0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68, /* r o m - - - - h */
- 0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69, /* o s t - - - - i */
- 0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, /* f - m a t c h - */
- 0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f, /* - - - i f - m o */
- 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73, /* d i f i e d - s */
- 0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d, /* i n c e - - - - */
- 0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d, /* i f - n o n e - */
- 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00, /* m a t c h - - - */
- 0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67, /* - i f - r a n g */
- 0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d, /* e - - - - i f - */
- 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, /* u n m o d i f i */
- 0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65, /* e d - s i n c e */
- 0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74, /* - - - - l a s t */
- 0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, /* - m o d i f i e */
- 0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63, /* d - - - - l o c */
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, /* a t i o n - - - */
- 0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72, /* - m a x - f o r */
- 0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00, /* w a r d s - - - */
- 0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00, /* - p r a g m a - */
- 0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79, /* - - - p r o x y */
- 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, /* - a u t h e n t */
- 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, /* i c a t e - - - */
- 0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, /* - p r o x y - a */
- 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, /* u t h o r i z a */
- 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05, /* t i o n - - - - */
- 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00, /* r a n g e - - - */
- 0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, /* - r e f e r e r */
- 0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72, /* - - - - r e t r */
- 0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00, /* y - a f t e r - */
- 0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, /* - - - s e r v e */
- 0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00, /* r - - - - t e - */
- 0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c, /* - - - t r a i l */
- 0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72, /* e r - - - - t r */
- 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65, /* a n s f e r - e */
- 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00, /* n c o d i n g - */
- 0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, /* - - - u p g r a */
- 0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73, /* d e - - - - u s */
- 0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, /* e r - a g e n t */
- 0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79, /* - - - - v a r y */
- 0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00, /* - - - - v i a - */
- 0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, /* - - - w a r n i */
- 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77, /* n g - - - - w w */
- 0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, /* w - a u t h e n */
- 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, /* t i c a t e - - */
- 0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, /* - - m e t h o d */
- 0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00, /* - - - - g e t - */
- 0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, /* - - - s t a t u */
- 0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30, /* s - - - - 2 0 0 */
- 0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76, /* - O K - - - - v */
- 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00, /* e r s i o n - - */
- 0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, /* - - H T T P - 1 */
- 0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72, /* - 1 - - - - u r */
- 0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62, /* l - - - - p u b */
- 0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73, /* l i c - - - - s */
- 0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69, /* e t - c o o k i */
- 0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65, /* e - - - - k e e */
- 0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00, /* p - a l i v e - */
- 0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, /* - - - o r i g i */
- 0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32, /* n 1 0 0 1 0 1 2 */
- 0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35, /* 0 1 2 0 2 2 0 5 */
- 0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30, /* 2 0 6 3 0 0 3 0 */
- 0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33, /* 2 3 0 3 3 0 4 3 */
- 0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37, /* 0 5 3 0 6 3 0 7 */
- 0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30, /* 4 0 2 4 0 5 4 0 */
- 0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34, /* 6 4 0 7 4 0 8 4 */
- 0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31, /* 0 9 4 1 0 4 1 1 */
- 0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31, /* 4 1 2 4 1 3 4 1 */
- 0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34, /* 4 4 1 5 4 1 6 4 */
- 0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34, /* 1 7 5 0 2 5 0 4 */
- 0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e, /* 5 0 5 2 0 3 - N */
- 0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f, /* o n - A u t h o */
- 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, /* r i t a t i v e */
- 0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, /* - I n f o r m a */
- 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20, /* t i o n 2 0 4 - */
- 0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, /* N o - C o n t e */
- 0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f, /* n t 3 0 1 - M o */
- 0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d, /* v e d - P e r m */
- 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34, /* a n e n t l y 4 */
- 0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52, /* 0 0 - B a d - R */
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30, /* e q u e s t 4 0 */
- 0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, /* 1 - U n a u t h */
- 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30, /* o r i z e d 4 0 */
- 0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64, /* 3 - F o r b i d */
- 0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e, /* d e n 4 0 4 - N */
- 0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64, /* o t - F o u n d */
- 0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65, /* 5 0 0 - I n t e */
- 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, /* r n a l - S e r */
- 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f, /* v e r - E r r o */
- 0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74, /* r 5 0 1 - N o t */
- 0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, /* - I m p l e m e */
- 0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20, /* n t e d 5 0 3 - */
- 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, /* S e r v i c e - */
- 0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, /* U n a v a i l a */
- 0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46, /* b l e J a n - F */
- 0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41, /* e b - M a r - A */
- 0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a, /* p r - M a y - J */
- 0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41, /* u n - J u l - A */
- 0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20, /* u g - S e p t - */
- 0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20, /* O c t - N o v - */
- 0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30, /* D e c - 0 0 - 0 */
- 0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e, /* 0 - 0 0 - M o n */
- 0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57, /* - - T u e - - W */
- 0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c, /* e d - - T h u - */
- 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61, /* - F r i - - S a */
- 0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20, /* t - - S u n - - */
- 0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b, /* G M T c h u n k */
- 0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, /* e d - t e x t - */
- 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61, /* h t m l - i m a */
- 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69, /* g e - p n g - i */
- 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67, /* m a g e - j p g */
- 0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, /* - i m a g e - g */
- 0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, /* i f - a p p l i */
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, /* c a t i o n - x */
- 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, /* m l - a p p l i */
- 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, /* c a t i o n - x */
- 0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c, /* h t m l - x m l */
- 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, /* - t e x t - p l */
- 0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74, /* a i n - t e x t */
- 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, /* - j a v a s c r */
- 0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c, /* i p t - p u b l */
- 0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, /* i c p r i v a t */
- 0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, /* e m a x - a g e */
- 0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65, /* - g z i p - d e */
- 0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64, /* f l a t e - s d */
- 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, /* c h c h a r s e */
- 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63, /* t - u t f - 8 c */
- 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69, /* h a r s e t - i */
- 0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d, /* s o - 8 8 5 9 - */
- 0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a, /* 1 - u t f - - - */
- 0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e /* - e n q - 0 - */
-};
-
-
-static ngx_http_spdy_request_header_t ngx_http_spdy_request_headers[] = {
- { 0, 6, "method", ngx_http_spdy_parse_method },
- { 0, 6, "scheme", ngx_http_spdy_parse_scheme },
- { 0, 4, "host", ngx_http_spdy_parse_host },
- { 0, 4, "path", ngx_http_spdy_parse_path },
- { 0, 7, "version", ngx_http_spdy_parse_version },
-};
-
-#define NGX_SPDY_REQUEST_HEADERS \
- (sizeof(ngx_http_spdy_request_headers) \
- / sizeof(ngx_http_spdy_request_header_t))
-
-
-void
-ngx_http_spdy_init(ngx_event_t *rev)
-{
- int rc;
- ngx_connection_t *c;
- ngx_pool_cleanup_t *cln;
- ngx_http_connection_t *hc;
- ngx_http_spdy_srv_conf_t *sscf;
- ngx_http_spdy_main_conf_t *smcf;
- ngx_http_spdy_connection_t *sc;
-
- c = rev->data;
- hc = c->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "init spdy request");
-
- c->log->action = "processing SPDY";
-
- smcf = ngx_http_get_module_main_conf(hc->conf_ctx, ngx_http_spdy_module);
-
- if (smcf->recv_buffer == NULL) {
- smcf->recv_buffer = ngx_palloc(ngx_cycle->pool, smcf->recv_buffer_size);
- if (smcf->recv_buffer == NULL) {
- ngx_http_close_connection(c);
- return;
- }
- }
-
- sc = ngx_pcalloc(c->pool, sizeof(ngx_http_spdy_connection_t));
- if (sc == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- sc->connection = c;
- sc->http_connection = hc;
-
- sc->send_window = NGX_SPDY_CONNECTION_WINDOW;
- sc->recv_window = NGX_SPDY_CONNECTION_WINDOW;
-
- sc->init_window = NGX_SPDY_INIT_STREAM_WINDOW;
-
- sc->handler = ngx_http_spdy_state_head;
-
- if (hc->proxy_protocol) {
- c->log->action = "reading PROXY protocol";
- sc->handler = ngx_http_spdy_proxy_protocol;
- }
-
- sc->zstream_in.zalloc = ngx_http_spdy_zalloc;
- sc->zstream_in.zfree = ngx_http_spdy_zfree;
- sc->zstream_in.opaque = sc;
-
- rc = inflateInit(&sc->zstream_in);
- if (rc != Z_OK) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "inflateInit() failed: %d", rc);
- ngx_http_close_connection(c);
- return;
- }
-
- sc->zstream_out.zalloc = ngx_http_spdy_zalloc;
- sc->zstream_out.zfree = ngx_http_spdy_zfree;
- sc->zstream_out.opaque = sc;
-
- sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_spdy_module);
-
- rc = deflateInit2(&sc->zstream_out, (int) sscf->headers_comp,
- Z_DEFLATED, 11, 4, Z_DEFAULT_STRATEGY);
-
- if (rc != Z_OK) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "deflateInit2() failed: %d", rc);
- ngx_http_close_connection(c);
- return;
- }
-
- rc = deflateSetDictionary(&sc->zstream_out, ngx_http_spdy_dict,
- sizeof(ngx_http_spdy_dict));
- if (rc != Z_OK) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "deflateSetDictionary() failed: %d", rc);
- ngx_http_close_connection(c);
- return;
- }
-
- sc->pool = ngx_create_pool(sscf->pool_size, sc->connection->log);
- if (sc->pool == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- cln = ngx_pool_cleanup_add(c->pool, sizeof(ngx_pool_cleanup_file_t));
- if (cln == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- cln->handler = ngx_http_spdy_pool_cleanup;
- cln->data = sc;
-
- sc->streams_index = ngx_pcalloc(sc->pool,
- ngx_http_spdy_streams_index_size(sscf)
- * sizeof(ngx_http_spdy_stream_t *));
- if (sc->streams_index == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- if (ngx_http_spdy_send_settings(sc) == NGX_ERROR) {
- ngx_http_close_connection(c);
- return;
- }
-
- if (ngx_http_spdy_send_window_update(sc, 0, NGX_SPDY_MAX_WINDOW
- - sc->recv_window)
- == NGX_ERROR)
- {
- ngx_http_close_connection(c);
- return;
- }
-
- sc->recv_window = NGX_SPDY_MAX_WINDOW;
-
- ngx_queue_init(&sc->waiting);
- ngx_queue_init(&sc->posted);
-
- c->data = sc;
-
- rev->handler = ngx_http_spdy_read_handler;
- c->write->handler = ngx_http_spdy_write_handler;
-
- ngx_http_spdy_read_handler(rev);
-}
-
-
-static void
-ngx_http_spdy_read_handler(ngx_event_t *rev)
-{
- u_char *p, *end;
- size_t available;
- ssize_t n;
- ngx_connection_t *c;
- ngx_http_spdy_main_conf_t *smcf;
- ngx_http_spdy_connection_t *sc;
-
- c = rev->data;
- sc = c->data;
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_REQUEST_TIME_OUT);
- return;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "spdy read handler");
-
- sc->blocked = 1;
-
- smcf = ngx_http_get_module_main_conf(sc->http_connection->conf_ctx,
- ngx_http_spdy_module);
-
- available = smcf->recv_buffer_size - 2 * NGX_SPDY_STATE_BUFFER_SIZE;
-
- do {
- p = smcf->recv_buffer;
-
- ngx_memcpy(p, sc->buffer, NGX_SPDY_STATE_BUFFER_SIZE);
- end = p + sc->buffer_used;
-
- n = c->recv(c, end, available);
-
- if (n == NGX_AGAIN) {
- break;
- }
-
- if (n == 0 && (sc->incomplete || sc->processing)) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client closed prematurely connection");
- }
-
- if (n == 0 || n == NGX_ERROR) {
- ngx_http_spdy_finalize_connection(sc,
- NGX_HTTP_CLIENT_CLOSED_REQUEST);
- return;
- }
-
- end += n;
-
- sc->buffer_used = 0;
- sc->incomplete = 0;
-
- do {
- p = sc->handler(sc, p, end);
-
- if (p == NULL) {
- return;
- }
-
- } while (p != end);
-
- } while (rev->ready);
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- if (sc->last_out && ngx_http_spdy_send_output_queue(sc) == NGX_ERROR) {
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
- return;
- }
-
- sc->blocked = 0;
-
- if (sc->processing) {
- if (rev->timer_set) {
- ngx_del_timer(rev);
- }
- return;
- }
-
- ngx_http_spdy_handle_connection(sc);
-}
-
-
-static void
-ngx_http_spdy_write_handler(ngx_event_t *wev)
-{
- ngx_int_t rc;
- ngx_queue_t *q;
- ngx_connection_t *c;
- ngx_http_spdy_stream_t *stream;
- ngx_http_spdy_connection_t *sc;
-
- c = wev->data;
- sc = c->data;
-
- if (wev->timedout) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "spdy write event timed out");
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
- return;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "spdy write handler");
-
- sc->blocked = 1;
-
- rc = ngx_http_spdy_send_output_queue(sc);
-
- if (rc == NGX_ERROR) {
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
- return;
- }
-
- while (!ngx_queue_empty(&sc->posted)) {
- q = ngx_queue_head(&sc->posted);
-
- ngx_queue_remove(q);
-
- stream = ngx_queue_data(q, ngx_http_spdy_stream_t, queue);
-
- stream->handled = 0;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "spdy run stream %ui", stream->id);
-
- wev = stream->request->connection->write;
- wev->handler(wev);
- }
-
- sc->blocked = 0;
-
- if (rc == NGX_AGAIN) {
- return;
- }
-
- ngx_http_spdy_handle_connection(sc);
-}
-
-
-ngx_int_t
-ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc)
-{
- ngx_chain_t *cl;
- ngx_event_t *wev;
- ngx_connection_t *c;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_spdy_out_frame_t *out, *frame, *fn;
-
- c = sc->connection;
-
- if (c->error) {
- return NGX_ERROR;
- }
-
- wev = c->write;
-
- if (!wev->ready) {
- return NGX_OK;
- }
-
- cl = NULL;
- out = NULL;
-
- for (frame = sc->last_out; frame; frame = fn) {
- frame->last->next = cl;
- cl = frame->first;
-
- fn = frame->next;
- frame->next = out;
- out = frame;
-
- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "spdy frame out: %p sid:%ui prio:%ui bl:%d len:%uz",
- out, out->stream ? out->stream->id : 0, out->priority,
- out->blocked, out->length);
- }
-
- cl = c->send_chain(c, cl, 0);
-
- if (cl == NGX_CHAIN_ERROR) {
- c->error = 1;
-
- if (!sc->blocked) {
- ngx_post_event(wev, &ngx_posted_events);
- }
-
- return NGX_ERROR;
- }
-
- clcf = ngx_http_get_module_loc_conf(sc->http_connection->conf_ctx,
- ngx_http_core_module);
-
- if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
- return NGX_ERROR; /* FIXME */
- }
-
- if (cl) {
- ngx_add_timer(wev, clcf->send_timeout);
-
- } else {
- if (wev->timer_set) {
- ngx_del_timer(wev);
- }
- }
-
- for ( /* void */ ; out; out = fn) {
- fn = out->next;
-
- if (out->handler(sc, out) != NGX_OK) {
- out->blocked = 1;
- out->priority = NGX_SPDY_HIGHEST_PRIORITY;
- break;
- }
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "spdy frame sent: %p sid:%ui bl:%d len:%uz",
- out, out->stream ? out->stream->id : 0,
- out->blocked, out->length);
- }
-
- frame = NULL;
-
- for ( /* void */ ; out; out = fn) {
- fn = out->next;
- out->next = frame;
- frame = out;
- }
-
- sc->last_out = frame;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_spdy_handle_connection(ngx_http_spdy_connection_t *sc)
-{
- ngx_connection_t *c;
- ngx_http_spdy_srv_conf_t *sscf;
-
- if (sc->last_out || sc->processing) {
- return;
- }
-
- c = sc->connection;
-
- if (c->error) {
- ngx_http_close_connection(c);
- return;
- }
-
- if (c->buffered) {
- return;
- }
-
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
- ngx_http_spdy_module);
- if (sc->incomplete) {
- ngx_add_timer(c->read, sscf->recv_timeout);
- return;
- }
-
- if (ngx_terminate || ngx_exiting) {
- ngx_http_close_connection(c);
- return;
- }
-
- ngx_destroy_pool(sc->pool);
-
- sc->pool = NULL;
- sc->free_ctl_frames = NULL;
- sc->free_fake_connections = NULL;
-
-#if (NGX_HTTP_SSL)
- if (c->ssl) {
- ngx_ssl_free_buffer(c);
- }
-#endif
-
- c->destroyed = 1;
- c->idle = 1;
- ngx_reusable_connection(c, 1);
-
- c->write->handler = ngx_http_empty_handler;
- c->read->handler = ngx_http_spdy_keepalive_handler;
-
- if (c->write->timer_set) {
- ngx_del_timer(c->write);
- }
-
- ngx_add_timer(c->read, sscf->keepalive_timeout);
-}
-
-
-static u_char *
-ngx_http_spdy_proxy_protocol(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- pos = ngx_proxy_protocol_parse(sc->connection, pos, end);
-
- if (pos == NULL) {
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- sc->connection->log->action = "processing SPDY";
-
- return ngx_http_spdy_state_complete(sc, pos, end);
-}
-
-
-static u_char *
-ngx_http_spdy_state_head(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- uint32_t head, flen;
- ngx_uint_t type;
-
- if (end - pos < NGX_SPDY_FRAME_HEADER_SIZE) {
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_head);
- }
-
- head = ngx_spdy_frame_parse_uint32(pos);
-
- pos += sizeof(uint32_t);
-
- flen = ngx_spdy_frame_parse_uint32(pos);
-
- sc->flags = ngx_spdy_frame_flags(flen);
- sc->length = ngx_spdy_frame_length(flen);
-
- pos += sizeof(uint32_t);
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy process frame head:%08XD f:%Xd l:%uz",
- head, sc->flags, sc->length);
-
- if (ngx_spdy_ctl_frame_check(head)) {
- type = ngx_spdy_ctl_frame_type(head);
-
- switch (type) {
-
- case NGX_SPDY_SYN_STREAM:
- return ngx_http_spdy_state_syn_stream(sc, pos, end);
-
- case NGX_SPDY_SYN_REPLY:
- return ngx_http_spdy_state_protocol_error(sc);
-
- case NGX_SPDY_RST_STREAM:
- return ngx_http_spdy_state_rst_stream(sc, pos, end);
-
- case NGX_SPDY_SETTINGS:
- return ngx_http_spdy_state_settings(sc, pos, end);
-
- case NGX_SPDY_PING:
- return ngx_http_spdy_state_ping(sc, pos, end);
-
- case NGX_SPDY_GOAWAY:
- return ngx_http_spdy_state_skip(sc, pos, end); /* TODO */
-
- case NGX_SPDY_HEADERS:
- return ngx_http_spdy_state_protocol_error(sc);
-
- case NGX_SPDY_WINDOW_UPDATE:
- return ngx_http_spdy_state_window_update(sc, pos, end);
-
- default:
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy control frame with unknown type %ui", type);
- return ngx_http_spdy_state_skip(sc, pos, end);
- }
- }
-
- if (ngx_spdy_data_frame_check(head)) {
- sc->stream = ngx_http_spdy_get_stream_by_id(sc, head);
- return ngx_http_spdy_state_data(sc, pos, end);
- }
-
-
- /* TODO version & type check */
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy unknown frame");
-
- return ngx_http_spdy_state_protocol_error(sc);
-}
-
-
-static u_char *
-ngx_http_spdy_state_syn_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- ngx_uint_t sid, prio;
- ngx_http_spdy_stream_t *stream;
- ngx_http_spdy_srv_conf_t *sscf;
-
- if (end - pos < NGX_SPDY_SYN_STREAM_SIZE) {
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_syn_stream);
- }
-
- if (sc->length <= NGX_SPDY_SYN_STREAM_SIZE) {
- /* TODO logging */
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- sc->length -= NGX_SPDY_SYN_STREAM_SIZE;
-
- sid = ngx_spdy_frame_parse_sid(pos);
- prio = pos[8] >> 5;
-
- pos += NGX_SPDY_SYN_STREAM_SIZE;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy SYN_STREAM frame sid:%ui prio:%ui", sid, prio);
-
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
- ngx_http_spdy_module);
-
- if (sc->processing >= sscf->concurrent_streams) {
-
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
- "spdy concurrent streams exceeded %ui", sc->processing);
-
- if (ngx_http_spdy_send_rst_stream(sc, sid, NGX_SPDY_REFUSED_STREAM,
- prio)
- != NGX_OK)
- {
- return ngx_http_spdy_state_internal_error(sc);
- }
-
- return ngx_http_spdy_state_headers_skip(sc, pos, end);
- }
-
- stream = ngx_http_spdy_create_stream(sc, sid, prio);
- if (stream == NULL) {
- return ngx_http_spdy_state_internal_error(sc);
- }
-
- stream->in_closed = (sc->flags & NGX_SPDY_FLAG_FIN) ? 1 : 0;
-
- stream->request->request_length = NGX_SPDY_FRAME_HEADER_SIZE
- + NGX_SPDY_SYN_STREAM_SIZE
- + sc->length;
-
- sc->stream = stream;
-
- sc->last_sid = sid;
-
- return ngx_http_spdy_state_headers(sc, pos, end);
-}
-
-
-static u_char *
-ngx_http_spdy_state_headers(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- int z;
- size_t size;
- ngx_buf_t *buf;
- ngx_int_t rc;
- ngx_uint_t complete;
- ngx_http_request_t *r;
-
- size = end - pos;
-
- if (size == 0) {
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_headers);
- }
-
- if (size >= sc->length) {
- size = sc->length;
- complete = 1;
-
- } else {
- complete = 0;
- }
-
- r = sc->stream->request;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "spdy process HEADERS %uz of %uz", size, sc->length);
-
- buf = r->header_in;
-
- sc->zstream_in.next_in = pos;
- sc->zstream_in.avail_in = size;
- sc->zstream_in.next_out = buf->last;
-
- /* one byte is reserved for null-termination of the last header value */
- sc->zstream_in.avail_out = buf->end - buf->last - 1;
-
- z = inflate(&sc->zstream_in, Z_NO_FLUSH);
-
- if (z == Z_NEED_DICT) {
- z = inflateSetDictionary(&sc->zstream_in, ngx_http_spdy_dict,
- sizeof(ngx_http_spdy_dict));
- if (z != Z_OK) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "spdy inflateSetDictionary() failed: %d", z);
- ngx_http_spdy_close_stream(sc->stream, 0);
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "spdy inflateSetDictionary(): %d", z);
-
- z = sc->zstream_in.avail_in ? inflate(&sc->zstream_in, Z_NO_FLUSH)
- : Z_OK;
- }
-
- if (z != Z_OK) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "spdy inflate() failed: %d", z);
- ngx_http_spdy_close_stream(sc->stream, 0);
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "spdy inflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
- sc->zstream_in.next_in, sc->zstream_in.next_out,
- sc->zstream_in.avail_in, sc->zstream_in.avail_out,
- z);
-
- sc->length -= sc->zstream_in.next_in - pos;
- pos = sc->zstream_in.next_in;
-
- buf->last = sc->zstream_in.next_out;
-
- if (r->headers_in.headers.part.elts == NULL) {
-
- if (buf->last - buf->pos < NGX_SPDY_NV_NUM_SIZE) {
-
- if (complete) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent SYN_STREAM frame "
- "with invalid HEADERS block");
- ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_headers);
- }
-
- sc->entries = ngx_spdy_frame_parse_uint32(buf->pos);
-
- buf->pos += NGX_SPDY_NV_NUM_SIZE;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "spdy HEADERS block consists of %ui entries",
- sc->entries);
-
- if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
- sizeof(ngx_table_elt_t))
- != NGX_OK)
- {
- ngx_http_spdy_close_stream(sc->stream,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return ngx_http_spdy_state_headers_error(sc, pos, end);
- }
-
- if (ngx_array_init(&r->headers_in.cookies, r->pool, 2,
- sizeof(ngx_table_elt_t *))
- != NGX_OK)
- {
- ngx_http_spdy_close_stream(sc->stream,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return ngx_http_spdy_state_headers_error(sc, pos, end);
- }
- }
-
- while (sc->entries) {
-
- rc = ngx_http_spdy_parse_header(r);
-
- switch (rc) {
-
- case NGX_DONE:
- sc->entries--;
-
- case NGX_OK:
- break;
-
- case NGX_AGAIN:
-
- if (sc->zstream_in.avail_in) {
-
- rc = ngx_http_spdy_alloc_large_header_buffer(r);
-
- if (rc == NGX_DECLINED) {
- /* TODO logging */
- ngx_http_finalize_request(r,
- NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
- return ngx_http_spdy_state_headers_error(sc, pos, end);
- }
-
- if (rc != NGX_OK) {
- ngx_http_spdy_close_stream(sc->stream,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return ngx_http_spdy_state_headers_error(sc, pos, end);
- }
-
- /* null-terminate the last processed header name or value */
- *buf->pos = '\0';
-
- buf = r->header_in;
-
- sc->zstream_in.next_out = buf->last;
-
- /* one byte is reserved for null-termination */
- sc->zstream_in.avail_out = buf->end - buf->last - 1;
-
- z = inflate(&sc->zstream_in, Z_NO_FLUSH);
-
- if (z != Z_OK) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "spdy inflate() failed: %d", z);
- ngx_http_spdy_close_stream(sc->stream, 0);
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- sc->length -= sc->zstream_in.next_in - pos;
- pos = sc->zstream_in.next_in;
-
- buf->last = sc->zstream_in.next_out;
-
- continue;
- }
-
- if (complete) {
- /* TODO: improve error message */
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "spdy again while last chunk");
- ngx_http_spdy_close_stream(sc->stream, 0);
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_headers);
-
- case NGX_HTTP_PARSE_INVALID_REQUEST:
-
- /* TODO: improve error message */
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent invalid header line");
-
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
-
- return ngx_http_spdy_state_headers_error(sc, pos, end);
-
- default: /* NGX_HTTP_PARSE_INVALID_HEADER */
-
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent invalid HEADERS spdy frame");
- ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- /* a header line has been parsed successfully */
-
- rc = ngx_http_spdy_handle_request_header(r);
-
- if (rc != NGX_OK) {
- if (rc == NGX_HTTP_PARSE_INVALID_HEADER) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent invalid HEADERS spdy frame");
- ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) {
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- }
-
- return ngx_http_spdy_state_headers_error(sc, pos, end);
- }
- }
-
- if (buf->pos != buf->last || sc->zstream_in.avail_in) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent SYN_STREAM frame "
- "with invalid HEADERS block");
- ngx_http_spdy_close_stream(sc->stream, NGX_HTTP_BAD_REQUEST);
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- if (!complete) {
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_headers);
- }
-
- /* null-terminate the last header value */
- *buf->pos = '\0';
-
- ngx_http_spdy_run_request(r);
-
- return ngx_http_spdy_state_complete(sc, pos, end);
-}
-
-
-static u_char *
-ngx_http_spdy_state_headers_error(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- if (sc->connection->error) {
- return ngx_http_spdy_state_internal_error(sc);
- }
-
- return ngx_http_spdy_state_headers_skip(sc, pos, end);
-}
-
-
-static u_char *
-ngx_http_spdy_state_headers_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- int n;
- size_t size;
- u_char buffer[NGX_SPDY_SKIP_HEADERS_BUFFER_SIZE];
-
- if (sc->length == 0) {
- return ngx_http_spdy_state_complete(sc, pos, end);
- }
-
- size = end - pos;
-
- if (size == 0) {
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_headers_skip);
- }
-
- sc->zstream_in.next_in = pos;
- sc->zstream_in.avail_in = (size < sc->length) ? size : sc->length;
-
- while (sc->zstream_in.avail_in) {
- sc->zstream_in.next_out = buffer;
- sc->zstream_in.avail_out = NGX_SPDY_SKIP_HEADERS_BUFFER_SIZE;
-
- n = inflate(&sc->zstream_in, Z_NO_FLUSH);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy inflate(): %d", n);
-
- if (n != Z_OK) {
- /* TODO: logging */
- return ngx_http_spdy_state_protocol_error(sc);
- }
- }
-
- pos = sc->zstream_in.next_in;
-
- if (size < sc->length) {
- sc->length -= size;
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_headers_skip);
- }
-
- return ngx_http_spdy_state_complete(sc, pos, end);
-}
-
-
-static u_char *
-ngx_http_spdy_state_window_update(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- size_t delta;
- ngx_uint_t sid;
- ngx_event_t *wev;
- ngx_queue_t *q;
- ngx_http_spdy_stream_t *stream;
-
- if (end - pos < NGX_SPDY_WINDOW_UPDATE_SIZE) {
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_window_update);
- }
-
- if (sc->length != NGX_SPDY_WINDOW_UPDATE_SIZE) {
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
- "client sent WINDOW_UPDATE frame "
- "with incorrect length %uz", sc->length);
-
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- sid = ngx_spdy_frame_parse_sid(pos);
-
- pos += NGX_SPDY_SID_SIZE;
-
- delta = ngx_spdy_frame_parse_delta(pos);
-
- pos += NGX_SPDY_DELTA_SIZE;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy WINDOW_UPDATE sid:%ui delta:%ui", sid, delta);
-
- if (sid) {
- stream = ngx_http_spdy_get_stream_by_id(sc, sid);
-
- if (stream == NULL) {
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
- "client sent WINDOW_UPDATE frame "
- "for unknown stream %ui", sid);
-
- if (ngx_http_spdy_send_rst_stream(sc, sid, NGX_SPDY_INVALID_STREAM,
- NGX_SPDY_LOWEST_PRIORITY)
- == NGX_ERROR)
- {
- return ngx_http_spdy_state_internal_error(sc);
- }
-
- return ngx_http_spdy_state_complete(sc, pos, end);
- }
-
- if (stream->send_window > (ssize_t) (NGX_SPDY_MAX_WINDOW - delta)) {
-
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
- "client violated flow control for stream %ui: "
- "received WINDOW_UPDATE frame with delta %uz "
- "that is not allowed for window %z",
- sid, delta, stream->send_window);
-
- if (ngx_http_spdy_terminate_stream(sc, stream,
- NGX_SPDY_FLOW_CONTROL_ERROR)
- == NGX_ERROR)
- {
- return ngx_http_spdy_state_internal_error(sc);
- }
-
- return ngx_http_spdy_state_complete(sc, pos, end);
- }
-
- stream->send_window += delta;
-
- if (stream->exhausted) {
- stream->exhausted = 0;
-
- wev = stream->request->connection->write;
-
- if (!wev->timer_set) {
- wev->delayed = 0;
- wev->handler(wev);
- }
- }
-
- } else {
- sc->send_window += delta;
-
- if (sc->send_window > NGX_SPDY_MAX_WINDOW) {
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
- "client violated connection flow control: "
- "received WINDOW_UPDATE frame with delta %uz "
- "that is not allowed for window %uz",
- delta, sc->send_window);
-
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- while (!ngx_queue_empty(&sc->waiting)) {
- q = ngx_queue_head(&sc->waiting);
-
- ngx_queue_remove(q);
-
- stream = ngx_queue_data(q, ngx_http_spdy_stream_t, queue);
-
- stream->handled = 0;
-
- wev = stream->request->connection->write;
-
- if (!wev->timer_set) {
- wev->delayed = 0;
- wev->handler(wev);
-
- if (sc->send_window == 0) {
- break;
- }
- }
- }
- }
-
- return ngx_http_spdy_state_complete(sc, pos, end);
-}
-
-
-static u_char *
-ngx_http_spdy_state_data(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- ngx_http_spdy_stream_t *stream;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy DATA frame");
-
- if (sc->length > sc->recv_window) {
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
- "client violated connection flow control: length of "
- "received DATA frame %uz, while available window %uz",
- sc->length, sc->recv_window);
-
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- sc->recv_window -= sc->length;
-
- if (sc->recv_window < NGX_SPDY_MAX_WINDOW / 4) {
-
- if (ngx_http_spdy_send_window_update(sc, 0,
- NGX_SPDY_MAX_WINDOW
- - sc->recv_window)
- == NGX_ERROR)
- {
- return ngx_http_spdy_state_internal_error(sc);
- }
-
- sc->recv_window = NGX_SPDY_MAX_WINDOW;
- }
-
- stream = sc->stream;
-
- if (stream == NULL) {
- return ngx_http_spdy_state_skip(sc, pos, end);
- }
-
- if (sc->length > stream->recv_window) {
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
- "client violated flow control for stream %ui: length of "
- "received DATA frame %uz, while available window %uz",
- stream->id, sc->length, stream->recv_window);
-
- if (ngx_http_spdy_terminate_stream(sc, stream,
- NGX_SPDY_FLOW_CONTROL_ERROR)
- == NGX_ERROR)
- {
- return ngx_http_spdy_state_internal_error(sc);
- }
-
- return ngx_http_spdy_state_skip(sc, pos, end);
- }
-
- stream->recv_window -= sc->length;
-
- if (stream->recv_window < NGX_SPDY_STREAM_WINDOW / 4) {
-
- if (ngx_http_spdy_send_window_update(sc, stream->id,
- NGX_SPDY_STREAM_WINDOW
- - stream->recv_window)
- == NGX_ERROR)
- {
- return ngx_http_spdy_state_internal_error(sc);
- }
-
- stream->recv_window = NGX_SPDY_STREAM_WINDOW;
- }
-
- if (stream->in_closed) {
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
- "client sent DATA frame for half closed stream %ui",
- stream->id);
-
- if (ngx_http_spdy_terminate_stream(sc, stream,
- NGX_SPDY_STREAM_ALREADY_CLOSED)
- == NGX_ERROR)
- {
- return ngx_http_spdy_state_internal_error(sc);
- }
-
- return ngx_http_spdy_state_skip(sc, pos, end);
- }
-
- return ngx_http_spdy_state_read_data(sc, pos, end);
-}
-
-
-static u_char *
-ngx_http_spdy_state_read_data(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- size_t size;
- ssize_t n;
- ngx_buf_t *buf;
- ngx_int_t rc;
- ngx_temp_file_t *tf;
- ngx_http_request_t *r;
- ngx_http_spdy_stream_t *stream;
- ngx_http_request_body_t *rb;
- ngx_http_core_loc_conf_t *clcf;
-
- stream = sc->stream;
-
- if (stream == NULL) {
- return ngx_http_spdy_state_skip(sc, pos, end);
- }
-
- if (stream->skip_data) {
-
- if (sc->flags & NGX_SPDY_FLAG_FIN) {
- stream->in_closed = 1;
- }
-
- /* TODO log and accounting */
- return ngx_http_spdy_state_skip(sc, pos, end);
- }
-
- size = end - pos;
-
- if (size > sc->length) {
- size = sc->length;
- }
-
- r = stream->request;
-
- if (r->request_body == NULL
- && ngx_http_spdy_init_request_body(r) != NGX_OK)
- {
- stream->skip_data = NGX_SPDY_DATA_INTERNAL_ERROR;
- return ngx_http_spdy_state_skip(sc, pos, end);
- }
-
- rb = r->request_body;
- tf = rb->temp_file;
- buf = rb->buf;
-
- if (size) {
- rb->rest += size;
-
- if (r->headers_in.content_length_n != -1
- && r->headers_in.content_length_n < rb->rest)
- {
- /* TODO logging */
- stream->skip_data = NGX_SPDY_DATA_ERROR;
- goto error;
-
- } else {
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->client_max_body_size
- && clcf->client_max_body_size < rb->rest)
- {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "client intended to send too large chunked "
- "body: %O bytes",
- rb->rest);
-
- stream->skip_data = NGX_SPDY_DATA_ERROR;
- goto error;
- }
- }
-
- sc->length -= size;
-
- if (tf) {
- buf->start = pos;
- buf->pos = pos;
-
- pos += size;
-
- buf->end = pos;
- buf->last = pos;
-
- n = ngx_write_chain_to_temp_file(tf, rb->bufs);
-
- /* TODO: n == 0 or not complete and level event */
-
- if (n == NGX_ERROR) {
- stream->skip_data = NGX_SPDY_DATA_INTERNAL_ERROR;
- goto error;
- }
-
- tf->offset += n;
-
- } else {
- buf->last = ngx_cpymem(buf->last, pos, size);
- pos += size;
- }
-
- r->request_length += size;
- }
-
- if (sc->length) {
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_read_data);
- }
-
- if (sc->flags & NGX_SPDY_FLAG_FIN) {
-
- stream->in_closed = 1;
-
- if (r->headers_in.content_length_n < 0) {
- r->headers_in.content_length_n = rb->rest;
-
- } else if (r->headers_in.content_length_n != rb->rest) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client prematurely closed stream: "
- "%O of %O bytes of request body received",
- rb->rest, r->headers_in.content_length_n);
-
- stream->skip_data = NGX_SPDY_DATA_ERROR;
- goto error;
- }
-
- if (tf) {
- ngx_memzero(buf, sizeof(ngx_buf_t));
-
- buf->in_file = 1;
- buf->file_last = tf->file.offset;
- buf->file = &tf->file;
-
- rb->buf = NULL;
- }
-
- if (rb->post_handler) {
- r->read_event_handler = ngx_http_block_reading;
- rb->post_handler(r);
- }
- }
-
- return ngx_http_spdy_state_complete(sc, pos, end);
-
-error:
-
- if (rb->post_handler) {
-
- if (stream->skip_data == NGX_SPDY_DATA_ERROR) {
- rc = (r->headers_in.content_length_n == -1)
- ? NGX_HTTP_REQUEST_ENTITY_TOO_LARGE
- : NGX_HTTP_BAD_REQUEST;
-
- } else {
- rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- ngx_http_finalize_request(r, rc);
- }
-
- return ngx_http_spdy_state_skip(sc, pos, end);
-}
-
-
-static u_char *
-ngx_http_spdy_state_rst_stream(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- ngx_uint_t sid, status;
- ngx_event_t *ev;
- ngx_connection_t *fc;
- ngx_http_spdy_stream_t *stream;
-
- if (end - pos < NGX_SPDY_RST_STREAM_SIZE) {
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_rst_stream);
- }
-
- if (sc->length != NGX_SPDY_RST_STREAM_SIZE) {
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
- "client sent RST_STREAM frame with incorrect length %uz",
- sc->length);
-
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- sid = ngx_spdy_frame_parse_sid(pos);
-
- pos += NGX_SPDY_SID_SIZE;
-
- status = ngx_spdy_frame_parse_uint32(pos);
-
- pos += sizeof(uint32_t);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy RST_STREAM sid:%ui st:%ui", sid, status);
-
- stream = ngx_http_spdy_get_stream_by_id(sc, sid);
- if (stream == NULL) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "unknown stream, probably it has been closed already");
- return ngx_http_spdy_state_complete(sc, pos, end);
- }
-
- stream->in_closed = 1;
- stream->out_closed = 1;
-
- fc = stream->request->connection;
- fc->error = 1;
-
- switch (status) {
-
- case NGX_SPDY_CANCEL:
- ngx_log_error(NGX_LOG_INFO, fc->log, 0,
- "client canceled stream %ui", sid);
- break;
-
- case NGX_SPDY_INTERNAL_ERROR:
- ngx_log_error(NGX_LOG_INFO, fc->log, 0,
- "client terminated stream %ui because of internal error",
- sid);
- break;
-
- default:
- ngx_log_error(NGX_LOG_INFO, fc->log, 0,
- "client terminated stream %ui with status %ui",
- sid, status);
- break;
- }
-
- ev = fc->read;
- ev->handler(ev);
-
- return ngx_http_spdy_state_complete(sc, pos, end);
-}
-
-
-static u_char *
-ngx_http_spdy_state_ping(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- u_char *p;
- ngx_buf_t *buf;
- ngx_http_spdy_out_frame_t *frame;
-
- if (end - pos < NGX_SPDY_PING_SIZE) {
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_ping);
- }
-
- if (sc->length != NGX_SPDY_PING_SIZE) {
- /* TODO logging */
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy PING frame");
-
- frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_PING_SIZE,
- NGX_SPDY_HIGHEST_PRIORITY);
- if (frame == NULL) {
- return ngx_http_spdy_state_internal_error(sc);
- }
-
- buf = frame->first->buf;
-
- p = buf->pos;
-
- p = ngx_spdy_frame_write_head(p, NGX_SPDY_PING);
- p = ngx_spdy_frame_write_flags_and_len(p, 0, NGX_SPDY_PING_SIZE);
-
- p = ngx_cpymem(p, pos, NGX_SPDY_PING_SIZE);
-
- buf->last = p;
-
- ngx_http_spdy_queue_frame(sc, frame);
-
- pos += NGX_SPDY_PING_SIZE;
-
- return ngx_http_spdy_state_complete(sc, pos, end);
-}
-
-
-static u_char *
-ngx_http_spdy_state_skip(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- size_t size;
-
- size = end - pos;
-
- if (size < sc->length) {
- sc->length -= size;
- return ngx_http_spdy_state_save(sc, end, end,
- ngx_http_spdy_state_skip);
- }
-
- return ngx_http_spdy_state_complete(sc, pos + sc->length, end);
-}
-
-
-static u_char *
-ngx_http_spdy_state_settings(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- ngx_uint_t fid, val;
-
- if (sc->entries == 0) {
-
- if (end - pos < NGX_SPDY_SETTINGS_NUM_SIZE) {
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_settings);
- }
-
- sc->entries = ngx_spdy_frame_parse_uint32(pos);
-
- pos += NGX_SPDY_SETTINGS_NUM_SIZE;
- sc->length -= NGX_SPDY_SETTINGS_NUM_SIZE;
-
- if (sc->length < sc->entries * NGX_SPDY_SETTINGS_PAIR_SIZE) {
- /* TODO logging */
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy SETTINGS frame consists of %ui entries",
- sc->entries);
- }
-
- while (sc->entries) {
- if (end - pos < NGX_SPDY_SETTINGS_PAIR_SIZE) {
- return ngx_http_spdy_state_save(sc, pos, end,
- ngx_http_spdy_state_settings);
- }
-
- sc->entries--;
- sc->length -= NGX_SPDY_SETTINGS_PAIR_SIZE;
-
- fid = ngx_spdy_frame_parse_uint32(pos);
-
- pos += NGX_SPDY_SETTINGS_FID_SIZE;
-
- val = ngx_spdy_frame_parse_uint32(pos);
-
- pos += NGX_SPDY_SETTINGS_VAL_SIZE;
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy SETTINGS entry fl:%ui id:%ui val:%ui",
- ngx_spdy_frame_flags(fid), ngx_spdy_frame_id(fid), val);
-
- if (ngx_spdy_frame_flags(fid) == NGX_SPDY_SETTINGS_FLAG_PERSISTED) {
- continue;
- }
-
- switch (ngx_spdy_frame_id(fid)) {
-
- case NGX_SPDY_SETTINGS_INIT_WINDOW:
-
- if (val > NGX_SPDY_MAX_WINDOW) {
- ngx_log_error(NGX_LOG_INFO, sc->connection->log, 0,
- "client sent SETTINGS frame with "
- "incorrect INIT_WINDOW value: %ui", val);
-
- return ngx_http_spdy_state_protocol_error(sc);
- }
-
- if (ngx_http_spdy_adjust_windows(sc, val - sc->init_window)
- != NGX_OK)
- {
- return ngx_http_spdy_state_internal_error(sc);
- }
-
- sc->init_window = val;
-
- continue;
- }
- }
-
- return ngx_http_spdy_state_complete(sc, pos, end);
-}
-
-
-static u_char *
-ngx_http_spdy_state_complete(ngx_http_spdy_connection_t *sc, u_char *pos,
- u_char *end)
-{
- sc->handler = ngx_http_spdy_state_head;
- return pos;
-}
-
-
-static u_char *
-ngx_http_spdy_state_save(ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end, ngx_http_spdy_handler_pt handler)
-{
- size_t size;
-
- size = end - pos;
-
- if (size > NGX_SPDY_STATE_BUFFER_SIZE) {
- ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
- "spdy state buffer overflow: "
- "%uz bytes required", size);
- return ngx_http_spdy_state_internal_error(sc);
- }
-
- ngx_memcpy(sc->buffer, pos, NGX_SPDY_STATE_BUFFER_SIZE);
-
- sc->buffer_used = size;
- sc->handler = handler;
- sc->incomplete = 1;
-
- return end;
-}
-
-
-static u_char *
-ngx_http_spdy_state_protocol_error(ngx_http_spdy_connection_t *sc)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy state protocol error");
-
- /* TODO */
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_CLIENT_CLOSED_REQUEST);
- return NULL;
-}
-
-
-static u_char *
-ngx_http_spdy_state_internal_error(ngx_http_spdy_connection_t *sc)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy state internal error");
-
- /* TODO */
- ngx_http_spdy_finalize_connection(sc, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NULL;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_send_window_update(ngx_http_spdy_connection_t *sc, ngx_uint_t sid,
- ngx_uint_t delta)
-{
- u_char *p;
- ngx_buf_t *buf;
- ngx_http_spdy_out_frame_t *frame;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy write WINDOW_UPDATE sid:%ui delta:%ui", sid, delta);
-
- frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_WINDOW_UPDATE_SIZE,
- NGX_SPDY_HIGHEST_PRIORITY);
- if (frame == NULL) {
- return NGX_ERROR;
- }
-
- buf = frame->first->buf;
-
- p = buf->pos;
-
- p = ngx_spdy_frame_write_head(p, NGX_SPDY_WINDOW_UPDATE);
- p = ngx_spdy_frame_write_flags_and_len(p, 0, NGX_SPDY_WINDOW_UPDATE_SIZE);
-
- p = ngx_spdy_frame_write_sid(p, sid);
- p = ngx_spdy_frame_aligned_write_uint32(p, delta);
-
- buf->last = p;
-
- ngx_http_spdy_queue_frame(sc, frame);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_send_rst_stream(ngx_http_spdy_connection_t *sc, ngx_uint_t sid,
- ngx_uint_t status, ngx_uint_t priority)
-{
- u_char *p;
- ngx_buf_t *buf;
- ngx_http_spdy_out_frame_t *frame;
-
- if (sc->connection->error) {
- return NGX_OK;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy write RST_STREAM sid:%ui st:%ui", sid, status);
-
- frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_RST_STREAM_SIZE,
- priority);
- if (frame == NULL) {
- return NGX_ERROR;
- }
-
- buf = frame->first->buf;
-
- p = buf->pos;
-
- p = ngx_spdy_frame_write_head(p, NGX_SPDY_RST_STREAM);
- p = ngx_spdy_frame_write_flags_and_len(p, 0, NGX_SPDY_RST_STREAM_SIZE);
-
- p = ngx_spdy_frame_write_sid(p, sid);
- p = ngx_spdy_frame_aligned_write_uint32(p, status);
-
- buf->last = p;
-
- ngx_http_spdy_queue_frame(sc, frame);
-
- return NGX_OK;
-}
-
-
-#if 0
-static ngx_int_t
-ngx_http_spdy_send_goaway(ngx_http_spdy_connection_t *sc)
-{
- u_char *p;
- ngx_buf_t *buf;
- ngx_http_spdy_out_frame_t *frame;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy create GOAWAY sid:%ui", sc->last_sid);
-
- frame = ngx_http_spdy_get_ctl_frame(sc, NGX_SPDY_GOAWAY_SIZE,
- NGX_SPDY_HIGHEST_PRIORITY);
- if (frame == NULL) {
- return NGX_ERROR;
- }
-
- buf = frame->first->buf;
-
- p = buf->pos;
-
- p = ngx_spdy_frame_write_head(p, NGX_SPDY_GOAWAY);
- p = ngx_spdy_frame_write_flags_and_len(p, 0, NGX_SPDY_GOAWAY_SIZE);
-
- p = ngx_spdy_frame_write_sid(p, sc->last_sid);
-
- buf->last = p;
-
- ngx_http_spdy_queue_frame(sc, frame);
-
- return NGX_OK;
-}
-#endif
-
-
-static ngx_int_t
-ngx_http_spdy_send_settings(ngx_http_spdy_connection_t *sc)
-{
- u_char *p;
- ngx_buf_t *buf;
- ngx_chain_t *cl;
- ngx_http_spdy_srv_conf_t *sscf;
- ngx_http_spdy_out_frame_t *frame;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy create SETTINGS frame");
-
- frame = ngx_palloc(sc->pool, sizeof(ngx_http_spdy_out_frame_t));
- if (frame == NULL) {
- return NGX_ERROR;
- }
-
- cl = ngx_alloc_chain_link(sc->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- buf = ngx_create_temp_buf(sc->pool, NGX_SPDY_FRAME_HEADER_SIZE
- + NGX_SPDY_SETTINGS_NUM_SIZE
- + 2 * NGX_SPDY_SETTINGS_PAIR_SIZE);
- if (buf == NULL) {
- return NGX_ERROR;
- }
-
- buf->last_buf = 1;
-
- cl->buf = buf;
- cl->next = NULL;
-
- frame->first = cl;
- frame->last = cl;
- frame->handler = ngx_http_spdy_settings_frame_handler;
- frame->stream = NULL;
-#if (NGX_DEBUG)
- frame->length = NGX_SPDY_SETTINGS_NUM_SIZE
- + 2 * NGX_SPDY_SETTINGS_PAIR_SIZE;
-#endif
- frame->priority = NGX_SPDY_HIGHEST_PRIORITY;
- frame->blocked = 0;
-
- p = buf->pos;
-
- p = ngx_spdy_frame_write_head(p, NGX_SPDY_SETTINGS);
- p = ngx_spdy_frame_write_flags_and_len(p, NGX_SPDY_FLAG_CLEAR_SETTINGS,
- NGX_SPDY_SETTINGS_NUM_SIZE
- + 2 * NGX_SPDY_SETTINGS_PAIR_SIZE);
-
- p = ngx_spdy_frame_aligned_write_uint32(p, 2);
-
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
- ngx_http_spdy_module);
-
- p = ngx_spdy_frame_write_flags_and_id(p, 0, NGX_SPDY_SETTINGS_MAX_STREAMS);
- p = ngx_spdy_frame_aligned_write_uint32(p, sscf->concurrent_streams);
-
- p = ngx_spdy_frame_write_flags_and_id(p, 0, NGX_SPDY_SETTINGS_INIT_WINDOW);
- p = ngx_spdy_frame_aligned_write_uint32(p, NGX_SPDY_STREAM_WINDOW);
-
- buf->last = p;
-
- ngx_http_spdy_queue_frame(sc, frame);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_spdy_settings_frame_handler(ngx_http_spdy_connection_t *sc,
- ngx_http_spdy_out_frame_t *frame)
-{
- ngx_buf_t *buf;
-
- buf = frame->first->buf;
-
- if (buf->pos != buf->last) {
- return NGX_AGAIN;
- }
-
- ngx_free_chain(sc->pool, frame->first);
-
- return NGX_OK;
-}
-
-
-static ngx_http_spdy_out_frame_t *
-ngx_http_spdy_get_ctl_frame(ngx_http_spdy_connection_t *sc, size_t length,
- ngx_uint_t priority)
-{
- ngx_chain_t *cl;
- ngx_http_spdy_out_frame_t *frame;
-
- frame = sc->free_ctl_frames;
-
- if (frame) {
- sc->free_ctl_frames = frame->next;
-
- cl = frame->first;
- cl->buf->pos = cl->buf->start;
-
- } else {
- frame = ngx_palloc(sc->pool, sizeof(ngx_http_spdy_out_frame_t));
- if (frame == NULL) {
- return NULL;
- }
-
- cl = ngx_alloc_chain_link(sc->pool);
- if (cl == NULL) {
- return NULL;
- }
-
- cl->buf = ngx_create_temp_buf(sc->pool,
- NGX_SPDY_CTL_FRAME_BUFFER_SIZE);
- if (cl->buf == NULL) {
- return NULL;
- }
-
- cl->buf->last_buf = 1;
-
- frame->first = cl;
- frame->last = cl;
- frame->handler = ngx_http_spdy_ctl_frame_handler;
- frame->stream = NULL;
- }
-
-#if (NGX_DEBUG)
- if (length > NGX_SPDY_CTL_FRAME_BUFFER_SIZE - NGX_SPDY_FRAME_HEADER_SIZE) {
- ngx_log_error(NGX_LOG_ALERT, sc->pool->log, 0,
- "requested control frame is too big: %uz", length);
- return NULL;
- }
-
- frame->length = length;
-#endif
-
- frame->priority = priority;
- frame->blocked = 0;
-
- return frame;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_ctl_frame_handler(ngx_http_spdy_connection_t *sc,
- ngx_http_spdy_out_frame_t *frame)
-{
- ngx_buf_t *buf;
-
- buf = frame->first->buf;
-
- if (buf->pos != buf->last) {
- return NGX_AGAIN;
- }
-
- frame->next = sc->free_ctl_frames;
- sc->free_ctl_frames = frame;
-
- return NGX_OK;
-}
-
-
-static ngx_http_spdy_stream_t *
-ngx_http_spdy_create_stream(ngx_http_spdy_connection_t *sc, ngx_uint_t id,
- ngx_uint_t priority)
-{
- ngx_log_t *log;
- ngx_uint_t index;
- ngx_event_t *rev, *wev;
- ngx_connection_t *fc;
- ngx_http_log_ctx_t *ctx;
- ngx_http_request_t *r;
- ngx_http_spdy_stream_t *stream;
- ngx_http_core_srv_conf_t *cscf;
- ngx_http_spdy_srv_conf_t *sscf;
-
- fc = sc->free_fake_connections;
-
- if (fc) {
- sc->free_fake_connections = fc->data;
-
- rev = fc->read;
- wev = fc->write;
- log = fc->log;
- ctx = log->data;
-
- } else {
- fc = ngx_palloc(sc->pool, sizeof(ngx_connection_t));
- if (fc == NULL) {
- return NULL;
- }
-
- rev = ngx_palloc(sc->pool, sizeof(ngx_event_t));
- if (rev == NULL) {
- return NULL;
- }
-
- wev = ngx_palloc(sc->pool, sizeof(ngx_event_t));
- if (wev == NULL) {
- return NULL;
- }
-
- log = ngx_palloc(sc->pool, sizeof(ngx_log_t));
- if (log == NULL) {
- return NULL;
- }
-
- ctx = ngx_palloc(sc->pool, sizeof(ngx_http_log_ctx_t));
- if (ctx == NULL) {
- return NULL;
- }
-
- ctx->connection = fc;
- ctx->request = NULL;
- }
-
- ngx_memcpy(log, sc->connection->log, sizeof(ngx_log_t));
-
- log->data = ctx;
-
- ngx_memzero(rev, sizeof(ngx_event_t));
-
- rev->data = fc;
- rev->ready = 1;
- rev->handler = ngx_http_spdy_close_stream_handler;
- rev->log = log;
-
- ngx_memcpy(wev, rev, sizeof(ngx_event_t));
-
- wev->write = 1;
-
- ngx_memcpy(fc, sc->connection, sizeof(ngx_connection_t));
-
- fc->data = sc->http_connection;
- fc->read = rev;
- fc->write = wev;
- fc->sent = 0;
- fc->log = log;
- fc->buffered = 0;
- fc->sndlowat = 1;
- fc->tcp_nodelay = NGX_TCP_NODELAY_DISABLED;
-
- r = ngx_http_create_request(fc);
- if (r == NULL) {
- return NULL;
- }
-
- r->valid_location = 1;
-
- fc->data = r;
- sc->connection->requests++;
-
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
- r->header_in = ngx_create_temp_buf(r->pool,
- cscf->client_header_buffer_size);
- if (r->header_in == NULL) {
- ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NULL;
- }
-
- r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
-
- stream = ngx_pcalloc(r->pool, sizeof(ngx_http_spdy_stream_t));
- if (stream == NULL) {
- ngx_http_free_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NULL;
- }
-
- r->spdy_stream = stream;
-
- stream->id = id;
- stream->request = r;
- stream->connection = sc;
-
- stream->send_window = sc->init_window;
- stream->recv_window = NGX_SPDY_STREAM_WINDOW;
-
- stream->priority = priority;
-
- sscf = ngx_http_get_module_srv_conf(r, ngx_http_spdy_module);
-
- index = ngx_http_spdy_stream_index(sscf, id);
-
- stream->index = sc->streams_index[index];
- sc->streams_index[index] = stream;
-
- sc->processing++;
-
- return stream;
-}
-
-
-static ngx_http_spdy_stream_t *
-ngx_http_spdy_get_stream_by_id(ngx_http_spdy_connection_t *sc,
- ngx_uint_t sid)
-{
- ngx_http_spdy_stream_t *stream;
- ngx_http_spdy_srv_conf_t *sscf;
-
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
- ngx_http_spdy_module);
-
- stream = sc->streams_index[ngx_http_spdy_stream_index(sscf, sid)];
-
- while (stream) {
- if (stream->id == sid) {
- return stream;
- }
-
- stream = stream->index;
- }
-
- return NULL;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_parse_header(ngx_http_request_t *r)
-{
- u_char *p, *end, ch;
- ngx_uint_t hash;
- ngx_http_core_srv_conf_t *cscf;
-
- enum {
- sw_name_len = 0,
- sw_name,
- sw_value_len,
- sw_value
- } state;
-
- state = r->state;
-
- p = r->header_in->pos;
- end = r->header_in->last;
-
- switch (state) {
-
- case sw_name_len:
-
- if (end - p < NGX_SPDY_NV_NLEN_SIZE) {
- return NGX_AGAIN;
- }
-
- r->lowcase_index = ngx_spdy_frame_parse_uint32(p);
-
- if (r->lowcase_index == 0) {
- return NGX_HTTP_PARSE_INVALID_HEADER;
- }
-
- /* null-terminate the previous header value */
- *p = '\0';
-
- p += NGX_SPDY_NV_NLEN_SIZE;
-
- r->invalid_header = 0;
-
- state = sw_name;
-
- /* fall through */
-
- case sw_name:
-
- if ((ngx_uint_t) (end - p) < r->lowcase_index) {
- break;
- }
-
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
- r->header_name_start = p;
- r->header_name_end = p + r->lowcase_index;
-
- if (p[0] == ':') {
- p++;
- }
-
- hash = 0;
-
- for ( /* void */ ; p != r->header_name_end; p++) {
-
- ch = *p;
-
- hash = ngx_hash(hash, ch);
-
- if ((ch >= 'a' && ch <= 'z')
- || (ch == '-')
- || (ch >= '0' && ch <= '9')
- || (ch == '_' && cscf->underscores_in_headers))
- {
- continue;
- }
-
- switch (ch) {
- case '\0':
- case LF:
- case CR:
- case ':':
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- if (ch >= 'A' && ch <= 'Z') {
- return NGX_HTTP_PARSE_INVALID_HEADER;
- }
-
- r->invalid_header = 1;
- }
-
- r->header_hash = hash;
-
- state = sw_value_len;
-
- /* fall through */
-
- case sw_value_len:
-
- if (end - p < NGX_SPDY_NV_VLEN_SIZE) {
- break;
- }
-
- r->lowcase_index = ngx_spdy_frame_parse_uint32(p);
-
- /* null-terminate header name */
- *p = '\0';
-
- p += NGX_SPDY_NV_VLEN_SIZE;
-
- state = sw_value;
-
- /* fall through */
-
- case sw_value:
-
- if ((ngx_uint_t) (end - p) < r->lowcase_index) {
- break;
- }
-
- r->header_start = p;
-
- while (r->lowcase_index--) {
- ch = *p;
-
- if (ch == '\0') {
-
- if (p == r->header_start) {
- return NGX_ERROR;
- }
-
- r->header_end = p;
- r->header_in->pos = p + 1;
-
- return NGX_OK;
- }
-
- if (ch == CR || ch == LF) {
- return NGX_HTTP_PARSE_INVALID_HEADER;
- }
-
- p++;
- }
-
- r->header_end = p;
- r->header_in->pos = p;
-
- r->state = 0;
-
- return NGX_DONE;
- }
-
- r->header_in->pos = p;
- r->state = state;
-
- return NGX_AGAIN;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_alloc_large_header_buffer(ngx_http_request_t *r)
-{
- u_char *old, *new;
- size_t rest;
- ngx_buf_t *buf;
- ngx_http_spdy_stream_t *stream;
- ngx_http_core_srv_conf_t *cscf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "spdy alloc large header buffer");
-
- stream = r->spdy_stream;
-
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
- if (stream->header_buffers
- == (ngx_uint_t) cscf->large_client_header_buffers.num)
- {
- return NGX_DECLINED;
- }
-
- rest = r->header_in->last - r->header_in->pos;
-
- if (rest >= cscf->large_client_header_buffers.size) {
- return NGX_DECLINED;
- }
-
- buf = ngx_create_temp_buf(r->pool, cscf->large_client_header_buffers.size);
- if (buf == NULL) {
- return NGX_ERROR;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "spdy large header alloc: %p %z",
- buf->pos, buf->end - buf->last);
-
- old = r->header_in->pos;
- new = buf->pos;
-
- if (rest) {
- buf->last = ngx_cpymem(new, old, rest);
- }
-
- r->header_in = buf;
-
- stream->header_buffers++;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_handle_request_header(ngx_http_request_t *r)
-{
- ngx_uint_t i;
- ngx_table_elt_t *h;
- ngx_http_core_srv_conf_t *cscf;
- ngx_http_spdy_request_header_t *sh;
-
- if (r->invalid_header) {
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
- if (cscf->ignore_invalid_headers) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent invalid header: \"%*s\"",
- r->header_end - r->header_name_start,
- r->header_name_start);
- return NGX_OK;
- }
-
- }
-
- if (r->header_name_start[0] == ':') {
- r->header_name_start++;
-
- for (i = 0; i < NGX_SPDY_REQUEST_HEADERS; i++) {
- sh = &ngx_http_spdy_request_headers[i];
-
- if (sh->hash != r->header_hash
- || sh->len != r->header_name_end - r->header_name_start
- || ngx_strncmp(sh->header, r->header_name_start, sh->len) != 0)
- {
- continue;
- }
-
- return sh->handler(r);
- }
-
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- h = ngx_list_push(&r->headers_in.headers);
- if (h == NULL) {
- ngx_http_spdy_close_stream(r->spdy_stream,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_ERROR;
- }
-
- h->hash = r->header_hash;
-
- h->key.len = r->header_name_end - r->header_name_start;
- h->key.data = r->header_name_start;
-
- h->value.len = r->header_end - r->header_start;
- h->value.data = r->header_start;
-
- h->lowcase_key = h->key.data;
-
- return NGX_OK;
-}
-
-
-void
-ngx_http_spdy_request_headers_init(void)
-{
- ngx_uint_t i;
- ngx_http_spdy_request_header_t *h;
-
- for (i = 0; i < NGX_SPDY_REQUEST_HEADERS; i++) {
- h = &ngx_http_spdy_request_headers[i];
- h->hash = ngx_hash_key(h->header, h->len);
- }
-}
-
-
-static ngx_int_t
-ngx_http_spdy_parse_method(ngx_http_request_t *r)
-{
- size_t k, len;
- ngx_uint_t n;
- const u_char *p, *m;
-
- /*
- * This array takes less than 256 sequential bytes,
- * and if typical CPU cache line size is 64 bytes,
- * it is prefetched for 4 load operations.
- */
- static const struct {
- u_char len;
- const u_char method[11];
- uint32_t value;
- } tests[] = {
- { 3, "GET", NGX_HTTP_GET },
- { 4, "POST", NGX_HTTP_POST },
- { 4, "HEAD", NGX_HTTP_HEAD },
- { 7, "OPTIONS", NGX_HTTP_OPTIONS },
- { 8, "PROPFIND", NGX_HTTP_PROPFIND },
- { 3, "PUT", NGX_HTTP_PUT },
- { 5, "MKCOL", NGX_HTTP_MKCOL },
- { 6, "DELETE", NGX_HTTP_DELETE },
- { 4, "COPY", NGX_HTTP_COPY },
- { 4, "MOVE", NGX_HTTP_MOVE },
- { 9, "PROPPATCH", NGX_HTTP_PROPPATCH },
- { 4, "LOCK", NGX_HTTP_LOCK },
- { 6, "UNLOCK", NGX_HTTP_UNLOCK },
- { 5, "PATCH", NGX_HTTP_PATCH },
- { 5, "TRACE", NGX_HTTP_TRACE }
- }, *test;
-
- if (r->method_name.len) {
- return NGX_HTTP_PARSE_INVALID_HEADER;
- }
-
- len = r->header_end - r->header_start;
-
- r->method_name.len = len;
- r->method_name.data = r->header_start;
-
- test = tests;
- n = sizeof(tests) / sizeof(tests[0]);
-
- do {
- if (len == test->len) {
- p = r->method_name.data;
- m = test->method;
- k = len;
-
- do {
- if (*p++ != *m++) {
- goto next;
- }
- } while (--k);
-
- r->method = test->value;
- return NGX_OK;
- }
-
- next:
- test++;
-
- } while (--n);
-
- p = r->method_name.data;
-
- do {
- if ((*p < 'A' || *p > 'Z') && *p != '_') {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent invalid method");
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- p++;
-
- } while (--len);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_parse_scheme(ngx_http_request_t *r)
-{
- if (r->schema_start) {
- return NGX_HTTP_PARSE_INVALID_HEADER;
- }
-
- r->schema_start = r->header_start;
- r->schema_end = r->header_end;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_parse_host(ngx_http_request_t *r)
-{
- ngx_table_elt_t *h;
-
- if (r->headers_in.host) {
- return NGX_HTTP_PARSE_INVALID_HEADER;
- }
-
- h = ngx_list_push(&r->headers_in.headers);
- if (h == NULL) {
- ngx_http_spdy_close_stream(r->spdy_stream,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_ERROR;
- }
-
- r->headers_in.host = h;
-
- h->hash = r->header_hash;
-
- h->key.len = r->header_name_end - r->header_name_start;
- h->key.data = r->header_name_start;
-
- h->value.len = r->header_end - r->header_start;
- h->value.data = r->header_start;
-
- h->lowcase_key = h->key.data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_parse_path(ngx_http_request_t *r)
-{
- if (r->unparsed_uri.len) {
- return NGX_HTTP_PARSE_INVALID_HEADER;
- }
-
- r->uri_start = r->header_start;
- r->uri_end = r->header_end;
-
- if (ngx_http_parse_uri(r) != NGX_OK) {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- if (ngx_http_process_request_uri(r) != NGX_OK) {
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_parse_version(ngx_http_request_t *r)
-{
- u_char *p, ch;
-
- if (r->http_protocol.len) {
- return NGX_HTTP_PARSE_INVALID_HEADER;
- }
-
- p = r->header_start;
-
- if (r->header_end - p < 8 || !(ngx_str5cmp(p, 'H', 'T', 'T', 'P', '/'))) {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- ch = *(p + 5);
-
- if (ch < '1' || ch > '9') {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- r->http_major = ch - '0';
-
- for (p += 6; p != r->header_end - 2; p++) {
-
- ch = *p;
-
- if (ch == '.') {
- break;
- }
-
- if (ch < '0' || ch > '9') {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- r->http_major = r->http_major * 10 + ch - '0';
- }
-
- if (*p != '.') {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- ch = *(p + 1);
-
- if (ch < '0' || ch > '9') {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- r->http_minor = ch - '0';
-
- for (p += 2; p != r->header_end; p++) {
-
- ch = *p;
-
- if (ch < '0' || ch > '9') {
- return NGX_HTTP_PARSE_INVALID_REQUEST;
- }
-
- r->http_minor = r->http_minor * 10 + ch - '0';
- }
-
- r->http_protocol.len = r->header_end - r->header_start;
- r->http_protocol.data = r->header_start;
- r->http_version = r->http_major * 1000 + r->http_minor;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_construct_request_line(ngx_http_request_t *r)
-{
- u_char *p;
-
- if (r->method_name.len == 0
- || r->unparsed_uri.len == 0
- || r->http_protocol.len == 0)
- {
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return NGX_ERROR;
- }
-
- r->request_line.len = r->method_name.len + 1
- + r->unparsed_uri.len + 1
- + r->http_protocol.len;
-
- p = ngx_pnalloc(r->pool, r->request_line.len + 1);
- if (p == NULL) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_ERROR;
- }
-
- r->request_line.data = p;
-
- p = ngx_cpymem(p, r->method_name.data, r->method_name.len);
-
- *p++ = ' ';
-
- p = ngx_cpymem(p, r->unparsed_uri.data, r->unparsed_uri.len);
-
- *p++ = ' ';
-
- ngx_memcpy(p, r->http_protocol.data, r->http_protocol.len + 1);
-
- /* some modules expect the space character after method name */
- r->method_name.data = r->request_line.data;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_spdy_run_request(ngx_http_request_t *r)
-{
- ngx_uint_t i;
- ngx_list_part_t *part;
- ngx_table_elt_t *h;
- ngx_http_header_t *hh;
- ngx_http_core_main_conf_t *cmcf;
-
- if (ngx_http_spdy_construct_request_line(r) != NGX_OK) {
- return;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "spdy http request line: \"%V\"", &r->request_line);
-
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
- part = &r->headers_in.headers.part;
- h = part->elts;
-
- for (i = 0 ;; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- h = part->elts;
- i = 0;
- }
-
- hh = ngx_hash_find(&cmcf->headers_in_hash, h[i].hash,
- h[i].lowcase_key, h[i].key.len);
-
- if (hh && hh->handler(r, &h[i], hh->offset) != NGX_OK) {
- return;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http header: \"%V: %V\"", &h[i].key, &h[i].value);
- }
-
- r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
-
- if (ngx_http_process_request_header(r) != NGX_OK) {
- return;
- }
-
- if (r->headers_in.content_length_n > 0 && r->spdy_stream->in_closed) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client prematurely closed stream");
-
- r->spdy_stream->skip_data = NGX_SPDY_DATA_ERROR;
-
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return;
- }
-
- ngx_http_process_request(r);
-}
-
-
-static ngx_int_t
-ngx_http_spdy_init_request_body(ngx_http_request_t *r)
-{
- ngx_buf_t *buf;
- ngx_temp_file_t *tf;
- ngx_http_request_body_t *rb;
- ngx_http_core_loc_conf_t *clcf;
-
- rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
- if (rb == NULL) {
- return NGX_ERROR;
- }
-
- r->request_body = rb;
-
- if (r->spdy_stream->in_closed) {
- return NGX_OK;
- }
-
- rb->rest = r->headers_in.content_length_n;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (r->request_body_in_file_only
- || rb->rest > (off_t) clcf->client_body_buffer_size
- || rb->rest < 0)
- {
- tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
- if (tf == NULL) {
- return NGX_ERROR;
- }
-
- tf->file.fd = NGX_INVALID_FILE;
- tf->file.log = r->connection->log;
- tf->path = clcf->client_body_temp_path;
- tf->pool = r->pool;
- tf->warn = "a client request body is buffered to a temporary file";
- tf->log_level = r->request_body_file_log_level;
- tf->persistent = r->request_body_in_persistent_file;
- tf->clean = r->request_body_in_clean_file;
-
- if (r->request_body_file_group_access) {
- tf->access = 0660;
- }
-
- rb->temp_file = tf;
-
- if (r->spdy_stream->in_closed
- && ngx_create_temp_file(&tf->file, tf->path, tf->pool,
- tf->persistent, tf->clean, tf->access)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- buf = ngx_calloc_buf(r->pool);
- if (buf == NULL) {
- return NGX_ERROR;
- }
-
- } else {
-
- if (rb->rest == 0) {
- return NGX_OK;
- }
-
- buf = ngx_create_temp_buf(r->pool, (size_t) rb->rest);
- if (buf == NULL) {
- return NGX_ERROR;
- }
- }
-
- rb->buf = buf;
-
- rb->bufs = ngx_alloc_chain_link(r->pool);
- if (rb->bufs == NULL) {
- return NGX_ERROR;
- }
-
- rb->bufs->buf = buf;
- rb->bufs->next = NULL;
-
- rb->rest = 0;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_spdy_read_request_body(ngx_http_request_t *r,
- ngx_http_client_body_handler_pt post_handler)
-{
- ngx_http_spdy_stream_t *stream;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "spdy read request body");
-
- stream = r->spdy_stream;
-
- switch (stream->skip_data) {
-
- case NGX_SPDY_DATA_DISCARD:
- post_handler(r);
- return NGX_OK;
-
- case NGX_SPDY_DATA_ERROR:
- if (r->headers_in.content_length_n == -1) {
- return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
- } else {
- return NGX_HTTP_BAD_REQUEST;
- }
-
- case NGX_SPDY_DATA_INTERNAL_ERROR:
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (!r->request_body && ngx_http_spdy_init_request_body(r) != NGX_OK) {
- stream->skip_data = NGX_SPDY_DATA_INTERNAL_ERROR;
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- if (stream->in_closed) {
- post_handler(r);
- return NGX_OK;
- }
-
- r->request_body->post_handler = post_handler;
-
- r->read_event_handler = ngx_http_test_reading;
- r->write_event_handler = ngx_http_request_empty_handler;
-
- return NGX_AGAIN;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_terminate_stream(ngx_http_spdy_connection_t *sc,
- ngx_http_spdy_stream_t *stream, ngx_uint_t status)
-{
- ngx_event_t *rev;
- ngx_connection_t *fc;
-
- if (ngx_http_spdy_send_rst_stream(sc, stream->id, status,
- NGX_SPDY_HIGHEST_PRIORITY)
- == NGX_ERROR)
- {
- return NGX_ERROR;
- }
-
- stream->out_closed = 1;
-
- fc = stream->request->connection;
- fc->error = 1;
-
- rev = fc->read;
- rev->handler(rev);
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_spdy_close_stream_handler(ngx_event_t *ev)
-{
- ngx_connection_t *fc;
- ngx_http_request_t *r;
-
- fc = ev->data;
- r = fc->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "spdy close stream handler");
-
- ngx_http_spdy_close_stream(r->spdy_stream, 0);
-}
-
-
-void
-ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
-{
- ngx_event_t *ev;
- ngx_connection_t *fc;
- ngx_http_spdy_stream_t **index, *s;
- ngx_http_spdy_srv_conf_t *sscf;
- ngx_http_spdy_connection_t *sc;
-
- sc = stream->connection;
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy close stream %ui, queued %ui, processing %ui",
- stream->id, stream->queued, sc->processing);
-
- fc = stream->request->connection;
-
- if (stream->queued) {
- fc->write->handler = ngx_http_spdy_close_stream_handler;
- return;
- }
-
- if (!stream->out_closed) {
- if (ngx_http_spdy_send_rst_stream(sc, stream->id,
- NGX_SPDY_INTERNAL_ERROR,
- stream->priority)
- != NGX_OK)
- {
- sc->connection->error = 1;
- }
- }
-
- if (sc->stream == stream) {
- sc->stream = NULL;
- }
-
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
- ngx_http_spdy_module);
-
- index = sc->streams_index + ngx_http_spdy_stream_index(sscf, stream->id);
-
- for ( ;; ) {
- s = *index;
-
- if (s == NULL) {
- break;
- }
-
- if (s == stream) {
- *index = s->index;
- break;
- }
-
- index = &s->index;
- }
-
- ngx_http_free_request(stream->request, rc);
-
- ev = fc->read;
-
- if (ev->active || ev->disabled) {
- ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
- "spdy fake read event was activated");
- }
-
- if (ev->timer_set) {
- ngx_del_timer(ev);
- }
-
- if (ev->prev) {
- ngx_delete_posted_event(ev);
- }
-
- ev = fc->write;
-
- if (ev->active || ev->disabled) {
- ngx_log_error(NGX_LOG_ALERT, sc->connection->log, 0,
- "spdy fake write event was activated");
- }
-
- if (ev->timer_set) {
- ngx_del_timer(ev);
- }
-
- if (ev->prev) {
- ngx_delete_posted_event(ev);
- }
-
- fc->data = sc->free_fake_connections;
- sc->free_fake_connections = fc;
-
- sc->processing--;
-
- if (sc->processing || sc->blocked) {
- return;
- }
-
- ev = sc->connection->read;
-
- ev->handler = ngx_http_spdy_handle_connection_handler;
- ngx_post_event(ev, &ngx_posted_events);
-}
-
-
-static void
-ngx_http_spdy_handle_connection_handler(ngx_event_t *rev)
-{
- ngx_connection_t *c;
-
- rev->handler = ngx_http_spdy_read_handler;
-
- if (rev->ready) {
- ngx_http_spdy_read_handler(rev);
- return;
- }
-
- c = rev->data;
-
- ngx_http_spdy_handle_connection(c->data);
-}
-
-
-static void
-ngx_http_spdy_keepalive_handler(ngx_event_t *rev)
-{
- ngx_connection_t *c;
- ngx_http_spdy_srv_conf_t *sscf;
- ngx_http_spdy_connection_t *sc;
-
- c = rev->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "spdy keepalive handler");
-
- if (rev->timedout || c->close) {
- ngx_http_close_connection(c);
- return;
- }
-
-#if (NGX_HAVE_KQUEUE)
-
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
- if (rev->pending_eof) {
- c->log->handler = NULL;
- ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
- "kevent() reported that client %V closed "
- "keepalive connection", &c->addr_text);
-#if (NGX_HTTP_SSL)
- if (c->ssl) {
- c->ssl->no_send_shutdown = 1;
- }
-#endif
- ngx_http_close_connection(c);
- return;
- }
- }
-
-#endif
-
- c->destroyed = 0;
- c->idle = 0;
- ngx_reusable_connection(c, 0);
-
- sc = c->data;
-
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
- ngx_http_spdy_module);
-
- sc->pool = ngx_create_pool(sscf->pool_size, sc->connection->log);
- if (sc->pool == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- sc->streams_index = ngx_pcalloc(sc->pool,
- ngx_http_spdy_streams_index_size(sscf)
- * sizeof(ngx_http_spdy_stream_t *));
- if (sc->streams_index == NULL) {
- ngx_http_close_connection(c);
- return;
- }
-
- c->write->handler = ngx_http_spdy_write_handler;
-
- rev->handler = ngx_http_spdy_read_handler;
- ngx_http_spdy_read_handler(rev);
-}
-
-
-static void
-ngx_http_spdy_finalize_connection(ngx_http_spdy_connection_t *sc,
- ngx_int_t rc)
-{
- ngx_uint_t i, size;
- ngx_event_t *ev;
- ngx_connection_t *c, *fc;
- ngx_http_request_t *r;
- ngx_http_spdy_stream_t *stream;
- ngx_http_spdy_srv_conf_t *sscf;
-
- c = sc->connection;
-
- if (!sc->processing) {
- ngx_http_close_connection(c);
- return;
- }
-
- c->error = 1;
- c->read->handler = ngx_http_empty_handler;
- c->write->handler = ngx_http_empty_handler;
-
- sc->last_out = NULL;
-
- sc->blocked = 1;
-
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
- ngx_http_spdy_module);
-
- size = ngx_http_spdy_streams_index_size(sscf);
-
- for (i = 0; i < size; i++) {
- stream = sc->streams_index[i];
-
- while (stream) {
- stream->handled = 0;
-
- r = stream->request;
- fc = r->connection;
-
- fc->error = 1;
-
- if (stream->queued) {
- stream->queued = 0;
-
- ev = fc->write;
- ev->delayed = 0;
-
- } else {
- ev = fc->read;
- }
-
- stream = stream->index;
-
- ev->eof = 1;
- ev->handler(ev);
- }
- }
-
- sc->blocked = 0;
-
- if (sc->processing) {
- return;
- }
-
- ngx_http_close_connection(c);
-}
-
-
-static ngx_int_t
-ngx_http_spdy_adjust_windows(ngx_http_spdy_connection_t *sc, ssize_t delta)
-{
- ngx_uint_t i, size;
- ngx_event_t *wev;
- ngx_http_spdy_stream_t *stream, *sn;
- ngx_http_spdy_srv_conf_t *sscf;
-
- sscf = ngx_http_get_module_srv_conf(sc->http_connection->conf_ctx,
- ngx_http_spdy_module);
-
- size = ngx_http_spdy_streams_index_size(sscf);
-
- for (i = 0; i < size; i++) {
-
- for (stream = sc->streams_index[i]; stream; stream = sn) {
- sn = stream->index;
-
- if (delta > 0
- && stream->send_window
- > (ssize_t) (NGX_SPDY_MAX_WINDOW - delta))
- {
- if (ngx_http_spdy_terminate_stream(sc, stream,
- NGX_SPDY_FLOW_CONTROL_ERROR)
- == NGX_ERROR)
- {
- return NGX_ERROR;
- }
-
- continue;
- }
-
- stream->send_window += delta;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy:%ui adjust window:%z",
- stream->id, stream->send_window);
-
- if (stream->send_window > 0 && stream->exhausted) {
- stream->exhausted = 0;
-
- wev = stream->request->connection->write;
-
- if (!wev->timer_set) {
- wev->delayed = 0;
- wev->handler(wev);
- }
- }
- }
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_spdy_pool_cleanup(void *data)
-{
- ngx_http_spdy_connection_t *sc = data;
-
- if (sc->pool) {
- ngx_destroy_pool(sc->pool);
- }
-}
-
-
-static void *
-ngx_http_spdy_zalloc(void *opaque, u_int items, u_int size)
-{
- ngx_http_spdy_connection_t *sc = opaque;
-
- return ngx_palloc(sc->connection->pool, items * size);
-}
-
-
-static void
-ngx_http_spdy_zfree(void *opaque, void *address)
-{
-#if 0
- ngx_http_spdy_connection_t *sc = opaque;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy zfree: %p", address);
-#endif
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_spdy.h b/usr.sbin/nginx/src/http/ngx_http_spdy.h
deleted file mode 100644
index 55aceda8999..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_spdy.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) Nginx, Inc.
- * Copyright (C) Valentin V. Bartenev
- */
-
-
-#ifndef _NGX_HTTP_SPDY_H_INCLUDED_
-#define _NGX_HTTP_SPDY_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-#include <zlib.h>
-
-
-#define NGX_SPDY_VERSION 3
-
-#define NGX_SPDY_NPN_ADVERTISE "\x08spdy/3.1"
-#define NGX_SPDY_NPN_NEGOTIATED "spdy/3.1"
-
-#define NGX_SPDY_STATE_BUFFER_SIZE 16
-
-#define NGX_SPDY_CTL_BIT 1
-
-#define NGX_SPDY_SYN_STREAM 1
-#define NGX_SPDY_SYN_REPLY 2
-#define NGX_SPDY_RST_STREAM 3
-#define NGX_SPDY_SETTINGS 4
-#define NGX_SPDY_PING 6
-#define NGX_SPDY_GOAWAY 7
-#define NGX_SPDY_HEADERS 8
-#define NGX_SPDY_WINDOW_UPDATE 9
-
-#define NGX_SPDY_FRAME_HEADER_SIZE 8
-
-#define NGX_SPDY_SID_SIZE 4
-#define NGX_SPDY_DELTA_SIZE 4
-
-#define NGX_SPDY_SYN_STREAM_SIZE 10
-#define NGX_SPDY_SYN_REPLY_SIZE 4
-#define NGX_SPDY_RST_STREAM_SIZE 8
-#define NGX_SPDY_PING_SIZE 4
-#define NGX_SPDY_GOAWAY_SIZE 8
-#define NGX_SPDY_WINDOW_UPDATE_SIZE 8
-#define NGX_SPDY_NV_NUM_SIZE 4
-#define NGX_SPDY_NV_NLEN_SIZE 4
-#define NGX_SPDY_NV_VLEN_SIZE 4
-#define NGX_SPDY_SETTINGS_NUM_SIZE 4
-#define NGX_SPDY_SETTINGS_FID_SIZE 4
-#define NGX_SPDY_SETTINGS_VAL_SIZE 4
-
-#define NGX_SPDY_SETTINGS_PAIR_SIZE \
- (NGX_SPDY_SETTINGS_FID_SIZE + NGX_SPDY_SETTINGS_VAL_SIZE)
-
-#define NGX_SPDY_HIGHEST_PRIORITY 0
-#define NGX_SPDY_LOWEST_PRIORITY 7
-
-#define NGX_SPDY_FLAG_FIN 0x01
-#define NGX_SPDY_FLAG_UNIDIRECTIONAL 0x02
-#define NGX_SPDY_FLAG_CLEAR_SETTINGS 0x01
-
-#define NGX_SPDY_MAX_FRAME_SIZE ((1 << 24) - 1)
-
-#define NGX_SPDY_DATA_DISCARD 1
-#define NGX_SPDY_DATA_ERROR 2
-#define NGX_SPDY_DATA_INTERNAL_ERROR 3
-
-
-typedef struct ngx_http_spdy_connection_s ngx_http_spdy_connection_t;
-typedef struct ngx_http_spdy_out_frame_s ngx_http_spdy_out_frame_t;
-
-
-typedef u_char *(*ngx_http_spdy_handler_pt) (ngx_http_spdy_connection_t *sc,
- u_char *pos, u_char *end);
-
-struct ngx_http_spdy_connection_s {
- ngx_connection_t *connection;
- ngx_http_connection_t *http_connection;
-
- ngx_uint_t processing;
-
- size_t send_window;
- size_t recv_window;
- size_t init_window;
-
- ngx_queue_t waiting;
-
- u_char buffer[NGX_SPDY_STATE_BUFFER_SIZE];
- size_t buffer_used;
- ngx_http_spdy_handler_pt handler;
-
- z_stream zstream_in;
- z_stream zstream_out;
-
- ngx_pool_t *pool;
-
- ngx_http_spdy_out_frame_t *free_ctl_frames;
- ngx_connection_t *free_fake_connections;
-
- ngx_http_spdy_stream_t **streams_index;
-
- ngx_http_spdy_out_frame_t *last_out;
-
- ngx_queue_t posted;
-
- ngx_http_spdy_stream_t *stream;
-
- ngx_uint_t entries;
- size_t length;
- u_char flags;
-
- ngx_uint_t last_sid;
-
- unsigned blocked:1;
- unsigned incomplete:1;
-};
-
-
-struct ngx_http_spdy_stream_s {
- ngx_uint_t id;
- ngx_http_request_t *request;
- ngx_http_spdy_connection_t *connection;
- ngx_http_spdy_stream_t *index;
-
- ngx_uint_t header_buffers;
- ngx_uint_t queued;
-
- /*
- * A change to SETTINGS_INITIAL_WINDOW_SIZE could cause the
- * send_window to become negative, hence it's signed.
- */
- ssize_t send_window;
- size_t recv_window;
-
- ngx_http_spdy_out_frame_t *free_frames;
- ngx_chain_t *free_data_headers;
- ngx_chain_t *free_bufs;
-
- ngx_queue_t queue;
-
- unsigned priority:3;
- unsigned handled:1;
- unsigned blocked:1;
- unsigned exhausted:1;
- unsigned in_closed:1;
- unsigned out_closed:1;
- unsigned skip_data:2;
-};
-
-
-struct ngx_http_spdy_out_frame_s {
- ngx_http_spdy_out_frame_t *next;
- ngx_chain_t *first;
- ngx_chain_t *last;
- ngx_int_t (*handler)(ngx_http_spdy_connection_t *sc,
- ngx_http_spdy_out_frame_t *frame);
-
- ngx_http_spdy_stream_t *stream;
- size_t length;
-
- ngx_uint_t priority;
- unsigned blocked:1;
- unsigned fin:1;
-};
-
-
-static ngx_inline void
-ngx_http_spdy_queue_frame(ngx_http_spdy_connection_t *sc,
- ngx_http_spdy_out_frame_t *frame)
-{
- ngx_http_spdy_out_frame_t **out;
-
- for (out = &sc->last_out; *out; out = &(*out)->next)
- {
- /*
- * NB: higher values represent lower priorities.
- */
- if (frame->priority >= (*out)->priority) {
- break;
- }
- }
-
- frame->next = *out;
- *out = frame;
-}
-
-
-static ngx_inline void
-ngx_http_spdy_queue_blocked_frame(ngx_http_spdy_connection_t *sc,
- ngx_http_spdy_out_frame_t *frame)
-{
- ngx_http_spdy_out_frame_t **out;
-
- for (out = &sc->last_out; *out; out = &(*out)->next)
- {
- if ((*out)->blocked) {
- break;
- }
- }
-
- frame->next = *out;
- *out = frame;
-}
-
-
-void ngx_http_spdy_init(ngx_event_t *rev);
-void ngx_http_spdy_request_headers_init(void);
-
-ngx_int_t ngx_http_spdy_read_request_body(ngx_http_request_t *r,
- ngx_http_client_body_handler_pt post_handler);
-
-void ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc);
-
-ngx_int_t ngx_http_spdy_send_output_queue(ngx_http_spdy_connection_t *sc);
-
-
-#define ngx_spdy_frame_aligned_write_uint16(p, s) \
- (*(uint16_t *) (p) = htons((uint16_t) (s)), (p) + sizeof(uint16_t))
-
-#define ngx_spdy_frame_aligned_write_uint32(p, s) \
- (*(uint32_t *) (p) = htonl((uint32_t) (s)), (p) + sizeof(uint32_t))
-
-#if (NGX_HAVE_NONALIGNED)
-
-#define ngx_spdy_frame_write_uint16 ngx_spdy_frame_aligned_write_uint16
-#define ngx_spdy_frame_write_uint32 ngx_spdy_frame_aligned_write_uint32
-
-#else
-
-#define ngx_spdy_frame_write_uint16(p, s) \
- ((p)[0] = (u_char) (s) >> 8, (p)[1] = (u_char) (s), (p) + sizeof(uint16_t))
-
-#define ngx_spdy_frame_write_uint32(p, s) \
- ((p)[0] = (u_char) (s) >> 24, \
- (p)[1] = (u_char) (s) >> 16, \
- (p)[2] = (u_char) (s) >> 8, \
- (p)[3] = (u_char) (s), (p) + sizeof(uint32_t))
-
-#endif
-
-
-#define ngx_spdy_ctl_frame_head(t) \
- ((uint32_t) NGX_SPDY_CTL_BIT << 31 | NGX_SPDY_VERSION << 16 | (t))
-
-#define ngx_spdy_frame_write_head(p, t) \
- ngx_spdy_frame_aligned_write_uint32(p, ngx_spdy_ctl_frame_head(t))
-
-#define ngx_spdy_frame_write_flags_and_len(p, f, l) \
- ngx_spdy_frame_aligned_write_uint32(p, (f) << 24 | (l))
-#define ngx_spdy_frame_write_flags_and_id(p, f, i) \
- ngx_spdy_frame_aligned_write_uint32(p, (f) << 24 | (i))
-
-#define ngx_spdy_frame_write_sid ngx_spdy_frame_aligned_write_uint32
-#define ngx_spdy_frame_write_window ngx_spdy_frame_aligned_write_uint32
-
-#endif /* _NGX_HTTP_SPDY_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/ngx_http_spdy_filter_module.c b/usr.sbin/nginx/src/http/ngx_http_spdy_filter_module.c
deleted file mode 100644
index 559fb4aab9a..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_spdy_filter_module.c
+++ /dev/null
@@ -1,1214 +0,0 @@
-
-/*
- * Copyright (C) Nginx, Inc.
- * Copyright (C) Valentin V. Bartenev
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-#include <nginx.h>
-#include <ngx_http_spdy_module.h>
-
-#include <zlib.h>
-
-
-#define ngx_http_spdy_nv_nsize(h) (NGX_SPDY_NV_NLEN_SIZE + sizeof(h) - 1)
-#define ngx_http_spdy_nv_vsize(h) (NGX_SPDY_NV_VLEN_SIZE + sizeof(h) - 1)
-
-#define ngx_http_spdy_nv_write_num ngx_spdy_frame_write_uint32
-#define ngx_http_spdy_nv_write_nlen ngx_spdy_frame_write_uint32
-#define ngx_http_spdy_nv_write_vlen ngx_spdy_frame_write_uint32
-
-#define ngx_http_spdy_nv_write_name(p, h) \
- ngx_cpymem(ngx_http_spdy_nv_write_nlen(p, sizeof(h) - 1), h, sizeof(h) - 1)
-
-#define ngx_http_spdy_nv_write_val(p, h) \
- ngx_cpymem(ngx_http_spdy_nv_write_vlen(p, sizeof(h) - 1), h, sizeof(h) - 1)
-
-
-static ngx_chain_t *ngx_http_spdy_send_chain(ngx_connection_t *fc,
- ngx_chain_t *in, off_t limit);
-
-static ngx_inline ngx_int_t ngx_http_spdy_filter_send(
- ngx_connection_t *fc, ngx_http_spdy_stream_t *stream);
-static ngx_inline ngx_int_t ngx_http_spdy_flow_control(
- ngx_http_spdy_connection_t *sc, ngx_http_spdy_stream_t *stream);
-static void ngx_http_spdy_waiting_queue(ngx_http_spdy_connection_t *sc,
- ngx_http_spdy_stream_t *stream);
-
-static ngx_chain_t *ngx_http_spdy_filter_get_shadow(
- ngx_http_spdy_stream_t *stream, ngx_buf_t *buf, off_t offset, off_t size);
-static ngx_http_spdy_out_frame_t *ngx_http_spdy_filter_get_data_frame(
- ngx_http_spdy_stream_t *stream, size_t len, ngx_chain_t *first,
- ngx_chain_t *last);
-
-static ngx_int_t ngx_http_spdy_syn_frame_handler(
- ngx_http_spdy_connection_t *sc, ngx_http_spdy_out_frame_t *frame);
-static ngx_int_t ngx_http_spdy_data_frame_handler(
- ngx_http_spdy_connection_t *sc, ngx_http_spdy_out_frame_t *frame);
-static ngx_inline void ngx_http_spdy_handle_frame(
- ngx_http_spdy_stream_t *stream, ngx_http_spdy_out_frame_t *frame);
-static ngx_inline void ngx_http_spdy_handle_stream(
- ngx_http_spdy_connection_t *sc, ngx_http_spdy_stream_t *stream);
-
-static void ngx_http_spdy_filter_cleanup(void *data);
-
-static ngx_int_t ngx_http_spdy_filter_init(ngx_conf_t *cf);
-
-
-static ngx_http_module_t ngx_http_spdy_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_spdy_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_spdy_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_spdy_filter_module_ctx, /* module context */
- NULL, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-
-
-static ngx_int_t
-ngx_http_spdy_header_filter(ngx_http_request_t *r)
-{
- int rc;
- size_t len;
- u_char *p, *buf, *last;
- ngx_buf_t *b;
- ngx_str_t host;
- ngx_uint_t i, j, count, port;
- ngx_chain_t *cl;
- ngx_list_part_t *part, *pt;
- ngx_table_elt_t *header, *h;
- ngx_connection_t *c;
- ngx_http_cleanup_t *cln;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_core_srv_conf_t *cscf;
- ngx_http_spdy_stream_t *stream;
- ngx_http_spdy_out_frame_t *frame;
- ngx_http_spdy_connection_t *sc;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
- u_char addr[NGX_SOCKADDR_STRLEN];
-
- if (!r->spdy_stream) {
- return ngx_http_next_header_filter(r);
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "spdy header filter");
-
- if (r->header_sent) {
- return NGX_OK;
- }
-
- r->header_sent = 1;
-
- if (r != r->main) {
- return NGX_OK;
- }
-
- c = r->connection;
-
- if (r->method == NGX_HTTP_HEAD) {
- r->header_only = 1;
- }
-
- switch (r->headers_out.status) {
-
- case NGX_HTTP_OK:
- case NGX_HTTP_PARTIAL_CONTENT:
- break;
-
- case NGX_HTTP_NOT_MODIFIED:
- r->header_only = 1;
- break;
-
- case NGX_HTTP_NO_CONTENT:
- r->header_only = 1;
-
- ngx_str_null(&r->headers_out.content_type);
-
- r->headers_out.content_length = NULL;
- r->headers_out.content_length_n = -1;
-
- /* fall through */
-
- default:
- r->headers_out.last_modified_time = -1;
- r->headers_out.last_modified = NULL;
- }
-
- len = NGX_SPDY_NV_NUM_SIZE
- + ngx_http_spdy_nv_nsize(":version")
- + ngx_http_spdy_nv_vsize("HTTP/1.1")
- + ngx_http_spdy_nv_nsize(":status")
- + (r->headers_out.status_line.len
- ? NGX_SPDY_NV_VLEN_SIZE + r->headers_out.status_line.len
- : ngx_http_spdy_nv_vsize("418"));
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (r->headers_out.server == NULL) {
- len += ngx_http_spdy_nv_nsize("server");
- len += clcf->server_tokens ? ngx_http_spdy_nv_vsize(NGINX_VER)
- : ngx_http_spdy_nv_vsize("nginx");
- }
-
- if (r->headers_out.date == NULL) {
- len += ngx_http_spdy_nv_nsize("date")
- + ngx_http_spdy_nv_vsize("Wed, 31 Dec 1986 10:00:00 GMT");
- }
-
- if (r->headers_out.content_type.len) {
- len += ngx_http_spdy_nv_nsize("content-type")
- + NGX_SPDY_NV_VLEN_SIZE + r->headers_out.content_type.len;
-
- if (r->headers_out.content_type_len == r->headers_out.content_type.len
- && r->headers_out.charset.len)
- {
- len += sizeof("; charset=") - 1 + r->headers_out.charset.len;
- }
- }
-
- if (r->headers_out.content_length == NULL
- && r->headers_out.content_length_n >= 0)
- {
- len += ngx_http_spdy_nv_nsize("content-length")
- + NGX_SPDY_NV_VLEN_SIZE + NGX_OFF_T_LEN;
- }
-
- if (r->headers_out.last_modified == NULL
- && r->headers_out.last_modified_time != -1)
- {
- len += ngx_http_spdy_nv_nsize("last-modified")
- + ngx_http_spdy_nv_vsize("Wed, 31 Dec 1986 10:00:00 GMT");
- }
-
- if (r->headers_out.location
- && r->headers_out.location->value.len
- && r->headers_out.location->value.data[0] == '/')
- {
- r->headers_out.location->hash = 0;
-
- if (clcf->server_name_in_redirect) {
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
- host = cscf->server_name;
-
- } else if (r->headers_in.server.len) {
- host = r->headers_in.server;
-
- } else {
- host.len = NGX_SOCKADDR_STRLEN;
- host.data = addr;
-
- if (ngx_connection_local_sockaddr(c, &host, 0) != NGX_OK) {
- return NGX_ERROR;
- }
- }
-
- switch (c->local_sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
- port = ntohs(sin6->sin6_port);
- break;
-#endif
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- port = 0;
- break;
-#endif
- default: /* AF_INET */
- sin = (struct sockaddr_in *) c->local_sockaddr;
- port = ntohs(sin->sin_port);
- break;
- }
-
- len += ngx_http_spdy_nv_nsize("location")
- + ngx_http_spdy_nv_vsize("https://")
- + host.len
- + r->headers_out.location->value.len;
-
- if (clcf->port_in_redirect) {
-
-#if (NGX_HTTP_SSL)
- if (c->ssl)
- port = (port == 443) ? 0 : port;
- else
-#endif
- port = (port == 80) ? 0 : port;
-
- } else {
- port = 0;
- }
-
- if (port) {
- len += sizeof(":65535") - 1;
- }
-
- } else {
- ngx_str_null(&host);
- port = 0;
- }
-
- part = &r->headers_out.headers.part;
- header = part->elts;
-
- for (i = 0; /* void */; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- if (header[i].hash == 0) {
- continue;
- }
-
- len += NGX_SPDY_NV_NLEN_SIZE + header[i].key.len
- + NGX_SPDY_NV_VLEN_SIZE + header[i].value.len;
- }
-
- buf = ngx_alloc(len, r->pool->log);
- if (buf == NULL) {
- return NGX_ERROR;
- }
-
- last = buf + NGX_SPDY_NV_NUM_SIZE;
-
- last = ngx_http_spdy_nv_write_name(last, ":version");
- last = ngx_http_spdy_nv_write_val(last, "HTTP/1.1");
-
- last = ngx_http_spdy_nv_write_name(last, ":status");
-
- if (r->headers_out.status_line.len) {
- last = ngx_http_spdy_nv_write_vlen(last,
- r->headers_out.status_line.len);
- last = ngx_cpymem(last, r->headers_out.status_line.data,
- r->headers_out.status_line.len);
- } else {
- last = ngx_http_spdy_nv_write_vlen(last, 3);
- last = ngx_sprintf(last, "%03ui", r->headers_out.status);
- }
-
- count = 2;
-
- if (r->headers_out.server == NULL) {
- last = ngx_http_spdy_nv_write_name(last, "server");
- last = clcf->server_tokens
- ? ngx_http_spdy_nv_write_val(last, NGINX_VER)
- : ngx_http_spdy_nv_write_val(last, "nginx");
-
- count++;
- }
-
- if (r->headers_out.date == NULL) {
- last = ngx_http_spdy_nv_write_name(last, "date");
-
- last = ngx_http_spdy_nv_write_vlen(last, ngx_cached_http_time.len);
-
- last = ngx_cpymem(last, ngx_cached_http_time.data,
- ngx_cached_http_time.len);
-
- count++;
- }
-
- if (r->headers_out.content_type.len) {
-
- last = ngx_http_spdy_nv_write_name(last, "content-type");
-
- p = last + NGX_SPDY_NV_VLEN_SIZE;
-
- last = ngx_cpymem(p, r->headers_out.content_type.data,
- r->headers_out.content_type.len);
-
- if (r->headers_out.content_type_len == r->headers_out.content_type.len
- && r->headers_out.charset.len)
- {
- last = ngx_cpymem(last, "; charset=", sizeof("; charset=") - 1);
-
- last = ngx_cpymem(last, r->headers_out.charset.data,
- r->headers_out.charset.len);
-
- /* update r->headers_out.content_type for possible logging */
-
- r->headers_out.content_type.len = last - p;
- r->headers_out.content_type.data = p;
- }
-
- (void) ngx_http_spdy_nv_write_vlen(p - NGX_SPDY_NV_VLEN_SIZE,
- r->headers_out.content_type.len);
-
- count++;
- }
-
- if (r->headers_out.content_length == NULL
- && r->headers_out.content_length_n >= 0)
- {
- last = ngx_http_spdy_nv_write_name(last, "content-length");
-
- p = last + NGX_SPDY_NV_VLEN_SIZE;
-
- last = ngx_sprintf(p, "%O", r->headers_out.content_length_n);
-
- (void) ngx_http_spdy_nv_write_vlen(p - NGX_SPDY_NV_VLEN_SIZE,
- last - p);
-
- count++;
- }
-
- if (r->headers_out.last_modified == NULL
- && r->headers_out.last_modified_time != -1)
- {
- last = ngx_http_spdy_nv_write_name(last, "last-modified");
-
- p = last + NGX_SPDY_NV_VLEN_SIZE;
-
- last = ngx_http_time(p, r->headers_out.last_modified_time);
-
- (void) ngx_http_spdy_nv_write_vlen(p - NGX_SPDY_NV_VLEN_SIZE,
- last - p);
-
- count++;
- }
-
- if (host.data) {
-
- last = ngx_http_spdy_nv_write_name(last, "location");
-
- p = last + NGX_SPDY_NV_VLEN_SIZE;
-
- last = ngx_cpymem(p, "http", sizeof("http") - 1);
-
-#if (NGX_HTTP_SSL)
- if (c->ssl) {
- *last++ ='s';
- }
-#endif
-
- *last++ = ':'; *last++ = '/'; *last++ = '/';
-
- last = ngx_cpymem(last, host.data, host.len);
-
- if (port) {
- last = ngx_sprintf(last, ":%ui", port);
- }
-
- last = ngx_cpymem(last, r->headers_out.location->value.data,
- r->headers_out.location->value.len);
-
- /* update r->headers_out.location->value for possible logging */
-
- r->headers_out.location->value.len = last - p;
- r->headers_out.location->value.data = p;
- ngx_str_set(&r->headers_out.location->key, "location");
-
- (void) ngx_http_spdy_nv_write_vlen(p - NGX_SPDY_NV_VLEN_SIZE,
- r->headers_out.location->value.len);
-
- count++;
- }
-
- part = &r->headers_out.headers.part;
- header = part->elts;
-
- for (i = 0; /* void */; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- if (header[i].hash == 0 || header[i].hash == 2) {
- continue;
- }
-
- last = ngx_http_spdy_nv_write_nlen(last, header[i].key.len);
-
- ngx_strlow(last, header[i].key.data, header[i].key.len);
- last += header[i].key.len;
-
- p = last + NGX_SPDY_NV_VLEN_SIZE;
-
- last = ngx_cpymem(p, header[i].value.data, header[i].value.len);
-
- pt = part;
- h = header;
-
- for (j = i + 1; /* void */; j++) {
-
- if (j >= pt->nelts) {
- if (pt->next == NULL) {
- break;
- }
-
- pt = pt->next;
- h = pt->elts;
- j = 0;
- }
-
- if (h[j].hash == 0 || h[j].hash == 2
- || h[j].key.len != header[i].key.len
- || ngx_strncasecmp(header[i].key.data, h[j].key.data,
- header[i].key.len))
- {
- continue;
- }
-
- *last++ = '\0';
-
- last = ngx_cpymem(last, h[j].value.data, h[j].value.len);
-
- h[j].hash = 2;
- }
-
- (void) ngx_http_spdy_nv_write_vlen(p - NGX_SPDY_NV_VLEN_SIZE,
- last - p);
-
- count++;
- }
-
- (void) ngx_http_spdy_nv_write_num(buf, count);
-
- stream = r->spdy_stream;
- sc = stream->connection;
-
- len = last - buf;
-
- b = ngx_create_temp_buf(r->pool, NGX_SPDY_FRAME_HEADER_SIZE
- + NGX_SPDY_SYN_REPLY_SIZE
- + deflateBound(&sc->zstream_out, len));
- if (b == NULL) {
- ngx_free(buf);
- return NGX_ERROR;
- }
-
- b->last += NGX_SPDY_FRAME_HEADER_SIZE + NGX_SPDY_SYN_REPLY_SIZE;
-
- sc->zstream_out.next_in = buf;
- sc->zstream_out.avail_in = len;
- sc->zstream_out.next_out = b->last;
- sc->zstream_out.avail_out = b->end - b->last;
-
- rc = deflate(&sc->zstream_out, Z_SYNC_FLUSH);
-
- ngx_free(buf);
-
- if (rc != Z_OK) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "spdy deflate() failed: %d", rc);
- return NGX_ERROR;
- }
-
- ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "spdy deflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
- sc->zstream_out.next_in, sc->zstream_out.next_out,
- sc->zstream_out.avail_in, sc->zstream_out.avail_out,
- rc);
-
- b->last = sc->zstream_out.next_out;
-
- p = b->pos;
- p = ngx_spdy_frame_write_head(p, NGX_SPDY_SYN_REPLY);
-
- len = b->last - b->pos;
-
- r->header_size = len;
-
- len -= NGX_SPDY_FRAME_HEADER_SIZE;
-
- if (r->header_only) {
- b->last_buf = 1;
- p = ngx_spdy_frame_write_flags_and_len(p, NGX_SPDY_FLAG_FIN, len);
-
- } else {
- p = ngx_spdy_frame_write_flags_and_len(p, 0, len);
- }
-
- (void) ngx_spdy_frame_write_sid(p, stream->id);
-
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = b;
- cl->next = NULL;
-
- frame = ngx_palloc(r->pool, sizeof(ngx_http_spdy_out_frame_t));
- if (frame == NULL) {
- return NGX_ERROR;
- }
-
- frame->first = cl;
- frame->last = cl;
- frame->handler = ngx_http_spdy_syn_frame_handler;
- frame->stream = stream;
- frame->length = len;
- frame->priority = stream->priority;
- frame->blocked = 1;
- frame->fin = r->header_only;
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, stream->request->connection->log, 0,
- "spdy:%ui create SYN_REPLY frame %p: len:%uz",
- stream->id, frame, frame->length);
-
- ngx_http_spdy_queue_blocked_frame(sc, frame);
-
- cln = ngx_http_cleanup_add(r, 0);
- if (cln == NULL) {
- return NGX_ERROR;
- }
-
- cln->handler = ngx_http_spdy_filter_cleanup;
- cln->data = stream;
-
- stream->queued = 1;
-
- c->send_chain = ngx_http_spdy_send_chain;
- c->need_last_buf = 1;
-
- return ngx_http_spdy_filter_send(c, stream);
-}
-
-
-static ngx_chain_t *
-ngx_http_spdy_send_chain(ngx_connection_t *fc, ngx_chain_t *in, off_t limit)
-{
- off_t size, offset;
- size_t rest, frame_size;
- ngx_chain_t *cl, *out, **ln;
- ngx_http_request_t *r;
- ngx_http_spdy_stream_t *stream;
- ngx_http_spdy_loc_conf_t *slcf;
- ngx_http_spdy_out_frame_t *frame;
- ngx_http_spdy_connection_t *sc;
-
- r = fc->data;
- stream = r->spdy_stream;
-
-#if (NGX_SUPPRESS_WARN)
- size = 0;
-#endif
-
- while (in) {
- size = ngx_buf_size(in->buf);
-
- if (size || in->buf->last_buf) {
- break;
- }
-
- in = in->next;
- }
-
- if (in == NULL) {
-
- if (stream->queued) {
- fc->write->delayed = 1;
- } else {
- fc->buffered &= ~NGX_SPDY_BUFFERED;
- }
-
- return NULL;
- }
-
- sc = stream->connection;
-
- if (size && ngx_http_spdy_flow_control(sc, stream) == NGX_DECLINED) {
- fc->write->delayed = 1;
- return in;
- }
-
- if (limit == 0 || limit > (off_t) sc->send_window) {
- limit = sc->send_window;
- }
-
- if (limit > stream->send_window) {
- limit = (stream->send_window > 0) ? stream->send_window : 0;
- }
-
- if (in->buf->tag == (ngx_buf_tag_t) &ngx_http_spdy_filter_get_shadow) {
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- cl->buf = in->buf;
- in->buf = cl->buf->shadow;
-
- offset = ngx_buf_in_memory(in->buf)
- ? (cl->buf->pos - in->buf->pos)
- : (cl->buf->file_pos - in->buf->file_pos);
-
- cl->next = stream->free_bufs;
- stream->free_bufs = cl;
-
- } else {
- offset = 0;
- }
-
-#if (NGX_SUPPRESS_WARN)
- cl = NULL;
-#endif
-
- slcf = ngx_http_get_module_loc_conf(r, ngx_http_spdy_module);
-
- frame_size = (limit <= (off_t) slcf->chunk_size) ? (size_t) limit
- : slcf->chunk_size;
-
- for ( ;; ) {
- ln = &out;
- rest = frame_size;
-
- while ((off_t) rest >= size) {
-
- if (offset) {
- cl = ngx_http_spdy_filter_get_shadow(stream, in->buf,
- offset, size);
- if (cl == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- offset = 0;
-
- } else {
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- cl->buf = in->buf;
- }
-
- *ln = cl;
- ln = &cl->next;
-
- rest -= (size_t) size;
- in = in->next;
-
- if (in == NULL) {
- frame_size -= rest;
- rest = 0;
- break;
- }
-
- size = ngx_buf_size(in->buf);
- }
-
- if (rest) {
- cl = ngx_http_spdy_filter_get_shadow(stream, in->buf,
- offset, rest);
- if (cl == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- cl->buf->flush = 0;
- cl->buf->last_buf = 0;
-
- *ln = cl;
-
- offset += rest;
- size -= rest;
- }
-
- frame = ngx_http_spdy_filter_get_data_frame(stream, frame_size,
- out, cl);
- if (frame == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- ngx_http_spdy_queue_frame(sc, frame);
-
- sc->send_window -= frame_size;
-
- stream->send_window -= frame_size;
- stream->queued++;
-
- if (in == NULL) {
- break;
- }
-
- limit -= frame_size;
-
- if (limit == 0) {
- break;
- }
-
- if (limit < (off_t) slcf->chunk_size) {
- frame_size = (size_t) limit;
- }
- }
-
- if (offset) {
- cl = ngx_http_spdy_filter_get_shadow(stream, in->buf, offset, size);
- if (cl == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- in->buf = cl->buf;
- ngx_free_chain(r->pool, cl);
- }
-
- if (ngx_http_spdy_filter_send(fc, stream) == NGX_ERROR) {
- return NGX_CHAIN_ERROR;
- }
-
- if (in && ngx_http_spdy_flow_control(sc, stream) == NGX_DECLINED) {
- fc->write->delayed = 1;
- }
-
- return in;
-}
-
-
-static ngx_chain_t *
-ngx_http_spdy_filter_get_shadow(ngx_http_spdy_stream_t *stream, ngx_buf_t *buf,
- off_t offset, off_t size)
-{
- ngx_buf_t *chunk;
- ngx_chain_t *cl;
-
- cl = ngx_chain_get_free_buf(stream->request->pool, &stream->free_bufs);
- if (cl == NULL) {
- return NULL;
- }
-
- chunk = cl->buf;
-
- ngx_memcpy(chunk, buf, sizeof(ngx_buf_t));
-
- chunk->tag = (ngx_buf_tag_t) &ngx_http_spdy_filter_get_shadow;
- chunk->shadow = buf;
-
- if (ngx_buf_in_memory(chunk)) {
- chunk->pos += offset;
- chunk->last = chunk->pos + size;
- }
-
- if (chunk->in_file) {
- chunk->file_pos += offset;
- chunk->file_last = chunk->file_pos + size;
- }
-
- return cl;
-}
-
-
-static ngx_http_spdy_out_frame_t *
-ngx_http_spdy_filter_get_data_frame(ngx_http_spdy_stream_t *stream,
- size_t len, ngx_chain_t *first, ngx_chain_t *last)
-{
- u_char *p;
- ngx_buf_t *buf;
- ngx_uint_t flags;
- ngx_chain_t *cl;
- ngx_http_spdy_out_frame_t *frame;
-
-
- frame = stream->free_frames;
-
- if (frame) {
- stream->free_frames = frame->next;
-
- } else {
- frame = ngx_palloc(stream->request->pool,
- sizeof(ngx_http_spdy_out_frame_t));
- if (frame == NULL) {
- return NULL;
- }
- }
-
- flags = last->buf->last_buf ? NGX_SPDY_FLAG_FIN : 0;
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, stream->request->connection->log, 0,
- "spdy:%ui create DATA frame %p: len:%uz flags:%ui",
- stream->id, frame, len, flags);
-
- cl = ngx_chain_get_free_buf(stream->request->pool,
- &stream->free_data_headers);
- if (cl == NULL) {
- return NULL;
- }
-
- buf = cl->buf;
-
- if (buf->start) {
- p = buf->start;
- buf->pos = p;
-
- p += NGX_SPDY_SID_SIZE;
-
- (void) ngx_spdy_frame_write_flags_and_len(p, flags, len);
-
- } else {
- p = ngx_palloc(stream->request->pool, NGX_SPDY_FRAME_HEADER_SIZE);
- if (p == NULL) {
- return NULL;
- }
-
- buf->pos = p;
- buf->start = p;
-
- p = ngx_spdy_frame_write_sid(p, stream->id);
- p = ngx_spdy_frame_write_flags_and_len(p, flags, len);
-
- buf->last = p;
- buf->end = p;
-
- buf->tag = (ngx_buf_tag_t) &ngx_http_spdy_filter_get_data_frame;
- buf->memory = 1;
- }
-
- cl->next = first;
- first = cl;
-
- last->buf->flush = 1;
-
- frame->first = first;
- frame->last = last;
- frame->handler = ngx_http_spdy_data_frame_handler;
- frame->stream = stream;
- frame->length = len;
- frame->priority = stream->priority;
- frame->blocked = 0;
- frame->fin = last->buf->last_buf;
-
- return frame;
-}
-
-
-static ngx_inline ngx_int_t
-ngx_http_spdy_filter_send(ngx_connection_t *fc, ngx_http_spdy_stream_t *stream)
-{
- stream->blocked = 1;
-
- if (ngx_http_spdy_send_output_queue(stream->connection) == NGX_ERROR) {
- fc->error = 1;
- return NGX_ERROR;
- }
-
- stream->blocked = 0;
-
- if (stream->queued) {
- fc->buffered |= NGX_SPDY_BUFFERED;
- fc->write->delayed = 1;
- return NGX_AGAIN;
- }
-
- fc->buffered &= ~NGX_SPDY_BUFFERED;
-
- return NGX_OK;
-}
-
-
-static ngx_inline ngx_int_t
-ngx_http_spdy_flow_control(ngx_http_spdy_connection_t *sc,
- ngx_http_spdy_stream_t *stream)
-{
- if (stream->send_window <= 0) {
- stream->exhausted = 1;
- return NGX_DECLINED;
- }
-
- if (sc->send_window == 0) {
- ngx_http_spdy_waiting_queue(sc, stream);
- return NGX_DECLINED;
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_spdy_waiting_queue(ngx_http_spdy_connection_t *sc,
- ngx_http_spdy_stream_t *stream)
-{
- ngx_queue_t *q;
- ngx_http_spdy_stream_t *s;
-
- if (stream->handled) {
- return;
- }
-
- stream->handled = 1;
-
- for (q = ngx_queue_last(&sc->waiting);
- q != ngx_queue_sentinel(&sc->waiting);
- q = ngx_queue_prev(q))
- {
- s = ngx_queue_data(q, ngx_http_spdy_stream_t, queue);
-
- /*
- * NB: higher values represent lower priorities.
- */
- if (stream->priority >= s->priority) {
- break;
- }
- }
-
- ngx_queue_insert_after(q, &stream->queue);
-}
-
-
-static ngx_int_t
-ngx_http_spdy_syn_frame_handler(ngx_http_spdy_connection_t *sc,
- ngx_http_spdy_out_frame_t *frame)
-{
- ngx_buf_t *buf;
- ngx_http_spdy_stream_t *stream;
-
- buf = frame->first->buf;
-
- if (buf->pos != buf->last) {
- return NGX_AGAIN;
- }
-
- stream = frame->stream;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy:%ui SYN_REPLY frame %p was sent", stream->id, frame);
-
- ngx_free_chain(stream->request->pool, frame->first);
-
- ngx_http_spdy_handle_frame(stream, frame);
-
- ngx_http_spdy_handle_stream(sc, stream);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_data_frame_handler(ngx_http_spdy_connection_t *sc,
- ngx_http_spdy_out_frame_t *frame)
-{
- ngx_buf_t *buf;
- ngx_chain_t *cl, *ln;
- ngx_http_spdy_stream_t *stream;
-
- stream = frame->stream;
-
- cl = frame->first;
-
- if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_spdy_filter_get_data_frame) {
-
- if (cl->buf->pos != cl->buf->last) {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy:%ui DATA frame %p was sent partially",
- stream->id, frame);
-
- return NGX_AGAIN;
- }
-
- ln = cl->next;
-
- cl->next = stream->free_data_headers;
- stream->free_data_headers = cl;
-
- if (cl == frame->last) {
- goto done;
- }
-
- cl = ln;
- }
-
- for ( ;; ) {
- if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_spdy_filter_get_shadow) {
- buf = cl->buf->shadow;
-
- if (ngx_buf_in_memory(buf)) {
- buf->pos = cl->buf->pos;
- }
-
- if (buf->in_file) {
- buf->file_pos = cl->buf->file_pos;
- }
- }
-
- if (ngx_buf_size(cl->buf) != 0) {
-
- if (cl != frame->first) {
- frame->first = cl;
- ngx_http_spdy_handle_stream(sc, stream);
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy:%ui DATA frame %p was sent partially",
- stream->id, frame);
-
- return NGX_AGAIN;
- }
-
- ln = cl->next;
-
- if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_spdy_filter_get_shadow) {
- cl->next = stream->free_bufs;
- stream->free_bufs = cl;
-
- } else {
- ngx_free_chain(stream->request->pool, cl);
- }
-
- if (cl == frame->last) {
- goto done;
- }
-
- cl = ln;
- }
-
-done:
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, sc->connection->log, 0,
- "spdy:%ui DATA frame %p was sent", stream->id, frame);
-
- stream->request->header_size += NGX_SPDY_FRAME_HEADER_SIZE;
-
- ngx_http_spdy_handle_frame(stream, frame);
-
- ngx_http_spdy_handle_stream(sc, stream);
-
- return NGX_OK;
-}
-
-
-static ngx_inline void
-ngx_http_spdy_handle_frame(ngx_http_spdy_stream_t *stream,
- ngx_http_spdy_out_frame_t *frame)
-{
- ngx_http_request_t *r;
-
- r = stream->request;
-
- r->connection->sent += NGX_SPDY_FRAME_HEADER_SIZE + frame->length;
-
- if (frame->fin) {
- stream->out_closed = 1;
- }
-
- frame->next = stream->free_frames;
- stream->free_frames = frame;
-
- stream->queued--;
-}
-
-
-static ngx_inline void
-ngx_http_spdy_handle_stream(ngx_http_spdy_connection_t *sc,
- ngx_http_spdy_stream_t *stream)
-{
- ngx_event_t *wev;
-
- if (stream->handled || stream->blocked || stream->exhausted) {
- return;
- }
-
- wev = stream->request->connection->write;
-
- if (!wev->timer_set) {
- wev->delayed = 0;
-
- stream->handled = 1;
- ngx_queue_insert_tail(&sc->posted, &stream->queue);
- }
-}
-
-
-static void
-ngx_http_spdy_filter_cleanup(void *data)
-{
- ngx_http_spdy_stream_t *stream = data;
-
- size_t delta;
- ngx_http_spdy_out_frame_t *frame, **fn;
- ngx_http_spdy_connection_t *sc;
-
- if (stream->handled) {
- stream->handled = 0;
- ngx_queue_remove(&stream->queue);
- }
-
- if (stream->queued == 0) {
- return;
- }
-
- delta = 0;
- sc = stream->connection;
- fn = &sc->last_out;
-
- for ( ;; ) {
- frame = *fn;
-
- if (frame == NULL) {
- break;
- }
-
- if (frame->stream == stream && !frame->blocked) {
- *fn = frame->next;
-
- delta += frame->length;
-
- if (--stream->queued == 0) {
- break;
- }
-
- continue;
- }
-
- fn = &frame->next;
- }
-
- if (sc->send_window == 0 && delta && !ngx_queue_empty(&sc->waiting)) {
- ngx_queue_add(&sc->posted, &sc->waiting);
- ngx_queue_init(&sc->waiting);
- }
-
- sc->send_window += delta;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_spdy_header_filter;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_spdy_module.c b/usr.sbin/nginx/src/http/ngx_http_spdy_module.c
deleted file mode 100644
index 5178a36f239..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_spdy_module.c
+++ /dev/null
@@ -1,408 +0,0 @@
-
-/*
- * Copyright (C) Nginx, Inc.
- * Copyright (C) Valentin V. Bartenev
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-#include <ngx_http_spdy_module.h>
-
-
-static ngx_int_t ngx_http_spdy_add_variables(ngx_conf_t *cf);
-
-static ngx_int_t ngx_http_spdy_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_spdy_request_priority_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-
-static ngx_int_t ngx_http_spdy_module_init(ngx_cycle_t *cycle);
-
-static void *ngx_http_spdy_create_main_conf(ngx_conf_t *cf);
-static char *ngx_http_spdy_init_main_conf(ngx_conf_t *cf, void *conf);
-static void *ngx_http_spdy_create_srv_conf(ngx_conf_t *cf);
-static char *ngx_http_spdy_merge_srv_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static void *ngx_http_spdy_create_loc_conf(ngx_conf_t *cf);
-static char *ngx_http_spdy_merge_loc_conf(ngx_conf_t *cf, void *parent,
- void *child);
-
-static char *ngx_http_spdy_recv_buffer_size(ngx_conf_t *cf, void *post,
- void *data);
-static char *ngx_http_spdy_pool_size(ngx_conf_t *cf, void *post, void *data);
-static char *ngx_http_spdy_streams_index_mask(ngx_conf_t *cf, void *post,
- void *data);
-static char *ngx_http_spdy_chunk_size(ngx_conf_t *cf, void *post, void *data);
-
-
-static ngx_conf_num_bounds_t ngx_http_spdy_headers_comp_bounds = {
- ngx_conf_check_num_bounds, 0, 9
-};
-
-static ngx_conf_post_t ngx_http_spdy_recv_buffer_size_post =
- { ngx_http_spdy_recv_buffer_size };
-static ngx_conf_post_t ngx_http_spdy_pool_size_post =
- { ngx_http_spdy_pool_size };
-static ngx_conf_post_t ngx_http_spdy_streams_index_mask_post =
- { ngx_http_spdy_streams_index_mask };
-static ngx_conf_post_t ngx_http_spdy_chunk_size_post =
- { ngx_http_spdy_chunk_size };
-
-
-static ngx_command_t ngx_http_spdy_commands[] = {
-
- { ngx_string("spdy_recv_buffer_size"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_MAIN_CONF_OFFSET,
- offsetof(ngx_http_spdy_main_conf_t, recv_buffer_size),
- &ngx_http_spdy_recv_buffer_size_post },
-
- { ngx_string("spdy_pool_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_spdy_srv_conf_t, pool_size),
- &ngx_http_spdy_pool_size_post },
-
- { ngx_string("spdy_max_concurrent_streams"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_spdy_srv_conf_t, concurrent_streams),
- NULL },
-
- { ngx_string("spdy_streams_index_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_spdy_srv_conf_t, streams_index_mask),
- &ngx_http_spdy_streams_index_mask_post },
-
- { ngx_string("spdy_recv_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_spdy_srv_conf_t, recv_timeout),
- NULL },
-
- { ngx_string("spdy_keepalive_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_spdy_srv_conf_t, keepalive_timeout),
- NULL },
-
- { ngx_string("spdy_headers_comp"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_num_slot,
- NGX_HTTP_SRV_CONF_OFFSET,
- offsetof(ngx_http_spdy_srv_conf_t, headers_comp),
- &ngx_http_spdy_headers_comp_bounds },
-
- { ngx_string("spdy_chunk_size"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_spdy_loc_conf_t, chunk_size),
- &ngx_http_spdy_chunk_size_post },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_spdy_module_ctx = {
- ngx_http_spdy_add_variables, /* preconfiguration */
- NULL, /* postconfiguration */
-
- ngx_http_spdy_create_main_conf, /* create main configuration */
- ngx_http_spdy_init_main_conf, /* init main configuration */
-
- ngx_http_spdy_create_srv_conf, /* create server configuration */
- ngx_http_spdy_merge_srv_conf, /* merge server configuration */
-
- ngx_http_spdy_create_loc_conf, /* create location configuration */
- ngx_http_spdy_merge_loc_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_spdy_module = {
- NGX_MODULE_V1,
- &ngx_http_spdy_module_ctx, /* module context */
- ngx_http_spdy_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- ngx_http_spdy_module_init, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_variable_t ngx_http_spdy_vars[] = {
-
- { ngx_string("spdy"), NULL,
- ngx_http_spdy_variable, 0, 0, 0 },
-
- { ngx_string("spdy_request_priority"), NULL,
- ngx_http_spdy_request_priority_variable, 0, 0, 0 },
-
- { ngx_null_string, NULL, NULL, 0, 0, 0 }
-};
-
-
-static ngx_int_t
-ngx_http_spdy_add_variables(ngx_conf_t *cf)
-{
- ngx_http_variable_t *var, *v;
-
- for (v = ngx_http_spdy_vars; v->name.len; v++) {
- var = ngx_http_add_variable(cf, &v->name, v->flags);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = v->get_handler;
- var->data = v->data;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- if (r->spdy_stream) {
- v->len = sizeof("3.1") - 1;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = (u_char *) "3.1";
-
- return NGX_OK;
- }
-
- *v = ngx_http_variable_null_value;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_request_priority_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- if (r->spdy_stream) {
- v->len = 1;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- v->data = ngx_pnalloc(r->pool, 1);
- if (v->data == NULL) {
- return NGX_ERROR;
- }
-
- v->data[0] = '0' + (u_char) r->spdy_stream->priority;
-
- return NGX_OK;
- }
-
- *v = ngx_http_variable_null_value;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_spdy_module_init(ngx_cycle_t *cycle)
-{
- ngx_http_spdy_request_headers_init();
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_spdy_create_main_conf(ngx_conf_t *cf)
-{
- ngx_http_spdy_main_conf_t *smcf;
-
- smcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_spdy_main_conf_t));
- if (smcf == NULL) {
- return NULL;
- }
-
- smcf->recv_buffer_size = NGX_CONF_UNSET_SIZE;
-
- return smcf;
-}
-
-
-static char *
-ngx_http_spdy_init_main_conf(ngx_conf_t *cf, void *conf)
-{
- ngx_http_spdy_main_conf_t *smcf = conf;
-
- ngx_conf_init_size_value(smcf->recv_buffer_size, 256 * 1024);
-
- return NGX_CONF_OK;
-}
-
-
-static void *
-ngx_http_spdy_create_srv_conf(ngx_conf_t *cf)
-{
- ngx_http_spdy_srv_conf_t *sscf;
-
- sscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_spdy_srv_conf_t));
- if (sscf == NULL) {
- return NULL;
- }
-
- sscf->pool_size = NGX_CONF_UNSET_SIZE;
-
- sscf->concurrent_streams = NGX_CONF_UNSET_UINT;
- sscf->streams_index_mask = NGX_CONF_UNSET_UINT;
-
- sscf->recv_timeout = NGX_CONF_UNSET_MSEC;
- sscf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
-
- sscf->headers_comp = NGX_CONF_UNSET;
-
- return sscf;
-}
-
-
-static char *
-ngx_http_spdy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_spdy_srv_conf_t *prev = parent;
- ngx_http_spdy_srv_conf_t *conf = child;
-
- ngx_conf_merge_size_value(conf->pool_size, prev->pool_size, 4096);
-
- ngx_conf_merge_uint_value(conf->concurrent_streams,
- prev->concurrent_streams, 100);
-
- ngx_conf_merge_uint_value(conf->streams_index_mask,
- prev->streams_index_mask, 32 - 1);
-
- ngx_conf_merge_msec_value(conf->recv_timeout,
- prev->recv_timeout, 30000);
- ngx_conf_merge_msec_value(conf->keepalive_timeout,
- prev->keepalive_timeout, 180000);
-
- ngx_conf_merge_value(conf->headers_comp, prev->headers_comp, 0);
-
- return NGX_CONF_OK;
-}
-
-
-static void *
-ngx_http_spdy_create_loc_conf(ngx_conf_t *cf)
-{
- ngx_http_spdy_loc_conf_t *slcf;
-
- slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_spdy_loc_conf_t));
- if (slcf == NULL) {
- return NULL;
- }
-
- slcf->chunk_size = NGX_CONF_UNSET_SIZE;
-
- return slcf;
-}
-
-
-static char *
-ngx_http_spdy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_spdy_loc_conf_t *prev = parent;
- ngx_http_spdy_loc_conf_t *conf = child;
-
- ngx_conf_merge_size_value(conf->chunk_size, prev->chunk_size, 8 * 1024);
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_spdy_recv_buffer_size(ngx_conf_t *cf, void *post, void *data)
-{
- size_t *sp = data;
-
- if (*sp <= 2 * NGX_SPDY_STATE_BUFFER_SIZE) {
- return "value is too small";
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_spdy_pool_size(ngx_conf_t *cf, void *post, void *data)
-{
- size_t *sp = data;
-
- if (*sp < NGX_MIN_POOL_SIZE) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the pool size must be no less than %uz",
- NGX_MIN_POOL_SIZE);
- return NGX_CONF_ERROR;
- }
-
- if (*sp % NGX_POOL_ALIGNMENT) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the pool size must be a multiple of %uz",
- NGX_POOL_ALIGNMENT);
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_spdy_streams_index_mask(ngx_conf_t *cf, void *post, void *data)
-{
- ngx_uint_t *np = data;
-
- ngx_uint_t mask;
-
- mask = *np - 1;
-
- if (*np == 0 || (*np & mask)) {
- return "must be a power of two";
- }
-
- *np = mask;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_spdy_chunk_size(ngx_conf_t *cf, void *post, void *data)
-{
- size_t *sp = data;
-
- if (*sp == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the spdy chunk size cannot be zero");
- return NGX_CONF_ERROR;
- }
-
- if (*sp > NGX_SPDY_MAX_FRAME_SIZE) {
- *sp = NGX_SPDY_MAX_FRAME_SIZE;
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_spdy_module.h b/usr.sbin/nginx/src/http/ngx_http_spdy_module.h
deleted file mode 100644
index 5242322b3d6..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_spdy_module.h
+++ /dev/null
@@ -1,41 +0,0 @@
-
-/*
- * Copyright (C) Nginx, Inc.
- * Copyright (C) Valentin V. Bartenev
- */
-
-
-#ifndef _NGX_HTTP_SPDY_MODULE_H_INCLUDED_
-#define _NGX_HTTP_SPDY_MODULE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- size_t recv_buffer_size;
- u_char *recv_buffer;
-} ngx_http_spdy_main_conf_t;
-
-
-typedef struct {
- size_t pool_size;
- ngx_uint_t concurrent_streams;
- ngx_uint_t streams_index_mask;
- ngx_msec_t recv_timeout;
- ngx_msec_t keepalive_timeout;
- ngx_int_t headers_comp;
-} ngx_http_spdy_srv_conf_t;
-
-
-typedef struct {
- size_t chunk_size;
-} ngx_http_spdy_loc_conf_t;
-
-
-extern ngx_module_t ngx_http_spdy_module;
-
-
-#endif /* _NGX_HTTP_SPDY_MODULE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/ngx_http_special_response.c b/usr.sbin/nginx/src/http/ngx_http_special_response.c
deleted file mode 100644
index 546400539ba..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_special_response.c
+++ /dev/null
@@ -1,792 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-#include <nginx.h>
-
-
-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_padding[] =
-"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
-"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
-"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
-"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
-"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
-"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
-;
-
-
-static u_char ngx_http_msie_refresh_head[] =
-"<html><head><meta http-equiv=\"Refresh\" content=\"0; URL=";
-
-
-static u_char ngx_http_msie_refresh_tail[] =
-"\"></head><body></body></html>" CRLF;
-
-
-static char ngx_http_error_301_page[] =
-"<html>" CRLF
-"<head><title>301 Moved Permanently</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>301 Moved Permanently</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_302_page[] =
-"<html>" CRLF
-"<head><title>302 Found</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>302 Found</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_303_page[] =
-"<html>" CRLF
-"<head><title>303 See Other</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>303 See Other</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_307_page[] =
-"<html>" CRLF
-"<head><title>307 Temporary Redirect</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>307 Temporary Redirect</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_400_page[] =
-"<html>" CRLF
-"<head><title>400 Bad Request</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>400 Bad Request</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_401_page[] =
-"<html>" CRLF
-"<head><title>401 Authorization Required</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>401 Authorization Required</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_402_page[] =
-"<html>" CRLF
-"<head><title>402 Payment Required</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>402 Payment Required</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_403_page[] =
-"<html>" CRLF
-"<head><title>403 Forbidden</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>403 Forbidden</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_404_page[] =
-"<html>" CRLF
-"<head><title>404 Not Found</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>404 Not Found</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_405_page[] =
-"<html>" CRLF
-"<head><title>405 Not Allowed</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>405 Not Allowed</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_406_page[] =
-"<html>" CRLF
-"<head><title>406 Not Acceptable</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>406 Not Acceptable</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_408_page[] =
-"<html>" CRLF
-"<head><title>408 Request Time-out</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>408 Request Time-out</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_409_page[] =
-"<html>" CRLF
-"<head><title>409 Conflict</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>409 Conflict</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_410_page[] =
-"<html>" CRLF
-"<head><title>410 Gone</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>410 Gone</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_411_page[] =
-"<html>" CRLF
-"<head><title>411 Length Required</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>411 Length Required</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_412_page[] =
-"<html>" CRLF
-"<head><title>412 Precondition Failed</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>412 Precondition Failed</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_413_page[] =
-"<html>" CRLF
-"<head><title>413 Request Entity Too Large</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>413 Request Entity Too Large</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_414_page[] =
-"<html>" CRLF
-"<head><title>414 Request-URI Too Large</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>414 Request-URI Too Large</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_415_page[] =
-"<html>" CRLF
-"<head><title>415 Unsupported Media Type</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>415 Unsupported Media Type</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_416_page[] =
-"<html>" CRLF
-"<head><title>416 Requested Range Not Satisfiable</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>416 Requested Range Not Satisfiable</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_494_page[] =
-"<html>" CRLF
-"<head><title>400 Request Header Or Cookie Too Large</title></head>"
-CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>400 Bad Request</h1></center>" CRLF
-"<center>Request Header Or Cookie Too Large</center>" CRLF
-;
-
-
-static char ngx_http_error_495_page[] =
-"<html>" CRLF
-"<head><title>400 The SSL certificate error</title></head>"
-CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>400 Bad Request</h1></center>" CRLF
-"<center>The SSL certificate error</center>" CRLF
-;
-
-
-static char ngx_http_error_496_page[] =
-"<html>" CRLF
-"<head><title>400 No required SSL certificate was sent</title></head>"
-CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>400 Bad Request</h1></center>" CRLF
-"<center>No required SSL certificate was sent</center>" CRLF
-;
-
-
-static char ngx_http_error_497_page[] =
-"<html>" CRLF
-"<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>"
-CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>400 Bad Request</h1></center>" CRLF
-"<center>The plain HTTP request was sent to HTTPS port</center>" CRLF
-;
-
-
-static char ngx_http_error_500_page[] =
-"<html>" CRLF
-"<head><title>500 Internal Server Error</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>500 Internal Server Error</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_501_page[] =
-"<html>" CRLF
-"<head><title>501 Not Implemented</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>501 Not Implemented</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_502_page[] =
-"<html>" CRLF
-"<head><title>502 Bad Gateway</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>502 Bad Gateway</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_503_page[] =
-"<html>" CRLF
-"<head><title>503 Service Temporarily Unavailable</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>503 Service Temporarily Unavailable</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_504_page[] =
-"<html>" CRLF
-"<head><title>504 Gateway Time-out</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>504 Gateway Time-out</h1></center>" CRLF
-;
-
-
-static char ngx_http_error_507_page[] =
-"<html>" CRLF
-"<head><title>507 Insufficient Storage</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
-"<center><h1>507 Insufficient Storage</h1></center>" CRLF
-;
-
-
-static ngx_str_t ngx_http_error_pages[] = {
-
- ngx_null_string, /* 201, 204 */
-
-#define NGX_HTTP_LAST_2XX 202
-#define NGX_HTTP_OFF_3XX (NGX_HTTP_LAST_2XX - 201)
-
- /* ngx_null_string, */ /* 300 */
- ngx_string(ngx_http_error_301_page),
- ngx_string(ngx_http_error_302_page),
- ngx_string(ngx_http_error_303_page),
- ngx_null_string, /* 304 */
- ngx_null_string, /* 305 */
- ngx_null_string, /* 306 */
- ngx_string(ngx_http_error_307_page),
-
-#define NGX_HTTP_LAST_3XX 308
-#define NGX_HTTP_OFF_4XX (NGX_HTTP_LAST_3XX - 301 + NGX_HTTP_OFF_3XX)
-
- 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_LAST_4XX 417
-#define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX)
-
- ngx_string(ngx_http_error_494_page), /* 494, request header too large */
- 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(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)
-
-#define NGX_HTTP_LAST_5XX 508
-
-};
-
-
-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)
-{
- ngx_uint_t i, err;
- ngx_http_err_page_t *err_page;
- ngx_http_core_loc_conf_t *clcf;
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http special response: %i, \"%V?%V\"",
- error, &r->uri, &r->args);
-
- r->err_status = error;
-
- if (r->keepalive) {
- switch (error) {
- case NGX_HTTP_BAD_REQUEST:
- case NGX_HTTP_REQUEST_ENTITY_TOO_LARGE:
- case NGX_HTTP_REQUEST_URI_TOO_LARGE:
- case NGX_HTTP_TO_HTTPS:
- case NGX_HTTPS_CERT_ERROR:
- case NGX_HTTPS_NO_CERT:
- case NGX_HTTP_INTERNAL_SERVER_ERROR:
- case NGX_HTTP_NOT_IMPLEMENTED:
- r->keepalive = 0;
- }
- }
-
- if (r->lingering_close) {
- switch (error) {
- case NGX_HTTP_BAD_REQUEST:
- case NGX_HTTP_TO_HTTPS:
- case NGX_HTTPS_CERT_ERROR:
- case NGX_HTTPS_NO_CERT:
- r->lingering_close = 0;
- }
- }
-
- r->headers_out.content_type.len = 0;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (!r->error_page && clcf->error_pages && r->uri_changes != 0) {
-
- if (clcf->recursive_error_pages == 0) {
- r->error_page = 1;
- }
-
- err_page = clcf->error_pages->elts;
-
- for (i = 0; i < clcf->error_pages->nelts; i++) {
- if (err_page[i].status == error) {
- return ngx_http_send_error_page(r, &err_page[i]);
- }
- }
- }
-
- r->expect_tested = 1;
-
- if (ngx_http_discard_request_body(r) != NGX_OK) {
- r->keepalive = 0;
- }
-
- 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;
-
- } else if (error == NGX_HTTP_NO_CONTENT) {
- /* 204 */
- err = 0;
-
- } else if (error >= NGX_HTTP_MOVED_PERMANENTLY
- && error < NGX_HTTP_LAST_3XX)
- {
- /* 3XX */
- err = error - NGX_HTTP_MOVED_PERMANENTLY + NGX_HTTP_OFF_3XX;
-
- } else if (error >= NGX_HTTP_BAD_REQUEST
- && error < NGX_HTTP_LAST_4XX)
- {
- /* 4XX */
- err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_OFF_4XX;
-
- } else if (error >= NGX_HTTP_NGINX_CODES
- && error < NGX_HTTP_LAST_5XX)
- {
- /* 49X, 5XX */
- err = error - NGX_HTTP_NGINX_CODES + NGX_HTTP_OFF_5XX;
- switch (error) {
- case NGX_HTTP_TO_HTTPS:
- case NGX_HTTPS_CERT_ERROR:
- case NGX_HTTPS_NO_CERT:
- case NGX_HTTP_REQUEST_HEADER_TOO_LARGE:
- r->err_status = NGX_HTTP_BAD_REQUEST;
- break;
- }
-
- } else {
- /* unknown code, zero body */
- err = 0;
- }
-
- return ngx_http_send_special_response(r, clcf, err);
-}
-
-
-ngx_int_t
-ngx_http_filter_finalize_request(ngx_http_request_t *r, ngx_module_t *m,
- ngx_int_t error)
-{
- void *ctx;
- ngx_int_t rc;
-
- ngx_http_clean_header(r);
-
- ctx = NULL;
-
- if (m) {
- ctx = r->ctx[m->ctx_index];
- }
-
- /* clear the modules contexts */
- ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
-
- if (m) {
- r->ctx[m->ctx_index] = ctx;
- }
-
- r->filter_finalize = 1;
-
- rc = ngx_http_special_response_handler(r, error);
-
- /* NGX_ERROR resets any pending data */
-
- switch (rc) {
-
- case NGX_OK:
- case NGX_DONE:
- return NGX_ERROR;
-
- default:
- return rc;
- }
-}
-
-
-void
-ngx_http_clean_header(ngx_http_request_t *r)
-{
- ngx_memzero(&r->headers_out.status,
- sizeof(ngx_http_headers_out_t)
- - offsetof(ngx_http_headers_out_t, status));
-
- r->headers_out.headers.part.nelts = 0;
- r->headers_out.headers.part.next = NULL;
- r->headers_out.headers.last = &r->headers_out.headers.part;
-
- r->headers_out.content_length_n = -1;
- r->headers_out.last_modified_time = -1;
-}
-
-
-static ngx_int_t
-ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
-{
- ngx_int_t overwrite;
- ngx_str_t uri, args;
- ngx_table_elt_t *location;
- ngx_http_core_loc_conf_t *clcf;
-
- overwrite = err_page->overwrite;
-
- if (overwrite && overwrite != NGX_HTTP_OK) {
- r->expect_tested = 1;
- }
-
- if (overwrite >= 0) {
- r->err_status = overwrite;
- }
-
- if (ngx_http_complex_value(r, &err_page->value, &uri) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (uri.data[0] == '/') {
-
- if (err_page->value.lengths) {
- ngx_http_split_args(r, &uri, &args);
-
- } else {
- args = err_page->args;
- }
-
- if (r->method != NGX_HTTP_HEAD) {
- r->method = NGX_HTTP_GET;
- r->method_name = ngx_http_get_name;
- }
-
- 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;
- }
-
- if (overwrite != NGX_HTTP_MOVED_PERMANENTLY
- && overwrite != NGX_HTTP_MOVED_TEMPORARILY
- && overwrite != NGX_HTTP_SEE_OTHER
- && overwrite != NGX_HTTP_TEMPORARY_REDIRECT)
- {
- r->err_status = NGX_HTTP_MOVED_TEMPORARILY;
- }
-
- location->hash = 1;
- ngx_str_set(&location->key, "Location");
- location->value = uri;
-
- ngx_http_clear_location(r);
-
- 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, r->err_status
- - NGX_HTTP_MOVED_PERMANENTLY
- + NGX_HTTP_OFF_3XX);
-}
-
-
-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 (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->headers_in.chrome)
- && r->http_version >= NGX_HTTP_VERSION_10
- && err >= NGX_HTTP_OFF_4XX)
- {
- r->headers_out.content_length_n +=
- sizeof(ngx_http_msie_padding) - 1;
- msie_padding = 1;
- }
-
- r->headers_out.content_type_len = sizeof("text/html") - 1;
- ngx_str_set(&r->headers_out.content_type, "text/html");
- r->headers_out.content_type_lowcase = NULL;
-
- } else {
- r->headers_out.content_length_n = 0;
- }
-
- 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);
- ngx_http_clear_last_modified(r);
- ngx_http_clear_etag(r);
-
- rc = ngx_http_send_header(r);
-
- if (rc == NGX_ERROR || r->header_only) {
- return rc;
- }
-
- if (ngx_http_error_pages[err].len == 0) {
- return ngx_http_send_special(r, NGX_HTTP_LAST);
- }
-
- 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_padding;
- b->last = ngx_http_msie_padding + sizeof(ngx_http_msie_padding) - 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;
- ngx_str_set(&r->headers_out.content_type, "text/html");
- r->headers_out.content_type_lowcase = NULL;
-
- 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);
- ngx_http_clear_last_modified(r);
- ngx_http_clear_etag(r);
-
- rc = ngx_http_send_header(r);
-
- if (rc == NGX_ERROR || r->header_only) {
- return rc;
- }
-
- b = ngx_create_temp_buf(r->pool, size);
- if (b == NULL) {
- return NGX_ERROR;
- }
-
- p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head,
- sizeof(ngx_http_msie_refresh_head) - 1);
-
- if (escape == 0) {
- p = ngx_cpymem(p, location, len);
-
- } else {
- p = (u_char *) ngx_escape_uri(p, location, len, NGX_ESCAPE_REFRESH);
- }
-
- 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;
-
- out.buf = b;
- out.next = NULL;
-
- return ngx_http_output_filter(r, &out);
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_upstream.c b/usr.sbin/nginx/src/http/ngx_http_upstream.c
deleted file mode 100644
index 040bda10623..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_upstream.c
+++ /dev/null
@@ -1,5311 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-#if (NGX_HTTP_CACHE)
-static ngx_int_t ngx_http_upstream_cache(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static ngx_int_t ngx_http_upstream_cache_send(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static ngx_int_t ngx_http_upstream_cache_status(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_upstream_cache_last_modified(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-#endif
-
-static void ngx_http_upstream_init_request(ngx_http_request_t *r);
-static void ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx);
-static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r);
-static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r);
-static void ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
- ngx_event_t *ev);
-static void ngx_http_upstream_connect(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static ngx_int_t ngx_http_upstream_reinit(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static void ngx_http_upstream_send_request(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static void ngx_http_upstream_process_header(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c);
-static ngx_int_t ngx_http_upstream_process_headers(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static void ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static void ngx_http_upstream_send_response(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static void ngx_http_upstream_upgrade(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static void ngx_http_upstream_upgraded_read_downstream(ngx_http_request_t *r);
-static void ngx_http_upstream_upgraded_write_downstream(ngx_http_request_t *r);
-static void ngx_http_upstream_upgraded_read_upstream(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static void ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static void ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
- ngx_uint_t from_upstream, ngx_uint_t do_write);
-static void
- ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r);
-static void
- ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static void
- ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
- ngx_uint_t do_write);
-static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data);
-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_upstream(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static void ngx_http_upstream_process_request(ngx_http_request_t *r);
-static void ngx_http_upstream_store(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static void ngx_http_upstream_dummy_handler(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-static void ngx_http_upstream_next(ngx_http_request_t *r,
- ngx_http_upstream_t *u, ngx_uint_t ft_type);
-static void ngx_http_upstream_cleanup(void *data);
-static void ngx_http_upstream_finalize_request(ngx_http_request_t *r,
- ngx_http_upstream_t *u, ngx_int_t rc);
-
-static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_process_content_length(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_process_set_cookie(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t
- ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_process_expires(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_process_accel_expires(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_process_limit_rate(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_process_buffering(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_process_charset(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_process_connection(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t
- ngx_http_upstream_process_transfer_encoding(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t
- ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_copy_content_type(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_copy_last_modified(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_rewrite_location(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_rewrite_set_cookie(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-static ngx_int_t ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-
-#if (NGX_HTTP_GZIP)
-static ngx_int_t ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset);
-#endif
-
-static ngx_int_t ngx_http_upstream_add_variables(ngx_conf_t *cf);
-static ngx_int_t ngx_http_upstream_addr_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_upstream_status_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_upstream_response_length_variable(
- ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
-
-static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy);
-static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-static ngx_addr_t *ngx_http_upstream_get_local(ngx_http_request_t *r,
- ngx_http_upstream_local_t *local);
-
-static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf);
-static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf);
-
-#if (NGX_HTTP_SSL)
-static void ngx_http_upstream_ssl_init_connection(ngx_http_request_t *,
- ngx_http_upstream_t *u, ngx_connection_t *c);
-static void ngx_http_upstream_ssl_handshake(ngx_connection_t *c);
-#endif
-
-
-ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
-
- { ngx_string("Status"),
- ngx_http_upstream_process_header_line,
- offsetof(ngx_http_upstream_headers_in_t, status),
- ngx_http_upstream_copy_header_line, 0, 0 },
-
- { ngx_string("Content-Type"),
- ngx_http_upstream_process_header_line,
- offsetof(ngx_http_upstream_headers_in_t, content_type),
- ngx_http_upstream_copy_content_type, 0, 1 },
-
- { ngx_string("Content-Length"),
- ngx_http_upstream_process_content_length,
- offsetof(ngx_http_upstream_headers_in_t, content_length),
- ngx_http_upstream_ignore_header_line, 0, 0 },
-
- { ngx_string("Date"),
- ngx_http_upstream_process_header_line,
- offsetof(ngx_http_upstream_headers_in_t, date),
- 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_last_modified, 0, 0 },
-
- { ngx_string("ETag"),
- ngx_http_upstream_process_header_line,
- offsetof(ngx_http_upstream_headers_in_t, etag),
- ngx_http_upstream_copy_header_line,
- offsetof(ngx_http_headers_out_t, etag), 0 },
-
- { ngx_string("Server"),
- ngx_http_upstream_process_header_line,
- offsetof(ngx_http_upstream_headers_in_t, server),
- ngx_http_upstream_copy_header_line,
- offsetof(ngx_http_headers_out_t, server), 0 },
-
- { ngx_string("WWW-Authenticate"),
- ngx_http_upstream_process_header_line,
- offsetof(ngx_http_upstream_headers_in_t, www_authenticate),
- ngx_http_upstream_copy_header_line, 0, 0 },
-
- { ngx_string("Location"),
- ngx_http_upstream_process_header_line,
- offsetof(ngx_http_upstream_headers_in_t, location),
- ngx_http_upstream_rewrite_location, 0, 0 },
-
- { ngx_string("Refresh"),
- ngx_http_upstream_ignore_header_line, 0,
- ngx_http_upstream_rewrite_refresh, 0, 0 },
-
- { ngx_string("Set-Cookie"),
- ngx_http_upstream_process_set_cookie, 0,
- ngx_http_upstream_rewrite_set_cookie, 0, 1 },
-
- { ngx_string("Content-Disposition"),
- ngx_http_upstream_ignore_header_line, 0,
- ngx_http_upstream_copy_header_line, 0, 1 },
-
- { ngx_string("Cache-Control"),
- ngx_http_upstream_process_cache_control, 0,
- ngx_http_upstream_copy_multi_header_lines,
- offsetof(ngx_http_headers_out_t, cache_control), 1 },
-
- { ngx_string("Expires"),
- ngx_http_upstream_process_expires, 0,
- ngx_http_upstream_copy_header_line,
- offsetof(ngx_http_headers_out_t, expires), 1 },
-
- { ngx_string("Accept-Ranges"),
- ngx_http_upstream_process_header_line,
- offsetof(ngx_http_upstream_headers_in_t, accept_ranges),
- ngx_http_upstream_copy_allow_ranges,
- offsetof(ngx_http_headers_out_t, accept_ranges), 1 },
-
- { ngx_string("Connection"),
- ngx_http_upstream_process_connection, 0,
- ngx_http_upstream_ignore_header_line, 0, 0 },
-
- { ngx_string("Keep-Alive"),
- ngx_http_upstream_ignore_header_line, 0,
- ngx_http_upstream_ignore_header_line, 0, 0 },
-
- { ngx_string("X-Powered-By"),
- ngx_http_upstream_ignore_header_line, 0,
- ngx_http_upstream_copy_header_line, 0, 0 },
-
- { ngx_string("X-Accel-Expires"),
- ngx_http_upstream_process_accel_expires, 0,
- ngx_http_upstream_copy_header_line, 0, 0 },
-
- { ngx_string("X-Accel-Redirect"),
- ngx_http_upstream_process_header_line,
- offsetof(ngx_http_upstream_headers_in_t, x_accel_redirect),
- ngx_http_upstream_copy_header_line, 0, 0 },
-
- { ngx_string("X-Accel-Limit-Rate"),
- ngx_http_upstream_process_limit_rate, 0,
- ngx_http_upstream_copy_header_line, 0, 0 },
-
- { ngx_string("X-Accel-Buffering"),
- ngx_http_upstream_process_buffering, 0,
- ngx_http_upstream_copy_header_line, 0, 0 },
-
- { ngx_string("X-Accel-Charset"),
- ngx_http_upstream_process_charset, 0,
- ngx_http_upstream_copy_header_line, 0, 0 },
-
- { ngx_string("Transfer-Encoding"),
- ngx_http_upstream_process_transfer_encoding, 0,
- ngx_http_upstream_ignore_header_line, 0, 0 },
-
-#if (NGX_HTTP_GZIP)
- { ngx_string("Content-Encoding"),
- ngx_http_upstream_process_header_line,
- offsetof(ngx_http_upstream_headers_in_t, content_encoding),
- ngx_http_upstream_copy_content_encoding, 0, 0 },
-#endif
-
- { ngx_null_string, NULL, 0, NULL, 0, 0 }
-};
-
-
-static ngx_command_t ngx_http_upstream_commands[] = {
-
- { ngx_string("upstream"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
- ngx_http_upstream,
- 0,
- 0,
- NULL },
-
- { ngx_string("server"),
- NGX_HTTP_UPS_CONF|NGX_CONF_1MORE,
- ngx_http_upstream_server,
- NGX_HTTP_SRV_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_upstream_module_ctx = {
- ngx_http_upstream_add_variables, /* preconfiguration */
- NULL, /* postconfiguration */
-
- ngx_http_upstream_create_main_conf, /* create main configuration */
- ngx_http_upstream_init_main_conf, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_upstream_module = {
- NGX_MODULE_V1,
- &ngx_http_upstream_module_ctx, /* module context */
- ngx_http_upstream_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_variable_t ngx_http_upstream_vars[] = {
-
- { ngx_string("upstream_addr"), NULL,
- ngx_http_upstream_addr_variable, 0,
- NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("upstream_status"), NULL,
- ngx_http_upstream_status_variable, 0,
- NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("upstream_response_time"), NULL,
- ngx_http_upstream_response_time_variable, 0,
- NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("upstream_response_length"), NULL,
- ngx_http_upstream_response_length_variable, 0,
- NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
-#if (NGX_HTTP_CACHE)
-
- { ngx_string("upstream_cache_status"), NULL,
- ngx_http_upstream_cache_status, 0,
- NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("upstream_cache_last_modified"), NULL,
- ngx_http_upstream_cache_last_modified, 0,
- NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
-
-#endif
-
- { ngx_null_string, NULL, NULL, 0, 0, 0 }
-};
-
-
-static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = {
- { 500, NGX_HTTP_UPSTREAM_FT_HTTP_500 },
- { 502, NGX_HTTP_UPSTREAM_FT_HTTP_502 },
- { 503, NGX_HTTP_UPSTREAM_FT_HTTP_503 },
- { 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 },
- { 403, NGX_HTTP_UPSTREAM_FT_HTTP_403 },
- { 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 },
- { 0, 0 }
-};
-
-
-ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[] = {
- { ngx_string("GET"), NGX_HTTP_GET},
- { ngx_string("HEAD"), NGX_HTTP_HEAD },
- { ngx_string("POST"), NGX_HTTP_POST },
- { ngx_null_string, 0 }
-};
-
-
-ngx_conf_bitmask_t ngx_http_upstream_ignore_headers_masks[] = {
- { ngx_string("X-Accel-Redirect"), NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT },
- { ngx_string("X-Accel-Expires"), NGX_HTTP_UPSTREAM_IGN_XA_EXPIRES },
- { ngx_string("X-Accel-Limit-Rate"), NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE },
- { ngx_string("X-Accel-Buffering"), NGX_HTTP_UPSTREAM_IGN_XA_BUFFERING },
- { ngx_string("X-Accel-Charset"), NGX_HTTP_UPSTREAM_IGN_XA_CHARSET },
- { ngx_string("Expires"), NGX_HTTP_UPSTREAM_IGN_EXPIRES },
- { ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL },
- { ngx_string("Set-Cookie"), NGX_HTTP_UPSTREAM_IGN_SET_COOKIE },
- { ngx_null_string, 0 }
-};
-
-
-ngx_int_t
-ngx_http_upstream_create(ngx_http_request_t *r)
-{
- ngx_http_upstream_t *u;
-
- u = r->upstream;
-
- if (u && u->cleanup) {
- r->main->count++;
- ngx_http_upstream_cleanup(r);
- }
-
- u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
- if (u == NULL) {
- return NGX_ERROR;
- }
-
- r->upstream = u;
-
- u->peer.log = r->connection->log;
- u->peer.log_error = NGX_ERROR_ERR;
-#if (NGX_THREADS)
- u->peer.lock = &r->connection->lock;
-#endif
-
-#if (NGX_HTTP_CACHE)
- r->cache = NULL;
-#endif
-
- u->headers_in.content_length_n = -1;
-
- return NGX_OK;
-}
-
-
-void
-ngx_http_upstream_init(ngx_http_request_t *r)
-{
- ngx_connection_t *c;
-
- c = r->connection;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http init upstream, client timer: %d", c->read->timer_set);
-
-#if (NGX_HTTP_SPDY)
- if (r->spdy_stream) {
- ngx_http_upstream_init_request(r);
- return;
- }
-#endif
-
- if (c->read->timer_set) {
- ngx_del_timer(c->read);
- }
-
- if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
-
- if (!c->write->active) {
- if (ngx_add_event(c->write, NGX_WRITE_EVENT, NGX_CLEAR_EVENT)
- == NGX_ERROR)
- {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
- }
- }
-
- ngx_http_upstream_init_request(r);
-}
-
-
-static void
-ngx_http_upstream_init_request(ngx_http_request_t *r)
-{
- ngx_str_t *host;
- ngx_uint_t i;
- ngx_resolver_ctx_t *ctx, temp;
- ngx_http_cleanup_t *cln;
- ngx_http_upstream_t *u;
- ngx_http_core_loc_conf_t *clcf;
- ngx_http_upstream_srv_conf_t *uscf, **uscfp;
- ngx_http_upstream_main_conf_t *umcf;
-
- if (r->aio) {
- return;
- }
-
- u = r->upstream;
-
-#if (NGX_HTTP_CACHE)
-
- if (u->conf->cache) {
- ngx_int_t rc;
-
- rc = ngx_http_upstream_cache(r, u);
-
- if (rc == NGX_BUSY) {
- r->write_event_handler = ngx_http_upstream_init_request;
- return;
- }
-
- r->write_event_handler = ngx_http_request_empty_handler;
-
- if (rc == NGX_DONE) {
- return;
- }
-
- if (rc != NGX_DECLINED) {
- ngx_http_finalize_request(r, rc);
- return;
- }
- }
-
-#endif
-
- u->store = (u->conf->store || u->conf->store_lengths);
-
- if (!u->store && !r->post_action && !u->conf->ignore_client_abort) {
- r->read_event_handler = ngx_http_upstream_rd_check_broken_connection;
- r->write_event_handler = ngx_http_upstream_wr_check_broken_connection;
- }
-
- if (r->request_body) {
- u->request_bufs = r->request_body->bufs;
- }
-
- if (u->create_request(r) != NGX_OK) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- u->peer.local = ngx_http_upstream_get_local(r, u->conf->local);
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- u->output.alignment = clcf->directio_alignment;
- u->output.pool = r->pool;
- u->output.bufs.num = 1;
- u->output.bufs.size = clcf->client_body_buffer_size;
- u->output.output_filter = ngx_chain_writer;
- u->output.filter_ctx = &u->writer;
-
- u->writer.pool = r->pool;
-
- if (r->upstream_states == NULL) {
-
- r->upstream_states = ngx_array_create(r->pool, 1,
- sizeof(ngx_http_upstream_state_t));
- if (r->upstream_states == NULL) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- } else {
-
- u->state = ngx_array_push(r->upstream_states);
- if (u->state == NULL) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t));
- }
-
- cln = ngx_http_cleanup_add(r, 0);
- if (cln == NULL) {
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- cln->handler = ngx_http_upstream_cleanup;
- cln->data = r;
- u->cleanup = &cln->handler;
-
- if (u->resolved == NULL) {
-
- uscf = u->conf->upstream;
-
- } else {
-
- if (u->resolved->sockaddr) {
-
- if (ngx_http_upstream_create_round_robin_peer(r, u->resolved)
- != NGX_OK)
- {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- ngx_http_upstream_connect(r, u);
-
- return;
- }
-
- host = &u->resolved->host;
-
- umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
-
- uscfp = umcf->upstreams.elts;
-
- for (i = 0; i < umcf->upstreams.nelts; i++) {
-
- uscf = uscfp[i];
-
- if (uscf->host.len == host->len
- && ((uscf->port == 0 && u->resolved->no_port)
- || uscf->port == u->resolved->port)
- && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0)
- {
- goto found;
- }
- }
-
- if (u->resolved->port == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "no port in upstream \"%V\"", host);
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- temp.name = *host;
-
- ctx = ngx_resolve_start(clcf->resolver, &temp);
- if (ctx == NULL) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- if (ctx == NGX_NO_RESOLVER) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "no resolver defined to resolve %V", host);
-
- ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
- return;
- }
-
- ctx->name = *host;
- ctx->handler = ngx_http_upstream_resolve_handler;
- ctx->data = r;
- ctx->timeout = clcf->resolver_timeout;
-
- u->resolved->ctx = ctx;
-
- if (ngx_resolve_name(ctx) != NGX_OK) {
- u->resolved->ctx = NULL;
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- return;
- }
-
-found:
-
- if (uscf == NULL) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "no upstream configuration");
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- if (uscf->peer.init(r, uscf) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- ngx_http_upstream_connect(r, u);
-}
-
-
-#if (NGX_HTTP_CACHE)
-
-static ngx_int_t
-ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
-{
- ngx_int_t rc;
- ngx_http_cache_t *c;
-
- c = r->cache;
-
- if (c == NULL) {
-
- if (!(r->method & u->conf->cache_methods)) {
- return NGX_DECLINED;
- }
-
- if (r->method & NGX_HTTP_HEAD) {
- u->method = ngx_http_core_get_method;
- }
-
- if (ngx_http_file_cache_new(r) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if (u->create_key(r) != NGX_OK) {
- return NGX_ERROR;
- }
-
- /* TODO: add keys */
-
- ngx_http_file_cache_create_key(r);
-
- if (r->cache->header_start + 256 >= u->conf->buffer_size) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "%V_buffer_size %uz is not enough for cache key, "
- "it should be increased to at least %uz",
- &u->conf->module, u->conf->buffer_size,
- ngx_align(r->cache->header_start + 256, 1024));
-
- r->cache = NULL;
- return NGX_DECLINED;
- }
-
- u->cacheable = 1;
-
- switch (ngx_http_test_predicates(r, u->conf->cache_bypass)) {
-
- case NGX_ERROR:
- return NGX_ERROR;
-
- case NGX_DECLINED:
- u->cache_status = NGX_HTTP_CACHE_BYPASS;
- return NGX_DECLINED;
-
- default: /* NGX_OK */
- break;
- }
-
- c = r->cache;
-
- c->min_uses = u->conf->cache_min_uses;
- c->body_start = u->conf->buffer_size;
- c->file_cache = u->conf->cache->data;
-
- c->lock = u->conf->cache_lock;
- c->lock_timeout = u->conf->cache_lock_timeout;
-
- u->cache_status = NGX_HTTP_CACHE_MISS;
- }
-
- rc = ngx_http_file_cache_open(r);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http upstream cache: %i", rc);
-
- switch (rc) {
-
- case NGX_HTTP_CACHE_UPDATING:
-
- if (u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING) {
- u->cache_status = rc;
- rc = NGX_OK;
-
- } else {
- rc = NGX_HTTP_CACHE_STALE;
- }
-
- break;
-
- case NGX_OK:
- u->cache_status = NGX_HTTP_CACHE_HIT;
- }
-
- switch (rc) {
-
- case NGX_OK:
-
- rc = ngx_http_upstream_cache_send(r, u);
-
- if (rc != NGX_HTTP_UPSTREAM_INVALID_HEADER) {
- return rc;
- }
-
- break;
-
- case NGX_HTTP_CACHE_STALE:
-
- c->valid_sec = 0;
- u->buffer.start = NULL;
- u->cache_status = NGX_HTTP_CACHE_EXPIRED;
-
- break;
-
- case NGX_DECLINED:
-
- if ((size_t) (u->buffer.end - u->buffer.start) < u->conf->buffer_size) {
- u->buffer.start = NULL;
-
- } else {
- u->buffer.pos = u->buffer.start + c->header_start;
- u->buffer.last = u->buffer.pos;
- }
-
- break;
-
- case NGX_HTTP_CACHE_SCARCE:
-
- u->cacheable = 0;
-
- break;
-
- case NGX_AGAIN:
-
- return NGX_BUSY;
-
- case NGX_ERROR:
-
- return NGX_ERROR;
-
- default:
-
- /* cached NGX_HTTP_BAD_GATEWAY, NGX_HTTP_GATEWAY_TIME_OUT, etc. */
-
- u->cache_status = NGX_HTTP_CACHE_HIT;
-
- return rc;
- }
-
- r->cached = 0;
-
- return NGX_DECLINED;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u)
-{
- ngx_int_t rc;
- ngx_http_cache_t *c;
-
- r->cached = 1;
- c = r->cache;
-
- if (c->header_start == c->body_start) {
- r->http_version = NGX_HTTP_VERSION_9;
- return ngx_http_cache_send(r);
- }
-
- /* TODO: cache stack */
-
- u->buffer = *c->buf;
- u->buffer.pos += c->header_start;
-
- ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));
- u->headers_in.content_length_n = -1;
-
- if (ngx_list_init(&u->headers_in.headers, r->pool, 8,
- sizeof(ngx_table_elt_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- rc = u->process_header(r);
-
- if (rc == NGX_OK) {
-
- if (ngx_http_upstream_process_headers(r, u) != NGX_OK) {
- return NGX_DONE;
- }
-
- return ngx_http_cache_send(r);
- }
-
- if (rc == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- /* rc == NGX_HTTP_UPSTREAM_INVALID_HEADER */
-
- /* TODO: delete file */
-
- return rc;
-}
-
-#endif
-
-
-static void
-ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
-{
- ngx_connection_t *c;
- ngx_http_request_t *r;
- ngx_http_upstream_t *u;
- ngx_http_upstream_resolved_t *ur;
-
- r = ctx->data;
- c = r->connection;
-
- u = r->upstream;
- ur = u->resolved;
-
- if (ctx->state) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "%V could not be resolved (%i: %s)",
- &ctx->name, ctx->state,
- ngx_resolver_strerror(ctx->state));
-
- ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
- goto failed;
- }
-
- ur->naddrs = ctx->naddrs;
- ur->addrs = ctx->addrs;
-
-#if (NGX_DEBUG)
- {
- u_char text[NGX_SOCKADDR_STRLEN];
- ngx_str_t addr;
- ngx_uint_t i;
-
- addr.data = text;
-
- for (i = 0; i < ctx->naddrs; i++) {
- addr.len = ngx_sock_ntop(ur->addrs[i].sockaddr, ur->addrs[i].socklen,
- text, NGX_SOCKADDR_STRLEN, 0);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "name was resolved to %V", &addr);
- }
- }
-#endif
-
- if (ngx_http_upstream_create_round_robin_peer(r, ur) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- goto failed;
- }
-
- ngx_resolve_name_done(ctx);
- ur->ctx = NULL;
-
- ngx_http_upstream_connect(r, u);
-
-failed:
-
- ngx_http_run_posted_requests(c);
-}
-
-
-static void
-ngx_http_upstream_handler(ngx_event_t *ev)
-{
- ngx_connection_t *c;
- ngx_http_request_t *r;
- ngx_http_log_ctx_t *ctx;
- ngx_http_upstream_t *u;
-
- c = ev->data;
- r = c->data;
-
- u = r->upstream;
- c = r->connection;
-
- ctx = c->log->data;
- ctx->current_request = r;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http upstream request: \"%V?%V\"", &r->uri, &r->args);
-
- if (ev->write) {
- u->write_event_handler(r, u);
-
- } else {
- u->read_event_handler(r, u);
- }
-
- ngx_http_run_posted_requests(c);
-}
-
-
-static void
-ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r)
-{
- ngx_http_upstream_check_broken_connection(r, r->connection->read);
-}
-
-
-static void
-ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r)
-{
- ngx_http_upstream_check_broken_connection(r, r->connection->write);
-}
-
-
-static void
-ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
- ngx_event_t *ev)
-{
- int n;
- char buf[1];
- ngx_err_t err;
- ngx_int_t event;
- ngx_connection_t *c;
- ngx_http_upstream_t *u;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ev->log, 0,
- "http upstream check client, write event:%d, \"%V\"",
- ev->write, &r->uri);
-
- c = r->connection;
- u = r->upstream;
-
- if (c->error) {
- if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && ev->active) {
-
- event = ev->write ? NGX_WRITE_EVENT : NGX_READ_EVENT;
-
- if (ngx_del_event(ev, event, 0) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
- }
-
- if (!u->cacheable) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_CLIENT_CLOSED_REQUEST);
- }
-
- return;
- }
-
-#if (NGX_HTTP_SPDY)
- if (r->spdy_stream) {
- return;
- }
-#endif
-
-#if (NGX_HAVE_KQUEUE)
-
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
-
- if (!ev->pending_eof) {
- return;
- }
-
- ev->eof = 1;
- c->error = 1;
-
- if (ev->kq_errno) {
- ev->error = 1;
- }
-
- if (!u->cacheable && u->peer.connection) {
- ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
- "kevent() reported that client prematurely closed "
- "connection, so upstream connection is closed too");
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_CLIENT_CLOSED_REQUEST);
- return;
- }
-
- ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
- "kevent() reported that client prematurely closed "
- "connection");
-
- if (u->peer.connection == NULL) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_CLIENT_CLOSED_REQUEST);
- }
-
- return;
- }
-
-#endif
-
-#if (NGX_HAVE_EPOLLRDHUP)
-
- if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) && ev->pending_eof) {
- socklen_t len;
-
- ev->eof = 1;
- c->error = 1;
-
- err = 0;
- len = sizeof(ngx_err_t);
-
- /*
- * BSDs and Linux return 0 and set a pending error in err
- * Solaris returns -1 and sets errno
- */
-
- if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
- == -1)
- {
- err = ngx_socket_errno;
- }
-
- if (err) {
- ev->error = 1;
- }
-
- if (!u->cacheable && u->peer.connection) {
- ngx_log_error(NGX_LOG_INFO, ev->log, err,
- "epoll_wait() reported that client prematurely closed "
- "connection, so upstream connection is closed too");
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_CLIENT_CLOSED_REQUEST);
- return;
- }
-
- ngx_log_error(NGX_LOG_INFO, ev->log, err,
- "epoll_wait() reported that client prematurely closed "
- "connection");
-
- if (u->peer.connection == NULL) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_CLIENT_CLOSED_REQUEST);
- }
-
- return;
- }
-
-#endif
-
- n = recv(c->fd, buf, 1, MSG_PEEK);
-
- err = ngx_socket_errno;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, err,
- "http upstream recv(): %d", n);
-
- if (ev->write && (n >= 0 || err == NGX_EAGAIN)) {
- return;
- }
-
- if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && ev->active) {
-
- event = ev->write ? NGX_WRITE_EVENT : NGX_READ_EVENT;
-
- if (ngx_del_event(ev, event, 0) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
- }
-
- if (n > 0) {
- return;
- }
-
- if (n == -1) {
- if (err == NGX_EAGAIN) {
- return;
- }
-
- ev->error = 1;
-
- } else { /* n == 0 */
- err = 0;
- }
-
- ev->eof = 1;
- c->error = 1;
-
- if (!u->cacheable && u->peer.connection) {
- ngx_log_error(NGX_LOG_INFO, ev->log, err,
- "client prematurely closed connection, "
- "so upstream connection is closed too");
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_CLIENT_CLOSED_REQUEST);
- return;
- }
-
- ngx_log_error(NGX_LOG_INFO, ev->log, err,
- "client prematurely closed connection");
-
- if (u->peer.connection == NULL) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_CLIENT_CLOSED_REQUEST);
- }
-}
-
-
-static void
-ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
-{
- ngx_int_t rc;
- ngx_time_t *tp;
- ngx_connection_t *c;
-
- r->connection->log->action = "connecting to upstream";
-
- if (u->state && u->state->response_sec) {
- tp = ngx_timeofday();
- u->state->response_sec = tp->sec - u->state->response_sec;
- u->state->response_msec = tp->msec - u->state->response_msec;
- }
-
- u->state = ngx_array_push(r->upstream_states);
- if (u->state == NULL) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t));
-
- tp = ngx_timeofday();
- u->state->response_sec = tp->sec;
- u->state->response_msec = tp->msec;
-
- rc = ngx_event_connect_peer(&u->peer);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http upstream connect: %i", rc);
-
- if (rc == NGX_ERROR) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- u->state->peer = u->peer.name;
-
- if (rc == NGX_BUSY) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams");
- ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_NOLIVE);
- return;
- }
-
- if (rc == NGX_DECLINED) {
- ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
- return;
- }
-
- /* rc == NGX_OK || rc == NGX_AGAIN || rc == NGX_DONE */
-
- c = u->peer.connection;
-
- c->data = r;
-
- c->write->handler = ngx_http_upstream_handler;
- c->read->handler = ngx_http_upstream_handler;
-
- u->write_event_handler = ngx_http_upstream_send_request_handler;
- u->read_event_handler = ngx_http_upstream_process_header;
-
- c->sendfile &= r->connection->sendfile;
- u->output.sendfile = c->sendfile;
-
- if (c->pool == NULL) {
-
- /* we need separate pool here to be able to cache SSL connections */
-
- c->pool = ngx_create_pool(128, r->connection->log);
- if (c->pool == NULL) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
- }
-
- c->log = r->connection->log;
- c->pool->log = c->log;
- c->read->log = c->log;
- c->write->log = c->log;
-
- /* init or reinit the ngx_output_chain() and ngx_chain_writer() contexts */
-
- u->writer.out = NULL;
- u->writer.last = &u->writer.out;
- u->writer.connection = c;
- u->writer.limit = 0;
-
- if (u->request_sent) {
- if (ngx_http_upstream_reinit(r, u) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
- }
-
- if (r->request_body
- && r->request_body->buf
- && r->request_body->temp_file
- && r == r->main)
- {
- /*
- * the r->request_body->buf can be reused for one request only,
- * the subrequests should allocate their own temporary bufs
- */
-
- u->output.free = ngx_alloc_chain_link(r->pool);
- if (u->output.free == NULL) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- u->output.free->buf = r->request_body->buf;
- u->output.free->next = NULL;
- u->output.allocated = 1;
-
- r->request_body->buf->pos = r->request_body->buf->start;
- r->request_body->buf->last = r->request_body->buf->start;
- r->request_body->buf->tag = u->output.tag;
- }
-
- u->request_sent = 0;
-
- if (rc == NGX_AGAIN) {
- ngx_add_timer(c->write, u->conf->connect_timeout);
- return;
- }
-
-#if (NGX_HTTP_SSL)
-
- if (u->ssl && c->ssl == NULL) {
- ngx_http_upstream_ssl_init_connection(r, u, c);
- return;
- }
-
-#endif
-
- ngx_http_upstream_send_request(r, u);
-}
-
-
-#if (NGX_HTTP_SSL)
-
-static void
-ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
- ngx_http_upstream_t *u, ngx_connection_t *c)
-{
- ngx_int_t rc;
-
- if (ngx_http_upstream_test_connect(c) != NGX_OK) {
- ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
- return;
- }
-
- if (ngx_ssl_create_connection(u->conf->ssl, c,
- NGX_SSL_BUFFER|NGX_SSL_CLIENT)
- != NGX_OK)
- {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- c->sendfile = 0;
- u->output.sendfile = 0;
-
- if (u->conf->ssl_session_reuse) {
- 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;
- }
- }
-
- r->connection->log->action = "SSL handshaking to upstream";
-
- rc = ngx_ssl_handshake(c);
-
- if (rc == NGX_AGAIN) {
- c->ssl->handler = ngx_http_upstream_ssl_handshake;
- return;
- }
-
- ngx_http_upstream_ssl_handshake(c);
-}
-
-
-static void
-ngx_http_upstream_ssl_handshake(ngx_connection_t *c)
-{
- ngx_http_request_t *r;
- ngx_http_upstream_t *u;
-
- r = c->data;
- u = r->upstream;
-
- if (c->ssl->handshaked) {
-
- if (u->conf->ssl_session_reuse) {
- u->peer.save_session(&u->peer, u->peer.data);
- }
-
- c->write->handler = ngx_http_upstream_handler;
- c->read->handler = ngx_http_upstream_handler;
-
- c = r->connection;
-
- ngx_http_upstream_send_request(r, u);
-
- ngx_http_run_posted_requests(c);
- return;
- }
-
- c = r->connection;
-
- ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
-
- ngx_http_run_posted_requests(c);
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u)
-{
- ngx_chain_t *cl;
-
- if (u->reinit_request(r) != NGX_OK) {
- return NGX_ERROR;
- }
-
- u->keepalive = 0;
- u->upgrade = 0;
-
- ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));
- u->headers_in.content_length_n = -1;
-
- if (ngx_list_init(&u->headers_in.headers, r->pool, 8,
- sizeof(ngx_table_elt_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- /* reinit the request chain */
-
- for (cl = u->request_bufs; cl; cl = cl->next) {
- cl->buf->pos = cl->buf->start;
- cl->buf->file_pos = 0;
- }
-
- /* reinit the subrequest's ngx_output_chain() context */
-
- if (r->request_body && r->request_body->temp_file
- && r != r->main && u->output.buf)
- {
- u->output.free = ngx_alloc_chain_link(r->pool);
- if (u->output.free == NULL) {
- return NGX_ERROR;
- }
-
- u->output.free->buf = u->output.buf;
- u->output.free->next = NULL;
-
- u->output.buf->pos = u->output.buf->start;
- u->output.buf->last = u->output.buf->start;
- }
-
- u->output.buf = NULL;
- u->output.in = NULL;
- u->output.busy = NULL;
-
- /* reinit u->buffer */
-
- u->buffer.pos = u->buffer.start;
-
-#if (NGX_HTTP_CACHE)
-
- if (r->cache) {
- u->buffer.pos += r->cache->header_start;
- }
-
-#endif
-
- u->buffer.last = u->buffer.pos;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u)
-{
- ngx_int_t rc;
- ngx_connection_t *c;
-
- c = u->peer.connection;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http upstream send request");
-
- if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) {
- ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
- return;
- }
-
- c->log->action = "sending request to upstream";
-
- rc = ngx_output_chain(&u->output, u->request_sent ? NULL : u->request_bufs);
-
- u->request_sent = 1;
-
- if (rc == NGX_ERROR) {
- ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
- return;
- }
-
- if (c->write->timer_set) {
- ngx_del_timer(c->write);
- }
-
- if (rc == NGX_AGAIN) {
- ngx_add_timer(c->write, u->conf->send_timeout);
-
- if (ngx_handle_write_event(c->write, u->conf->send_lowat) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- return;
- }
-
- /* rc == NGX_OK */
-
- if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
- if (ngx_tcp_push(c->fd) == NGX_ERROR) {
- ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
- ngx_tcp_push_n " failed");
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
- }
-
- ngx_add_timer(c->read, u->conf->read_timeout);
-
- if (c->read->ready) {
- ngx_http_upstream_process_header(r, u);
- return;
- }
-
- u->write_event_handler = ngx_http_upstream_dummy_handler;
-
- if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-}
-
-
-static void
-ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
- ngx_http_upstream_t *u)
-{
- ngx_connection_t *c;
-
- c = u->peer.connection;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http upstream send request handler");
-
- if (c->write->timedout) {
- ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT);
- return;
- }
-
-#if (NGX_HTTP_SSL)
-
- if (u->ssl && c->ssl == NULL) {
- ngx_http_upstream_ssl_init_connection(r, u, c);
- return;
- }
-
-#endif
-
- if (u->header_sent) {
- u->write_event_handler = ngx_http_upstream_dummy_handler;
-
- (void) ngx_handle_write_event(c->write, 0);
-
- return;
- }
-
- ngx_http_upstream_send_request(r, u);
-}
-
-
-static void
-ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
-{
- ssize_t n;
- ngx_int_t rc;
- ngx_connection_t *c;
-
- c = u->peer.connection;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http upstream process header");
-
- c->log->action = "reading response header from upstream";
-
- if (c->read->timedout) {
- ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT);
- return;
- }
-
- if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) {
- ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
- return;
- }
-
- if (u->buffer.start == NULL) {
- u->buffer.start = ngx_palloc(r->pool, u->conf->buffer_size);
- if (u->buffer.start == NULL) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- u->buffer.pos = u->buffer.start;
- u->buffer.last = u->buffer.start;
- u->buffer.end = u->buffer.start + u->conf->buffer_size;
- u->buffer.temporary = 1;
-
- u->buffer.tag = u->output.tag;
-
- if (ngx_list_init(&u->headers_in.headers, r->pool, 8,
- sizeof(ngx_table_elt_t))
- != NGX_OK)
- {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
-#if (NGX_HTTP_CACHE)
-
- if (r->cache) {
- u->buffer.pos += r->cache->header_start;
- u->buffer.last = u->buffer.pos;
- }
-#endif
- }
-
- for ( ;; ) {
-
- n = c->recv(c, u->buffer.last, u->buffer.end - u->buffer.last);
-
- if (n == NGX_AGAIN) {
-#if 0
- ngx_add_timer(rev, u->read_timeout);
-#endif
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- return;
- }
-
- if (n == 0) {
- ngx_log_error(NGX_LOG_ERR, c->log, 0,
- "upstream prematurely closed connection");
- }
-
- if (n == NGX_ERROR || n == 0) {
- ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
- return;
- }
-
- u->buffer.last += n;
-
-#if 0
- u->valid_header_in = 0;
-
- u->peer.cached = 0;
-#endif
-
- rc = u->process_header(r);
-
- if (rc == NGX_AGAIN) {
-
- if (u->buffer.last == u->buffer.end) {
- ngx_log_error(NGX_LOG_ERR, c->log, 0,
- "upstream sent too big header");
-
- ngx_http_upstream_next(r, u,
- NGX_HTTP_UPSTREAM_FT_INVALID_HEADER);
- return;
- }
-
- continue;
- }
-
- break;
- }
-
- if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) {
- ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_INVALID_HEADER);
- return;
- }
-
- if (rc == NGX_ERROR) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
- }
-
- /* rc == NGX_OK */
-
- if (u->headers_in.status_n >= NGX_HTTP_SPECIAL_RESPONSE) {
-
- if (ngx_http_upstream_test_next(r, u) == NGX_OK) {
- return;
- }
-
- if (ngx_http_upstream_intercept_errors(r, u) == NGX_OK) {
- return;
- }
- }
-
- if (ngx_http_upstream_process_headers(r, u) != NGX_OK) {
- return;
- }
-
- if (!r->subrequest_in_memory) {
- ngx_http_upstream_send_response(r, u);
- return;
- }
-
- /* subrequest content in memory */
-
- if (u->input_filter == NULL) {
- u->input_filter_init = ngx_http_upstream_non_buffered_filter_init;
- u->input_filter = ngx_http_upstream_non_buffered_filter;
- u->input_filter_ctx = r;
- }
-
- if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- n = u->buffer.last - u->buffer.pos;
-
- if (n) {
- u->buffer.last = u->buffer.pos;
-
- u->state->response_length += n;
-
- if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
- }
-
- if (u->length == 0) {
- ngx_http_upstream_finalize_request(r, u, 0);
- return;
- }
-
- u->read_event_handler = ngx_http_upstream_process_body_in_memory;
-
- ngx_http_upstream_process_body_in_memory(r, u);
-}
-
-
-static ngx_int_t
-ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
-{
- ngx_uint_t status;
- ngx_http_upstream_next_t *un;
-
- status = u->headers_in.status_n;
-
- for (un = ngx_http_upstream_next_errors; un->status; un++) {
-
- if (status != un->status) {
- continue;
- }
-
- if (u->peer.tries > 1 && (u->conf->next_upstream & un->mask)) {
- ngx_http_upstream_next(r, u, un->mask);
- return NGX_OK;
- }
-
-#if (NGX_HTTP_CACHE)
-
- if (u->cache_status == NGX_HTTP_CACHE_EXPIRED
- && (u->conf->cache_use_stale & un->mask))
- {
- ngx_int_t rc;
-
- rc = u->reinit_request(r);
-
- if (rc == NGX_OK) {
- u->cache_status = NGX_HTTP_CACHE_STALE;
- rc = ngx_http_upstream_cache_send(r, u);
- }
-
- ngx_http_upstream_finalize_request(r, u, rc);
- return NGX_OK;
- }
-
-#endif
- }
-
-#if (NGX_HTTP_CACHE)
-
- if (status == NGX_HTTP_NOT_MODIFIED
- && u->cache_status == NGX_HTTP_CACHE_EXPIRED
- && u->conf->cache_revalidate)
- {
- time_t now, valid;
- ngx_int_t rc;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http upstream not modified");
-
- now = ngx_time();
- valid = r->cache->valid_sec;
-
- rc = u->reinit_request(r);
-
- if (rc != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u, rc);
- return NGX_OK;
- }
-
- u->cache_status = NGX_HTTP_CACHE_REVALIDATED;
- rc = ngx_http_upstream_cache_send(r, u);
-
- if (valid == 0) {
- valid = r->cache->valid_sec;
- }
-
- if (valid == 0) {
- valid = ngx_http_file_cache_valid(u->conf->cache_valid,
- u->headers_in.status_n);
- if (valid) {
- valid = now + valid;
- }
- }
-
- if (valid) {
- r->cache->valid_sec = valid;
- r->cache->date = now;
-
- ngx_http_file_cache_update_header(r);
- }
-
- ngx_http_upstream_finalize_request(r, u, rc);
- return NGX_OK;
- }
-
-#endif
-
- return NGX_DECLINED;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
- ngx_http_upstream_t *u)
-{
- ngx_int_t status;
- ngx_uint_t i;
- ngx_table_elt_t *h;
- ngx_http_err_page_t *err_page;
- ngx_http_core_loc_conf_t *clcf;
-
- status = u->headers_in.status_n;
-
- if (status == NGX_HTTP_NOT_FOUND && u->conf->intercept_404) {
- ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
- return NGX_OK;
- }
-
- if (!u->conf->intercept_errors) {
- return NGX_DECLINED;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->error_pages == NULL) {
- return NGX_DECLINED;
- }
-
- err_page = clcf->error_pages->elts;
- for (i = 0; i < clcf->error_pages->nelts; i++) {
-
- if (err_page[i].status == status) {
-
- if (status == NGX_HTTP_UNAUTHORIZED
- && u->headers_in.www_authenticate)
- {
- h = ngx_list_push(&r->headers_out.headers);
-
- if (h == NULL) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_OK;
- }
-
- *h = *u->headers_in.www_authenticate;
-
- r->headers_out.www_authenticate = h;
- }
-
-#if (NGX_HTTP_CACHE)
-
- if (r->cache) {
- time_t valid;
-
- valid = ngx_http_file_cache_valid(u->conf->cache_valid, status);
-
- if (valid) {
- r->cache->valid_sec = ngx_time() + valid;
- r->cache->error = status;
- }
-
- ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
- }
-#endif
- ngx_http_upstream_finalize_request(r, u, status);
-
- return NGX_OK;
- }
- }
-
- return NGX_DECLINED;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_test_connect(ngx_connection_t *c)
-{
- int err;
- socklen_t len;
-
-#if (NGX_HAVE_KQUEUE)
-
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
- if (c->write->pending_eof || c->read->pending_eof) {
- if (c->write->pending_eof) {
- err = c->write->kq_errno;
-
- } else {
- err = c->read->kq_errno;
- }
-
- c->log->action = "connecting to upstream";
- (void) ngx_connection_error(c, err,
- "kevent() reported that connect() failed");
- return NGX_ERROR;
- }
-
- } else
-#endif
- {
- err = 0;
- len = sizeof(int);
-
- /*
- * BSDs and Linux return 0 and set a pending error in err
- * Solaris returns -1 and sets errno
- */
-
- if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
- == -1)
- {
- err = ngx_socket_errno;
- }
-
- if (err) {
- c->log->action = "connecting to upstream";
- (void) ngx_connection_error(c, err, "connect() failed");
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
-{
- ngx_str_t uri, args;
- ngx_uint_t i, flags;
- ngx_list_part_t *part;
- ngx_table_elt_t *h;
- ngx_http_upstream_header_t *hh;
- ngx_http_upstream_main_conf_t *umcf;
-
- umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
-
- if (u->headers_in.x_accel_redirect
- && !(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT))
- {
- ngx_http_upstream_finalize_request(r, u, NGX_DECLINED);
-
- part = &u->headers_in.headers.part;
- h = part->elts;
-
- for (i = 0; /* void */; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- h = part->elts;
- i = 0;
- }
-
- hh = ngx_hash_find(&umcf->headers_in_hash, h[i].hash,
- h[i].lowcase_key, h[i].key.len);
-
- if (hh && hh->redirect) {
- if (hh->copy_handler(r, &h[i], hh->conf) != NGX_OK) {
- ngx_http_finalize_request(r,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_DONE;
- }
- }
- }
-
- uri = u->headers_in.x_accel_redirect->value;
- ngx_str_null(&args);
- flags = NGX_HTTP_LOG_UNSAFE;
-
- if (ngx_http_parse_unsafe_uri(r, &uri, &args, &flags) != NGX_OK) {
- ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
- return NGX_DONE;
- }
-
- if (r->method != NGX_HTTP_HEAD) {
- r->method = NGX_HTTP_GET;
- }
-
- ngx_http_internal_redirect(r, &uri, &args);
- ngx_http_finalize_request(r, NGX_DONE);
- return NGX_DONE;
- }
-
- part = &u->headers_in.headers.part;
- h = part->elts;
-
- for (i = 0; /* void */; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- h = part->elts;
- i = 0;
- }
-
- if (ngx_hash_find(&u->conf->hide_headers_hash, h[i].hash,
- h[i].lowcase_key, h[i].key.len))
- {
- continue;
- }
-
- hh = ngx_hash_find(&umcf->headers_in_hash, h[i].hash,
- h[i].lowcase_key, h[i].key.len);
-
- if (hh) {
- if (hh->copy_handler(r, &h[i], hh->conf) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_DONE;
- }
-
- continue;
- }
-
- if (ngx_http_upstream_copy_header_line(r, &h[i], 0) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_INTERNAL_SERVER_ERROR);
- return NGX_DONE;
- }
- }
-
- if (r->headers_out.server && r->headers_out.server->value.data == NULL) {
- r->headers_out.server->hash = 0;
- }
-
- if (r->headers_out.date && r->headers_out.date->value.data == NULL) {
- r->headers_out.date->hash = 0;
- }
-
- r->headers_out.status = u->headers_in.status_n;
- r->headers_out.status_line = u->headers_in.status_line;
-
- r->headers_out.content_length_n = u->headers_in.content_length_n;
-
- u->length = -1;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
- ngx_http_upstream_t *u)
-{
- size_t size;
- ssize_t n;
- ngx_buf_t *b;
- ngx_event_t *rev;
- ngx_connection_t *c;
-
- c = u->peer.connection;
- rev = c->read;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http upstream process body on memory");
-
- if (rev->timedout) {
- ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
- ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT);
- return;
- }
-
- b = &u->buffer;
-
- for ( ;; ) {
-
- size = b->end - b->last;
-
- if (size == 0) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "upstream buffer is too small to read response");
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- n = c->recv(c, b->last, size);
-
- if (n == NGX_AGAIN) {
- break;
- }
-
- if (n == 0 || n == NGX_ERROR) {
- ngx_http_upstream_finalize_request(r, u, n);
- return;
- }
-
- u->state->response_length += n;
-
- if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- if (!rev->ready) {
- break;
- }
- }
-
- if (u->length == 0) {
- ngx_http_upstream_finalize_request(r, u, 0);
- return;
- }
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- if (rev->active) {
- ngx_add_timer(rev, u->conf->read_timeout);
-
- } else if (rev->timer_set) {
- ngx_del_timer(rev);
- }
-}
-
-
-static void
-ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
-{
- int tcp_nodelay;
- ssize_t n;
- ngx_int_t rc;
- ngx_event_pipe_t *p;
- ngx_connection_t *c;
- ngx_http_core_loc_conf_t *clcf;
-
- rc = ngx_http_send_header(r);
-
- if (rc == NGX_ERROR || rc > NGX_OK || r->post_action) {
- ngx_http_upstream_finalize_request(r, u, rc);
- return;
- }
-
- u->header_sent = 1;
-
- if (u->upgrade) {
- ngx_http_upstream_upgrade(r, u);
- return;
- }
-
- c = r->connection;
-
- if (r->header_only) {
-
- if (u->cacheable || u->store) {
-
- if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
- ngx_connection_error(c, ngx_socket_errno,
- ngx_shutdown_socket_n " failed");
- }
-
- r->read_event_handler = ngx_http_request_empty_handler;
- r->write_event_handler = ngx_http_request_empty_handler;
- c->error = 1;
-
- } else {
- ngx_http_upstream_finalize_request(r, u, rc);
- return;
- }
- }
-
- if (r->request_body && r->request_body->temp_file) {
- ngx_pool_run_cleanup_file(r->pool, r->request_body->temp_file->file.fd);
- r->request_body->temp_file->file.fd = NGX_INVALID_FILE;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (!u->buffering) {
-
- if (u->input_filter == NULL) {
- u->input_filter_init = ngx_http_upstream_non_buffered_filter_init;
- u->input_filter = ngx_http_upstream_non_buffered_filter;
- u->input_filter_ctx = r;
- }
-
- u->read_event_handler = ngx_http_upstream_process_non_buffered_upstream;
- r->write_event_handler =
- ngx_http_upstream_process_non_buffered_downstream;
-
- r->limit_rate = 0;
-
- if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
-
- tcp_nodelay = 1;
-
- if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
- (const void *) &tcp_nodelay, sizeof(int)) == -1)
- {
- ngx_connection_error(c, ngx_socket_errno,
- "setsockopt(TCP_NODELAY) failed");
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- c->tcp_nodelay = NGX_TCP_NODELAY_SET;
- }
-
- n = u->buffer.last - u->buffer.pos;
-
- if (n) {
- u->buffer.last = u->buffer.pos;
-
- u->state->response_length += n;
-
- if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- ngx_http_upstream_process_non_buffered_downstream(r);
-
- } else {
- u->buffer.pos = u->buffer.start;
- u->buffer.last = u->buffer.start;
-
- if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- if (u->peer.connection->read->ready || u->length == 0) {
- ngx_http_upstream_process_non_buffered_upstream(r, u);
- }
- }
-
- return;
- }
-
- /* TODO: preallocate event_pipe bufs, look "Content-Length" */
-
-#if (NGX_HTTP_CACHE)
-
- if (r->cache && r->cache->file.fd != NGX_INVALID_FILE) {
- ngx_pool_run_cleanup_file(r->pool, r->cache->file.fd);
- r->cache->file.fd = NGX_INVALID_FILE;
- }
-
- switch (ngx_http_test_predicates(r, u->conf->no_cache)) {
-
- case NGX_ERROR:
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
-
- case NGX_DECLINED:
- u->cacheable = 0;
- break;
-
- default: /* NGX_OK */
-
- if (u->cache_status == NGX_HTTP_CACHE_BYPASS) {
-
- r->cache->min_uses = u->conf->cache_min_uses;
- r->cache->body_start = u->conf->buffer_size;
- r->cache->file_cache = u->conf->cache->data;
-
- if (ngx_http_file_cache_create(r) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
- }
-
- break;
- }
-
- if (u->cacheable) {
- time_t now, valid;
-
- now = ngx_time();
-
- valid = r->cache->valid_sec;
-
- if (valid == 0) {
- valid = ngx_http_file_cache_valid(u->conf->cache_valid,
- u->headers_in.status_n);
- if (valid) {
- r->cache->valid_sec = now + valid;
- }
- }
-
- if (valid) {
- r->cache->last_modified = r->headers_out.last_modified_time;
- r->cache->date = now;
- r->cache->body_start = (u_short) (u->buffer.pos - u->buffer.start);
-
- ngx_http_file_cache_set_header(r, u->buffer.start);
-
- } else {
- u->cacheable = 0;
- r->headers_out.last_modified_time = -1;
- }
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http cacheable: %d", u->cacheable);
-
- if (u->cacheable == 0 && r->cache) {
- ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
- }
-
-#endif
-
- p = u->pipe;
-
- p->output_filter = (ngx_event_pipe_output_filter_pt) ngx_http_output_filter;
- p->output_ctx = r;
- p->tag = u->output.tag;
- p->bufs = u->conf->bufs;
- p->busy_size = u->conf->busy_buffers_size;
- p->upstream = u->peer.connection;
- p->downstream = c;
- p->pool = r->pool;
- p->log = c->log;
-
- p->cacheable = u->cacheable || u->store;
-
- p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
- if (p->temp_file == NULL) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- p->temp_file->file.fd = NGX_INVALID_FILE;
- p->temp_file->file.log = c->log;
- p->temp_file->path = u->conf->temp_path;
- p->temp_file->pool = r->pool;
-
- if (p->cacheable) {
- p->temp_file->persistent = 1;
-
- } else {
- p->temp_file->log_level = NGX_LOG_WARN;
- p->temp_file->warn = "an upstream response is buffered "
- "to a temporary file";
- }
-
- p->max_temp_file_size = u->conf->max_temp_file_size;
- p->temp_file_write_size = u->conf->temp_file_write_size;
-
- p->preread_bufs = ngx_alloc_chain_link(r->pool);
- if (p->preread_bufs == NULL) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- 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->cacheable) {
-
- p->buf_to_file = ngx_calloc_buf(r->pool);
- if (p->buf_to_file == NULL) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- p->buf_to_file->start = u->buffer.start;
- p->buf_to_file->pos = u->buffer.start;
- p->buf_to_file->last = u->buffer.pos;
- p->buf_to_file->temporary = 1;
- }
-
- if (ngx_event_flags & NGX_USE_AIO_EVENT) {
- /* the posted aio operation may corrupt a shadow buffer */
- p->single_buf = 1;
- }
-
- /* TODO: p->free_bufs = 0 if use ngx_create_chain_of_bufs() */
- p->free_bufs = 1;
-
- /*
- * event_pipe would do u->buffer.last += p->preread_size
- * as though these bytes were read
- */
- u->buffer.last = u->buffer.pos;
-
- if (u->conf->cyclic_temp_file) {
-
- /*
- * we need to disable the use of sendfile() if we use cyclic temp file
- * because the writing a new data may interfere with sendfile()
- * that uses the same kernel file pages (at least on FreeBSD)
- */
-
- p->cyclic_temp_file = 1;
- c->sendfile = 0;
-
- } else {
- p->cyclic_temp_file = 0;
- }
-
- p->read_timeout = u->conf->read_timeout;
- p->send_timeout = clcf->send_timeout;
- p->send_lowat = clcf->send_lowat;
-
- p->length = -1;
-
- if (u->input_filter_init
- && u->input_filter_init(p->input_ctx) != NGX_OK)
- {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- u->read_event_handler = ngx_http_upstream_process_upstream;
- r->write_event_handler = ngx_http_upstream_process_downstream;
-
- ngx_http_upstream_process_upstream(r, u);
-}
-
-
-static void
-ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u)
-{
- int tcp_nodelay;
- ngx_connection_t *c;
- ngx_http_core_loc_conf_t *clcf;
-
- c = r->connection;
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- /* TODO: prevent upgrade if not requested or not possible */
-
- r->keepalive = 0;
- c->log->action = "proxying upgraded connection";
-
- u->read_event_handler = ngx_http_upstream_upgraded_read_upstream;
- u->write_event_handler = ngx_http_upstream_upgraded_write_upstream;
- r->read_event_handler = ngx_http_upstream_upgraded_read_downstream;
- r->write_event_handler = ngx_http_upstream_upgraded_write_downstream;
-
- if (clcf->tcp_nodelay) {
- tcp_nodelay = 1;
-
- if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
-
- if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
- (const void *) &tcp_nodelay, sizeof(int)) == -1)
- {
- ngx_connection_error(c, ngx_socket_errno,
- "setsockopt(TCP_NODELAY) failed");
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- c->tcp_nodelay = NGX_TCP_NODELAY_SET;
- }
-
- if (u->peer.connection->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, u->peer.connection->log, 0,
- "tcp_nodelay");
-
- if (setsockopt(u->peer.connection->fd, IPPROTO_TCP, TCP_NODELAY,
- (const void *) &tcp_nodelay, sizeof(int)) == -1)
- {
- ngx_connection_error(u->peer.connection, ngx_socket_errno,
- "setsockopt(TCP_NODELAY) failed");
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- u->peer.connection->tcp_nodelay = NGX_TCP_NODELAY_SET;
- }
- }
-
- if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- if (u->peer.connection->read->ready
- || u->buffer.pos != u->buffer.last)
- {
- ngx_post_event(c->read, &ngx_posted_events);
- ngx_http_upstream_process_upgraded(r, 1, 1);
- return;
- }
-
- ngx_http_upstream_process_upgraded(r, 0, 1);
-}
-
-
-static void
-ngx_http_upstream_upgraded_read_downstream(ngx_http_request_t *r)
-{
- ngx_http_upstream_process_upgraded(r, 0, 0);
-}
-
-
-static void
-ngx_http_upstream_upgraded_write_downstream(ngx_http_request_t *r)
-{
- ngx_http_upstream_process_upgraded(r, 1, 1);
-}
-
-
-static void
-ngx_http_upstream_upgraded_read_upstream(ngx_http_request_t *r,
- ngx_http_upstream_t *u)
-{
- ngx_http_upstream_process_upgraded(r, 1, 0);
-}
-
-
-static void
-ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r,
- ngx_http_upstream_t *u)
-{
- ngx_http_upstream_process_upgraded(r, 0, 1);
-}
-
-
-static void
-ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
- ngx_uint_t from_upstream, ngx_uint_t do_write)
-{
- size_t size;
- ssize_t n;
- ngx_buf_t *b;
- ngx_connection_t *c, *downstream, *upstream, *dst, *src;
- ngx_http_upstream_t *u;
- ngx_http_core_loc_conf_t *clcf;
-
- c = r->connection;
- u = r->upstream;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http upstream process upgraded, fu:%ui", from_upstream);
-
- downstream = c;
- upstream = u->peer.connection;
-
- if (downstream->write->timedout) {
- c->timedout = 1;
- ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
- ngx_http_upstream_finalize_request(r, u, NGX_HTTP_REQUEST_TIME_OUT);
- return;
- }
-
- if (upstream->read->timedout || upstream->write->timedout) {
- ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
- ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT);
- return;
- }
-
- if (from_upstream) {
- src = upstream;
- dst = downstream;
- b = &u->buffer;
-
- } else {
- src = downstream;
- dst = upstream;
- b = &u->from_client;
-
- if (r->header_in->last > r->header_in->pos) {
- b = r->header_in;
- b->end = b->last;
- do_write = 1;
- }
-
- if (b->start == NULL) {
- b->start = ngx_palloc(r->pool, u->conf->buffer_size);
- if (b->start == NULL) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- b->pos = b->start;
- b->last = b->start;
- b->end = b->start + u->conf->buffer_size;
- b->temporary = 1;
- b->tag = u->output.tag;
- }
- }
-
- for ( ;; ) {
-
- if (do_write) {
-
- size = b->last - b->pos;
-
- if (size && dst->write->ready) {
-
- n = dst->send(dst, b->pos, size);
-
- if (n == NGX_ERROR) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- if (n > 0) {
- b->pos += n;
-
- if (b->pos == b->last) {
- b->pos = b->start;
- b->last = b->start;
- }
- }
- }
- }
-
- size = b->end - b->last;
-
- if (size && src->read->ready) {
-
- n = src->recv(src, b->last, size);
-
- if (n == NGX_AGAIN || n == 0) {
- break;
- }
-
- if (n > 0) {
- do_write = 1;
- b->last += n;
-
- continue;
- }
-
- if (n == NGX_ERROR) {
- src->read->eof = 1;
- }
- }
-
- break;
- }
-
- if ((upstream->read->eof && u->buffer.pos == u->buffer.last)
- || (downstream->read->eof && u->from_client.pos == u->from_client.last)
- || (downstream->read->eof && upstream->read->eof))
- {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http upstream upgraded done");
- ngx_http_upstream_finalize_request(r, u, 0);
- return;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (ngx_handle_write_event(upstream->write, u->conf->send_lowat)
- != NGX_OK)
- {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- if (upstream->write->active && !upstream->write->ready) {
- ngx_add_timer(upstream->write, u->conf->send_timeout);
-
- } else if (upstream->write->timer_set) {
- ngx_del_timer(upstream->write);
- }
-
- if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- if (upstream->read->active && !upstream->read->ready) {
- ngx_add_timer(upstream->read, u->conf->read_timeout);
-
- } else if (upstream->read->timer_set) {
- ngx_del_timer(upstream->read);
- }
-
- if (ngx_handle_write_event(downstream->write, clcf->send_lowat)
- != NGX_OK)
- {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- if (ngx_handle_read_event(downstream->read, 0) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- if (downstream->write->active && !downstream->write->ready) {
- ngx_add_timer(downstream->write, clcf->send_timeout);
-
- } else if (downstream->write->timer_set) {
- ngx_del_timer(downstream->write);
- }
-}
-
-
-static void
-ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r)
-{
- ngx_event_t *wev;
- ngx_connection_t *c;
- ngx_http_upstream_t *u;
-
- c = r->connection;
- u = r->upstream;
- wev = c->write;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http upstream process non buffered downstream");
-
- c->log->action = "sending to client";
-
- if (wev->timedout) {
- c->timedout = 1;
- ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
- ngx_http_upstream_finalize_request(r, u, NGX_HTTP_REQUEST_TIME_OUT);
- return;
- }
-
- ngx_http_upstream_process_non_buffered_request(r, 1);
-}
-
-
-static void
-ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r,
- ngx_http_upstream_t *u)
-{
- ngx_connection_t *c;
-
- c = u->peer.connection;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http upstream process non buffered upstream");
-
- c->log->action = "reading upstream";
-
- if (c->read->timedout) {
- ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
- ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT);
- return;
- }
-
- ngx_http_upstream_process_non_buffered_request(r, 0);
-}
-
-
-static void
-ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
- ngx_uint_t do_write)
-{
- size_t size;
- ssize_t n;
- ngx_buf_t *b;
- ngx_int_t rc;
- ngx_connection_t *downstream, *upstream;
- ngx_http_upstream_t *u;
- ngx_http_core_loc_conf_t *clcf;
-
- u = r->upstream;
- downstream = r->connection;
- upstream = u->peer.connection;
-
- b = &u->buffer;
-
- do_write = do_write || u->length == 0;
-
- for ( ;; ) {
-
- if (do_write) {
-
- if (u->out_bufs || u->busy_bufs) {
- rc = ngx_http_output_filter(r, u->out_bufs);
-
- if (rc == NGX_ERROR) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- ngx_chain_update_chains(r->pool, &u->free_bufs, &u->busy_bufs,
- &u->out_bufs, u->output.tag);
- }
-
- if (u->busy_bufs == NULL) {
-
- if (u->length == 0
- || (upstream->read->eof && u->length == -1))
- {
- ngx_http_upstream_finalize_request(r, u, 0);
- return;
- }
-
- if (upstream->read->eof) {
- ngx_log_error(NGX_LOG_ERR, upstream->log, 0,
- "upstream prematurely closed connection");
-
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_BAD_GATEWAY);
- return;
- }
-
- if (upstream->read->error) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_BAD_GATEWAY);
- return;
- }
-
- b->pos = b->start;
- b->last = b->start;
- }
- }
-
- size = b->end - b->last;
-
- if (size && upstream->read->ready) {
-
- n = upstream->recv(upstream, b->last, size);
-
- if (n == NGX_AGAIN) {
- break;
- }
-
- if (n > 0) {
- u->state->response_length += n;
-
- if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
- }
-
- do_write = 1;
-
- continue;
- }
-
- break;
- }
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (downstream->data == r) {
- if (ngx_handle_write_event(downstream->write, clcf->send_lowat)
- != NGX_OK)
- {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
- }
-
- if (downstream->write->active && !downstream->write->ready) {
- ngx_add_timer(downstream->write, clcf->send_timeout);
-
- } else if (downstream->write->timer_set) {
- ngx_del_timer(downstream->write);
- }
-
- if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- if (upstream->read->active && !upstream->read->ready) {
- ngx_add_timer(upstream->read, u->conf->read_timeout);
-
- } else if (upstream->read->timer_set) {
- ngx_del_timer(upstream->read);
- }
-}
-
-
-static ngx_int_t
-ngx_http_upstream_non_buffered_filter_init(void *data)
-{
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes)
-{
- ngx_http_request_t *r = data;
-
- ngx_buf_t *b;
- ngx_chain_t *cl, **ll;
- ngx_http_upstream_t *u;
-
- u = r->upstream;
-
- for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) {
- ll = &cl->next;
- }
-
- cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- *ll = cl;
-
- cl->buf->flush = 1;
- cl->buf->memory = 1;
-
- b = &u->buffer;
-
- cl->buf->pos = b->last;
- b->last += bytes;
- cl->buf->last = b->last;
- cl->buf->tag = u->output.tag;
-
- if (u->length == -1) {
- return NGX_OK;
- }
-
- u->length -= bytes;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_upstream_process_downstream(ngx_http_request_t *r)
-{
- ngx_event_t *wev;
- ngx_connection_t *c;
- ngx_event_pipe_t *p;
- ngx_http_upstream_t *u;
-
- c = r->connection;
- u = r->upstream;
- p = u->pipe;
- wev = c->write;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http upstream process downstream");
-
- c->log->action = "sending to client";
-
- if (wev->timedout) {
-
- if (wev->delayed) {
-
- wev->timedout = 0;
- wev->delayed = 0;
-
- if (!wev->ready) {
- ngx_add_timer(wev, p->send_timeout);
-
- if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- }
-
- return;
- }
-
- if (ngx_event_pipe(p, wev->write) == NGX_ABORT) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
-
- } else {
- p->downstream_error = 1;
- c->timedout = 1;
- ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
- }
-
- } else {
-
- if (wev->delayed) {
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http downstream delayed");
-
- if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- }
-
- return;
- }
-
- if (ngx_event_pipe(p, 1) == NGX_ABORT) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
- }
-
- ngx_http_upstream_process_request(r);
-}
-
-
-static void
-ngx_http_upstream_process_upstream(ngx_http_request_t *r,
- ngx_http_upstream_t *u)
-{
- ngx_connection_t *c;
-
- c = u->peer.connection;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http upstream process upstream");
-
- c->log->action = "reading upstream";
-
- if (c->read->timedout) {
- u->pipe->upstream_error = 1;
- ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
-
- } else {
- if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- return;
- }
- }
-
- ngx_http_upstream_process_request(r);
-}
-
-
-static void
-ngx_http_upstream_process_request(ngx_http_request_t *r)
-{
- ngx_temp_file_t *tf;
- ngx_event_pipe_t *p;
- ngx_http_upstream_t *u;
-
- u = r->upstream;
- p = u->pipe;
-
- if (u->peer.connection) {
-
- if (u->store) {
-
- if (p->upstream_eof || p->upstream_done) {
-
- tf = p->temp_file;
-
- if (u->headers_in.status_n == NGX_HTTP_OK
- && (p->upstream_done || p->length == -1)
- && (u->headers_in.content_length_n == -1
- || u->headers_in.content_length_n == tf->offset))
- {
- ngx_http_upstream_store(r, u);
- u->store = 0;
- }
- }
- }
-
-#if (NGX_HTTP_CACHE)
-
- if (u->cacheable) {
-
- if (p->upstream_done) {
- ngx_http_file_cache_update(r, p->temp_file);
-
- } else if (p->upstream_eof) {
-
- tf = p->temp_file;
-
- if (p->length == -1
- && (u->headers_in.content_length_n == -1
- || u->headers_in.content_length_n
- == tf->offset - (off_t) r->cache->body_start))
- {
- ngx_http_file_cache_update(r, tf);
-
- } else {
- ngx_http_file_cache_free(r->cache, tf);
- }
-
- } else if (p->upstream_error) {
- ngx_http_file_cache_free(r->cache, p->temp_file);
- }
- }
-
-#endif
-
- if (p->upstream_done || p->upstream_eof || p->upstream_error) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http upstream exit: %p", p->out);
-
- if (p->upstream_done
- || (p->upstream_eof && p->length == -1))
- {
- ngx_http_upstream_finalize_request(r, u, 0);
- return;
- }
-
- if (p->upstream_eof) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream prematurely closed connection");
- }
-
- ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
- return;
- }
- }
-
- if (p->downstream_error) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http upstream downstream error");
-
- if (!u->cacheable && !u->store && u->peer.connection) {
- ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
- }
- }
-}
-
-
-static void
-ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
-{
- size_t root;
- time_t lm;
- ngx_str_t path;
- ngx_temp_file_t *tf;
- ngx_ext_rename_file_t ext;
-
- tf = u->pipe->temp_file;
-
- if (tf->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;
- }
-
- ext.access = u->conf->store_access;
- ext.path_access = u->conf->store_access;
- ext.time = -1;
- ext.create_path = 1;
- ext.delete_file = 1;
- ext.log = r->connection->log;
-
- if (u->headers_in.last_modified) {
-
- lm = ngx_http_parse_time(u->headers_in.last_modified->value.data,
- u->headers_in.last_modified->value.len);
-
- if (lm != NGX_ERROR) {
- ext.time = lm;
- ext.fd = tf->file.fd;
- }
- }
-
- 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;
- }
- }
-
- path.len--;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "upstream stores \"%s\" to \"%s\"",
- tf->file.name.data, path.data);
-
- (void) ngx_ext_rename_file(&tf->file.name, &path, &ext);
-}
-
-
-static void
-ngx_http_upstream_dummy_handler(ngx_http_request_t *r, ngx_http_upstream_t *u)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http upstream dummy handler");
-}
-
-
-static void
-ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
- ngx_uint_t ft_type)
-{
- ngx_uint_t status, state;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http next upstream, %xi", ft_type);
-
- if (u->peer.sockaddr) {
-
- if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_403
- || ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404)
- {
- state = NGX_PEER_NEXT;
-
- } else {
- state = NGX_PEER_FAILED;
- }
-
- u->peer.free(&u->peer, u->peer.data, state);
- u->peer.sockaddr = NULL;
- }
-
- if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT,
- "upstream timed out");
- }
-
- if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR) {
- status = 0;
-
- /* TODO: inform balancer instead */
-
- u->peer.tries++;
-
- } else {
- switch(ft_type) {
-
- case NGX_HTTP_UPSTREAM_FT_TIMEOUT:
- status = NGX_HTTP_GATEWAY_TIME_OUT;
- break;
-
- case NGX_HTTP_UPSTREAM_FT_HTTP_500:
- status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- break;
-
- case NGX_HTTP_UPSTREAM_FT_HTTP_403:
- status = NGX_HTTP_FORBIDDEN;
- break;
-
- case NGX_HTTP_UPSTREAM_FT_HTTP_404:
- status = NGX_HTTP_NOT_FOUND;
- break;
-
- /*
- * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING
- * never reach here
- */
-
- default:
- status = NGX_HTTP_BAD_GATEWAY;
- }
- }
-
- if (r->connection->error) {
- ngx_http_upstream_finalize_request(r, u,
- NGX_HTTP_CLIENT_CLOSED_REQUEST);
- return;
- }
-
- if (status) {
- u->state->status = status;
-
- if (u->peer.tries == 0 || !(u->conf->next_upstream & ft_type)) {
-
-#if (NGX_HTTP_CACHE)
-
- if (u->cache_status == NGX_HTTP_CACHE_EXPIRED
- && (u->conf->cache_use_stale & ft_type))
- {
- ngx_int_t rc;
-
- rc = u->reinit_request(r);
-
- if (rc == NGX_OK) {
- u->cache_status = NGX_HTTP_CACHE_STALE;
- rc = ngx_http_upstream_cache_send(r, u);
- }
-
- ngx_http_upstream_finalize_request(r, u, rc);
- return;
- }
-#endif
-
- ngx_http_upstream_finalize_request(r, u, status);
- return;
- }
- }
-
- if (u->peer.connection) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "close http upstream connection: %d",
- u->peer.connection->fd);
-#if (NGX_HTTP_SSL)
-
- if (u->peer.connection->ssl) {
- u->peer.connection->ssl->no_wait_shutdown = 1;
- u->peer.connection->ssl->no_send_shutdown = 1;
-
- (void) ngx_ssl_shutdown(u->peer.connection);
- }
-#endif
-
- if (u->peer.connection->pool) {
- ngx_destroy_pool(u->peer.connection->pool);
- }
-
- ngx_close_connection(u->peer.connection);
- u->peer.connection = NULL;
- }
-
- ngx_http_upstream_connect(r, u);
-}
-
-
-static void
-ngx_http_upstream_cleanup(void *data)
-{
- ngx_http_request_t *r = data;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "cleanup http upstream request: \"%V\"", &r->uri);
-
- ngx_http_upstream_finalize_request(r, r->upstream, NGX_DONE);
-}
-
-
-static void
-ngx_http_upstream_finalize_request(ngx_http_request_t *r,
- ngx_http_upstream_t *u, ngx_int_t rc)
-{
- ngx_uint_t flush;
- ngx_time_t *tp;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "finalize http upstream request: %i", rc);
-
- if (u->cleanup) {
- *u->cleanup = NULL;
- u->cleanup = NULL;
- }
-
- if (u->resolved && u->resolved->ctx) {
- ngx_resolve_name_done(u->resolved->ctx);
- u->resolved->ctx = NULL;
- }
-
- if (u->state && u->state->response_sec) {
- tp = ngx_timeofday();
- u->state->response_sec = tp->sec - u->state->response_sec;
- u->state->response_msec = tp->msec - u->state->response_msec;
-
- if (u->pipe && u->pipe->read_length) {
- u->state->response_length = u->pipe->read_length;
- }
- }
-
- u->finalize_request(r, rc);
-
- if (u->peer.free && u->peer.sockaddr) {
- u->peer.free(&u->peer, u->peer.data, 0);
- u->peer.sockaddr = NULL;
- }
-
- if (u->peer.connection) {
-
-#if (NGX_HTTP_SSL)
-
- /* TODO: do not shutdown persistent connection */
-
- if (u->peer.connection->ssl) {
-
- /*
- * We send the "close notify" shutdown alert to the upstream only
- * and do not wait its "close notify" shutdown alert.
- * It is acceptable according to the TLS standard.
- */
-
- u->peer.connection->ssl->no_wait_shutdown = 1;
-
- (void) ngx_ssl_shutdown(u->peer.connection);
- }
-#endif
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "close http upstream connection: %d",
- u->peer.connection->fd);
-
- if (u->peer.connection->pool) {
- ngx_destroy_pool(u->peer.connection->pool);
- }
-
- ngx_close_connection(u->peer.connection);
- }
-
- u->peer.connection = NULL;
-
- if (u->pipe && u->pipe->temp_file) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http upstream temp fd: %d",
- u->pipe->temp_file->file.fd);
- }
-
- if (u->store && u->pipe && u->pipe->temp_file
- && u->pipe->temp_file->file.fd != NGX_INVALID_FILE)
- {
- if (ngx_delete_file(u->pipe->temp_file->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_CACHE)
-
- if (r->cache) {
-
- if (u->cacheable) {
-
- if (rc == NGX_HTTP_BAD_GATEWAY || rc == NGX_HTTP_GATEWAY_TIME_OUT) {
- time_t valid;
-
- valid = ngx_http_file_cache_valid(u->conf->cache_valid, rc);
-
- if (valid) {
- r->cache->valid_sec = ngx_time() + valid;
- r->cache->error = rc;
- }
- }
- }
-
- ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
- }
-
-#endif
-
- if (r->subrequest_in_memory
- && u->headers_in.status_n >= NGX_HTTP_SPECIAL_RESPONSE)
- {
- u->buffer.last = u->buffer.pos;
- }
-
- if (rc == NGX_DECLINED) {
- return;
- }
-
- r->connection->log->action = "sending to client";
-
- if (!u->header_sent
- || rc == NGX_HTTP_REQUEST_TIME_OUT
- || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST)
- {
- ngx_http_finalize_request(r, rc);
- return;
- }
-
- flush = 0;
-
- if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
- rc = NGX_ERROR;
- flush = 1;
- }
-
- if (r->header_only) {
- ngx_http_finalize_request(r, rc);
- return;
- }
-
- if (rc == 0) {
- rc = ngx_http_send_special(r, NGX_HTTP_LAST);
-
- } else if (flush) {
- r->keepalive = 0;
- rc = ngx_http_send_special(r, NGX_HTTP_FLUSH);
- }
-
- ngx_http_finalize_request(r, rc);
-}
-
-
-static ngx_int_t
-ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- ngx_table_elt_t **ph;
-
- ph = (ngx_table_elt_t **) ((char *) &r->upstream->headers_in + offset);
-
- if (*ph == NULL) {
- *ph = h;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_process_content_length(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset)
-{
- ngx_http_upstream_t *u;
-
- u = r->upstream;
-
- u->headers_in.content_length = h;
- u->headers_in.content_length_n = ngx_atoof(h->value.data, h->value.len);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_process_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
-#if (NGX_HTTP_CACHE)
- ngx_http_upstream_t *u;
-
- u = r->upstream;
-
- if (!(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_SET_COOKIE)) {
- u->cacheable = 0;
- }
-#endif
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset)
-{
- ngx_array_t *pa;
- ngx_table_elt_t **ph;
- ngx_http_upstream_t *u;
-
- u = r->upstream;
- pa = &u->headers_in.cache_control;
-
- if (pa->elts == NULL) {
- if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK)
- {
- return NGX_ERROR;
- }
- }
-
- ph = ngx_array_push(pa);
- if (ph == NULL) {
- return NGX_ERROR;
- }
-
- *ph = h;
-
-#if (NGX_HTTP_CACHE)
- {
- u_char *p, *last;
- ngx_int_t n;
-
- if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL) {
- return NGX_OK;
- }
-
- if (r->cache == NULL) {
- return NGX_OK;
- }
-
- if (r->cache->valid_sec != 0 && u->headers_in.x_accel_expires != NULL) {
- return NGX_OK;
- }
-
- p = h->value.data;
- last = p + h->value.len;
-
- if (ngx_strlcasestrn(p, last, (u_char *) "no-cache", 8 - 1) != NULL
- || ngx_strlcasestrn(p, last, (u_char *) "no-store", 8 - 1) != NULL
- || ngx_strlcasestrn(p, last, (u_char *) "private", 7 - 1) != NULL)
- {
- u->cacheable = 0;
- return NGX_OK;
- }
-
- p = ngx_strlcasestrn(p, last, (u_char *) "max-age=", 8 - 1);
-
- if (p == NULL) {
- return NGX_OK;
- }
-
- n = 0;
-
- for (p += 8; p < last; p++) {
- if (*p == ',' || *p == ';' || *p == ' ') {
- break;
- }
-
- if (*p >= '0' && *p <= '9') {
- n = n * 10 + *p - '0';
- continue;
- }
-
- u->cacheable = 0;
- return NGX_OK;
- }
-
- if (n == 0) {
- u->cacheable = 0;
- return NGX_OK;
- }
-
- r->cache->valid_sec = ngx_time() + n;
- }
-#endif
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- ngx_http_upstream_t *u;
-
- u = r->upstream;
- u->headers_in.expires = h;
-
-#if (NGX_HTTP_CACHE)
- {
- time_t expires;
-
- if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_EXPIRES) {
- return NGX_OK;
- }
-
- if (r->cache == NULL) {
- return NGX_OK;
- }
-
- if (r->cache->valid_sec != 0) {
- return NGX_OK;
- }
-
- expires = ngx_http_parse_time(h->value.data, h->value.len);
-
- if (expires == NGX_ERROR || expires < ngx_time()) {
- u->cacheable = 0;
- return NGX_OK;
- }
-
- r->cache->valid_sec = expires;
- }
-#endif
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_process_accel_expires(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset)
-{
- ngx_http_upstream_t *u;
-
- u = r->upstream;
- u->headers_in.x_accel_expires = h;
-
-#if (NGX_HTTP_CACHE)
- {
- u_char *p;
- size_t len;
- ngx_int_t n;
-
- if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_EXPIRES) {
- return NGX_OK;
- }
-
- if (r->cache == NULL) {
- return NGX_OK;
- }
-
- len = h->value.len;
- p = h->value.data;
-
- if (p[0] != '@') {
- n = ngx_atoi(p, len);
-
- switch (n) {
- case 0:
- u->cacheable = 0;
- /* fall through */
-
- case NGX_ERROR:
- return NGX_OK;
-
- default:
- r->cache->valid_sec = ngx_time() + n;
- return NGX_OK;
- }
- }
-
- p++;
- len--;
-
- n = ngx_atoi(p, len);
-
- if (n != NGX_ERROR) {
- r->cache->valid_sec = n;
- }
- }
-#endif
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- ngx_int_t n;
- ngx_http_upstream_t *u;
-
- u = r->upstream;
- u->headers_in.x_accel_limit_rate = h;
-
- if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE) {
- return NGX_OK;
- }
-
- n = ngx_atoi(h->value.data, h->value.len);
-
- if (n != NGX_ERROR) {
- r->limit_rate = (size_t) n;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_process_buffering(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- u_char c0, c1, c2;
- ngx_http_upstream_t *u;
-
- u = r->upstream;
-
- if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_BUFFERING) {
- return NGX_OK;
- }
-
- if (u->conf->change_buffering) {
-
- if (h->value.len == 2) {
- c0 = ngx_tolower(h->value.data[0]);
- c1 = ngx_tolower(h->value.data[1]);
-
- if (c0 == 'n' && c1 == 'o') {
- u->buffering = 0;
- }
-
- } else if (h->value.len == 3) {
- c0 = ngx_tolower(h->value.data[0]);
- c1 = ngx_tolower(h->value.data[1]);
- c2 = ngx_tolower(h->value.data[2]);
-
- if (c0 == 'y' && c1 == 'e' && c2 == 's') {
- u->buffering = 1;
- }
- }
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_process_charset(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- if (r->upstream->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_CHARSET) {
- return NGX_OK;
- }
-
- r->headers_out.override_charset = &h->value;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- r->upstream->headers_in.connection = h;
-
- if (ngx_strlcasestrn(h->value.data, h->value.data + h->value.len,
- (u_char *) "close", 5 - 1)
- != NULL)
- {
- r->upstream->headers_in.connection_close = 1;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_process_transfer_encoding(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset)
-{
- r->upstream->headers_in.transfer_encoding = h;
-
- if (ngx_strlcasestrn(h->value.data, h->value.data + h->value.len,
- (u_char *) "chunked", 7 - 1)
- != NULL)
- {
- r->upstream->headers_in.chunked = 1;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- ngx_table_elt_t *ho, **ph;
-
- ho = ngx_list_push(&r->headers_out.headers);
- if (ho == NULL) {
- return NGX_ERROR;
- }
-
- *ho = *h;
-
- if (offset) {
- ph = (ngx_table_elt_t **) ((char *) &r->headers_out + offset);
- *ph = ho;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset)
-{
- ngx_array_t *pa;
- ngx_table_elt_t *ho, **ph;
-
- pa = (ngx_array_t *) ((char *) &r->headers_out + offset);
-
- if (pa->elts == NULL) {
- if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK)
- {
- return NGX_ERROR;
- }
- }
-
- ph = ngx_array_push(pa);
- if (ph == NULL) {
- return NGX_ERROR;
- }
-
- ho = ngx_list_push(&r->headers_out.headers);
- if (ho == NULL) {
- return NGX_ERROR;
- }
-
- *ho = *h;
- *ph = ho;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_copy_content_type(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- u_char *p, *last;
-
- r->headers_out.content_type_len = h->value.len;
- r->headers_out.content_type = h->value;
- r->headers_out.content_type_lowcase = NULL;
-
- for (p = h->value.data; *p; p++) {
-
- if (*p != ';') {
- continue;
- }
-
- last = p;
-
- while (*++p == ' ') { /* void */ }
-
- if (*p == '\0') {
- return NGX_OK;
- }
-
- if (ngx_strncasecmp(p, (u_char *) "charset=", 8) != 0) {
- continue;
- }
-
- p += 8;
-
- r->headers_out.content_type_len = last - h->value.data;
-
- if (*p == '"') {
- p++;
- }
-
- last = h->value.data + h->value.len;
-
- if (*(last - 1) == '"') {
- last--;
- }
-
- r->headers_out.charset.len = last - p;
- r->headers_out.charset.data = p;
-
- return NGX_OK;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_copy_last_modified(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- ngx_table_elt_t *ho;
-
- ho = ngx_list_push(&r->headers_out.headers);
- if (ho == NULL) {
- return NGX_ERROR;
- }
-
- *ho = *h;
-
- r->headers_out.last_modified = ho;
-
-#if (NGX_HTTP_CACHE)
-
- if (r->upstream->cacheable) {
- r->headers_out.last_modified_time = ngx_http_parse_time(h->value.data,
- h->value.len);
- }
-
-#endif
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_rewrite_location(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- ngx_int_t rc;
- ngx_table_elt_t *ho;
-
- ho = ngx_list_push(&r->headers_out.headers);
- if (ho == NULL) {
- return NGX_ERROR;
- }
-
- *ho = *h;
-
- if (r->upstream->rewrite_redirect) {
- rc = r->upstream->rewrite_redirect(r, ho, 0);
-
- if (rc == NGX_DECLINED) {
- return NGX_OK;
- }
-
- if (rc == NGX_OK) {
- r->headers_out.location = ho;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "rewritten location: \"%V\"", &ho->value);
- }
-
- return rc;
- }
-
- if (ho->value.data[0] != '/') {
- r->headers_out.location = ho;
- }
-
- /*
- * we do not set r->headers_out.location here to avoid the handling
- * the local redirects without a host name by ngx_http_header_filter()
- */
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- u_char *p;
- ngx_int_t rc;
- ngx_table_elt_t *ho;
-
- ho = ngx_list_push(&r->headers_out.headers);
- if (ho == NULL) {
- return NGX_ERROR;
- }
-
- *ho = *h;
-
- if (r->upstream->rewrite_redirect) {
-
- p = ngx_strcasestrn(ho->value.data, "url=", 4 - 1);
-
- if (p) {
- rc = r->upstream->rewrite_redirect(r, ho, p + 4 - ho->value.data);
-
- } else {
- return NGX_OK;
- }
-
- if (rc == NGX_DECLINED) {
- return NGX_OK;
- }
-
- if (rc == NGX_OK) {
- r->headers_out.refresh = ho;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "rewritten refresh: \"%V\"", &ho->value);
- }
-
- return rc;
- }
-
- r->headers_out.refresh = ho;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_rewrite_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
- ngx_uint_t offset)
-{
- ngx_int_t rc;
- ngx_table_elt_t *ho;
-
- ho = ngx_list_push(&r->headers_out.headers);
- if (ho == NULL) {
- return NGX_ERROR;
- }
-
- *ho = *h;
-
- if (r->upstream->rewrite_cookie) {
- rc = r->upstream->rewrite_cookie(r, ho);
-
- if (rc == NGX_DECLINED) {
- return NGX_OK;
- }
-
-#if (NGX_DEBUG)
- if (rc == NGX_OK) {
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "rewritten cookie: \"%V\"", &ho->value);
- }
-#endif
-
- return rc;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset)
-{
- ngx_table_elt_t *ho;
-
-#if (NGX_HTTP_CACHE)
-
- if (r->cached) {
- r->allow_ranges = 1;
- return NGX_OK;
- }
-
- if (r->upstream->cacheable) {
- r->allow_ranges = 1;
- r->single_range = 1;
- return NGX_OK;
- }
-
-#endif
-
- ho = ngx_list_push(&r->headers_out.headers);
- if (ho == NULL) {
- return NGX_ERROR;
- }
-
- *ho = *h;
-
- r->headers_out.accept_ranges = ho;
-
- return NGX_OK;
-}
-
-
-#if (NGX_HTTP_GZIP)
-
-static ngx_int_t
-ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r,
- ngx_table_elt_t *h, ngx_uint_t offset)
-{
- ngx_table_elt_t *ho;
-
- ho = ngx_list_push(&r->headers_out.headers);
- if (ho == NULL) {
- return NGX_ERROR;
- }
-
- *ho = *h;
-
- r->headers_out.content_encoding = ho;
-
- return NGX_OK;
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_upstream_add_variables(ngx_conf_t *cf)
-{
- ngx_http_variable_t *var, *v;
-
- for (v = ngx_http_upstream_vars; v->name.len; v++) {
- var = ngx_http_add_variable(cf, &v->name, v->flags);
- if (var == NULL) {
- return NGX_ERROR;
- }
-
- var->get_handler = v->get_handler;
- var->data = v->data;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_addr_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
- size_t len;
- ngx_uint_t i;
- ngx_http_upstream_state_t *state;
-
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- len = 0;
- state = r->upstream_states->elts;
-
- for (i = 0; i < r->upstream_states->nelts; i++) {
- if (state[i].peer) {
- len += state[i].peer->len + 2;
-
- } else {
- len += 3;
- }
- }
-
- p = ngx_pnalloc(r->pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->data = p;
-
- i = 0;
-
- for ( ;; ) {
- if (state[i].peer) {
- p = ngx_cpymem(p, state[i].peer->data, state[i].peer->len);
- }
-
- if (++i == r->upstream_states->nelts) {
- break;
- }
-
- if (state[i].peer) {
- *p++ = ',';
- *p++ = ' ';
-
- } else {
- *p++ = ' ';
- *p++ = ':';
- *p++ = ' ';
-
- if (++i == r->upstream_states->nelts) {
- break;
- }
-
- continue;
- }
- }
-
- v->len = p - v->data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_status_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
- size_t len;
- ngx_uint_t i;
- ngx_http_upstream_state_t *state;
-
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- len = r->upstream_states->nelts * (3 + 2);
-
- p = ngx_pnalloc(r->pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->data = p;
-
- i = 0;
- state = r->upstream_states->elts;
-
- for ( ;; ) {
- if (state[i].status) {
- p = ngx_sprintf(p, "%ui", state[i].status);
-
- } else {
- *p++ = '-';
- }
-
- if (++i == r->upstream_states->nelts) {
- break;
- }
-
- if (state[i].peer) {
- *p++ = ',';
- *p++ = ' ';
-
- } else {
- *p++ = ' ';
- *p++ = ':';
- *p++ = ' ';
-
- if (++i == r->upstream_states->nelts) {
- break;
- }
-
- continue;
- }
- }
-
- v->len = p - v->data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
- size_t len;
- ngx_uint_t i;
- ngx_msec_int_t ms;
- ngx_http_upstream_state_t *state;
-
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- len = r->upstream_states->nelts * (NGX_TIME_T_LEN + 4 + 2);
-
- p = ngx_pnalloc(r->pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->data = p;
-
- i = 0;
- state = r->upstream_states->elts;
-
- for ( ;; ) {
- if (state[i].status) {
- ms = (ngx_msec_int_t)
- (state[i].response_sec * 1000 + state[i].response_msec);
- ms = ngx_max(ms, 0);
- p = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000);
-
- } else {
- *p++ = '-';
- }
-
- if (++i == r->upstream_states->nelts) {
- break;
- }
-
- if (state[i].peer) {
- *p++ = ',';
- *p++ = ' ';
-
- } else {
- *p++ = ' ';
- *p++ = ':';
- *p++ = ' ';
-
- if (++i == r->upstream_states->nelts) {
- break;
- }
-
- continue;
- }
- }
-
- v->len = p - v->data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_response_length_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
- size_t len;
- ngx_uint_t i;
- ngx_http_upstream_state_t *state;
-
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- len = r->upstream_states->nelts * (NGX_OFF_T_LEN + 2);
-
- p = ngx_pnalloc(r->pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->data = p;
-
- i = 0;
- state = r->upstream_states->elts;
-
- for ( ;; ) {
- p = ngx_sprintf(p, "%O", state[i].response_length);
-
- if (++i == r->upstream_states->nelts) {
- break;
- }
-
- if (state[i].peer) {
- *p++ = ',';
- *p++ = ' ';
-
- } else {
- *p++ = ' ';
- *p++ = ':';
- *p++ = ' ';
-
- if (++i == r->upstream_states->nelts) {
- break;
- }
-
- continue;
- }
- }
-
- v->len = p - v->data;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_upstream_header_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- if (r->upstream == NULL) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
- &r->upstream->headers_in.headers.part,
- sizeof("upstream_http_") - 1);
-}
-
-
-#if (NGX_HTTP_CACHE)
-
-ngx_int_t
-ngx_http_upstream_cache_status(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_uint_t n;
-
- if (r->upstream == NULL || r->upstream->cache_status == 0) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- n = r->upstream->cache_status - 1;
-
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->len = ngx_http_cache_status[n].len;
- v->data = ngx_http_cache_status[n].data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_upstream_cache_last_modified(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
-
- if (r->upstream == NULL
- || !r->upstream->conf->cache_revalidate
- || r->upstream->cache_status != NGX_HTTP_CACHE_EXPIRED
- || r->cache->last_modified == -1)
- {
- v->not_found = 1;
- return NGX_OK;
- }
-
- p = ngx_pnalloc(r->pool, sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_http_time(p, r->cache->last_modified) - p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
-}
-
-#endif
-
-
-static char *
-ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
-{
- char *rv;
- void *mconf;
- ngx_str_t *value;
- ngx_url_t u;
- ngx_uint_t m;
- ngx_conf_t pcf;
- ngx_http_module_t *module;
- ngx_http_conf_ctx_t *ctx, *http_ctx;
- ngx_http_upstream_srv_conf_t *uscf;
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- value = cf->args->elts;
- u.host = value[1];
- u.no_resolve = 1;
- u.no_port = 1;
-
- uscf = ngx_http_upstream_add(cf, &u, NGX_HTTP_UPSTREAM_CREATE
- |NGX_HTTP_UPSTREAM_WEIGHT
- |NGX_HTTP_UPSTREAM_MAX_FAILS
- |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
- |NGX_HTTP_UPSTREAM_DOWN
- |NGX_HTTP_UPSTREAM_BACKUP);
- if (uscf == NULL) {
- return NGX_CONF_ERROR;
- }
-
-
- ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- http_ctx = cf->ctx;
- ctx->main_conf = http_ctx->main_conf;
-
- /* the upstream{}'s srv_conf */
-
- ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
- if (ctx->srv_conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->srv_conf[ngx_http_upstream_module.ctx_index] = uscf;
-
- uscf->srv_conf = ctx->srv_conf;
-
-
- /* the upstream{}'s loc_conf */
-
- ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
- if (ctx->loc_conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
- continue;
- }
-
- module = ngx_modules[m]->ctx;
-
- if (module->create_srv_conf) {
- mconf = module->create_srv_conf(cf);
- if (mconf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf;
- }
-
- if (module->create_loc_conf) {
- mconf = module->create_loc_conf(cf);
- if (mconf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->loc_conf[ngx_modules[m]->ctx_index] = mconf;
- }
- }
-
-
- /* parse inside upstream{} */
-
- pcf = *cf;
- cf->ctx = ctx;
- cf->cmd_type = NGX_HTTP_UPS_CONF;
-
- rv = ngx_conf_parse(cf, NULL);
-
- *cf = pcf;
-
- if (rv != NGX_CONF_OK) {
- return rv;
- }
-
- if (uscf->servers == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "no servers are inside upstream");
- return NGX_CONF_ERROR;
- }
-
- return rv;
-}
-
-
-static char *
-ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_upstream_srv_conf_t *uscf = conf;
-
- time_t fail_timeout;
- ngx_str_t *value, s;
- ngx_url_t u;
- ngx_int_t weight, max_fails;
- ngx_uint_t i;
- ngx_http_upstream_server_t *us;
-
- if (uscf->servers == NULL) {
- uscf->servers = ngx_array_create(cf->pool, 4,
- sizeof(ngx_http_upstream_server_t));
- if (uscf->servers == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- us = ngx_array_push(uscf->servers);
- if (us == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(us, sizeof(ngx_http_upstream_server_t));
-
- value = cf->args->elts;
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- u.url = value[1];
- u.default_port = 80;
-
- 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);
- }
-
- return NGX_CONF_ERROR;
- }
-
- weight = 1;
- max_fails = 1;
- fail_timeout = 10;
-
- for (i = 2; i < cf->args->nelts; i++) {
-
- if (ngx_strncmp(value[i].data, "weight=", 7) == 0) {
-
- if (!(uscf->flags & NGX_HTTP_UPSTREAM_WEIGHT)) {
- goto invalid;
- }
-
- weight = ngx_atoi(&value[i].data[7], value[i].len - 7);
-
- if (weight == NGX_ERROR || weight == 0) {
- goto invalid;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) {
-
- if (!(uscf->flags & NGX_HTTP_UPSTREAM_MAX_FAILS)) {
- goto invalid;
- }
-
- max_fails = ngx_atoi(&value[i].data[10], value[i].len - 10);
-
- if (max_fails == NGX_ERROR) {
- goto invalid;
- }
-
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "fail_timeout=", 13) == 0) {
-
- if (!(uscf->flags & NGX_HTTP_UPSTREAM_FAIL_TIMEOUT)) {
- goto invalid;
- }
-
- s.len = value[i].len - 13;
- s.data = &value[i].data[13];
-
- fail_timeout = ngx_parse_time(&s, 1);
-
- if (fail_timeout == (time_t) NGX_ERROR) {
- goto invalid;
- }
-
- continue;
- }
-
- if (ngx_strcmp(value[i].data, "backup") == 0) {
-
- if (!(uscf->flags & NGX_HTTP_UPSTREAM_BACKUP)) {
- goto invalid;
- }
-
- us->backup = 1;
-
- continue;
- }
-
- if (ngx_strcmp(value[i].data, "down") == 0) {
-
- if (!(uscf->flags & NGX_HTTP_UPSTREAM_DOWN)) {
- goto invalid;
- }
-
- us->down = 1;
-
- continue;
- }
-
- goto invalid;
- }
-
- us->addrs = u.addrs;
- us->naddrs = u.naddrs;
- us->weight = weight;
- us->max_fails = max_fails;
- us->fail_timeout = fail_timeout;
-
- return NGX_CONF_OK;
-
-invalid:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[i]);
-
- return NGX_CONF_ERROR;
-}
-
-
-ngx_http_upstream_srv_conf_t *
-ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
-{
- ngx_uint_t i;
- ngx_http_upstream_server_t *us;
- ngx_http_upstream_srv_conf_t *uscf, **uscfp;
- ngx_http_upstream_main_conf_t *umcf;
-
- if (!(flags & NGX_HTTP_UPSTREAM_CREATE)) {
-
- 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);
- }
-
- return NULL;
- }
- }
-
- umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module);
-
- uscfp = umcf->upstreams.elts;
-
- for (i = 0; i < umcf->upstreams.nelts; i++) {
-
- if (uscfp[i]->host.len != u->host.len
- || ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len)
- != 0)
- {
- continue;
- }
-
- if ((flags & NGX_HTTP_UPSTREAM_CREATE)
- && (uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE))
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate upstream \"%V\"", &u->host);
- return NULL;
- }
-
- if ((uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE) && !u->no_port) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "upstream \"%V\" may not have port %d",
- &u->host, u->port);
- return NULL;
- }
-
- if ((flags & NGX_HTTP_UPSTREAM_CREATE) && !uscfp[i]->no_port) {
- 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, uscfp[i]->line);
- return NULL;
- }
-
- if (uscfp[i]->port && u->port
- && uscfp[i]->port != u->port)
- {
- continue;
- }
-
- if (uscfp[i]->default_port && u->default_port
- && uscfp[i]->default_port != u->default_port)
- {
- continue;
- }
-
- if (flags & NGX_HTTP_UPSTREAM_CREATE) {
- uscfp[i]->flags = flags;
- }
-
- return uscfp[i];
- }
-
- uscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_srv_conf_t));
- if (uscf == NULL) {
- return NULL;
- }
-
- uscf->flags = flags;
- uscf->host = u->host;
- 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;
- uscf->no_port = u->no_port;
-
- if (u->naddrs == 1) {
- uscf->servers = ngx_array_create(cf->pool, 1,
- sizeof(ngx_http_upstream_server_t));
- if (uscf->servers == NULL) {
- return NULL;
- }
-
- us = ngx_array_push(uscf->servers);
- if (us == NULL) {
- return NULL;
- }
-
- ngx_memzero(us, sizeof(ngx_http_upstream_server_t));
-
- us->addrs = u->addrs;
- us->naddrs = 1;
- }
-
- uscfp = ngx_array_push(&umcf->upstreams);
- if (uscfp == NULL) {
- return NULL;
- }
-
- *uscfp = uscf;
-
- return uscf;
-}
-
-
-char *
-ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf)
-{
- char *p = conf;
-
- ngx_int_t rc;
- ngx_str_t *value;
- ngx_http_complex_value_t cv;
- ngx_http_upstream_local_t **plocal, *local;
- ngx_http_compile_complex_value_t ccv;
-
- plocal = (ngx_http_upstream_local_t **) (p + cmd->offset);
-
- if (*plocal != NGX_CONF_UNSET_PTR) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- *plocal = NULL;
- return NGX_CONF_OK;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- local = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_local_t));
- if (local == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *plocal = local;
-
- if (cv.lengths) {
- local->value = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (local->value == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *local->value = cv;
-
- return NGX_CONF_OK;
- }
-
- local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
- if (local->addr == NULL) {
- return NGX_CONF_ERROR;
- }
-
- rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len);
-
- switch (rc) {
- case NGX_OK:
- local->addr->name = value[1];
- return NGX_CONF_OK;
-
- case NGX_DECLINED:
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid address \"%V\"", &value[1]);
- /* fall through */
-
- default:
- return NGX_CONF_ERROR;
- }
-}
-
-
-static ngx_addr_t *
-ngx_http_upstream_get_local(ngx_http_request_t *r,
- ngx_http_upstream_local_t *local)
-{
- ngx_int_t rc;
- ngx_str_t val;
- ngx_addr_t *addr;
-
- if (local == NULL) {
- return NULL;
- }
-
- if (local->value == NULL) {
- return local->addr;
- }
-
- if (ngx_http_complex_value(r, local->value, &val) != NGX_OK) {
- return NULL;
- }
-
- if (val.len == 0) {
- return NULL;
- }
-
- addr = ngx_palloc(r->pool, sizeof(ngx_addr_t));
- if (addr == NULL) {
- return NULL;
- }
-
- rc = ngx_parse_addr(r->pool, addr, val.data, val.len);
-
- switch (rc) {
- case NGX_OK:
- addr->name = val;
- return addr;
-
- case NGX_DECLINED:
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "invalid local address \"%V\"", &val);
- /* fall through */
-
- default:
- return NULL;
- }
-}
-
-
-char *
-ngx_http_upstream_param_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf)
-{
- char *p = conf;
-
- ngx_str_t *value;
- ngx_array_t **a;
- ngx_http_upstream_param_t *param;
-
- a = (ngx_array_t **) (p + cmd->offset);
-
- if (*a == NULL) {
- *a = ngx_array_create(cf->pool, 4, sizeof(ngx_http_upstream_param_t));
- if (*a == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- param = ngx_array_push(*a);
- if (param == NULL) {
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
-
- param->key = value[1];
- param->value = value[2];
- param->skip_empty = 0;
-
- if (cf->args->nelts == 4) {
- if (ngx_strcmp(value[3].data, "if_not_empty") != 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid parameter \"%V\"", &value[3]);
- return NGX_CONF_ERROR;
- }
-
- param->skip_empty = 1;
- }
-
- return NGX_CONF_OK;
-}
-
-
-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 = prev->hide_headers;
- conf->pass_headers = prev->pass_headers;
-
- conf->hide_headers_hash = prev->hide_headers_hash;
-
- if (conf->hide_headers_hash.buckets
-#if (NGX_HTTP_CACHE)
- && ((conf->cache == NULL) == (prev->cache == NULL))
-#endif
- )
- {
- return NGX_OK;
- }
-
- } 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)
-{
- ngx_http_upstream_main_conf_t *umcf;
-
- umcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_main_conf_t));
- if (umcf == NULL) {
- return NULL;
- }
-
- if (ngx_array_init(&umcf->upstreams, cf->pool, 4,
- sizeof(ngx_http_upstream_srv_conf_t *))
- != NGX_OK)
- {
- return NULL;
- }
-
- return umcf;
-}
-
-
-static char *
-ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf)
-{
- ngx_http_upstream_main_conf_t *umcf = conf;
-
- ngx_uint_t i;
- ngx_array_t headers_in;
- ngx_hash_key_t *hk;
- ngx_hash_init_t hash;
- ngx_http_upstream_init_pt init;
- ngx_http_upstream_header_t *header;
- ngx_http_upstream_srv_conf_t **uscfp;
-
- uscfp = umcf->upstreams.elts;
-
- for (i = 0; i < umcf->upstreams.nelts; i++) {
-
- init = uscfp[i]->peer.init_upstream ? uscfp[i]->peer.init_upstream:
- ngx_http_upstream_init_round_robin;
-
- if (init(cf, uscfp[i]) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
-
- /* upstream_headers_in_hash */
-
- if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t))
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- for (header = ngx_http_upstream_headers_in; header->name.len; header++) {
- hk = ngx_array_push(&headers_in);
- if (hk == NULL) {
- return NGX_CONF_ERROR;
- }
-
- hk->key = header->name;
- hk->key_hash = ngx_hash_key_lc(header->name.data, header->name.len);
- hk->value = header;
- }
-
- hash.hash = &umcf->headers_in_hash;
- hash.key = ngx_hash_key_lc;
- hash.max_size = 512;
- hash.bucket_size = ngx_align(64, ngx_cacheline_size);
- hash.name = "upstream_headers_in_hash";
- hash.pool = cf->pool;
- hash.temp_pool = NULL;
-
- if (ngx_hash_init(&hash, headers_in.elts, headers_in.nelts) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_upstream.h b/usr.sbin/nginx/src/http/ngx_http_upstream.h
deleted file mode 100644
index 9f96c50f309..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_upstream.h
+++ /dev/null
@@ -1,383 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HTTP_UPSTREAM_H_INCLUDED_
-#define _NGX_HTTP_UPSTREAM_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_event_connect.h>
-#include <ngx_event_pipe.h>
-#include <ngx_http.h>
-
-
-#define NGX_HTTP_UPSTREAM_FT_ERROR 0x00000002
-#define NGX_HTTP_UPSTREAM_FT_TIMEOUT 0x00000004
-#define NGX_HTTP_UPSTREAM_FT_INVALID_HEADER 0x00000008
-#define NGX_HTTP_UPSTREAM_FT_HTTP_500 0x00000010
-#define NGX_HTTP_UPSTREAM_FT_HTTP_502 0x00000020
-#define NGX_HTTP_UPSTREAM_FT_HTTP_503 0x00000040
-#define NGX_HTTP_UPSTREAM_FT_HTTP_504 0x00000080
-#define NGX_HTTP_UPSTREAM_FT_HTTP_403 0x00000100
-#define NGX_HTTP_UPSTREAM_FT_HTTP_404 0x00000200
-#define NGX_HTTP_UPSTREAM_FT_UPDATING 0x00000400
-#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00000800
-#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00001000
-#define NGX_HTTP_UPSTREAM_FT_NOLIVE 0x40000000
-#define NGX_HTTP_UPSTREAM_FT_OFF 0x80000000
-
-#define NGX_HTTP_UPSTREAM_FT_STATUS (NGX_HTTP_UPSTREAM_FT_HTTP_500 \
- |NGX_HTTP_UPSTREAM_FT_HTTP_502 \
- |NGX_HTTP_UPSTREAM_FT_HTTP_503 \
- |NGX_HTTP_UPSTREAM_FT_HTTP_504 \
- |NGX_HTTP_UPSTREAM_FT_HTTP_403 \
- |NGX_HTTP_UPSTREAM_FT_HTTP_404)
-
-#define NGX_HTTP_UPSTREAM_INVALID_HEADER 40
-
-
-#define NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT 0x00000002
-#define NGX_HTTP_UPSTREAM_IGN_XA_EXPIRES 0x00000004
-#define NGX_HTTP_UPSTREAM_IGN_EXPIRES 0x00000008
-#define NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL 0x00000010
-#define NGX_HTTP_UPSTREAM_IGN_SET_COOKIE 0x00000020
-#define NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE 0x00000040
-#define NGX_HTTP_UPSTREAM_IGN_XA_BUFFERING 0x00000080
-#define NGX_HTTP_UPSTREAM_IGN_XA_CHARSET 0x00000100
-
-
-typedef struct {
- ngx_msec_t bl_time;
- ngx_uint_t bl_state;
-
- ngx_uint_t status;
- time_t response_sec;
- ngx_uint_t response_msec;
- off_t response_length;
-
- ngx_str_t *peer;
-} ngx_http_upstream_state_t;
-
-
-typedef struct {
- ngx_hash_t headers_in_hash;
- ngx_array_t upstreams;
- /* ngx_http_upstream_srv_conf_t */
-} ngx_http_upstream_main_conf_t;
-
-typedef struct ngx_http_upstream_srv_conf_s ngx_http_upstream_srv_conf_t;
-
-typedef ngx_int_t (*ngx_http_upstream_init_pt)(ngx_conf_t *cf,
- ngx_http_upstream_srv_conf_t *us);
-typedef ngx_int_t (*ngx_http_upstream_init_peer_pt)(ngx_http_request_t *r,
- ngx_http_upstream_srv_conf_t *us);
-
-
-typedef struct {
- ngx_http_upstream_init_pt init_upstream;
- ngx_http_upstream_init_peer_pt init;
- void *data;
-} ngx_http_upstream_peer_t;
-
-
-typedef struct {
- ngx_addr_t *addrs;
- ngx_uint_t naddrs;
- ngx_uint_t weight;
- ngx_uint_t max_fails;
- time_t fail_timeout;
-
- unsigned down:1;
- unsigned backup:1;
-} ngx_http_upstream_server_t;
-
-
-#define NGX_HTTP_UPSTREAM_CREATE 0x0001
-#define NGX_HTTP_UPSTREAM_WEIGHT 0x0002
-#define NGX_HTTP_UPSTREAM_MAX_FAILS 0x0004
-#define NGX_HTTP_UPSTREAM_FAIL_TIMEOUT 0x0008
-#define NGX_HTTP_UPSTREAM_DOWN 0x0010
-#define NGX_HTTP_UPSTREAM_BACKUP 0x0020
-
-
-struct ngx_http_upstream_srv_conf_s {
- ngx_http_upstream_peer_t peer;
- void **srv_conf;
-
- ngx_array_t *servers; /* ngx_http_upstream_server_t */
-
- ngx_uint_t flags;
- ngx_str_t host;
- u_char *file_name;
- ngx_uint_t line;
- in_port_t port;
- in_port_t default_port;
- ngx_uint_t no_port; /* unsigned no_port:1 */
-};
-
-
-typedef struct {
- ngx_addr_t *addr;
- ngx_http_complex_value_t *value;
-} ngx_http_upstream_local_t;
-
-
-typedef struct {
- ngx_http_upstream_srv_conf_t *upstream;
-
- ngx_msec_t connect_timeout;
- ngx_msec_t send_timeout;
- ngx_msec_t read_timeout;
- ngx_msec_t timeout;
-
- size_t send_lowat;
- size_t buffer_size;
-
- size_t busy_buffers_size;
- size_t max_temp_file_size;
- size_t temp_file_write_size;
-
- size_t busy_buffers_size_conf;
- size_t max_temp_file_size_conf;
- size_t temp_file_write_size_conf;
-
- ngx_bufs_t bufs;
-
- ngx_uint_t ignore_headers;
- ngx_uint_t next_upstream;
- ngx_uint_t store_access;
- ngx_flag_t buffering;
- ngx_flag_t pass_request_headers;
- ngx_flag_t pass_request_body;
-
- ngx_flag_t ignore_client_abort;
- ngx_flag_t intercept_errors;
- ngx_flag_t cyclic_temp_file;
-
- ngx_path_t *temp_path;
-
- ngx_hash_t hide_headers_hash;
- ngx_array_t *hide_headers;
- ngx_array_t *pass_headers;
-
- ngx_http_upstream_local_t *local;
-
-#if (NGX_HTTP_CACHE)
- ngx_shm_zone_t *cache;
-
- ngx_uint_t cache_min_uses;
- ngx_uint_t cache_use_stale;
- ngx_uint_t cache_methods;
-
- ngx_flag_t cache_lock;
- ngx_msec_t cache_lock_timeout;
-
- ngx_flag_t cache_revalidate;
-
- ngx_array_t *cache_valid;
- ngx_array_t *cache_bypass;
- ngx_array_t *no_cache;
-#endif
-
- ngx_array_t *store_lengths;
- ngx_array_t *store_values;
-
- signed store:2;
- unsigned intercept_404:1;
- unsigned change_buffering:1;
-
-#if (NGX_HTTP_SSL)
- ngx_ssl_t *ssl;
- ngx_flag_t ssl_session_reuse;
-#endif
-
- ngx_str_t module;
-} ngx_http_upstream_conf_t;
-
-
-typedef struct {
- ngx_str_t name;
- ngx_http_header_handler_pt handler;
- ngx_uint_t offset;
- ngx_http_header_handler_pt copy_handler;
- ngx_uint_t conf;
- ngx_uint_t redirect; /* unsigned redirect:1; */
-} ngx_http_upstream_header_t;
-
-
-typedef struct {
- ngx_list_t headers;
-
- ngx_uint_t status_n;
- ngx_str_t status_line;
-
- ngx_table_elt_t *status;
- ngx_table_elt_t *date;
- ngx_table_elt_t *server;
- ngx_table_elt_t *connection;
-
- ngx_table_elt_t *expires;
- ngx_table_elt_t *etag;
- ngx_table_elt_t *x_accel_expires;
- ngx_table_elt_t *x_accel_redirect;
- ngx_table_elt_t *x_accel_limit_rate;
-
- ngx_table_elt_t *content_type;
- ngx_table_elt_t *content_length;
-
- ngx_table_elt_t *last_modified;
- ngx_table_elt_t *location;
- ngx_table_elt_t *accept_ranges;
- ngx_table_elt_t *www_authenticate;
- ngx_table_elt_t *transfer_encoding;
-
-#if (NGX_HTTP_GZIP)
- ngx_table_elt_t *content_encoding;
-#endif
-
- off_t content_length_n;
-
- ngx_array_t cache_control;
-
- unsigned connection_close:1;
- unsigned chunked:1;
-} ngx_http_upstream_headers_in_t;
-
-
-typedef struct {
- ngx_str_t host;
- in_port_t port;
- ngx_uint_t no_port; /* unsigned no_port:1 */
-
- ngx_uint_t naddrs;
- ngx_addr_t *addrs;
-
- struct sockaddr *sockaddr;
- socklen_t socklen;
-
- ngx_resolver_ctx_t *ctx;
-} ngx_http_upstream_resolved_t;
-
-
-typedef void (*ngx_http_upstream_handler_pt)(ngx_http_request_t *r,
- ngx_http_upstream_t *u);
-
-
-struct ngx_http_upstream_s {
- ngx_http_upstream_handler_pt read_event_handler;
- ngx_http_upstream_handler_pt write_event_handler;
-
- ngx_peer_connection_t peer;
-
- ngx_event_pipe_t *pipe;
-
- ngx_chain_t *request_bufs;
-
- ngx_output_chain_ctx_t output;
- ngx_chain_writer_ctx_t writer;
-
- ngx_http_upstream_conf_t *conf;
-
- ngx_http_upstream_headers_in_t headers_in;
-
- ngx_http_upstream_resolved_t *resolved;
-
- ngx_buf_t from_client;
-
- ngx_buf_t buffer;
- off_t length;
-
- ngx_chain_t *out_bufs;
- ngx_chain_t *busy_bufs;
- ngx_chain_t *free_bufs;
-
- ngx_int_t (*input_filter_init)(void *data);
- ngx_int_t (*input_filter)(void *data, ssize_t bytes);
- void *input_filter_ctx;
-
-#if (NGX_HTTP_CACHE)
- ngx_int_t (*create_key)(ngx_http_request_t *r);
-#endif
- ngx_int_t (*create_request)(ngx_http_request_t *r);
- ngx_int_t (*reinit_request)(ngx_http_request_t *r);
- ngx_int_t (*process_header)(ngx_http_request_t *r);
- void (*abort_request)(ngx_http_request_t *r);
- void (*finalize_request)(ngx_http_request_t *r,
- ngx_int_t rc);
- ngx_int_t (*rewrite_redirect)(ngx_http_request_t *r,
- ngx_table_elt_t *h, size_t prefix);
- ngx_int_t (*rewrite_cookie)(ngx_http_request_t *r,
- ngx_table_elt_t *h);
-
- ngx_msec_t timeout;
-
- ngx_http_upstream_state_t *state;
-
- ngx_str_t method;
- ngx_str_t schema;
- ngx_str_t uri;
-
- ngx_http_cleanup_pt *cleanup;
-
- unsigned store:1;
- unsigned cacheable:1;
- unsigned accel:1;
- unsigned ssl:1;
-#if (NGX_HTTP_CACHE)
- unsigned cache_status:3;
-#endif
-
- unsigned buffering:1;
- unsigned keepalive:1;
- unsigned upgrade:1;
-
- unsigned request_sent:1;
- unsigned header_sent:1;
-};
-
-
-typedef struct {
- ngx_uint_t status;
- ngx_uint_t mask;
-} ngx_http_upstream_next_t;
-
-
-typedef struct {
- ngx_str_t key;
- ngx_str_t value;
- ngx_uint_t skip_empty;
-} ngx_http_upstream_param_t;
-
-
-ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-
-ngx_int_t ngx_http_upstream_create(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);
-char *ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-char *ngx_http_upstream_param_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-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) \
- uscf->srv_conf[module.ctx_index]
-
-
-extern ngx_module_t ngx_http_upstream_module;
-extern ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[];
-extern ngx_conf_bitmask_t ngx_http_upstream_ignore_headers_masks[];
-
-
-#endif /* _NGX_HTTP_UPSTREAM_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.c b/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.c
deleted file mode 100644
index 85ff5581baf..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.c
+++ /dev/null
@@ -1,689 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static ngx_http_upstream_rr_peer_t *ngx_http_upstream_get_peer(
- ngx_http_upstream_rr_peer_data_t *rrp);
-
-#if (NGX_HTTP_SSL)
-
-static ngx_int_t ngx_http_upstream_empty_set_session(ngx_peer_connection_t *pc,
- void *data);
-static void ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc,
- void *data);
-
-#endif
-
-
-ngx_int_t
-ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
- ngx_http_upstream_srv_conf_t *us)
-{
- ngx_url_t u;
- ngx_uint_t i, j, n, w;
- ngx_http_upstream_server_t *server;
- ngx_http_upstream_rr_peers_t *peers, *backup;
-
- us->peer.init = ngx_http_upstream_init_round_robin_peer;
-
- if (us->servers) {
- server = us->servers->elts;
-
- n = 0;
- w = 0;
-
- for (i = 0; i < us->servers->nelts; i++) {
- if (server[i].backup) {
- continue;
- }
-
- n += server[i].naddrs;
- w += server[i].naddrs * server[i].weight;
- }
-
- if (n == 0) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no servers in upstream \"%V\" in %s:%ui",
- &us->host, us->file_name, us->line);
- return NGX_ERROR;
- }
-
- peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
- + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
- if (peers == NULL) {
- return NGX_ERROR;
- }
-
- peers->single = (n == 1);
- peers->number = n;
- peers->weighted = (w != n);
- peers->total_weight = w;
- peers->name = &us->host;
-
- n = 0;
-
- for (i = 0; i < us->servers->nelts; i++) {
- if (server[i].backup) {
- continue;
- }
-
- for (j = 0; j < server[i].naddrs; j++) {
- peers->peer[n].sockaddr = server[i].addrs[j].sockaddr;
- peers->peer[n].socklen = server[i].addrs[j].socklen;
- peers->peer[n].name = server[i].addrs[j].name;
- peers->peer[n].weight = server[i].weight;
- peers->peer[n].effective_weight = server[i].weight;
- peers->peer[n].current_weight = 0;
- peers->peer[n].max_fails = server[i].max_fails;
- peers->peer[n].fail_timeout = server[i].fail_timeout;
- peers->peer[n].down = server[i].down;
- n++;
- }
- }
-
- us->peer.data = peers;
-
- /* backup servers */
-
- n = 0;
- w = 0;
-
- for (i = 0; i < us->servers->nelts; i++) {
- if (!server[i].backup) {
- continue;
- }
-
- n += server[i].naddrs;
- w += server[i].naddrs * server[i].weight;
- }
-
- if (n == 0) {
- return NGX_OK;
- }
-
- backup = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
- + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
- if (backup == NULL) {
- return NGX_ERROR;
- }
-
- peers->single = 0;
- backup->single = 0;
- backup->number = n;
- backup->weighted = (w != n);
- backup->total_weight = w;
- backup->name = &us->host;
-
- n = 0;
-
- for (i = 0; i < us->servers->nelts; i++) {
- if (!server[i].backup) {
- continue;
- }
-
- for (j = 0; j < server[i].naddrs; j++) {
- backup->peer[n].sockaddr = server[i].addrs[j].sockaddr;
- backup->peer[n].socklen = server[i].addrs[j].socklen;
- backup->peer[n].name = server[i].addrs[j].name;
- backup->peer[n].weight = server[i].weight;
- backup->peer[n].effective_weight = server[i].weight;
- backup->peer[n].current_weight = 0;
- backup->peer[n].max_fails = server[i].max_fails;
- backup->peer[n].fail_timeout = server[i].fail_timeout;
- backup->peer[n].down = server[i].down;
- n++;
- }
- }
-
- peers->next = backup;
-
- return NGX_OK;
- }
-
-
- /* an upstream implicitly defined by proxy_pass, etc. */
-
- if (us->port == 0) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no port in upstream \"%V\" in %s:%ui",
- &us->host, us->file_name, us->line);
- return NGX_ERROR;
- }
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- u.host = us->host;
- u.port = us->port;
-
- if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
- if (u.err) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "%s in upstream \"%V\" in %s:%ui",
- u.err, &us->host, us->file_name, us->line);
- }
-
- return NGX_ERROR;
- }
-
- n = u.naddrs;
-
- peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
- + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
- if (peers == NULL) {
- return NGX_ERROR;
- }
-
- peers->single = (n == 1);
- peers->number = n;
- peers->weighted = 0;
- peers->total_weight = n;
- peers->name = &us->host;
-
- for (i = 0; i < u.naddrs; i++) {
- peers->peer[i].sockaddr = u.addrs[i].sockaddr;
- peers->peer[i].socklen = u.addrs[i].socklen;
- peers->peer[i].name = u.addrs[i].name;
- peers->peer[i].weight = 1;
- peers->peer[i].effective_weight = 1;
- peers->peer[i].current_weight = 0;
- peers->peer[i].max_fails = 1;
- peers->peer[i].fail_timeout = 10;
- }
-
- us->peer.data = peers;
-
- /* implicitly defined upstream has no backup servers */
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,
- ngx_http_upstream_srv_conf_t *us)
-{
- ngx_uint_t n;
- ngx_http_upstream_rr_peer_data_t *rrp;
-
- rrp = r->upstream->peer.data;
-
- if (rrp == NULL) {
- rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t));
- if (rrp == NULL) {
- return NGX_ERROR;
- }
-
- r->upstream->peer.data = rrp;
- }
-
- rrp->peers = us->peer.data;
- rrp->current = 0;
-
- n = rrp->peers->number;
-
- if (rrp->peers->next && rrp->peers->next->number > n) {
- n = rrp->peers->next->number;
- }
-
- if (n <= 8 * sizeof(uintptr_t)) {
- rrp->tried = &rrp->data;
- rrp->data = 0;
-
- } else {
- n = (n + (8 * sizeof(uintptr_t) - 1)) / (8 * sizeof(uintptr_t));
-
- rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t));
- if (rrp->tried == NULL) {
- return NGX_ERROR;
- }
- }
-
- r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer;
- r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer;
- r->upstream->peer.tries = rrp->peers->number;
-#if (NGX_HTTP_SSL)
- r->upstream->peer.set_session =
- ngx_http_upstream_set_round_robin_peer_session;
- r->upstream->peer.save_session =
- ngx_http_upstream_save_round_robin_peer_session;
-#endif
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
- ngx_http_upstream_resolved_t *ur)
-{
- u_char *p;
- size_t len;
- socklen_t socklen;
- ngx_uint_t i, n;
- struct sockaddr *sockaddr;
- ngx_http_upstream_rr_peers_t *peers;
- ngx_http_upstream_rr_peer_data_t *rrp;
-
- rrp = r->upstream->peer.data;
-
- if (rrp == NULL) {
- rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t));
- if (rrp == NULL) {
- return NGX_ERROR;
- }
-
- r->upstream->peer.data = rrp;
- }
-
- peers = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_rr_peers_t)
- + sizeof(ngx_http_upstream_rr_peer_t) * (ur->naddrs - 1));
- if (peers == NULL) {
- return NGX_ERROR;
- }
-
- peers->single = (ur->naddrs == 1);
- peers->number = ur->naddrs;
- peers->name = &ur->host;
-
- if (ur->sockaddr) {
- peers->peer[0].sockaddr = ur->sockaddr;
- peers->peer[0].socklen = ur->socklen;
- peers->peer[0].name = ur->host;
- peers->peer[0].weight = 1;
- peers->peer[0].effective_weight = 1;
- peers->peer[0].current_weight = 0;
- peers->peer[0].max_fails = 1;
- peers->peer[0].fail_timeout = 10;
-
- } else {
-
- for (i = 0; i < ur->naddrs; i++) {
-
- socklen = ur->addrs[i].socklen;
-
- sockaddr = ngx_palloc(r->pool, socklen);
- if (sockaddr == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(sockaddr, ur->addrs[i].sockaddr, socklen);
-
- switch (sockaddr->sa_family) {
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- ((struct sockaddr_in6 *) sockaddr)->sin6_port = htons(ur->port);
- break;
-#endif
- default: /* AF_INET */
- ((struct sockaddr_in *) sockaddr)->sin_port = htons(ur->port);
- }
-
- p = ngx_pnalloc(r->pool, NGX_SOCKADDR_STRLEN);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1);
-
- peers->peer[i].sockaddr = sockaddr;
- peers->peer[i].socklen = socklen;
- peers->peer[i].name.len = len;
- peers->peer[i].name.data = p;
- peers->peer[i].weight = 1;
- peers->peer[i].effective_weight = 1;
- peers->peer[i].current_weight = 0;
- peers->peer[i].max_fails = 1;
- peers->peer[i].fail_timeout = 10;
- }
- }
-
- rrp->peers = peers;
- rrp->current = 0;
-
- if (rrp->peers->number <= 8 * sizeof(uintptr_t)) {
- rrp->tried = &rrp->data;
- rrp->data = 0;
-
- } else {
- n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
- / (8 * sizeof(uintptr_t));
-
- rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t));
- if (rrp->tried == NULL) {
- return NGX_ERROR;
- }
- }
-
- r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer;
- r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer;
- r->upstream->peer.tries = rrp->peers->number;
-#if (NGX_HTTP_SSL)
- r->upstream->peer.set_session = ngx_http_upstream_empty_set_session;
- r->upstream->peer.save_session = ngx_http_upstream_empty_save_session;
-#endif
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
-{
- ngx_http_upstream_rr_peer_data_t *rrp = data;
-
- ngx_int_t rc;
- ngx_uint_t i, n;
- ngx_http_upstream_rr_peer_t *peer;
- ngx_http_upstream_rr_peers_t *peers;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "get rr peer, try: %ui", pc->tries);
-
- /* ngx_lock_mutex(rrp->peers->mutex); */
-
- pc->cached = 0;
- pc->connection = NULL;
-
- if (rrp->peers->single) {
- peer = &rrp->peers->peer[0];
-
- if (peer->down) {
- goto failed;
- }
-
- } else {
-
- /* there are several peers */
-
- peer = ngx_http_upstream_get_peer(rrp);
-
- if (peer == NULL) {
- goto failed;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "get rr peer, current: %ui %i",
- rrp->current, peer->current_weight);
- }
-
- pc->sockaddr = peer->sockaddr;
- pc->socklen = peer->socklen;
- pc->name = &peer->name;
-
- /* ngx_unlock_mutex(rrp->peers->mutex); */
-
- if (pc->tries == 1 && rrp->peers->next) {
- pc->tries += rrp->peers->next->number;
- }
-
- return NGX_OK;
-
-failed:
-
- peers = rrp->peers;
-
- if (peers->next) {
-
- /* ngx_unlock_mutex(peers->mutex); */
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "backup servers");
-
- rrp->peers = peers->next;
- pc->tries = rrp->peers->number;
-
- n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
- / (8 * sizeof(uintptr_t));
-
- for (i = 0; i < n; i++) {
- rrp->tried[i] = 0;
- }
-
- rc = ngx_http_upstream_get_round_robin_peer(pc, rrp);
-
- if (rc != NGX_BUSY) {
- return rc;
- }
-
- /* ngx_lock_mutex(peers->mutex); */
- }
-
- /* all peers failed, mark them as live for quick recovery */
-
- for (i = 0; i < peers->number; i++) {
- peers->peer[i].fails = 0;
- }
-
- /* ngx_unlock_mutex(peers->mutex); */
-
- pc->name = peers->name;
-
- return NGX_BUSY;
-}
-
-
-static ngx_http_upstream_rr_peer_t *
-ngx_http_upstream_get_peer(ngx_http_upstream_rr_peer_data_t *rrp)
-{
- time_t now;
- uintptr_t m;
- ngx_int_t total;
- ngx_uint_t i, n;
- ngx_http_upstream_rr_peer_t *peer, *best;
-
- now = ngx_time();
-
- best = NULL;
- total = 0;
-
- for (i = 0; i < rrp->peers->number; i++) {
-
- n = i / (8 * sizeof(uintptr_t));
- m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
-
- if (rrp->tried[n] & m) {
- continue;
- }
-
- peer = &rrp->peers->peer[i];
-
- if (peer->down) {
- continue;
- }
-
- if (peer->max_fails
- && peer->fails >= peer->max_fails
- && now - peer->checked <= peer->fail_timeout)
- {
- continue;
- }
-
- peer->current_weight += peer->effective_weight;
- total += peer->effective_weight;
-
- if (peer->effective_weight < peer->weight) {
- peer->effective_weight++;
- }
-
- if (best == NULL || peer->current_weight > best->current_weight) {
- best = peer;
- }
- }
-
- if (best == NULL) {
- return NULL;
- }
-
- i = best - &rrp->peers->peer[0];
-
- rrp->current = i;
-
- n = i / (8 * sizeof(uintptr_t));
- m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
-
- rrp->tried[n] |= m;
-
- best->current_weight -= total;
-
- if (now - best->checked > best->fail_timeout) {
- best->checked = now;
- }
-
- return best;
-}
-
-
-void
-ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data,
- ngx_uint_t state)
-{
- ngx_http_upstream_rr_peer_data_t *rrp = data;
-
- time_t now;
- ngx_http_upstream_rr_peer_t *peer;
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "free rr peer %ui %ui", pc->tries, state);
-
- /* TODO: NGX_PEER_KEEPALIVE */
-
- if (rrp->peers->single) {
- pc->tries = 0;
- return;
- }
-
- peer = &rrp->peers->peer[rrp->current];
-
- if (state & NGX_PEER_FAILED) {
- now = ngx_time();
-
- /* ngx_lock_mutex(rrp->peers->mutex); */
-
- peer->fails++;
- peer->accessed = now;
- peer->checked = now;
-
- if (peer->max_fails) {
- peer->effective_weight -= peer->weight / peer->max_fails;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "free rr peer failed: %ui %i",
- rrp->current, peer->effective_weight);
-
- if (peer->effective_weight < 0) {
- peer->effective_weight = 0;
- }
-
- /* ngx_unlock_mutex(rrp->peers->mutex); */
-
- } else {
-
- /* mark peer live if check passed */
-
- if (peer->accessed < peer->checked) {
- peer->fails = 0;
- }
- }
-
- if (pc->tries) {
- pc->tries--;
- }
-
- /* ngx_unlock_mutex(rrp->peers->mutex); */
-}
-
-
-#if (NGX_HTTP_SSL)
-
-ngx_int_t
-ngx_http_upstream_set_round_robin_peer_session(ngx_peer_connection_t *pc,
- void *data)
-{
- ngx_http_upstream_rr_peer_data_t *rrp = data;
-
- ngx_int_t rc;
- ngx_ssl_session_t *ssl_session;
- ngx_http_upstream_rr_peer_t *peer;
-
- peer = &rrp->peers->peer[rrp->current];
-
- /* TODO: threads only mutex */
- /* ngx_lock_mutex(rrp->peers->mutex); */
-
- ssl_session = peer->ssl_session;
-
- rc = ngx_ssl_set_session(pc->connection, ssl_session);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "set session: %p:%d",
- ssl_session, ssl_session ? ssl_session->references : 0);
-
- /* ngx_unlock_mutex(rrp->peers->mutex); */
-
- return rc;
-}
-
-
-void
-ngx_http_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc,
- void *data)
-{
- ngx_http_upstream_rr_peer_data_t *rrp = data;
-
- ngx_ssl_session_t *old_ssl_session, *ssl_session;
- ngx_http_upstream_rr_peer_t *peer;
-
- ssl_session = ngx_ssl_get_session(pc->connection);
-
- if (ssl_session == NULL) {
- return;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "save session: %p:%d", ssl_session, ssl_session->references);
-
- peer = &rrp->peers->peer[rrp->current];
-
- /* TODO: threads only mutex */
- /* ngx_lock_mutex(rrp->peers->mutex); */
-
- old_ssl_session = peer->ssl_session;
- peer->ssl_session = ssl_session;
-
- /* ngx_unlock_mutex(rrp->peers->mutex); */
-
- if (old_ssl_session) {
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
- "old session: %p:%d",
- old_ssl_session, old_ssl_session->references);
-
- /* TODO: may block */
-
- ngx_ssl_free_session(old_ssl_session);
- }
-}
-
-
-static ngx_int_t
-ngx_http_upstream_empty_set_session(ngx_peer_connection_t *pc, void *data)
-{
- return NGX_OK;
-}
-
-
-static void
-ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc, void *data)
-{
- return;
-}
-
-#endif
diff --git a/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.h b/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.h
deleted file mode 100644
index ea90ab9181e..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_upstream_round_robin.h
+++ /dev/null
@@ -1,89 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_
-#define _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- struct sockaddr *sockaddr;
- socklen_t socklen;
- ngx_str_t name;
-
- ngx_int_t current_weight;
- ngx_int_t effective_weight;
- ngx_int_t weight;
-
- ngx_uint_t fails;
- time_t accessed;
- time_t checked;
-
- ngx_uint_t max_fails;
- time_t fail_timeout;
-
- ngx_uint_t down; /* unsigned down:1; */
-
-#if (NGX_HTTP_SSL)
- ngx_ssl_session_t *ssl_session; /* local to a process */
-#endif
-} ngx_http_upstream_rr_peer_t;
-
-
-typedef struct ngx_http_upstream_rr_peers_s ngx_http_upstream_rr_peers_t;
-
-struct ngx_http_upstream_rr_peers_s {
- ngx_uint_t number;
-
- /* ngx_mutex_t *mutex; */
-
- ngx_uint_t total_weight;
-
- unsigned single:1;
- unsigned weighted:1;
-
- ngx_str_t *name;
-
- ngx_http_upstream_rr_peers_t *next;
-
- ngx_http_upstream_rr_peer_t peer[1];
-};
-
-
-typedef struct {
- ngx_http_upstream_rr_peers_t *peers;
- ngx_uint_t current;
- uintptr_t *tried;
- uintptr_t data;
-} ngx_http_upstream_rr_peer_data_t;
-
-
-ngx_int_t ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
- ngx_http_upstream_srv_conf_t *us);
-ngx_int_t ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,
- ngx_http_upstream_srv_conf_t *us);
-ngx_int_t ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
- ngx_http_upstream_resolved_t *ur);
-ngx_int_t ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc,
- void *data);
-void ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc,
- void *data, ngx_uint_t state);
-
-#if (NGX_HTTP_SSL)
-ngx_int_t
- ngx_http_upstream_set_round_robin_peer_session(ngx_peer_connection_t *pc,
- void *data);
-void ngx_http_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc,
- void *data);
-#endif
-
-
-#endif /* _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/ngx_http_variables.c b/usr.sbin/nginx/src/http/ngx_http_variables.c
deleted file mode 100644
index f618622976f..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_variables.c
+++ /dev/null
@@ -1,2576 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-#include <nginx.h>
-
-
-static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static void ngx_http_variable_request_set(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_request_get_size(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static void ngx_http_variable_request_set_size(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-
-static ngx_int_t ngx_http_variable_cookies(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_headers_internal(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data, u_char sep);
-
-static ngx_int_t ngx_http_variable_unknown_header_in(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_unknown_header_out(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_request_line(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_cookie(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_argument(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-#if (NGX_HAVE_TCP_INFO)
-static ngx_int_t ngx_http_variable_tcpinfo(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-#endif
-
-static ngx_int_t ngx_http_variable_content_length(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_host(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_binary_remote_addr(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_remote_addr(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_remote_port(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_server_addr(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_scheme(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_https(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_is_args(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_document_root(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_realpath_root(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_request_filename(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_server_name(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_request_method(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_remote_user(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_bytes_sent(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_pipe(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_request_completion(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_request_body(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_request_body_file(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_request_length(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_request_time(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-
-static ngx_int_t ngx_http_variable_sent_content_type(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_sent_content_length(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_sent_location(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_sent_last_modified(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_sent_connection(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_sent_keep_alive(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_sent_transfer_encoding(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-
-static ngx_int_t ngx_http_variable_connection(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_connection_requests(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-
-static ngx_int_t ngx_http_variable_nginx_version(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_hostname(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_pid(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_msec(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_time_iso8601(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-static ngx_int_t ngx_http_variable_time_local(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-
-/*
- * TODO:
- * Apache CGI: AUTH_TYPE, PATH_INFO (null), PATH_TRANSLATED
- * REMOTE_HOST (null), REMOTE_IDENT (null),
- * SERVER_SOFTWARE
- *
- * Apache SSI: DOCUMENT_NAME, LAST_MODIFIED, USER_NAME (file owner)
- */
-
-/*
- * the $http_host, $http_user_agent, $http_referer, and $http_via
- * variables may be handled by generic
- * ngx_http_variable_unknown_header_in(), but for performance reasons
- * they are handled using dedicated entries
- */
-
-static ngx_http_variable_t ngx_http_core_variables[] = {
-
- { ngx_string("http_host"), NULL, ngx_http_variable_header,
- offsetof(ngx_http_request_t, headers_in.host), 0, 0 },
-
- { ngx_string("http_user_agent"), NULL, ngx_http_variable_header,
- offsetof(ngx_http_request_t, headers_in.user_agent), 0, 0 },
-
- { ngx_string("http_referer"), NULL, ngx_http_variable_header,
- offsetof(ngx_http_request_t, headers_in.referer), 0, 0 },
-
-#if (NGX_HTTP_GZIP)
- { ngx_string("http_via"), NULL, ngx_http_variable_header,
- offsetof(ngx_http_request_t, headers_in.via), 0, 0 },
-#endif
-
-#if (NGX_HTTP_X_FORWARDED_FOR)
- { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_headers,
- offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 },
-#endif
-
- { ngx_string("http_cookie"), NULL, ngx_http_variable_cookies,
- offsetof(ngx_http_request_t, headers_in.cookies), 0, 0 },
-
- { ngx_string("content_length"), NULL, ngx_http_variable_content_length,
- 0, 0, 0 },
-
- { ngx_string("content_type"), NULL, ngx_http_variable_header,
- offsetof(ngx_http_request_t, headers_in.content_type), 0, 0 },
-
- { ngx_string("host"), NULL, ngx_http_variable_host, 0, 0, 0 },
-
- { ngx_string("binary_remote_addr"), NULL,
- ngx_http_variable_binary_remote_addr, 0, 0, 0 },
-
- { ngx_string("remote_addr"), NULL, ngx_http_variable_remote_addr, 0, 0, 0 },
-
- { ngx_string("remote_port"), NULL, ngx_http_variable_remote_port, 0, 0, 0 },
-
- { ngx_string("proxy_protocol_addr"), NULL,
- ngx_http_variable_proxy_protocol_addr, 0, 0, 0 },
-
- { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 },
-
- { ngx_string("server_port"), NULL, ngx_http_variable_server_port, 0, 0, 0 },
-
- { ngx_string("server_protocol"), NULL, ngx_http_variable_request,
- offsetof(ngx_http_request_t, http_protocol), 0, 0 },
-
- { ngx_string("scheme"), NULL, ngx_http_variable_scheme, 0, 0, 0 },
-
- { ngx_string("https"), NULL, ngx_http_variable_https, 0, 0, 0 },
-
- { ngx_string("request_uri"), NULL, ngx_http_variable_request,
- offsetof(ngx_http_request_t, unparsed_uri), 0, 0 },
-
- { ngx_string("uri"), NULL, ngx_http_variable_request,
- offsetof(ngx_http_request_t, uri),
- NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("document_uri"), NULL, ngx_http_variable_request,
- offsetof(ngx_http_request_t, uri),
- NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("request"), NULL, ngx_http_variable_request_line, 0, 0, 0 },
-
- { ngx_string("document_root"), NULL,
- ngx_http_variable_document_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("realpath_root"), NULL,
- ngx_http_variable_realpath_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("query_string"), NULL, ngx_http_variable_request,
- offsetof(ngx_http_request_t, args),
- NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("args"),
- ngx_http_variable_request_set,
- ngx_http_variable_request,
- offsetof(ngx_http_request_t, args),
- NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("is_args"), NULL, ngx_http_variable_is_args,
- 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("request_filename"), NULL,
- ngx_http_variable_request_filename, 0,
- NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("server_name"), NULL, ngx_http_variable_server_name, 0, 0, 0 },
-
- { ngx_string("request_method"), NULL,
- ngx_http_variable_request_method, 0,
- NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 },
-
- { ngx_string("bytes_sent"), NULL, ngx_http_variable_bytes_sent,
- 0, 0, 0 },
-
- { ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent,
- 0, 0, 0 },
-
- { ngx_string("pipe"), NULL, ngx_http_variable_pipe,
- 0, 0, 0 },
-
- { ngx_string("request_completion"), NULL,
- ngx_http_variable_request_completion,
- 0, 0, 0 },
-
- { ngx_string("request_body"), NULL,
- ngx_http_variable_request_body,
- 0, 0, 0 },
-
- { ngx_string("request_body_file"), NULL,
- ngx_http_variable_request_body_file,
- 0, 0, 0 },
-
- { ngx_string("request_length"), NULL, ngx_http_variable_request_length,
- 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("request_time"), NULL, ngx_http_variable_request_time,
- 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("status"), NULL,
- ngx_http_variable_status, 0,
- NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("sent_http_content_type"), NULL,
- ngx_http_variable_sent_content_type, 0, 0, 0 },
-
- { ngx_string("sent_http_content_length"), NULL,
- ngx_http_variable_sent_content_length, 0, 0, 0 },
-
- { ngx_string("sent_http_location"), NULL,
- ngx_http_variable_sent_location, 0, 0, 0 },
-
- { ngx_string("sent_http_last_modified"), NULL,
- ngx_http_variable_sent_last_modified, 0, 0, 0 },
-
- { ngx_string("sent_http_connection"), NULL,
- ngx_http_variable_sent_connection, 0, 0, 0 },
-
- { ngx_string("sent_http_keep_alive"), NULL,
- ngx_http_variable_sent_keep_alive, 0, 0, 0 },
-
- { ngx_string("sent_http_transfer_encoding"), NULL,
- ngx_http_variable_sent_transfer_encoding, 0, 0, 0 },
-
- { ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_headers,
- offsetof(ngx_http_request_t, headers_out.cache_control), 0, 0 },
-
- { ngx_string("limit_rate"), ngx_http_variable_request_set_size,
- ngx_http_variable_request_get_size,
- offsetof(ngx_http_request_t, limit_rate),
- NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("connection"), NULL,
- ngx_http_variable_connection, 0, 0, 0 },
-
- { ngx_string("connection_requests"), NULL,
- ngx_http_variable_connection_requests, 0, 0, 0 },
-
- { ngx_string("nginx_version"), NULL, ngx_http_variable_nginx_version,
- 0, 0, 0 },
-
- { ngx_string("hostname"), NULL, ngx_http_variable_hostname,
- 0, 0, 0 },
-
- { ngx_string("pid"), NULL, ngx_http_variable_pid,
- 0, 0, 0 },
-
- { ngx_string("msec"), NULL, ngx_http_variable_msec,
- 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("time_iso8601"), NULL, ngx_http_variable_time_iso8601,
- 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("time_local"), NULL, ngx_http_variable_time_local,
- 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
-#if (NGX_HAVE_TCP_INFO)
- { ngx_string("tcpinfo_rtt"), NULL, ngx_http_variable_tcpinfo,
- 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("tcpinfo_rttvar"), NULL, ngx_http_variable_tcpinfo,
- 1, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("tcpinfo_snd_cwnd"), NULL, ngx_http_variable_tcpinfo,
- 2, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-
- { ngx_string("tcpinfo_rcv_space"), NULL, ngx_http_variable_tcpinfo,
- 3, NGX_HTTP_VAR_NOCACHEABLE, 0 },
-#endif
-
- { ngx_null_string, NULL, NULL, 0, 0, 0 }
-};
-
-
-ngx_http_variable_value_t ngx_http_variable_null_value =
- ngx_http_variable("");
-ngx_http_variable_value_t ngx_http_variable_true_value =
- ngx_http_variable("1");
-
-
-ngx_http_variable_t *
-ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
-{
- ngx_int_t rc;
- ngx_uint_t i;
- ngx_hash_key_t *key;
- ngx_http_variable_t *v;
- ngx_http_core_main_conf_t *cmcf;
-
- if (name->len == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid variable name \"$\"");
- return NULL;
- }
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- key = cmcf->variables_keys->keys.elts;
- for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) {
- if (name->len != key[i].key.len
- || ngx_strncasecmp(name->data, key[i].key.data, name->len) != 0)
- {
- continue;
- }
-
- v = key[i].value;
-
- if (!(v->flags & NGX_HTTP_VAR_CHANGEABLE)) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the duplicate \"%V\" variable", name);
- return NULL;
- }
-
- return v;
- }
-
- v = ngx_palloc(cf->pool, sizeof(ngx_http_variable_t));
- if (v == NULL) {
- return NULL;
- }
-
- v->name.len = name->len;
- v->name.data = ngx_pnalloc(cf->pool, name->len);
- if (v->name.data == NULL) {
- return NULL;
- }
-
- ngx_strlow(v->name.data, name->data, name->len);
-
- v->set_handler = NULL;
- v->get_handler = NULL;
- v->data = 0;
- v->flags = flags;
- v->index = 0;
-
- rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, 0);
-
- if (rc == NGX_ERROR) {
- return NULL;
- }
-
- if (rc == NGX_BUSY) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "conflicting variable name \"%V\"", name);
- return NULL;
- }
-
- return v;
-}
-
-
-ngx_int_t
-ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name)
-{
- ngx_uint_t i;
- ngx_http_variable_t *v;
- ngx_http_core_main_conf_t *cmcf;
-
- if (name->len == 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid variable name \"$\"");
- return NGX_ERROR;
- }
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- v = cmcf->variables.elts;
-
- if (v == NULL) {
- if (ngx_array_init(&cmcf->variables, cf->pool, 4,
- sizeof(ngx_http_variable_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- } else {
- for (i = 0; i < cmcf->variables.nelts; i++) {
- if (name->len != v[i].name.len
- || ngx_strncasecmp(name->data, v[i].name.data, name->len) != 0)
- {
- continue;
- }
-
- return i;
- }
- }
-
- v = ngx_array_push(&cmcf->variables);
- if (v == NULL) {
- return NGX_ERROR;
- }
-
- v->name.len = name->len;
- v->name.data = ngx_pnalloc(cf->pool, name->len);
- if (v->name.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_strlow(v->name.data, name->data, name->len);
-
- v->set_handler = NULL;
- v->get_handler = NULL;
- v->data = 0;
- v->flags = 0;
- v->index = cmcf->variables.nelts - 1;
-
- return v->index;
-}
-
-
-ngx_http_variable_value_t *
-ngx_http_get_indexed_variable(ngx_http_request_t *r, ngx_uint_t index)
-{
- ngx_http_variable_t *v;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
- if (cmcf->variables.nelts <= index) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "unknown variable index: %ui", index);
- return NULL;
- }
-
- if (r->variables[index].not_found || r->variables[index].valid) {
- return &r->variables[index];
- }
-
- v = cmcf->variables.elts;
-
- if (v[index].get_handler(r, &r->variables[index], v[index].data)
- == NGX_OK)
- {
- if (v[index].flags & NGX_HTTP_VAR_NOCACHEABLE) {
- r->variables[index].no_cacheable = 1;
- }
-
- return &r->variables[index];
- }
-
- r->variables[index].valid = 0;
- r->variables[index].not_found = 1;
-
- return NULL;
-}
-
-
-ngx_http_variable_value_t *
-ngx_http_get_flushed_variable(ngx_http_request_t *r, ngx_uint_t index)
-{
- ngx_http_variable_value_t *v;
-
- v = &r->variables[index];
-
- if (v->valid || v->not_found) {
- if (!v->no_cacheable) {
- return v;
- }
-
- v->valid = 0;
- v->not_found = 0;
- }
-
- return ngx_http_get_indexed_variable(r, index);
-}
-
-
-ngx_http_variable_value_t *
-ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key)
-{
- ngx_http_variable_t *v;
- ngx_http_variable_value_t *vv;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
- v = ngx_hash_find(&cmcf->variables_hash, key, name->data, name->len);
-
- if (v) {
- if (v->flags & NGX_HTTP_VAR_INDEXED) {
- return ngx_http_get_flushed_variable(r, v->index);
-
- } else {
-
- vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
-
- if (vv && v->get_handler(r, vv, v->data) == NGX_OK) {
- return vv;
- }
-
- return NULL;
- }
- }
-
- vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
- if (vv == NULL) {
- return NULL;
- }
-
- if (ngx_strncmp(name->data, "http_", 5) == 0) {
-
- if (ngx_http_variable_unknown_header_in(r, vv, (uintptr_t) name)
- == NGX_OK)
- {
- return vv;
- }
-
- return NULL;
- }
-
- if (ngx_strncmp(name->data, "sent_http_", 10) == 0) {
-
- if (ngx_http_variable_unknown_header_out(r, vv, (uintptr_t) name)
- == NGX_OK)
- {
- return vv;
- }
-
- return NULL;
- }
-
- if (ngx_strncmp(name->data, "upstream_http_", 14) == 0) {
-
- if (ngx_http_upstream_header_variable(r, vv, (uintptr_t) name)
- == NGX_OK)
- {
- return vv;
- }
-
- return NULL;
- }
-
- if (ngx_strncmp(name->data, "cookie_", 7) == 0) {
-
- if (ngx_http_variable_cookie(r, vv, (uintptr_t) name) == NGX_OK) {
- return vv;
- }
-
- return NULL;
- }
-
- if (ngx_strncmp(name->data, "arg_", 4) == 0) {
-
- if (ngx_http_variable_argument(r, vv, (uintptr_t) name) == NGX_OK) {
- return vv;
- }
-
- return NULL;
- }
-
- vv->not_found = 1;
-
- return vv;
-}
-
-
-static ngx_int_t
-ngx_http_variable_request(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- ngx_str_t *s;
-
- s = (ngx_str_t *) ((char *) r + data);
-
- if (s->data) {
- v->len = s->len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = s->data;
-
- } else {
- v->not_found = 1;
- }
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_variable_request_set(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_str_t *s;
-
- s = (ngx_str_t *) ((char *) r + data);
-
- s->len = v->len;
- s->data = v->data;
-}
-
-
-static ngx_int_t
-ngx_http_variable_request_get_size(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- size_t *sp;
-
- sp = (size_t *) ((char *) r + data);
-
- v->data = ngx_pnalloc(r->pool, NGX_SIZE_T_LEN);
- if (v->data == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_sprintf(v->data, "%uz", *sp) - v->data;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_http_variable_request_set_size(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ssize_t s, *sp;
- ngx_str_t val;
-
- val.len = v->len;
- val.data = v->data;
-
- s = ngx_parse_size(&val);
-
- if (s == NGX_ERROR) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "invalid size \"%V\"", &val);
- return;
- }
-
- sp = (ssize_t *) ((char *) r + data);
-
- *sp = s;
-
- return;
-}
-
-
-static ngx_int_t
-ngx_http_variable_header(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- ngx_table_elt_t *h;
-
- h = *(ngx_table_elt_t **) ((char *) r + data);
-
- if (h) {
- v->len = h->value.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = h->value.data;
-
- } else {
- v->not_found = 1;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_cookies(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- return ngx_http_variable_headers_internal(r, v, data, ';');
-}
-
-
-static ngx_int_t
-ngx_http_variable_headers(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- return ngx_http_variable_headers_internal(r, v, data, ',');
-}
-
-
-static ngx_int_t
-ngx_http_variable_headers_internal(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data, u_char sep)
-{
- size_t len;
- u_char *p, *end;
- ngx_uint_t i, n;
- ngx_array_t *a;
- ngx_table_elt_t **h;
-
- a = (ngx_array_t *) ((char *) r + data);
-
- n = a->nelts;
- h = a->elts;
-
- len = 0;
-
- for (i = 0; i < n; i++) {
-
- if (h[i]->hash == 0) {
- continue;
- }
-
- len += h[i]->value.len + 2;
- }
-
- if (len == 0) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- len -= 2;
-
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- if (n == 1) {
- v->len = (*h)->value.len;
- v->data = (*h)->value.data;
-
- return NGX_OK;
- }
-
- p = ngx_pnalloc(r->pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->len = len;
- v->data = p;
-
- end = p + len;
-
- for (i = 0; /* void */ ; i++) {
-
- if (h[i]->hash == 0) {
- continue;
- }
-
- p = ngx_copy(p, h[i]->value.data, h[i]->value.len);
-
- if (p == end) {
- break;
- }
-
- *p++ = sep; *p++ = ' ';
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_unknown_header_in(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
- &r->headers_in.headers.part,
- sizeof("http_") - 1);
-}
-
-
-static ngx_int_t
-ngx_http_variable_unknown_header_out(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
- &r->headers_out.headers.part,
- sizeof("sent_http_") - 1);
-}
-
-
-ngx_int_t
-ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, ngx_str_t *var,
- ngx_list_part_t *part, size_t prefix)
-{
- u_char ch;
- ngx_uint_t i, n;
- ngx_table_elt_t *header;
-
- header = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
-
- part = part->next;
- header = part->elts;
- i = 0;
- }
-
- if (header[i].hash == 0) {
- continue;
- }
-
- for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) {
- ch = header[i].key.data[n];
-
- if (ch >= 'A' && ch <= 'Z') {
- ch |= 0x20;
-
- } else if (ch == '-') {
- ch = '_';
- }
-
- if (var->data[n + prefix] != ch) {
- break;
- }
- }
-
- if (n + prefix == var->len && n == header[i].key.len) {
- v->len = header[i].value.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = header[i].value.data;
-
- return NGX_OK;
- }
- }
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_request_line(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p, *s;
-
- s = r->request_line.data;
-
- if (s == NULL) {
- s = r->request_start;
-
- if (s == NULL) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- for (p = s; p < r->header_in->last; p++) {
- if (*p == CR || *p == LF) {
- break;
- }
- }
-
- r->request_line.len = p - s;
- r->request_line.data = s;
- }
-
- v->len = r->request_line.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = s;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_cookie(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- ngx_str_t *name = (ngx_str_t *) data;
-
- ngx_str_t cookie, s;
-
- s.len = name->len - (sizeof("cookie_") - 1);
- s.data = name->data + sizeof("cookie_") - 1;
-
- if (ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &s, &cookie)
- == NGX_DECLINED)
- {
- v->not_found = 1;
- return NGX_OK;
- }
-
- v->len = cookie.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = cookie.data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_argument(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- ngx_str_t *name = (ngx_str_t *) data;
-
- u_char *arg;
- size_t len;
- ngx_str_t value;
-
- len = name->len - (sizeof("arg_") - 1);
- arg = name->data + sizeof("arg_") - 1;
-
- if (ngx_http_arg(r, arg, len, &value) != NGX_OK) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- v->data = value.data;
- v->len = value.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- return NGX_OK;
-}
-
-
-#if (NGX_HAVE_TCP_INFO)
-
-static ngx_int_t
-ngx_http_variable_tcpinfo(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- struct tcp_info ti;
- socklen_t len;
- uint32_t value;
-
- len = sizeof(struct tcp_info);
- if (getsockopt(r->connection->fd, IPPROTO_TCP, TCP_INFO, &ti, &len) == -1) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- v->data = ngx_pnalloc(r->pool, NGX_INT32_LEN);
- if (v->data == NULL) {
- return NGX_ERROR;
- }
-
- switch (data) {
- case 0:
- value = ti.tcpi_rtt;
- break;
-
- case 1:
- value = ti.tcpi_rttvar;
- break;
-
- case 2:
- value = ti.tcpi_snd_cwnd;
- break;
-
- case 3:
- value = ti.tcpi_rcv_space;
- break;
-
- /* suppress warning */
- default:
- value = 0;
- break;
- }
-
- v->len = ngx_sprintf(v->data, "%uD", value) - v->data;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- return NGX_OK;
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_http_variable_content_length(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
-
- if (r->headers_in.content_length) {
- v->len = r->headers_in.content_length->value.len;
- v->data = r->headers_in.content_length->value.data;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- } else if (r->headers_in.content_length_n >= 0) {
- p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_sprintf(p, "%O", r->headers_in.content_length_n) - p;
- v->data = p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- } else {
- v->not_found = 1;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_host(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- ngx_http_core_srv_conf_t *cscf;
-
- if (r->headers_in.server.len) {
- v->len = r->headers_in.server.len;
- v->data = r->headers_in.server.data;
-
- } else {
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
- v->len = cscf->server_name.len;
- v->data = cscf->server_name.data;
- }
-
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_binary_remote_addr(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
-
- switch (r->connection->sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
-
- v->len = sizeof(struct in6_addr);
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = sin6->sin6_addr.s6_addr;
-
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) r->connection->sockaddr;
-
- v->len = sizeof(in_addr_t);
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = (u_char *) &sin->sin_addr;
-
- break;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_remote_addr(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- v->len = r->connection->addr_text.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = r->connection->addr_text.data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_remote_port(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_uint_t port;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
-
- v->len = 0;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1);
- if (v->data == NULL) {
- return NGX_ERROR;
- }
-
- switch (r->connection->sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
- port = ntohs(sin6->sin6_port);
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- port = 0;
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) r->connection->sockaddr;
- port = ntohs(sin->sin_port);
- break;
- }
-
- if (port > 0 && port < 65536) {
- v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_proxy_protocol_addr(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- v->len = r->connection->proxy_protocol_addr.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = r->connection->proxy_protocol_addr.data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_server_addr(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_str_t s;
- u_char addr[NGX_SOCKADDR_STRLEN];
-
- s.len = NGX_SOCKADDR_STRLEN;
- s.data = addr;
-
- if (ngx_connection_local_sockaddr(r->connection, &s, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- s.data = ngx_pnalloc(r->pool, s.len);
- if (s.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(s.data, addr, s.len);
-
- v->len = s.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = s.data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_server_port(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_uint_t port;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
-
- v->len = 0;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- if (ngx_connection_local_sockaddr(r->connection, NULL, 0) != NGX_OK) {
- return NGX_ERROR;
- }
-
- v->data = ngx_pnalloc(r->pool, sizeof("65535") - 1);
- if (v->data == NULL) {
- return NGX_ERROR;
- }
-
- switch (r->connection->local_sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) r->connection->local_sockaddr;
- port = ntohs(sin6->sin6_port);
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- port = 0;
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) r->connection->local_sockaddr;
- port = ntohs(sin->sin_port);
- break;
- }
-
- if (port > 0 && port < 65536) {
- v->len = ngx_sprintf(v->data, "%ui", port) - v->data;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_scheme(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
-#if (NGX_HTTP_SSL)
-
- if (r->connection->ssl) {
- v->len = sizeof("https") - 1;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = (u_char *) "https";
-
- return NGX_OK;
- }
-
-#endif
-
- v->len = sizeof("http") - 1;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = (u_char *) "http";
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_https(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
-#if (NGX_HTTP_SSL)
-
- if (r->connection->ssl) {
- v->len = sizeof("on") - 1;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = (u_char *) "on";
-
- return NGX_OK;
- }
-
-#endif
-
- *v = ngx_http_variable_null_value;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_is_args(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- if (r->args.len == 0) {
- v->len = 0;
- v->data = NULL;
- return NGX_OK;
- }
-
- v->len = 1;
- v->data = (u_char *) "?";
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_document_root(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_str_t path;
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->root_lengths == NULL) {
- v->len = clcf->root.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = clcf->root.data;
-
- } else {
- if (ngx_http_script_run(r, &path, clcf->root_lengths->elts, 0,
- clcf->root_values->elts)
- == NULL)
- {
- return NGX_ERROR;
- }
-
- if (ngx_get_full_name(r->pool, (ngx_str_t *) &ngx_cycle->prefix, &path)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- v->len = path.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = path.data;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_realpath_root(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *real;
- size_t len;
- ngx_str_t path;
- ngx_http_core_loc_conf_t *clcf;
-#if (NGX_HAVE_MAX_PATH)
- u_char buffer[NGX_MAX_PATH];
-#endif
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->root_lengths == NULL) {
- path = clcf->root;
-
- } else {
- if (ngx_http_script_run(r, &path, clcf->root_lengths->elts, 1,
- clcf->root_values->elts)
- == NULL)
- {
- return NGX_ERROR;
- }
-
- path.data[path.len - 1] = '\0';
-
- if (ngx_get_full_name(r->pool, (ngx_str_t *) &ngx_cycle->prefix, &path)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
- }
-
-#if (NGX_HAVE_MAX_PATH)
- real = buffer;
-#else
- real = NULL;
-#endif
-
- real = ngx_realpath(path.data, real);
-
- if (real == NULL) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
- ngx_realpath_n " \"%s\" failed", path.data);
- return NGX_ERROR;
- }
-
- len = ngx_strlen(real);
-
- v->data = ngx_pnalloc(r->pool, len);
- if (v->data == NULL) {
-#if !(NGX_HAVE_MAX_PATH)
- ngx_free(real);
-#endif
- return NGX_ERROR;
- }
-
- v->len = len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- ngx_memcpy(v->data, real, len);
-
-#if !(NGX_HAVE_MAX_PATH)
- ngx_free(real);
-#endif
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_request_filename(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- size_t root;
- ngx_str_t path;
-
- if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) {
- return NGX_ERROR;
- }
-
- /* ngx_http_map_uri_to_path() allocates memory for terminating '\0' */
-
- v->len = path.len - 1;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = path.data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_server_name(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_http_core_srv_conf_t *cscf;
-
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
-
- v->len = cscf->server_name.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = cscf->server_name.data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_request_method(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- if (r->main->method_name.data) {
- v->len = r->main->method_name.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = r->main->method_name.data;
-
- } else {
- v->not_found = 1;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_remote_user(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_int_t rc;
-
- rc = ngx_http_auth_basic_user(r);
-
- if (rc == NGX_DECLINED) {
- v->not_found = 1;
- return NGX_OK;
- }
-
- if (rc == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- v->len = r->headers_in.user.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = r->headers_in.user.data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_bytes_sent(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
-
- p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_sprintf(p, "%O", r->connection->sent) - p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_body_bytes_sent(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- off_t sent;
- u_char *p;
-
- sent = r->connection->sent - r->header_size;
-
- if (sent < 0) {
- sent = 0;
- }
-
- p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_sprintf(p, "%O", sent) - p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_pipe(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- v->data = (u_char *) (r->pipeline ? "p" : ".");
- v->len = 1;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_status(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_uint_t status;
-
- v->data = ngx_pnalloc(r->pool, NGX_INT_T_LEN);
- if (v->data == NULL) {
- return NGX_ERROR;
- }
-
- if (r->err_status) {
- status = r->err_status;
-
- } else if (r->headers_out.status) {
- status = r->headers_out.status;
-
- } else if (r->http_version == NGX_HTTP_VERSION_9) {
- status = 9;
-
- } else {
- status = 0;
- }
-
- v->len = ngx_sprintf(v->data, "%03ui", status) - v->data;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_sent_content_type(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- if (r->headers_out.content_type.len) {
- v->len = r->headers_out.content_type.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = r->headers_out.content_type.data;
-
- } else {
- v->not_found = 1;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_sent_content_length(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
-
- if (r->headers_out.content_length) {
- v->len = r->headers_out.content_length->value.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = r->headers_out.content_length->value.data;
-
- return NGX_OK;
- }
-
- if (r->headers_out.content_length_n >= 0) {
- p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_sprintf(p, "%O", r->headers_out.content_length_n) - p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
- }
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_sent_location(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_str_t name;
-
- if (r->headers_out.location) {
- v->len = r->headers_out.location->value.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = r->headers_out.location->value.data;
-
- return NGX_OK;
- }
-
- ngx_str_set(&name, "sent_http_location");
-
- return ngx_http_variable_unknown_header(v, &name,
- &r->headers_out.headers.part,
- sizeof("sent_http_") - 1);
-}
-
-
-static ngx_int_t
-ngx_http_variable_sent_last_modified(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
-
- if (r->headers_out.last_modified) {
- v->len = r->headers_out.last_modified->value.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = r->headers_out.last_modified->value.data;
-
- return NGX_OK;
- }
-
- if (r->headers_out.last_modified_time >= 0) {
- p = ngx_pnalloc(r->pool, sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_http_time(p, r->headers_out.last_modified_time) - p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
- }
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_sent_connection(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- size_t len;
- char *p;
-
- if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {
- len = sizeof("upgrade") - 1;
- p = "upgrade";
-
- } else if (r->keepalive) {
- len = sizeof("keep-alive") - 1;
- p = "keep-alive";
-
- } else {
- len = sizeof("close") - 1;
- p = "close";
- }
-
- v->len = len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = (u_char *) p;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_sent_keep_alive(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
- ngx_http_core_loc_conf_t *clcf;
-
- if (r->keepalive) {
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->keepalive_header) {
-
- p = ngx_pnalloc(r->pool, sizeof("timeout=") - 1 + NGX_TIME_T_LEN);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_sprintf(p, "timeout=%T", clcf->keepalive_header) - p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
- }
- }
-
- v->not_found = 1;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_sent_transfer_encoding(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- if (r->chunked) {
- v->len = sizeof("chunked") - 1;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = (u_char *) "chunked";
-
- } else {
- v->not_found = 1;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_request_completion(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- if (r->request_complete) {
- v->len = 2;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = (u_char *) "OK";
-
- return NGX_OK;
- }
-
- v->len = 0;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = (u_char *) "";
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_request_body(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
- size_t len;
- ngx_buf_t *buf;
- ngx_chain_t *cl;
-
- if (r->request_body == NULL
- || r->request_body->bufs == NULL
- || r->request_body->temp_file)
- {
- v->not_found = 1;
-
- return NGX_OK;
- }
-
- cl = r->request_body->bufs;
- buf = cl->buf;
-
- if (cl->next == NULL) {
- v->len = buf->last - buf->pos;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = buf->pos;
-
- return NGX_OK;
- }
-
- len = buf->last - buf->pos;
- cl = cl->next;
-
- for ( /* void */ ; cl; cl = cl->next) {
- buf = cl->buf;
- len += buf->last - buf->pos;
- }
-
- p = ngx_pnalloc(r->pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->data = p;
- cl = r->request_body->bufs;
-
- for ( /* void */ ; cl; cl = cl->next) {
- buf = cl->buf;
- p = ngx_cpymem(p, buf->pos, buf->last - buf->pos);
- }
-
- v->len = len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_request_body_file(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- if (r->request_body == NULL || r->request_body->temp_file == NULL) {
- v->not_found = 1;
-
- return NGX_OK;
- }
-
- v->len = r->request_body->temp_file->file.name.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = r->request_body->temp_file->file.name.data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_request_length(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
-
- p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_sprintf(p, "%O", r->request_length) - p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_request_time(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
- ngx_time_t *tp;
- ngx_msec_int_t ms;
-
- p = ngx_pnalloc(r->pool, NGX_TIME_T_LEN + 4);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- tp = ngx_timeofday();
-
- ms = (ngx_msec_int_t)
- ((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec));
- ms = ngx_max(ms, 0);
-
- v->len = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000) - p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_connection(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
-
- p = ngx_pnalloc(r->pool, NGX_ATOMIC_T_LEN);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_sprintf(p, "%uA", r->connection->number) - p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_connection_requests(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
-
- p = ngx_pnalloc(r->pool, NGX_INT_T_LEN);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_sprintf(p, "%ui", r->connection->requests) - p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_nginx_version(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- v->len = sizeof(NGINX_VERSION) - 1;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = (u_char *) NGINX_VERSION;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_hostname(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- v->len = ngx_cycle->hostname.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = ngx_cycle->hostname.data;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_pid(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
-
- p = ngx_pnalloc(r->pool, NGX_INT64_LEN);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- v->len = ngx_sprintf(p, "%P", ngx_pid) - p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_msec(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
- ngx_time_t *tp;
-
- p = ngx_pnalloc(r->pool, NGX_TIME_T_LEN + 4);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- tp = ngx_timeofday();
-
- v->len = ngx_sprintf(p, "%T.%03M", tp->sec, tp->msec) - p;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_time_iso8601(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
-
- p = ngx_pnalloc(r->pool, ngx_cached_http_log_iso8601.len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(p, ngx_cached_http_log_iso8601.data,
- ngx_cached_http_log_iso8601.len);
-
- v->len = ngx_cached_http_log_iso8601.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_variable_time_local(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- u_char *p;
-
- p = ngx_pnalloc(r->pool, ngx_cached_http_log_time.len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(p, ngx_cached_http_log_time.data, ngx_cached_http_log_time.len);
-
- v->len = ngx_cached_http_log_time.len;
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
- v->data = p;
-
- return NGX_OK;
-}
-
-
-void *
-ngx_http_map_find(ngx_http_request_t *r, ngx_http_map_t *map, ngx_str_t *match)
-{
- void *value;
- u_char *low;
- size_t len;
- ngx_uint_t key;
-
- len = match->len;
-
- if (len) {
- low = ngx_pnalloc(r->pool, len);
- if (low == NULL) {
- return NULL;
- }
-
- } else {
- low = NULL;
- }
-
- key = ngx_hash_strlow(low, match->data, len);
-
- value = ngx_hash_find_combined(&map->hash, key, low, len);
- if (value) {
- return value;
- }
-
-#if (NGX_PCRE)
-
- if (len && map->nregex) {
- ngx_int_t n;
- ngx_uint_t i;
- ngx_http_map_regex_t *reg;
-
- reg = map->regex;
-
- for (i = 0; i < map->nregex; i++) {
-
- n = ngx_http_regex_exec(r, reg[i].regex, match);
-
- if (n == NGX_OK) {
- return reg[i].value;
- }
-
- if (n == NGX_DECLINED) {
- continue;
- }
-
- /* NGX_ERROR */
-
- return NULL;
- }
- }
-
-#endif
-
- return NULL;
-}
-
-
-#if (NGX_PCRE)
-
-static ngx_int_t
-ngx_http_variable_not_found(ngx_http_request_t *r, ngx_http_variable_value_t *v,
- uintptr_t data)
-{
- v->not_found = 1;
- return NGX_OK;
-}
-
-
-ngx_http_regex_t *
-ngx_http_regex_compile(ngx_conf_t *cf, ngx_regex_compile_t *rc)
-{
- u_char *p;
- size_t size;
- ngx_str_t name;
- ngx_uint_t i, n;
- ngx_http_variable_t *v;
- ngx_http_regex_t *re;
- ngx_http_regex_variable_t *rv;
- ngx_http_core_main_conf_t *cmcf;
-
- rc->pool = cf->pool;
-
- if (ngx_regex_compile(rc) != NGX_OK) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc->err);
- return NULL;
- }
-
- re = ngx_pcalloc(cf->pool, sizeof(ngx_http_regex_t));
- if (re == NULL) {
- return NULL;
- }
-
- re->regex = rc->regex;
- re->ncaptures = rc->captures;
- re->name = rc->pattern;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
- cmcf->ncaptures = ngx_max(cmcf->ncaptures, re->ncaptures);
-
- n = (ngx_uint_t) rc->named_captures;
-
- if (n == 0) {
- return re;
- }
-
- rv = ngx_palloc(rc->pool, n * sizeof(ngx_http_regex_variable_t));
- if (rv == NULL) {
- return NULL;
- }
-
- re->variables = rv;
- re->nvariables = n;
-
- size = rc->name_size;
- p = rc->names;
-
- for (i = 0; i < n; i++) {
- rv[i].capture = 2 * ((p[0] << 8) + p[1]);
-
- name.data = &p[2];
- name.len = ngx_strlen(name.data);
-
- v = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
- if (v == NULL) {
- return NULL;
- }
-
- rv[i].index = ngx_http_get_variable_index(cf, &name);
- if (rv[i].index == NGX_ERROR) {
- return NULL;
- }
-
- v->get_handler = ngx_http_variable_not_found;
-
- p += size;
- }
-
- return re;
-}
-
-
-ngx_int_t
-ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re, ngx_str_t *s)
-{
- ngx_int_t rc, index;
- ngx_uint_t i, n, len;
- ngx_http_variable_value_t *vv;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
-
- if (re->ncaptures) {
- len = cmcf->ncaptures;
-
- if (r->captures == NULL) {
- r->captures = ngx_palloc(r->pool, len * sizeof(int));
- if (r->captures == NULL) {
- return NGX_ERROR;
- }
- }
-
- } else {
- len = 0;
- }
-
- rc = ngx_regex_exec(re->regex, s, r->captures, len);
-
- if (rc == NGX_REGEX_NO_MATCHED) {
- return NGX_DECLINED;
- }
-
- if (rc < 0) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
- rc, s, &re->name);
- return NGX_ERROR;
- }
-
- for (i = 0; i < re->nvariables; i++) {
-
- n = re->variables[i].capture;
- index = re->variables[i].index;
- vv = &r->variables[index];
-
- vv->len = r->captures[n + 1] - r->captures[n];
- vv->valid = 1;
- vv->no_cacheable = 0;
- vv->not_found = 0;
- vv->data = &s->data[r->captures[n]];
-
-#if (NGX_DEBUG)
- {
- ngx_http_variable_t *v;
-
- v = cmcf->variables.elts;
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "http regex set $%V to \"%*s\"",
- &v[index].name, vv->len, vv->data);
- }
-#endif
- }
-
- r->ncaptures = rc * 2;
- r->captures_data = s->data;
-
- return NGX_OK;
-}
-
-#endif
-
-
-ngx_int_t
-ngx_http_variables_add_core_vars(ngx_conf_t *cf)
-{
- ngx_int_t rc;
- ngx_http_variable_t *cv, *v;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- cmcf->variables_keys = ngx_pcalloc(cf->temp_pool,
- sizeof(ngx_hash_keys_arrays_t));
- if (cmcf->variables_keys == NULL) {
- return NGX_ERROR;
- }
-
- cmcf->variables_keys->pool = cf->pool;
- cmcf->variables_keys->temp_pool = cf->pool;
-
- if (ngx_hash_keys_array_init(cmcf->variables_keys, NGX_HASH_SMALL)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- for (cv = ngx_http_core_variables; cv->name.len; cv++) {
- v = ngx_palloc(cf->pool, sizeof(ngx_http_variable_t));
- if (v == NULL) {
- return NGX_ERROR;
- }
-
- *v = *cv;
-
- rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v,
- NGX_HASH_READONLY_KEY);
-
- if (rc == NGX_OK) {
- continue;
- }
-
- if (rc == NGX_BUSY) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "conflicting variable name \"%V\"", &v->name);
- }
-
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_http_variables_init_vars(ngx_conf_t *cf)
-{
- ngx_uint_t i, n;
- ngx_hash_key_t *key;
- ngx_hash_init_t hash;
- ngx_http_variable_t *v, *av;
- ngx_http_core_main_conf_t *cmcf;
-
- /* set the handlers for the indexed http variables */
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- v = cmcf->variables.elts;
- key = cmcf->variables_keys->keys.elts;
-
- for (i = 0; i < cmcf->variables.nelts; i++) {
-
- for (n = 0; n < cmcf->variables_keys->keys.nelts; n++) {
-
- av = key[n].value;
-
- if (av->get_handler
- && v[i].name.len == key[n].key.len
- && ngx_strncmp(v[i].name.data, key[n].key.data, v[i].name.len)
- == 0)
- {
- v[i].get_handler = av->get_handler;
- v[i].data = av->data;
-
- av->flags |= NGX_HTTP_VAR_INDEXED;
- v[i].flags = av->flags;
-
- av->index = i;
-
- goto next;
- }
- }
-
- if (ngx_strncmp(v[i].name.data, "http_", 5) == 0) {
- v[i].get_handler = ngx_http_variable_unknown_header_in;
- v[i].data = (uintptr_t) &v[i].name;
-
- continue;
- }
-
- if (ngx_strncmp(v[i].name.data, "sent_http_", 10) == 0) {
- v[i].get_handler = ngx_http_variable_unknown_header_out;
- v[i].data = (uintptr_t) &v[i].name;
-
- continue;
- }
-
- if (ngx_strncmp(v[i].name.data, "upstream_http_", 14) == 0) {
- v[i].get_handler = ngx_http_upstream_header_variable;
- v[i].data = (uintptr_t) &v[i].name;
- v[i].flags = NGX_HTTP_VAR_NOCACHEABLE;
-
- continue;
- }
-
- if (ngx_strncmp(v[i].name.data, "cookie_", 7) == 0) {
- v[i].get_handler = ngx_http_variable_cookie;
- v[i].data = (uintptr_t) &v[i].name;
-
- continue;
- }
-
- if (ngx_strncmp(v[i].name.data, "arg_", 4) == 0) {
- v[i].get_handler = ngx_http_variable_argument;
- v[i].data = (uintptr_t) &v[i].name;
- v[i].flags = NGX_HTTP_VAR_NOCACHEABLE;
-
- continue;
- }
-
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "unknown \"%V\" variable", &v[i].name);
-
- return NGX_ERROR;
-
- next:
- continue;
- }
-
-
- for (n = 0; n < cmcf->variables_keys->keys.nelts; n++) {
- av = key[n].value;
-
- if (av->flags & NGX_HTTP_VAR_NOHASH) {
- key[n].key.data = NULL;
- }
- }
-
-
- hash.hash = &cmcf->variables_hash;
- hash.key = ngx_hash_key;
- hash.max_size = cmcf->variables_hash_max_size;
- hash.bucket_size = cmcf->variables_hash_bucket_size;
- hash.name = "variables_hash";
- hash.pool = cf->pool;
- hash.temp_pool = NULL;
-
- if (ngx_hash_init(&hash, cmcf->variables_keys->keys.elts,
- cmcf->variables_keys->keys.nelts)
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
- cmcf->variables_keys = NULL;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/http/ngx_http_variables.h b/usr.sbin/nginx/src/http/ngx_http_variables.h
deleted file mode 100644
index 829fab31e64..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_variables.h
+++ /dev/null
@@ -1,112 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_HTTP_VARIABLES_H_INCLUDED_
-#define _NGX_HTTP_VARIABLES_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef ngx_variable_value_t ngx_http_variable_value_t;
-
-#define ngx_http_variable(v) { sizeof(v) - 1, 1, 0, 0, 0, (u_char *) v }
-
-typedef struct ngx_http_variable_s ngx_http_variable_t;
-
-typedef void (*ngx_http_set_variable_pt) (ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-typedef ngx_int_t (*ngx_http_get_variable_pt) (ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
-
-
-#define NGX_HTTP_VAR_CHANGEABLE 1
-#define NGX_HTTP_VAR_NOCACHEABLE 2
-#define NGX_HTTP_VAR_INDEXED 4
-#define NGX_HTTP_VAR_NOHASH 8
-
-
-struct ngx_http_variable_s {
- ngx_str_t name; /* must be first to build the hash */
- ngx_http_set_variable_pt set_handler;
- ngx_http_get_variable_pt get_handler;
- uintptr_t data;
- ngx_uint_t flags;
- ngx_uint_t index;
-};
-
-
-ngx_http_variable_t *ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name,
- ngx_uint_t flags);
-ngx_int_t ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name);
-ngx_http_variable_value_t *ngx_http_get_indexed_variable(ngx_http_request_t *r,
- ngx_uint_t index);
-ngx_http_variable_value_t *ngx_http_get_flushed_variable(ngx_http_request_t *r,
- ngx_uint_t index);
-
-ngx_http_variable_value_t *ngx_http_get_variable(ngx_http_request_t *r,
- ngx_str_t *name, ngx_uint_t key);
-
-ngx_int_t ngx_http_variable_unknown_header(ngx_http_variable_value_t *v,
- ngx_str_t *var, ngx_list_part_t *part, size_t prefix);
-
-
-#if (NGX_PCRE)
-
-typedef struct {
- ngx_uint_t capture;
- ngx_int_t index;
-} ngx_http_regex_variable_t;
-
-
-typedef struct {
- ngx_regex_t *regex;
- ngx_uint_t ncaptures;
- ngx_http_regex_variable_t *variables;
- ngx_uint_t nvariables;
- ngx_str_t name;
-} ngx_http_regex_t;
-
-
-typedef struct {
- ngx_http_regex_t *regex;
- void *value;
-} ngx_http_map_regex_t;
-
-
-ngx_http_regex_t *ngx_http_regex_compile(ngx_conf_t *cf,
- ngx_regex_compile_t *rc);
-ngx_int_t ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re,
- ngx_str_t *s);
-
-#endif
-
-
-typedef struct {
- ngx_hash_combined_t hash;
-#if (NGX_PCRE)
- ngx_http_map_regex_t *regex;
- ngx_uint_t nregex;
-#endif
-} ngx_http_map_t;
-
-
-void *ngx_http_map_find(ngx_http_request_t *r, ngx_http_map_t *map,
- ngx_str_t *match);
-
-
-ngx_int_t ngx_http_variables_add_core_vars(ngx_conf_t *cf);
-ngx_int_t ngx_http_variables_init_vars(ngx_conf_t *cf);
-
-
-extern ngx_http_variable_value_t ngx_http_variable_null_value;
-extern ngx_http_variable_value_t ngx_http_variable_true_value;
-
-
-#endif /* _NGX_HTTP_VARIABLES_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/http/ngx_http_write_filter_module.c b/usr.sbin/nginx/src/http/ngx_http_write_filter_module.c
deleted file mode 100644
index 83cb1fa1e98..00000000000
--- a/usr.sbin/nginx/src/http/ngx_http_write_filter_module.c
+++ /dev/null
@@ -1,318 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-static ngx_int_t ngx_http_write_filter_init(ngx_conf_t *cf);
-
-
-static ngx_http_module_t ngx_http_write_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_write_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- NULL, /* create location configuration */
- NULL, /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_write_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_write_filter_module_ctx, /* module context */
- NULL, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-ngx_int_t
-ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- off_t size, sent, nsent, limit;
- ngx_uint_t last, flush;
- ngx_msec_t delay;
- ngx_chain_t *cl, *ln, **ll, *chain;
- ngx_connection_t *c;
- ngx_http_core_loc_conf_t *clcf;
-
- c = r->connection;
-
- if (c->error) {
- return NGX_ERROR;
- }
-
- size = 0;
- flush = 0;
- last = 0;
- ll = &r->out;
-
- /* find the size, the flush point and the last link of the saved chain */
-
- for (cl = r->out; cl; cl = cl->next) {
- ll = &cl->next;
-
- ngx_log_debug7(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "write old buf t:%d f:%d %p, pos %p, size: %z "
- "file: %O, size: %z",
- cl->buf->temporary, cl->buf->in_file,
- cl->buf->start, cl->buf->pos,
- cl->buf->last - cl->buf->pos,
- cl->buf->file_pos,
- cl->buf->file_last - cl->buf->file_pos);
-
-#if 1
- if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "zero size buf in writer "
- "t:%d r:%d f:%d %p %p-%p %p %O-%O",
- cl->buf->temporary,
- cl->buf->recycled,
- cl->buf->in_file,
- cl->buf->start,
- cl->buf->pos,
- cl->buf->last,
- cl->buf->file,
- cl->buf->file_pos,
- cl->buf->file_last);
-
- ngx_debug_point();
- return NGX_ERROR;
- }
-#endif
-
- size += ngx_buf_size(cl->buf);
-
- if (cl->buf->flush || cl->buf->recycled) {
- flush = 1;
- }
-
- if (cl->buf->last_buf) {
- last = 1;
- }
- }
-
- /* add the new chain to the existent one */
-
- for (ln = in; ln; ln = ln->next) {
- cl = ngx_alloc_chain_link(r->pool);
- if (cl == NULL) {
- return NGX_ERROR;
- }
-
- cl->buf = ln->buf;
- *ll = cl;
- ll = &cl->next;
-
- ngx_log_debug7(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "write new buf t:%d f:%d %p, pos %p, size: %z "
- "file: %O, size: %z",
- cl->buf->temporary, cl->buf->in_file,
- cl->buf->start, cl->buf->pos,
- cl->buf->last - cl->buf->pos,
- cl->buf->file_pos,
- cl->buf->file_last - cl->buf->file_pos);
-
-#if 1
- if (ngx_buf_size(cl->buf) == 0 && !ngx_buf_special(cl->buf)) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "zero size buf in writer "
- "t:%d r:%d f:%d %p %p-%p %p %O-%O",
- cl->buf->temporary,
- cl->buf->recycled,
- cl->buf->in_file,
- cl->buf->start,
- cl->buf->pos,
- cl->buf->last,
- cl->buf->file,
- cl->buf->file_pos,
- cl->buf->file_last);
-
- ngx_debug_point();
- return NGX_ERROR;
- }
-#endif
-
- size += ngx_buf_size(cl->buf);
-
- if (cl->buf->flush || cl->buf->recycled) {
- flush = 1;
- }
-
- if (cl->buf->last_buf) {
- last = 1;
- }
- }
-
- *ll = NULL;
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http write filter: l:%d f:%d s:%O", last, flush, size);
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- /*
- * avoid the output if there are no last buf, no flush point,
- * there are the incoming bufs and the size of all bufs
- * is smaller than "postpone_output" directive
- */
-
- if (!last && !flush && in && size < (off_t) clcf->postpone_output) {
- return NGX_OK;
- }
-
- if (c->write->delayed) {
- c->buffered |= NGX_HTTP_WRITE_BUFFERED;
- return NGX_AGAIN;
- }
-
- if (size == 0
- && !(c->buffered & NGX_LOWLEVEL_BUFFERED)
- && !(last && c->need_last_buf))
- {
- if (last || flush) {
- for (cl = r->out; cl; /* void */) {
- ln = cl;
- cl = cl->next;
- ngx_free_chain(r->pool, ln);
- }
-
- r->out = NULL;
- c->buffered &= ~NGX_HTTP_WRITE_BUFFERED;
-
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "the http output chain is empty");
-
- ngx_debug_point();
-
- return NGX_ERROR;
- }
-
- if (r->limit_rate) {
- if (r->limit_rate_after == 0) {
- r->limit_rate_after = clcf->limit_rate_after;
- }
-
- limit = (off_t) r->limit_rate * (ngx_time() - r->start_sec + 1)
- - (c->sent - r->limit_rate_after);
-
- if (limit <= 0) {
- c->write->delayed = 1;
- ngx_add_timer(c->write,
- (ngx_msec_t) (- limit * 1000 / r->limit_rate + 1));
-
- c->buffered |= NGX_HTTP_WRITE_BUFFERED;
-
- return NGX_AGAIN;
- }
-
- if (clcf->sendfile_max_chunk
- && (off_t) clcf->sendfile_max_chunk < limit)
- {
- limit = clcf->sendfile_max_chunk;
- }
-
- } else {
- limit = clcf->sendfile_max_chunk;
- }
-
- sent = c->sent;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http write filter limit %O", limit);
-
- chain = c->send_chain(c, r->out, limit);
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
- "http write filter %p", chain);
-
- if (chain == NGX_CHAIN_ERROR) {
- c->error = 1;
- return NGX_ERROR;
- }
-
- if (r->limit_rate) {
-
- nsent = c->sent;
-
- if (r->limit_rate_after) {
-
- sent -= r->limit_rate_after;
- if (sent < 0) {
- sent = 0;
- }
-
- nsent -= r->limit_rate_after;
- if (nsent < 0) {
- nsent = 0;
- }
- }
-
- delay = (ngx_msec_t) ((nsent - sent) * 1000 / r->limit_rate);
-
- if (delay > 0) {
- limit = 0;
- c->write->delayed = 1;
- ngx_add_timer(c->write, delay);
- }
- }
-
- if (limit
- && c->write->ready
- && c->sent - sent >= limit - (off_t) (2 * ngx_pagesize))
- {
- c->write->delayed = 1;
- ngx_add_timer(c->write, 1);
- }
-
- for (cl = r->out; cl && cl != chain; /* void */) {
- ln = cl;
- cl = cl->next;
- ngx_free_chain(r->pool, ln);
- }
-
- r->out = chain;
-
- if (chain) {
- c->buffered |= NGX_HTTP_WRITE_BUFFERED;
- return NGX_AGAIN;
- }
-
- c->buffered &= ~NGX_HTTP_WRITE_BUFFERED;
-
- if ((c->buffered & NGX_LOWLEVEL_BUFFERED) && r->postponed == NULL) {
- return NGX_AGAIN;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_write_filter_init(ngx_conf_t *cf)
-{
- ngx_http_top_body_filter = ngx_http_write_filter;
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail.c b/usr.sbin/nginx/src/mail/ngx_mail.c
deleted file mode 100644
index 350d2cdf90b..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail.c
+++ /dev/null
@@ -1,568 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_mail.h>
-
-
-static char *ngx_mail_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static ngx_int_t ngx_mail_add_ports(ngx_conf_t *cf, ngx_array_t *ports,
- ngx_mail_listen_t *listen);
-static char *ngx_mail_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports);
-static ngx_int_t ngx_mail_add_addrs(ngx_conf_t *cf, ngx_mail_port_t *mport,
- ngx_mail_conf_addr_t *addr);
-#if (NGX_HAVE_INET6)
-static ngx_int_t ngx_mail_add_addrs6(ngx_conf_t *cf, ngx_mail_port_t *mport,
- ngx_mail_conf_addr_t *addr);
-#endif
-static ngx_int_t ngx_mail_cmp_conf_addrs(const void *one, const void *two);
-
-
-ngx_uint_t ngx_mail_max_module;
-
-
-static ngx_command_t ngx_mail_commands[] = {
-
- { ngx_string("mail"),
- NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
- ngx_mail_block,
- 0,
- 0,
- NULL },
-
- { ngx_string("imap"),
- NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
- ngx_mail_block,
- 0,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_core_module_t ngx_mail_module_ctx = {
- ngx_string("mail"),
- NULL,
- NULL
-};
-
-
-ngx_module_t ngx_mail_module = {
- NGX_MODULE_V1,
- &ngx_mail_module_ctx, /* module context */
- ngx_mail_commands, /* module directives */
- NGX_CORE_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static char *
-ngx_mail_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *rv;
- ngx_uint_t i, m, mi, s;
- ngx_conf_t pcf;
- ngx_array_t ports;
- ngx_mail_listen_t *listen;
- ngx_mail_module_t *module;
- ngx_mail_conf_ctx_t *ctx;
- ngx_mail_core_srv_conf_t **cscfp;
- ngx_mail_core_main_conf_t *cmcf;
-
- if (cmd->name.data[0] == 'i') {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "the \"imap\" directive is deprecated, "
- "use the \"mail\" directive instead");
- }
-
- /* the main mail context */
-
- ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *(ngx_mail_conf_ctx_t **) conf = ctx;
-
- /* count the number of the http modules and set up their indices */
-
- ngx_mail_max_module = 0;
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
- continue;
- }
-
- ngx_modules[m]->ctx_index = ngx_mail_max_module++;
- }
-
-
- /* the mail main_conf context, it is the same in the all mail contexts */
-
- ctx->main_conf = ngx_pcalloc(cf->pool,
- sizeof(void *) * ngx_mail_max_module);
- if (ctx->main_conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
-
- /*
- * the mail null srv_conf context, it is used to merge
- * the server{}s' srv_conf's
- */
-
- ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_mail_max_module);
- if (ctx->srv_conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
-
- /*
- * create the main_conf's, the null srv_conf's, and the null loc_conf's
- * of the all mail modules
- */
-
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
- continue;
- }
-
- module = ngx_modules[m]->ctx;
- mi = ngx_modules[m]->ctx_index;
-
- if (module->create_main_conf) {
- ctx->main_conf[mi] = module->create_main_conf(cf);
- if (ctx->main_conf[mi] == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- if (module->create_srv_conf) {
- ctx->srv_conf[mi] = module->create_srv_conf(cf);
- if (ctx->srv_conf[mi] == NULL) {
- return NGX_CONF_ERROR;
- }
- }
- }
-
-
- /* parse inside the mail{} block */
-
- pcf = *cf;
- cf->ctx = ctx;
-
- cf->module_type = NGX_MAIL_MODULE;
- cf->cmd_type = NGX_MAIL_MAIN_CONF;
- rv = ngx_conf_parse(cf, NULL);
-
- if (rv != NGX_CONF_OK) {
- *cf = pcf;
- return rv;
- }
-
-
- /* init mail{} main_conf's, merge the server{}s' srv_conf's */
-
- cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index];
- cscfp = cmcf->servers.elts;
-
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
- continue;
- }
-
- module = ngx_modules[m]->ctx;
- mi = ngx_modules[m]->ctx_index;
-
- /* init mail{} main_conf's */
-
- cf->ctx = ctx;
-
- if (module->init_main_conf) {
- rv = module->init_main_conf(cf, ctx->main_conf[mi]);
- if (rv != NGX_CONF_OK) {
- *cf = pcf;
- return rv;
- }
- }
-
- for (s = 0; s < cmcf->servers.nelts; s++) {
-
- /* merge the server{}s' srv_conf's */
-
- cf->ctx = cscfp[s]->ctx;
-
- if (module->merge_srv_conf) {
- rv = module->merge_srv_conf(cf,
- ctx->srv_conf[mi],
- cscfp[s]->ctx->srv_conf[mi]);
- if (rv != NGX_CONF_OK) {
- *cf = pcf;
- return rv;
- }
- }
- }
- }
-
- *cf = pcf;
-
-
- if (ngx_array_init(&ports, cf->temp_pool, 4, sizeof(ngx_mail_conf_port_t))
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- listen = cmcf->listen.elts;
-
- for (i = 0; i < cmcf->listen.nelts; i++) {
- if (ngx_mail_add_ports(cf, &ports, &listen[i]) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- }
-
- return ngx_mail_optimize_servers(cf, &ports);
-}
-
-
-static ngx_int_t
-ngx_mail_add_ports(ngx_conf_t *cf, ngx_array_t *ports,
- ngx_mail_listen_t *listen)
-{
- in_port_t p;
- ngx_uint_t i;
- struct sockaddr *sa;
- struct sockaddr_in *sin;
- ngx_mail_conf_port_t *port;
- ngx_mail_conf_addr_t *addr;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
-
- sa = (struct sockaddr *) &listen->sockaddr;
-
- switch (sa->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) sa;
- p = sin6->sin6_port;
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- p = 0;
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) sa;
- p = sin->sin_port;
- break;
- }
-
- port = ports->elts;
- for (i = 0; i < ports->nelts; i++) {
- if (p == port[i].port && sa->sa_family == port[i].family) {
-
- /* a port is already in the port list */
-
- port = &port[i];
- goto found;
- }
- }
-
- /* add a port to the port list */
-
- port = ngx_array_push(ports);
- if (port == NULL) {
- return NGX_ERROR;
- }
-
- port->family = sa->sa_family;
- port->port = p;
-
- if (ngx_array_init(&port->addrs, cf->temp_pool, 2,
- sizeof(ngx_mail_conf_addr_t))
- != NGX_OK)
- {
- return NGX_ERROR;
- }
-
-found:
-
- addr = ngx_array_push(&port->addrs);
- if (addr == NULL) {
- return NGX_ERROR;
- }
-
- addr->sockaddr = (struct sockaddr *) &listen->sockaddr;
- addr->socklen = listen->socklen;
- addr->ctx = listen->ctx;
- addr->bind = listen->bind;
- addr->wildcard = listen->wildcard;
- addr->so_keepalive = listen->so_keepalive;
-#if (NGX_HAVE_KEEPALIVE_TUNABLE)
- addr->tcp_keepidle = listen->tcp_keepidle;
- addr->tcp_keepintvl = listen->tcp_keepintvl;
- addr->tcp_keepcnt = listen->tcp_keepcnt;
-#endif
-#if (NGX_MAIL_SSL)
- addr->ssl = listen->ssl;
-#endif
-#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- addr->ipv6only = listen->ipv6only;
-#endif
-
- return NGX_OK;
-}
-
-
-static char *
-ngx_mail_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports)
-{
- ngx_uint_t i, p, last, bind_wildcard;
- ngx_listening_t *ls;
- ngx_mail_port_t *mport;
- ngx_mail_conf_port_t *port;
- ngx_mail_conf_addr_t *addr;
-
- port = ports->elts;
- for (p = 0; p < ports->nelts; p++) {
-
- ngx_sort(port[p].addrs.elts, (size_t) port[p].addrs.nelts,
- sizeof(ngx_mail_conf_addr_t), ngx_mail_cmp_conf_addrs);
-
- addr = port[p].addrs.elts;
- last = port[p].addrs.nelts;
-
- /*
- * if there is the binding to the "*:port" then we need to bind()
- * to the "*:port" only and ignore the other bindings
- */
-
- if (addr[last - 1].wildcard) {
- addr[last - 1].bind = 1;
- bind_wildcard = 1;
-
- } else {
- bind_wildcard = 0;
- }
-
- i = 0;
-
- while (i < last) {
-
- if (bind_wildcard && !addr[i].bind) {
- i++;
- continue;
- }
-
- ls = ngx_create_listening(cf, addr[i].sockaddr, addr[i].socklen);
- if (ls == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ls->addr_ntop = 1;
- ls->handler = ngx_mail_init_connection;
- ls->pool_size = 256;
-
- /* TODO: error_log directive */
- ls->logp = &cf->cycle->new_log;
- ls->log.data = &ls->addr_text;
- ls->log.handler = ngx_accept_log_error;
-
- ls->keepalive = addr[i].so_keepalive;
-#if (NGX_HAVE_KEEPALIVE_TUNABLE)
- ls->keepidle = addr[i].tcp_keepidle;
- ls->keepintvl = addr[i].tcp_keepintvl;
- ls->keepcnt = addr[i].tcp_keepcnt;
-#endif
-
-#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- ls->ipv6only = addr[i].ipv6only;
-#endif
-
- mport = ngx_palloc(cf->pool, sizeof(ngx_mail_port_t));
- if (mport == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ls->servers = mport;
-
- if (i == last - 1) {
- mport->naddrs = last;
-
- } else {
- mport->naddrs = 1;
- i = 0;
- }
-
- switch (ls->sockaddr->sa_family) {
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- if (ngx_mail_add_addrs6(cf, mport, addr) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- break;
-#endif
- default: /* AF_INET */
- if (ngx_mail_add_addrs(cf, mport, addr) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
- break;
- }
-
- addr++;
- last--;
- }
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_mail_add_addrs(ngx_conf_t *cf, ngx_mail_port_t *mport,
- ngx_mail_conf_addr_t *addr)
-{
- u_char *p;
- size_t len;
- ngx_uint_t i;
- ngx_mail_in_addr_t *addrs;
- struct sockaddr_in *sin;
- u_char buf[NGX_SOCKADDR_STRLEN];
-
- mport->addrs = ngx_pcalloc(cf->pool,
- mport->naddrs * sizeof(ngx_mail_in_addr_t));
- if (mport->addrs == NULL) {
- return NGX_ERROR;
- }
-
- addrs = mport->addrs;
-
- for (i = 0; i < mport->naddrs; i++) {
-
- sin = (struct sockaddr_in *) addr[i].sockaddr;
- addrs[i].addr = sin->sin_addr.s_addr;
-
- addrs[i].conf.ctx = addr[i].ctx;
-#if (NGX_MAIL_SSL)
- addrs[i].conf.ssl = addr[i].ssl;
-#endif
-
- len = ngx_sock_ntop(addr[i].sockaddr, addr[i].socklen, buf,
- NGX_SOCKADDR_STRLEN, 1);
-
- p = ngx_pnalloc(cf->pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(p, buf, len);
-
- addrs[i].conf.addr_text.len = len;
- addrs[i].conf.addr_text.data = p;
- }
-
- return NGX_OK;
-}
-
-
-#if (NGX_HAVE_INET6)
-
-static ngx_int_t
-ngx_mail_add_addrs6(ngx_conf_t *cf, ngx_mail_port_t *mport,
- ngx_mail_conf_addr_t *addr)
-{
- u_char *p;
- size_t len;
- ngx_uint_t i;
- ngx_mail_in6_addr_t *addrs6;
- struct sockaddr_in6 *sin6;
- u_char buf[NGX_SOCKADDR_STRLEN];
-
- mport->addrs = ngx_pcalloc(cf->pool,
- mport->naddrs * sizeof(ngx_mail_in6_addr_t));
- if (mport->addrs == NULL) {
- return NGX_ERROR;
- }
-
- addrs6 = mport->addrs;
-
- for (i = 0; i < mport->naddrs; i++) {
-
- sin6 = (struct sockaddr_in6 *) addr[i].sockaddr;
- addrs6[i].addr6 = sin6->sin6_addr;
-
- addrs6[i].conf.ctx = addr[i].ctx;
-#if (NGX_MAIL_SSL)
- addrs6[i].conf.ssl = addr[i].ssl;
-#endif
-
- len = ngx_sock_ntop(addr[i].sockaddr, addr[i].socklen, buf,
- NGX_SOCKADDR_STRLEN, 1);
-
- p = ngx_pnalloc(cf->pool, len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(p, buf, len);
-
- addrs6[i].conf.addr_text.len = len;
- addrs6[i].conf.addr_text.data = p;
- }
-
- return NGX_OK;
-}
-
-#endif
-
-
-static ngx_int_t
-ngx_mail_cmp_conf_addrs(const void *one, const void *two)
-{
- ngx_mail_conf_addr_t *first, *second;
-
- first = (ngx_mail_conf_addr_t *) one;
- second = (ngx_mail_conf_addr_t *) two;
-
- if (first->wildcard) {
- /* a wildcard must be the last resort, shift it to the end */
- return 1;
- }
-
- if (second->wildcard) {
- /* a wildcard must be the last resort, shift it to the end */
- return -1;
- }
-
- if (first->bind && !second->bind) {
- /* shift explicit bind()ed addresses to the start */
- return -1;
- }
-
- if (!first->bind && second->bind) {
- /* shift explicit bind()ed addresses to the start */
- return 1;
- }
-
- /* do not sort by default */
-
- return 0;
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail.h b/usr.sbin/nginx/src/mail/ngx_mail.h
deleted file mode 100644
index dc39f1e1375..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail.h
+++ /dev/null
@@ -1,421 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_MAIL_H_INCLUDED_
-#define _NGX_MAIL_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_event_connect.h>
-
-#if (NGX_MAIL_SSL)
-#include <ngx_mail_ssl_module.h>
-#endif
-
-
-
-typedef struct {
- void **main_conf;
- void **srv_conf;
-} ngx_mail_conf_ctx_t;
-
-
-typedef struct {
- u_char sockaddr[NGX_SOCKADDRLEN];
- socklen_t socklen;
-
- /* server ctx */
- ngx_mail_conf_ctx_t *ctx;
-
- unsigned bind:1;
- unsigned wildcard:1;
-#if (NGX_MAIL_SSL)
- unsigned ssl:1;
-#endif
-#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- unsigned ipv6only:1;
-#endif
- unsigned so_keepalive:2;
-#if (NGX_HAVE_KEEPALIVE_TUNABLE)
- int tcp_keepidle;
- int tcp_keepintvl;
- int tcp_keepcnt;
-#endif
-} ngx_mail_listen_t;
-
-
-typedef struct {
- ngx_mail_conf_ctx_t *ctx;
- ngx_str_t addr_text;
-#if (NGX_MAIL_SSL)
- ngx_uint_t ssl; /* unsigned ssl:1; */
-#endif
-} ngx_mail_addr_conf_t;
-
-typedef struct {
- in_addr_t addr;
- ngx_mail_addr_conf_t conf;
-} ngx_mail_in_addr_t;
-
-
-#if (NGX_HAVE_INET6)
-
-typedef struct {
- struct in6_addr addr6;
- ngx_mail_addr_conf_t conf;
-} ngx_mail_in6_addr_t;
-
-#endif
-
-
-typedef struct {
- /* ngx_mail_in_addr_t or ngx_mail_in6_addr_t */
- void *addrs;
- ngx_uint_t naddrs;
-} ngx_mail_port_t;
-
-
-typedef struct {
- int family;
- in_port_t port;
- ngx_array_t addrs; /* array of ngx_mail_conf_addr_t */
-} ngx_mail_conf_port_t;
-
-
-typedef struct {
- struct sockaddr *sockaddr;
- socklen_t socklen;
-
- ngx_mail_conf_ctx_t *ctx;
-
- unsigned bind:1;
- unsigned wildcard:1;
-#if (NGX_MAIL_SSL)
- unsigned ssl:1;
-#endif
-#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- unsigned ipv6only:1;
-#endif
- unsigned so_keepalive:2;
-#if (NGX_HAVE_KEEPALIVE_TUNABLE)
- int tcp_keepidle;
- int tcp_keepintvl;
- int tcp_keepcnt;
-#endif
-} ngx_mail_conf_addr_t;
-
-
-typedef struct {
- ngx_array_t servers; /* ngx_mail_core_srv_conf_t */
- ngx_array_t listen; /* ngx_mail_listen_t */
-} ngx_mail_core_main_conf_t;
-
-
-#define NGX_MAIL_POP3_PROTOCOL 0
-#define NGX_MAIL_IMAP_PROTOCOL 1
-#define NGX_MAIL_SMTP_PROTOCOL 2
-
-
-typedef struct ngx_mail_protocol_s ngx_mail_protocol_t;
-
-
-typedef struct {
- ngx_mail_protocol_t *protocol;
-
- ngx_msec_t timeout;
- ngx_msec_t resolver_timeout;
-
- ngx_flag_t so_keepalive;
-
- ngx_str_t server_name;
-
- u_char *file_name;
- ngx_int_t line;
-
- ngx_resolver_t *resolver;
-
- /* server ctx */
- ngx_mail_conf_ctx_t *ctx;
-} ngx_mail_core_srv_conf_t;
-
-
-typedef enum {
- ngx_pop3_start = 0,
- ngx_pop3_user,
- ngx_pop3_passwd,
- ngx_pop3_auth_login_username,
- ngx_pop3_auth_login_password,
- ngx_pop3_auth_plain,
- ngx_pop3_auth_cram_md5
-} ngx_pop3_state_e;
-
-
-typedef enum {
- ngx_imap_start = 0,
- ngx_imap_auth_login_username,
- ngx_imap_auth_login_password,
- ngx_imap_auth_plain,
- ngx_imap_auth_cram_md5,
- ngx_imap_login,
- ngx_imap_user,
- ngx_imap_passwd
-} ngx_imap_state_e;
-
-
-typedef enum {
- ngx_smtp_start = 0,
- ngx_smtp_auth_login_username,
- ngx_smtp_auth_login_password,
- ngx_smtp_auth_plain,
- ngx_smtp_auth_cram_md5,
- ngx_smtp_helo,
- ngx_smtp_helo_xclient,
- ngx_smtp_helo_from,
- ngx_smtp_xclient,
- ngx_smtp_xclient_from,
- ngx_smtp_xclient_helo,
- ngx_smtp_from,
- ngx_smtp_to
-} ngx_smtp_state_e;
-
-
-typedef struct {
- ngx_peer_connection_t upstream;
- ngx_buf_t *buffer;
-} ngx_mail_proxy_ctx_t;
-
-
-typedef struct {
- uint32_t signature; /* "MAIL" */
-
- ngx_connection_t *connection;
-
- ngx_str_t out;
- ngx_buf_t *buffer;
-
- void **ctx;
- void **main_conf;
- void **srv_conf;
-
- ngx_resolver_ctx_t *resolver_ctx;
-
- ngx_mail_proxy_ctx_t *proxy;
-
- ngx_uint_t mail_state;
-
- unsigned protocol:3;
- unsigned blocked:1;
- unsigned quit:1;
- unsigned quoted:1;
- unsigned backslash:1;
- unsigned no_sync_literal:1;
- unsigned starttls:1;
- unsigned esmtp:1;
- unsigned auth_method:3;
- unsigned auth_wait:1;
-
- ngx_str_t login;
- ngx_str_t passwd;
-
- ngx_str_t salt;
- ngx_str_t tag;
- ngx_str_t tagged_line;
- ngx_str_t text;
-
- ngx_str_t *addr_text;
- ngx_str_t host;
- ngx_str_t smtp_helo;
- ngx_str_t smtp_from;
- ngx_str_t smtp_to;
-
- ngx_str_t cmd;
-
- ngx_uint_t command;
- ngx_array_t args;
-
- ngx_uint_t login_attempt;
-
- /* used to parse POP3/IMAP/SMTP command */
-
- ngx_uint_t state;
- u_char *cmd_start;
- u_char *arg_start;
- u_char *arg_end;
- ngx_uint_t literal_len;
-} ngx_mail_session_t;
-
-
-typedef struct {
- ngx_str_t *client;
- ngx_mail_session_t *session;
-} ngx_mail_log_ctx_t;
-
-
-#define NGX_POP3_USER 1
-#define NGX_POP3_PASS 2
-#define NGX_POP3_CAPA 3
-#define NGX_POP3_QUIT 4
-#define NGX_POP3_NOOP 5
-#define NGX_POP3_STLS 6
-#define NGX_POP3_APOP 7
-#define NGX_POP3_AUTH 8
-#define NGX_POP3_STAT 9
-#define NGX_POP3_LIST 10
-#define NGX_POP3_RETR 11
-#define NGX_POP3_DELE 12
-#define NGX_POP3_RSET 13
-#define NGX_POP3_TOP 14
-#define NGX_POP3_UIDL 15
-
-
-#define NGX_IMAP_LOGIN 1
-#define NGX_IMAP_LOGOUT 2
-#define NGX_IMAP_CAPABILITY 3
-#define NGX_IMAP_NOOP 4
-#define NGX_IMAP_STARTTLS 5
-
-#define NGX_IMAP_NEXT 6
-
-#define NGX_IMAP_AUTHENTICATE 7
-
-
-#define NGX_SMTP_HELO 1
-#define NGX_SMTP_EHLO 2
-#define NGX_SMTP_AUTH 3
-#define NGX_SMTP_QUIT 4
-#define NGX_SMTP_NOOP 5
-#define NGX_SMTP_MAIL 6
-#define NGX_SMTP_RSET 7
-#define NGX_SMTP_RCPT 8
-#define NGX_SMTP_DATA 9
-#define NGX_SMTP_VRFY 10
-#define NGX_SMTP_EXPN 11
-#define NGX_SMTP_HELP 12
-#define NGX_SMTP_STARTTLS 13
-
-
-#define NGX_MAIL_AUTH_PLAIN 0
-#define NGX_MAIL_AUTH_LOGIN 1
-#define NGX_MAIL_AUTH_LOGIN_USERNAME 2
-#define NGX_MAIL_AUTH_APOP 3
-#define NGX_MAIL_AUTH_CRAM_MD5 4
-#define NGX_MAIL_AUTH_NONE 5
-
-
-#define NGX_MAIL_AUTH_PLAIN_ENABLED 0x0002
-#define NGX_MAIL_AUTH_LOGIN_ENABLED 0x0004
-#define NGX_MAIL_AUTH_APOP_ENABLED 0x0008
-#define NGX_MAIL_AUTH_CRAM_MD5_ENABLED 0x0010
-#define NGX_MAIL_AUTH_NONE_ENABLED 0x0020
-
-
-#define NGX_MAIL_PARSE_INVALID_COMMAND 20
-
-
-typedef void (*ngx_mail_init_session_pt)(ngx_mail_session_t *s,
- ngx_connection_t *c);
-typedef void (*ngx_mail_init_protocol_pt)(ngx_event_t *rev);
-typedef void (*ngx_mail_auth_state_pt)(ngx_event_t *rev);
-typedef ngx_int_t (*ngx_mail_parse_command_pt)(ngx_mail_session_t *s);
-
-
-struct ngx_mail_protocol_s {
- ngx_str_t name;
- in_port_t port[4];
- ngx_uint_t type;
-
- ngx_mail_init_session_pt init_session;
- ngx_mail_init_protocol_pt init_protocol;
- ngx_mail_parse_command_pt parse_command;
- ngx_mail_auth_state_pt auth_state;
-
- ngx_str_t internal_server_error;
-};
-
-
-typedef struct {
- ngx_mail_protocol_t *protocol;
-
- void *(*create_main_conf)(ngx_conf_t *cf);
- char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
-
- void *(*create_srv_conf)(ngx_conf_t *cf);
- char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev,
- void *conf);
-} ngx_mail_module_t;
-
-
-#define NGX_MAIL_MODULE 0x4C49414D /* "MAIL" */
-
-#define NGX_MAIL_MAIN_CONF 0x02000000
-#define NGX_MAIL_SRV_CONF 0x04000000
-
-
-#define NGX_MAIL_MAIN_CONF_OFFSET offsetof(ngx_mail_conf_ctx_t, main_conf)
-#define NGX_MAIL_SRV_CONF_OFFSET offsetof(ngx_mail_conf_ctx_t, srv_conf)
-
-
-#define ngx_mail_get_module_ctx(s, module) (s)->ctx[module.ctx_index]
-#define ngx_mail_set_ctx(s, c, module) s->ctx[module.ctx_index] = c;
-#define ngx_mail_delete_ctx(s, module) s->ctx[module.ctx_index] = NULL;
-
-
-#define ngx_mail_get_module_main_conf(s, module) \
- (s)->main_conf[module.ctx_index]
-#define ngx_mail_get_module_srv_conf(s, module) (s)->srv_conf[module.ctx_index]
-
-#define ngx_mail_conf_get_module_main_conf(cf, module) \
- ((ngx_mail_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
-#define ngx_mail_conf_get_module_srv_conf(cf, module) \
- ((ngx_mail_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index]
-
-
-#if (NGX_MAIL_SSL)
-void ngx_mail_starttls_handler(ngx_event_t *rev);
-ngx_int_t ngx_mail_starttls_only(ngx_mail_session_t *s, ngx_connection_t *c);
-#endif
-
-
-void ngx_mail_init_connection(ngx_connection_t *c);
-
-ngx_int_t ngx_mail_salt(ngx_mail_session_t *s, ngx_connection_t *c,
- ngx_mail_core_srv_conf_t *cscf);
-ngx_int_t ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c,
- ngx_uint_t n);
-ngx_int_t ngx_mail_auth_login_username(ngx_mail_session_t *s,
- ngx_connection_t *c, ngx_uint_t n);
-ngx_int_t ngx_mail_auth_login_password(ngx_mail_session_t *s,
- ngx_connection_t *c);
-ngx_int_t ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s,
- ngx_connection_t *c, char *prefix, size_t len);
-ngx_int_t ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c);
-ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c);
-
-void ngx_mail_send(ngx_event_t *wev);
-ngx_int_t ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c);
-void ngx_mail_auth(ngx_mail_session_t *s, ngx_connection_t *c);
-void ngx_mail_close_connection(ngx_connection_t *c);
-void ngx_mail_session_internal_server_error(ngx_mail_session_t *s);
-u_char *ngx_mail_log_error(ngx_log_t *log, u_char *buf, size_t len);
-
-
-char *ngx_mail_capabilities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-
-
-/* STUB */
-void ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer);
-void ngx_mail_auth_http_init(ngx_mail_session_t *s);
-/**/
-
-
-extern ngx_uint_t ngx_mail_max_module;
-extern ngx_module_t ngx_mail_core_module;
-
-
-#endif /* _NGX_MAIL_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_auth_http_module.c b/usr.sbin/nginx/src/mail/ngx_mail_auth_http_module.c
deleted file mode 100644
index 8094bbc5cc7..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_auth_http_module.c
+++ /dev/null
@@ -1,1461 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_event_connect.h>
-#include <ngx_mail.h>
-
-
-typedef struct {
- ngx_addr_t *peer;
-
- ngx_msec_t timeout;
-
- ngx_str_t host_header;
- ngx_str_t uri;
- ngx_str_t header;
-
- ngx_array_t *headers;
-
- u_char *file;
- ngx_uint_t line;
-} ngx_mail_auth_http_conf_t;
-
-
-typedef struct ngx_mail_auth_http_ctx_s ngx_mail_auth_http_ctx_t;
-
-typedef void (*ngx_mail_auth_http_handler_pt)(ngx_mail_session_t *s,
- ngx_mail_auth_http_ctx_t *ctx);
-
-struct ngx_mail_auth_http_ctx_s {
- ngx_buf_t *request;
- ngx_buf_t *response;
- ngx_peer_connection_t peer;
-
- ngx_mail_auth_http_handler_pt handler;
-
- ngx_uint_t state;
-
- u_char *header_name_start;
- u_char *header_name_end;
- u_char *header_start;
- u_char *header_end;
-
- ngx_str_t addr;
- ngx_str_t port;
- ngx_str_t err;
- ngx_str_t errmsg;
- ngx_str_t errcode;
-
- time_t sleep;
-
- ngx_pool_t *pool;
-};
-
-
-static void ngx_mail_auth_http_write_handler(ngx_event_t *wev);
-static void ngx_mail_auth_http_read_handler(ngx_event_t *rev);
-static void ngx_mail_auth_http_ignore_status_line(ngx_mail_session_t *s,
- ngx_mail_auth_http_ctx_t *ctx);
-static void ngx_mail_auth_http_process_headers(ngx_mail_session_t *s,
- ngx_mail_auth_http_ctx_t *ctx);
-static void ngx_mail_auth_sleep_handler(ngx_event_t *rev);
-static ngx_int_t ngx_mail_auth_http_parse_header_line(ngx_mail_session_t *s,
- ngx_mail_auth_http_ctx_t *ctx);
-static void ngx_mail_auth_http_block_read(ngx_event_t *rev);
-static void ngx_mail_auth_http_dummy_handler(ngx_event_t *ev);
-static ngx_buf_t *ngx_mail_auth_http_create_request(ngx_mail_session_t *s,
- ngx_pool_t *pool, ngx_mail_auth_http_conf_t *ahcf);
-static ngx_int_t ngx_mail_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text,
- ngx_str_t *escaped);
-
-static void *ngx_mail_auth_http_create_conf(ngx_conf_t *cf);
-static char *ngx_mail_auth_http_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static char *ngx_mail_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-static char *ngx_mail_auth_http_header(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_command_t ngx_mail_auth_http_commands[] = {
-
- { ngx_string("auth_http"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_mail_auth_http,
- NGX_MAIL_SRV_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("auth_http_timeout"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_auth_http_conf_t, timeout),
- NULL },
-
- { ngx_string("auth_http_header"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE2,
- ngx_mail_auth_http_header,
- NGX_MAIL_SRV_CONF_OFFSET,
- 0,
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_mail_module_t ngx_mail_auth_http_module_ctx = {
- NULL, /* protocol */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- ngx_mail_auth_http_create_conf, /* create server configuration */
- ngx_mail_auth_http_merge_conf /* merge server configuration */
-};
-
-
-ngx_module_t ngx_mail_auth_http_module = {
- NGX_MODULE_V1,
- &ngx_mail_auth_http_module_ctx, /* module context */
- ngx_mail_auth_http_commands, /* module directives */
- NGX_MAIL_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_str_t ngx_mail_auth_http_method[] = {
- ngx_string("plain"),
- ngx_string("plain"),
- ngx_string("plain"),
- ngx_string("apop"),
- ngx_string("cram-md5"),
- ngx_string("none")
-};
-
-static ngx_str_t ngx_mail_smtp_errcode = ngx_string("535 5.7.0");
-
-
-void
-ngx_mail_auth_http_init(ngx_mail_session_t *s)
-{
- ngx_int_t rc;
- ngx_pool_t *pool;
- ngx_mail_auth_http_ctx_t *ctx;
- ngx_mail_auth_http_conf_t *ahcf;
-
- s->connection->log->action = "in http auth state";
-
- pool = ngx_create_pool(2048, s->connection->log);
- if (pool == NULL) {
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- ctx = ngx_pcalloc(pool, sizeof(ngx_mail_auth_http_ctx_t));
- if (ctx == NULL) {
- ngx_destroy_pool(pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- ctx->pool = pool;
-
- ahcf = ngx_mail_get_module_srv_conf(s, ngx_mail_auth_http_module);
-
- ctx->request = ngx_mail_auth_http_create_request(s, pool, ahcf);
- if (ctx->request == NULL) {
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- ngx_mail_set_ctx(s, ctx, ngx_mail_auth_http_module);
-
- ctx->peer.sockaddr = ahcf->peer->sockaddr;
- ctx->peer.socklen = ahcf->peer->socklen;
- ctx->peer.name = &ahcf->peer->name;
- ctx->peer.get = ngx_event_get_peer;
- ctx->peer.log = s->connection->log;
- ctx->peer.log_error = NGX_ERROR_ERR;
-
- rc = ngx_event_connect_peer(&ctx->peer);
-
- if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) {
- if (ctx->peer.connection) {
- ngx_close_connection(ctx->peer.connection);
- }
-
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- ctx->peer.connection->data = s;
- ctx->peer.connection->pool = s->connection->pool;
-
- s->connection->read->handler = ngx_mail_auth_http_block_read;
- ctx->peer.connection->read->handler = ngx_mail_auth_http_read_handler;
- ctx->peer.connection->write->handler = ngx_mail_auth_http_write_handler;
-
- ctx->handler = ngx_mail_auth_http_ignore_status_line;
-
- ngx_add_timer(ctx->peer.connection->read, ahcf->timeout);
- ngx_add_timer(ctx->peer.connection->write, ahcf->timeout);
-
- if (rc == NGX_OK) {
- ngx_mail_auth_http_write_handler(ctx->peer.connection->write);
- return;
- }
-}
-
-
-static void
-ngx_mail_auth_http_write_handler(ngx_event_t *wev)
-{
- ssize_t n, size;
- ngx_connection_t *c;
- ngx_mail_session_t *s;
- ngx_mail_auth_http_ctx_t *ctx;
- ngx_mail_auth_http_conf_t *ahcf;
-
- c = wev->data;
- s = c->data;
-
- ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module);
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0,
- "mail auth http write handler");
-
- if (wev->timedout) {
- ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT,
- "auth http server %V timed out", ctx->peer.name);
- ngx_close_connection(c);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- size = ctx->request->last - ctx->request->pos;
-
- n = ngx_send(c, ctx->request->pos, size);
-
- if (n == NGX_ERROR) {
- ngx_close_connection(c);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- if (n > 0) {
- ctx->request->pos += n;
-
- if (n == size) {
- wev->handler = ngx_mail_auth_http_dummy_handler;
-
- if (wev->timer_set) {
- ngx_del_timer(wev);
- }
-
- if (ngx_handle_write_event(wev, 0) != NGX_OK) {
- ngx_close_connection(c);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- }
-
- return;
- }
- }
-
- if (!wev->timer_set) {
- ahcf = ngx_mail_get_module_srv_conf(s, ngx_mail_auth_http_module);
- ngx_add_timer(wev, ahcf->timeout);
- }
-}
-
-
-static void
-ngx_mail_auth_http_read_handler(ngx_event_t *rev)
-{
- ssize_t n, size;
- ngx_connection_t *c;
- ngx_mail_session_t *s;
- ngx_mail_auth_http_ctx_t *ctx;
-
- c = rev->data;
- s = c->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
- "mail auth http read handler");
-
- ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module);
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
- "auth http server %V timed out", ctx->peer.name);
- ngx_close_connection(c);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- if (ctx->response == NULL) {
- ctx->response = ngx_create_temp_buf(ctx->pool, 1024);
- if (ctx->response == NULL) {
- ngx_close_connection(c);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
- }
-
- size = ctx->response->end - ctx->response->last;
-
- n = ngx_recv(c, ctx->response->pos, size);
-
- if (n > 0) {
- ctx->response->last += n;
-
- ctx->handler(s, ctx);
- return;
- }
-
- if (n == NGX_AGAIN) {
- return;
- }
-
- ngx_close_connection(c);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
-}
-
-
-static void
-ngx_mail_auth_http_ignore_status_line(ngx_mail_session_t *s,
- ngx_mail_auth_http_ctx_t *ctx)
-{
- u_char *p, ch;
- enum {
- sw_start = 0,
- sw_H,
- sw_HT,
- sw_HTT,
- sw_HTTP,
- sw_skip,
- sw_almost_done
- } state;
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
- "mail auth http process status line");
-
- state = ctx->state;
-
- for (p = ctx->response->pos; p < ctx->response->last; p++) {
- ch = *p;
-
- switch (state) {
-
- /* "HTTP/" */
- case sw_start:
- if (ch == 'H') {
- state = sw_H;
- break;
- }
- goto next;
-
- case sw_H:
- if (ch == 'T') {
- state = sw_HT;
- break;
- }
- goto next;
-
- case sw_HT:
- if (ch == 'T') {
- state = sw_HTT;
- break;
- }
- goto next;
-
- case sw_HTT:
- if (ch == 'P') {
- state = sw_HTTP;
- break;
- }
- goto next;
-
- case sw_HTTP:
- if (ch == '/') {
- state = sw_skip;
- break;
- }
- goto next;
-
- /* any text until end of line */
- case sw_skip:
- switch (ch) {
- case CR:
- state = sw_almost_done;
-
- break;
- case LF:
- goto done;
- }
- break;
-
- /* end of status line */
- case sw_almost_done:
- if (ch == LF) {
- goto done;
- }
-
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
- "auth http server &V sent invalid response",
- ctx->peer.name);
- ngx_close_connection(ctx->peer.connection);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
- }
-
- ctx->response->pos = p;
- ctx->state = state;
-
- return;
-
-next:
-
- p = ctx->response->start - 1;
-
-done:
-
- ctx->response->pos = p + 1;
- ctx->state = 0;
- ctx->handler = ngx_mail_auth_http_process_headers;
- ctx->handler(s, ctx);
-}
-
-
-static void
-ngx_mail_auth_http_process_headers(ngx_mail_session_t *s,
- ngx_mail_auth_http_ctx_t *ctx)
-{
- u_char *p;
- time_t timer;
- size_t len, size;
- ngx_int_t rc, port, n;
- ngx_addr_t *peer;
- struct sockaddr_in *sin;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
- "mail auth http process headers");
-
- for ( ;; ) {
- rc = ngx_mail_auth_http_parse_header_line(s, ctx);
-
- if (rc == NGX_OK) {
-
-#if (NGX_DEBUG)
- {
- ngx_str_t key, value;
-
- key.len = ctx->header_name_end - ctx->header_name_start;
- key.data = ctx->header_name_start;
- value.len = ctx->header_end - ctx->header_start;
- value.data = ctx->header_start;
-
- ngx_log_debug2(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
- "mail auth http header: \"%V: %V\"",
- &key, &value);
- }
-#endif
-
- len = ctx->header_name_end - ctx->header_name_start;
-
- if (len == sizeof("Auth-Status") - 1
- && ngx_strncasecmp(ctx->header_name_start,
- (u_char *) "Auth-Status",
- sizeof("Auth-Status") - 1)
- == 0)
- {
- len = ctx->header_end - ctx->header_start;
-
- if (len == 2
- && ctx->header_start[0] == 'O'
- && ctx->header_start[1] == 'K')
- {
- continue;
- }
-
- if (len == 4
- && ctx->header_start[0] == 'W'
- && ctx->header_start[1] == 'A'
- && ctx->header_start[2] == 'I'
- && ctx->header_start[3] == 'T')
- {
- s->auth_wait = 1;
- continue;
- }
-
- ctx->errmsg.len = len;
- ctx->errmsg.data = ctx->header_start;
-
- switch (s->protocol) {
-
- case NGX_MAIL_POP3_PROTOCOL:
- size = sizeof("-ERR ") - 1 + len + sizeof(CRLF) - 1;
- break;
-
- case NGX_MAIL_IMAP_PROTOCOL:
- size = s->tag.len + sizeof("NO ") - 1 + len
- + sizeof(CRLF) - 1;
- break;
-
- default: /* NGX_MAIL_SMTP_PROTOCOL */
- ctx->err = ctx->errmsg;
- continue;
- }
-
- p = ngx_pnalloc(s->connection->pool, size);
- if (p == NULL) {
- ngx_close_connection(ctx->peer.connection);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- ctx->err.data = p;
-
- switch (s->protocol) {
-
- case NGX_MAIL_POP3_PROTOCOL:
- *p++ = '-'; *p++ = 'E'; *p++ = 'R'; *p++ = 'R'; *p++ = ' ';
- break;
-
- case NGX_MAIL_IMAP_PROTOCOL:
- p = ngx_cpymem(p, s->tag.data, s->tag.len);
- *p++ = 'N'; *p++ = 'O'; *p++ = ' ';
- break;
-
- default: /* NGX_MAIL_SMTP_PROTOCOL */
- break;
- }
-
- p = ngx_cpymem(p, ctx->header_start, len);
- *p++ = CR; *p++ = LF;
-
- ctx->err.len = p - ctx->err.data;
-
- continue;
- }
-
- if (len == sizeof("Auth-Server") - 1
- && ngx_strncasecmp(ctx->header_name_start,
- (u_char *) "Auth-Server",
- sizeof("Auth-Server") - 1)
- == 0)
- {
- ctx->addr.len = ctx->header_end - ctx->header_start;
- ctx->addr.data = ctx->header_start;
-
- continue;
- }
-
- if (len == sizeof("Auth-Port") - 1
- && ngx_strncasecmp(ctx->header_name_start,
- (u_char *) "Auth-Port",
- sizeof("Auth-Port") - 1)
- == 0)
- {
- ctx->port.len = ctx->header_end - ctx->header_start;
- ctx->port.data = ctx->header_start;
-
- continue;
- }
-
- if (len == sizeof("Auth-User") - 1
- && ngx_strncasecmp(ctx->header_name_start,
- (u_char *) "Auth-User",
- sizeof("Auth-User") - 1)
- == 0)
- {
- s->login.len = ctx->header_end - ctx->header_start;
-
- s->login.data = ngx_pnalloc(s->connection->pool, s->login.len);
- if (s->login.data == NULL) {
- ngx_close_connection(ctx->peer.connection);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- ngx_memcpy(s->login.data, ctx->header_start, s->login.len);
-
- continue;
- }
-
- if (len == sizeof("Auth-Pass") - 1
- && ngx_strncasecmp(ctx->header_name_start,
- (u_char *) "Auth-Pass",
- sizeof("Auth-Pass") - 1)
- == 0)
- {
- s->passwd.len = ctx->header_end - ctx->header_start;
-
- s->passwd.data = ngx_pnalloc(s->connection->pool,
- s->passwd.len);
- if (s->passwd.data == NULL) {
- ngx_close_connection(ctx->peer.connection);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- ngx_memcpy(s->passwd.data, ctx->header_start, s->passwd.len);
-
- continue;
- }
-
- if (len == sizeof("Auth-Wait") - 1
- && ngx_strncasecmp(ctx->header_name_start,
- (u_char *) "Auth-Wait",
- sizeof("Auth-Wait") - 1)
- == 0)
- {
- n = ngx_atoi(ctx->header_start,
- ctx->header_end - ctx->header_start);
-
- if (n != NGX_ERROR) {
- ctx->sleep = n;
- }
-
- continue;
- }
-
- if (len == sizeof("Auth-Error-Code") - 1
- && ngx_strncasecmp(ctx->header_name_start,
- (u_char *) "Auth-Error-Code",
- sizeof("Auth-Error-Code") - 1)
- == 0)
- {
- ctx->errcode.len = ctx->header_end - ctx->header_start;
-
- ctx->errcode.data = ngx_pnalloc(s->connection->pool,
- ctx->errcode.len);
- if (ctx->errcode.data == NULL) {
- ngx_close_connection(ctx->peer.connection);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- ngx_memcpy(ctx->errcode.data, ctx->header_start,
- ctx->errcode.len);
-
- continue;
- }
-
- /* ignore other headers */
-
- continue;
- }
-
- if (rc == NGX_DONE) {
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
- "mail auth http header done");
-
- ngx_close_connection(ctx->peer.connection);
-
- if (ctx->err.len) {
-
- ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
- "client login failed: \"%V\"", &ctx->errmsg);
-
- if (s->protocol == NGX_MAIL_SMTP_PROTOCOL) {
-
- if (ctx->errcode.len == 0) {
- ctx->errcode = ngx_mail_smtp_errcode;
- }
-
- ctx->err.len = ctx->errcode.len + ctx->errmsg.len
- + sizeof(" " CRLF) - 1;
-
- p = ngx_pnalloc(s->connection->pool, ctx->err.len);
- if (p == NULL) {
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- ctx->err.data = p;
-
- p = ngx_cpymem(p, ctx->errcode.data, ctx->errcode.len);
- *p++ = ' ';
- p = ngx_cpymem(p, ctx->errmsg.data, ctx->errmsg.len);
- *p++ = CR; *p = LF;
- }
-
- s->out = ctx->err;
- timer = ctx->sleep;
-
- ngx_destroy_pool(ctx->pool);
-
- if (timer == 0) {
- s->quit = 1;
- ngx_mail_send(s->connection->write);
- return;
- }
-
- ngx_add_timer(s->connection->read, (ngx_msec_t) (timer * 1000));
-
- s->connection->read->handler = ngx_mail_auth_sleep_handler;
-
- return;
- }
-
- if (s->auth_wait) {
- timer = ctx->sleep;
-
- ngx_destroy_pool(ctx->pool);
-
- if (timer == 0) {
- ngx_mail_auth_http_init(s);
- return;
- }
-
- ngx_add_timer(s->connection->read, (ngx_msec_t) (timer * 1000));
-
- s->connection->read->handler = ngx_mail_auth_sleep_handler;
-
- return;
- }
-
- if (ctx->addr.len == 0 || ctx->port.len == 0) {
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
- "auth http server %V did not send server or port",
- ctx->peer.name);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- if (s->passwd.data == NULL
- && s->protocol != NGX_MAIL_SMTP_PROTOCOL)
- {
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
- "auth http server %V did not send password",
- ctx->peer.name);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- peer = ngx_pcalloc(s->connection->pool, sizeof(ngx_addr_t));
- if (peer == NULL) {
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- rc = ngx_parse_addr(s->connection->pool, peer,
- ctx->addr.data, ctx->addr.len);
-
- switch (rc) {
- case NGX_OK:
- break;
-
- case NGX_DECLINED:
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
- "auth http server %V sent invalid server "
- "address:\"%V\"",
- ctx->peer.name, &ctx->addr);
- /* fall through */
-
- default:
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- port = ngx_atoi(ctx->port.data, ctx->port.len);
- if (port == NGX_ERROR || port < 1 || port > 65535) {
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
- "auth http server %V sent invalid server "
- "port:\"%V\"",
- ctx->peer.name, &ctx->port);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- switch (peer->sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) peer->sockaddr;
- sin6->sin6_port = htons((in_port_t) port);
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) peer->sockaddr;
- sin->sin_port = htons((in_port_t) port);
- break;
- }
-
- len = ctx->addr.len + 1 + ctx->port.len;
-
- peer->name.len = len;
-
- peer->name.data = ngx_pnalloc(s->connection->pool, len);
- if (peer->name.data == NULL) {
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- len = ctx->addr.len;
-
- ngx_memcpy(peer->name.data, ctx->addr.data, len);
-
- peer->name.data[len++] = ':';
-
- ngx_memcpy(peer->name.data + len, ctx->port.data, ctx->port.len);
-
- ngx_destroy_pool(ctx->pool);
- ngx_mail_proxy_init(s, peer);
-
- return;
- }
-
- if (rc == NGX_AGAIN ) {
- return;
- }
-
- /* rc == NGX_ERROR */
-
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
- "auth http server %V sent invalid header in response",
- ctx->peer.name);
- ngx_close_connection(ctx->peer.connection);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
-
- return;
- }
-}
-
-
-static void
-ngx_mail_auth_sleep_handler(ngx_event_t *rev)
-{
- ngx_connection_t *c;
- ngx_mail_session_t *s;
- ngx_mail_core_srv_conf_t *cscf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail auth sleep handler");
-
- c = rev->data;
- s = c->data;
-
- if (rev->timedout) {
-
- rev->timedout = 0;
-
- if (s->auth_wait) {
- s->auth_wait = 0;
- ngx_mail_auth_http_init(s);
- return;
- }
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- rev->handler = cscf->protocol->auth_state;
-
- s->mail_state = 0;
- s->auth_method = NGX_MAIL_AUTH_PLAIN;
-
- c->log->action = "in auth state";
-
- ngx_mail_send(c->write);
-
- if (c->destroyed) {
- return;
- }
-
- ngx_add_timer(rev, cscf->timeout);
-
- if (rev->ready) {
- rev->handler(rev);
- return;
- }
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- ngx_mail_close_connection(c);
- }
-
- return;
- }
-
- if (rev->active) {
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- ngx_mail_close_connection(c);
- }
- }
-}
-
-
-static ngx_int_t
-ngx_mail_auth_http_parse_header_line(ngx_mail_session_t *s,
- ngx_mail_auth_http_ctx_t *ctx)
-{
- u_char c, ch, *p;
- enum {
- sw_start = 0,
- sw_name,
- sw_space_before_value,
- sw_value,
- sw_space_after_value,
- sw_almost_done,
- sw_header_almost_done
- } state;
-
- state = ctx->state;
-
- for (p = ctx->response->pos; p < ctx->response->last; p++) {
- ch = *p;
-
- switch (state) {
-
- /* first char */
- case sw_start:
-
- switch (ch) {
- case CR:
- ctx->header_end = p;
- state = sw_header_almost_done;
- break;
- case LF:
- ctx->header_end = p;
- goto header_done;
- default:
- state = sw_name;
- ctx->header_name_start = p;
-
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'z') {
- break;
- }
-
- if (ch >= '0' && ch <= '9') {
- break;
- }
-
- return NGX_ERROR;
- }
- break;
-
- /* header name */
- case sw_name:
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'z') {
- break;
- }
-
- if (ch == ':') {
- ctx->header_name_end = p;
- state = sw_space_before_value;
- break;
- }
-
- if (ch == '-') {
- break;
- }
-
- if (ch >= '0' && ch <= '9') {
- break;
- }
-
- if (ch == CR) {
- ctx->header_name_end = p;
- ctx->header_start = p;
- ctx->header_end = p;
- state = sw_almost_done;
- break;
- }
-
- if (ch == LF) {
- ctx->header_name_end = p;
- ctx->header_start = p;
- ctx->header_end = p;
- goto done;
- }
-
- return NGX_ERROR;
-
- /* space* before header value */
- case sw_space_before_value:
- switch (ch) {
- case ' ':
- break;
- case CR:
- ctx->header_start = p;
- ctx->header_end = p;
- state = sw_almost_done;
- break;
- case LF:
- ctx->header_start = p;
- ctx->header_end = p;
- goto done;
- default:
- ctx->header_start = p;
- state = sw_value;
- break;
- }
- break;
-
- /* header value */
- case sw_value:
- switch (ch) {
- case ' ':
- ctx->header_end = p;
- state = sw_space_after_value;
- break;
- case CR:
- ctx->header_end = p;
- state = sw_almost_done;
- break;
- case LF:
- ctx->header_end = p;
- goto done;
- }
- break;
-
- /* space* before end of header line */
- case sw_space_after_value:
- switch (ch) {
- case ' ':
- break;
- case CR:
- state = sw_almost_done;
- break;
- case LF:
- goto done;
- default:
- state = sw_value;
- break;
- }
- break;
-
- /* end of header line */
- case sw_almost_done:
- switch (ch) {
- case LF:
- goto done;
- default:
- return NGX_ERROR;
- }
-
- /* end of header */
- case sw_header_almost_done:
- switch (ch) {
- case LF:
- goto header_done;
- default:
- return NGX_ERROR;
- }
- }
- }
-
- ctx->response->pos = p;
- ctx->state = state;
-
- return NGX_AGAIN;
-
-done:
-
- ctx->response->pos = p + 1;
- ctx->state = sw_start;
-
- return NGX_OK;
-
-header_done:
-
- ctx->response->pos = p + 1;
- ctx->state = sw_start;
-
- return NGX_DONE;
-}
-
-
-static void
-ngx_mail_auth_http_block_read(ngx_event_t *rev)
-{
- ngx_connection_t *c;
- ngx_mail_session_t *s;
- ngx_mail_auth_http_ctx_t *ctx;
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
- "mail auth http block read");
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- c = rev->data;
- s = c->data;
-
- ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module);
-
- ngx_close_connection(ctx->peer.connection);
- ngx_destroy_pool(ctx->pool);
- ngx_mail_session_internal_server_error(s);
- }
-}
-
-
-static void
-ngx_mail_auth_http_dummy_handler(ngx_event_t *ev)
-{
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, ev->log, 0,
- "mail auth http dummy handler");
-}
-
-
-static ngx_buf_t *
-ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
- ngx_mail_auth_http_conf_t *ahcf)
-{
- size_t len;
- ngx_buf_t *b;
- ngx_str_t login, passwd;
- ngx_mail_core_srv_conf_t *cscf;
-
- if (ngx_mail_auth_http_escape(pool, &s->login, &login) != NGX_OK) {
- return NULL;
- }
-
- if (ngx_mail_auth_http_escape(pool, &s->passwd, &passwd) != NGX_OK) {
- return NULL;
- }
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- len = sizeof("GET ") - 1 + ahcf->uri.len + sizeof(" HTTP/1.0" CRLF) - 1
- + sizeof("Host: ") - 1 + ahcf->host_header.len + sizeof(CRLF) - 1
- + sizeof("Auth-Method: ") - 1
- + ngx_mail_auth_http_method[s->auth_method].len
- + sizeof(CRLF) - 1
- + sizeof("Auth-User: ") - 1 + login.len + sizeof(CRLF) - 1
- + sizeof("Auth-Pass: ") - 1 + passwd.len + sizeof(CRLF) - 1
- + sizeof("Auth-Salt: ") - 1 + s->salt.len
- + sizeof("Auth-Protocol: ") - 1 + cscf->protocol->name.len
- + sizeof(CRLF) - 1
- + sizeof("Auth-Login-Attempt: ") - 1 + NGX_INT_T_LEN
- + sizeof(CRLF) - 1
- + sizeof("Client-IP: ") - 1 + s->connection->addr_text.len
- + sizeof(CRLF) - 1
- + sizeof("Client-Host: ") - 1 + s->host.len + sizeof(CRLF) - 1
- + sizeof("Auth-SMTP-Helo: ") - 1 + s->smtp_helo.len
- + sizeof("Auth-SMTP-From: ") - 1 + s->smtp_from.len
- + sizeof("Auth-SMTP-To: ") - 1 + s->smtp_to.len
- + ahcf->header.len
- + sizeof(CRLF) - 1;
-
- b = ngx_create_temp_buf(pool, len);
- if (b == NULL) {
- return NULL;
- }
-
- b->last = ngx_cpymem(b->last, "GET ", sizeof("GET ") - 1);
- b->last = ngx_copy(b->last, ahcf->uri.data, ahcf->uri.len);
- b->last = ngx_cpymem(b->last, " HTTP/1.0" CRLF,
- sizeof(" HTTP/1.0" CRLF) - 1);
-
- b->last = ngx_cpymem(b->last, "Host: ", sizeof("Host: ") - 1);
- b->last = ngx_copy(b->last, ahcf->host_header.data,
- ahcf->host_header.len);
- *b->last++ = CR; *b->last++ = LF;
-
- b->last = ngx_cpymem(b->last, "Auth-Method: ",
- sizeof("Auth-Method: ") - 1);
- b->last = ngx_cpymem(b->last,
- ngx_mail_auth_http_method[s->auth_method].data,
- ngx_mail_auth_http_method[s->auth_method].len);
- *b->last++ = CR; *b->last++ = LF;
-
- b->last = ngx_cpymem(b->last, "Auth-User: ", sizeof("Auth-User: ") - 1);
- b->last = ngx_copy(b->last, login.data, login.len);
- *b->last++ = CR; *b->last++ = LF;
-
- b->last = ngx_cpymem(b->last, "Auth-Pass: ", sizeof("Auth-Pass: ") - 1);
- b->last = ngx_copy(b->last, passwd.data, passwd.len);
- *b->last++ = CR; *b->last++ = LF;
-
- if (s->auth_method != NGX_MAIL_AUTH_PLAIN && s->salt.len) {
- b->last = ngx_cpymem(b->last, "Auth-Salt: ", sizeof("Auth-Salt: ") - 1);
- b->last = ngx_copy(b->last, s->salt.data, s->salt.len);
-
- s->passwd.data = NULL;
- }
-
- b->last = ngx_cpymem(b->last, "Auth-Protocol: ",
- sizeof("Auth-Protocol: ") - 1);
- b->last = ngx_cpymem(b->last, cscf->protocol->name.data,
- cscf->protocol->name.len);
- *b->last++ = CR; *b->last++ = LF;
-
- b->last = ngx_sprintf(b->last, "Auth-Login-Attempt: %ui" CRLF,
- s->login_attempt);
-
- b->last = ngx_cpymem(b->last, "Client-IP: ", sizeof("Client-IP: ") - 1);
- b->last = ngx_copy(b->last, s->connection->addr_text.data,
- s->connection->addr_text.len);
- *b->last++ = CR; *b->last++ = LF;
-
- if (s->host.len) {
- b->last = ngx_cpymem(b->last, "Client-Host: ",
- sizeof("Client-Host: ") - 1);
- b->last = ngx_copy(b->last, s->host.data, s->host.len);
- *b->last++ = CR; *b->last++ = LF;
- }
-
- if (s->auth_method == NGX_MAIL_AUTH_NONE) {
-
- /* HELO, MAIL FROM, and RCPT TO can't contain CRLF, no need to escape */
-
- b->last = ngx_cpymem(b->last, "Auth-SMTP-Helo: ",
- sizeof("Auth-SMTP-Helo: ") - 1);
- b->last = ngx_copy(b->last, s->smtp_helo.data, s->smtp_helo.len);
- *b->last++ = CR; *b->last++ = LF;
-
- b->last = ngx_cpymem(b->last, "Auth-SMTP-From: ",
- sizeof("Auth-SMTP-From: ") - 1);
- b->last = ngx_copy(b->last, s->smtp_from.data, s->smtp_from.len);
- *b->last++ = CR; *b->last++ = LF;
-
- b->last = ngx_cpymem(b->last, "Auth-SMTP-To: ",
- sizeof("Auth-SMTP-To: ") - 1);
- b->last = ngx_copy(b->last, s->smtp_to.data, s->smtp_to.len);
- *b->last++ = CR; *b->last++ = LF;
-
- }
-
- if (ahcf->header.len) {
- b->last = ngx_copy(b->last, ahcf->header.data, ahcf->header.len);
- }
-
- /* add "\r\n" at the header end */
- *b->last++ = CR; *b->last++ = LF;
-
-#if (NGX_DEBUG_MAIL_PASSWD)
- {
- ngx_str_t l;
-
- l.len = b->last - b->pos;
- l.data = b->pos;
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
- "mail auth http header:\n\"%V\"", &l);
- }
-#endif
-
- return b;
-}
-
-
-static ngx_int_t
-ngx_mail_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text, ngx_str_t *escaped)
-{
- u_char *p;
- uintptr_t n;
-
- n = ngx_escape_uri(NULL, text->data, text->len, NGX_ESCAPE_MAIL_AUTH);
-
- if (n == 0) {
- *escaped = *text;
- return NGX_OK;
- }
-
- escaped->len = text->len + n * 2;
-
- p = ngx_pnalloc(pool, escaped->len);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- (void) ngx_escape_uri(p, text->data, text->len, NGX_ESCAPE_MAIL_AUTH);
-
- escaped->data = p;
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_mail_auth_http_create_conf(ngx_conf_t *cf)
-{
- ngx_mail_auth_http_conf_t *ahcf;
-
- ahcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_auth_http_conf_t));
- if (ahcf == NULL) {
- return NULL;
- }
-
- ahcf->timeout = NGX_CONF_UNSET_MSEC;
-
- ahcf->file = cf->conf_file->file.name.data;
- ahcf->line = cf->conf_file->line;
-
- return ahcf;
-}
-
-
-static char *
-ngx_mail_auth_http_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_mail_auth_http_conf_t *prev = parent;
- ngx_mail_auth_http_conf_t *conf = child;
-
- u_char *p;
- size_t len;
- ngx_uint_t i;
- ngx_table_elt_t *header;
-
- if (conf->peer == NULL) {
- conf->peer = prev->peer;
- conf->host_header = prev->host_header;
- conf->uri = prev->uri;
-
- if (conf->peer == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"auth_http\" is defined for server in %s:%ui",
- conf->file, conf->line);
-
- return NGX_CONF_ERROR;
- }
- }
-
- ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
-
- if (conf->headers == NULL) {
- conf->headers = prev->headers;
- conf->header = prev->header;
- }
-
- if (conf->headers && conf->header.len == 0) {
- len = 0;
- header = conf->headers->elts;
- for (i = 0; i < conf->headers->nelts; i++) {
- len += header[i].key.len + 2 + header[i].value.len + 2;
- }
-
- p = ngx_pnalloc(cf->pool, len);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->header.len = len;
- conf->header.data = p;
-
- for (i = 0; i < conf->headers->nelts; i++) {
- p = ngx_cpymem(p, header[i].key.data, header[i].key.len);
- *p++ = ':'; *p++ = ' ';
- p = ngx_cpymem(p, header[i].value.data, header[i].value.len);
- *p++ = CR; *p++ = LF;
- }
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_mail_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_mail_auth_http_conf_t *ahcf = conf;
-
- ngx_str_t *value;
- ngx_url_t u;
-
- value = cf->args->elts;
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- u.url = value[1];
- u.default_port = 80;
- u.uri_part = 1;
-
- if (ngx_strncmp(u.url.data, "http://", 7) == 0) {
- u.url.len -= 7;
- u.url.data += 7;
- }
-
- if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
- if (u.err) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "%s in auth_http \"%V\"", u.err, &u.url);
- }
-
- return NGX_CONF_ERROR;
- }
-
- ahcf->peer = u.addrs;
-
- if (u.family != AF_UNIX) {
- ahcf->host_header = u.host;
-
- } else {
- ngx_str_set(&ahcf->host_header, "localhost");
- }
-
- ahcf->uri = u.uri;
-
- if (ahcf->uri.len == 0) {
- ngx_str_set(&ahcf->uri, "/");
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_mail_auth_http_header(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_mail_auth_http_conf_t *ahcf = conf;
-
- ngx_str_t *value;
- ngx_table_elt_t *header;
-
- if (ahcf->headers == NULL) {
- ahcf->headers = ngx_array_create(cf->pool, 1, sizeof(ngx_table_elt_t));
- if (ahcf->headers == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- header = ngx_array_push(ahcf->headers);
- if (header == NULL) {
- return NGX_CONF_ERROR;
- }
-
- value = cf->args->elts;
-
- header->key = value[1];
- header->value = value[2];
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_core_module.c b/usr.sbin/nginx/src/mail/ngx_mail_core_module.c
deleted file mode 100644
index 4ee7c8dc3d7..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_core_module.c
+++ /dev/null
@@ -1,653 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_mail.h>
-
-
-static void *ngx_mail_core_create_main_conf(ngx_conf_t *cf);
-static void *ngx_mail_core_create_srv_conf(ngx_conf_t *cf);
-static char *ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static char *ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_mail_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_conf_deprecated_t ngx_conf_deprecated_so_keepalive = {
- ngx_conf_deprecated, "so_keepalive",
- "so_keepalive\" parameter of the \"listen"
-};
-
-
-static ngx_command_t ngx_mail_core_commands[] = {
-
- { ngx_string("server"),
- NGX_MAIL_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
- ngx_mail_core_server,
- 0,
- 0,
- NULL },
-
- { ngx_string("listen"),
- NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12,
- ngx_mail_core_listen,
- NGX_MAIL_SRV_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("protocol"),
- NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_mail_core_protocol,
- NGX_MAIL_SRV_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("so_keepalive"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_core_srv_conf_t, so_keepalive),
- &ngx_conf_deprecated_so_keepalive },
-
- { ngx_string("timeout"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_core_srv_conf_t, timeout),
- NULL },
-
- { ngx_string("server_name"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_core_srv_conf_t, server_name),
- NULL },
-
- { ngx_string("resolver"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
- ngx_mail_core_resolver,
- NGX_MAIL_SRV_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("resolver_timeout"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_core_srv_conf_t, resolver_timeout),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_mail_module_t ngx_mail_core_module_ctx = {
- NULL, /* protocol */
-
- ngx_mail_core_create_main_conf, /* create main configuration */
- NULL, /* init main configuration */
-
- ngx_mail_core_create_srv_conf, /* create server configuration */
- ngx_mail_core_merge_srv_conf /* merge server configuration */
-};
-
-
-ngx_module_t ngx_mail_core_module = {
- NGX_MODULE_V1,
- &ngx_mail_core_module_ctx, /* module context */
- ngx_mail_core_commands, /* module directives */
- NGX_MAIL_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static void *
-ngx_mail_core_create_main_conf(ngx_conf_t *cf)
-{
- ngx_mail_core_main_conf_t *cmcf;
-
- cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_main_conf_t));
- if (cmcf == NULL) {
- return NULL;
- }
-
- if (ngx_array_init(&cmcf->servers, cf->pool, 4,
- sizeof(ngx_mail_core_srv_conf_t *))
- != NGX_OK)
- {
- return NULL;
- }
-
- if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t))
- != NGX_OK)
- {
- return NULL;
- }
-
- return cmcf;
-}
-
-
-static void *
-ngx_mail_core_create_srv_conf(ngx_conf_t *cf)
-{
- ngx_mail_core_srv_conf_t *cscf;
-
- cscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_srv_conf_t));
- if (cscf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * cscf->protocol = NULL;
- */
-
- cscf->timeout = NGX_CONF_UNSET_MSEC;
- cscf->resolver_timeout = NGX_CONF_UNSET_MSEC;
- cscf->so_keepalive = NGX_CONF_UNSET;
-
- cscf->resolver = NGX_CONF_UNSET_PTR;
-
- cscf->file_name = cf->conf_file->file.name.data;
- cscf->line = cf->conf_file->line;
-
- return cscf;
-}
-
-
-static char *
-ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_mail_core_srv_conf_t *prev = parent;
- ngx_mail_core_srv_conf_t *conf = child;
-
- ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
- ngx_conf_merge_msec_value(conf->resolver_timeout, prev->resolver_timeout,
- 30000);
-
- ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0);
-
-
- ngx_conf_merge_str_value(conf->server_name, prev->server_name, "");
-
- if (conf->server_name.len == 0) {
- conf->server_name = cf->cycle->hostname;
- }
-
- if (conf->protocol == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "unknown mail protocol for server in %s:%ui",
- conf->file_name, conf->line);
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_ptr_value(conf->resolver, prev->resolver, NULL);
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *rv;
- void *mconf;
- ngx_uint_t m;
- ngx_conf_t pcf;
- ngx_mail_module_t *module;
- ngx_mail_conf_ctx_t *ctx, *mail_ctx;
- ngx_mail_core_srv_conf_t *cscf, **cscfp;
- ngx_mail_core_main_conf_t *cmcf;
-
- ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- mail_ctx = cf->ctx;
- ctx->main_conf = mail_ctx->main_conf;
-
- /* the server{}'s srv_conf */
-
- ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_mail_max_module);
- if (ctx->srv_conf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
- continue;
- }
-
- module = ngx_modules[m]->ctx;
-
- if (module->create_srv_conf) {
- mconf = module->create_srv_conf(cf);
- if (mconf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf;
- }
- }
-
- /* the server configuration context */
-
- cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index];
- cscf->ctx = ctx;
-
- cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index];
-
- cscfp = ngx_array_push(&cmcf->servers);
- if (cscfp == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *cscfp = cscf;
-
-
- /* parse inside server{} */
-
- pcf = *cf;
- cf->ctx = ctx;
- cf->cmd_type = NGX_MAIL_SRV_CONF;
-
- rv = ngx_conf_parse(cf, NULL);
-
- *cf = pcf;
-
- return rv;
-}
-
-
-static char *
-ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_mail_core_srv_conf_t *cscf = conf;
-
- size_t len, off;
- in_port_t port;
- ngx_str_t *value;
- ngx_url_t u;
- ngx_uint_t i, m;
- struct sockaddr *sa;
- ngx_mail_listen_t *ls;
- ngx_mail_module_t *module;
- struct sockaddr_in *sin;
- ngx_mail_core_main_conf_t *cmcf;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
-#endif
-
- value = cf->args->elts;
-
- ngx_memzero(&u, sizeof(ngx_url_t));
-
- u.url = value[1];
- u.listen = 1;
-
- 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",
- u.err, &u.url);
- }
-
- return NGX_CONF_ERROR;
- }
-
- cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module);
-
- ls = cmcf->listen.elts;
-
- for (i = 0; i < cmcf->listen.nelts; i++) {
-
- sa = (struct sockaddr *) ls[i].sockaddr;
-
- if (sa->sa_family != u.family) {
- continue;
- }
-
- switch (sa->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- off = offsetof(struct sockaddr_in6, sin6_addr);
- len = 16;
- sin6 = (struct sockaddr_in6 *) sa;
- port = sin6->sin6_port;
- break;
-#endif
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- case AF_UNIX:
- off = offsetof(struct sockaddr_un, sun_path);
- len = sizeof(((struct sockaddr_un *) sa)->sun_path);
- port = 0;
- break;
-#endif
-
- default: /* AF_INET */
- off = offsetof(struct sockaddr_in, sin_addr);
- len = 4;
- sin = (struct sockaddr_in *) sa;
- port = sin->sin_port;
- break;
- }
-
- if (ngx_memcmp(ls[i].sockaddr + off, u.sockaddr + off, len) != 0) {
- continue;
- }
-
- if (port != u.port) {
- continue;
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "duplicate \"%V\" address and port pair", &u.url);
- return NGX_CONF_ERROR;
- }
-
- ls = ngx_array_push(&cmcf->listen);
- if (ls == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(ls, sizeof(ngx_mail_listen_t));
-
- ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen);
-
- ls->socklen = u.socklen;
- ls->wildcard = u.wildcard;
- ls->ctx = cf->ctx;
-
-#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- ls->ipv6only = 1;
-#endif
-
- if (cscf->protocol == NULL) {
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
- continue;
- }
-
- module = ngx_modules[m]->ctx;
-
- if (module->protocol == NULL) {
- continue;
- }
-
- for (i = 0; module->protocol->port[i]; i++) {
- if (module->protocol->port[i] == u.port) {
- cscf->protocol = module->protocol;
- break;
- }
- }
- }
- }
-
- for (i = 2; i < cf->args->nelts; i++) {
-
- if (ngx_strcmp(value[i].data, "bind") == 0) {
- ls->bind = 1;
- continue;
- }
-
- if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) {
-#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
- struct sockaddr *sa;
- u_char buf[NGX_SOCKADDR_STRLEN];
-
- sa = (struct sockaddr *) ls->sockaddr;
-
- if (sa->sa_family == AF_INET6) {
-
- if (ngx_strcmp(&value[i].data[10], "n") == 0) {
- ls->ipv6only = 1;
-
- } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
- ls->ipv6only = 0;
-
- } else {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid ipv6only flags \"%s\"",
- &value[i].data[9]);
- return NGX_CONF_ERROR;
- }
-
- ls->bind = 1;
-
- } else {
- len = ngx_sock_ntop(sa, ls->socklen, buf,
- NGX_SOCKADDR_STRLEN, 1);
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "ipv6only is not supported "
- "on addr \"%*s\", ignored", len, buf);
- }
-
- continue;
-#else
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "bind ipv6only is not supported "
- "on this platform");
- return NGX_CONF_ERROR;
-#endif
- }
-
- if (ngx_strcmp(value[i].data, "ssl") == 0) {
-#if (NGX_MAIL_SSL)
- ls->ssl = 1;
- continue;
-#else
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the \"ssl\" parameter requires "
- "ngx_mail_ssl_module");
- return NGX_CONF_ERROR;
-#endif
- }
-
- if (ngx_strncmp(value[i].data, "so_keepalive=", 13) == 0) {
-
- if (ngx_strcmp(&value[i].data[13], "on") == 0) {
- ls->so_keepalive = 1;
-
- } else if (ngx_strcmp(&value[i].data[13], "off") == 0) {
- ls->so_keepalive = 2;
-
- } else {
-
-#if (NGX_HAVE_KEEPALIVE_TUNABLE)
- u_char *p, *end;
- ngx_str_t s;
-
- end = value[i].data + value[i].len;
- s.data = value[i].data + 13;
-
- p = ngx_strlchr(s.data, end, ':');
- if (p == NULL) {
- p = end;
- }
-
- if (p > s.data) {
- s.len = p - s.data;
-
- ls->tcp_keepidle = ngx_parse_time(&s, 1);
- if (ls->tcp_keepidle == (time_t) NGX_ERROR) {
- goto invalid_so_keepalive;
- }
- }
-
- s.data = (p < end) ? (p + 1) : end;
-
- p = ngx_strlchr(s.data, end, ':');
- if (p == NULL) {
- p = end;
- }
-
- if (p > s.data) {
- s.len = p - s.data;
-
- ls->tcp_keepintvl = ngx_parse_time(&s, 1);
- if (ls->tcp_keepintvl == (time_t) NGX_ERROR) {
- goto invalid_so_keepalive;
- }
- }
-
- s.data = (p < end) ? (p + 1) : end;
-
- if (s.data < end) {
- s.len = end - s.data;
-
- ls->tcp_keepcnt = ngx_atoi(s.data, s.len);
- if (ls->tcp_keepcnt == NGX_ERROR) {
- goto invalid_so_keepalive;
- }
- }
-
- if (ls->tcp_keepidle == 0 && ls->tcp_keepintvl == 0
- && ls->tcp_keepcnt == 0)
- {
- goto invalid_so_keepalive;
- }
-
- ls->so_keepalive = 1;
-
-#else
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the \"so_keepalive\" parameter accepts "
- "only \"on\" or \"off\" on this platform");
- return NGX_CONF_ERROR;
-
-#endif
- }
-
- ls->bind = 1;
-
- continue;
-
-#if (NGX_HAVE_KEEPALIVE_TUNABLE)
- invalid_so_keepalive:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid so_keepalive value: \"%s\"",
- &value[i].data[13]);
- return NGX_CONF_ERROR;
-#endif
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the invalid \"%V\" parameter", &value[i]);
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_mail_core_srv_conf_t *cscf = conf;
-
- ngx_str_t *value;
- ngx_uint_t m;
- ngx_mail_module_t *module;
-
- value = cf->args->elts;
-
- for (m = 0; ngx_modules[m]; m++) {
- if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
- continue;
- }
-
- module = ngx_modules[m]->ctx;
-
- if (module->protocol
- && ngx_strcmp(module->protocol->name.data, value[1].data) == 0)
- {
- cscf->protocol = module->protocol;
-
- return NGX_CONF_OK;
- }
- }
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "unknown protocol \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
-}
-
-
-static char *
-ngx_mail_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_mail_core_srv_conf_t *cscf = conf;
-
- ngx_str_t *value;
-
- value = cf->args->elts;
-
- if (cscf->resolver != NGX_CONF_UNSET_PTR) {
- return "is duplicate";
- }
-
- if (ngx_strcmp(value[1].data, "off") == 0) {
- cscf->resolver = NULL;
- return NGX_CONF_OK;
- }
-
- cscf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1);
- if (cscf->resolver == NULL) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-char *
-ngx_mail_capabilities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- char *p = conf;
-
- ngx_str_t *c, *value;
- ngx_uint_t i;
- ngx_array_t *a;
-
- a = (ngx_array_t *) (p + cmd->offset);
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
- c = ngx_array_push(a);
- if (c == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *c = value[i];
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_handler.c b/usr.sbin/nginx/src/mail/ngx_mail_handler.c
deleted file mode 100644
index 47ddb0dcf05..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_handler.c
+++ /dev/null
@@ -1,784 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_mail.h>
-
-
-static void ngx_mail_init_session(ngx_connection_t *c);
-
-#if (NGX_MAIL_SSL)
-static void ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c);
-static void ngx_mail_ssl_handshake_handler(ngx_connection_t *c);
-#endif
-
-
-void
-ngx_mail_init_connection(ngx_connection_t *c)
-{
- ngx_uint_t i;
- ngx_mail_port_t *port;
- struct sockaddr *sa;
- struct sockaddr_in *sin;
- ngx_mail_log_ctx_t *ctx;
- ngx_mail_in_addr_t *addr;
- ngx_mail_session_t *s;
- ngx_mail_addr_conf_t *addr_conf;
-#if (NGX_HAVE_INET6)
- struct sockaddr_in6 *sin6;
- ngx_mail_in6_addr_t *addr6;
-#endif
-
-
- /* find the server configuration for the address:port */
-
- port = c->listening->servers;
-
- if (port->naddrs > 1) {
-
- /*
- * There are several addresses on this port and one of them
- * is the "*:port" wildcard so getsockname() is needed to determine
- * the server address.
- *
- * AcceptEx() already gave this address.
- */
-
- if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
- ngx_mail_close_connection(c);
- return;
- }
-
- sa = c->local_sockaddr;
-
- switch (sa->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- sin6 = (struct sockaddr_in6 *) sa;
-
- addr6 = port->addrs;
-
- /* the last address is "*" */
-
- for (i = 0; i < port->naddrs - 1; i++) {
- if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) {
- break;
- }
- }
-
- addr_conf = &addr6[i].conf;
-
- break;
-#endif
-
- default: /* AF_INET */
- sin = (struct sockaddr_in *) sa;
-
- addr = port->addrs;
-
- /* the last address is "*" */
-
- for (i = 0; i < port->naddrs - 1; i++) {
- if (addr[i].addr == sin->sin_addr.s_addr) {
- break;
- }
- }
-
- addr_conf = &addr[i].conf;
-
- break;
- }
-
- } else {
- switch (c->local_sockaddr->sa_family) {
-
-#if (NGX_HAVE_INET6)
- case AF_INET6:
- addr6 = port->addrs;
- addr_conf = &addr6[0].conf;
- break;
-#endif
-
- default: /* AF_INET */
- addr = port->addrs;
- addr_conf = &addr[0].conf;
- break;
- }
- }
-
- s = ngx_pcalloc(c->pool, sizeof(ngx_mail_session_t));
- if (s == NULL) {
- ngx_mail_close_connection(c);
- return;
- }
-
- s->main_conf = addr_conf->ctx->main_conf;
- s->srv_conf = addr_conf->ctx->srv_conf;
-
- s->addr_text = &addr_conf->addr_text;
-
- c->data = s;
- s->connection = c;
-
- ngx_log_error(NGX_LOG_INFO, c->log, 0, "*%uA client %V connected to %V",
- c->number, &c->addr_text, s->addr_text);
-
- ctx = ngx_palloc(c->pool, sizeof(ngx_mail_log_ctx_t));
- if (ctx == NULL) {
- ngx_mail_close_connection(c);
- return;
- }
-
- ctx->client = &c->addr_text;
- ctx->session = s;
-
- c->log->connection = c->number;
- c->log->handler = ngx_mail_log_error;
- c->log->data = ctx;
- c->log->action = "sending client greeting line";
-
- c->log_error = NGX_ERROR_INFO;
-
-#if (NGX_MAIL_SSL)
- {
- ngx_mail_ssl_conf_t *sslcf;
-
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
-
- if (sslcf->enable) {
- c->log->action = "SSL handshaking";
-
- ngx_mail_ssl_init_connection(&sslcf->ssl, c);
- return;
- }
-
- if (addr_conf->ssl) {
-
- c->log->action = "SSL handshaking";
-
- if (sslcf->ssl.ctx == NULL) {
- ngx_log_error(NGX_LOG_ERR, c->log, 0,
- "no \"ssl_certificate\" is defined "
- "in server listening on SSL port");
- ngx_mail_close_connection(c);
- return;
- }
-
- ngx_mail_ssl_init_connection(&sslcf->ssl, c);
- return;
- }
-
- }
-#endif
-
- ngx_mail_init_session(c);
-}
-
-
-#if (NGX_MAIL_SSL)
-
-void
-ngx_mail_starttls_handler(ngx_event_t *rev)
-{
- ngx_connection_t *c;
- ngx_mail_session_t *s;
- ngx_mail_ssl_conf_t *sslcf;
-
- c = rev->data;
- s = c->data;
- s->starttls = 1;
-
- c->log->action = "in starttls state";
-
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
-
- ngx_mail_ssl_init_connection(&sslcf->ssl, c);
-}
-
-
-static void
-ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c)
-{
- ngx_mail_session_t *s;
- ngx_mail_core_srv_conf_t *cscf;
-
- if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) {
- ngx_mail_close_connection(c);
- return;
- }
-
- if (ngx_ssl_handshake(c) == NGX_AGAIN) {
-
- s = c->data;
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- ngx_add_timer(c->read, cscf->timeout);
-
- c->ssl->handler = ngx_mail_ssl_handshake_handler;
-
- return;
- }
-
- ngx_mail_ssl_handshake_handler(c);
-}
-
-
-static void
-ngx_mail_ssl_handshake_handler(ngx_connection_t *c)
-{
- ngx_mail_session_t *s;
- ngx_mail_core_srv_conf_t *cscf;
-
- if (c->ssl->handshaked) {
-
- s = c->data;
-
- if (s->starttls) {
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- c->read->handler = cscf->protocol->init_protocol;
- c->write->handler = ngx_mail_send;
-
- cscf->protocol->init_protocol(c->read);
-
- return;
- }
-
- c->read->ready = 0;
-
- ngx_mail_init_session(c);
- return;
- }
-
- ngx_mail_close_connection(c);
-}
-
-#endif
-
-
-static void
-ngx_mail_init_session(ngx_connection_t *c)
-{
- ngx_mail_session_t *s;
- ngx_mail_core_srv_conf_t *cscf;
-
- s = c->data;
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- s->protocol = cscf->protocol->type;
-
- s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_mail_max_module);
- if (s->ctx == NULL) {
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- c->write->handler = ngx_mail_send;
-
- cscf->protocol->init_session(s, c);
-}
-
-
-ngx_int_t
-ngx_mail_salt(ngx_mail_session_t *s, ngx_connection_t *c,
- ngx_mail_core_srv_conf_t *cscf)
-{
- s->salt.data = ngx_pnalloc(c->pool,
- sizeof(" <18446744073709551616.@>" CRLF) - 1
- + NGX_TIME_T_LEN
- + cscf->server_name.len);
- if (s->salt.data == NULL) {
- return NGX_ERROR;
- }
-
- s->salt.len = ngx_sprintf(s->salt.data, "<%ul.%T@%V>" CRLF,
- ngx_random(), ngx_time(), &cscf->server_name)
- - s->salt.data;
-
- return NGX_OK;
-}
-
-
-#if (NGX_MAIL_SSL)
-
-ngx_int_t
-ngx_mail_starttls_only(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_mail_ssl_conf_t *sslcf;
-
- if (c->ssl) {
- return 0;
- }
-
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
-
- if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
- return 1;
- }
-
- return 0;
-}
-
-#endif
-
-
-ngx_int_t
-ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n)
-{
- u_char *p, *last;
- ngx_str_t *arg, plain;
-
- arg = s->args.elts;
-
-#if (NGX_DEBUG_MAIL_PASSWD)
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "mail auth plain: \"%V\"", &arg[n]);
-#endif
-
- plain.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len));
- if (plain.data == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_decode_base64(&plain, &arg[n]) != NGX_OK) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent invalid base64 encoding in AUTH PLAIN command");
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- p = plain.data;
- last = p + plain.len;
-
- while (p < last && *p++) { /* void */ }
-
- if (p == last) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent invalid login in AUTH PLAIN command");
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- s->login.data = p;
-
- while (p < last && *p) { p++; }
-
- if (p == last) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent invalid password in AUTH PLAIN command");
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- s->login.len = p++ - s->login.data;
-
- s->passwd.len = last - p;
- s->passwd.data = p;
-
-#if (NGX_DEBUG_MAIL_PASSWD)
- ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "mail auth plain: \"%V\" \"%V\"", &s->login, &s->passwd);
-#endif
-
- return NGX_DONE;
-}
-
-
-ngx_int_t
-ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c,
- ngx_uint_t n)
-{
- ngx_str_t *arg;
-
- arg = s->args.elts;
-
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "mail auth login username: \"%V\"", &arg[n]);
-
- s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len));
- if (s->login.data == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_decode_base64(&s->login, &arg[n]) != NGX_OK) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent invalid base64 encoding in AUTH LOGIN command");
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "mail auth login username: \"%V\"", &s->login);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_mail_auth_login_password(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_str_t *arg;
-
- arg = s->args.elts;
-
-#if (NGX_DEBUG_MAIL_PASSWD)
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "mail auth login password: \"%V\"", &arg[0]);
-#endif
-
- s->passwd.data = ngx_pnalloc(c->pool,
- ngx_base64_decoded_length(arg[0].len));
- if (s->passwd.data == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_decode_base64(&s->passwd, &arg[0]) != NGX_OK) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent invalid base64 encoding in AUTH LOGIN command");
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
-#if (NGX_DEBUG_MAIL_PASSWD)
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "mail auth login password: \"%V\"", &s->passwd);
-#endif
-
- return NGX_DONE;
-}
-
-
-ngx_int_t
-ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s, ngx_connection_t *c,
- char *prefix, size_t len)
-{
- u_char *p;
- ngx_str_t salt;
- ngx_uint_t n;
-
- p = ngx_pnalloc(c->pool, len + ngx_base64_encoded_length(s->salt.len) + 2);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- salt.data = ngx_cpymem(p, prefix, len);
- s->salt.len -= 2;
-
- ngx_encode_base64(&salt, &s->salt);
-
- s->salt.len += 2;
- n = len + salt.len;
- p[n++] = CR; p[n++] = LF;
-
- s->out.len = n;
- s->out.data = p;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- u_char *p, *last;
- ngx_str_t *arg;
-
- arg = s->args.elts;
-
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "mail auth cram-md5: \"%V\"", &arg[0]);
-
- s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[0].len));
- if (s->login.data == NULL) {
- return NGX_ERROR;
- }
-
- if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent invalid base64 encoding in AUTH CRAM-MD5 command");
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- p = s->login.data;
- last = p + s->login.len;
-
- while (p < last) {
- if (*p++ == ' ') {
- s->login.len = p - s->login.data - 1;
- s->passwd.len = last - p;
- s->passwd.data = p;
- break;
- }
- }
-
- if (s->passwd.len != 32) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent invalid CRAM-MD5 hash in AUTH CRAM-MD5 command");
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "mail auth cram-md5: \"%V\" \"%V\"", &s->login, &s->passwd);
-
- s->auth_method = NGX_MAIL_AUTH_CRAM_MD5;
-
- return NGX_DONE;
-}
-
-
-void
-ngx_mail_send(ngx_event_t *wev)
-{
- ngx_int_t n;
- ngx_connection_t *c;
- ngx_mail_session_t *s;
- ngx_mail_core_srv_conf_t *cscf;
-
- c = wev->data;
- s = c->data;
-
- if (wev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
- c->timedout = 1;
- ngx_mail_close_connection(c);
- return;
- }
-
- if (s->out.len == 0) {
- if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
- ngx_mail_close_connection(c);
- }
-
- return;
- }
-
- n = c->send(c, s->out.data, s->out.len);
-
- if (n > 0) {
- s->out.data += n;
- s->out.len -= n;
-
- if (s->out.len != 0) {
- goto again;
- }
-
- if (wev->timer_set) {
- ngx_del_timer(wev);
- }
-
- if (s->quit) {
- ngx_mail_close_connection(c);
- return;
- }
-
- if (s->blocked) {
- c->read->handler(c->read);
- }
-
- return;
- }
-
- if (n == NGX_ERROR) {
- ngx_mail_close_connection(c);
- return;
- }
-
- /* n == NGX_AGAIN */
-
-again:
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- ngx_add_timer(c->write, cscf->timeout);
-
- if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
- ngx_mail_close_connection(c);
- return;
- }
-}
-
-
-ngx_int_t
-ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ssize_t n;
- ngx_int_t rc;
- ngx_str_t l;
- ngx_mail_core_srv_conf_t *cscf;
-
- n = c->recv(c, s->buffer->last, s->buffer->end - s->buffer->last);
-
- if (n == NGX_ERROR || n == 0) {
- ngx_mail_close_connection(c);
- return NGX_ERROR;
- }
-
- if (n > 0) {
- s->buffer->last += n;
- }
-
- if (n == NGX_AGAIN) {
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- ngx_mail_session_internal_server_error(s);
- return NGX_ERROR;
- }
-
- if (s->buffer->pos == s->buffer->last) {
- return NGX_AGAIN;
- }
- }
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- rc = cscf->protocol->parse_command(s);
-
- if (rc == NGX_AGAIN) {
-
- if (s->buffer->last < s->buffer->end) {
- return rc;
- }
-
- l.len = s->buffer->last - s->buffer->start;
- l.data = s->buffer->start;
-
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent too long command \"%V\"", &l);
-
- s->quit = 1;
-
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- if (rc == NGX_IMAP_NEXT || rc == NGX_MAIL_PARSE_INVALID_COMMAND) {
- return rc;
- }
-
- if (rc == NGX_ERROR) {
- ngx_mail_close_connection(c);
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-void
-ngx_mail_auth(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- s->args.nelts = 0;
-
- if (s->buffer->pos == s->buffer->last) {
- s->buffer->pos = s->buffer->start;
- s->buffer->last = s->buffer->start;
- }
-
- s->state = 0;
-
- if (c->read->timer_set) {
- ngx_del_timer(c->read);
- }
-
- s->login_attempt++;
-
- ngx_mail_auth_http_init(s);
-}
-
-
-void
-ngx_mail_session_internal_server_error(ngx_mail_session_t *s)
-{
- ngx_mail_core_srv_conf_t *cscf;
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- s->out = cscf->protocol->internal_server_error;
- s->quit = 1;
-
- ngx_mail_send(s->connection->write);
-}
-
-
-void
-ngx_mail_close_connection(ngx_connection_t *c)
-{
- ngx_pool_t *pool;
-
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "close mail connection: %d", c->fd);
-
-#if (NGX_MAIL_SSL)
-
- if (c->ssl) {
- if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
- c->ssl->handler = ngx_mail_close_connection;
- return;
- }
- }
-
-#endif
-
-#if (NGX_STAT_STUB)
- (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
-#endif
-
- c->destroyed = 1;
-
- pool = c->pool;
-
- ngx_close_connection(c);
-
- ngx_destroy_pool(pool);
-}
-
-
-u_char *
-ngx_mail_log_error(ngx_log_t *log, u_char *buf, size_t len)
-{
- u_char *p;
- ngx_mail_session_t *s;
- ngx_mail_log_ctx_t *ctx;
-
- if (log->action) {
- p = ngx_snprintf(buf, len, " while %s", log->action);
- len -= p - buf;
- buf = p;
- }
-
- ctx = log->data;
-
- p = ngx_snprintf(buf, len, ", client: %V", ctx->client);
- len -= p - buf;
- buf = p;
-
- s = ctx->session;
-
- if (s == NULL) {
- return p;
- }
-
- p = ngx_snprintf(buf, len, "%s, server: %V",
- s->starttls ? " using starttls" : "",
- s->addr_text);
- len -= p - buf;
- buf = p;
-
- if (s->login.len == 0) {
- return p;
- }
-
- p = ngx_snprintf(buf, len, ", login: \"%V\"", &s->login);
- len -= p - buf;
- buf = p;
-
- if (s->proxy == NULL) {
- return p;
- }
-
- p = ngx_snprintf(buf, len, ", upstream: %V", s->proxy->upstream.name);
-
- return p;
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_imap_handler.c b/usr.sbin/nginx/src/mail/ngx_mail_imap_handler.c
deleted file mode 100644
index 57e2fb77daa..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_imap_handler.c
+++ /dev/null
@@ -1,457 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_mail.h>
-#include <ngx_mail_imap_module.h>
-
-
-static ngx_int_t ngx_mail_imap_login(ngx_mail_session_t *s,
- ngx_connection_t *c);
-static ngx_int_t ngx_mail_imap_authenticate(ngx_mail_session_t *s,
- ngx_connection_t *c);
-static ngx_int_t ngx_mail_imap_capability(ngx_mail_session_t *s,
- ngx_connection_t *c);
-static ngx_int_t ngx_mail_imap_starttls(ngx_mail_session_t *s,
- ngx_connection_t *c);
-
-
-static u_char imap_greeting[] = "* OK IMAP4 ready" CRLF;
-static u_char imap_star[] = "* ";
-static u_char imap_ok[] = "OK completed" CRLF;
-static u_char imap_next[] = "+ OK" CRLF;
-static u_char imap_plain_next[] = "+ " CRLF;
-static u_char imap_username[] = "+ VXNlcm5hbWU6" CRLF;
-static u_char imap_password[] = "+ UGFzc3dvcmQ6" CRLF;
-static u_char imap_bye[] = "* BYE" CRLF;
-static u_char imap_invalid_command[] = "BAD invalid command" CRLF;
-
-
-void
-ngx_mail_imap_init_session(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_mail_core_srv_conf_t *cscf;
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- ngx_str_set(&s->out, imap_greeting);
-
- c->read->handler = ngx_mail_imap_init_protocol;
-
- ngx_add_timer(c->read, cscf->timeout);
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- ngx_mail_close_connection(c);
- }
-
- ngx_mail_send(c->write);
-}
-
-
-void
-ngx_mail_imap_init_protocol(ngx_event_t *rev)
-{
- ngx_connection_t *c;
- ngx_mail_session_t *s;
- ngx_mail_imap_srv_conf_t *iscf;
-
- c = rev->data;
-
- c->log->action = "in auth state";
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
- c->timedout = 1;
- ngx_mail_close_connection(c);
- return;
- }
-
- s = c->data;
-
- if (s->buffer == NULL) {
- if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t))
- == NGX_ERROR)
- {
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- iscf = ngx_mail_get_module_srv_conf(s, ngx_mail_imap_module);
-
- s->buffer = ngx_create_temp_buf(c->pool, iscf->client_buffer_size);
- if (s->buffer == NULL) {
- ngx_mail_session_internal_server_error(s);
- return;
- }
- }
-
- s->mail_state = ngx_imap_start;
- c->read->handler = ngx_mail_imap_auth_state;
-
- ngx_mail_imap_auth_state(rev);
-}
-
-
-void
-ngx_mail_imap_auth_state(ngx_event_t *rev)
-{
- u_char *p, *dst, *src, *end;
- ngx_str_t *arg;
- ngx_int_t rc;
- ngx_uint_t tag, i;
- ngx_connection_t *c;
- ngx_mail_session_t *s;
-
- c = rev->data;
- s = c->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "imap auth state");
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
- c->timedout = 1;
- ngx_mail_close_connection(c);
- return;
- }
-
- if (s->out.len) {
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "imap send handler busy");
- s->blocked = 1;
- return;
- }
-
- s->blocked = 0;
-
- rc = ngx_mail_read_command(s, c);
-
- if (rc == NGX_AGAIN || rc == NGX_ERROR) {
- return;
- }
-
- tag = 1;
- s->text.len = 0;
- ngx_str_set(&s->out, imap_ok);
-
- if (rc == NGX_OK) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "imap auth command: %i",
- s->command);
-
- if (s->backslash) {
-
- arg = s->args.elts;
-
- for (i = 0; i < s->args.nelts; i++) {
- dst = arg[i].data;
- end = dst + arg[i].len;
-
- for (src = dst; src < end; dst++) {
- *dst = *src;
- if (*src++ == '\\') {
- *dst = *src++;
- }
- }
-
- arg[i].len = dst - arg[i].data;
- }
-
- s->backslash = 0;
- }
-
- switch (s->mail_state) {
-
- case ngx_imap_start:
-
- switch (s->command) {
-
- case NGX_IMAP_LOGIN:
- rc = ngx_mail_imap_login(s, c);
- break;
-
- case NGX_IMAP_AUTHENTICATE:
- rc = ngx_mail_imap_authenticate(s, c);
- tag = (rc != NGX_OK);
- break;
-
- case NGX_IMAP_CAPABILITY:
- rc = ngx_mail_imap_capability(s, c);
- break;
-
- case NGX_IMAP_LOGOUT:
- s->quit = 1;
- ngx_str_set(&s->text, imap_bye);
- break;
-
- case NGX_IMAP_NOOP:
- break;
-
- case NGX_IMAP_STARTTLS:
- rc = ngx_mail_imap_starttls(s, c);
- break;
-
- default:
- rc = NGX_MAIL_PARSE_INVALID_COMMAND;
- break;
- }
-
- break;
-
- case ngx_imap_auth_login_username:
- rc = ngx_mail_auth_login_username(s, c, 0);
-
- tag = 0;
- ngx_str_set(&s->out, imap_password);
- s->mail_state = ngx_imap_auth_login_password;
-
- break;
-
- case ngx_imap_auth_login_password:
- rc = ngx_mail_auth_login_password(s, c);
- break;
-
- case ngx_imap_auth_plain:
- rc = ngx_mail_auth_plain(s, c, 0);
- break;
-
- case ngx_imap_auth_cram_md5:
- rc = ngx_mail_auth_cram_md5(s, c);
- break;
- }
-
- } else if (rc == NGX_IMAP_NEXT) {
- tag = 0;
- ngx_str_set(&s->out, imap_next);
- }
-
- switch (rc) {
-
- case NGX_DONE:
- ngx_mail_auth(s, c);
- return;
-
- case NGX_ERROR:
- ngx_mail_session_internal_server_error(s);
- return;
-
- case NGX_MAIL_PARSE_INVALID_COMMAND:
- s->state = 0;
- ngx_str_set(&s->out, imap_invalid_command);
- s->mail_state = ngx_imap_start;
- break;
- }
-
- if (tag) {
- if (s->tag.len == 0) {
- ngx_str_set(&s->tag, imap_star);
- }
-
- if (s->tagged_line.len < s->tag.len + s->text.len + s->out.len) {
- s->tagged_line.len = s->tag.len + s->text.len + s->out.len;
- s->tagged_line.data = ngx_pnalloc(c->pool, s->tagged_line.len);
- if (s->tagged_line.data == NULL) {
- ngx_mail_close_connection(c);
- return;
- }
- }
-
- p = s->tagged_line.data;
-
- if (s->text.len) {
- p = ngx_cpymem(p, s->text.data, s->text.len);
- }
-
- p = ngx_cpymem(p, s->tag.data, s->tag.len);
- ngx_memcpy(p, s->out.data, s->out.len);
-
- s->out.len = s->text.len + s->tag.len + s->out.len;
- s->out.data = s->tagged_line.data;
- }
-
- if (rc != NGX_IMAP_NEXT) {
- s->args.nelts = 0;
-
- if (s->state) {
- /* preserve tag */
- s->arg_start = s->buffer->start + s->tag.len;
- s->buffer->pos = s->arg_start;
- s->buffer->last = s->arg_start;
-
- } else {
- s->buffer->pos = s->buffer->start;
- s->buffer->last = s->buffer->start;
- s->tag.len = 0;
- }
- }
-
- ngx_mail_send(c->write);
-}
-
-
-static ngx_int_t
-ngx_mail_imap_login(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_str_t *arg;
-
-#if (NGX_MAIL_SSL)
- if (ngx_mail_starttls_only(s, c)) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-#endif
-
- arg = s->args.elts;
-
- if (s->args.nelts != 2 || arg[0].len == 0) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- s->login.len = arg[0].len;
- s->login.data = ngx_pnalloc(c->pool, s->login.len);
- if (s->login.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(s->login.data, arg[0].data, s->login.len);
-
- s->passwd.len = arg[1].len;
- s->passwd.data = ngx_pnalloc(c->pool, s->passwd.len);
- if (s->passwd.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(s->passwd.data, arg[1].data, s->passwd.len);
-
-#if (NGX_DEBUG_MAIL_PASSWD)
- ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "imap login:\"%V\" passwd:\"%V\"",
- &s->login, &s->passwd);
-#else
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "imap login:\"%V\"", &s->login);
-#endif
-
- return NGX_DONE;
-}
-
-
-static ngx_int_t
-ngx_mail_imap_authenticate(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_int_t rc;
- ngx_mail_core_srv_conf_t *cscf;
- ngx_mail_imap_srv_conf_t *iscf;
-
-#if (NGX_MAIL_SSL)
- if (ngx_mail_starttls_only(s, c)) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-#endif
-
- rc = ngx_mail_auth_parse(s, c);
-
- switch (rc) {
-
- case NGX_MAIL_AUTH_LOGIN:
-
- ngx_str_set(&s->out, imap_username);
- s->mail_state = ngx_imap_auth_login_username;
-
- return NGX_OK;
-
- case NGX_MAIL_AUTH_LOGIN_USERNAME:
-
- ngx_str_set(&s->out, imap_password);
- s->mail_state = ngx_imap_auth_login_password;
-
- return ngx_mail_auth_login_username(s, c, 1);
-
- case NGX_MAIL_AUTH_PLAIN:
-
- ngx_str_set(&s->out, imap_plain_next);
- s->mail_state = ngx_imap_auth_plain;
-
- return NGX_OK;
-
- case NGX_MAIL_AUTH_CRAM_MD5:
-
- iscf = ngx_mail_get_module_srv_conf(s, ngx_mail_imap_module);
-
- if (!(iscf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- if (s->salt.data == NULL) {
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- if (ngx_mail_salt(s, c, cscf) != NGX_OK) {
- return NGX_ERROR;
- }
- }
-
- if (ngx_mail_auth_cram_md5_salt(s, c, "+ ", 2) == NGX_OK) {
- s->mail_state = ngx_imap_auth_cram_md5;
- return NGX_OK;
- }
-
- return NGX_ERROR;
- }
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_mail_imap_capability(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_mail_imap_srv_conf_t *iscf;
-
- iscf = ngx_mail_get_module_srv_conf(s, ngx_mail_imap_module);
-
-#if (NGX_MAIL_SSL)
-
- if (c->ssl == NULL) {
- ngx_mail_ssl_conf_t *sslcf;
-
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
-
- if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) {
- s->text = iscf->starttls_capability;
- return NGX_OK;
- }
-
- if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
- s->text = iscf->starttls_only_capability;
- return NGX_OK;
- }
- }
-#endif
-
- s->text = iscf->capability;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_mail_imap_starttls(ngx_mail_session_t *s, ngx_connection_t *c)
-{
-#if (NGX_MAIL_SSL)
- ngx_mail_ssl_conf_t *sslcf;
-
- if (c->ssl == NULL) {
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
- if (sslcf->starttls) {
- c->read->handler = ngx_mail_starttls_handler;
- return NGX_OK;
- }
- }
-
-#endif
-
- return NGX_MAIL_PARSE_INVALID_COMMAND;
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_imap_module.c b/usr.sbin/nginx/src/mail/ngx_mail_imap_module.c
deleted file mode 100644
index dc80b4fb4c1..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_imap_module.c
+++ /dev/null
@@ -1,253 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_mail.h>
-#include <ngx_mail_imap_module.h>
-
-
-static void *ngx_mail_imap_create_srv_conf(ngx_conf_t *cf);
-static char *ngx_mail_imap_merge_srv_conf(ngx_conf_t *cf, void *parent,
- void *child);
-
-
-static ngx_str_t ngx_mail_imap_default_capabilities[] = {
- ngx_string("IMAP4"),
- ngx_string("IMAP4rev1"),
- ngx_string("UIDPLUS"),
- ngx_null_string
-};
-
-
-static ngx_conf_bitmask_t ngx_mail_imap_auth_methods[] = {
- { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
- { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED },
- { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_str_t ngx_mail_imap_auth_methods_names[] = {
- ngx_string("AUTH=PLAIN"),
- ngx_string("AUTH=LOGIN"),
- ngx_null_string, /* APOP */
- ngx_string("AUTH=CRAM-MD5"),
- ngx_null_string /* NONE */
-};
-
-
-static ngx_mail_protocol_t ngx_mail_imap_protocol = {
- ngx_string("imap"),
- { 143, 993, 0, 0 },
- NGX_MAIL_IMAP_PROTOCOL,
-
- ngx_mail_imap_init_session,
- ngx_mail_imap_init_protocol,
- ngx_mail_imap_parse_command,
- ngx_mail_imap_auth_state,
-
- ngx_string("* BAD internal server error" CRLF)
-};
-
-
-static ngx_command_t ngx_mail_imap_commands[] = {
-
- { ngx_string("imap_client_buffer"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_imap_srv_conf_t, client_buffer_size),
- NULL },
-
- { ngx_string("imap_capabilities"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
- ngx_mail_capabilities,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_imap_srv_conf_t, capabilities),
- NULL },
-
- { ngx_string("imap_auth"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_imap_srv_conf_t, auth_methods),
- &ngx_mail_imap_auth_methods },
-
- ngx_null_command
-};
-
-
-static ngx_mail_module_t ngx_mail_imap_module_ctx = {
- &ngx_mail_imap_protocol, /* protocol */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- ngx_mail_imap_create_srv_conf, /* create server configuration */
- ngx_mail_imap_merge_srv_conf /* merge server configuration */
-};
-
-
-ngx_module_t ngx_mail_imap_module = {
- NGX_MODULE_V1,
- &ngx_mail_imap_module_ctx, /* module context */
- ngx_mail_imap_commands, /* module directives */
- NGX_MAIL_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static void *
-ngx_mail_imap_create_srv_conf(ngx_conf_t *cf)
-{
- ngx_mail_imap_srv_conf_t *iscf;
-
- iscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_imap_srv_conf_t));
- if (iscf == NULL) {
- return NULL;
- }
-
- iscf->client_buffer_size = NGX_CONF_UNSET_SIZE;
-
- if (ngx_array_init(&iscf->capabilities, cf->pool, 4, sizeof(ngx_str_t))
- != NGX_OK)
- {
- return NULL;
- }
-
- return iscf;
-}
-
-
-static char *
-ngx_mail_imap_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_mail_imap_srv_conf_t *prev = parent;
- ngx_mail_imap_srv_conf_t *conf = child;
-
- u_char *p, *auth;
- size_t size;
- ngx_str_t *c, *d;
- ngx_uint_t i, m;
-
- ngx_conf_merge_size_value(conf->client_buffer_size,
- prev->client_buffer_size,
- (size_t) ngx_pagesize);
-
- ngx_conf_merge_bitmask_value(conf->auth_methods,
- prev->auth_methods,
- (NGX_CONF_BITMASK_SET
- |NGX_MAIL_AUTH_PLAIN_ENABLED));
-
-
- if (conf->capabilities.nelts == 0) {
- conf->capabilities = prev->capabilities;
- }
-
- if (conf->capabilities.nelts == 0) {
-
- for (d = ngx_mail_imap_default_capabilities; d->len; d++) {
- c = ngx_array_push(&conf->capabilities);
- if (c == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *c = *d;
- }
- }
-
- size = sizeof("* CAPABILITY" CRLF) - 1;
-
- c = conf->capabilities.elts;
- for (i = 0; i < conf->capabilities.nelts; i++) {
- size += 1 + c[i].len;
- }
-
- for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
- m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
- m <<= 1, i++)
- {
- if (m & conf->auth_methods) {
- size += 1 + ngx_mail_imap_auth_methods_names[i].len;
- }
- }
-
- p = ngx_pnalloc(cf->pool, size);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->capability.len = size;
- conf->capability.data = p;
-
- p = ngx_cpymem(p, "* CAPABILITY", sizeof("* CAPABILITY") - 1);
-
- for (i = 0; i < conf->capabilities.nelts; i++) {
- *p++ = ' ';
- p = ngx_cpymem(p, c[i].data, c[i].len);
- }
-
- auth = p;
-
- for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
- m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
- m <<= 1, i++)
- {
- if (m & conf->auth_methods) {
- *p++ = ' ';
- p = ngx_cpymem(p, ngx_mail_imap_auth_methods_names[i].data,
- ngx_mail_imap_auth_methods_names[i].len);
- }
- }
-
- *p++ = CR; *p = LF;
-
-
- size += sizeof(" STARTTLS") - 1;
-
- p = ngx_pnalloc(cf->pool, size);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->starttls_capability.len = size;
- conf->starttls_capability.data = p;
-
- p = ngx_cpymem(p, conf->capability.data,
- conf->capability.len - (sizeof(CRLF) - 1));
- p = ngx_cpymem(p, " STARTTLS", sizeof(" STARTTLS") - 1);
- *p++ = CR; *p = LF;
-
-
- size = (auth - conf->capability.data) + sizeof(CRLF) - 1
- + sizeof(" STARTTLS LOGINDISABLED") - 1;
-
- p = ngx_pnalloc(cf->pool, size);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->starttls_only_capability.len = size;
- conf->starttls_only_capability.data = p;
-
- p = ngx_cpymem(p, conf->capability.data,
- auth - conf->capability.data);
- p = ngx_cpymem(p, " STARTTLS LOGINDISABLED",
- sizeof(" STARTTLS LOGINDISABLED") - 1);
- *p++ = CR; *p = LF;
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_imap_module.h b/usr.sbin/nginx/src/mail/ngx_mail_imap_module.h
deleted file mode 100644
index 131b44597f8..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_imap_module.h
+++ /dev/null
@@ -1,39 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_MAIL_IMAP_MODULE_H_INCLUDED_
-#define _NGX_MAIL_IMAP_MODULE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_mail.h>
-
-
-typedef struct {
- size_t client_buffer_size;
-
- ngx_str_t capability;
- ngx_str_t starttls_capability;
- ngx_str_t starttls_only_capability;
-
- ngx_uint_t auth_methods;
-
- ngx_array_t capabilities;
-} ngx_mail_imap_srv_conf_t;
-
-
-void ngx_mail_imap_init_session(ngx_mail_session_t *s, ngx_connection_t *c);
-void ngx_mail_imap_init_protocol(ngx_event_t *rev);
-void ngx_mail_imap_auth_state(ngx_event_t *rev);
-ngx_int_t ngx_mail_imap_parse_command(ngx_mail_session_t *s);
-
-
-extern ngx_module_t ngx_mail_imap_module;
-
-
-#endif /* _NGX_MAIL_IMAP_MODULE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_parse.c b/usr.sbin/nginx/src/mail/ngx_mail_parse.c
deleted file mode 100644
index b158f5a0fba..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_parse.c
+++ /dev/null
@@ -1,918 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_mail.h>
-#include <ngx_mail_pop3_module.h>
-#include <ngx_mail_imap_module.h>
-#include <ngx_mail_smtp_module.h>
-
-
-ngx_int_t
-ngx_mail_pop3_parse_command(ngx_mail_session_t *s)
-{
- u_char ch, *p, *c, c0, c1, c2, c3;
- ngx_str_t *arg;
- enum {
- sw_start = 0,
- sw_spaces_before_argument,
- sw_argument,
- sw_almost_done
- } state;
-
- state = s->state;
-
- for (p = s->buffer->pos; p < s->buffer->last; p++) {
- ch = *p;
-
- switch (state) {
-
- /* POP3 command */
- case sw_start:
- if (ch == ' ' || ch == CR || ch == LF) {
- c = s->buffer->start;
-
- if (p - c == 4) {
-
- c0 = ngx_toupper(c[0]);
- c1 = ngx_toupper(c[1]);
- c2 = ngx_toupper(c[2]);
- c3 = ngx_toupper(c[3]);
-
- if (c0 == 'U' && c1 == 'S' && c2 == 'E' && c3 == 'R')
- {
- s->command = NGX_POP3_USER;
-
- } else if (c0 == 'P' && c1 == 'A' && c2 == 'S' && c3 == 'S')
- {
- s->command = NGX_POP3_PASS;
-
- } else if (c0 == 'A' && c1 == 'P' && c2 == 'O' && c3 == 'P')
- {
- s->command = NGX_POP3_APOP;
-
- } else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T')
- {
- s->command = NGX_POP3_QUIT;
-
- } else if (c0 == 'C' && c1 == 'A' && c2 == 'P' && c3 == 'A')
- {
- s->command = NGX_POP3_CAPA;
-
- } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H')
- {
- s->command = NGX_POP3_AUTH;
-
- } else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P')
- {
- s->command = NGX_POP3_NOOP;
-#if (NGX_MAIL_SSL)
- } else if (c0 == 'S' && c1 == 'T' && c2 == 'L' && c3 == 'S')
- {
- s->command = NGX_POP3_STLS;
-#endif
- } else {
- goto invalid;
- }
-
- } else {
- goto invalid;
- }
-
- switch (ch) {
- case ' ':
- state = sw_spaces_before_argument;
- break;
- case CR:
- state = sw_almost_done;
- break;
- case LF:
- goto done;
- }
- break;
- }
-
- if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
- goto invalid;
- }
-
- break;
-
- case sw_spaces_before_argument:
- switch (ch) {
- case ' ':
- break;
- case CR:
- state = sw_almost_done;
- s->arg_end = p;
- break;
- case LF:
- s->arg_end = p;
- goto done;
- default:
- if (s->args.nelts <= 2) {
- state = sw_argument;
- s->arg_start = p;
- break;
- }
- goto invalid;
- }
- break;
-
- case sw_argument:
- switch (ch) {
-
- case ' ':
-
- /*
- * the space should be considered as part of the at username
- * or password, but not of argument in other commands
- */
-
- if (s->command == NGX_POP3_USER
- || s->command == NGX_POP3_PASS)
- {
- break;
- }
-
- /* fall through */
-
- case CR:
- case LF:
- arg = ngx_array_push(&s->args);
- if (arg == NULL) {
- return NGX_ERROR;
- }
- arg->len = p - s->arg_start;
- arg->data = s->arg_start;
- s->arg_start = NULL;
-
- switch (ch) {
- case ' ':
- state = sw_spaces_before_argument;
- break;
- case CR:
- state = sw_almost_done;
- break;
- case LF:
- goto done;
- }
- break;
-
- default:
- break;
- }
- break;
-
- case sw_almost_done:
- switch (ch) {
- case LF:
- goto done;
- default:
- goto invalid;
- }
- }
- }
-
- s->buffer->pos = p;
- s->state = state;
-
- return NGX_AGAIN;
-
-done:
-
- s->buffer->pos = p + 1;
-
- if (s->arg_start) {
- arg = ngx_array_push(&s->args);
- if (arg == NULL) {
- return NGX_ERROR;
- }
- arg->len = s->arg_end - s->arg_start;
- arg->data = s->arg_start;
- s->arg_start = NULL;
- }
-
- s->state = (s->command != NGX_POP3_AUTH) ? sw_start : sw_argument;
-
- return NGX_OK;
-
-invalid:
-
- s->state = sw_start;
- s->arg_start = NULL;
-
- return NGX_MAIL_PARSE_INVALID_COMMAND;
-}
-
-
-ngx_int_t
-ngx_mail_imap_parse_command(ngx_mail_session_t *s)
-{
- u_char ch, *p, *c;
- ngx_str_t *arg;
- enum {
- sw_start = 0,
- sw_spaces_before_command,
- sw_command,
- sw_spaces_before_argument,
- sw_argument,
- sw_backslash,
- sw_literal,
- sw_no_sync_literal_argument,
- sw_start_literal_argument,
- sw_literal_argument,
- sw_end_literal_argument,
- sw_almost_done
- } state;
-
- state = s->state;
-
- for (p = s->buffer->pos; p < s->buffer->last; p++) {
- ch = *p;
-
- switch (state) {
-
- /* IMAP tag */
- case sw_start:
- switch (ch) {
- case ' ':
- s->tag.len = p - s->buffer->start + 1;
- s->tag.data = s->buffer->start;
- state = sw_spaces_before_command;
- break;
- case CR:
- s->state = sw_start;
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- case LF:
- s->state = sw_start;
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
- break;
-
- case sw_spaces_before_command:
- switch (ch) {
- case ' ':
- break;
- case CR:
- s->state = sw_start;
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- case LF:
- s->state = sw_start;
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- default:
- s->cmd_start = p;
- state = sw_command;
- break;
- }
- break;
-
- case sw_command:
- if (ch == ' ' || ch == CR || ch == LF) {
-
- c = s->cmd_start;
-
- switch (p - c) {
-
- case 4:
- if ((c[0] == 'N' || c[0] == 'n')
- && (c[1] == 'O'|| c[1] == 'o')
- && (c[2] == 'O'|| c[2] == 'o')
- && (c[3] == 'P'|| c[3] == 'p'))
- {
- s->command = NGX_IMAP_NOOP;
-
- } else {
- goto invalid;
- }
- break;
-
- case 5:
- if ((c[0] == 'L'|| c[0] == 'l')
- && (c[1] == 'O'|| c[1] == 'o')
- && (c[2] == 'G'|| c[2] == 'g')
- && (c[3] == 'I'|| c[3] == 'i')
- && (c[4] == 'N'|| c[4] == 'n'))
- {
- s->command = NGX_IMAP_LOGIN;
-
- } else {
- goto invalid;
- }
- break;
-
- case 6:
- if ((c[0] == 'L'|| c[0] == 'l')
- && (c[1] == 'O'|| c[1] == 'o')
- && (c[2] == 'G'|| c[2] == 'g')
- && (c[3] == 'O'|| c[3] == 'o')
- && (c[4] == 'U'|| c[4] == 'u')
- && (c[5] == 'T'|| c[5] == 't'))
- {
- s->command = NGX_IMAP_LOGOUT;
-
- } else {
- goto invalid;
- }
- break;
-
-#if (NGX_MAIL_SSL)
- case 8:
- if ((c[0] == 'S'|| c[0] == 's')
- && (c[1] == 'T'|| c[1] == 't')
- && (c[2] == 'A'|| c[2] == 'a')
- && (c[3] == 'R'|| c[3] == 'r')
- && (c[4] == 'T'|| c[4] == 't')
- && (c[5] == 'T'|| c[5] == 't')
- && (c[6] == 'L'|| c[6] == 'l')
- && (c[7] == 'S'|| c[7] == 's'))
- {
- s->command = NGX_IMAP_STARTTLS;
-
- } else {
- goto invalid;
- }
- break;
-#endif
-
- case 10:
- if ((c[0] == 'C'|| c[0] == 'c')
- && (c[1] == 'A'|| c[1] == 'a')
- && (c[2] == 'P'|| c[2] == 'p')
- && (c[3] == 'A'|| c[3] == 'a')
- && (c[4] == 'B'|| c[4] == 'b')
- && (c[5] == 'I'|| c[5] == 'i')
- && (c[6] == 'L'|| c[6] == 'l')
- && (c[7] == 'I'|| c[7] == 'i')
- && (c[8] == 'T'|| c[8] == 't')
- && (c[9] == 'Y'|| c[9] == 'y'))
- {
- s->command = NGX_IMAP_CAPABILITY;
-
- } else {
- goto invalid;
- }
- break;
-
- case 12:
- if ((c[0] == 'A'|| c[0] == 'a')
- && (c[1] == 'U'|| c[1] == 'u')
- && (c[2] == 'T'|| c[2] == 't')
- && (c[3] == 'H'|| c[3] == 'h')
- && (c[4] == 'E'|| c[4] == 'e')
- && (c[5] == 'N'|| c[5] == 'n')
- && (c[6] == 'T'|| c[6] == 't')
- && (c[7] == 'I'|| c[7] == 'i')
- && (c[8] == 'C'|| c[8] == 'c')
- && (c[9] == 'A'|| c[9] == 'a')
- && (c[10] == 'T'|| c[10] == 't')
- && (c[11] == 'E'|| c[11] == 'e'))
- {
- s->command = NGX_IMAP_AUTHENTICATE;
-
- } else {
- goto invalid;
- }
- break;
-
- default:
- goto invalid;
- }
-
- switch (ch) {
- case ' ':
- state = sw_spaces_before_argument;
- break;
- case CR:
- state = sw_almost_done;
- break;
- case LF:
- goto done;
- }
- break;
- }
-
- if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
- goto invalid;
- }
-
- break;
-
- case sw_spaces_before_argument:
- switch (ch) {
- case ' ':
- break;
- case CR:
- state = sw_almost_done;
- s->arg_end = p;
- break;
- case LF:
- s->arg_end = p;
- goto done;
- case '"':
- if (s->args.nelts <= 2) {
- s->quoted = 1;
- s->arg_start = p + 1;
- state = sw_argument;
- break;
- }
- goto invalid;
- case '{':
- if (s->args.nelts <= 2) {
- state = sw_literal;
- break;
- }
- goto invalid;
- default:
- if (s->args.nelts <= 2) {
- s->arg_start = p;
- state = sw_argument;
- break;
- }
- goto invalid;
- }
- break;
-
- case sw_argument:
- if (ch == ' ' && s->quoted) {
- break;
- }
-
- switch (ch) {
- case '"':
- if (!s->quoted) {
- break;
- }
- s->quoted = 0;
- /* fall through */
- case ' ':
- case CR:
- case LF:
- arg = ngx_array_push(&s->args);
- if (arg == NULL) {
- return NGX_ERROR;
- }
- arg->len = p - s->arg_start;
- arg->data = s->arg_start;
- s->arg_start = NULL;
-
- switch (ch) {
- case '"':
- case ' ':
- state = sw_spaces_before_argument;
- break;
- case CR:
- state = sw_almost_done;
- break;
- case LF:
- goto done;
- }
- break;
- case '\\':
- if (s->quoted) {
- s->backslash = 1;
- state = sw_backslash;
- }
- break;
- }
- break;
-
- case sw_backslash:
- switch (ch) {
- case CR:
- case LF:
- goto invalid;
- default:
- state = sw_argument;
- }
- break;
-
- case sw_literal:
- if (ch >= '0' && ch <= '9') {
- s->literal_len = s->literal_len * 10 + (ch - '0');
- break;
- }
- if (ch == '}') {
- state = sw_start_literal_argument;
- break;
- }
- if (ch == '+') {
- state = sw_no_sync_literal_argument;
- break;
- }
- goto invalid;
-
- case sw_no_sync_literal_argument:
- if (ch == '}') {
- s->no_sync_literal = 1;
- state = sw_start_literal_argument;
- break;
- }
- goto invalid;
-
- case sw_start_literal_argument:
- switch (ch) {
- case CR:
- break;
- case LF:
- s->buffer->pos = p + 1;
- s->arg_start = p + 1;
- if (s->no_sync_literal == 0) {
- s->state = sw_literal_argument;
- return NGX_IMAP_NEXT;
- }
- state = sw_literal_argument;
- s->no_sync_literal = 0;
- break;
- default:
- goto invalid;
- }
- break;
-
- case sw_literal_argument:
- if (s->literal_len && --s->literal_len) {
- break;
- }
-
- arg = ngx_array_push(&s->args);
- if (arg == NULL) {
- return NGX_ERROR;
- }
- arg->len = p + 1 - s->arg_start;
- arg->data = s->arg_start;
- s->arg_start = NULL;
- state = sw_end_literal_argument;
-
- break;
-
- case sw_end_literal_argument:
- switch (ch) {
- case '{':
- if (s->args.nelts <= 2) {
- state = sw_literal;
- break;
- }
- goto invalid;
- case CR:
- state = sw_almost_done;
- break;
- case LF:
- goto done;
- default:
- state = sw_spaces_before_argument;
- break;
- }
- break;
-
- case sw_almost_done:
- switch (ch) {
- case LF:
- goto done;
- default:
- goto invalid;
- }
- }
- }
-
- s->buffer->pos = p;
- s->state = state;
-
- return NGX_AGAIN;
-
-done:
-
- s->buffer->pos = p + 1;
-
- if (s->arg_start) {
- arg = ngx_array_push(&s->args);
- if (arg == NULL) {
- return NGX_ERROR;
- }
- arg->len = s->arg_end - s->arg_start;
- arg->data = s->arg_start;
-
- s->arg_start = NULL;
- s->cmd_start = NULL;
- s->quoted = 0;
- s->no_sync_literal = 0;
- s->literal_len = 0;
- }
-
- s->state = (s->command != NGX_IMAP_AUTHENTICATE) ? sw_start : sw_argument;
-
- return NGX_OK;
-
-invalid:
-
- s->state = sw_start;
- s->quoted = 0;
- s->no_sync_literal = 0;
- s->literal_len = 0;
-
- return NGX_MAIL_PARSE_INVALID_COMMAND;
-}
-
-
-ngx_int_t
-ngx_mail_smtp_parse_command(ngx_mail_session_t *s)
-{
- u_char ch, *p, *c, c0, c1, c2, c3;
- ngx_str_t *arg;
- enum {
- sw_start = 0,
- sw_command,
- sw_invalid,
- sw_spaces_before_argument,
- sw_argument,
- sw_almost_done
- } state;
-
- state = s->state;
-
- for (p = s->buffer->pos; p < s->buffer->last; p++) {
- ch = *p;
-
- switch (state) {
-
- /* SMTP command */
- case sw_start:
- s->cmd_start = p;
- state = sw_command;
-
- /* fall through */
-
- case sw_command:
- if (ch == ' ' || ch == CR || ch == LF) {
- c = s->cmd_start;
-
- if (p - c == 4) {
-
- c0 = ngx_toupper(c[0]);
- c1 = ngx_toupper(c[1]);
- c2 = ngx_toupper(c[2]);
- c3 = ngx_toupper(c[3]);
-
- if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 == 'O')
- {
- s->command = NGX_SMTP_HELO;
-
- } else if (c0 == 'E' && c1 == 'H' && c2 == 'L' && c3 == 'O')
- {
- s->command = NGX_SMTP_EHLO;
-
- } else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T')
- {
- s->command = NGX_SMTP_QUIT;
-
- } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H')
- {
- s->command = NGX_SMTP_AUTH;
-
- } else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P')
- {
- s->command = NGX_SMTP_NOOP;
-
- } else if (c0 == 'M' && c1 == 'A' && c2 == 'I' && c3 == 'L')
- {
- s->command = NGX_SMTP_MAIL;
-
- } else if (c0 == 'R' && c1 == 'S' && c2 == 'E' && c3 == 'T')
- {
- s->command = NGX_SMTP_RSET;
-
- } else if (c0 == 'R' && c1 == 'C' && c2 == 'P' && c3 == 'T')
- {
- s->command = NGX_SMTP_RCPT;
-
- } else if (c0 == 'V' && c1 == 'R' && c2 == 'F' && c3 == 'Y')
- {
- s->command = NGX_SMTP_VRFY;
-
- } else if (c0 == 'E' && c1 == 'X' && c2 == 'P' && c3 == 'N')
- {
- s->command = NGX_SMTP_EXPN;
-
- } else if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 == 'P')
- {
- s->command = NGX_SMTP_HELP;
-
- } else {
- goto invalid;
- }
-#if (NGX_MAIL_SSL)
- } else if (p - c == 8) {
-
- if ((c[0] == 'S'|| c[0] == 's')
- && (c[1] == 'T'|| c[1] == 't')
- && (c[2] == 'A'|| c[2] == 'a')
- && (c[3] == 'R'|| c[3] == 'r')
- && (c[4] == 'T'|| c[4] == 't')
- && (c[5] == 'T'|| c[5] == 't')
- && (c[6] == 'L'|| c[6] == 'l')
- && (c[7] == 'S'|| c[7] == 's'))
- {
- s->command = NGX_SMTP_STARTTLS;
-
- } else {
- goto invalid;
- }
-#endif
- } else {
- goto invalid;
- }
-
- s->cmd.data = s->cmd_start;
- s->cmd.len = p - s->cmd_start;
-
- switch (ch) {
- case ' ':
- state = sw_spaces_before_argument;
- break;
- case CR:
- state = sw_almost_done;
- break;
- case LF:
- goto done;
- }
- break;
- }
-
- if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
- goto invalid;
- }
-
- break;
-
- case sw_invalid:
- goto invalid;
-
- case sw_spaces_before_argument:
- switch (ch) {
- case ' ':
- break;
- case CR:
- state = sw_almost_done;
- s->arg_end = p;
- break;
- case LF:
- s->arg_end = p;
- goto done;
- default:
- if (s->args.nelts <= 10) {
- state = sw_argument;
- s->arg_start = p;
- break;
- }
- goto invalid;
- }
- break;
-
- case sw_argument:
- switch (ch) {
- case ' ':
- case CR:
- case LF:
- arg = ngx_array_push(&s->args);
- if (arg == NULL) {
- return NGX_ERROR;
- }
- arg->len = p - s->arg_start;
- arg->data = s->arg_start;
- s->arg_start = NULL;
-
- switch (ch) {
- case ' ':
- state = sw_spaces_before_argument;
- break;
- case CR:
- state = sw_almost_done;
- break;
- case LF:
- goto done;
- }
- break;
-
- default:
- break;
- }
- break;
-
- case sw_almost_done:
- switch (ch) {
- case LF:
- goto done;
- default:
- goto invalid;
- }
- }
- }
-
- s->buffer->pos = p;
- s->state = state;
-
- return NGX_AGAIN;
-
-done:
-
- s->buffer->pos = p + 1;
-
- if (s->arg_start) {
- arg = ngx_array_push(&s->args);
- if (arg == NULL) {
- return NGX_ERROR;
- }
- arg->len = s->arg_end - s->arg_start;
- arg->data = s->arg_start;
- s->arg_start = NULL;
- }
-
- s->state = (s->command != NGX_SMTP_AUTH) ? sw_start : sw_argument;
-
- return NGX_OK;
-
-invalid:
-
- s->state = sw_invalid;
- s->arg_start = NULL;
-
- /* skip invalid command till LF */
-
- for (p = s->buffer->pos; p < s->buffer->last; p++) {
- if (*p == LF) {
- s->state = sw_start;
- p++;
- break;
- }
- }
-
- s->buffer->pos = p;
-
- return NGX_MAIL_PARSE_INVALID_COMMAND;
-}
-
-
-ngx_int_t
-ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_str_t *arg;
-
-#if (NGX_MAIL_SSL)
- if (ngx_mail_starttls_only(s, c)) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-#endif
-
- if (s->args.nelts == 0) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- arg = s->args.elts;
-
- if (arg[0].len == 5) {
-
- if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) {
-
- if (s->args.nelts == 1) {
- return NGX_MAIL_AUTH_LOGIN;
- }
-
- if (s->args.nelts == 2) {
- return NGX_MAIL_AUTH_LOGIN_USERNAME;
- }
-
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) {
-
- if (s->args.nelts == 1) {
- return NGX_MAIL_AUTH_PLAIN;
- }
-
- if (s->args.nelts == 2) {
- return ngx_mail_auth_plain(s, c, 1);
- }
- }
-
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- if (arg[0].len == 8) {
-
- if (s->args.nelts != 1) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- if (ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0) {
- return NGX_MAIL_AUTH_CRAM_MD5;
- }
- }
-
- return NGX_MAIL_PARSE_INVALID_COMMAND;
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_pop3_handler.c b/usr.sbin/nginx/src/mail/ngx_mail_pop3_handler.c
deleted file mode 100644
index 51bc257a595..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_pop3_handler.c
+++ /dev/null
@@ -1,500 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_mail.h>
-#include <ngx_mail_pop3_module.h>
-
-
-static ngx_int_t ngx_mail_pop3_user(ngx_mail_session_t *s, ngx_connection_t *c);
-static ngx_int_t ngx_mail_pop3_pass(ngx_mail_session_t *s, ngx_connection_t *c);
-static ngx_int_t ngx_mail_pop3_capa(ngx_mail_session_t *s, ngx_connection_t *c,
- ngx_int_t stls);
-static ngx_int_t ngx_mail_pop3_stls(ngx_mail_session_t *s, ngx_connection_t *c);
-static ngx_int_t ngx_mail_pop3_apop(ngx_mail_session_t *s, ngx_connection_t *c);
-static ngx_int_t ngx_mail_pop3_auth(ngx_mail_session_t *s, ngx_connection_t *c);
-
-
-static u_char pop3_greeting[] = "+OK POP3 ready" CRLF;
-static u_char pop3_ok[] = "+OK" CRLF;
-static u_char pop3_next[] = "+ " CRLF;
-static u_char pop3_username[] = "+ VXNlcm5hbWU6" CRLF;
-static u_char pop3_password[] = "+ UGFzc3dvcmQ6" CRLF;
-static u_char pop3_invalid_command[] = "-ERR invalid command" CRLF;
-
-
-void
-ngx_mail_pop3_init_session(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- u_char *p;
- ngx_mail_core_srv_conf_t *cscf;
- ngx_mail_pop3_srv_conf_t *pscf;
-
- pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module);
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- if (pscf->auth_methods
- & (NGX_MAIL_AUTH_APOP_ENABLED|NGX_MAIL_AUTH_CRAM_MD5_ENABLED))
- {
- if (ngx_mail_salt(s, c, cscf) != NGX_OK) {
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- s->out.data = ngx_pnalloc(c->pool, sizeof(pop3_greeting) + s->salt.len);
- if (s->out.data == NULL) {
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- p = ngx_cpymem(s->out.data, pop3_greeting, sizeof(pop3_greeting) - 3);
- *p++ = ' ';
- p = ngx_cpymem(p, s->salt.data, s->salt.len);
-
- s->out.len = p - s->out.data;
-
- } else {
- ngx_str_set(&s->out, pop3_greeting);
- }
-
- c->read->handler = ngx_mail_pop3_init_protocol;
-
- ngx_add_timer(c->read, cscf->timeout);
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- ngx_mail_close_connection(c);
- }
-
- ngx_mail_send(c->write);
-}
-
-
-void
-ngx_mail_pop3_init_protocol(ngx_event_t *rev)
-{
- ngx_connection_t *c;
- ngx_mail_session_t *s;
-
- c = rev->data;
-
- c->log->action = "in auth state";
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
- c->timedout = 1;
- ngx_mail_close_connection(c);
- return;
- }
-
- s = c->data;
-
- if (s->buffer == NULL) {
- if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t))
- == NGX_ERROR)
- {
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- s->buffer = ngx_create_temp_buf(c->pool, 128);
- if (s->buffer == NULL) {
- ngx_mail_session_internal_server_error(s);
- return;
- }
- }
-
- s->mail_state = ngx_pop3_start;
- c->read->handler = ngx_mail_pop3_auth_state;
-
- ngx_mail_pop3_auth_state(rev);
-}
-
-
-void
-ngx_mail_pop3_auth_state(ngx_event_t *rev)
-{
- ngx_int_t rc;
- ngx_connection_t *c;
- ngx_mail_session_t *s;
-
- c = rev->data;
- s = c->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "pop3 auth state");
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
- c->timedout = 1;
- ngx_mail_close_connection(c);
- return;
- }
-
- if (s->out.len) {
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "pop3 send handler busy");
- s->blocked = 1;
- return;
- }
-
- s->blocked = 0;
-
- rc = ngx_mail_read_command(s, c);
-
- if (rc == NGX_AGAIN || rc == NGX_ERROR) {
- return;
- }
-
- ngx_str_set(&s->out, pop3_ok);
-
- if (rc == NGX_OK) {
- switch (s->mail_state) {
-
- case ngx_pop3_start:
-
- switch (s->command) {
-
- case NGX_POP3_USER:
- rc = ngx_mail_pop3_user(s, c);
- break;
-
- case NGX_POP3_CAPA:
- rc = ngx_mail_pop3_capa(s, c, 1);
- break;
-
- case NGX_POP3_APOP:
- rc = ngx_mail_pop3_apop(s, c);
- break;
-
- case NGX_POP3_AUTH:
- rc = ngx_mail_pop3_auth(s, c);
- break;
-
- case NGX_POP3_QUIT:
- s->quit = 1;
- break;
-
- case NGX_POP3_NOOP:
- break;
-
- case NGX_POP3_STLS:
- rc = ngx_mail_pop3_stls(s, c);
- break;
-
- default:
- rc = NGX_MAIL_PARSE_INVALID_COMMAND;
- break;
- }
-
- break;
-
- case ngx_pop3_user:
-
- switch (s->command) {
-
- case NGX_POP3_PASS:
- rc = ngx_mail_pop3_pass(s, c);
- break;
-
- case NGX_POP3_CAPA:
- rc = ngx_mail_pop3_capa(s, c, 0);
- break;
-
- case NGX_POP3_QUIT:
- s->quit = 1;
- break;
-
- case NGX_POP3_NOOP:
- break;
-
- default:
- rc = NGX_MAIL_PARSE_INVALID_COMMAND;
- break;
- }
-
- break;
-
- /* suppress warnings */
- case ngx_pop3_passwd:
- break;
-
- case ngx_pop3_auth_login_username:
- rc = ngx_mail_auth_login_username(s, c, 0);
-
- ngx_str_set(&s->out, pop3_password);
- s->mail_state = ngx_pop3_auth_login_password;
- break;
-
- case ngx_pop3_auth_login_password:
- rc = ngx_mail_auth_login_password(s, c);
- break;
-
- case ngx_pop3_auth_plain:
- rc = ngx_mail_auth_plain(s, c, 0);
- break;
-
- case ngx_pop3_auth_cram_md5:
- rc = ngx_mail_auth_cram_md5(s, c);
- break;
- }
- }
-
- switch (rc) {
-
- case NGX_DONE:
- ngx_mail_auth(s, c);
- return;
-
- case NGX_ERROR:
- ngx_mail_session_internal_server_error(s);
- return;
-
- case NGX_MAIL_PARSE_INVALID_COMMAND:
- s->mail_state = ngx_pop3_start;
- s->state = 0;
-
- ngx_str_set(&s->out, pop3_invalid_command);
-
- /* fall through */
-
- case NGX_OK:
-
- s->args.nelts = 0;
- s->buffer->pos = s->buffer->start;
- s->buffer->last = s->buffer->start;
-
- if (s->state) {
- s->arg_start = s->buffer->start;
- }
-
- ngx_mail_send(c->write);
- }
-}
-
-static ngx_int_t
-ngx_mail_pop3_user(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_str_t *arg;
-
-#if (NGX_MAIL_SSL)
- if (ngx_mail_starttls_only(s, c)) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-#endif
-
- if (s->args.nelts != 1) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- arg = s->args.elts;
- s->login.len = arg[0].len;
- s->login.data = ngx_pnalloc(c->pool, s->login.len);
- if (s->login.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(s->login.data, arg[0].data, s->login.len);
-
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "pop3 login: \"%V\"", &s->login);
-
- s->mail_state = ngx_pop3_user;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_mail_pop3_pass(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_str_t *arg;
-
- if (s->args.nelts != 1) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- arg = s->args.elts;
- s->passwd.len = arg[0].len;
- s->passwd.data = ngx_pnalloc(c->pool, s->passwd.len);
- if (s->passwd.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(s->passwd.data, arg[0].data, s->passwd.len);
-
-#if (NGX_DEBUG_MAIL_PASSWD)
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "pop3 passwd: \"%V\"", &s->passwd);
-#endif
-
- return NGX_DONE;
-}
-
-
-static ngx_int_t
-ngx_mail_pop3_capa(ngx_mail_session_t *s, ngx_connection_t *c, ngx_int_t stls)
-{
- ngx_mail_pop3_srv_conf_t *pscf;
-
- pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module);
-
-#if (NGX_MAIL_SSL)
-
- if (stls && c->ssl == NULL) {
- ngx_mail_ssl_conf_t *sslcf;
-
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
-
- if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) {
- s->out = pscf->starttls_capability;
- return NGX_OK;
- }
-
- if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
- s->out = pscf->starttls_only_capability;
- return NGX_OK;
- }
- }
-
-#endif
-
- s->out = pscf->capability;
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_mail_pop3_stls(ngx_mail_session_t *s, ngx_connection_t *c)
-{
-#if (NGX_MAIL_SSL)
- ngx_mail_ssl_conf_t *sslcf;
-
- if (c->ssl == NULL) {
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
- if (sslcf->starttls) {
- c->read->handler = ngx_mail_starttls_handler;
- return NGX_OK;
- }
- }
-
-#endif
-
- return NGX_MAIL_PARSE_INVALID_COMMAND;
-}
-
-
-static ngx_int_t
-ngx_mail_pop3_apop(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_str_t *arg;
- ngx_mail_pop3_srv_conf_t *pscf;
-
-#if (NGX_MAIL_SSL)
- if (ngx_mail_starttls_only(s, c)) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-#endif
-
- if (s->args.nelts != 2) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module);
-
- if (!(pscf->auth_methods & NGX_MAIL_AUTH_APOP_ENABLED)) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- arg = s->args.elts;
-
- s->login.len = arg[0].len;
- s->login.data = ngx_pnalloc(c->pool, s->login.len);
- if (s->login.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(s->login.data, arg[0].data, s->login.len);
-
- s->passwd.len = arg[1].len;
- s->passwd.data = ngx_pnalloc(c->pool, s->passwd.len);
- if (s->passwd.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(s->passwd.data, arg[1].data, s->passwd.len);
-
- ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "pop3 apop: \"%V\" \"%V\"", &s->login, &s->passwd);
-
- s->auth_method = NGX_MAIL_AUTH_APOP;
-
- return NGX_DONE;
-}
-
-
-static ngx_int_t
-ngx_mail_pop3_auth(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_int_t rc;
- ngx_mail_pop3_srv_conf_t *pscf;
-
-#if (NGX_MAIL_SSL)
- if (ngx_mail_starttls_only(s, c)) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-#endif
-
- pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module);
-
- if (s->args.nelts == 0) {
- s->out = pscf->auth_capability;
- s->state = 0;
-
- return NGX_OK;
- }
-
- rc = ngx_mail_auth_parse(s, c);
-
- switch (rc) {
-
- case NGX_MAIL_AUTH_LOGIN:
-
- ngx_str_set(&s->out, pop3_username);
- s->mail_state = ngx_pop3_auth_login_username;
-
- return NGX_OK;
-
- case NGX_MAIL_AUTH_LOGIN_USERNAME:
-
- ngx_str_set(&s->out, pop3_password);
- s->mail_state = ngx_pop3_auth_login_password;
-
- return ngx_mail_auth_login_username(s, c, 1);
-
- case NGX_MAIL_AUTH_PLAIN:
-
- ngx_str_set(&s->out, pop3_next);
- s->mail_state = ngx_pop3_auth_plain;
-
- return NGX_OK;
-
- case NGX_MAIL_AUTH_CRAM_MD5:
-
- if (!(pscf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- if (ngx_mail_auth_cram_md5_salt(s, c, "+ ", 2) == NGX_OK) {
- s->mail_state = ngx_pop3_auth_cram_md5;
- return NGX_OK;
- }
-
- return NGX_ERROR;
- }
-
- return rc;
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_pop3_module.c b/usr.sbin/nginx/src/mail/ngx_mail_pop3_module.c
deleted file mode 100644
index b59747290e2..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_pop3_module.c
+++ /dev/null
@@ -1,264 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_mail.h>
-#include <ngx_mail_pop3_module.h>
-
-
-static void *ngx_mail_pop3_create_srv_conf(ngx_conf_t *cf);
-static char *ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent,
- void *child);
-
-
-static ngx_str_t ngx_mail_pop3_default_capabilities[] = {
- ngx_string("TOP"),
- ngx_string("USER"),
- ngx_string("UIDL"),
- ngx_null_string
-};
-
-
-static ngx_conf_bitmask_t ngx_mail_pop3_auth_methods[] = {
- { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
- { ngx_string("apop"), NGX_MAIL_AUTH_APOP_ENABLED },
- { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_str_t ngx_mail_pop3_auth_plain_capability =
- ngx_string("+OK methods supported:" CRLF
- "LOGIN" CRLF
- "PLAIN" CRLF
- "." CRLF);
-
-
-static ngx_str_t ngx_mail_pop3_auth_cram_md5_capability =
- ngx_string("+OK methods supported:" CRLF
- "LOGIN" CRLF
- "PLAIN" CRLF
- "CRAM-MD5" CRLF
- "." CRLF);
-
-
-static ngx_mail_protocol_t ngx_mail_pop3_protocol = {
- ngx_string("pop3"),
- { 110, 995, 0, 0 },
- NGX_MAIL_POP3_PROTOCOL,
-
- ngx_mail_pop3_init_session,
- ngx_mail_pop3_init_protocol,
- ngx_mail_pop3_parse_command,
- ngx_mail_pop3_auth_state,
-
- ngx_string("-ERR internal server error" CRLF)
-};
-
-
-static ngx_command_t ngx_mail_pop3_commands[] = {
-
- { ngx_string("pop3_capabilities"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
- ngx_mail_capabilities,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_pop3_srv_conf_t, capabilities),
- NULL },
-
- { ngx_string("pop3_auth"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_pop3_srv_conf_t, auth_methods),
- &ngx_mail_pop3_auth_methods },
-
- ngx_null_command
-};
-
-
-static ngx_mail_module_t ngx_mail_pop3_module_ctx = {
- &ngx_mail_pop3_protocol, /* protocol */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- ngx_mail_pop3_create_srv_conf, /* create server configuration */
- ngx_mail_pop3_merge_srv_conf /* merge server configuration */
-};
-
-
-ngx_module_t ngx_mail_pop3_module = {
- NGX_MODULE_V1,
- &ngx_mail_pop3_module_ctx, /* module context */
- ngx_mail_pop3_commands, /* module directives */
- NGX_MAIL_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static void *
-ngx_mail_pop3_create_srv_conf(ngx_conf_t *cf)
-{
- ngx_mail_pop3_srv_conf_t *pscf;
-
- pscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_pop3_srv_conf_t));
- if (pscf == NULL) {
- return NULL;
- }
-
- if (ngx_array_init(&pscf->capabilities, cf->pool, 4, sizeof(ngx_str_t))
- != NGX_OK)
- {
- return NULL;
- }
-
- return pscf;
-}
-
-
-static char *
-ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_mail_pop3_srv_conf_t *prev = parent;
- ngx_mail_pop3_srv_conf_t *conf = child;
-
- u_char *p;
- size_t size, stls_only_size;
- ngx_str_t *c, *d;
- ngx_uint_t i;
-
- ngx_conf_merge_bitmask_value(conf->auth_methods,
- prev->auth_methods,
- (NGX_CONF_BITMASK_SET
- |NGX_MAIL_AUTH_PLAIN_ENABLED));
-
- if (conf->capabilities.nelts == 0) {
- conf->capabilities = prev->capabilities;
- }
-
- if (conf->capabilities.nelts == 0) {
-
- for (d = ngx_mail_pop3_default_capabilities; d->len; d++) {
- c = ngx_array_push(&conf->capabilities);
- if (c == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *c = *d;
- }
- }
-
- size = sizeof("+OK Capability list follows" CRLF) - 1
- + sizeof("." CRLF) - 1;
-
- stls_only_size = size + sizeof("STLS" CRLF) - 1;
-
- c = conf->capabilities.elts;
- for (i = 0; i < conf->capabilities.nelts; i++) {
- size += c[i].len + sizeof(CRLF) - 1;
-
- if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
- continue;
- }
-
- stls_only_size += c[i].len + sizeof(CRLF) - 1;
- }
-
- if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
- size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1;
-
- } else {
- size += sizeof("SASL LOGIN PLAIN" CRLF) - 1;
- }
-
- p = ngx_pnalloc(cf->pool, size);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->capability.len = size;
- conf->capability.data = p;
-
- p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
- sizeof("+OK Capability list follows" CRLF) - 1);
-
- for (i = 0; i < conf->capabilities.nelts; i++) {
- p = ngx_cpymem(p, c[i].data, c[i].len);
- *p++ = CR; *p++ = LF;
- }
-
- if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
- p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF,
- sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1);
-
- } else {
- p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF,
- sizeof("SASL LOGIN PLAIN" CRLF) - 1);
- }
-
- *p++ = '.'; *p++ = CR; *p = LF;
-
-
- size += sizeof("STLS" CRLF) - 1;
-
- p = ngx_pnalloc(cf->pool, size);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->starttls_capability.len = size;
- conf->starttls_capability.data = p;
-
- p = ngx_cpymem(p, conf->capability.data,
- conf->capability.len - (sizeof("." CRLF) - 1));
-
- p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
- *p++ = '.'; *p++ = CR; *p = LF;
-
-
- if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
- conf->auth_capability = ngx_mail_pop3_auth_cram_md5_capability;
-
- } else {
- conf->auth_capability = ngx_mail_pop3_auth_plain_capability;
- }
-
-
- p = ngx_pnalloc(cf->pool, stls_only_size);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->starttls_only_capability.len = stls_only_size;
- conf->starttls_only_capability.data = p;
-
- p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
- sizeof("+OK Capability list follows" CRLF) - 1);
-
- for (i = 0; i < conf->capabilities.nelts; i++) {
- if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
- continue;
- }
-
- p = ngx_cpymem(p, c[i].data, c[i].len);
- *p++ = CR; *p++ = LF;
- }
-
- p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
- *p++ = '.'; *p++ = CR; *p = LF;
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_pop3_module.h b/usr.sbin/nginx/src/mail/ngx_mail_pop3_module.h
deleted file mode 100644
index 86947a77251..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_pop3_module.h
+++ /dev/null
@@ -1,38 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_MAIL_POP3_MODULE_H_INCLUDED_
-#define _NGX_MAIL_POP3_MODULE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_mail.h>
-
-
-typedef struct {
- ngx_str_t capability;
- ngx_str_t starttls_capability;
- ngx_str_t starttls_only_capability;
- ngx_str_t auth_capability;
-
- ngx_uint_t auth_methods;
-
- ngx_array_t capabilities;
-} ngx_mail_pop3_srv_conf_t;
-
-
-void ngx_mail_pop3_init_session(ngx_mail_session_t *s, ngx_connection_t *c);
-void ngx_mail_pop3_init_protocol(ngx_event_t *rev);
-void ngx_mail_pop3_auth_state(ngx_event_t *rev);
-ngx_int_t ngx_mail_pop3_parse_command(ngx_mail_session_t *s);
-
-
-extern ngx_module_t ngx_mail_pop3_module;
-
-
-#endif /* _NGX_MAIL_POP3_MODULE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_proxy_module.c b/usr.sbin/nginx/src/mail/ngx_mail_proxy_module.c
deleted file mode 100644
index 41cbcf6e312..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_proxy_module.c
+++ /dev/null
@@ -1,1136 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_event_connect.h>
-#include <ngx_mail.h>
-
-
-typedef struct {
- ngx_flag_t enable;
- ngx_flag_t pass_error_message;
- ngx_flag_t xclient;
- size_t buffer_size;
- ngx_msec_t timeout;
-} ngx_mail_proxy_conf_t;
-
-
-static void ngx_mail_proxy_block_read(ngx_event_t *rev);
-static void ngx_mail_proxy_pop3_handler(ngx_event_t *rev);
-static void ngx_mail_proxy_imap_handler(ngx_event_t *rev);
-static void ngx_mail_proxy_smtp_handler(ngx_event_t *rev);
-static void ngx_mail_proxy_dummy_handler(ngx_event_t *ev);
-static ngx_int_t ngx_mail_proxy_read_response(ngx_mail_session_t *s,
- ngx_uint_t state);
-static void ngx_mail_proxy_handler(ngx_event_t *ev);
-static void ngx_mail_proxy_upstream_error(ngx_mail_session_t *s);
-static void ngx_mail_proxy_internal_server_error(ngx_mail_session_t *s);
-static void ngx_mail_proxy_close_session(ngx_mail_session_t *s);
-static void *ngx_mail_proxy_create_conf(ngx_conf_t *cf);
-static char *ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-
-
-static ngx_command_t ngx_mail_proxy_commands[] = {
-
- { ngx_string("proxy"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_proxy_conf_t, enable),
- NULL },
-
- { ngx_string("proxy_buffer"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_proxy_conf_t, buffer_size),
- NULL },
-
- { ngx_string("proxy_timeout"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_proxy_conf_t, timeout),
- NULL },
-
- { ngx_string("proxy_pass_error_message"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_proxy_conf_t, pass_error_message),
- NULL },
-
- { ngx_string("xclient"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_proxy_conf_t, xclient),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_mail_module_t ngx_mail_proxy_module_ctx = {
- NULL, /* protocol */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- ngx_mail_proxy_create_conf, /* create server configuration */
- ngx_mail_proxy_merge_conf /* merge server configuration */
-};
-
-
-ngx_module_t ngx_mail_proxy_module = {
- NGX_MODULE_V1,
- &ngx_mail_proxy_module_ctx, /* module context */
- ngx_mail_proxy_commands, /* module directives */
- NGX_MAIL_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static u_char smtp_auth_ok[] = "235 2.0.0 OK" CRLF;
-
-
-void
-ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer)
-{
- int keepalive;
- ngx_int_t rc;
- ngx_mail_proxy_ctx_t *p;
- ngx_mail_proxy_conf_t *pcf;
- ngx_mail_core_srv_conf_t *cscf;
-
- s->connection->log->action = "connecting to upstream";
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- if (cscf->so_keepalive) {
- keepalive = 1;
-
- if (setsockopt(s->connection->fd, SOL_SOCKET, SO_KEEPALIVE,
- (const void *) &keepalive, sizeof(int))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, s->connection->log, ngx_socket_errno,
- "setsockopt(SO_KEEPALIVE) failed");
- }
- }
-
- p = ngx_pcalloc(s->connection->pool, sizeof(ngx_mail_proxy_ctx_t));
- if (p == NULL) {
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- s->proxy = p;
-
- p->upstream.sockaddr = peer->sockaddr;
- p->upstream.socklen = peer->socklen;
- p->upstream.name = &peer->name;
- p->upstream.get = ngx_event_get_peer;
- p->upstream.log = s->connection->log;
- p->upstream.log_error = NGX_ERROR_ERR;
-
- rc = ngx_event_connect_peer(&p->upstream);
-
- if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) {
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- ngx_add_timer(p->upstream.connection->read, cscf->timeout);
-
- p->upstream.connection->data = s;
- p->upstream.connection->pool = s->connection->pool;
-
- s->connection->read->handler = ngx_mail_proxy_block_read;
- p->upstream.connection->write->handler = ngx_mail_proxy_dummy_handler;
-
- pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
-
- s->proxy->buffer = ngx_create_temp_buf(s->connection->pool,
- pcf->buffer_size);
- if (s->proxy->buffer == NULL) {
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- s->out.len = 0;
-
- switch (s->protocol) {
-
- case NGX_MAIL_POP3_PROTOCOL:
- p->upstream.connection->read->handler = ngx_mail_proxy_pop3_handler;
- s->mail_state = ngx_pop3_start;
- break;
-
- case NGX_MAIL_IMAP_PROTOCOL:
- p->upstream.connection->read->handler = ngx_mail_proxy_imap_handler;
- s->mail_state = ngx_imap_start;
- break;
-
- default: /* NGX_MAIL_SMTP_PROTOCOL */
- p->upstream.connection->read->handler = ngx_mail_proxy_smtp_handler;
- s->mail_state = ngx_smtp_start;
- break;
- }
-}
-
-
-static void
-ngx_mail_proxy_block_read(ngx_event_t *rev)
-{
- ngx_connection_t *c;
- ngx_mail_session_t *s;
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy block read");
-
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
- c = rev->data;
- s = c->data;
-
- ngx_mail_proxy_close_session(s);
- }
-}
-
-
-static void
-ngx_mail_proxy_pop3_handler(ngx_event_t *rev)
-{
- u_char *p;
- ngx_int_t rc;
- ngx_str_t line;
- ngx_connection_t *c;
- ngx_mail_session_t *s;
- ngx_mail_proxy_conf_t *pcf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
- "mail proxy pop3 auth handler");
-
- c = rev->data;
- s = c->data;
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
- "upstream timed out");
- c->timedout = 1;
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- rc = ngx_mail_proxy_read_response(s, 0);
-
- if (rc == NGX_AGAIN) {
- return;
- }
-
- if (rc == NGX_ERROR) {
- ngx_mail_proxy_upstream_error(s);
- return;
- }
-
- switch (s->mail_state) {
-
- case ngx_pop3_start:
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send user");
-
- s->connection->log->action = "sending user name to upstream";
-
- line.len = sizeof("USER ") - 1 + s->login.len + 2;
- line.data = ngx_pnalloc(c->pool, line.len);
- if (line.data == NULL) {
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- p = ngx_cpymem(line.data, "USER ", sizeof("USER ") - 1);
- p = ngx_cpymem(p, s->login.data, s->login.len);
- *p++ = CR; *p = LF;
-
- s->mail_state = ngx_pop3_user;
- break;
-
- case ngx_pop3_user:
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send pass");
-
- s->connection->log->action = "sending password to upstream";
-
- line.len = sizeof("PASS ") - 1 + s->passwd.len + 2;
- line.data = ngx_pnalloc(c->pool, line.len);
- if (line.data == NULL) {
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- p = ngx_cpymem(line.data, "PASS ", sizeof("PASS ") - 1);
- p = ngx_cpymem(p, s->passwd.data, s->passwd.len);
- *p++ = CR; *p = LF;
-
- s->mail_state = ngx_pop3_passwd;
- break;
-
- case ngx_pop3_passwd:
- s->connection->read->handler = ngx_mail_proxy_handler;
- s->connection->write->handler = ngx_mail_proxy_handler;
- rev->handler = ngx_mail_proxy_handler;
- c->write->handler = ngx_mail_proxy_handler;
-
- pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
- ngx_add_timer(s->connection->read, pcf->timeout);
- ngx_del_timer(c->read);
-
- c->log->action = NULL;
- ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
-
- ngx_mail_proxy_handler(s->connection->write);
-
- return;
-
- default:
-#if (NGX_SUPPRESS_WARN)
- ngx_str_null(&line);
-#endif
- break;
- }
-
- if (c->send(c, line.data, line.len) < (ssize_t) line.len) {
- /*
- * we treat the incomplete sending as NGX_ERROR
- * because it is very strange here
- */
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- s->proxy->buffer->pos = s->proxy->buffer->start;
- s->proxy->buffer->last = s->proxy->buffer->start;
-}
-
-
-static void
-ngx_mail_proxy_imap_handler(ngx_event_t *rev)
-{
- u_char *p;
- ngx_int_t rc;
- ngx_str_t line;
- ngx_connection_t *c;
- ngx_mail_session_t *s;
- ngx_mail_proxy_conf_t *pcf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
- "mail proxy imap auth handler");
-
- c = rev->data;
- s = c->data;
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
- "upstream timed out");
- c->timedout = 1;
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- rc = ngx_mail_proxy_read_response(s, s->mail_state);
-
- if (rc == NGX_AGAIN) {
- return;
- }
-
- if (rc == NGX_ERROR) {
- ngx_mail_proxy_upstream_error(s);
- return;
- }
-
- switch (s->mail_state) {
-
- case ngx_imap_start:
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
- "mail proxy send login");
-
- s->connection->log->action = "sending LOGIN command to upstream";
-
- line.len = s->tag.len + sizeof("LOGIN ") - 1
- + 1 + NGX_SIZE_T_LEN + 1 + 2;
- line.data = ngx_pnalloc(c->pool, line.len);
- if (line.data == NULL) {
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- line.len = ngx_sprintf(line.data, "%VLOGIN {%uz}" CRLF,
- &s->tag, s->login.len)
- - line.data;
-
- s->mail_state = ngx_imap_login;
- break;
-
- case ngx_imap_login:
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send user");
-
- s->connection->log->action = "sending user name to upstream";
-
- line.len = s->login.len + 1 + 1 + NGX_SIZE_T_LEN + 1 + 2;
- line.data = ngx_pnalloc(c->pool, line.len);
- if (line.data == NULL) {
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- line.len = ngx_sprintf(line.data, "%V {%uz}" CRLF,
- &s->login, s->passwd.len)
- - line.data;
-
- s->mail_state = ngx_imap_user;
- break;
-
- case ngx_imap_user:
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
- "mail proxy send passwd");
-
- s->connection->log->action = "sending password to upstream";
-
- line.len = s->passwd.len + 2;
- line.data = ngx_pnalloc(c->pool, line.len);
- if (line.data == NULL) {
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- p = ngx_cpymem(line.data, s->passwd.data, s->passwd.len);
- *p++ = CR; *p = LF;
-
- s->mail_state = ngx_imap_passwd;
- break;
-
- case ngx_imap_passwd:
- s->connection->read->handler = ngx_mail_proxy_handler;
- s->connection->write->handler = ngx_mail_proxy_handler;
- rev->handler = ngx_mail_proxy_handler;
- c->write->handler = ngx_mail_proxy_handler;
-
- pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
- ngx_add_timer(s->connection->read, pcf->timeout);
- ngx_del_timer(c->read);
-
- c->log->action = NULL;
- ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
-
- ngx_mail_proxy_handler(s->connection->write);
-
- return;
-
- default:
-#if (NGX_SUPPRESS_WARN)
- ngx_str_null(&line);
-#endif
- break;
- }
-
- if (c->send(c, line.data, line.len) < (ssize_t) line.len) {
- /*
- * we treat the incomplete sending as NGX_ERROR
- * because it is very strange here
- */
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- s->proxy->buffer->pos = s->proxy->buffer->start;
- s->proxy->buffer->last = s->proxy->buffer->start;
-}
-
-
-static void
-ngx_mail_proxy_smtp_handler(ngx_event_t *rev)
-{
- u_char *p;
- ngx_int_t rc;
- ngx_str_t line;
- ngx_buf_t *b;
- ngx_connection_t *c;
- ngx_mail_session_t *s;
- ngx_mail_proxy_conf_t *pcf;
- ngx_mail_core_srv_conf_t *cscf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
- "mail proxy smtp auth handler");
-
- c = rev->data;
- s = c->data;
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
- "upstream timed out");
- c->timedout = 1;
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- rc = ngx_mail_proxy_read_response(s, s->mail_state);
-
- if (rc == NGX_AGAIN) {
- return;
- }
-
- if (rc == NGX_ERROR) {
- ngx_mail_proxy_upstream_error(s);
- return;
- }
-
- switch (s->mail_state) {
-
- case ngx_smtp_start:
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send ehlo");
-
- s->connection->log->action = "sending HELO/EHLO to upstream";
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- line.len = sizeof("HELO ") - 1 + cscf->server_name.len + 2;
- line.data = ngx_pnalloc(c->pool, line.len);
- if (line.data == NULL) {
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
-
- p = ngx_cpymem(line.data,
- ((s->esmtp || pcf->xclient) ? "EHLO " : "HELO "),
- sizeof("HELO ") - 1);
-
- p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
- *p++ = CR; *p = LF;
-
- if (pcf->xclient) {
- s->mail_state = ngx_smtp_helo_xclient;
-
- } else if (s->auth_method == NGX_MAIL_AUTH_NONE) {
- s->mail_state = ngx_smtp_helo_from;
-
- } else {
- s->mail_state = ngx_smtp_helo;
- }
-
- break;
-
- case ngx_smtp_helo_xclient:
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
- "mail proxy send xclient");
-
- s->connection->log->action = "sending XCLIENT to upstream";
-
- line.len = sizeof("XCLIENT ADDR= LOGIN= NAME="
- CRLF) - 1
- + s->connection->addr_text.len + s->login.len + s->host.len;
-
-#if (NGX_HAVE_INET6)
- if (s->connection->sockaddr->sa_family == AF_INET6) {
- line.len += sizeof("IPV6:") - 1;
- }
-#endif
-
- line.data = ngx_pnalloc(c->pool, line.len);
- if (line.data == NULL) {
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- p = ngx_cpymem(line.data, "XCLIENT ADDR=", sizeof("XCLIENT ADDR=") - 1);
-
-#if (NGX_HAVE_INET6)
- if (s->connection->sockaddr->sa_family == AF_INET6) {
- p = ngx_cpymem(p, "IPV6:", sizeof("IPV6:") - 1);
- }
-#endif
-
- p = ngx_copy(p, s->connection->addr_text.data,
- s->connection->addr_text.len);
-
- if (s->login.len) {
- p = ngx_cpymem(p, " LOGIN=", sizeof(" LOGIN=") - 1);
- p = ngx_copy(p, s->login.data, s->login.len);
- }
-
- p = ngx_cpymem(p, " NAME=", sizeof(" NAME=") - 1);
- p = ngx_copy(p, s->host.data, s->host.len);
-
- *p++ = CR; *p++ = LF;
-
- line.len = p - line.data;
-
- if (s->smtp_helo.len) {
- s->mail_state = ngx_smtp_xclient_helo;
-
- } else if (s->auth_method == NGX_MAIL_AUTH_NONE) {
- s->mail_state = ngx_smtp_xclient_from;
-
- } else {
- s->mail_state = ngx_smtp_xclient;
- }
-
- break;
-
- case ngx_smtp_xclient_helo:
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
- "mail proxy send client ehlo");
-
- s->connection->log->action = "sending client HELO/EHLO to upstream";
-
- line.len = sizeof("HELO " CRLF) - 1 + s->smtp_helo.len;
-
- line.data = ngx_pnalloc(c->pool, line.len);
- if (line.data == NULL) {
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- line.len = ngx_sprintf(line.data,
- ((s->esmtp) ? "EHLO %V" CRLF : "HELO %V" CRLF),
- &s->smtp_helo)
- - line.data;
-
- s->mail_state = (s->auth_method == NGX_MAIL_AUTH_NONE) ?
- ngx_smtp_helo_from : ngx_smtp_helo;
-
- break;
-
- case ngx_smtp_helo_from:
- case ngx_smtp_xclient_from:
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
- "mail proxy send mail from");
-
- s->connection->log->action = "sending MAIL FROM to upstream";
-
- line.len = s->smtp_from.len + sizeof(CRLF) - 1;
- line.data = ngx_pnalloc(c->pool, line.len);
- if (line.data == NULL) {
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- p = ngx_cpymem(line.data, s->smtp_from.data, s->smtp_from.len);
- *p++ = CR; *p = LF;
-
- s->mail_state = ngx_smtp_from;
-
- break;
-
- case ngx_smtp_from:
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
- "mail proxy send rcpt to");
-
- s->connection->log->action = "sending RCPT TO to upstream";
-
- line.len = s->smtp_to.len + sizeof(CRLF) - 1;
- line.data = ngx_pnalloc(c->pool, line.len);
- if (line.data == NULL) {
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- p = ngx_cpymem(line.data, s->smtp_to.data, s->smtp_to.len);
- *p++ = CR; *p = LF;
-
- s->mail_state = ngx_smtp_to;
-
- break;
-
- case ngx_smtp_helo:
- case ngx_smtp_xclient:
- case ngx_smtp_to:
-
- b = s->proxy->buffer;
-
- if (s->auth_method == NGX_MAIL_AUTH_NONE) {
- b->pos = b->start;
-
- } else {
- ngx_memcpy(b->start, smtp_auth_ok, sizeof(smtp_auth_ok) - 1);
- b->last = b->start + sizeof(smtp_auth_ok) - 1;
- }
-
- s->connection->read->handler = ngx_mail_proxy_handler;
- s->connection->write->handler = ngx_mail_proxy_handler;
- rev->handler = ngx_mail_proxy_handler;
- c->write->handler = ngx_mail_proxy_handler;
-
- pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
- ngx_add_timer(s->connection->read, pcf->timeout);
- ngx_del_timer(c->read);
-
- c->log->action = NULL;
- ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in");
-
- if (s->buffer->pos == s->buffer->last) {
- ngx_mail_proxy_handler(s->connection->write);
-
- } else {
- ngx_mail_proxy_handler(c->write);
- }
-
- return;
-
- default:
-#if (NGX_SUPPRESS_WARN)
- ngx_str_null(&line);
-#endif
- break;
- }
-
- if (c->send(c, line.data, line.len) < (ssize_t) line.len) {
- /*
- * we treat the incomplete sending as NGX_ERROR
- * because it is very strange here
- */
- ngx_mail_proxy_internal_server_error(s);
- return;
- }
-
- s->proxy->buffer->pos = s->proxy->buffer->start;
- s->proxy->buffer->last = s->proxy->buffer->start;
-}
-
-
-static void
-ngx_mail_proxy_dummy_handler(ngx_event_t *wev)
-{
- ngx_connection_t *c;
- ngx_mail_session_t *s;
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0, "mail proxy dummy handler");
-
- if (ngx_handle_write_event(wev, 0) != NGX_OK) {
- c = wev->data;
- s = c->data;
-
- ngx_mail_proxy_close_session(s);
- }
-}
-
-
-static ngx_int_t
-ngx_mail_proxy_read_response(ngx_mail_session_t *s, ngx_uint_t state)
-{
- u_char *p, *m;
- ssize_t n;
- ngx_buf_t *b;
- ngx_mail_proxy_conf_t *pcf;
-
- s->connection->log->action = "reading response from upstream";
-
- b = s->proxy->buffer;
-
- n = s->proxy->upstream.connection->recv(s->proxy->upstream.connection,
- b->last, b->end - b->last);
-
- if (n == NGX_ERROR || n == 0) {
- return NGX_ERROR;
- }
-
- if (n == NGX_AGAIN) {
- return NGX_AGAIN;
- }
-
- b->last += n;
-
- if (b->last - b->pos < 4) {
- return NGX_AGAIN;
- }
-
- if (*(b->last - 2) != CR || *(b->last - 1) != LF) {
- if (b->last == b->end) {
- *(b->last - 1) = '\0';
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
- "upstream sent too long response line: \"%s\"",
- b->pos);
- return NGX_ERROR;
- }
-
- return NGX_AGAIN;
- }
-
- p = b->pos;
-
- switch (s->protocol) {
-
- case NGX_MAIL_POP3_PROTOCOL:
- if (p[0] == '+' && p[1] == 'O' && p[2] == 'K') {
- return NGX_OK;
- }
- break;
-
- case NGX_MAIL_IMAP_PROTOCOL:
- switch (state) {
-
- case ngx_imap_start:
- if (p[0] == '*' && p[1] == ' ' && p[2] == 'O' && p[3] == 'K') {
- return NGX_OK;
- }
- break;
-
- case ngx_imap_login:
- case ngx_imap_user:
- if (p[0] == '+') {
- return NGX_OK;
- }
- break;
-
- case ngx_imap_passwd:
- if (ngx_strncmp(p, s->tag.data, s->tag.len) == 0) {
- p += s->tag.len;
- if (p[0] == 'O' && p[1] == 'K') {
- return NGX_OK;
- }
- }
- break;
- }
-
- break;
-
- default: /* NGX_MAIL_SMTP_PROTOCOL */
-
- if (p[3] == '-') {
- /* multiline reply, check if we got last line */
-
- m = b->last - (sizeof(CRLF "200" CRLF) - 1);
-
- while (m > p) {
- if (m[0] == CR && m[1] == LF) {
- break;
- }
-
- m--;
- }
-
- if (m <= p || m[5] == '-') {
- return NGX_AGAIN;
- }
- }
-
- switch (state) {
-
- case ngx_smtp_start:
- if (p[0] == '2' && p[1] == '2' && p[2] == '0') {
- return NGX_OK;
- }
- break;
-
- case ngx_smtp_helo:
- case ngx_smtp_helo_xclient:
- case ngx_smtp_helo_from:
- case ngx_smtp_from:
- if (p[0] == '2' && p[1] == '5' && p[2] == '0') {
- return NGX_OK;
- }
- break;
-
- case ngx_smtp_xclient:
- case ngx_smtp_xclient_from:
- case ngx_smtp_xclient_helo:
- if (p[0] == '2' && (p[1] == '2' || p[1] == '5') && p[2] == '0') {
- return NGX_OK;
- }
- break;
-
- case ngx_smtp_to:
- return NGX_OK;
- }
-
- break;
- }
-
- pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
-
- if (pcf->pass_error_message == 0) {
- *(b->last - 2) = '\0';
- ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
- "upstream sent invalid response: \"%s\"", p);
- return NGX_ERROR;
- }
-
- s->out.len = b->last - p - 2;
- s->out.data = p;
-
- ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
- "upstream sent invalid response: \"%V\"", &s->out);
-
- s->out.len = b->last - b->pos;
- s->out.data = b->pos;
-
- return NGX_ERROR;
-}
-
-
-static void
-ngx_mail_proxy_handler(ngx_event_t *ev)
-{
- char *action, *recv_action, *send_action;
- size_t size;
- ssize_t n;
- ngx_buf_t *b;
- ngx_uint_t do_write;
- ngx_connection_t *c, *src, *dst;
- ngx_mail_session_t *s;
- ngx_mail_proxy_conf_t *pcf;
-
- c = ev->data;
- s = c->data;
-
- if (ev->timedout) {
- c->log->action = "proxying";
-
- if (c == s->connection) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
- "client timed out");
- c->timedout = 1;
-
- } else {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
- "upstream timed out");
- }
-
- ngx_mail_proxy_close_session(s);
- return;
- }
-
- if (c == s->connection) {
- if (ev->write) {
- recv_action = "proxying and reading from upstream";
- send_action = "proxying and sending to client";
- src = s->proxy->upstream.connection;
- dst = c;
- b = s->proxy->buffer;
-
- } else {
- recv_action = "proxying and reading from client";
- send_action = "proxying and sending to upstream";
- src = c;
- dst = s->proxy->upstream.connection;
- b = s->buffer;
- }
-
- } else {
- if (ev->write) {
- recv_action = "proxying and reading from client";
- send_action = "proxying and sending to upstream";
- src = s->connection;
- dst = c;
- b = s->buffer;
-
- } else {
- recv_action = "proxying and reading from upstream";
- send_action = "proxying and sending to client";
- src = c;
- dst = s->connection;
- b = s->proxy->buffer;
- }
- }
-
- do_write = ev->write ? 1 : 0;
-
- ngx_log_debug3(NGX_LOG_DEBUG_MAIL, ev->log, 0,
- "mail proxy handler: %d, #%d > #%d",
- do_write, src->fd, dst->fd);
-
- for ( ;; ) {
-
- if (do_write) {
-
- size = b->last - b->pos;
-
- if (size && dst->write->ready) {
- c->log->action = send_action;
-
- n = dst->send(dst, b->pos, size);
-
- if (n == NGX_ERROR) {
- ngx_mail_proxy_close_session(s);
- return;
- }
-
- if (n > 0) {
- b->pos += n;
-
- if (b->pos == b->last) {
- b->pos = b->start;
- b->last = b->start;
- }
- }
- }
- }
-
- size = b->end - b->last;
-
- if (size && src->read->ready) {
- c->log->action = recv_action;
-
- n = src->recv(src, b->last, size);
-
- if (n == NGX_AGAIN || n == 0) {
- break;
- }
-
- if (n > 0) {
- do_write = 1;
- b->last += n;
-
- continue;
- }
-
- if (n == NGX_ERROR) {
- src->read->eof = 1;
- }
- }
-
- break;
- }
-
- c->log->action = "proxying";
-
- if ((s->connection->read->eof && s->buffer->pos == s->buffer->last)
- || (s->proxy->upstream.connection->read->eof
- && s->proxy->buffer->pos == s->proxy->buffer->last)
- || (s->connection->read->eof
- && s->proxy->upstream.connection->read->eof))
- {
- action = c->log->action;
- c->log->action = NULL;
- ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxied session done");
- c->log->action = action;
-
- ngx_mail_proxy_close_session(s);
- return;
- }
-
- if (ngx_handle_write_event(dst->write, 0) != NGX_OK) {
- ngx_mail_proxy_close_session(s);
- return;
- }
-
- if (ngx_handle_read_event(dst->read, 0) != NGX_OK) {
- ngx_mail_proxy_close_session(s);
- return;
- }
-
- if (ngx_handle_write_event(src->write, 0) != NGX_OK) {
- ngx_mail_proxy_close_session(s);
- return;
- }
-
- if (ngx_handle_read_event(src->read, 0) != NGX_OK) {
- ngx_mail_proxy_close_session(s);
- return;
- }
-
- if (c == s->connection) {
- pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module);
- ngx_add_timer(c->read, pcf->timeout);
- }
-}
-
-
-static void
-ngx_mail_proxy_upstream_error(ngx_mail_session_t *s)
-{
- if (s->proxy->upstream.connection) {
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
- "close mail proxy connection: %d",
- s->proxy->upstream.connection->fd);
-
- ngx_close_connection(s->proxy->upstream.connection);
- }
-
- if (s->out.len == 0) {
- ngx_mail_session_internal_server_error(s);
- return;
- }
-
- s->quit = 1;
- ngx_mail_send(s->connection->write);
-}
-
-
-static void
-ngx_mail_proxy_internal_server_error(ngx_mail_session_t *s)
-{
- if (s->proxy->upstream.connection) {
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
- "close mail proxy connection: %d",
- s->proxy->upstream.connection->fd);
-
- ngx_close_connection(s->proxy->upstream.connection);
- }
-
- ngx_mail_session_internal_server_error(s);
-}
-
-
-static void
-ngx_mail_proxy_close_session(ngx_mail_session_t *s)
-{
- if (s->proxy->upstream.connection) {
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
- "close mail proxy connection: %d",
- s->proxy->upstream.connection->fd);
-
- ngx_close_connection(s->proxy->upstream.connection);
- }
-
- ngx_mail_close_connection(s->connection);
-}
-
-
-static void *
-ngx_mail_proxy_create_conf(ngx_conf_t *cf)
-{
- ngx_mail_proxy_conf_t *pcf;
-
- pcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_proxy_conf_t));
- if (pcf == NULL) {
- return NULL;
- }
-
- pcf->enable = NGX_CONF_UNSET;
- pcf->pass_error_message = NGX_CONF_UNSET;
- pcf->xclient = NGX_CONF_UNSET;
- pcf->buffer_size = NGX_CONF_UNSET_SIZE;
- pcf->timeout = NGX_CONF_UNSET_MSEC;
-
- return pcf;
-}
-
-
-static char *
-ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_mail_proxy_conf_t *prev = parent;
- ngx_mail_proxy_conf_t *conf = child;
-
- ngx_conf_merge_value(conf->enable, prev->enable, 0);
- ngx_conf_merge_value(conf->pass_error_message, prev->pass_error_message, 0);
- ngx_conf_merge_value(conf->xclient, prev->xclient, 1);
- ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
- (size_t) ngx_pagesize);
- ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000);
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_smtp_handler.c b/usr.sbin/nginx/src/mail/ngx_mail_smtp_handler.c
deleted file mode 100644
index 52fe475234a..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_smtp_handler.c
+++ /dev/null
@@ -1,844 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_mail.h>
-#include <ngx_mail_smtp_module.h>
-
-
-static void ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx);
-static void ngx_mail_smtp_resolve_name(ngx_event_t *rev);
-static void ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx);
-static void ngx_mail_smtp_greeting(ngx_mail_session_t *s, ngx_connection_t *c);
-static void ngx_mail_smtp_invalid_pipelining(ngx_event_t *rev);
-static ngx_int_t ngx_mail_smtp_create_buffer(ngx_mail_session_t *s,
- ngx_connection_t *c);
-
-static ngx_int_t ngx_mail_smtp_helo(ngx_mail_session_t *s, ngx_connection_t *c);
-static ngx_int_t ngx_mail_smtp_auth(ngx_mail_session_t *s, ngx_connection_t *c);
-static ngx_int_t ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c);
-static ngx_int_t ngx_mail_smtp_starttls(ngx_mail_session_t *s,
- ngx_connection_t *c);
-static ngx_int_t ngx_mail_smtp_rset(ngx_mail_session_t *s, ngx_connection_t *c);
-static ngx_int_t ngx_mail_smtp_rcpt(ngx_mail_session_t *s, ngx_connection_t *c);
-
-static ngx_int_t ngx_mail_smtp_discard_command(ngx_mail_session_t *s,
- ngx_connection_t *c, char *err);
-static void ngx_mail_smtp_log_rejected_command(ngx_mail_session_t *s,
- ngx_connection_t *c, char *err);
-
-
-static u_char smtp_ok[] = "250 2.0.0 OK" CRLF;
-static u_char smtp_bye[] = "221 2.0.0 Bye" CRLF;
-static u_char smtp_starttls[] = "220 2.0.0 Start TLS" CRLF;
-static u_char smtp_next[] = "334 " CRLF;
-static u_char smtp_username[] = "334 VXNlcm5hbWU6" CRLF;
-static u_char smtp_password[] = "334 UGFzc3dvcmQ6" CRLF;
-static u_char smtp_invalid_command[] = "500 5.5.1 Invalid command" CRLF;
-static u_char smtp_invalid_pipelining[] =
- "503 5.5.0 Improper use of SMTP command pipelining" CRLF;
-static u_char smtp_invalid_argument[] = "501 5.5.4 Invalid argument" CRLF;
-static u_char smtp_auth_required[] = "530 5.7.1 Authentication required" CRLF;
-static u_char smtp_bad_sequence[] = "503 5.5.1 Bad sequence of commands" CRLF;
-
-
-static ngx_str_t smtp_unavailable = ngx_string("[UNAVAILABLE]");
-static ngx_str_t smtp_tempunavail = ngx_string("[TEMPUNAVAIL]");
-
-
-void
-ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_resolver_ctx_t *ctx;
- ngx_mail_core_srv_conf_t *cscf;
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- if (cscf->resolver == NULL) {
- s->host = smtp_unavailable;
- ngx_mail_smtp_greeting(s, c);
- return;
- }
-
-#if (NGX_HAVE_UNIX_DOMAIN)
- if (c->sockaddr->sa_family == AF_UNIX) {
- s->host = smtp_tempunavail;
- ngx_mail_smtp_greeting(s, c);
- return;
- }
-#endif
-
- c->log->action = "in resolving client address";
-
- ctx = ngx_resolve_start(cscf->resolver, NULL);
- if (ctx == NULL) {
- ngx_mail_close_connection(c);
- return;
- }
-
- ctx->addr.sockaddr = c->sockaddr;
- ctx->addr.socklen = c->socklen;
- ctx->handler = ngx_mail_smtp_resolve_addr_handler;
- ctx->data = s;
- ctx->timeout = cscf->resolver_timeout;
-
- if (ngx_resolve_addr(ctx) != NGX_OK) {
- ngx_mail_close_connection(c);
- }
-}
-
-
-static void
-ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx)
-{
- ngx_connection_t *c;
- ngx_mail_session_t *s;
-
- s = ctx->data;
- c = s->connection;
-
- if (ctx->state) {
- ngx_log_error(NGX_LOG_ERR, c->log, 0,
- "%V could not be resolved (%i: %s)",
- &c->addr_text, ctx->state,
- ngx_resolver_strerror(ctx->state));
-
- if (ctx->state == NGX_RESOLVE_NXDOMAIN) {
- s->host = smtp_unavailable;
-
- } else {
- s->host = smtp_tempunavail;
- }
-
- ngx_resolve_addr_done(ctx);
-
- ngx_mail_smtp_greeting(s, s->connection);
-
- return;
- }
-
- c->log->action = "in resolving client hostname";
-
- s->host.data = ngx_pstrdup(c->pool, &ctx->name);
- if (s->host.data == NULL) {
- ngx_resolve_addr_done(ctx);
- ngx_mail_close_connection(c);
- return;
- }
-
- s->host.len = ctx->name.len;
-
- ngx_resolve_addr_done(ctx);
-
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "address resolved: %V", &s->host);
-
- c->read->handler = ngx_mail_smtp_resolve_name;
-
- ngx_post_event(c->read, &ngx_posted_events);
-}
-
-
-static void
-ngx_mail_smtp_resolve_name(ngx_event_t *rev)
-{
- ngx_connection_t *c;
- ngx_mail_session_t *s;
- ngx_resolver_ctx_t *ctx;
- ngx_mail_core_srv_conf_t *cscf;
-
- c = rev->data;
- s = c->data;
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- ctx = ngx_resolve_start(cscf->resolver, NULL);
- if (ctx == NULL) {
- ngx_mail_close_connection(c);
- return;
- }
-
- ctx->name = s->host;
- ctx->handler = ngx_mail_smtp_resolve_name_handler;
- ctx->data = s;
- ctx->timeout = cscf->resolver_timeout;
-
- if (ngx_resolve_name(ctx) != NGX_OK) {
- ngx_mail_close_connection(c);
- }
-}
-
-
-static void
-ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx)
-{
- ngx_uint_t i;
- ngx_connection_t *c;
- ngx_mail_session_t *s;
-
- s = ctx->data;
- c = s->connection;
-
- if (ctx->state) {
- ngx_log_error(NGX_LOG_ERR, c->log, 0,
- "\"%V\" could not be resolved (%i: %s)",
- &ctx->name, ctx->state,
- ngx_resolver_strerror(ctx->state));
-
- if (ctx->state == NGX_RESOLVE_NXDOMAIN) {
- s->host = smtp_unavailable;
-
- } else {
- s->host = smtp_tempunavail;
- }
-
- } else {
-
-#if (NGX_DEBUG)
- {
- u_char text[NGX_SOCKADDR_STRLEN];
- ngx_str_t addr;
-
- addr.data = text;
-
- for (i = 0; i < ctx->naddrs; i++) {
- addr.len = ngx_sock_ntop(ctx->addrs[i].sockaddr,
- ctx->addrs[i].socklen,
- text, NGX_SOCKADDR_STRLEN, 0);
-
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "name was resolved to %V", &addr);
- }
- }
-#endif
-
- for (i = 0; i < ctx->naddrs; i++) {
- if (ngx_cmp_sockaddr(ctx->addrs[i].sockaddr, ctx->addrs[i].socklen,
- c->sockaddr, c->socklen, 0)
- == NGX_OK)
- {
- goto found;
- }
- }
-
- s->host = smtp_unavailable;
- }
-
-found:
-
- ngx_resolve_name_done(ctx);
-
- ngx_mail_smtp_greeting(s, c);
-}
-
-
-static void
-ngx_mail_smtp_greeting(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_msec_t timeout;
- ngx_mail_core_srv_conf_t *cscf;
- ngx_mail_smtp_srv_conf_t *sscf;
-
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "smtp greeting for \"%V\"", &s->host);
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
- sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
-
- timeout = sscf->greeting_delay ? sscf->greeting_delay : cscf->timeout;
- ngx_add_timer(c->read, timeout);
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- ngx_mail_close_connection(c);
- }
-
- if (sscf->greeting_delay) {
- c->read->handler = ngx_mail_smtp_invalid_pipelining;
- return;
- }
-
- c->read->handler = ngx_mail_smtp_init_protocol;
-
- s->out = sscf->greeting;
-
- ngx_mail_send(c->write);
-}
-
-
-static void
-ngx_mail_smtp_invalid_pipelining(ngx_event_t *rev)
-{
- ngx_connection_t *c;
- ngx_mail_session_t *s;
- ngx_mail_core_srv_conf_t *cscf;
- ngx_mail_smtp_srv_conf_t *sscf;
-
- c = rev->data;
- s = c->data;
-
- c->log->action = "in delay pipelining state";
-
- if (rev->timedout) {
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "delay greeting");
-
- rev->timedout = 0;
-
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- c->read->handler = ngx_mail_smtp_init_protocol;
-
- ngx_add_timer(c->read, cscf->timeout);
-
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- ngx_mail_close_connection(c);
- return;
- }
-
- sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
-
- s->out = sscf->greeting;
-
- } else {
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "invalid pipelining");
-
- if (s->buffer == NULL) {
- if (ngx_mail_smtp_create_buffer(s, c) != NGX_OK) {
- return;
- }
- }
-
- if (ngx_mail_smtp_discard_command(s, c,
- "client was rejected before greeting: \"%V\"")
- != NGX_OK)
- {
- return;
- }
-
- ngx_str_set(&s->out, smtp_invalid_pipelining);
- s->quit = 1;
- }
-
- ngx_mail_send(c->write);
-}
-
-
-void
-ngx_mail_smtp_init_protocol(ngx_event_t *rev)
-{
- ngx_connection_t *c;
- ngx_mail_session_t *s;
-
- c = rev->data;
-
- c->log->action = "in auth state";
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
- c->timedout = 1;
- ngx_mail_close_connection(c);
- return;
- }
-
- s = c->data;
-
- if (s->buffer == NULL) {
- if (ngx_mail_smtp_create_buffer(s, c) != NGX_OK) {
- return;
- }
- }
-
- s->mail_state = ngx_smtp_start;
- c->read->handler = ngx_mail_smtp_auth_state;
-
- ngx_mail_smtp_auth_state(rev);
-}
-
-
-static ngx_int_t
-ngx_mail_smtp_create_buffer(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_mail_smtp_srv_conf_t *sscf;
-
- if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t)) == NGX_ERROR) {
- ngx_mail_session_internal_server_error(s);
- return NGX_ERROR;
- }
-
- sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
-
- s->buffer = ngx_create_temp_buf(c->pool, sscf->client_buffer_size);
- if (s->buffer == NULL) {
- ngx_mail_session_internal_server_error(s);
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-void
-ngx_mail_smtp_auth_state(ngx_event_t *rev)
-{
- ngx_int_t rc;
- ngx_connection_t *c;
- ngx_mail_session_t *s;
-
- c = rev->data;
- s = c->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "smtp auth state");
-
- if (rev->timedout) {
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
- c->timedout = 1;
- ngx_mail_close_connection(c);
- return;
- }
-
- if (s->out.len) {
- ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "smtp send handler busy");
- s->blocked = 1;
- return;
- }
-
- s->blocked = 0;
-
- rc = ngx_mail_read_command(s, c);
-
- if (rc == NGX_AGAIN || rc == NGX_ERROR) {
- return;
- }
-
- ngx_str_set(&s->out, smtp_ok);
-
- if (rc == NGX_OK) {
- switch (s->mail_state) {
-
- case ngx_smtp_start:
-
- switch (s->command) {
-
- case NGX_SMTP_HELO:
- case NGX_SMTP_EHLO:
- rc = ngx_mail_smtp_helo(s, c);
- break;
-
- case NGX_SMTP_AUTH:
- rc = ngx_mail_smtp_auth(s, c);
- break;
-
- case NGX_SMTP_QUIT:
- s->quit = 1;
- ngx_str_set(&s->out, smtp_bye);
- break;
-
- case NGX_SMTP_MAIL:
- rc = ngx_mail_smtp_mail(s, c);
- break;
-
- case NGX_SMTP_RCPT:
- rc = ngx_mail_smtp_rcpt(s, c);
- break;
-
- case NGX_SMTP_RSET:
- rc = ngx_mail_smtp_rset(s, c);
- break;
-
- case NGX_SMTP_NOOP:
- break;
-
- case NGX_SMTP_STARTTLS:
- rc = ngx_mail_smtp_starttls(s, c);
- ngx_str_set(&s->out, smtp_starttls);
- break;
-
- default:
- rc = NGX_MAIL_PARSE_INVALID_COMMAND;
- break;
- }
-
- break;
-
- case ngx_smtp_auth_login_username:
- rc = ngx_mail_auth_login_username(s, c, 0);
-
- ngx_str_set(&s->out, smtp_password);
- s->mail_state = ngx_smtp_auth_login_password;
- break;
-
- case ngx_smtp_auth_login_password:
- rc = ngx_mail_auth_login_password(s, c);
- break;
-
- case ngx_smtp_auth_plain:
- rc = ngx_mail_auth_plain(s, c, 0);
- break;
-
- case ngx_smtp_auth_cram_md5:
- rc = ngx_mail_auth_cram_md5(s, c);
- break;
- }
- }
-
- if (s->buffer->pos < s->buffer->last) {
- s->blocked = 1;
- }
-
- switch (rc) {
-
- case NGX_DONE:
- ngx_mail_auth(s, c);
- return;
-
- case NGX_ERROR:
- ngx_mail_session_internal_server_error(s);
- return;
-
- case NGX_MAIL_PARSE_INVALID_COMMAND:
- s->mail_state = ngx_smtp_start;
- s->state = 0;
- ngx_str_set(&s->out, smtp_invalid_command);
-
- /* fall through */
-
- case NGX_OK:
- s->args.nelts = 0;
-
- if (s->buffer->pos == s->buffer->last) {
- s->buffer->pos = s->buffer->start;
- s->buffer->last = s->buffer->start;
- }
-
- if (s->state) {
- s->arg_start = s->buffer->pos;
- }
-
- ngx_mail_send(c->write);
- }
-}
-
-
-static ngx_int_t
-ngx_mail_smtp_helo(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_str_t *arg;
- ngx_mail_smtp_srv_conf_t *sscf;
-
- if (s->args.nelts != 1) {
- ngx_str_set(&s->out, smtp_invalid_argument);
- s->state = 0;
- return NGX_OK;
- }
-
- arg = s->args.elts;
-
- s->smtp_helo.len = arg[0].len;
-
- s->smtp_helo.data = ngx_pnalloc(c->pool, arg[0].len);
- if (s->smtp_helo.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(s->smtp_helo.data, arg[0].data, arg[0].len);
-
- ngx_str_null(&s->smtp_from);
- ngx_str_null(&s->smtp_to);
-
- sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
-
- if (s->command == NGX_SMTP_HELO) {
- s->out = sscf->server_name;
-
- } else {
- s->esmtp = 1;
-
-#if (NGX_MAIL_SSL)
-
- if (c->ssl == NULL) {
- ngx_mail_ssl_conf_t *sslcf;
-
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
-
- if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) {
- s->out = sscf->starttls_capability;
- return NGX_OK;
- }
-
- if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
- s->out = sscf->starttls_only_capability;
- return NGX_OK;
- }
- }
-#endif
-
- s->out = sscf->capability;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_mail_smtp_auth(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_int_t rc;
- ngx_mail_core_srv_conf_t *cscf;
- ngx_mail_smtp_srv_conf_t *sscf;
-
-#if (NGX_MAIL_SSL)
- if (ngx_mail_starttls_only(s, c)) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-#endif
-
- if (s->args.nelts == 0) {
- ngx_str_set(&s->out, smtp_invalid_argument);
- s->state = 0;
- return NGX_OK;
- }
-
- rc = ngx_mail_auth_parse(s, c);
-
- switch (rc) {
-
- case NGX_MAIL_AUTH_LOGIN:
-
- ngx_str_set(&s->out, smtp_username);
- s->mail_state = ngx_smtp_auth_login_username;
-
- return NGX_OK;
-
- case NGX_MAIL_AUTH_LOGIN_USERNAME:
-
- ngx_str_set(&s->out, smtp_password);
- s->mail_state = ngx_smtp_auth_login_password;
-
- return ngx_mail_auth_login_username(s, c, 1);
-
- case NGX_MAIL_AUTH_PLAIN:
-
- ngx_str_set(&s->out, smtp_next);
- s->mail_state = ngx_smtp_auth_plain;
-
- return NGX_OK;
-
- case NGX_MAIL_AUTH_CRAM_MD5:
-
- sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
-
- if (!(sscf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- if (s->salt.data == NULL) {
- cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
-
- if (ngx_mail_salt(s, c, cscf) != NGX_OK) {
- return NGX_ERROR;
- }
- }
-
- if (ngx_mail_auth_cram_md5_salt(s, c, "334 ", 4) == NGX_OK) {
- s->mail_state = ngx_smtp_auth_cram_md5;
- return NGX_OK;
- }
-
- return NGX_ERROR;
- }
-
- return rc;
-}
-
-
-static ngx_int_t
-ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_str_t *arg, cmd;
- ngx_mail_smtp_srv_conf_t *sscf;
-
- sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
-
- if (!(sscf->auth_methods & NGX_MAIL_AUTH_NONE_ENABLED)) {
- ngx_mail_smtp_log_rejected_command(s, c, "client was rejected: \"%V\"");
- ngx_str_set(&s->out, smtp_auth_required);
- return NGX_OK;
- }
-
- /* auth none */
-
- if (s->smtp_from.len) {
- ngx_str_set(&s->out, smtp_bad_sequence);
- return NGX_OK;
- }
-
- arg = s->args.elts;
- arg += s->args.nelts - 1;
-
- cmd.len = arg->data + arg->len - s->cmd.data;
- cmd.data = s->cmd.data;
-
- s->smtp_from.len = cmd.len;
-
- s->smtp_from.data = ngx_pnalloc(c->pool, cmd.len);
- if (s->smtp_from.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(s->smtp_from.data, cmd.data, cmd.len);
-
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "smtp mail from:\"%V\"", &s->smtp_from);
-
- ngx_str_set(&s->out, smtp_ok);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_mail_smtp_rcpt(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_str_t *arg, cmd;
-
- if (s->smtp_from.len == 0) {
- ngx_str_set(&s->out, smtp_bad_sequence);
- return NGX_OK;
- }
-
- arg = s->args.elts;
- arg += s->args.nelts - 1;
-
- cmd.len = arg->data + arg->len - s->cmd.data;
- cmd.data = s->cmd.data;
-
- s->smtp_to.len = cmd.len;
-
- s->smtp_to.data = ngx_pnalloc(c->pool, cmd.len);
- if (s->smtp_to.data == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(s->smtp_to.data, cmd.data, cmd.len);
-
- ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
- "smtp rcpt to:\"%V\"", &s->smtp_to);
-
- s->auth_method = NGX_MAIL_AUTH_NONE;
-
- return NGX_DONE;
-}
-
-
-static ngx_int_t
-ngx_mail_smtp_rset(ngx_mail_session_t *s, ngx_connection_t *c)
-{
- ngx_str_null(&s->smtp_from);
- ngx_str_null(&s->smtp_to);
- ngx_str_set(&s->out, smtp_ok);
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_mail_smtp_starttls(ngx_mail_session_t *s, ngx_connection_t *c)
-{
-#if (NGX_MAIL_SSL)
- ngx_mail_ssl_conf_t *sslcf;
-
- if (c->ssl == NULL) {
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
- if (sslcf->starttls) {
-
- /*
- * RFC3207 requires us to discard any knowledge
- * obtained from client before STARTTLS.
- */
-
- ngx_str_null(&s->smtp_helo);
- ngx_str_null(&s->smtp_from);
- ngx_str_null(&s->smtp_to);
-
- c->read->handler = ngx_mail_starttls_handler;
- return NGX_OK;
- }
- }
-
-#endif
-
- return NGX_MAIL_PARSE_INVALID_COMMAND;
-}
-
-
-static ngx_int_t
-ngx_mail_smtp_discard_command(ngx_mail_session_t *s, ngx_connection_t *c,
- char *err)
-{
- ssize_t n;
-
- n = c->recv(c, s->buffer->last, s->buffer->end - s->buffer->last);
-
- if (n == NGX_ERROR || n == 0) {
- ngx_mail_close_connection(c);
- return NGX_ERROR;
- }
-
- if (n > 0) {
- s->buffer->last += n;
- }
-
- if (n == NGX_AGAIN) {
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- ngx_mail_session_internal_server_error(s);
- return NGX_ERROR;
- }
-
- return NGX_AGAIN;
- }
-
- ngx_mail_smtp_log_rejected_command(s, c, err);
-
- s->buffer->pos = s->buffer->start;
- s->buffer->last = s->buffer->start;
-
- return NGX_OK;
-}
-
-
-static void
-ngx_mail_smtp_log_rejected_command(ngx_mail_session_t *s, ngx_connection_t *c,
- char *err)
-{
- u_char ch;
- ngx_str_t cmd;
- ngx_uint_t i;
-
- if (c->log->log_level < NGX_LOG_INFO) {
- return;
- }
-
- cmd.len = s->buffer->last - s->buffer->start;
- cmd.data = s->buffer->start;
-
- for (i = 0; i < cmd.len; i++) {
- ch = cmd.data[i];
-
- if (ch != CR && ch != LF) {
- continue;
- }
-
- cmd.data[i] = '_';
- }
-
- cmd.len = i;
-
- ngx_log_error(NGX_LOG_INFO, c->log, 0, err, &cmd);
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_smtp_module.c b/usr.sbin/nginx/src/mail/ngx_mail_smtp_module.c
deleted file mode 100644
index 02bbf1fb9d8..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_smtp_module.c
+++ /dev/null
@@ -1,307 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_mail.h>
-#include <ngx_mail_smtp_module.h>
-
-
-static void *ngx_mail_smtp_create_srv_conf(ngx_conf_t *cf);
-static char *ngx_mail_smtp_merge_srv_conf(ngx_conf_t *cf, void *parent,
- void *child);
-
-
-static ngx_conf_bitmask_t ngx_mail_smtp_auth_methods[] = {
- { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
- { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED },
- { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
- { ngx_string("none"), NGX_MAIL_AUTH_NONE_ENABLED },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_str_t ngx_mail_smtp_auth_methods_names[] = {
- ngx_string("PLAIN"),
- ngx_string("LOGIN"),
- ngx_null_string, /* APOP */
- ngx_string("CRAM-MD5"),
- ngx_null_string /* NONE */
-};
-
-
-static ngx_mail_protocol_t ngx_mail_smtp_protocol = {
- ngx_string("smtp"),
- { 25, 465, 587, 0 },
- NGX_MAIL_SMTP_PROTOCOL,
-
- ngx_mail_smtp_init_session,
- ngx_mail_smtp_init_protocol,
- ngx_mail_smtp_parse_command,
- ngx_mail_smtp_auth_state,
-
- ngx_string("451 4.3.2 Internal server error" CRLF)
-};
-
-
-static ngx_command_t ngx_mail_smtp_commands[] = {
-
- { ngx_string("smtp_client_buffer"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_smtp_srv_conf_t, client_buffer_size),
- NULL },
-
- { ngx_string("smtp_greeting_delay"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_msec_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_smtp_srv_conf_t, greeting_delay),
- NULL },
-
- { ngx_string("smtp_capabilities"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
- ngx_mail_capabilities,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_smtp_srv_conf_t, capabilities),
- NULL },
-
- { ngx_string("smtp_auth"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_smtp_srv_conf_t, auth_methods),
- &ngx_mail_smtp_auth_methods },
-
- ngx_null_command
-};
-
-
-static ngx_mail_module_t ngx_mail_smtp_module_ctx = {
- &ngx_mail_smtp_protocol, /* protocol */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- ngx_mail_smtp_create_srv_conf, /* create server configuration */
- ngx_mail_smtp_merge_srv_conf /* merge server configuration */
-};
-
-
-ngx_module_t ngx_mail_smtp_module = {
- NGX_MODULE_V1,
- &ngx_mail_smtp_module_ctx, /* module context */
- ngx_mail_smtp_commands, /* module directives */
- NGX_MAIL_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static void *
-ngx_mail_smtp_create_srv_conf(ngx_conf_t *cf)
-{
- ngx_mail_smtp_srv_conf_t *sscf;
-
- sscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_smtp_srv_conf_t));
- if (sscf == NULL) {
- return NULL;
- }
-
- sscf->client_buffer_size = NGX_CONF_UNSET_SIZE;
- sscf->greeting_delay = NGX_CONF_UNSET_MSEC;
-
- if (ngx_array_init(&sscf->capabilities, cf->pool, 4, sizeof(ngx_str_t))
- != NGX_OK)
- {
- return NULL;
- }
-
- return sscf;
-}
-
-
-static char *
-ngx_mail_smtp_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_mail_smtp_srv_conf_t *prev = parent;
- ngx_mail_smtp_srv_conf_t *conf = child;
-
- u_char *p, *auth, *last;
- size_t size;
- ngx_str_t *c;
- ngx_uint_t i, m, auth_enabled;
- ngx_mail_core_srv_conf_t *cscf;
-
- ngx_conf_merge_size_value(conf->client_buffer_size,
- prev->client_buffer_size,
- (size_t) ngx_pagesize);
-
- ngx_conf_merge_msec_value(conf->greeting_delay,
- prev->greeting_delay, 0);
-
- ngx_conf_merge_bitmask_value(conf->auth_methods,
- prev->auth_methods,
- (NGX_CONF_BITMASK_SET
- |NGX_MAIL_AUTH_PLAIN_ENABLED
- |NGX_MAIL_AUTH_LOGIN_ENABLED));
-
-
- cscf = ngx_mail_conf_get_module_srv_conf(cf, ngx_mail_core_module);
-
- size = sizeof("220 ESMTP ready" CRLF) - 1 + cscf->server_name.len;
-
- p = ngx_pnalloc(cf->pool, size);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->greeting.len = size;
- conf->greeting.data = p;
-
- *p++ = '2'; *p++ = '2'; *p++ = '0'; *p++ = ' ';
- p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
- ngx_memcpy(p, " ESMTP ready" CRLF, sizeof(" ESMTP ready" CRLF) - 1);
-
-
- size = sizeof("250 " CRLF) - 1 + cscf->server_name.len;
-
- p = ngx_pnalloc(cf->pool, size);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->server_name.len = size;
- conf->server_name.data = p;
-
- *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
- p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
- *p++ = CR; *p = LF;
-
-
- if (conf->capabilities.nelts == 0) {
- conf->capabilities = prev->capabilities;
- }
-
- size = sizeof("250-") - 1 + cscf->server_name.len + sizeof(CRLF) - 1;
-
- c = conf->capabilities.elts;
- for (i = 0; i < conf->capabilities.nelts; i++) {
- size += sizeof("250 ") - 1 + c[i].len + sizeof(CRLF) - 1;
- }
-
- auth_enabled = 0;
-
- for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
- m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
- m <<= 1, i++)
- {
- if (m & conf->auth_methods) {
- size += 1 + ngx_mail_smtp_auth_methods_names[i].len;
- auth_enabled = 1;
- }
- }
-
- if (auth_enabled) {
- size += sizeof("250 AUTH") - 1 + sizeof(CRLF) - 1;
- }
-
- p = ngx_pnalloc(cf->pool, size);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->capability.len = size;
- conf->capability.data = p;
-
- last = p;
-
- *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
- p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
- *p++ = CR; *p++ = LF;
-
- for (i = 0; i < conf->capabilities.nelts; i++) {
- last = p;
- *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
- p = ngx_cpymem(p, c[i].data, c[i].len);
- *p++ = CR; *p++ = LF;
- }
-
- auth = p;
-
- if (auth_enabled) {
- last = p;
-
- *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
- *p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H';
-
- for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
- m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
- m <<= 1, i++)
- {
- if (m & conf->auth_methods) {
- *p++ = ' ';
- p = ngx_cpymem(p, ngx_mail_smtp_auth_methods_names[i].data,
- ngx_mail_smtp_auth_methods_names[i].len);
- }
- }
-
- *p++ = CR; *p = LF;
-
- } else {
- last[3] = ' ';
- }
-
- size += sizeof("250 STARTTLS" CRLF) - 1;
-
- p = ngx_pnalloc(cf->pool, size);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->starttls_capability.len = size;
- conf->starttls_capability.data = p;
-
- p = ngx_cpymem(p, conf->capability.data, conf->capability.len);
-
- p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
-
- p = conf->starttls_capability.data
- + (last - conf->capability.data) + 3;
- *p = '-';
-
- size = (auth - conf->capability.data)
- + sizeof("250 STARTTLS" CRLF) - 1;
-
- p = ngx_pnalloc(cf->pool, size);
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- conf->starttls_only_capability.len = size;
- conf->starttls_only_capability.data = p;
-
- p = ngx_cpymem(p, conf->capability.data, auth - conf->capability.data);
-
- ngx_memcpy(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
-
- if (last < auth) {
- p = conf->starttls_only_capability.data
- + (last - conf->capability.data) + 3;
- *p = '-';
- }
-
- return NGX_CONF_OK;
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_smtp_module.h b/usr.sbin/nginx/src/mail/ngx_mail_smtp_module.h
deleted file mode 100644
index 04ffab60ade..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_smtp_module.h
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_MAIL_SMTP_MODULE_H_INCLUDED_
-#define _NGX_MAIL_SMTP_MODULE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_mail.h>
-#include <ngx_mail_smtp_module.h>
-
-
-typedef struct {
- ngx_msec_t greeting_delay;
-
- size_t client_buffer_size;
-
- ngx_str_t capability;
- ngx_str_t starttls_capability;
- ngx_str_t starttls_only_capability;
-
- ngx_str_t server_name;
- ngx_str_t greeting;
-
- ngx_uint_t auth_methods;
-
- ngx_array_t capabilities;
-} ngx_mail_smtp_srv_conf_t;
-
-
-void ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c);
-void ngx_mail_smtp_init_protocol(ngx_event_t *rev);
-void ngx_mail_smtp_auth_state(ngx_event_t *rev);
-ngx_int_t ngx_mail_smtp_parse_command(ngx_mail_session_t *s);
-
-
-extern ngx_module_t ngx_mail_smtp_module;
-
-
-#endif /* _NGX_MAIL_SMTP_MODULE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_ssl_module.c b/usr.sbin/nginx/src/mail/ngx_mail_ssl_module.c
deleted file mode 100644
index fe88f48e43b..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_ssl_module.c
+++ /dev/null
@@ -1,533 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_mail.h>
-
-
-#define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5"
-#define NGX_DEFAULT_ECDH_CURVE "prime256v1"
-
-
-static void *ngx_mail_ssl_create_conf(ngx_conf_t *cf);
-static char *ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child);
-
-static char *ngx_mail_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_mail_ssl_starttls(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-
-static ngx_conf_enum_t ngx_mail_starttls_state[] = {
- { ngx_string("off"), NGX_MAIL_STARTTLS_OFF },
- { ngx_string("on"), NGX_MAIL_STARTTLS_ON },
- { ngx_string("only"), NGX_MAIL_STARTTLS_ONLY },
- { ngx_null_string, 0 }
-};
-
-
-
-static ngx_conf_bitmask_t ngx_mail_ssl_protocols[] = {
- { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
- { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
- { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
- { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
- { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
- { ngx_null_string, 0 }
-};
-
-
-static ngx_command_t ngx_mail_ssl_commands[] = {
-
- { ngx_string("ssl"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
- ngx_mail_ssl_enable,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_ssl_conf_t, enable),
- NULL },
-
- { ngx_string("starttls"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_mail_ssl_starttls,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_ssl_conf_t, starttls),
- ngx_mail_starttls_state },
-
- { ngx_string("ssl_certificate"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_ssl_conf_t, certificate),
- NULL },
-
- { ngx_string("ssl_certificate_key"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_ssl_conf_t, certificate_key),
- NULL },
-
- { ngx_string("ssl_dhparam"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_ssl_conf_t, dhparam),
- NULL },
-
- { ngx_string("ssl_ecdh_curve"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_ssl_conf_t, ecdh_curve),
- NULL },
-
- { ngx_string("ssl_protocols"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
- ngx_conf_set_bitmask_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_ssl_conf_t, protocols),
- &ngx_mail_ssl_protocols },
-
- { ngx_string("ssl_ciphers"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_ssl_conf_t, ciphers),
- NULL },
-
- { ngx_string("ssl_prefer_server_ciphers"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_ssl_conf_t, prefer_server_ciphers),
- NULL },
-
- { ngx_string("ssl_session_cache"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12,
- ngx_mail_ssl_session_cache,
- NGX_MAIL_SRV_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("ssl_session_tickets"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_ssl_conf_t, session_tickets),
- NULL },
-
- { ngx_string("ssl_session_ticket_key"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_array_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_ssl_conf_t, session_ticket_keys),
- NULL },
-
- { ngx_string("ssl_session_timeout"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_sec_slot,
- NGX_MAIL_SRV_CONF_OFFSET,
- offsetof(ngx_mail_ssl_conf_t, session_timeout),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_mail_module_t ngx_mail_ssl_module_ctx = {
- NULL, /* protocol */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- ngx_mail_ssl_create_conf, /* create server configuration */
- ngx_mail_ssl_merge_conf /* merge server configuration */
-};
-
-
-ngx_module_t ngx_mail_ssl_module = {
- NGX_MODULE_V1,
- &ngx_mail_ssl_module_ctx, /* module context */
- ngx_mail_ssl_commands, /* module directives */
- NGX_MAIL_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_str_t ngx_mail_ssl_sess_id_ctx = ngx_string("MAIL");
-
-
-static void *
-ngx_mail_ssl_create_conf(ngx_conf_t *cf)
-{
- ngx_mail_ssl_conf_t *scf;
-
- scf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_ssl_conf_t));
- if (scf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * scf->protocols = 0;
- * scf->certificate = { 0, NULL };
- * scf->certificate_key = { 0, NULL };
- * scf->dhparam = { 0, NULL };
- * scf->ecdh_curve = { 0, NULL };
- * scf->ciphers = { 0, NULL };
- * scf->shm_zone = NULL;
- */
-
- scf->enable = NGX_CONF_UNSET;
- scf->starttls = NGX_CONF_UNSET_UINT;
- scf->prefer_server_ciphers = NGX_CONF_UNSET;
- scf->builtin_session_cache = NGX_CONF_UNSET;
- scf->session_timeout = NGX_CONF_UNSET;
- scf->session_tickets = NGX_CONF_UNSET;
- scf->session_ticket_keys = NGX_CONF_UNSET_PTR;
-
- return scf;
-}
-
-
-static char *
-ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_mail_ssl_conf_t *prev = parent;
- ngx_mail_ssl_conf_t *conf = child;
-
- char *mode;
- ngx_pool_cleanup_t *cln;
-
- ngx_conf_merge_value(conf->enable, prev->enable, 0);
- ngx_conf_merge_uint_value(conf->starttls, prev->starttls,
- NGX_MAIL_STARTTLS_OFF);
-
- ngx_conf_merge_value(conf->session_timeout,
- prev->session_timeout, 300);
-
- ngx_conf_merge_value(conf->prefer_server_ciphers,
- prev->prefer_server_ciphers, 0);
-
- ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
- (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3|NGX_SSL_TLSv1
- |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
-
- ngx_conf_merge_str_value(conf->certificate, prev->certificate, "");
- ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, "");
-
- ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
-
- ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
- NGX_DEFAULT_ECDH_CURVE);
-
- ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
-
-
- conf->ssl.log = cf->log;
-
- if (conf->enable) {
- mode = "ssl";
-
- } else if (conf->starttls != NGX_MAIL_STARTTLS_OFF) {
- mode = "starttls";
-
- } else {
- mode = "";
- }
-
- if (conf->file == NULL) {
- conf->file = prev->file;
- conf->line = prev->line;
- }
-
- if (*mode) {
-
- if (conf->certificate.len == 0) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"ssl_certificate\" is defined for "
- "the \"%s\" directive in %s:%ui",
- mode, conf->file, conf->line);
- return NGX_CONF_ERROR;
- }
-
- if (conf->certificate_key.len == 0) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"ssl_certificate_key\" is defined for "
- "the \"%s\" directive in %s:%ui",
- mode, conf->file, conf->line);
- return NGX_CONF_ERROR;
- }
-
- } else {
-
- if (conf->certificate.len == 0) {
- return NGX_CONF_OK;
- }
-
- if (conf->certificate_key.len == 0) {
- ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no \"ssl_certificate_key\" is defined "
- "for certificate \"%V\"",
- &conf->certificate);
- return NGX_CONF_ERROR;
- }
- }
-
- if (ngx_ssl_create(&conf->ssl, conf->protocols, NULL) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- cln = ngx_pool_cleanup_add(cf->pool, 0);
- if (cln == NULL) {
- return NGX_CONF_ERROR;
- }
-
- cln->handler = ngx_ssl_cleanup_ctx;
- cln->data = &conf->ssl;
-
- if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate,
- &conf->certificate_key)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- if (SSL_CTX_set_cipher_list(conf->ssl.ctx,
- (const char *) conf->ciphers.data)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
- "SSL_CTX_set_cipher_list(\"%V\") failed",
- &conf->ciphers);
- return NGX_CONF_ERROR;
- }
-
- if (conf->prefer_server_ciphers) {
- SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
- }
-
- SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback);
-
- if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_value(conf->builtin_session_cache,
- prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);
-
- if (conf->shm_zone == NULL) {
- conf->shm_zone = prev->shm_zone;
- }
-
- if (ngx_ssl_session_cache(&conf->ssl, &ngx_mail_ssl_sess_id_ctx,
- conf->builtin_session_cache,
- conf->shm_zone, conf->session_timeout)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- ngx_conf_merge_value(conf->session_tickets,
- prev->session_tickets, 1);
-
-#ifdef SSL_OP_NO_TICKET
- if (!conf->session_tickets) {
- SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_NO_TICKET);
- }
-#endif
-
- ngx_conf_merge_ptr_value(conf->session_ticket_keys,
- prev->session_ticket_keys, NULL);
-
- if (ngx_ssl_session_ticket_keys(cf, &conf->ssl, conf->session_ticket_keys)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_mail_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_mail_ssl_conf_t *scf = conf;
-
- char *rv;
-
- rv = ngx_conf_set_flag_slot(cf, cmd, conf);
-
- if (rv != NGX_CONF_OK) {
- return rv;
- }
-
- if (scf->enable && (ngx_int_t) scf->starttls > NGX_MAIL_STARTTLS_OFF) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "\"starttls\" directive conflicts with \"ssl on\"");
- return NGX_CONF_ERROR;
- }
-
- scf->file = cf->conf_file->file.name.data;
- scf->line = cf->conf_file->line;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_mail_ssl_starttls(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_mail_ssl_conf_t *scf = conf;
-
- char *rv;
-
- rv = ngx_conf_set_enum_slot(cf, cmd, conf);
-
- if (rv != NGX_CONF_OK) {
- return rv;
- }
-
- if (scf->enable == 1 && (ngx_int_t) scf->starttls > NGX_MAIL_STARTTLS_OFF) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "\"ssl\" directive conflicts with \"starttls\"");
- return NGX_CONF_ERROR;
- }
-
- scf->file = cf->conf_file->file.name.data;
- scf->line = cf->conf_file->line;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_mail_ssl_conf_t *scf = conf;
-
- size_t len;
- ngx_str_t *value, name, size;
- ngx_int_t n;
- ngx_uint_t i, j;
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (ngx_strcmp(value[i].data, "off") == 0) {
- scf->builtin_session_cache = NGX_SSL_NO_SCACHE;
- continue;
- }
-
- if (ngx_strcmp(value[i].data, "none") == 0) {
- scf->builtin_session_cache = NGX_SSL_NONE_SCACHE;
- continue;
- }
-
- if (ngx_strcmp(value[i].data, "builtin") == 0) {
- scf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
- continue;
- }
-
- if (value[i].len > sizeof("builtin:") - 1
- && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1)
- == 0)
- {
- n = ngx_atoi(value[i].data + sizeof("builtin:") - 1,
- value[i].len - (sizeof("builtin:") - 1));
-
- if (n == NGX_ERROR) {
- goto invalid;
- }
-
- scf->builtin_session_cache = n;
-
- continue;
- }
-
- if (value[i].len > sizeof("shared:") - 1
- && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1)
- == 0)
- {
- len = 0;
-
- for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
- if (value[i].data[j] == ':') {
- break;
- }
-
- len++;
- }
-
- if (len == 0) {
- goto invalid;
- }
-
- name.len = len;
- name.data = value[i].data + sizeof("shared:") - 1;
-
- size.len = value[i].len - j - 1;
- size.data = name.data + len + 1;
-
- n = ngx_parse_size(&size);
-
- if (n == NGX_ERROR) {
- goto invalid;
- }
-
- if (n < (ngx_int_t) (8 * ngx_pagesize)) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "session cache \"%V\" is too small",
- &value[i]);
-
- return NGX_CONF_ERROR;
- }
-
- scf->shm_zone = ngx_shared_memory_add(cf, &name, n,
- &ngx_mail_ssl_module);
- if (scf->shm_zone == NULL) {
- return NGX_CONF_ERROR;
- }
-
- scf->shm_zone->init = ngx_ssl_session_cache_init;
-
- continue;
- }
-
- goto invalid;
- }
-
- if (scf->shm_zone && scf->builtin_session_cache == NGX_CONF_UNSET) {
- scf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
- }
-
- return NGX_CONF_OK;
-
-invalid:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid session cache \"%V\"", &value[i]);
-
- return NGX_CONF_ERROR;
-}
diff --git a/usr.sbin/nginx/src/mail/ngx_mail_ssl_module.h b/usr.sbin/nginx/src/mail/ngx_mail_ssl_module.h
deleted file mode 100644
index bef0e515a02..00000000000
--- a/usr.sbin/nginx/src/mail/ngx_mail_ssl_module.h
+++ /dev/null
@@ -1,55 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_MAIL_SSL_H_INCLUDED_
-#define _NGX_MAIL_SSL_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_mail.h>
-
-
-#define NGX_MAIL_STARTTLS_OFF 0
-#define NGX_MAIL_STARTTLS_ON 1
-#define NGX_MAIL_STARTTLS_ONLY 2
-
-
-typedef struct {
- ngx_flag_t enable;
- ngx_flag_t prefer_server_ciphers;
-
- ngx_ssl_t ssl;
-
- ngx_uint_t starttls;
- ngx_uint_t protocols;
-
- ssize_t builtin_session_cache;
-
- time_t session_timeout;
-
- ngx_str_t certificate;
- ngx_str_t certificate_key;
- ngx_str_t dhparam;
- ngx_str_t ecdh_curve;
-
- ngx_str_t ciphers;
-
- ngx_shm_zone_t *shm_zone;
-
- ngx_flag_t session_tickets;
- ngx_array_t *session_ticket_keys;
-
- u_char *file;
- ngx_uint_t line;
-} ngx_mail_ssl_conf_t;
-
-
-extern ngx_module_t ngx_mail_ssl_module;
-
-
-#endif /* _NGX_MAIL_SSL_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/misc/ngx_cpp_test_module.cpp b/usr.sbin/nginx/src/misc/ngx_cpp_test_module.cpp
deleted file mode 100644
index 3cbc0a8111a..00000000000
--- a/usr.sbin/nginx/src/misc/ngx_cpp_test_module.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-
-// stub module to test header files' C++ compatibilty
-
-extern "C" {
- #include <ngx_config.h>
- #include <ngx_core.h>
- #include <ngx_event.h>
- #include <ngx_event_connect.h>
- #include <ngx_event_pipe.h>
-
- #include <ngx_http.h>
-
- #include <ngx_mail.h>
- #include <ngx_mail_pop3_module.h>
- #include <ngx_mail_imap_module.h>
- #include <ngx_mail_smtp_module.h>
-}
-
-// nginx header files should go before other, because they define 64-bit off_t
-// #include <string>
-
-
-void ngx_cpp_test_handler(void *data);
-
-void
-ngx_cpp_test_handler(void *data)
-{
- return;
-}
diff --git a/usr.sbin/nginx/src/misc/ngx_google_perftools_module.c b/usr.sbin/nginx/src/misc/ngx_google_perftools_module.c
deleted file mode 100644
index f2f8221b560..00000000000
--- a/usr.sbin/nginx/src/misc/ngx_google_perftools_module.c
+++ /dev/null
@@ -1,126 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-/*
- * declare Profiler interface here because
- * <google/profiler.h> is C++ header file
- */
-
-int ProfilerStart(u_char* fname);
-void ProfilerStop(void);
-void ProfilerRegisterThread(void);
-
-
-static void *ngx_google_perftools_create_conf(ngx_cycle_t *cycle);
-static ngx_int_t ngx_google_perftools_worker(ngx_cycle_t *cycle);
-
-
-typedef struct {
- ngx_str_t profiles;
-} ngx_google_perftools_conf_t;
-
-
-static ngx_command_t ngx_google_perftools_commands[] = {
-
- { ngx_string("google_perftools_profiles"),
- NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
- 0,
- offsetof(ngx_google_perftools_conf_t, profiles),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_core_module_t ngx_google_perftools_module_ctx = {
- ngx_string("google_perftools"),
- ngx_google_perftools_create_conf,
- NULL
-};
-
-
-ngx_module_t ngx_google_perftools_module = {
- NGX_MODULE_V1,
- &ngx_google_perftools_module_ctx, /* module context */
- ngx_google_perftools_commands, /* module directives */
- NGX_CORE_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- ngx_google_perftools_worker, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static void *
-ngx_google_perftools_create_conf(ngx_cycle_t *cycle)
-{
- ngx_google_perftools_conf_t *gptcf;
-
- gptcf = ngx_pcalloc(cycle->pool, sizeof(ngx_google_perftools_conf_t));
- if (gptcf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc()
- *
- * gptcf->profiles = { 0, NULL };
- */
-
- return gptcf;
-}
-
-
-static ngx_int_t
-ngx_google_perftools_worker(ngx_cycle_t *cycle)
-{
- u_char *profile;
- ngx_google_perftools_conf_t *gptcf;
-
- gptcf = (ngx_google_perftools_conf_t *)
- ngx_get_conf(cycle->conf_ctx, ngx_google_perftools_module);
-
- if (gptcf->profiles.len == 0) {
- return NGX_OK;
- }
-
- profile = ngx_alloc(gptcf->profiles.len + NGX_INT_T_LEN + 2, cycle->log);
- if (profile == NULL) {
- return NGX_OK;
- }
-
- if (getenv("CPUPROFILE")) {
- /* disable inherited Profiler enabled in master process */
- ProfilerStop();
- }
-
- ngx_sprintf(profile, "%V.%d%Z", &gptcf->profiles, ngx_pid);
-
- if (ProfilerStart(profile)) {
- /* start ITIMER_PROF timer */
- ProfilerRegisterThread();
-
- } else {
- ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_errno,
- "ProfilerStart(%s) failed", profile);
- }
-
- ngx_free(profile);
-
- return NGX_OK;
-}
-
-
-/* ProfilerStop() is called on Profiler destruction */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_aio_read.c b/usr.sbin/nginx/src/os/unix/ngx_aio_read.c
deleted file mode 100644
index 7849881730f..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_aio_read.c
+++ /dev/null
@@ -1,109 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-extern int ngx_kqueue;
-
-
-ssize_t
-ngx_aio_read(ngx_connection_t *c, u_char *buf, size_t size)
-{
- int n;
- ngx_event_t *rev;
-
- rev = c->read;
-
- if (!rev->ready) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0, "second aio post");
- return NGX_AGAIN;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "rev->complete: %d", rev->complete);
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "aio size: %d", size);
-
- if (!rev->complete) {
- ngx_memzero(&rev->aiocb, sizeof(struct aiocb));
-
- rev->aiocb.aio_fildes = c->fd;
- rev->aiocb.aio_buf = buf;
- rev->aiocb.aio_nbytes = size;
-
-#if (NGX_HAVE_KQUEUE)
- rev->aiocb.aio_sigevent.sigev_notify_kqueue = ngx_kqueue;
- rev->aiocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
- rev->aiocb.aio_sigevent.sigev_value.sigval_ptr = rev;
-#endif
-
- if (aio_read(&rev->aiocb) == -1) {
- ngx_log_error(NGX_LOG_CRIT, rev->log, ngx_errno,
- "aio_read() failed");
- rev->error = 1;
- return NGX_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "aio_read: #%d OK", c->fd);
-
- rev->active = 1;
- rev->ready = 0;
- }
-
- rev->complete = 0;
-
- n = aio_error(&rev->aiocb);
- if (n == -1) {
- ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "aio_error() failed");
- rev->error = 1;
- return NGX_ERROR;
- }
-
- if (n != 0) {
- if (n == NGX_EINPROGRESS) {
- if (rev->ready) {
- ngx_log_error(NGX_LOG_ALERT, c->log, n,
- "aio_read() still in progress");
- rev->ready = 0;
- }
- return NGX_AGAIN;
- }
-
- ngx_log_error(NGX_LOG_CRIT, c->log, n, "aio_read() failed");
- rev->error = 1;
- rev->ready = 0;
- return NGX_ERROR;
- }
-
- n = aio_return(&rev->aiocb);
- if (n == -1) {
- ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
- "aio_return() failed");
-
- rev->error = 1;
- rev->ready = 0;
- return NGX_ERROR;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, rev->log, 0,
- "aio_read: #%d %d", c->fd, n);
-
- if (n == 0) {
- rev->eof = 1;
- rev->ready = 0;
- } else {
- rev->ready = 1;
- }
-
- rev->active = 0;
-
- return n;
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_aio_read_chain.c b/usr.sbin/nginx/src/os/unix/ngx_aio_read_chain.c
deleted file mode 100644
index 8c831b95129..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_aio_read_chain.c
+++ /dev/null
@@ -1,78 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-ssize_t
-ngx_aio_read_chain(ngx_connection_t *c, ngx_chain_t *cl)
-{
- int n;
- u_char *buf, *prev;
- size_t size;
- ssize_t total;
-
- if (c->read->pending_eof) {
- c->read->ready = 0;
- return 0;
- }
-
- total = 0;
-
- while (cl) {
-
- /* we can post the single aio operation only */
-
- if (!c->read->ready) {
- return total ? total : NGX_AGAIN;
- }
-
- buf = cl->buf->last;
- prev = cl->buf->last;
- size = 0;
-
- /* coalesce the neighbouring bufs */
-
- while (cl && prev == cl->buf->last) {
- size += cl->buf->end - cl->buf->last;
- prev = cl->buf->end;
- cl = cl->next;
- }
-
- n = ngx_aio_read(c, buf, size);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "aio_read: %d", n);
-
- if (n == NGX_AGAIN) {
- return total ? total : NGX_AGAIN;
- }
-
- if (n == NGX_ERROR) {
- return NGX_ERROR;
- }
-
- if (n == 0) {
- c->read->pending_eof = 1;
- if (total) {
- c->read->eof = 0;
- c->read->ready = 1;
- }
- return total;
- }
-
- if (n > 0) {
- total += n;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "aio_read total: %d", total);
- }
-
- return total ? total : NGX_AGAIN;
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_aio_write.c b/usr.sbin/nginx/src/os/unix/ngx_aio_write.c
deleted file mode 100644
index f0d93918e3b..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_aio_write.c
+++ /dev/null
@@ -1,109 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-extern int ngx_kqueue;
-
-
-ssize_t
-ngx_aio_write(ngx_connection_t *c, u_char *buf, size_t size)
-{
- int n;
- ngx_event_t *wev;
-
- wev = c->write;
-
- if (!wev->ready) {
- return NGX_AGAIN;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, wev->log, 0,
- "aio: wev->complete: %d", wev->complete);
-
- if (!wev->complete) {
- ngx_memzero(&wev->aiocb, sizeof(struct aiocb));
-
- wev->aiocb.aio_fildes = c->fd;
- wev->aiocb.aio_buf = buf;
- wev->aiocb.aio_nbytes = size;
-
-#if (NGX_HAVE_KQUEUE)
- wev->aiocb.aio_sigevent.sigev_notify_kqueue = ngx_kqueue;
- wev->aiocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
- wev->aiocb.aio_sigevent.sigev_value.sigval_ptr = wev;
-#endif
-
- if (aio_write(&wev->aiocb) == -1) {
- ngx_log_error(NGX_LOG_CRIT, wev->log, ngx_errno,
- "aio_write() failed");
- return NGX_ERROR;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, wev->log, 0, "aio_write: OK");
-
- wev->active = 1;
- wev->ready = 0;
- }
-
- wev->complete = 0;
-
- n = aio_error(&wev->aiocb);
- if (n == -1) {
- ngx_log_error(NGX_LOG_CRIT, wev->log, ngx_errno, "aio_error() failed");
- wev->error = 1;
- return NGX_ERROR;
- }
-
- if (n != 0) {
- if (n == NGX_EINPROGRESS) {
- if (wev->ready) {
- ngx_log_error(NGX_LOG_ALERT, wev->log, n,
- "aio_write() still in progress");
- wev->ready = 0;
- }
- return NGX_AGAIN;
- }
-
- ngx_log_error(NGX_LOG_CRIT, wev->log, n, "aio_write() failed");
- wev->error = 1;
- wev->ready = 0;
-
-#if 1
- n = aio_return(&wev->aiocb);
- if (n == -1) {
- ngx_log_error(NGX_LOG_ALERT, wev->log, ngx_errno,
- "aio_return() failed");
- }
-
- ngx_log_error(NGX_LOG_CRIT, wev->log, n, "aio_return() %d", n);
-#endif
-
- return NGX_ERROR;
- }
-
- n = aio_return(&wev->aiocb);
- if (n == -1) {
- ngx_log_error(NGX_LOG_ALERT, wev->log, ngx_errno,
- "aio_return() failed");
-
- wev->error = 1;
- wev->ready = 0;
- return NGX_ERROR;
- }
-
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, wev->log, 0, "aio_write: %d", n);
-
- wev->active = 0;
- wev->ready = 1;
-
- return n;
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_aio_write_chain.c b/usr.sbin/nginx/src/os/unix/ngx_aio_write_chain.c
deleted file mode 100644
index b0c25085d1f..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_aio_write_chain.c
+++ /dev/null
@@ -1,100 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-ngx_chain_t *
-ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
-{
- u_char *buf, *prev;
- off_t send, sent;
- size_t len;
- ssize_t n, size;
- ngx_chain_t *cl;
-
- /* the maximum limit size is the maximum size_t value - the page size */
-
- if (limit == 0 || limit > (off_t) (NGX_MAX_SIZE_T_VALUE - ngx_pagesize)) {
- limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
- }
-
- send = 0;
- sent = 0;
- cl = in;
-
- while (cl) {
-
- if (cl->buf->pos == cl->buf->last) {
- cl = cl->next;
- continue;
- }
-
- /* we can post the single aio operation only */
-
- if (!c->write->ready) {
- return cl;
- }
-
- buf = cl->buf->pos;
- prev = buf;
- len = 0;
-
- /* coalesce the neighbouring bufs */
-
- while (cl && prev == cl->buf->pos && send < limit) {
- if (ngx_buf_special(cl->buf)) {
- continue;
- }
-
- size = cl->buf->last - cl->buf->pos;
-
- if (send + size > limit) {
- size = limit - send;
- }
-
- len += size;
- prev = cl->buf->pos + size;
- send += size;
- cl = cl->next;
- }
-
- n = ngx_aio_write(c, buf, len);
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "aio_write: %z", n);
-
- if (n == NGX_ERROR) {
- return NGX_CHAIN_ERROR;
- }
-
- if (n > 0) {
- sent += n;
- c->sent += n;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "aio_write sent: %O", c->sent);
-
- for (cl = in; cl; cl = cl->next) {
-
- if (sent >= cl->buf->last - cl->buf->pos) {
- sent -= cl->buf->last - cl->buf->pos;
- cl->buf->pos = cl->buf->last;
-
- continue;
- }
-
- cl->buf->pos += sent;
-
- break;
- }
- }
-
- return cl;
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_alloc.c b/usr.sbin/nginx/src/os/unix/ngx_alloc.c
deleted file mode 100644
index 5c2f7870256..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_alloc.c
+++ /dev/null
@@ -1,90 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-ngx_uint_t ngx_pagesize;
-ngx_uint_t ngx_pagesize_shift;
-ngx_uint_t ngx_cacheline_size;
-
-
-void *
-ngx_alloc(size_t size, ngx_log_t *log)
-{
- void *p;
-
- p = malloc(size);
- if (p == NULL) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- "malloc(%uz) failed", size);
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, log, 0, "malloc: %p:%uz", p, size);
-
- return p;
-}
-
-
-void *
-ngx_calloc(size_t size, ngx_log_t *log)
-{
- void *p;
-
- p = ngx_alloc(size, log);
-
- if (p) {
- ngx_memzero(p, size);
- }
-
- return p;
-}
-
-
-#if (NGX_HAVE_POSIX_MEMALIGN)
-
-void *
-ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
-{
- void *p;
- int err;
-
- err = posix_memalign(&p, alignment, size);
-
- if (err) {
- ngx_log_error(NGX_LOG_EMERG, log, err,
- "posix_memalign(%uz, %uz) failed", alignment, size);
- p = NULL;
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_ALLOC, log, 0,
- "posix_memalign: %p:%uz @%uz", p, size, alignment);
-
- return p;
-}
-
-#elif (NGX_HAVE_MEMALIGN)
-
-void *
-ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
-{
- void *p;
-
- p = memalign(alignment, size);
- if (p == NULL) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- "memalign(%uz, %uz) failed", alignment, size);
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_ALLOC, log, 0,
- "memalign: %p:%uz @%uz", p, size, alignment);
-
- return p;
-}
-
-#endif
diff --git a/usr.sbin/nginx/src/os/unix/ngx_alloc.h b/usr.sbin/nginx/src/os/unix/ngx_alloc.h
deleted file mode 100644
index 655db257f41..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_alloc.h
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_ALLOC_H_INCLUDED_
-#define _NGX_ALLOC_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-void *ngx_alloc(size_t size, ngx_log_t *log);
-void *ngx_calloc(size_t size, ngx_log_t *log);
-
-#define ngx_free free
-
-
-/*
- * Linux has memalign() or posix_memalign()
- * Solaris has memalign()
- * FreeBSD 7.0 has posix_memalign(), besides, early version's malloc()
- * aligns allocations bigger than page size at the page boundary
- */
-
-#if (NGX_HAVE_POSIX_MEMALIGN || NGX_HAVE_MEMALIGN)
-
-void *ngx_memalign(size_t alignment, size_t size, ngx_log_t *log);
-
-#else
-
-#define ngx_memalign(alignment, size, log) ngx_alloc(size, log)
-
-#endif
-
-
-extern ngx_uint_t ngx_pagesize;
-extern ngx_uint_t ngx_pagesize_shift;
-extern ngx_uint_t ngx_cacheline_size;
-
-
-#endif /* _NGX_ALLOC_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_atomic.h b/usr.sbin/nginx/src/os/unix/ngx_atomic.h
deleted file mode 100644
index 417cd86ff29..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_atomic.h
+++ /dev/null
@@ -1,313 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_ATOMIC_H_INCLUDED_
-#define _NGX_ATOMIC_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#if (NGX_HAVE_LIBATOMIC)
-
-#define AO_REQUIRE_CAS
-#include <atomic_ops.h>
-
-#define NGX_HAVE_ATOMIC_OPS 1
-
-typedef long ngx_atomic_int_t;
-typedef AO_t ngx_atomic_uint_t;
-typedef volatile ngx_atomic_uint_t ngx_atomic_t;
-
-#if (NGX_PTR_SIZE == 8)
-#define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
-#else
-#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
-#endif
-
-#define ngx_atomic_cmp_set(lock, old, new) \
- AO_compare_and_swap(lock, old, new)
-#define ngx_atomic_fetch_add(value, add) \
- AO_fetch_and_add(value, add)
-#define ngx_memory_barrier() AO_nop()
-#define ngx_cpu_pause()
-
-
-#elif (NGX_DARWIN_ATOMIC)
-
-/*
- * use Darwin 8 atomic(3) and barrier(3) operations
- * optimized at run-time for UP and SMP
- */
-
-#include <libkern/OSAtomic.h>
-
-/* "bool" conflicts with perl's CORE/handy.h */
-#if 0
-#undef bool
-#endif
-
-
-#define NGX_HAVE_ATOMIC_OPS 1
-
-#if (NGX_PTR_SIZE == 8)
-
-typedef int64_t ngx_atomic_int_t;
-typedef uint64_t ngx_atomic_uint_t;
-#define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
-
-#define ngx_atomic_cmp_set(lock, old, new) \
- OSAtomicCompareAndSwap64Barrier(old, new, (int64_t *) lock)
-
-#define ngx_atomic_fetch_add(value, add) \
- (OSAtomicAdd64(add, (int64_t *) value) - add)
-
-#else
-
-typedef int32_t ngx_atomic_int_t;
-typedef uint32_t ngx_atomic_uint_t;
-#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
-
-#define ngx_atomic_cmp_set(lock, old, new) \
- OSAtomicCompareAndSwap32Barrier(old, new, (int32_t *) lock)
-
-#define ngx_atomic_fetch_add(value, add) \
- (OSAtomicAdd32(add, (int32_t *) value) - add)
-
-#endif
-
-#define ngx_memory_barrier() OSMemoryBarrier()
-
-#define ngx_cpu_pause()
-
-typedef volatile ngx_atomic_uint_t ngx_atomic_t;
-
-
-#elif (NGX_HAVE_GCC_ATOMIC)
-
-/* GCC 4.1 builtin atomic operations */
-
-#define NGX_HAVE_ATOMIC_OPS 1
-
-typedef long ngx_atomic_int_t;
-typedef unsigned long ngx_atomic_uint_t;
-
-#if (NGX_PTR_SIZE == 8)
-#define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
-#else
-#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
-#endif
-
-typedef volatile ngx_atomic_uint_t ngx_atomic_t;
-
-
-#define ngx_atomic_cmp_set(lock, old, set) \
- __sync_bool_compare_and_swap(lock, old, set)
-
-#define ngx_atomic_fetch_add(value, add) \
- __sync_fetch_and_add(value, add)
-
-#define ngx_memory_barrier() __sync_synchronize()
-
-#if ( __i386__ || __i386 || __amd64__ || __amd64 )
-#define ngx_cpu_pause() __asm__ ("pause")
-#else
-#define ngx_cpu_pause()
-#endif
-
-
-#elif ( __i386__ || __i386 )
-
-typedef int32_t ngx_atomic_int_t;
-typedef uint32_t ngx_atomic_uint_t;
-typedef volatile ngx_atomic_uint_t ngx_atomic_t;
-#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
-
-
-#if ( __SUNPRO_C )
-
-#define NGX_HAVE_ATOMIC_OPS 1
-
-ngx_atomic_uint_t
-ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
- ngx_atomic_uint_t set);
-
-ngx_atomic_int_t
-ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);
-
-/*
- * Sun Studio 12 exits with segmentation fault on '__asm ("pause")',
- * so ngx_cpu_pause is declared in src/os/unix/ngx_sunpro_x86.il
- */
-
-void
-ngx_cpu_pause(void);
-
-/* the code in src/os/unix/ngx_sunpro_x86.il */
-
-#define ngx_memory_barrier() __asm (".volatile"); __asm (".nonvolatile")
-
-
-#else /* ( __GNUC__ || __INTEL_COMPILER ) */
-
-#define NGX_HAVE_ATOMIC_OPS 1
-
-#include "ngx_gcc_atomic_x86.h"
-
-#endif
-
-
-#elif ( __amd64__ || __amd64 )
-
-typedef int64_t ngx_atomic_int_t;
-typedef uint64_t ngx_atomic_uint_t;
-typedef volatile ngx_atomic_uint_t ngx_atomic_t;
-#define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
-
-
-#if ( __SUNPRO_C )
-
-#define NGX_HAVE_ATOMIC_OPS 1
-
-ngx_atomic_uint_t
-ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
- ngx_atomic_uint_t set);
-
-ngx_atomic_int_t
-ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);
-
-/*
- * Sun Studio 12 exits with segmentation fault on '__asm ("pause")',
- * so ngx_cpu_pause is declared in src/os/unix/ngx_sunpro_amd64.il
- */
-
-void
-ngx_cpu_pause(void);
-
-/* the code in src/os/unix/ngx_sunpro_amd64.il */
-
-#define ngx_memory_barrier() __asm (".volatile"); __asm (".nonvolatile")
-
-
-#else /* ( __GNUC__ || __INTEL_COMPILER ) */
-
-#define NGX_HAVE_ATOMIC_OPS 1
-
-#include "ngx_gcc_atomic_amd64.h"
-
-#endif
-
-
-#elif ( __sparc__ || __sparc || __sparcv9 )
-
-#if (NGX_PTR_SIZE == 8)
-
-typedef int64_t ngx_atomic_int_t;
-typedef uint64_t ngx_atomic_uint_t;
-#define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
-
-#else
-
-typedef int32_t ngx_atomic_int_t;
-typedef uint32_t ngx_atomic_uint_t;
-#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
-
-#endif
-
-typedef volatile ngx_atomic_uint_t ngx_atomic_t;
-
-
-#if ( __SUNPRO_C )
-
-#define NGX_HAVE_ATOMIC_OPS 1
-
-#include "ngx_sunpro_atomic_sparc64.h"
-
-
-#else /* ( __GNUC__ || __INTEL_COMPILER ) */
-
-#define NGX_HAVE_ATOMIC_OPS 1
-
-#include "ngx_gcc_atomic_sparc64.h"
-
-#endif
-
-
-#elif ( __powerpc__ || __POWERPC__ )
-
-#define NGX_HAVE_ATOMIC_OPS 1
-
-#if (NGX_PTR_SIZE == 8)
-
-typedef int64_t ngx_atomic_int_t;
-typedef uint64_t ngx_atomic_uint_t;
-#define NGX_ATOMIC_T_LEN (sizeof("-9223372036854775808") - 1)
-
-#else
-
-typedef int32_t ngx_atomic_int_t;
-typedef uint32_t ngx_atomic_uint_t;
-#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
-
-#endif
-
-typedef volatile ngx_atomic_uint_t ngx_atomic_t;
-
-
-#include "ngx_gcc_atomic_ppc.h"
-
-#endif
-
-
-#if !(NGX_HAVE_ATOMIC_OPS)
-
-#define NGX_HAVE_ATOMIC_OPS 0
-
-typedef int32_t ngx_atomic_int_t;
-typedef uint32_t ngx_atomic_uint_t;
-typedef volatile ngx_atomic_uint_t ngx_atomic_t;
-#define NGX_ATOMIC_T_LEN (sizeof("-2147483648") - 1)
-
-
-static ngx_inline ngx_atomic_uint_t
-ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
- ngx_atomic_uint_t set)
-{
- if (*lock == old) {
- *lock = set;
- return 1;
- }
-
- return 0;
-}
-
-
-static ngx_inline ngx_atomic_int_t
-ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
-{
- ngx_atomic_int_t old;
-
- old = *value;
- *value += add;
-
- return old;
-}
-
-#define ngx_memory_barrier()
-#define ngx_cpu_pause()
-
-#endif
-
-
-void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin);
-
-#define ngx_trylock(lock) (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))
-#define ngx_unlock(lock) *(lock) = 0
-
-
-#endif /* _NGX_ATOMIC_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_channel.c b/usr.sbin/nginx/src/os/unix/ngx_channel.c
deleted file mode 100644
index 8e9069660f4..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_channel.c
+++ /dev/null
@@ -1,260 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_channel.h>
-
-
-ngx_int_t
-ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
- ngx_log_t *log)
-{
- ssize_t n;
- ngx_err_t err;
- struct iovec iov[1];
- struct msghdr msg;
-
-#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
-
- union {
- struct cmsghdr cm;
- char space[CMSG_SPACE(sizeof(int))];
- } cmsg;
-
- if (ch->fd == -1) {
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
-
- } else {
- msg.msg_control = (caddr_t) &cmsg;
- msg.msg_controllen = sizeof(cmsg);
-
- ngx_memzero(&cmsg, sizeof(cmsg));
-
- cmsg.cm.cmsg_len = CMSG_LEN(sizeof(int));
- cmsg.cm.cmsg_level = SOL_SOCKET;
- cmsg.cm.cmsg_type = SCM_RIGHTS;
-
- /*
- * We have to use ngx_memcpy() instead of simple
- * *(int *) CMSG_DATA(&cmsg.cm) = ch->fd;
- * because some gcc 4.4 with -O2/3/s optimization issues the warning:
- * dereferencing type-punned pointer will break strict-aliasing rules
- *
- * Fortunately, gcc with -O1 compiles this ngx_memcpy()
- * in the same simple assignment as in the code above
- */
-
- ngx_memcpy(CMSG_DATA(&cmsg.cm), &ch->fd, sizeof(int));
- }
-
- msg.msg_flags = 0;
-
-#else
-
- if (ch->fd == -1) {
- msg.msg_accrights = NULL;
- msg.msg_accrightslen = 0;
-
- } else {
- msg.msg_accrights = (caddr_t) &ch->fd;
- msg.msg_accrightslen = sizeof(int);
- }
-
-#endif
-
- iov[0].iov_base = (char *) ch;
- iov[0].iov_len = size;
-
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = iov;
- msg.msg_iovlen = 1;
-
- n = sendmsg(s, &msg, 0);
-
- if (n == -1) {
- err = ngx_errno;
- if (err == NGX_EAGAIN) {
- return NGX_AGAIN;
- }
-
- ngx_log_error(NGX_LOG_ALERT, log, err, "sendmsg() failed");
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, ngx_log_t *log)
-{
- ssize_t n;
- ngx_err_t err;
- struct iovec iov[1];
- struct msghdr msg;
-
-#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
- union {
- struct cmsghdr cm;
- char space[CMSG_SPACE(sizeof(int))];
- } cmsg;
-#else
- int fd;
-#endif
-
- iov[0].iov_base = (char *) ch;
- iov[0].iov_len = size;
-
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = iov;
- msg.msg_iovlen = 1;
-
-#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
- msg.msg_control = (caddr_t) &cmsg;
- msg.msg_controllen = sizeof(cmsg);
-#else
- msg.msg_accrights = (caddr_t) &fd;
- msg.msg_accrightslen = sizeof(int);
-#endif
-
- n = recvmsg(s, &msg, 0);
-
- if (n == -1) {
- err = ngx_errno;
- if (err == NGX_EAGAIN) {
- return NGX_AGAIN;
- }
-
- ngx_log_error(NGX_LOG_ALERT, log, err, "recvmsg() failed");
- return NGX_ERROR;
- }
-
- if (n == 0) {
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "recvmsg() returned zero");
- return NGX_ERROR;
- }
-
- if ((size_t) n < sizeof(ngx_channel_t)) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- "recvmsg() returned not enough data: %z", n);
- return NGX_ERROR;
- }
-
-#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
-
- if (ch->command == NGX_CMD_OPEN_CHANNEL) {
-
- if (cmsg.cm.cmsg_len < (socklen_t) CMSG_LEN(sizeof(int))) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- "recvmsg() returned too small ancillary data");
- return NGX_ERROR;
- }
-
- if (cmsg.cm.cmsg_level != SOL_SOCKET || cmsg.cm.cmsg_type != SCM_RIGHTS)
- {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- "recvmsg() returned invalid ancillary data "
- "level %d or type %d",
- cmsg.cm.cmsg_level, cmsg.cm.cmsg_type);
- return NGX_ERROR;
- }
-
- /* ch->fd = *(int *) CMSG_DATA(&cmsg.cm); */
-
- ngx_memcpy(&ch->fd, CMSG_DATA(&cmsg.cm), sizeof(int));
- }
-
- if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- "recvmsg() truncated data");
- }
-
-#else
-
- if (ch->command == NGX_CMD_OPEN_CHANNEL) {
- if (msg.msg_accrightslen != sizeof(int)) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- "recvmsg() returned no ancillary data");
- return NGX_ERROR;
- }
-
- ch->fd = fd;
- }
-
-#endif
-
- return n;
-}
-
-
-ngx_int_t
-ngx_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd, ngx_int_t event,
- ngx_event_handler_pt handler)
-{
- ngx_event_t *ev, *rev, *wev;
- ngx_connection_t *c;
-
- c = ngx_get_connection(fd, cycle->log);
-
- if (c == NULL) {
- return NGX_ERROR;
- }
-
- c->pool = cycle->pool;
-
- rev = c->read;
- wev = c->write;
-
- rev->log = cycle->log;
- wev->log = cycle->log;
-
-#if (NGX_THREADS)
- rev->lock = &c->lock;
- wev->lock = &c->lock;
- rev->own_lock = &c->lock;
- wev->own_lock = &c->lock;
-#endif
-
- rev->channel = 1;
- wev->channel = 1;
-
- ev = (event == NGX_READ_EVENT) ? rev : wev;
-
- ev->handler = handler;
-
- if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
- if (ngx_add_conn(c) == NGX_ERROR) {
- ngx_free_connection(c);
- return NGX_ERROR;
- }
-
- } else {
- if (ngx_add_event(ev, event, 0) == NGX_ERROR) {
- ngx_free_connection(c);
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
-}
-
-
-void
-ngx_close_channel(ngx_fd_t *fd, ngx_log_t *log)
-{
- if (close(fd[0]) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "close() channel failed");
- }
-
- if (close(fd[1]) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "close() channel failed");
- }
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_channel.h b/usr.sbin/nginx/src/os/unix/ngx_channel.h
deleted file mode 100644
index d7a9f6b54c5..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_channel.h
+++ /dev/null
@@ -1,34 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_CHANNEL_H_INCLUDED_
-#define _NGX_CHANNEL_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-typedef struct {
- ngx_uint_t command;
- ngx_pid_t pid;
- ngx_int_t slot;
- ngx_fd_t fd;
-} ngx_channel_t;
-
-
-ngx_int_t ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
- ngx_log_t *log);
-ngx_int_t ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
- ngx_log_t *log);
-ngx_int_t ngx_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd,
- ngx_int_t event, ngx_event_handler_pt handler);
-void ngx_close_channel(ngx_fd_t *fd, ngx_log_t *log);
-
-
-#endif /* _NGX_CHANNEL_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_daemon.c b/usr.sbin/nginx/src/os/unix/ngx_daemon.c
deleted file mode 100644
index ab672110838..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_daemon.c
+++ /dev/null
@@ -1,70 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-ngx_int_t
-ngx_daemon(ngx_log_t *log)
-{
- int fd;
-
- switch (fork()) {
- case -1:
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed");
- return NGX_ERROR;
-
- case 0:
- break;
-
- default:
- exit(0);
- }
-
- ngx_pid = ngx_getpid();
-
- if (setsid() == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed");
- return NGX_ERROR;
- }
-
- umask(0);
-
- fd = open("/dev/null", O_RDWR);
- if (fd == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- "open(\"/dev/null\") failed");
- return NGX_ERROR;
- }
-
- if (dup2(fd, STDIN_FILENO) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed");
- return NGX_ERROR;
- }
-
- if (dup2(fd, STDOUT_FILENO) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed");
- return NGX_ERROR;
- }
-
-#if 0
- if (dup2(fd, STDERR_FILENO) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDERR) failed");
- return NGX_ERROR;
- }
-#endif
-
- if (fd > STDERR_FILENO) {
- if (close(fd) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed");
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_darwin.h b/usr.sbin/nginx/src/os/unix/ngx_darwin.h
deleted file mode 100644
index 4d01b26ea54..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_darwin.h
+++ /dev/null
@@ -1,23 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_DARWIN_H_INCLUDED_
-#define _NGX_DARWIN_H_INCLUDED_
-
-
-void ngx_debug_init(void);
-ngx_chain_t *ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
-
-extern int ngx_darwin_kern_osreldate;
-extern int ngx_darwin_hw_ncpu;
-extern u_long ngx_darwin_net_inet_tcp_sendspace;
-
-extern ngx_uint_t ngx_debug_malloc;
-
-
-#endif /* _NGX_DARWIN_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_darwin_config.h b/usr.sbin/nginx/src/os/unix/ngx_darwin_config.h
deleted file mode 100644
index 7ac86c73e82..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_darwin_config.h
+++ /dev/null
@@ -1,98 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_DARWIN_CONFIG_H_INCLUDED_
-#define _NGX_DARWIN_CONFIG_H_INCLUDED_
-
-
-#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_0
-
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <stdarg.h>
-#include <stddef.h> /* offsetof() */
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include <pwd.h>
-#include <grp.h>
-#include <dirent.h>
-#include <glob.h>
-#include <sys/mount.h> /* statfs() */
-
-#include <sys/filio.h> /* FIONBIO */
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <sched.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h> /* TCP_NODELAY */
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/un.h>
-
-#include <sys/sysctl.h>
-#include <xlocale.h>
-
-
-#ifndef IOV_MAX
-#define IOV_MAX 64
-#endif
-
-
-#include <ngx_auto_config.h>
-
-
-#if (NGX_HAVE_POSIX_SEM)
-#include <semaphore.h>
-#endif
-
-
-#if (NGX_HAVE_POLL)
-#include <poll.h>
-#endif
-
-
-#if (NGX_HAVE_KQUEUE)
-#include <sys/event.h>
-#endif
-
-
-#define NGX_LISTEN_BACKLOG -1
-
-
-#ifndef NGX_HAVE_INHERITED_NONBLOCK
-#define NGX_HAVE_INHERITED_NONBLOCK 1
-#endif
-
-
-#ifndef NGX_HAVE_CASELESS_FILESYSTEM
-#define NGX_HAVE_CASELESS_FILESYSTEM 1
-#endif
-
-
-#define NGX_HAVE_OS_SPECIFIC_INIT 1
-#define NGX_HAVE_DEBUG_MALLOC 1
-
-
-extern char **environ;
-
-
-#endif /* _NGX_DARWIN_CONFIG_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_darwin_init.c b/usr.sbin/nginx/src/os/unix/ngx_darwin_init.c
deleted file mode 100644
index 1bc7520cade..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_darwin_init.c
+++ /dev/null
@@ -1,196 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-char ngx_darwin_kern_ostype[16];
-char ngx_darwin_kern_osrelease[128];
-int ngx_darwin_hw_ncpu;
-int ngx_darwin_kern_ipc_somaxconn;
-u_long ngx_darwin_net_inet_tcp_sendspace;
-
-ngx_uint_t ngx_debug_malloc;
-
-
-static ngx_os_io_t ngx_darwin_io = {
- ngx_unix_recv,
- ngx_readv_chain,
- ngx_udp_unix_recv,
- ngx_unix_send,
-#if (NGX_HAVE_SENDFILE)
- ngx_darwin_sendfile_chain,
- NGX_IO_SENDFILE
-#else
- ngx_writev_chain,
- 0
-#endif
-};
-
-
-typedef struct {
- char *name;
- void *value;
- size_t size;
- ngx_uint_t exists;
-} sysctl_t;
-
-
-sysctl_t sysctls[] = {
- { "hw.ncpu",
- &ngx_darwin_hw_ncpu,
- sizeof(ngx_darwin_hw_ncpu), 0 },
-
- { "net.inet.tcp.sendspace",
- &ngx_darwin_net_inet_tcp_sendspace,
- sizeof(ngx_darwin_net_inet_tcp_sendspace), 0 },
-
- { "kern.ipc.somaxconn",
- &ngx_darwin_kern_ipc_somaxconn,
- sizeof(ngx_darwin_kern_ipc_somaxconn), 0 },
-
- { NULL, NULL, 0, 0 }
-};
-
-
-void
-ngx_debug_init(void)
-{
-#if (NGX_DEBUG_MALLOC)
-
- /*
- * MacOSX 10.6, 10.7: MallocScribble fills freed memory with 0x55
- * and fills allocated memory with 0xAA.
- * MacOSX 10.4, 10.5: MallocScribble fills freed memory with 0x55,
- * MallocPreScribble fills allocated memory with 0xAA.
- * MacOSX 10.3: MallocScribble fills freed memory with 0x55,
- * and no way to fill allocated memory.
- */
-
- setenv("MallocScribble", "1", 0);
-
- ngx_debug_malloc = 1;
-
-#else
-
- if (getenv("MallocScribble")) {
- ngx_debug_malloc = 1;
- }
-
-#endif
-}
-
-
-ngx_int_t
-ngx_os_specific_init(ngx_log_t *log)
-{
- size_t size;
- ngx_err_t err;
- ngx_uint_t i;
-
- size = sizeof(ngx_darwin_kern_ostype);
- if (sysctlbyname("kern.ostype", ngx_darwin_kern_ostype, &size, NULL, 0)
- == -1)
- {
- err = ngx_errno;
-
- if (err != NGX_ENOENT) {
-
- ngx_log_error(NGX_LOG_ALERT, log, err,
- "sysctlbyname(kern.ostype) failed");
-
- if (err != NGX_ENOMEM) {
- return NGX_ERROR;
- }
-
- ngx_darwin_kern_ostype[size - 1] = '\0';
- }
- }
-
- size = sizeof(ngx_darwin_kern_osrelease);
- if (sysctlbyname("kern.osrelease", ngx_darwin_kern_osrelease, &size,
- NULL, 0)
- == -1)
- {
- err = ngx_errno;
-
- if (err != NGX_ENOENT) {
-
- ngx_log_error(NGX_LOG_ALERT, log, err,
- "sysctlbyname(kern.osrelease) failed");
-
- if (err != NGX_ENOMEM) {
- return NGX_ERROR;
- }
-
- ngx_darwin_kern_osrelease[size - 1] = '\0';
- }
- }
-
- for (i = 0; sysctls[i].name; i++) {
- size = sysctls[i].size;
-
- if (sysctlbyname(sysctls[i].name, sysctls[i].value, &size, NULL, 0)
- == 0)
- {
- sysctls[i].exists = 1;
- continue;
- }
-
- err = ngx_errno;
-
- if (err == NGX_ENOENT) {
- continue;
- }
-
- ngx_log_error(NGX_LOG_ALERT, log, err,
- "sysctlbyname(%s) failed", sysctls[i].name);
- return NGX_ERROR;
- }
-
- ngx_ncpu = ngx_darwin_hw_ncpu;
-
- if (ngx_darwin_kern_ipc_somaxconn > 32767) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- "sysctl kern.ipc.somaxconn must be less than 32768");
- return NGX_ERROR;
- }
-
- ngx_tcp_nodelay_and_tcp_nopush = 1;
-
- ngx_os_io = ngx_darwin_io;
-
- return NGX_OK;
-}
-
-
-void
-ngx_os_specific_status(ngx_log_t *log)
-{
- u_long value;
- ngx_uint_t i;
-
- if (ngx_darwin_kern_ostype[0]) {
- ngx_log_error(NGX_LOG_NOTICE, log, 0, "OS: %s %s",
- ngx_darwin_kern_ostype, ngx_darwin_kern_osrelease);
- }
-
- for (i = 0; sysctls[i].name; i++) {
- if (sysctls[i].exists) {
- if (sysctls[i].size == sizeof(long)) {
- value = *(long *) sysctls[i].value;
-
- } else {
- value = *(int *) sysctls[i].value;
- }
-
- ngx_log_error(NGX_LOG_NOTICE, log, 0, "%s: %l",
- sysctls[i].name, value);
- }
- }
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_darwin_sendfile_chain.c b/usr.sbin/nginx/src/os/unix/ngx_darwin_sendfile_chain.c
deleted file mode 100644
index 76c4a3a4dad..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_darwin_sendfile_chain.c
+++ /dev/null
@@ -1,370 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-/*
- * It seems that Darwin 9.4 (Mac OS X 1.5) sendfile() has the same
- * old bug as early FreeBSD sendfile() syscall:
- * http://www.freebsd.org/cgi/query-pr.cgi?pr=33771
- *
- * Besides sendfile() has another bug: if one calls sendfile()
- * with both a header and a trailer, then sendfile() ignores a file part
- * at all and sends only the header and the trailer together.
- * For this reason we send a trailer only if there is no a header.
- *
- * Although sendfile() allows to pass a header or a trailer,
- * it may send the header or the trailer and a part of the file
- * in different packets. And FreeBSD workaround (TCP_NOPUSH option)
- * does not help.
- */
-
-
-#if (IOV_MAX > 64)
-#define NGX_HEADERS 64
-#define NGX_TRAILERS 64
-#else
-#define NGX_HEADERS IOV_MAX
-#define NGX_TRAILERS IOV_MAX
-#endif
-
-
-ngx_chain_t *
-ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
-{
- int rc;
- u_char *prev;
- off_t size, send, prev_send, aligned, sent, fprev;
- off_t header_size, file_size;
- ngx_uint_t eintr, complete;
- ngx_err_t err;
- ngx_buf_t *file;
- ngx_array_t header, trailer;
- ngx_event_t *wev;
- ngx_chain_t *cl;
- struct sf_hdtr hdtr;
- struct iovec *iov, headers[NGX_HEADERS], trailers[NGX_TRAILERS];
-
- wev = c->write;
-
- if (!wev->ready) {
- return in;
- }
-
-#if (NGX_HAVE_KQUEUE)
-
- if ((ngx_event_flags & NGX_USE_KQUEUE_EVENT) && wev->pending_eof) {
- (void) ngx_connection_error(c, wev->kq_errno,
- "kevent() reported about an closed connection");
- wev->error = 1;
- return NGX_CHAIN_ERROR;
- }
-
-#endif
-
- /* the maximum limit size is the maximum size_t value - the page size */
-
- if (limit == 0 || limit > (off_t) (NGX_MAX_SIZE_T_VALUE - ngx_pagesize)) {
- limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
- }
-
- send = 0;
-
- header.elts = headers;
- header.size = sizeof(struct iovec);
- header.nalloc = NGX_HEADERS;
- header.pool = c->pool;
-
- trailer.elts = trailers;
- trailer.size = sizeof(struct iovec);
- trailer.nalloc = NGX_TRAILERS;
- trailer.pool = c->pool;
-
- for ( ;; ) {
- file = NULL;
- file_size = 0;
- header_size = 0;
- eintr = 0;
- complete = 0;
- prev_send = send;
-
- header.nelts = 0;
- trailer.nelts = 0;
-
- /* create the header iovec and coalesce the neighbouring bufs */
-
- prev = NULL;
- iov = NULL;
-
- for (cl = in; cl && send < limit; cl = cl->next) {
-
- if (ngx_buf_special(cl->buf)) {
- continue;
- }
-
- if (!ngx_buf_in_memory_only(cl->buf)) {
- break;
- }
-
- size = cl->buf->last - cl->buf->pos;
-
- if (send + size > limit) {
- size = limit - send;
- }
-
- if (prev == cl->buf->pos) {
- iov->iov_len += (size_t) size;
-
- } else {
- if (header.nelts >= IOV_MAX) {
- break;
- }
-
- iov = ngx_array_push(&header);
- if (iov == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- iov->iov_base = (void *) cl->buf->pos;
- iov->iov_len = (size_t) size;
- }
-
- prev = cl->buf->pos + (size_t) size;
- header_size += size;
- send += size;
- }
-
-
- if (cl && cl->buf->in_file && send < limit) {
- file = cl->buf;
-
- /* coalesce the neighbouring file bufs */
-
- do {
- size = cl->buf->file_last - cl->buf->file_pos;
-
- if (send + size > limit) {
- size = limit - send;
-
- aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
- & ~((off_t) ngx_pagesize - 1);
-
- if (aligned <= cl->buf->file_last) {
- size = aligned - cl->buf->file_pos;
- }
- }
-
- file_size += size;
- send += size;
- fprev = cl->buf->file_pos + size;
- cl = cl->next;
-
- } while (cl
- && cl->buf->in_file
- && send < limit
- && file->file->fd == cl->buf->file->fd
- && fprev == cl->buf->file_pos);
- }
-
- if (file && header.nelts == 0) {
-
- /* create the trailer iovec and coalesce the neighbouring bufs */
-
- prev = NULL;
- iov = NULL;
-
- while (cl && send < limit) {
-
- if (ngx_buf_special(cl->buf)) {
- cl = cl->next;
- continue;
- }
-
- if (!ngx_buf_in_memory_only(cl->buf)) {
- break;
- }
-
- size = cl->buf->last - cl->buf->pos;
-
- if (send + size > limit) {
- size = limit - send;
- }
-
- if (prev == cl->buf->pos) {
- iov->iov_len += (size_t) size;
-
- } else {
- if (trailer.nelts >= IOV_MAX) {
- break;
- }
-
- iov = ngx_array_push(&trailer);
- if (iov == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- iov->iov_base = (void *) cl->buf->pos;
- iov->iov_len = (size_t) size;
- }
-
- prev = cl->buf->pos + (size_t) size;
- send += size;
- cl = cl->next;
- }
- }
-
- if (file) {
-
- /*
- * sendfile() returns EINVAL if sf_hdtr's count is 0,
- * but corresponding pointer is not NULL
- */
-
- hdtr.headers = header.nelts ? (struct iovec *) header.elts: NULL;
- hdtr.hdr_cnt = header.nelts;
- hdtr.trailers = trailer.nelts ? (struct iovec *) trailer.elts: NULL;
- hdtr.trl_cnt = trailer.nelts;
-
- sent = header_size + file_size;
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "sendfile: @%O %O h:%O",
- file->file_pos, sent, header_size);
-
- rc = sendfile(file->file->fd, c->fd, file->file_pos,
- &sent, &hdtr, 0);
-
- if (rc == -1) {
- err = ngx_errno;
-
- switch (err) {
- case NGX_EAGAIN:
- break;
-
- case NGX_EINTR:
- eintr = 1;
- break;
-
- default:
- wev->error = 1;
- (void) ngx_connection_error(c, err, "sendfile() failed");
- return NGX_CHAIN_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
- "sendfile() sent only %O bytes", sent);
- }
-
- if (rc == 0 && sent == 0) {
-
- /*
- * if rc and sent equal to zero, then someone
- * has truncated the file, so the offset became beyond
- * the end of the file
- */
-
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "sendfile() reported that \"%s\" was truncated",
- file->file->name.data);
-
- return NGX_CHAIN_ERROR;
- }
-
- ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "sendfile: %d, @%O %O:%O",
- rc, file->file_pos, sent, file_size + header_size);
-
- } else {
- rc = writev(c->fd, header.elts, header.nelts);
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "writev: %d of %uz", rc, send);
-
- if (rc == -1) {
- err = ngx_errno;
-
- switch (err) {
- case NGX_EAGAIN:
- break;
-
- case NGX_EINTR:
- eintr = 1;
- break;
-
- default:
- wev->error = 1;
- ngx_connection_error(c, err, "writev() failed");
- return NGX_CHAIN_ERROR;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "writev() not ready");
- }
-
- sent = rc > 0 ? rc : 0;
- }
-
- if (send - prev_send == sent) {
- complete = 1;
- }
-
- c->sent += sent;
-
- for ( /* void */ ; in; in = in->next) {
-
- if (ngx_buf_special(in->buf)) {
- continue;
- }
-
- if (sent == 0) {
- break;
- }
-
- size = ngx_buf_size(in->buf);
-
- if (sent >= size) {
- sent -= size;
-
- if (ngx_buf_in_memory(in->buf)) {
- in->buf->pos = in->buf->last;
- }
-
- if (in->buf->in_file) {
- in->buf->file_pos = in->buf->file_last;
- }
-
- continue;
- }
-
- if (ngx_buf_in_memory(in->buf)) {
- in->buf->pos += (size_t) sent;
- }
-
- if (in->buf->in_file) {
- in->buf->file_pos += sent;
- }
-
- break;
- }
-
- if (eintr) {
- continue;
- }
-
- if (!complete) {
- wev->ready = 0;
- return in;
- }
-
- if (send >= limit || in == NULL) {
- return in;
- }
- }
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_errno.c b/usr.sbin/nginx/src/os/unix/ngx_errno.c
deleted file mode 100644
index e787b2377ed..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_errno.c
+++ /dev/null
@@ -1,87 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/*
- * The strerror() messages are copied because:
- *
- * 1) strerror() and strerror_r() functions are not Async-Signal-Safe,
- * therefore, they cannot be used in signal handlers;
- *
- * 2) a direct sys_errlist[] array may be used instead of these functions,
- * but Linux linker warns about its usage:
- *
- * warning: `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead
- * warning: `sys_nerr' is deprecated; use `strerror' or `strerror_r' instead
- *
- * causing false bug reports.
- */
-
-
-static ngx_str_t *ngx_sys_errlist;
-static ngx_str_t ngx_unknown_error = ngx_string("Unknown error");
-
-
-u_char *
-ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
-{
- ngx_str_t *msg;
-
- msg = ((ngx_uint_t) err < NGX_SYS_NERR) ? &ngx_sys_errlist[err]:
- &ngx_unknown_error;
- size = ngx_min(size, msg->len);
-
- return ngx_cpymem(errstr, msg->data, size);
-}
-
-
-ngx_int_t
-ngx_strerror_init(void)
-{
- char *msg;
- u_char *p;
- size_t len;
- ngx_err_t err;
-
- /*
- * ngx_strerror() is not ready to work at this stage, therefore,
- * malloc() is used and possible errors are logged using strerror().
- */
-
- len = NGX_SYS_NERR * sizeof(ngx_str_t);
-
- ngx_sys_errlist = malloc(len);
- if (ngx_sys_errlist == NULL) {
- goto failed;
- }
-
- for (err = 0; err < NGX_SYS_NERR; err++) {
- msg = strerror(err);
- len = ngx_strlen(msg);
-
- p = malloc(len);
- if (p == NULL) {
- goto failed;
- }
-
- ngx_memcpy(p, msg, len);
- ngx_sys_errlist[err].len = len;
- ngx_sys_errlist[err].data = p;
- }
-
- return NGX_OK;
-
-failed:
-
- err = errno;
- ngx_log_stderr(0, "malloc(%uz) failed (%d: %s)", len, err, strerror(err));
-
- return NGX_ERROR;
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_errno.h b/usr.sbin/nginx/src/os/unix/ngx_errno.h
deleted file mode 100644
index 16cafda3107..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_errno.h
+++ /dev/null
@@ -1,78 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_ERRNO_H_INCLUDED_
-#define _NGX_ERRNO_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef int ngx_err_t;
-
-#define NGX_EPERM EPERM
-#define NGX_ENOENT ENOENT
-#define NGX_ENOPATH ENOENT
-#define NGX_ESRCH ESRCH
-#define NGX_EINTR EINTR
-#define NGX_ECHILD ECHILD
-#define NGX_ENOMEM ENOMEM
-#define NGX_EACCES EACCES
-#define NGX_EBUSY EBUSY
-#define NGX_EEXIST EEXIST
-#define NGX_EXDEV EXDEV
-#define NGX_ENOTDIR ENOTDIR
-#define NGX_EISDIR EISDIR
-#define NGX_EINVAL EINVAL
-#define NGX_ENFILE ENFILE
-#define NGX_EMFILE EMFILE
-#define NGX_ENOSPC ENOSPC
-#define NGX_EPIPE EPIPE
-#define NGX_EINPROGRESS EINPROGRESS
-#define NGX_ENOPROTOOPT ENOPROTOOPT
-#define NGX_EOPNOTSUPP EOPNOTSUPP
-#define NGX_EADDRINUSE EADDRINUSE
-#define NGX_ECONNABORTED ECONNABORTED
-#define NGX_ECONNRESET ECONNRESET
-#define NGX_ENOTCONN ENOTCONN
-#define NGX_ETIMEDOUT ETIMEDOUT
-#define NGX_ECONNREFUSED ECONNREFUSED
-#define NGX_ENAMETOOLONG ENAMETOOLONG
-#define NGX_ENETDOWN ENETDOWN
-#define NGX_ENETUNREACH ENETUNREACH
-#define NGX_EHOSTDOWN EHOSTDOWN
-#define NGX_EHOSTUNREACH EHOSTUNREACH
-#define NGX_ENOSYS ENOSYS
-#define NGX_ECANCELED ECANCELED
-#define NGX_EILSEQ EILSEQ
-#define NGX_ENOMOREFILES 0
-#define NGX_ELOOP ELOOP
-#define NGX_EBADF EBADF
-
-#if (NGX_HAVE_OPENAT)
-#define NGX_EMLINK EMLINK
-#endif
-
-#if (__hpux__)
-#define NGX_EAGAIN EWOULDBLOCK
-#else
-#define NGX_EAGAIN EAGAIN
-#endif
-
-
-#define ngx_errno errno
-#define ngx_socket_errno errno
-#define ngx_set_errno(err) errno = err
-#define ngx_set_socket_errno(err) errno = err
-
-
-u_char *ngx_strerror(ngx_err_t err, u_char *errstr, size_t size);
-ngx_int_t ngx_strerror_init(void);
-
-
-#endif /* _NGX_ERRNO_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_file_aio_read.c b/usr.sbin/nginx/src/os/unix/ngx_file_aio_read.c
deleted file mode 100644
index 0bb383de551..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_file_aio_read.c
+++ /dev/null
@@ -1,208 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-/*
- * FreeBSD file AIO features and quirks:
- *
- * if an asked data are already in VM cache, then aio_error() returns 0,
- * and the data are already copied in buffer;
- *
- * aio_read() preread in VM cache as minimum 16K (probably BKVASIZE);
- * the first AIO preload may be up to 128K;
- *
- * aio_read/aio_error() may return EINPROGRESS for just written data;
- *
- * kqueue EVFILT_AIO filter is level triggered only: an event repeats
- * until aio_return() will be called;
- *
- * aio_cancel() cannot cancel file AIO: it returns AIO_NOTCANCELED always.
- */
-
-
-extern int ngx_kqueue;
-
-
-static ssize_t ngx_file_aio_result(ngx_file_t *file, ngx_event_aio_t *aio,
- ngx_event_t *ev);
-static void ngx_file_aio_event_handler(ngx_event_t *ev);
-
-
-ssize_t
-ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
- ngx_pool_t *pool)
-{
- int n;
- ngx_event_t *ev;
- ngx_event_aio_t *aio;
-
- if (!ngx_file_aio) {
- return ngx_read_file(file, buf, size, offset);
- }
-
- aio = file->aio;
-
- if (aio == NULL) {
- aio = ngx_pcalloc(pool, sizeof(ngx_event_aio_t));
- if (aio == NULL) {
- return NGX_ERROR;
- }
-
- aio->file = file;
- aio->fd = file->fd;
- aio->event.data = aio;
- aio->event.ready = 1;
- aio->event.log = file->log;
-#if (NGX_HAVE_AIO_SENDFILE)
- aio->last_offset = -1;
-#endif
- file->aio = aio;
- }
-
- ev = &aio->event;
-
- if (!ev->ready) {
- ngx_log_error(NGX_LOG_ALERT, file->log, 0,
- "second aio post for \"%V\"", &file->name);
- return NGX_AGAIN;
- }
-
- ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
- "aio complete:%d @%O:%z %V",
- ev->complete, offset, size, &file->name);
-
- if (ev->complete) {
- ev->complete = 0;
- ngx_set_errno(aio->err);
-
- if (aio->err == 0) {
- return aio->nbytes;
- }
-
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "aio read \"%s\" failed", file->name.data);
-
- return NGX_ERROR;
- }
-
- ngx_memzero(&aio->aiocb, sizeof(struct aiocb));
-
- aio->aiocb.aio_fildes = file->fd;
- aio->aiocb.aio_offset = offset;
- aio->aiocb.aio_buf = buf;
- aio->aiocb.aio_nbytes = size;
-#if (NGX_HAVE_KQUEUE)
- aio->aiocb.aio_sigevent.sigev_notify_kqueue = ngx_kqueue;
- aio->aiocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
- aio->aiocb.aio_sigevent.sigev_value.sigval_ptr = ev;
-#endif
- ev->handler = ngx_file_aio_event_handler;
-
- n = aio_read(&aio->aiocb);
-
- if (n == -1) {
- n = ngx_errno;
-
- if (n == NGX_EAGAIN) {
- return ngx_read_file(file, buf, size, offset);
- }
-
- ngx_log_error(NGX_LOG_CRIT, file->log, n,
- "aio_read(\"%V\") failed", &file->name);
-
- if (n == NGX_ENOSYS) {
- ngx_file_aio = 0;
- return ngx_read_file(file, buf, size, offset);
- }
-
- return NGX_ERROR;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, file->log, 0,
- "aio_read: fd:%d %d", file->fd, n);
-
- ev->active = 1;
- ev->ready = 0;
- ev->complete = 0;
-
- return ngx_file_aio_result(aio->file, aio, ev);
-}
-
-
-static ssize_t
-ngx_file_aio_result(ngx_file_t *file, ngx_event_aio_t *aio, ngx_event_t *ev)
-{
- int n;
- ngx_err_t err;
-
- n = aio_error(&aio->aiocb);
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, file->log, 0,
- "aio_error: fd:%d %d", file->fd, n);
-
- if (n == -1) {
- err = ngx_errno;
- aio->err = err;
-
- ngx_log_error(NGX_LOG_ALERT, file->log, err,
- "aio_error(\"%V\") failed", &file->name);
- return NGX_ERROR;
- }
-
- if (n == NGX_EINPROGRESS) {
- if (ev->ready) {
- ev->ready = 0;
- ngx_log_error(NGX_LOG_ALERT, file->log, n,
- "aio_read(\"%V\") still in progress",
- &file->name);
- }
-
- return NGX_AGAIN;
- }
-
- n = aio_return(&aio->aiocb);
-
- if (n == -1) {
- err = ngx_errno;
- aio->err = err;
- ev->ready = 1;
-
- ngx_log_error(NGX_LOG_CRIT, file->log, err,
- "aio_return(\"%V\") failed", &file->name);
- return NGX_ERROR;
- }
-
- aio->err = 0;
- aio->nbytes = n;
- ev->ready = 1;
- ev->active = 0;
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, file->log, 0,
- "aio_return: fd:%d %d", file->fd, n);
-
- return n;
-}
-
-
-static void
-ngx_file_aio_event_handler(ngx_event_t *ev)
-{
- ngx_event_aio_t *aio;
-
- aio = ev->data;
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, ev->log, 0,
- "aio event handler fd:%d %V", aio->fd, &aio->file->name);
-
- if (ngx_file_aio_result(aio->file, aio, ev) != NGX_AGAIN) {
- aio->handler(ev);
- }
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_files.c b/usr.sbin/nginx/src/os/unix/ngx_files.c
deleted file mode 100644
index c3ae47fdbf6..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_files.c
+++ /dev/null
@@ -1,564 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#if (NGX_HAVE_FILE_AIO)
-
-ngx_uint_t ngx_file_aio = 1;
-
-#endif
-
-
-ssize_t
-ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
-{
- ssize_t n;
-
- ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
- "read: %d, %p, %uz, %O", file->fd, buf, size, offset);
-
-#if (NGX_HAVE_PREAD)
-
- n = pread(file->fd, buf, size, offset);
-
- if (n == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "pread() \"%s\" failed", file->name.data);
- return NGX_ERROR;
- }
-
-#else
-
- if (file->sys_offset != offset) {
- if (lseek(file->fd, offset, SEEK_SET) == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "lseek() \"%s\" failed", file->name.data);
- return NGX_ERROR;
- }
-
- file->sys_offset = offset;
- }
-
- n = read(file->fd, buf, size);
-
- if (n == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "read() \"%s\" failed", file->name.data);
- return NGX_ERROR;
- }
-
- file->sys_offset += n;
-
-#endif
-
- file->offset += n;
-
- return n;
-}
-
-
-ssize_t
-ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
-{
- ssize_t n, written;
-
- ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
- "write: %d, %p, %uz, %O", file->fd, buf, size, offset);
-
- written = 0;
-
-#if (NGX_HAVE_PWRITE)
-
- for ( ;; ) {
- n = pwrite(file->fd, buf + written, size, offset);
-
- if (n == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "pwrite() \"%s\" failed", file->name.data);
- return NGX_ERROR;
- }
-
- file->offset += n;
- written += n;
-
- if ((size_t) n == size) {
- return written;
- }
-
- offset += n;
- size -= n;
- }
-
-#else
-
- if (file->sys_offset != offset) {
- if (lseek(file->fd, offset, SEEK_SET) == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "lseek() \"%s\" failed", file->name.data);
- return NGX_ERROR;
- }
-
- file->sys_offset = offset;
- }
-
- for ( ;; ) {
- n = write(file->fd, buf + written, size);
-
- if (n == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "write() \"%s\" failed", file->name.data);
- return NGX_ERROR;
- }
-
- file->offset += n;
- written += n;
-
- if ((size_t) n == size) {
- return written;
- }
-
- size -= n;
- }
-#endif
-}
-
-
-ngx_fd_t
-ngx_open_tempfile(u_char *name, ngx_uint_t persistent, ngx_uint_t access)
-{
- ngx_fd_t fd;
-
- fd = open((const char *) name, O_CREAT|O_EXCL|O_RDWR,
- access ? access : 0600);
-
- if (fd != -1 && !persistent) {
- (void) unlink((const char *) name);
- }
-
- return fd;
-}
-
-
-#define NGX_IOVS 8
-
-ssize_t
-ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *cl, off_t offset,
- ngx_pool_t *pool)
-{
- u_char *prev;
- size_t size;
- ssize_t total, n;
- ngx_array_t vec;
- struct iovec *iov, iovs[NGX_IOVS];
-
- /* use pwrite() if there is the only buf in a chain */
-
- if (cl->next == NULL) {
- return ngx_write_file(file, cl->buf->pos,
- (size_t) (cl->buf->last - cl->buf->pos),
- offset);
- }
-
- total = 0;
-
- vec.elts = iovs;
- vec.size = sizeof(struct iovec);
- vec.nalloc = NGX_IOVS;
- vec.pool = pool;
-
- do {
- prev = NULL;
- iov = NULL;
- size = 0;
-
- vec.nelts = 0;
-
- /* create the iovec and coalesce the neighbouring bufs */
-
- while (cl && vec.nelts < IOV_MAX) {
- if (prev == cl->buf->pos) {
- iov->iov_len += cl->buf->last - cl->buf->pos;
-
- } else {
- iov = ngx_array_push(&vec);
- if (iov == NULL) {
- return NGX_ERROR;
- }
-
- iov->iov_base = (void *) cl->buf->pos;
- iov->iov_len = cl->buf->last - cl->buf->pos;
- }
-
- size += cl->buf->last - cl->buf->pos;
- prev = cl->buf->last;
- cl = cl->next;
- }
-
- /* use pwrite() if there is the only iovec buffer */
-
- if (vec.nelts == 1) {
- iov = vec.elts;
-
- n = ngx_write_file(file, (u_char *) iov[0].iov_base,
- iov[0].iov_len, offset);
-
- if (n == NGX_ERROR) {
- return n;
- }
-
- return total + n;
- }
-
- if (file->sys_offset != offset) {
- if (lseek(file->fd, offset, SEEK_SET) == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "lseek() \"%s\" failed", file->name.data);
- return NGX_ERROR;
- }
-
- file->sys_offset = offset;
- }
-
- n = writev(file->fd, vec.elts, vec.nelts);
-
- if (n == -1) {
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "writev() \"%s\" failed", file->name.data);
- return NGX_ERROR;
- }
-
- if ((size_t) n != size) {
- ngx_log_error(NGX_LOG_CRIT, file->log, 0,
- "writev() \"%s\" has written only %z of %uz",
- file->name.data, n, size);
- return NGX_ERROR;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, file->log, 0,
- "writev: %d, %z", file->fd, n);
-
- file->sys_offset += n;
- file->offset += n;
- offset += n;
- total += n;
-
- } while (cl);
-
- return total;
-}
-
-
-ngx_int_t
-ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s)
-{
- struct timeval tv[2];
-
- tv[0].tv_sec = ngx_time();
- tv[0].tv_usec = 0;
- tv[1].tv_sec = s;
- tv[1].tv_usec = 0;
-
- if (utimes((char *) name, tv) != -1) {
- return NGX_OK;
- }
-
- return NGX_ERROR;
-}
-
-
-ngx_int_t
-ngx_create_file_mapping(ngx_file_mapping_t *fm)
-{
- fm->fd = ngx_open_file(fm->name, NGX_FILE_RDWR, NGX_FILE_TRUNCATE,
- NGX_FILE_DEFAULT_ACCESS);
- if (fm->fd == NGX_INVALID_FILE) {
- ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
- ngx_open_file_n " \"%s\" failed", fm->name);
- return NGX_ERROR;
- }
-
- if (ftruncate(fm->fd, fm->size) == -1) {
- ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
- "ftruncate() \"%s\" failed", fm->name);
- goto failed;
- }
-
- fm->addr = mmap(NULL, fm->size, PROT_READ|PROT_WRITE, MAP_SHARED,
- fm->fd, 0);
- if (fm->addr != MAP_FAILED) {
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
- "mmap(%uz) \"%s\" failed", fm->size, fm->name);
-
-failed:
-
- if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", fm->name);
- }
-
- return NGX_ERROR;
-}
-
-
-void
-ngx_close_file_mapping(ngx_file_mapping_t *fm)
-{
- if (munmap(fm->addr, fm->size) == -1) {
- ngx_log_error(NGX_LOG_CRIT, fm->log, ngx_errno,
- "munmap(%uz) \"%s\" failed", fm->size, fm->name);
- }
-
- if (ngx_close_file(fm->fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, fm->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", fm->name);
- }
-}
-
-
-ngx_int_t
-ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir)
-{
- dir->dir = opendir((const char *) name->data);
-
- if (dir->dir == NULL) {
- return NGX_ERROR;
- }
-
- dir->valid_info = 0;
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_read_dir(ngx_dir_t *dir)
-{
- dir->de = readdir(dir->dir);
-
- if (dir->de) {
-#if (NGX_HAVE_D_TYPE)
- dir->type = dir->de->d_type;
-#else
- dir->type = 0;
-#endif
- return NGX_OK;
- }
-
- return NGX_ERROR;
-}
-
-
-ngx_int_t
-ngx_open_glob(ngx_glob_t *gl)
-{
- int n;
-
- n = glob((char *) gl->pattern, 0, NULL, &gl->pglob);
-
- if (n == 0) {
- return NGX_OK;
- }
-
-#ifdef GLOB_NOMATCH
-
- if (n == GLOB_NOMATCH && gl->test) {
- return NGX_OK;
- }
-
-#endif
-
- return NGX_ERROR;
-}
-
-
-ngx_int_t
-ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name)
-{
- size_t count;
-
-#ifdef GLOB_NOMATCH
- count = (size_t) gl->pglob.gl_pathc;
-#else
- count = (size_t) gl->pglob.gl_matchc;
-#endif
-
- if (gl->n < count) {
-
- name->len = (size_t) ngx_strlen(gl->pglob.gl_pathv[gl->n]);
- name->data = (u_char *) gl->pglob.gl_pathv[gl->n];
- gl->n++;
-
- return NGX_OK;
- }
-
- return NGX_DONE;
-}
-
-
-void
-ngx_close_glob(ngx_glob_t *gl)
-{
- globfree(&gl->pglob);
-}
-
-
-ngx_err_t
-ngx_trylock_fd(ngx_fd_t fd)
-{
- struct flock fl;
-
- ngx_memzero(&fl, sizeof(struct flock));
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
-
- if (fcntl(fd, F_SETLK, &fl) == -1) {
- return ngx_errno;
- }
-
- return 0;
-}
-
-
-ngx_err_t
-ngx_lock_fd(ngx_fd_t fd)
-{
- struct flock fl;
-
- ngx_memzero(&fl, sizeof(struct flock));
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
-
- if (fcntl(fd, F_SETLKW, &fl) == -1) {
- return ngx_errno;
- }
-
- return 0;
-}
-
-
-ngx_err_t
-ngx_unlock_fd(ngx_fd_t fd)
-{
- struct flock fl;
-
- ngx_memzero(&fl, sizeof(struct flock));
- fl.l_type = F_UNLCK;
- fl.l_whence = SEEK_SET;
-
- if (fcntl(fd, F_SETLK, &fl) == -1) {
- return ngx_errno;
- }
-
- return 0;
-}
-
-
-#if (NGX_HAVE_POSIX_FADVISE) && !(NGX_HAVE_F_READAHEAD)
-
-ngx_int_t
-ngx_read_ahead(ngx_fd_t fd, size_t n)
-{
- int err;
-
- err = posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
-
- if (err == 0) {
- return 0;
- }
-
- ngx_set_errno(err);
- return NGX_FILE_ERROR;
-}
-
-#endif
-
-
-#if (NGX_HAVE_O_DIRECT)
-
-ngx_int_t
-ngx_directio_on(ngx_fd_t fd)
-{
- int flags;
-
- flags = fcntl(fd, F_GETFL);
-
- if (flags == -1) {
- return NGX_FILE_ERROR;
- }
-
- return fcntl(fd, F_SETFL, flags | O_DIRECT);
-}
-
-
-ngx_int_t
-ngx_directio_off(ngx_fd_t fd)
-{
- int flags;
-
- flags = fcntl(fd, F_GETFL);
-
- if (flags == -1) {
- return NGX_FILE_ERROR;
- }
-
- return fcntl(fd, F_SETFL, flags & ~O_DIRECT);
-}
-
-#endif
-
-
-#if (NGX_HAVE_STATFS)
-
-size_t
-ngx_fs_bsize(u_char *name)
-{
- struct statfs fs;
-
- if (statfs((char *) name, &fs) == -1) {
- return 512;
- }
-
- if ((fs.f_bsize % 512) != 0) {
- return 512;
- }
-
- return (size_t) fs.f_bsize;
-}
-
-#elif (NGX_HAVE_STATVFS)
-
-size_t
-ngx_fs_bsize(u_char *name)
-{
- struct statvfs fs;
-
- if (statvfs((char *) name, &fs) == -1) {
- return 512;
- }
-
- if ((fs.f_frsize % 512) != 0) {
- return 512;
- }
-
- return (size_t) fs.f_frsize;
-}
-
-#else
-
-size_t
-ngx_fs_bsize(u_char *name)
-{
- return 512;
-}
-
-#endif
diff --git a/usr.sbin/nginx/src/os/unix/ngx_files.h b/usr.sbin/nginx/src/os/unix/ngx_files.h
deleted file mode 100644
index a78ec961365..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_files.h
+++ /dev/null
@@ -1,386 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_FILES_H_INCLUDED_
-#define _NGX_FILES_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef int ngx_fd_t;
-typedef struct stat ngx_file_info_t;
-typedef ino_t ngx_file_uniq_t;
-
-
-typedef struct {
- u_char *name;
- size_t size;
- void *addr;
- ngx_fd_t fd;
- ngx_log_t *log;
-} ngx_file_mapping_t;
-
-
-typedef struct {
- DIR *dir;
- struct dirent *de;
- struct stat info;
-
- unsigned type:8;
- unsigned valid_info:1;
-} ngx_dir_t;
-
-
-typedef struct {
- size_t n;
- glob_t pglob;
- u_char *pattern;
- ngx_log_t *log;
- ngx_uint_t test;
-} ngx_glob_t;
-
-
-#define NGX_INVALID_FILE -1
-#define NGX_FILE_ERROR -1
-
-
-
-#ifdef __CYGWIN__
-
-#ifndef NGX_HAVE_CASELESS_FILESYSTEM
-#define NGX_HAVE_CASELESS_FILESYSTEM 1
-#endif
-
-#define ngx_open_file(name, mode, create, access) \
- open((const char *) name, mode|create|O_BINARY, access)
-
-#else
-
-#define ngx_open_file(name, mode, create, access) \
- open((const char *) name, mode|create, access)
-
-#endif
-
-#define ngx_open_file_n "open()"
-
-#define NGX_FILE_RDONLY O_RDONLY
-#define NGX_FILE_WRONLY O_WRONLY
-#define NGX_FILE_RDWR O_RDWR
-#define NGX_FILE_CREATE_OR_OPEN O_CREAT
-#define NGX_FILE_OPEN 0
-#define NGX_FILE_TRUNCATE (O_CREAT|O_TRUNC)
-#define NGX_FILE_APPEND (O_WRONLY|O_APPEND)
-#define NGX_FILE_NONBLOCK O_NONBLOCK
-
-#if (NGX_HAVE_OPENAT)
-#define NGX_FILE_NOFOLLOW O_NOFOLLOW
-
-#if defined(O_DIRECTORY)
-#define NGX_FILE_DIRECTORY O_DIRECTORY
-#else
-#define NGX_FILE_DIRECTORY 0
-#endif
-
-#if defined(O_SEARCH)
-#define NGX_FILE_SEARCH (O_SEARCH|NGX_FILE_DIRECTORY)
-
-#elif defined(O_EXEC)
-#define NGX_FILE_SEARCH (O_EXEC|NGX_FILE_DIRECTORY)
-
-#elif (NGX_HAVE_O_PATH)
-#define NGX_FILE_SEARCH (O_PATH|O_RDONLY|NGX_FILE_DIRECTORY)
-
-#else
-#define NGX_FILE_SEARCH (O_RDONLY|NGX_FILE_DIRECTORY)
-#endif
-
-#endif /* NGX_HAVE_OPENAT */
-
-#define NGX_FILE_DEFAULT_ACCESS 0644
-#define NGX_FILE_OWNER_ACCESS 0600
-
-
-#define ngx_close_file close
-#define ngx_close_file_n "close()"
-
-
-#define ngx_delete_file(name) unlink((const char *) name)
-#define ngx_delete_file_n "unlink()"
-
-
-ngx_fd_t ngx_open_tempfile(u_char *name, ngx_uint_t persistent,
- ngx_uint_t access);
-#define ngx_open_tempfile_n "open()"
-
-
-ssize_t ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset);
-#if (NGX_HAVE_PREAD)
-#define ngx_read_file_n "pread()"
-#else
-#define ngx_read_file_n "read()"
-#endif
-
-ssize_t ngx_write_file(ngx_file_t *file, u_char *buf, size_t size,
- off_t offset);
-
-ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
- off_t offset, ngx_pool_t *pool);
-
-
-#define ngx_read_fd read
-#define ngx_read_fd_n "read()"
-
-/*
- * we use inlined function instead of simple #define
- * because glibc 2.3 sets warn_unused_result attribute for write()
- * and in this case gcc 4.3 ignores (void) cast
- */
-static ngx_inline ssize_t
-ngx_write_fd(ngx_fd_t fd, void *buf, size_t n)
-{
- return write(fd, buf, n);
-}
-
-#define ngx_write_fd_n "write()"
-
-
-#define ngx_write_console ngx_write_fd
-
-
-#define ngx_linefeed(p) *p++ = LF;
-#define NGX_LINEFEED_SIZE 1
-#define NGX_LINEFEED "\x0a"
-
-
-#define ngx_rename_file(o, n) rename((const char *) o, (const char *) n)
-#define ngx_rename_file_n "rename()"
-
-
-#define ngx_change_file_access(n, a) chmod((const char *) n, a)
-#define ngx_change_file_access_n "chmod()"
-
-
-ngx_int_t ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s);
-#define ngx_set_file_time_n "utimes()"
-
-
-#define ngx_file_info(file, sb) stat((const char *) file, sb)
-#define ngx_file_info_n "stat()"
-
-#define ngx_fd_info(fd, sb) fstat(fd, sb)
-#define ngx_fd_info_n "fstat()"
-
-#define ngx_link_info(file, sb) lstat((const char *) file, sb)
-#define ngx_link_info_n "lstat()"
-
-#define ngx_is_dir(sb) (S_ISDIR((sb)->st_mode))
-#define ngx_is_file(sb) (S_ISREG((sb)->st_mode))
-#define ngx_is_link(sb) (S_ISLNK((sb)->st_mode))
-#define ngx_is_exec(sb) (((sb)->st_mode & S_IXUSR) == S_IXUSR)
-#define ngx_file_access(sb) ((sb)->st_mode & 0777)
-#define ngx_file_size(sb) (sb)->st_size
-#define ngx_file_fs_size(sb) ngx_max((sb)->st_size, (sb)->st_blocks * 512)
-#define ngx_file_mtime(sb) (sb)->st_mtime
-#define ngx_file_uniq(sb) (sb)->st_ino
-
-
-ngx_int_t ngx_create_file_mapping(ngx_file_mapping_t *fm);
-void ngx_close_file_mapping(ngx_file_mapping_t *fm);
-
-
-#define ngx_realpath(p, r) (u_char *) realpath((char *) p, (char *) r)
-#define ngx_realpath_n "realpath()"
-#define ngx_getcwd(buf, size) (getcwd((char *) buf, size) != NULL)
-#define ngx_getcwd_n "getcwd()"
-#define ngx_path_separator(c) ((c) == '/')
-
-
-#if defined(PATH_MAX)
-
-#define NGX_HAVE_MAX_PATH 1
-#define NGX_MAX_PATH PATH_MAX
-
-#else
-
-#define NGX_MAX_PATH 4096
-
-#endif
-
-
-#define NGX_DIR_MASK_LEN 0
-
-
-ngx_int_t ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir);
-#define ngx_open_dir_n "opendir()"
-
-
-#define ngx_close_dir(d) closedir((d)->dir)
-#define ngx_close_dir_n "closedir()"
-
-
-ngx_int_t ngx_read_dir(ngx_dir_t *dir);
-#define ngx_read_dir_n "readdir()"
-
-
-#define ngx_create_dir(name, access) mkdir((const char *) name, access)
-#define ngx_create_dir_n "mkdir()"
-
-
-#define ngx_delete_dir(name) rmdir((const char *) name)
-#define ngx_delete_dir_n "rmdir()"
-
-
-#define ngx_dir_access(a) (a | (a & 0444) >> 2)
-
-
-#define ngx_de_name(dir) ((u_char *) (dir)->de->d_name)
-#if (NGX_HAVE_D_NAMLEN)
-#define ngx_de_namelen(dir) (dir)->de->d_namlen
-#else
-#define ngx_de_namelen(dir) ngx_strlen((dir)->de->d_name)
-#endif
-
-static ngx_inline ngx_int_t
-ngx_de_info(u_char *name, ngx_dir_t *dir)
-{
- dir->type = 0;
- return stat((const char *) name, &dir->info);
-}
-
-#define ngx_de_info_n "stat()"
-#define ngx_de_link_info(name, dir) lstat((const char *) name, &(dir)->info)
-#define ngx_de_link_info_n "lstat()"
-
-#if (NGX_HAVE_D_TYPE)
-
-/*
- * some file systems (e.g. XFS on Linux and CD9660 on FreeBSD)
- * do not set dirent.d_type
- */
-
-#define ngx_de_is_dir(dir) \
- (((dir)->type) ? ((dir)->type == DT_DIR) : (S_ISDIR((dir)->info.st_mode)))
-#define ngx_de_is_file(dir) \
- (((dir)->type) ? ((dir)->type == DT_REG) : (S_ISREG((dir)->info.st_mode)))
-#define ngx_de_is_link(dir) \
- (((dir)->type) ? ((dir)->type == DT_LNK) : (S_ISLNK((dir)->info.st_mode)))
-
-#else
-
-#define ngx_de_is_dir(dir) (S_ISDIR((dir)->info.st_mode))
-#define ngx_de_is_file(dir) (S_ISREG((dir)->info.st_mode))
-#define ngx_de_is_link(dir) (S_ISLNK((dir)->info.st_mode))
-
-#endif
-
-#define ngx_de_access(dir) (((dir)->info.st_mode) & 0777)
-#define ngx_de_size(dir) (dir)->info.st_size
-#define ngx_de_fs_size(dir) \
- ngx_max((dir)->info.st_size, (dir)->info.st_blocks * 512)
-#define ngx_de_mtime(dir) (dir)->info.st_mtime
-
-
-ngx_int_t ngx_open_glob(ngx_glob_t *gl);
-#define ngx_open_glob_n "glob()"
-ngx_int_t ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name);
-void ngx_close_glob(ngx_glob_t *gl);
-
-
-ngx_err_t ngx_trylock_fd(ngx_fd_t fd);
-ngx_err_t ngx_lock_fd(ngx_fd_t fd);
-ngx_err_t ngx_unlock_fd(ngx_fd_t fd);
-
-#define ngx_trylock_fd_n "fcntl(F_SETLK, F_WRLCK)"
-#define ngx_lock_fd_n "fcntl(F_SETLKW, F_WRLCK)"
-#define ngx_unlock_fd_n "fcntl(F_SETLK, F_UNLCK)"
-
-
-#if (NGX_HAVE_F_READAHEAD)
-
-#define NGX_HAVE_READ_AHEAD 1
-
-#define ngx_read_ahead(fd, n) fcntl(fd, F_READAHEAD, (int) n)
-#define ngx_read_ahead_n "fcntl(fd, F_READAHEAD)"
-
-#elif (NGX_HAVE_POSIX_FADVISE)
-
-#define NGX_HAVE_READ_AHEAD 1
-
-ngx_int_t ngx_read_ahead(ngx_fd_t fd, size_t n);
-#define ngx_read_ahead_n "posix_fadvise(POSIX_FADV_SEQUENTIAL)"
-
-#else
-
-#define ngx_read_ahead(fd, n) 0
-#define ngx_read_ahead_n "ngx_read_ahead_n"
-
-#endif
-
-
-#if (NGX_HAVE_O_DIRECT)
-
-ngx_int_t ngx_directio_on(ngx_fd_t fd);
-#define ngx_directio_on_n "fcntl(O_DIRECT)"
-
-ngx_int_t ngx_directio_off(ngx_fd_t fd);
-#define ngx_directio_off_n "fcntl(!O_DIRECT)"
-
-#elif (NGX_HAVE_F_NOCACHE)
-
-#define ngx_directio_on(fd) fcntl(fd, F_NOCACHE, 1)
-#define ngx_directio_on_n "fcntl(F_NOCACHE, 1)"
-
-#elif (NGX_HAVE_DIRECTIO)
-
-#define ngx_directio_on(fd) directio(fd, DIRECTIO_ON)
-#define ngx_directio_on_n "directio(DIRECTIO_ON)"
-
-#else
-
-#define ngx_directio_on(fd) 0
-#define ngx_directio_on_n "ngx_directio_on_n"
-
-#endif
-
-size_t ngx_fs_bsize(u_char *name);
-
-
-#if (NGX_HAVE_OPENAT)
-
-#define ngx_openat_file(fd, name, mode, create, access) \
- openat(fd, (const char *) name, mode|create, access)
-
-#define ngx_openat_file_n "openat()"
-
-#define ngx_file_at_info(fd, name, sb, flag) \
- fstatat(fd, (const char *) name, sb, flag)
-
-#define ngx_file_at_info_n "fstatat()"
-
-#define NGX_AT_FDCWD (ngx_fd_t) AT_FDCWD
-
-#endif
-
-
-#define ngx_stderr STDERR_FILENO
-#define ngx_set_stderr(fd) dup2(fd, STDERR_FILENO)
-#define ngx_set_stderr_n "dup2(STDERR_FILENO)"
-
-
-#if (NGX_HAVE_FILE_AIO)
-
-ssize_t ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size,
- off_t offset, ngx_pool_t *pool);
-
-extern ngx_uint_t ngx_file_aio;
-
-#endif
-
-
-#endif /* _NGX_FILES_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_freebsd.h b/usr.sbin/nginx/src/os/unix/ngx_freebsd.h
deleted file mode 100644
index 4f93da55cd2..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_freebsd.h
+++ /dev/null
@@ -1,25 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_FREEBSD_H_INCLUDED_
-#define _NGX_FREEBSD_H_INCLUDED_
-
-
-void ngx_debug_init(void);
-ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
-
-extern int ngx_freebsd_kern_osreldate;
-extern int ngx_freebsd_hw_ncpu;
-extern u_long ngx_freebsd_net_inet_tcp_sendspace;
-
-extern ngx_uint_t ngx_freebsd_sendfile_nbytes_bug;
-extern ngx_uint_t ngx_freebsd_use_tcp_nopush;
-extern ngx_uint_t ngx_debug_malloc;
-
-
-#endif /* _NGX_FREEBSD_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_freebsd_config.h b/usr.sbin/nginx/src/os/unix/ngx_freebsd_config.h
deleted file mode 100644
index 92b2928c8b5..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_freebsd_config.h
+++ /dev/null
@@ -1,127 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_FREEBSD_CONFIG_H_INCLUDED_
-#define _NGX_FREEBSD_CONFIG_H_INCLUDED_
-
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <stddef.h> /* offsetof() */
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include <pwd.h>
-#include <grp.h>
-#include <dirent.h>
-#include <glob.h>
-#include <time.h>
-#include <sys/param.h> /* ALIGN() */
-#include <sys/mount.h> /* statfs() */
-
-#include <sys/filio.h> /* FIONBIO */
-#include <sys/uio.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <sched.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h> /* TCP_NODELAY, TCP_NOPUSH */
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/un.h>
-
-#include <libutil.h> /* setproctitle() before 4.1 */
-#include <osreldate.h>
-#include <sys/sysctl.h>
-
-
-#if __FreeBSD_version < 400017
-
-/*
- * FreeBSD 3.x has no CMSG_SPACE() and CMSG_LEN() and has the broken CMSG_DATA()
- */
-
-#undef CMSG_SPACE
-#define CMSG_SPACE(l) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(l))
-
-#undef CMSG_LEN
-#define CMSG_LEN(l) (ALIGN(sizeof(struct cmsghdr)) + (l))
-
-#undef CMSG_DATA
-#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + ALIGN(sizeof(struct cmsghdr)))
-
-#endif
-
-
-#include <ngx_auto_config.h>
-
-
-#if (NGX_HAVE_POSIX_SEM)
-#include <semaphore.h>
-#endif
-
-
-#if (NGX_HAVE_POLL)
-#include <poll.h>
-#endif
-
-
-#if (NGX_HAVE_KQUEUE)
-#include <sys/event.h>
-#endif
-
-
-#if (NGX_HAVE_FILE_AIO || NGX_HAVE_AIO)
-#include <aio.h>
-typedef struct aiocb ngx_aiocb_t;
-#endif
-
-
-#define NGX_LISTEN_BACKLOG -1
-
-
-#ifdef __DragonFly__
-#define NGX_KEEPALIVE_FACTOR 1000
-#endif
-
-
-#if (__FreeBSD_version < 430000 || __FreeBSD_version < 500012)
-
-pid_t rfork_thread(int flags, void *stack, int (*func)(void *arg), void *arg);
-
-#endif
-
-#ifndef IOV_MAX
-#define IOV_MAX 1024
-#endif
-
-
-#ifndef NGX_HAVE_INHERITED_NONBLOCK
-#define NGX_HAVE_INHERITED_NONBLOCK 1
-#endif
-
-
-#define NGX_HAVE_OS_SPECIFIC_INIT 1
-#define NGX_HAVE_DEBUG_MALLOC 1
-
-
-extern char **environ;
-extern char *malloc_options;
-
-
-#endif /* _NGX_FREEBSD_CONFIG_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_freebsd_init.c b/usr.sbin/nginx/src/os/unix/ngx_freebsd_init.c
deleted file mode 100644
index c4c12dd741c..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_freebsd_init.c
+++ /dev/null
@@ -1,260 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/* FreeBSD 3.0 at least */
-char ngx_freebsd_kern_ostype[16];
-char ngx_freebsd_kern_osrelease[128];
-int ngx_freebsd_kern_osreldate;
-int ngx_freebsd_hw_ncpu;
-int ngx_freebsd_kern_ipc_somaxconn;
-u_long ngx_freebsd_net_inet_tcp_sendspace;
-
-/* FreeBSD 4.9 */
-int ngx_freebsd_machdep_hlt_logical_cpus;
-
-
-ngx_uint_t ngx_freebsd_sendfile_nbytes_bug;
-ngx_uint_t ngx_freebsd_use_tcp_nopush;
-
-ngx_uint_t ngx_debug_malloc;
-
-
-static ngx_os_io_t ngx_freebsd_io = {
- ngx_unix_recv,
- ngx_readv_chain,
- ngx_udp_unix_recv,
- ngx_unix_send,
-#if (NGX_HAVE_SENDFILE)
- ngx_freebsd_sendfile_chain,
- NGX_IO_SENDFILE
-#else
- ngx_writev_chain,
- 0
-#endif
-};
-
-
-typedef struct {
- char *name;
- void *value;
- size_t size;
- ngx_uint_t exists;
-} sysctl_t;
-
-
-sysctl_t sysctls[] = {
- { "hw.ncpu",
- &ngx_freebsd_hw_ncpu,
- sizeof(ngx_freebsd_hw_ncpu), 0 },
-
- { "machdep.hlt_logical_cpus",
- &ngx_freebsd_machdep_hlt_logical_cpus,
- sizeof(ngx_freebsd_machdep_hlt_logical_cpus), 0 },
-
- { "net.inet.tcp.sendspace",
- &ngx_freebsd_net_inet_tcp_sendspace,
- sizeof(ngx_freebsd_net_inet_tcp_sendspace), 0 },
-
- { "kern.ipc.somaxconn",
- &ngx_freebsd_kern_ipc_somaxconn,
- sizeof(ngx_freebsd_kern_ipc_somaxconn), 0 },
-
- { NULL, NULL, 0, 0 }
-};
-
-
-void
-ngx_debug_init(void)
-{
-#if (NGX_DEBUG_MALLOC)
-
-#if __FreeBSD_version >= 500014 && __FreeBSD_version < 1000011
- _malloc_options = "J";
-#elif __FreeBSD_version < 500014
- malloc_options = "J";
-#endif
-
- ngx_debug_malloc = 1;
-
-#else
- char *mo;
-
- mo = getenv("MALLOC_OPTIONS");
-
- if (mo && ngx_strchr(mo, 'J')) {
- ngx_debug_malloc = 1;
- }
-#endif
-}
-
-
-ngx_int_t
-ngx_os_specific_init(ngx_log_t *log)
-{
- int version;
- size_t size;
- ngx_err_t err;
- ngx_uint_t i;
-
- size = sizeof(ngx_freebsd_kern_ostype);
- if (sysctlbyname("kern.ostype",
- ngx_freebsd_kern_ostype, &size, NULL, 0) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "sysctlbyname(kern.ostype) failed");
-
- if (ngx_errno != NGX_ENOMEM) {
- return NGX_ERROR;
- }
-
- ngx_freebsd_kern_ostype[size - 1] = '\0';
- }
-
- size = sizeof(ngx_freebsd_kern_osrelease);
- if (sysctlbyname("kern.osrelease",
- ngx_freebsd_kern_osrelease, &size, NULL, 0) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "sysctlbyname(kern.osrelease) failed");
-
- if (ngx_errno != NGX_ENOMEM) {
- return NGX_ERROR;
- }
-
- ngx_freebsd_kern_osrelease[size - 1] = '\0';
- }
-
-
- size = sizeof(int);
- if (sysctlbyname("kern.osreldate",
- &ngx_freebsd_kern_osreldate, &size, NULL, 0) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "sysctlbyname(kern.osreldate) failed");
- return NGX_ERROR;
- }
-
- version = ngx_freebsd_kern_osreldate;
-
-
-#if (NGX_HAVE_SENDFILE)
-
- /*
- * The determination of the sendfile() "nbytes bug" is complex enough.
- * There are two sendfile() syscalls: a new #393 has no bug while
- * an old #336 has the bug in some versions and has not in others.
- * Besides libc_r wrapper also emulates the bug in some versions.
- * There is no way to say exactly if syscall #336 in FreeBSD circa 4.6
- * has the bug. We use the algorithm that is correct at least for
- * RELEASEs and for syscalls only (not libc_r wrapper).
- *
- * 4.6.1-RELEASE and below have the bug
- * 4.6.2-RELEASE and above have the new syscall
- *
- * We detect the new sendfile() syscall available at the compile time
- * to allow an old binary to run correctly on an updated FreeBSD system.
- */
-
-#if (__FreeBSD__ == 4 && __FreeBSD_version >= 460102) \
- || __FreeBSD_version == 460002 || __FreeBSD_version >= 500039
-
- /* a new syscall without the bug */
-
- ngx_freebsd_sendfile_nbytes_bug = 0;
-
-#else
-
- /* an old syscall that may have the bug */
-
- ngx_freebsd_sendfile_nbytes_bug = 1;
-
-#endif
-
-#endif /* NGX_HAVE_SENDFILE */
-
-
- if ((version < 500000 && version >= 440003) || version >= 500017) {
- ngx_freebsd_use_tcp_nopush = 1;
- }
-
-
- for (i = 0; sysctls[i].name; i++) {
- size = sysctls[i].size;
-
- if (sysctlbyname(sysctls[i].name, sysctls[i].value, &size, NULL, 0)
- == 0)
- {
- sysctls[i].exists = 1;
- continue;
- }
-
- err = ngx_errno;
-
- if (err == NGX_ENOENT) {
- continue;
- }
-
- ngx_log_error(NGX_LOG_ALERT, log, err,
- "sysctlbyname(%s) failed", sysctls[i].name);
- return NGX_ERROR;
- }
-
- if (ngx_freebsd_machdep_hlt_logical_cpus) {
- ngx_ncpu = ngx_freebsd_hw_ncpu / 2;
-
- } else {
- ngx_ncpu = ngx_freebsd_hw_ncpu;
- }
-
- if (version < 600008 && ngx_freebsd_kern_ipc_somaxconn > 32767) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- "sysctl kern.ipc.somaxconn must be less than 32768");
- return NGX_ERROR;
- }
-
- ngx_tcp_nodelay_and_tcp_nopush = 1;
-
- ngx_os_io = ngx_freebsd_io;
-
- return NGX_OK;
-}
-
-
-void
-ngx_os_specific_status(ngx_log_t *log)
-{
- u_long value;
- ngx_uint_t i;
-
- ngx_log_error(NGX_LOG_NOTICE, log, 0, "OS: %s %s",
- ngx_freebsd_kern_ostype, ngx_freebsd_kern_osrelease);
-
-#ifdef __DragonFly_version
- ngx_log_error(NGX_LOG_NOTICE, log, 0,
- "kern.osreldate: %d, built on %d",
- ngx_freebsd_kern_osreldate, __DragonFly_version);
-#else
- ngx_log_error(NGX_LOG_NOTICE, log, 0,
- "kern.osreldate: %d, built on %d",
- ngx_freebsd_kern_osreldate, __FreeBSD_version);
-#endif
-
- for (i = 0; sysctls[i].name; i++) {
- if (sysctls[i].exists) {
- if (sysctls[i].size == sizeof(long)) {
- value = *(long *) sysctls[i].value;
-
- } else {
- value = *(int *) sysctls[i].value;
- }
-
- ngx_log_error(NGX_LOG_NOTICE, log, 0, "%s: %l",
- sysctls[i].name, value);
- }
- }
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_freebsd_rfork_thread.c b/usr.sbin/nginx/src/os/unix/ngx_freebsd_rfork_thread.c
deleted file mode 100644
index e92f9a9fdd7..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_freebsd_rfork_thread.c
+++ /dev/null
@@ -1,756 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-/*
- * The threads implementation uses the rfork(RFPROC|RFTHREAD|RFMEM) syscall
- * to create threads. All threads use the stacks of the same size mmap()ed
- * below the main stack. Thus the current thread id is determined via
- * the stack pointer value.
- *
- * The mutex implementation uses the ngx_atomic_cmp_set() operation
- * to acquire a mutex and the SysV semaphore to wait on a mutex and to wake up
- * the waiting threads. The light mutex does not use semaphore, so after
- * spinning in the lock the thread calls sched_yield(). However the light
- * mutexes are intended to be used with the "trylock" operation only.
- * The SysV semop() is a cheap syscall, particularly if it has little sembuf's
- * and does not use SEM_UNDO.
- *
- * The condition variable implementation uses the signal #64.
- * The signal handler is SIG_IGN so the kill() is a cheap syscall.
- * The thread waits a signal in kevent(). The use of the EVFILT_SIGNAL
- * is safe since FreeBSD 4.10-STABLE.
- *
- * This threads implementation currently works on i386 (486+) and amd64
- * platforms only.
- */
-
-
-char *ngx_freebsd_kern_usrstack;
-size_t ngx_thread_stack_size;
-
-
-static size_t rz_size;
-static size_t usable_stack_size;
-static char *last_stack;
-
-static ngx_uint_t nthreads;
-static ngx_uint_t max_threads;
-
-static ngx_uint_t nkeys;
-static ngx_tid_t *tids; /* the threads tids array */
-void **ngx_tls; /* the threads tls's array */
-
-/* the thread-safe libc errno */
-
-static int errno0; /* the main thread's errno */
-static int *errnos; /* the threads errno's array */
-
-int *
-__error()
-{
- int tid;
-
- tid = ngx_gettid();
-
- return tid ? &errnos[tid - 1] : &errno0;
-}
-
-
-/*
- * __isthreaded enables the spinlocks in some libc functions, i.e. in malloc()
- * and some other places. Nevertheless we protect our malloc()/free() calls
- * by own mutex that is more efficient than the spinlock.
- *
- * _spinlock() is a weak referenced stub in src/lib/libc/gen/_spinlock_stub.c
- * that does nothing.
- */
-
-extern int __isthreaded;
-
-void
-_spinlock(ngx_atomic_t *lock)
-{
- ngx_int_t tries;
-
- tries = 0;
-
- for ( ;; ) {
-
- if (*lock) {
- if (ngx_ncpu > 1 && tries++ < 1000) {
- continue;
- }
-
- sched_yield();
- tries = 0;
-
- } else {
- if (ngx_atomic_cmp_set(lock, 0, 1)) {
- return;
- }
- }
- }
-}
-
-
-/*
- * Before FreeBSD 5.1 _spinunlock() is a simple #define in
- * src/lib/libc/include/spinlock.h that zeroes lock.
- *
- * Since FreeBSD 5.1 _spinunlock() is a weak referenced stub in
- * src/lib/libc/gen/_spinlock_stub.c that does nothing.
- */
-
-#ifndef _spinunlock
-
-void
-_spinunlock(ngx_atomic_t *lock)
-{
- *lock = 0;
-}
-
-#endif
-
-
-ngx_err_t
-ngx_create_thread(ngx_tid_t *tid, ngx_thread_value_t (*func)(void *arg),
- void *arg, ngx_log_t *log)
-{
- ngx_pid_t id;
- ngx_err_t err;
- char *stack, *stack_top;
-
- if (nthreads >= max_threads) {
- ngx_log_error(NGX_LOG_CRIT, log, 0,
- "no more than %ui threads can be created", max_threads);
- return NGX_ERROR;
- }
-
- last_stack -= ngx_thread_stack_size;
-
- stack = mmap(last_stack, usable_stack_size, PROT_READ|PROT_WRITE,
- MAP_STACK, -1, 0);
-
- if (stack == MAP_FAILED) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "mmap(%p:%uz, MAP_STACK) thread stack failed",
- last_stack, usable_stack_size);
- return NGX_ERROR;
- }
-
- if (stack != last_stack) {
- ngx_log_error(NGX_LOG_ALERT, log, 0,
- "stack %p address was changed to %p", last_stack, stack);
- return NGX_ERROR;
- }
-
- stack_top = stack + usable_stack_size;
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, log, 0,
- "thread stack: %p-%p", stack, stack_top);
-
- ngx_set_errno(0);
-
- id = rfork_thread(RFPROC|RFTHREAD|RFMEM, stack_top,
- (ngx_rfork_thread_func_pt) func, arg);
-
- err = ngx_errno;
-
- if (id == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, err, "rfork() failed");
-
- } else {
- *tid = id;
- nthreads = (ngx_freebsd_kern_usrstack - stack_top)
- / ngx_thread_stack_size;
- tids[nthreads] = id;
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "rfork()ed thread: %P", id);
- }
-
- return err;
-}
-
-
-ngx_int_t
-ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle)
-{
- char *red_zone, *zone;
- size_t len;
- ngx_int_t i;
- struct sigaction sa;
-
- max_threads = n + 1;
-
- for (i = 0; i < n; i++) {
- ngx_memzero(&sa, sizeof(struct sigaction));
- sa.sa_handler = SIG_IGN;
- sigemptyset(&sa.sa_mask);
- if (sigaction(NGX_CV_SIGNAL, &sa, NULL) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "sigaction(%d, SIG_IGN) failed", NGX_CV_SIGNAL);
- return NGX_ERROR;
- }
- }
-
- len = sizeof(ngx_freebsd_kern_usrstack);
- if (sysctlbyname("kern.usrstack", &ngx_freebsd_kern_usrstack, &len,
- NULL, 0) == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "sysctlbyname(kern.usrstack) failed");
- return NGX_ERROR;
- }
-
- /* the main thread stack red zone */
- rz_size = ngx_pagesize;
- red_zone = ngx_freebsd_kern_usrstack - (size + rz_size);
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
- "usrstack: %p red zone: %p",
- ngx_freebsd_kern_usrstack, red_zone);
-
- zone = mmap(red_zone, rz_size, PROT_NONE, MAP_ANON, -1, 0);
- if (zone == MAP_FAILED) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "mmap(%p:%uz, PROT_NONE, MAP_ANON) red zone failed",
- red_zone, rz_size);
- return NGX_ERROR;
- }
-
- if (zone != red_zone) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "red zone %p address was changed to %p", red_zone, zone);
- return NGX_ERROR;
- }
-
- /* create the thread errno' array */
-
- errnos = ngx_calloc(n * sizeof(int), cycle->log);
- if (errnos == NULL) {
- return NGX_ERROR;
- }
-
- /* create the thread tids array */
-
- tids = ngx_calloc((n + 1) * sizeof(ngx_tid_t), cycle->log);
- if (tids == NULL) {
- return NGX_ERROR;
- }
-
- tids[0] = ngx_pid;
-
- /* create the thread tls' array */
-
- ngx_tls = ngx_calloc(NGX_THREAD_KEYS_MAX * (n + 1) * sizeof(void *),
- cycle->log);
- if (ngx_tls == NULL) {
- return NGX_ERROR;
- }
-
- nthreads = 1;
-
- last_stack = zone + rz_size;
- usable_stack_size = size;
- ngx_thread_stack_size = size + rz_size;
-
- /* allow the spinlock in libc malloc() */
- __isthreaded = 1;
-
- ngx_threaded = 1;
-
- return NGX_OK;
-}
-
-
-ngx_tid_t
-ngx_thread_self(void)
-{
- ngx_int_t tid;
-
- tid = ngx_gettid();
-
- if (tids == NULL) {
- return ngx_pid;
- }
-
- return tids[tid];
-}
-
-
-ngx_err_t
-ngx_thread_key_create(ngx_tls_key_t *key)
-{
- if (nkeys >= NGX_THREAD_KEYS_MAX) {
- return NGX_ENOMEM;
- }
-
- *key = nkeys++;
-
- return 0;
-}
-
-
-ngx_err_t
-ngx_thread_set_tls(ngx_tls_key_t key, void *value)
-{
- if (key >= NGX_THREAD_KEYS_MAX) {
- return NGX_EINVAL;
- }
-
- ngx_tls[key * NGX_THREAD_KEYS_MAX + ngx_gettid()] = value;
- return 0;
-}
-
-
-ngx_mutex_t *
-ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags)
-{
- ngx_mutex_t *m;
- union semun op;
-
- m = ngx_alloc(sizeof(ngx_mutex_t), log);
- if (m == NULL) {
- return NULL;
- }
-
- m->lock = 0;
- m->log = log;
-
- if (flags & NGX_MUTEX_LIGHT) {
- m->semid = -1;
- return m;
- }
-
- m->semid = semget(IPC_PRIVATE, 1, SEM_R|SEM_A);
- if (m->semid == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "semget() failed");
- return NULL;
- }
-
- op.val = 0;
-
- if (semctl(m->semid, 0, SETVAL, op) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "semctl(SETVAL) failed");
-
- if (semctl(m->semid, 0, IPC_RMID) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "semctl(IPC_RMID) failed");
- }
-
- return NULL;
- }
-
- return m;
-}
-
-
-void
-ngx_mutex_destroy(ngx_mutex_t *m)
-{
- if (semctl(m->semid, 0, IPC_RMID) == -1) {
- ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
- "semctl(IPC_RMID) failed");
- }
-
- ngx_free((void *) m);
-}
-
-
-ngx_int_t
-ngx_mutex_dolock(ngx_mutex_t *m, ngx_int_t try)
-{
- uint32_t lock, old;
- ngx_uint_t tries;
- struct sembuf op;
-
- if (!ngx_threaded) {
- return NGX_OK;
- }
-
-#if (NGX_DEBUG)
- if (try) {
- ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
- "try lock mutex %p lock:%XD", m, m->lock);
- } else {
- ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
- "lock mutex %p lock:%XD", m, m->lock);
- }
-#endif
-
- old = m->lock;
- tries = 0;
-
- for ( ;; ) {
- if (old & NGX_MUTEX_LOCK_BUSY) {
-
- if (try) {
- return NGX_AGAIN;
- }
-
- if (ngx_ncpu > 1 && tries++ < 1000) {
-
- /* the spinlock is used only on the SMP system */
-
- old = m->lock;
- continue;
- }
-
- if (m->semid == -1) {
- sched_yield();
-
- tries = 0;
- old = m->lock;
- continue;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
- "mutex %p lock:%XD", m, m->lock);
-
- /*
- * The mutex is locked so we increase a number
- * of the threads that are waiting on the mutex
- */
-
- lock = old + 1;
-
- if ((lock & ~NGX_MUTEX_LOCK_BUSY) > nthreads) {
- ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
- "%D threads wait for mutex %p, "
- "while only %ui threads are available",
- lock & ~NGX_MUTEX_LOCK_BUSY, m, nthreads);
- ngx_abort();
- }
-
- if (ngx_atomic_cmp_set(&m->lock, old, lock)) {
-
- ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
- "wait mutex %p lock:%XD", m, m->lock);
-
- /*
- * The number of the waiting threads has been increased
- * and we would wait on the SysV semaphore.
- * A semaphore should wake up us more efficiently than
- * a simple sched_yield() or usleep().
- */
-
- op.sem_num = 0;
- op.sem_op = -1;
- op.sem_flg = 0;
-
- if (semop(m->semid, &op, 1) == -1) {
- ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
- "semop() failed while waiting on mutex %p", m);
- ngx_abort();
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
- "mutex waked up %p lock:%XD", m, m->lock);
-
- tries = 0;
- old = m->lock;
- continue;
- }
-
- old = m->lock;
-
- } else {
- lock = old | NGX_MUTEX_LOCK_BUSY;
-
- if (ngx_atomic_cmp_set(&m->lock, old, lock)) {
-
- /* we locked the mutex */
-
- break;
- }
-
- old = m->lock;
- }
-
- if (tries++ > 1000) {
-
- ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0,
- "mutex %p is contested", m);
-
- /* the mutex is probably contested so we are giving up now */
-
- sched_yield();
-
- tries = 0;
- old = m->lock;
- }
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
- "mutex %p is locked, lock:%XD", m, m->lock);
-
- return NGX_OK;
-}
-
-
-void
-ngx_mutex_unlock(ngx_mutex_t *m)
-{
- uint32_t lock, old;
- struct sembuf op;
-
- if (!ngx_threaded) {
- return;
- }
-
- old = m->lock;
-
- if (!(old & NGX_MUTEX_LOCK_BUSY)) {
- ngx_log_error(NGX_LOG_ALERT, m->log, 0,
- "trying to unlock the free mutex %p", m);
- ngx_abort();
- }
-
- /* free the mutex */
-
-#if 0
- ngx_log_debug2(NGX_LOG_DEBUG_MUTEX, m->log, 0,
- "unlock mutex %p lock:%XD", m, old);
-#endif
-
- for ( ;; ) {
- lock = old & ~NGX_MUTEX_LOCK_BUSY;
-
- if (ngx_atomic_cmp_set(&m->lock, old, lock)) {
- break;
- }
-
- old = m->lock;
- }
-
- if (m->semid == -1) {
- ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0,
- "mutex %p is unlocked", m);
-
- return;
- }
-
- /* check whether we need to wake up a waiting thread */
-
- old = m->lock;
-
- for ( ;; ) {
- if (old & NGX_MUTEX_LOCK_BUSY) {
-
- /* the mutex is just locked by another thread */
-
- break;
- }
-
- if (old == 0) {
- break;
- }
-
- /* there are the waiting threads */
-
- lock = old - 1;
-
- if (ngx_atomic_cmp_set(&m->lock, old, lock)) {
-
- /* wake up the thread that waits on semaphore */
-
- ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0,
- "wake up mutex %p", m);
-
- op.sem_num = 0;
- op.sem_op = 1;
- op.sem_flg = 0;
-
- if (semop(m->semid, &op, 1) == -1) {
- ngx_log_error(NGX_LOG_ALERT, m->log, ngx_errno,
- "semop() failed while waking up on mutex %p", m);
- ngx_abort();
- }
-
- break;
- }
-
- old = m->lock;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0,
- "mutex %p is unlocked", m);
-
- return;
-}
-
-
-ngx_cond_t *
-ngx_cond_init(ngx_log_t *log)
-{
- ngx_cond_t *cv;
-
- cv = ngx_alloc(sizeof(ngx_cond_t), log);
- if (cv == NULL) {
- return NULL;
- }
-
- cv->signo = NGX_CV_SIGNAL;
- cv->tid = -1;
- cv->log = log;
- cv->kq = -1;
-
- return cv;
-}
-
-
-void
-ngx_cond_destroy(ngx_cond_t *cv)
-{
- if (close(cv->kq) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cv->log, ngx_errno,
- "kqueue close() failed");
- }
-
- ngx_free(cv);
-}
-
-
-ngx_int_t
-ngx_cond_wait(ngx_cond_t *cv, ngx_mutex_t *m)
-{
- int n;
- ngx_err_t err;
- struct kevent kev;
- struct timespec ts;
-
- if (cv->kq == -1) {
-
- /*
- * We have to add the EVFILT_SIGNAL filter in the rfork()ed thread.
- * Otherwise the thread would not get a signal event.
- *
- * However, we have not to open the kqueue in the thread,
- * it is simply handy do it together.
- */
-
- cv->kq = kqueue();
- if (cv->kq == -1) {
- ngx_log_error(NGX_LOG_ALERT, cv->log, ngx_errno, "kqueue() failed");
- return NGX_ERROR;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, cv->log, 0,
- "cv kq:%d signo:%d", cv->kq, cv->signo);
-
- kev.ident = cv->signo;
- kev.filter = EVFILT_SIGNAL;
- kev.flags = EV_ADD;
- kev.fflags = 0;
- kev.data = 0;
- kev.udata = NULL;
-
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
-
- if (kevent(cv->kq, &kev, 1, NULL, 0, &ts) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cv->log, ngx_errno, "kevent() failed");
- return NGX_ERROR;
- }
-
- cv->tid = ngx_thread_self();
- }
-
- ngx_mutex_unlock(m);
-
- ngx_log_debug3(NGX_LOG_DEBUG_CORE, cv->log, 0,
- "cv %p wait, kq:%d, signo:%d", cv, cv->kq, cv->signo);
-
- for ( ;; ) {
- n = kevent(cv->kq, NULL, 0, &kev, 1, NULL);
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, cv->log, 0,
- "cv %p kevent: %d", cv, n);
-
- if (n == -1) {
- err = ngx_errno;
- ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
- cv->log, ngx_errno,
- "kevent() failed while waiting condition variable %p",
- cv);
-
- if (err == NGX_EINTR) {
- break;
- }
-
- return NGX_ERROR;
- }
-
- if (n == 0) {
- ngx_log_error(NGX_LOG_ALERT, cv->log, 0,
- "kevent() returned no events "
- "while waiting condition variable %p",
- cv);
- continue;
- }
-
- if (kev.filter != EVFILT_SIGNAL) {
- ngx_log_error(NGX_LOG_ALERT, cv->log, 0,
- "kevent() returned unexpected events: %d "
- "while waiting condition variable %p",
- kev.filter, cv);
- continue;
- }
-
- if (kev.ident != (uintptr_t) cv->signo) {
- ngx_log_error(NGX_LOG_ALERT, cv->log, 0,
- "kevent() returned unexpected signal: %d ",
- "while waiting condition variable %p",
- kev.ident, cv);
- continue;
- }
-
- break;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p is waked up", cv);
-
- ngx_mutex_lock(m);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_cond_signal(ngx_cond_t *cv)
-{
- ngx_err_t err;
-
- ngx_log_debug3(NGX_LOG_DEBUG_CORE, cv->log, 0,
- "cv %p to signal %P %d",
- cv, cv->tid, cv->signo);
-
- if (cv->tid == -1) {
- return NGX_OK;
- }
-
- if (kill(cv->tid, cv->signo) == -1) {
-
- err = ngx_errno;
-
- ngx_log_error(NGX_LOG_ALERT, cv->log, err,
- "kill() failed while signaling condition variable %p", cv);
-
- if (err == NGX_ESRCH) {
- cv->tid = -1;
- }
-
- return NGX_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p is signaled", cv);
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_freebsd_rfork_thread.h b/usr.sbin/nginx/src/os/unix/ngx_freebsd_rfork_thread.h
deleted file mode 100644
index ff160449dad..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_freebsd_rfork_thread.h
+++ /dev/null
@@ -1,122 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_FREEBSD_RFORK_THREAD_H_INCLUDED_
-#define _NGX_FREEBSD_RFORK_THREAD_H_INCLUDED_
-
-
-#include <sys/ipc.h>
-#include <sys/sem.h>
-#include <sched.h>
-
-typedef pid_t ngx_tid_t;
-
-#define ngx_log_pid ngx_thread_self()
-#define ngx_log_tid 0
-
-#define NGX_TID_T_FMT "%P"
-
-
-#define NGX_MUTEX_LIGHT 1
-
-#define NGX_MUTEX_LOCK_BUSY 0x80000000
-
-typedef volatile struct {
- ngx_atomic_t lock;
- ngx_log_t *log;
- int semid;
-} ngx_mutex_t;
-
-
-#define NGX_CV_SIGNAL 64
-
-typedef struct {
- int signo;
- int kq;
- ngx_tid_t tid;
- ngx_log_t *log;
-} ngx_cond_t;
-
-
-#define ngx_thread_sigmask(how, set, oset) \
- (sigprocmask(how, set, oset) == -1) ? ngx_errno : 0
-
-#define ngx_thread_sigmask_n "sigprocmask()"
-
-#define ngx_thread_join(t, p)
-
-#define ngx_setthrtitle(n) setproctitle(n)
-
-
-extern char *ngx_freebsd_kern_usrstack;
-extern size_t ngx_thread_stack_size;
-
-
-static ngx_inline ngx_int_t
-ngx_gettid(void)
-{
- char *sp;
-
- if (ngx_thread_stack_size == 0) {
- return 0;
- }
-
-#if ( __i386__ )
-
- __asm__ volatile ("mov %%esp, %0" : "=q" (sp));
-
-#elif ( __amd64__ )
-
- __asm__ volatile ("mov %%rsp, %0" : "=q" (sp));
-
-#else
-
-#error "rfork()ed threads are not supported on this platform"
-
-#endif
-
- return (ngx_freebsd_kern_usrstack - sp) / ngx_thread_stack_size;
-}
-
-
-ngx_tid_t ngx_thread_self(void);
-
-
-typedef ngx_uint_t ngx_tls_key_t;
-
-#define NGX_THREAD_KEYS_MAX 16
-
-extern void **ngx_tls;
-
-ngx_err_t ngx_thread_key_create(ngx_tls_key_t *key);
-#define ngx_thread_key_create_n "the tls key creation"
-
-ngx_err_t ngx_thread_set_tls(ngx_tls_key_t key, void *value);
-#define ngx_thread_set_tls_n "the tls key setting"
-
-
-static void *
-ngx_thread_get_tls(ngx_tls_key_t key)
-{
- if (key >= NGX_THREAD_KEYS_MAX) {
- return NULL;
- }
-
- return ngx_tls[key * NGX_THREAD_KEYS_MAX + ngx_gettid()];
-}
-
-
-#define ngx_mutex_trylock(m) ngx_mutex_dolock(m, 1)
-#define ngx_mutex_lock(m) (void) ngx_mutex_dolock(m, 0)
-ngx_int_t ngx_mutex_dolock(ngx_mutex_t *m, ngx_int_t try);
-void ngx_mutex_unlock(ngx_mutex_t *m);
-
-
-typedef int (*ngx_rfork_thread_func_pt)(void *arg);
-
-
-#endif /* _NGX_FREEBSD_RFORK_THREAD_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c b/usr.sbin/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c
deleted file mode 100644
index 11cec82269a..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ /dev/null
@@ -1,440 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-/*
- * Although FreeBSD sendfile() allows to pass a header and a trailer,
- * it cannot send a header with a part of the file in one packet until
- * FreeBSD 5.3. Besides, over the fast ethernet connection sendfile()
- * may send the partially filled packets, i.e. the 8 file pages may be sent
- * as the 11 full 1460-bytes packets, then one incomplete 324-bytes packet,
- * and then again the 11 full 1460-bytes packets.
- *
- * Therefore we use the TCP_NOPUSH option (similar to Linux's TCP_CORK)
- * to postpone the sending - it not only sends a header and the first part of
- * the file in one packet, but also sends the file pages in the full packets.
- *
- * But until FreeBSD 4.5 turning TCP_NOPUSH off does not flush a pending
- * data that less than MSS, so that data may be sent with 5 second delay.
- * So we do not use TCP_NOPUSH on FreeBSD prior to 4.5, although it can be used
- * for non-keepalive HTTP connections.
- */
-
-
-#if (IOV_MAX > 64)
-#define NGX_HEADERS 64
-#define NGX_TRAILERS 64
-#else
-#define NGX_HEADERS IOV_MAX
-#define NGX_TRAILERS IOV_MAX
-#endif
-
-
-ngx_chain_t *
-ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
-{
- int rc, flags;
- u_char *prev;
- off_t size, send, prev_send, aligned, sent, fprev;
- size_t header_size, file_size;
- ngx_uint_t eintr, eagain, complete;
- ngx_err_t err;
- ngx_buf_t *file;
- ngx_array_t header, trailer;
- ngx_event_t *wev;
- ngx_chain_t *cl;
- struct sf_hdtr hdtr;
- struct iovec *iov, headers[NGX_HEADERS], trailers[NGX_TRAILERS];
-
- wev = c->write;
-
- if (!wev->ready) {
- return in;
- }
-
-#if (NGX_HAVE_KQUEUE)
-
- if ((ngx_event_flags & NGX_USE_KQUEUE_EVENT) && wev->pending_eof) {
- (void) ngx_connection_error(c, wev->kq_errno,
- "kevent() reported about an closed connection");
- wev->error = 1;
- return NGX_CHAIN_ERROR;
- }
-
-#endif
-
- /* the maximum limit size is the maximum size_t value - the page size */
-
- if (limit == 0 || limit > (off_t) (NGX_MAX_SIZE_T_VALUE - ngx_pagesize)) {
- limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
- }
-
- send = 0;
- eagain = 0;
- flags = 0;
-
- header.elts = headers;
- header.size = sizeof(struct iovec);
- header.nalloc = NGX_HEADERS;
- header.pool = c->pool;
-
- trailer.elts = trailers;
- trailer.size = sizeof(struct iovec);
- trailer.nalloc = NGX_TRAILERS;
- trailer.pool = c->pool;
-
- for ( ;; ) {
- file = NULL;
- file_size = 0;
- header_size = 0;
- eintr = 0;
- complete = 0;
- prev_send = send;
-
- header.nelts = 0;
- trailer.nelts = 0;
-
- /* create the header iovec and coalesce the neighbouring bufs */
-
- prev = NULL;
- iov = NULL;
-
- for (cl = in; cl && send < limit; cl = cl->next) {
-
- if (ngx_buf_special(cl->buf)) {
- continue;
- }
-
- if (!ngx_buf_in_memory_only(cl->buf)) {
- break;
- }
-
- size = cl->buf->last - cl->buf->pos;
-
- if (send + size > limit) {
- size = limit - send;
- }
-
- if (prev == cl->buf->pos) {
- iov->iov_len += (size_t) size;
-
- } else {
- if (header.nelts >= IOV_MAX){
- break;
- }
-
- iov = ngx_array_push(&header);
- if (iov == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- iov->iov_base = (void *) cl->buf->pos;
- iov->iov_len = (size_t) size;
- }
-
- prev = cl->buf->pos + (size_t) size;
- header_size += (size_t) size;
- send += size;
- }
-
-
- if (cl && cl->buf->in_file && send < limit) {
- file = cl->buf;
-
- /* coalesce the neighbouring file bufs */
-
- do {
- size = cl->buf->file_last - cl->buf->file_pos;
-
- if (send + size > limit) {
- size = limit - send;
-
- aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
- & ~((off_t) ngx_pagesize - 1);
-
- if (aligned <= cl->buf->file_last) {
- size = aligned - cl->buf->file_pos;
- }
- }
-
- file_size += (size_t) size;
- send += size;
- fprev = cl->buf->file_pos + size;
- cl = cl->next;
-
- } while (cl
- && cl->buf->in_file
- && send < limit
- && file->file->fd == cl->buf->file->fd
- && fprev == cl->buf->file_pos);
- }
-
-
- if (file) {
-
- /* create the trailer iovec and coalesce the neighbouring bufs */
-
- prev = NULL;
- iov = NULL;
-
- while (cl && send < limit) {
-
- if (ngx_buf_special(cl->buf)) {
- cl = cl->next;
- continue;
- }
-
- if (!ngx_buf_in_memory_only(cl->buf)) {
- break;
- }
-
- size = cl->buf->last - cl->buf->pos;
-
- if (send + size > limit) {
- size = limit - send;
- }
-
- if (prev == cl->buf->pos) {
- iov->iov_len += (size_t) size;
-
- } else {
- if (trailer.nelts >= IOV_MAX){
- break;
- }
-
- iov = ngx_array_push(&trailer);
- if (iov == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- iov->iov_base = (void *) cl->buf->pos;
- iov->iov_len = (size_t) size;
- }
-
- prev = cl->buf->pos + (size_t) size;
- send += size;
- cl = cl->next;
- }
- }
-
- if (file) {
-
- if (ngx_freebsd_use_tcp_nopush
- && c->tcp_nopush == NGX_TCP_NOPUSH_UNSET)
- {
- if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
- err = ngx_socket_errno;
-
- /*
- * there is a tiny chance to be interrupted, however,
- * we continue a processing without the TCP_NOPUSH
- */
-
- if (err != NGX_EINTR) {
- wev->error = 1;
- (void) ngx_connection_error(c, err,
- ngx_tcp_nopush_n " failed");
- return NGX_CHAIN_ERROR;
- }
-
- } else {
- c->tcp_nopush = NGX_TCP_NOPUSH_SET;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "tcp_nopush");
- }
- }
-
- /*
- * sendfile() does unneeded work if sf_hdtr's count is 0,
- * but corresponding pointer is not NULL
- */
-
- hdtr.headers = header.nelts ? (struct iovec *) header.elts: NULL;
- hdtr.hdr_cnt = header.nelts;
- hdtr.trailers = trailer.nelts ? (struct iovec *) trailer.elts: NULL;
- hdtr.trl_cnt = trailer.nelts;
-
- /*
- * the "nbytes bug" of the old sendfile() syscall:
- * http://www.freebsd.org/cgi/query-pr.cgi?pr=33771
- */
-
- if (!ngx_freebsd_sendfile_nbytes_bug) {
- header_size = 0;
- }
-
- sent = 0;
-
-#if (NGX_HAVE_AIO_SENDFILE)
- flags = c->aio_sendfile ? SF_NODISKIO : 0;
-#endif
-
- rc = sendfile(file->file->fd, c->fd, file->file_pos,
- file_size + header_size, &hdtr, &sent, flags);
-
- if (rc == -1) {
- err = ngx_errno;
-
- switch (err) {
- case NGX_EAGAIN:
- eagain = 1;
- break;
-
- case NGX_EINTR:
- eintr = 1;
- break;
-
-#if (NGX_HAVE_AIO_SENDFILE)
- case NGX_EBUSY:
- c->busy_sendfile = file;
- break;
-#endif
-
- default:
- wev->error = 1;
- (void) ngx_connection_error(c, err, "sendfile() failed");
- return NGX_CHAIN_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
- "sendfile() sent only %O bytes", sent);
-
- /*
- * sendfile() in FreeBSD 3.x-4.x may return value >= 0
- * on success, although only 0 is documented
- */
-
- } else if (rc >= 0 && sent == 0) {
-
- /*
- * if rc is OK and sent equal to zero, then someone
- * has truncated the file, so the offset became beyond
- * the end of the file
- */
-
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "sendfile() reported that \"%s\" was truncated at %O",
- file->file->name.data, file->file_pos);
-
- return NGX_CHAIN_ERROR;
- }
-
- ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "sendfile: %d, @%O %O:%uz",
- rc, file->file_pos, sent, file_size + header_size);
-
- } else {
- rc = writev(c->fd, header.elts, header.nelts);
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "writev: %d of %uz", rc, header_size);
-
- if (rc == -1) {
- err = ngx_errno;
-
- switch (err) {
- case NGX_EAGAIN:
- break;
-
- case NGX_EINTR:
- eintr = 1;
- break;
-
- default:
- wev->error = 1;
- ngx_connection_error(c, err, "writev() failed");
- return NGX_CHAIN_ERROR;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "writev() not ready");
- }
-
- sent = rc > 0 ? rc : 0;
- }
-
- if (send - prev_send == sent) {
- complete = 1;
- }
-
- c->sent += sent;
-
- for ( /* void */ ; in; in = in->next) {
-
- if (ngx_buf_special(in->buf)) {
- continue;
- }
-
- if (sent == 0) {
- break;
- }
-
- size = ngx_buf_size(in->buf);
-
- if (sent >= size) {
- sent -= size;
-
- if (ngx_buf_in_memory(in->buf)) {
- in->buf->pos = in->buf->last;
- }
-
- if (in->buf->in_file) {
- in->buf->file_pos = in->buf->file_last;
- }
-
- continue;
- }
-
- if (ngx_buf_in_memory(in->buf)) {
- in->buf->pos += (size_t) sent;
- }
-
- if (in->buf->in_file) {
- in->buf->file_pos += sent;
- }
-
- break;
- }
-
-#if (NGX_HAVE_AIO_SENDFILE)
- if (c->busy_sendfile) {
- return in;
- }
-#endif
-
- if (eagain) {
-
- /*
- * sendfile() may return EAGAIN, even if it has sent a whole file
- * part, it indicates that the successive sendfile() call would
- * return EAGAIN right away and would not send anything.
- * We use it as a hint.
- */
-
- wev->ready = 0;
- return in;
- }
-
- if (eintr) {
- continue;
- }
-
- if (!complete) {
- wev->ready = 0;
- return in;
- }
-
- if (send >= limit || in == NULL) {
- return in;
- }
- }
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_amd64.h b/usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_amd64.h
deleted file mode 100644
index 159a2974270..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_amd64.h
+++ /dev/null
@@ -1,82 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#if (NGX_SMP)
-#define NGX_SMP_LOCK "lock;"
-#else
-#define NGX_SMP_LOCK
-#endif
-
-
-/*
- * "cmpxchgq r, [m]":
- *
- * if (rax == [m]) {
- * zf = 1;
- * [m] = r;
- * } else {
- * zf = 0;
- * rax = [m];
- * }
- *
- *
- * The "r" is any register, %rax (%r0) - %r16.
- * The "=a" and "a" are the %rax register.
- * Although we can return result in any register, we use "a" because it is
- * used in cmpxchgq anyway. The result is actually in %al but not in $rax,
- * however as the code is inlined gcc can test %al as well as %rax.
- *
- * The "cc" means that flags were changed.
- */
-
-static ngx_inline ngx_atomic_uint_t
-ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
- ngx_atomic_uint_t set)
-{
- u_char res;
-
- __asm__ volatile (
-
- NGX_SMP_LOCK
- " cmpxchgq %3, %1; "
- " sete %0; "
-
- : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");
-
- return res;
-}
-
-
-/*
- * "xaddq r, [m]":
- *
- * temp = [m];
- * [m] += r;
- * r = temp;
- *
- *
- * The "+r" is any register, %rax (%r0) - %r16.
- * The "cc" means that flags were changed.
- */
-
-static ngx_inline ngx_atomic_int_t
-ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
-{
- __asm__ volatile (
-
- NGX_SMP_LOCK
- " xaddq %0, %1; "
-
- : "+r" (add) : "m" (*value) : "cc", "memory");
-
- return add;
-}
-
-
-#define ngx_memory_barrier() __asm__ volatile ("" ::: "memory")
-
-#define ngx_cpu_pause() __asm__ ("pause")
diff --git a/usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_ppc.h b/usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_ppc.h
deleted file mode 100644
index 45afc4b9eac..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_ppc.h
+++ /dev/null
@@ -1,155 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-/*
- * The ppc assembler treats ";" as comment, so we have to use "\n".
- * The minus in "bne-" is a hint for the branch prediction unit that
- * this branch is unlikely to be taken.
- * The "1b" means the nearest backward label "1" and the "1f" means
- * the nearest forward label "1".
- *
- * The "b" means that the base registers can be used only, i.e.
- * any register except r0. The r0 register always has a zero value and
- * could not be used in "addi r0, r0, 1".
- * The "=&b" means that no input registers can be used.
- *
- * "sync" read and write barriers
- * "isync" read barrier, is faster than "sync"
- * "eieio" write barrier, is faster than "sync"
- * "lwsync" write barrier, is faster than "eieio" on ppc64
- */
-
-#if (NGX_PTR_SIZE == 8)
-
-static ngx_inline ngx_atomic_uint_t
-ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
- ngx_atomic_uint_t set)
-{
- ngx_atomic_uint_t res, temp;
-
- __asm__ volatile (
-
- " li %0, 0 \n" /* preset "0" to "res" */
- " lwsync \n" /* write barrier */
- "1: \n"
- " ldarx %1, 0, %2 \n" /* load from [lock] into "temp" */
- /* and store reservation */
- " cmpd %1, %3 \n" /* compare "temp" and "old" */
- " bne- 2f \n" /* not equal */
- " stdcx. %4, 0, %2 \n" /* store "set" into [lock] if reservation */
- /* is not cleared */
- " bne- 1b \n" /* the reservation was cleared */
- " isync \n" /* read barrier */
- " li %0, 1 \n" /* set "1" to "res" */
- "2: \n"
-
- : "=&b" (res), "=&b" (temp)
- : "b" (lock), "b" (old), "b" (set)
- : "cc", "memory");
-
- return res;
-}
-
-
-static ngx_inline ngx_atomic_int_t
-ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
-{
- ngx_atomic_uint_t res, temp;
-
- __asm__ volatile (
-
- " lwsync \n" /* write barrier */
- "1: ldarx %0, 0, %2 \n" /* load from [value] into "res" */
- /* and store reservation */
- " add %1, %0, %3 \n" /* "res" + "add" store in "temp" */
- " stdcx. %1, 0, %2 \n" /* store "temp" into [value] if reservation */
- /* is not cleared */
- " bne- 1b \n" /* try again if reservation was cleared */
- " isync \n" /* read barrier */
-
- : "=&b" (res), "=&b" (temp)
- : "b" (value), "b" (add)
- : "cc", "memory");
-
- return res;
-}
-
-
-#if (NGX_SMP)
-#define ngx_memory_barrier() \
- __asm__ volatile ("isync \n lwsync \n" ::: "memory")
-#else
-#define ngx_memory_barrier() __asm__ volatile ("" ::: "memory")
-#endif
-
-#else
-
-static ngx_inline ngx_atomic_uint_t
-ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
- ngx_atomic_uint_t set)
-{
- ngx_atomic_uint_t res, temp;
-
- __asm__ volatile (
-
- " li %0, 0 \n" /* preset "0" to "res" */
- " eieio \n" /* write barrier */
- "1: \n"
- " lwarx %1, 0, %2 \n" /* load from [lock] into "temp" */
- /* and store reservation */
- " cmpw %1, %3 \n" /* compare "temp" and "old" */
- " bne- 2f \n" /* not equal */
- " stwcx. %4, 0, %2 \n" /* store "set" into [lock] if reservation */
- /* is not cleared */
- " bne- 1b \n" /* the reservation was cleared */
- " isync \n" /* read barrier */
- " li %0, 1 \n" /* set "1" to "res" */
- "2: \n"
-
- : "=&b" (res), "=&b" (temp)
- : "b" (lock), "b" (old), "b" (set)
- : "cc", "memory");
-
- return res;
-}
-
-
-static ngx_inline ngx_atomic_int_t
-ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
-{
- ngx_atomic_uint_t res, temp;
-
- __asm__ volatile (
-
- " eieio \n" /* write barrier */
- "1: lwarx %0, 0, %2 \n" /* load from [value] into "res" */
- /* and store reservation */
- " add %1, %0, %3 \n" /* "res" + "add" store in "temp" */
- " stwcx. %1, 0, %2 \n" /* store "temp" into [value] if reservation */
- /* is not cleared */
- " bne- 1b \n" /* try again if reservation was cleared */
- " isync \n" /* read barrier */
-
- : "=&b" (res), "=&b" (temp)
- : "b" (value), "b" (add)
- : "cc", "memory");
-
- return res;
-}
-
-
-#if (NGX_SMP)
-#define ngx_memory_barrier() \
- __asm__ volatile ("isync \n eieio \n" ::: "memory")
-#else
-#define ngx_memory_barrier() __asm__ volatile ("" ::: "memory")
-#endif
-
-#endif
-
-
-#define ngx_cpu_pause()
diff --git a/usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_sparc64.h b/usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_sparc64.h
deleted file mode 100644
index a84db354482..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_sparc64.h
+++ /dev/null
@@ -1,82 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-/*
- * "casa [r1] 0x80, r2, r0" and
- * "casxa [r1] 0x80, r2, r0" do the following:
- *
- * if ([r1] == r2) {
- * swap(r0, [r1]);
- * } else {
- * r0 = [r1];
- * }
- *
- * so "r0 == r2" means that the operation was successful.
- *
- *
- * The "r" means the general register.
- * The "+r" means the general register used for both input and output.
- */
-
-
-#if (NGX_PTR_SIZE == 4)
-#define NGX_CASA "casa"
-#else
-#define NGX_CASA "casxa"
-#endif
-
-
-static ngx_inline ngx_atomic_uint_t
-ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
- ngx_atomic_uint_t set)
-{
- __asm__ volatile (
-
- NGX_CASA " [%1] 0x80, %2, %0"
-
- : "+r" (set) : "r" (lock), "r" (old) : "memory");
-
- return (set == old);
-}
-
-
-static ngx_inline ngx_atomic_int_t
-ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
-{
- ngx_atomic_uint_t old, res;
-
- old = *value;
-
- for ( ;; ) {
-
- res = old + add;
-
- __asm__ volatile (
-
- NGX_CASA " [%1] 0x80, %2, %0"
-
- : "+r" (res) : "r" (value), "r" (old) : "memory");
-
- if (res == old) {
- return res;
- }
-
- old = res;
- }
-}
-
-
-#if (NGX_SMP)
-#define ngx_memory_barrier() \
- __asm__ volatile ( \
- "membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad" \
- ::: "memory")
-#else
-#define ngx_memory_barrier() __asm__ volatile ("" ::: "memory")
-#endif
-
-#define ngx_cpu_pause()
diff --git a/usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_x86.h b/usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_x86.h
deleted file mode 100644
index 54e01aebf0b..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_gcc_atomic_x86.h
+++ /dev/null
@@ -1,127 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#if (NGX_SMP)
-#define NGX_SMP_LOCK "lock;"
-#else
-#define NGX_SMP_LOCK
-#endif
-
-
-/*
- * "cmpxchgl r, [m]":
- *
- * if (eax == [m]) {
- * zf = 1;
- * [m] = r;
- * } else {
- * zf = 0;
- * eax = [m];
- * }
- *
- *
- * The "r" means the general register.
- * The "=a" and "a" are the %eax register.
- * Although we can return result in any register, we use "a" because it is
- * used in cmpxchgl anyway. The result is actually in %al but not in %eax,
- * however, as the code is inlined gcc can test %al as well as %eax,
- * and icc adds "movzbl %al, %eax" by itself.
- *
- * The "cc" means that flags were changed.
- */
-
-static ngx_inline ngx_atomic_uint_t
-ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
- ngx_atomic_uint_t set)
-{
- u_char res;
-
- __asm__ volatile (
-
- NGX_SMP_LOCK
- " cmpxchgl %3, %1; "
- " sete %0; "
-
- : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");
-
- return res;
-}
-
-
-/*
- * "xaddl r, [m]":
- *
- * temp = [m];
- * [m] += r;
- * r = temp;
- *
- *
- * The "+r" means the general register.
- * The "cc" means that flags were changed.
- */
-
-
-#if !(( __GNUC__ == 2 && __GNUC_MINOR__ <= 7 ) || ( __INTEL_COMPILER >= 800 ))
-
-/*
- * icc 8.1 and 9.0 compile broken code with -march=pentium4 option:
- * ngx_atomic_fetch_add() always return the input "add" value,
- * so we use the gcc 2.7 version.
- *
- * icc 8.1 and 9.0 with -march=pentiumpro option or icc 7.1 compile
- * correct code.
- */
-
-static ngx_inline ngx_atomic_int_t
-ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
-{
- __asm__ volatile (
-
- NGX_SMP_LOCK
- " xaddl %0, %1; "
-
- : "+r" (add) : "m" (*value) : "cc", "memory");
-
- return add;
-}
-
-
-#else
-
-/*
- * gcc 2.7 does not support "+r", so we have to use the fixed
- * %eax ("=a" and "a") and this adds two superfluous instructions in the end
- * of code, something like this: "mov %eax, %edx / mov %edx, %eax".
- */
-
-static ngx_inline ngx_atomic_int_t
-ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
-{
- ngx_atomic_uint_t old;
-
- __asm__ volatile (
-
- NGX_SMP_LOCK
- " xaddl %2, %1; "
-
- : "=a" (old) : "m" (*value), "a" (add) : "cc", "memory");
-
- return old;
-}
-
-#endif
-
-
-/*
- * on x86 the write operations go in a program order, so we need only
- * to disable the gcc reorder optimizations
- */
-
-#define ngx_memory_barrier() __asm__ volatile ("" ::: "memory")
-
-/* old "as" does not support "pause" opcode */
-#define ngx_cpu_pause() __asm__ (".byte 0xf3, 0x90")
diff --git a/usr.sbin/nginx/src/os/unix/ngx_linux.h b/usr.sbin/nginx/src/os/unix/ngx_linux.h
deleted file mode 100644
index 1b8bdac51a4..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_linux.h
+++ /dev/null
@@ -1,18 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_LINUX_H_INCLUDED_
-#define _NGX_LINUX_H_INCLUDED_
-
-
-ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
-
-extern int ngx_linux_rtsig_max;
-
-
-#endif /* _NGX_LINUX_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_linux_aio_read.c b/usr.sbin/nginx/src/os/unix/ngx_linux_aio_read.c
deleted file mode 100644
index 8273c13f960..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_linux_aio_read.c
+++ /dev/null
@@ -1,137 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-extern int ngx_eventfd;
-extern aio_context_t ngx_aio_ctx;
-
-
-static void ngx_file_aio_event_handler(ngx_event_t *ev);
-
-
-static int
-io_submit(aio_context_t ctx, long n, struct iocb **paiocb)
-{
- return syscall(SYS_io_submit, ctx, n, paiocb);
-}
-
-
-ssize_t
-ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
- ngx_pool_t *pool)
-{
- ngx_err_t err;
- struct iocb *piocb[1];
- ngx_event_t *ev;
- ngx_event_aio_t *aio;
-
- if (!ngx_file_aio) {
- return ngx_read_file(file, buf, size, offset);
- }
-
- aio = file->aio;
-
- if (aio == NULL) {
- aio = ngx_pcalloc(pool, sizeof(ngx_event_aio_t));
- if (aio == NULL) {
- return NGX_ERROR;
- }
-
- aio->file = file;
- aio->fd = file->fd;
- aio->event.data = aio;
- aio->event.ready = 1;
- aio->event.log = file->log;
- file->aio = aio;
- }
-
- ev = &aio->event;
-
- if (!ev->ready) {
- ngx_log_error(NGX_LOG_ALERT, file->log, 0,
- "second aio post for \"%V\"", &file->name);
- return NGX_AGAIN;
- }
-
- ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0,
- "aio complete:%d @%O:%z %V",
- ev->complete, offset, size, &file->name);
-
- if (ev->complete) {
- ev->active = 0;
- ev->complete = 0;
-
- if (aio->res >= 0) {
- ngx_set_errno(0);
- return aio->res;
- }
-
- ngx_set_errno(-aio->res);
-
- ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno,
- "aio read \"%s\" failed", file->name.data);
-
- return NGX_ERROR;
- }
-
- ngx_memzero(&aio->aiocb, sizeof(struct iocb));
-
- aio->aiocb.aio_data = (uint64_t) (uintptr_t) ev;
- aio->aiocb.aio_lio_opcode = IOCB_CMD_PREAD;
- aio->aiocb.aio_fildes = file->fd;
- aio->aiocb.aio_buf = (uint64_t) (uintptr_t) buf;
- aio->aiocb.aio_nbytes = size;
- aio->aiocb.aio_offset = offset;
- aio->aiocb.aio_flags = IOCB_FLAG_RESFD;
- aio->aiocb.aio_resfd = ngx_eventfd;
-
- ev->handler = ngx_file_aio_event_handler;
-
- piocb[0] = &aio->aiocb;
-
- if (io_submit(ngx_aio_ctx, 1, piocb) == 1) {
- ev->active = 1;
- ev->ready = 0;
- ev->complete = 0;
-
- return NGX_AGAIN;
- }
-
- err = ngx_errno;
-
- if (err == NGX_EAGAIN) {
- return ngx_read_file(file, buf, size, offset);
- }
-
- ngx_log_error(NGX_LOG_CRIT, file->log, err,
- "io_submit(\"%V\") failed", &file->name);
-
- if (err == NGX_ENOSYS) {
- ngx_file_aio = 0;
- return ngx_read_file(file, buf, size, offset);
- }
-
- return NGX_ERROR;
-}
-
-
-static void
-ngx_file_aio_event_handler(ngx_event_t *ev)
-{
- ngx_event_aio_t *aio;
-
- aio = ev->data;
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, ev->log, 0,
- "aio event handler fd:%d %V", aio->fd, &aio->file->name);
-
- aio->handler(ev);
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_linux_config.h b/usr.sbin/nginx/src/os/unix/ngx_linux_config.h
deleted file mode 100644
index 72594bac0ea..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_linux_config.h
+++ /dev/null
@@ -1,124 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_LINUX_CONFIG_H_INCLUDED_
-#define _NGX_LINUX_CONFIG_H_INCLUDED_
-
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE /* pread(), pwrite(), gethostname() */
-#endif
-
-#define _FILE_OFFSET_BITS 64
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <stddef.h> /* offsetof() */
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include <pwd.h>
-#include <grp.h>
-#include <dirent.h>
-#include <glob.h>
-#include <sys/vfs.h> /* statfs() */
-
-#include <sys/uio.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <sched.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h> /* TCP_NODELAY, TCP_CORK */
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/un.h>
-
-#include <time.h> /* tzset() */
-#include <malloc.h> /* memalign() */
-#include <limits.h> /* IOV_MAX */
-#include <sys/ioctl.h>
-#include <crypt.h>
-#include <sys/utsname.h> /* uname() */
-
-
-#include <ngx_auto_config.h>
-
-
-#if (NGX_HAVE_POSIX_SEM)
-#include <semaphore.h>
-#endif
-
-
-#if (NGX_HAVE_SYS_PRCTL_H)
-#include <sys/prctl.h>
-#endif
-
-
-#if (NGX_HAVE_SENDFILE64)
-#include <sys/sendfile.h>
-#else
-extern ssize_t sendfile(int s, int fd, int32_t *offset, size_t size);
-#define NGX_SENDFILE_LIMIT 0x80000000
-#endif
-
-
-#if (NGX_HAVE_POLL)
-#include <poll.h>
-#endif
-
-
-#if (NGX_HAVE_RTSIG)
-#include <poll.h>
-#include <sys/sysctl.h>
-#endif
-
-
-#if (NGX_HAVE_EPOLL)
-#include <sys/epoll.h>
-#endif
-
-
-#if (NGX_HAVE_FILE_AIO)
-#include <sys/syscall.h>
-#include <linux/aio_abi.h>
-typedef struct iocb ngx_aiocb_t;
-#endif
-
-
-#define NGX_LISTEN_BACKLOG 511
-
-
-#ifndef NGX_HAVE_SO_SNDLOWAT
-/* setsockopt(SO_SNDLOWAT) returns ENOPROTOOPT */
-#define NGX_HAVE_SO_SNDLOWAT 0
-#endif
-
-
-#ifndef NGX_HAVE_INHERITED_NONBLOCK
-#define NGX_HAVE_INHERITED_NONBLOCK 0
-#endif
-
-
-#define NGX_HAVE_OS_SPECIFIC_INIT 1
-#define ngx_debug_init()
-
-
-extern char **environ;
-
-
-#endif /* _NGX_LINUX_CONFIG_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_linux_init.c b/usr.sbin/nginx/src/os/unix/ngx_linux_init.c
deleted file mode 100644
index b910380d7ce..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_linux_init.c
+++ /dev/null
@@ -1,91 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-u_char ngx_linux_kern_ostype[50];
-u_char ngx_linux_kern_osrelease[50];
-
-int ngx_linux_rtsig_max;
-
-
-static ngx_os_io_t ngx_linux_io = {
- ngx_unix_recv,
- ngx_readv_chain,
- ngx_udp_unix_recv,
- ngx_unix_send,
-#if (NGX_HAVE_SENDFILE)
- ngx_linux_sendfile_chain,
- NGX_IO_SENDFILE
-#else
- ngx_writev_chain,
- 0
-#endif
-};
-
-
-ngx_int_t
-ngx_os_specific_init(ngx_log_t *log)
-{
- struct utsname u;
-
- if (uname(&u) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "uname() failed");
- return NGX_ERROR;
- }
-
- (void) ngx_cpystrn(ngx_linux_kern_ostype, (u_char *) u.sysname,
- sizeof(ngx_linux_kern_ostype));
-
- (void) ngx_cpystrn(ngx_linux_kern_osrelease, (u_char *) u.release,
- sizeof(ngx_linux_kern_osrelease));
-
-#if (NGX_HAVE_RTSIG)
- {
- int name[2];
- size_t len;
- ngx_err_t err;
-
- name[0] = CTL_KERN;
- name[1] = KERN_RTSIGMAX;
- len = sizeof(ngx_linux_rtsig_max);
-
- if (sysctl(name, 2, &ngx_linux_rtsig_max, &len, NULL, 0) == -1) {
- err = ngx_errno;
-
- if (err != NGX_ENOTDIR && err != NGX_ENOSYS) {
- ngx_log_error(NGX_LOG_ALERT, log, err,
- "sysctl(KERN_RTSIGMAX) failed");
-
- return NGX_ERROR;
- }
-
- ngx_linux_rtsig_max = 0;
- }
-
- }
-#endif
-
- ngx_os_io = ngx_linux_io;
-
- return NGX_OK;
-}
-
-
-void
-ngx_os_specific_status(ngx_log_t *log)
-{
- ngx_log_error(NGX_LOG_NOTICE, log, 0, "OS: %s %s",
- ngx_linux_kern_ostype, ngx_linux_kern_osrelease);
-
-#if (NGX_HAVE_RTSIG)
- ngx_log_error(NGX_LOG_NOTICE, log, 0, "sysctl(KERN_RTSIGMAX): %d",
- ngx_linux_rtsig_max);
-#endif
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_linux_sendfile_chain.c b/usr.sbin/nginx/src/os/unix/ngx_linux_sendfile_chain.c
deleted file mode 100644
index 16395f94337..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_linux_sendfile_chain.c
+++ /dev/null
@@ -1,378 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-/*
- * On Linux up to 2.4.21 sendfile() (syscall #187) works with 32-bit
- * offsets only, and the including <sys/sendfile.h> breaks the compiling,
- * if off_t is 64 bit wide. So we use own sendfile() definition, where offset
- * parameter is int32_t, and use sendfile() for the file parts below 2G only,
- * see src/os/unix/ngx_linux_config.h
- *
- * Linux 2.4.21 has the new sendfile64() syscall #239.
- *
- * On Linux up to 2.6.16 sendfile() does not allow to pass the count parameter
- * more than 2G-1 bytes even on 64-bit platforms: it returns EINVAL,
- * so we limit it to 2G-1 bytes.
- */
-
-#define NGX_SENDFILE_MAXSIZE 2147483647L
-
-
-#if (IOV_MAX > 64)
-#define NGX_HEADERS 64
-#else
-#define NGX_HEADERS IOV_MAX
-#endif
-
-
-ngx_chain_t *
-ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
-{
- int rc, tcp_nodelay;
- off_t size, send, prev_send, aligned, sent, fprev;
- u_char *prev;
- size_t file_size;
- ngx_err_t err;
- ngx_buf_t *file;
- ngx_uint_t eintr, complete;
- ngx_array_t header;
- ngx_event_t *wev;
- ngx_chain_t *cl;
- struct iovec *iov, headers[NGX_HEADERS];
-#if (NGX_HAVE_SENDFILE64)
- off_t offset;
-#else
- int32_t offset;
-#endif
-
- wev = c->write;
-
- if (!wev->ready) {
- return in;
- }
-
-
- /* the maximum limit size is 2G-1 - the page size */
-
- if (limit == 0 || limit > (off_t) (NGX_SENDFILE_MAXSIZE - ngx_pagesize)) {
- limit = NGX_SENDFILE_MAXSIZE - ngx_pagesize;
- }
-
-
- send = 0;
-
- header.elts = headers;
- header.size = sizeof(struct iovec);
- header.nalloc = NGX_HEADERS;
- header.pool = c->pool;
-
- for ( ;; ) {
- file = NULL;
- file_size = 0;
- eintr = 0;
- complete = 0;
- prev_send = send;
-
- header.nelts = 0;
-
- prev = NULL;
- iov = NULL;
-
- /* create the iovec and coalesce the neighbouring bufs */
-
- for (cl = in; cl && send < limit; cl = cl->next) {
-
- if (ngx_buf_special(cl->buf)) {
- continue;
- }
-
-#if 1
- if (!ngx_buf_in_memory(cl->buf) && !cl->buf->in_file) {
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "zero size buf in sendfile "
- "t:%d r:%d f:%d %p %p-%p %p %O-%O",
- cl->buf->temporary,
- cl->buf->recycled,
- cl->buf->in_file,
- cl->buf->start,
- cl->buf->pos,
- cl->buf->last,
- cl->buf->file,
- cl->buf->file_pos,
- cl->buf->file_last);
-
- ngx_debug_point();
-
- return NGX_CHAIN_ERROR;
- }
-#endif
-
- if (!ngx_buf_in_memory_only(cl->buf)) {
- break;
- }
-
- size = cl->buf->last - cl->buf->pos;
-
- if (send + size > limit) {
- size = limit - send;
- }
-
- if (prev == cl->buf->pos) {
- iov->iov_len += (size_t) size;
-
- } else {
- if (header.nelts >= IOV_MAX) {
- break;
- }
-
- iov = ngx_array_push(&header);
- if (iov == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- iov->iov_base = (void *) cl->buf->pos;
- iov->iov_len = (size_t) size;
- }
-
- prev = cl->buf->pos + (size_t) size;
- send += size;
- }
-
- /* set TCP_CORK if there is a header before a file */
-
- if (c->tcp_nopush == NGX_TCP_NOPUSH_UNSET
- && header.nelts != 0
- && cl
- && cl->buf->in_file)
- {
- /* the TCP_CORK and TCP_NODELAY are mutually exclusive */
-
- if (c->tcp_nodelay == NGX_TCP_NODELAY_SET) {
-
- tcp_nodelay = 0;
-
- if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
- (const void *) &tcp_nodelay, sizeof(int)) == -1)
- {
- err = ngx_socket_errno;
-
- /*
- * there is a tiny chance to be interrupted, however,
- * we continue a processing with the TCP_NODELAY
- * and without the TCP_CORK
- */
-
- if (err != NGX_EINTR) {
- wev->error = 1;
- ngx_connection_error(c, err,
- "setsockopt(TCP_NODELAY) failed");
- return NGX_CHAIN_ERROR;
- }
-
- } else {
- c->tcp_nodelay = NGX_TCP_NODELAY_UNSET;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "no tcp_nodelay");
- }
- }
-
- if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
-
- if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
- err = ngx_socket_errno;
-
- /*
- * there is a tiny chance to be interrupted, however,
- * we continue a processing without the TCP_CORK
- */
-
- if (err != NGX_EINTR) {
- wev->error = 1;
- ngx_connection_error(c, err,
- ngx_tcp_nopush_n " failed");
- return NGX_CHAIN_ERROR;
- }
-
- } else {
- c->tcp_nopush = NGX_TCP_NOPUSH_SET;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "tcp_nopush");
- }
- }
- }
-
- /* get the file buf */
-
- if (header.nelts == 0 && cl && cl->buf->in_file && send < limit) {
- file = cl->buf;
-
- /* coalesce the neighbouring file bufs */
-
- do {
- size = cl->buf->file_last - cl->buf->file_pos;
-
- if (send + size > limit) {
- size = limit - send;
-
- aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
- & ~((off_t) ngx_pagesize - 1);
-
- if (aligned <= cl->buf->file_last) {
- size = aligned - cl->buf->file_pos;
- }
- }
-
- file_size += (size_t) size;
- send += size;
- fprev = cl->buf->file_pos + size;
- cl = cl->next;
-
- } while (cl
- && cl->buf->in_file
- && send < limit
- && file->file->fd == cl->buf->file->fd
- && fprev == cl->buf->file_pos);
- }
-
- if (file) {
-#if 1
- if (file_size == 0) {
- ngx_debug_point();
- return NGX_CHAIN_ERROR;
- }
-#endif
-#if (NGX_HAVE_SENDFILE64)
- offset = file->file_pos;
-#else
- offset = (int32_t) file->file_pos;
-#endif
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "sendfile: @%O %uz", file->file_pos, file_size);
-
- rc = sendfile(c->fd, file->file->fd, &offset, file_size);
-
- if (rc == -1) {
- err = ngx_errno;
-
- switch (err) {
- case NGX_EAGAIN:
- break;
-
- case NGX_EINTR:
- eintr = 1;
- break;
-
- default:
- wev->error = 1;
- ngx_connection_error(c, err, "sendfile() failed");
- return NGX_CHAIN_ERROR;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "sendfile() is not ready");
- }
-
- sent = rc > 0 ? rc : 0;
-
- ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "sendfile: %d, @%O %O:%uz",
- rc, file->file_pos, sent, file_size);
-
- } else {
- rc = writev(c->fd, header.elts, header.nelts);
-
- if (rc == -1) {
- err = ngx_errno;
-
- switch (err) {
- case NGX_EAGAIN:
- break;
-
- case NGX_EINTR:
- eintr = 1;
- break;
-
- default:
- wev->error = 1;
- ngx_connection_error(c, err, "writev() failed");
- return NGX_CHAIN_ERROR;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "writev() not ready");
- }
-
- sent = rc > 0 ? rc : 0;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %O", sent);
- }
-
- if (send - prev_send == sent) {
- complete = 1;
- }
-
- c->sent += sent;
-
- for ( /* void */ ; in; in = in->next) {
-
- if (ngx_buf_special(in->buf)) {
- continue;
- }
-
- if (sent == 0) {
- break;
- }
-
- size = ngx_buf_size(in->buf);
-
- if (sent >= size) {
- sent -= size;
-
- if (ngx_buf_in_memory(in->buf)) {
- in->buf->pos = in->buf->last;
- }
-
- if (in->buf->in_file) {
- in->buf->file_pos = in->buf->file_last;
- }
-
- continue;
- }
-
- if (ngx_buf_in_memory(in->buf)) {
- in->buf->pos += (size_t) sent;
- }
-
- if (in->buf->in_file) {
- in->buf->file_pos += sent;
- }
-
- break;
- }
-
- if (eintr) {
- continue;
- }
-
- if (!complete) {
- wev->ready = 0;
- return in;
- }
-
- if (send >= limit || in == NULL) {
- return in;
- }
- }
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_os.h b/usr.sbin/nginx/src/os/unix/ngx_os.h
deleted file mode 100644
index c646e2aa5a8..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_os.h
+++ /dev/null
@@ -1,83 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_OS_H_INCLUDED_
-#define _NGX_OS_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#define NGX_IO_SENDFILE 1
-
-
-typedef ssize_t (*ngx_recv_pt)(ngx_connection_t *c, u_char *buf, size_t size);
-typedef ssize_t (*ngx_recv_chain_pt)(ngx_connection_t *c, ngx_chain_t *in);
-typedef ssize_t (*ngx_send_pt)(ngx_connection_t *c, u_char *buf, size_t size);
-typedef ngx_chain_t *(*ngx_send_chain_pt)(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
-
-typedef struct {
- ngx_recv_pt recv;
- ngx_recv_chain_pt recv_chain;
- ngx_recv_pt udp_recv;
- ngx_send_pt send;
- ngx_send_chain_pt send_chain;
- ngx_uint_t flags;
-} ngx_os_io_t;
-
-
-ngx_int_t ngx_os_init(ngx_log_t *log);
-void ngx_os_status(ngx_log_t *log);
-ngx_int_t ngx_os_specific_init(ngx_log_t *log);
-void ngx_os_specific_status(ngx_log_t *log);
-ngx_int_t ngx_daemon(ngx_log_t *log);
-ngx_int_t ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_int_t pid);
-
-
-ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size);
-ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry);
-ssize_t ngx_udp_unix_recv(ngx_connection_t *c, u_char *buf, size_t size);
-ssize_t ngx_unix_send(ngx_connection_t *c, u_char *buf, size_t size);
-ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
-
-#if (NGX_HAVE_AIO)
-ssize_t ngx_aio_read(ngx_connection_t *c, u_char *buf, size_t size);
-ssize_t ngx_aio_read_chain(ngx_connection_t *c, ngx_chain_t *cl);
-ssize_t ngx_aio_write(ngx_connection_t *c, u_char *buf, size_t size);
-ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
-#endif
-
-
-extern ngx_os_io_t ngx_os_io;
-extern ngx_int_t ngx_ncpu;
-extern ngx_int_t ngx_max_sockets;
-extern ngx_uint_t ngx_inherited_nonblocking;
-extern ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush;
-
-
-#if (NGX_FREEBSD)
-#include <ngx_freebsd.h>
-
-
-#elif (NGX_LINUX)
-#include <ngx_linux.h>
-
-
-#elif (NGX_SOLARIS)
-#include <ngx_solaris.h>
-
-
-#elif (NGX_DARWIN)
-#include <ngx_darwin.h>
-#endif
-
-
-#endif /* _NGX_OS_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_posix_config.h b/usr.sbin/nginx/src/os/unix/ngx_posix_config.h
deleted file mode 100644
index d725659dfac..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_posix_config.h
+++ /dev/null
@@ -1,158 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_POSIX_CONFIG_H_INCLUDED_
-#define _NGX_POSIX_CONFIG_H_INCLUDED_
-
-
-#if (NGX_HPUX)
-#define _XOPEN_SOURCE
-#define _XOPEN_SOURCE_EXTENDED 1
-#define _HPUX_ALT_XOPEN_SOCKET_API
-#endif
-
-
-#if (NGX_TRU64)
-#define _REENTRANT
-#endif
-
-
-#ifdef __CYGWIN__
-#define timezonevar /* timezone is variable */
-#define NGX_BROKEN_SCM_RIGHTS 1
-#endif
-
-
-#include <sys/types.h>
-#include <sys/time.h>
-#if (NGX_HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#if (NGX_HAVE_INTTYPES_H)
-#include <inttypes.h>
-#endif
-#include <stdarg.h>
-#include <stddef.h> /* offsetof() */
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include <pwd.h>
-#include <grp.h>
-#include <dirent.h>
-#include <glob.h>
-#include <time.h>
-#if (NGX_HAVE_SYS_PARAM_H)
-#include <sys/param.h> /* statfs() */
-#endif
-#if (NGX_HAVE_SYS_MOUNT_H)
-#include <sys/mount.h> /* statfs() */
-#endif
-#if (NGX_HAVE_SYS_STATVFS_H)
-#include <sys/statvfs.h> /* statvfs() */
-#endif
-
-#if (NGX_HAVE_SYS_FILIO_H)
-#include <sys/filio.h> /* FIONBIO */
-#endif
-#include <sys/ioctl.h> /* FIONBIO */
-
-#include <sys/uio.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <sched.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h> /* TCP_NODELAY */
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/un.h>
-
-#if (NGX_HAVE_LIMITS_H)
-#include <limits.h> /* IOV_MAX */
-#endif
-
-#ifdef __CYGWIN__
-#include <malloc.h> /* memalign() */
-#endif
-
-#if (NGX_HAVE_CRYPT_H)
-#include <crypt.h>
-#endif
-
-
-#ifndef IOV_MAX
-#define IOV_MAX 16
-#endif
-
-
-#include <ngx_auto_config.h>
-
-
-#if (NGX_HAVE_POSIX_SEM)
-#include <semaphore.h>
-#endif
-
-
-#if (NGX_HAVE_POLL)
-#include <poll.h>
-#endif
-
-
-#if (NGX_HAVE_KQUEUE)
-#include <sys/event.h>
-#endif
-
-
-#if (NGX_HAVE_DEVPOLL)
-#include <sys/ioctl.h>
-#include <sys/devpoll.h>
-#endif
-
-
-#if (NGX_HAVE_FILE_AIO)
-#include <aio.h>
-typedef struct aiocb ngx_aiocb_t;
-#endif
-
-
-#define NGX_LISTEN_BACKLOG 511
-
-#define ngx_debug_init()
-
-
-#if (__FreeBSD__) && (__FreeBSD_version < 400017)
-
-#include <sys/param.h> /* ALIGN() */
-
-/*
- * FreeBSD 3.x has no CMSG_SPACE() and CMSG_LEN() and has the broken CMSG_DATA()
- */
-
-#undef CMSG_SPACE
-#define CMSG_SPACE(l) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(l))
-
-#undef CMSG_LEN
-#define CMSG_LEN(l) (ALIGN(sizeof(struct cmsghdr)) + (l))
-
-#undef CMSG_DATA
-#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + ALIGN(sizeof(struct cmsghdr)))
-
-#endif
-
-
-extern char **environ;
-
-
-#endif /* _NGX_POSIX_CONFIG_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_posix_init.c b/usr.sbin/nginx/src/os/unix/ngx_posix_init.c
deleted file mode 100644
index 58e6f76143b..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_posix_init.c
+++ /dev/null
@@ -1,128 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <nginx.h>
-
-
-ngx_int_t ngx_ncpu;
-ngx_int_t ngx_max_sockets;
-ngx_uint_t ngx_inherited_nonblocking;
-ngx_uint_t ngx_tcp_nodelay_and_tcp_nopush;
-
-
-struct rlimit rlmt;
-
-
-ngx_os_io_t ngx_os_io = {
- ngx_unix_recv,
- ngx_readv_chain,
- ngx_udp_unix_recv,
- ngx_unix_send,
- ngx_writev_chain,
- 0
-};
-
-
-ngx_int_t
-ngx_os_init(ngx_log_t *log)
-{
- ngx_uint_t n;
-
-#if (NGX_HAVE_OS_SPECIFIC_INIT)
- if (ngx_os_specific_init(log) != NGX_OK) {
- return NGX_ERROR;
- }
-#endif
-
- ngx_init_setproctitle(log);
-
- ngx_pagesize = getpagesize();
- ngx_cacheline_size = NGX_CPU_CACHE_LINE;
-
- for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }
-
-#if (NGX_HAVE_SC_NPROCESSORS_ONLN)
- if (ngx_ncpu == 0) {
- ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN);
- }
-#endif
-
- if (ngx_ncpu < 1) {
- ngx_ncpu = 1;
- }
-
- ngx_cpuinfo();
-
- if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, errno,
- "getrlimit(RLIMIT_NOFILE) failed)");
- return NGX_ERROR;
- }
-
- ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur;
-
-#if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4)
- ngx_inherited_nonblocking = 1;
-#else
- ngx_inherited_nonblocking = 0;
-#endif
-
- srandom(ngx_time());
-
- return NGX_OK;
-}
-
-
-void
-ngx_os_status(ngx_log_t *log)
-{
- ngx_log_error(NGX_LOG_NOTICE, log, 0, NGINX_VER);
-
-#ifdef NGX_COMPILER
- ngx_log_error(NGX_LOG_NOTICE, log, 0, "built by " NGX_COMPILER);
-#endif
-
-#if (NGX_HAVE_OS_SPECIFIC_INIT)
- ngx_os_specific_status(log);
-#endif
-
- ngx_log_error(NGX_LOG_NOTICE, log, 0,
- "getrlimit(RLIMIT_NOFILE): %r:%r",
- rlmt.rlim_cur, rlmt.rlim_max);
-}
-
-
-#if 0
-
-ngx_int_t
-ngx_posix_post_conf_init(ngx_log_t *log)
-{
- ngx_fd_t pp[2];
-
- if (pipe(pp) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "pipe() failed");
- return NGX_ERROR;
- }
-
- if (dup2(pp[1], STDERR_FILENO) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDERR) failed");
- return NGX_ERROR;
- }
-
- if (pp[1] > STDERR_FILENO) {
- if (close(pp[1]) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, errno, "close() failed");
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
-}
-
-#endif
diff --git a/usr.sbin/nginx/src/os/unix/ngx_process.c b/usr.sbin/nginx/src/os/unix/ngx_process.c
deleted file mode 100644
index 6f3f38556ab..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_process.c
+++ /dev/null
@@ -1,630 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_channel.h>
-
-
-typedef struct {
- int signo;
- char *signame;
- char *name;
- void (*handler)(int signo);
-} ngx_signal_t;
-
-
-
-static void ngx_execute_proc(ngx_cycle_t *cycle, void *data);
-static void ngx_signal_handler(int signo);
-static void ngx_process_get_status(void);
-static void ngx_unlock_mutexes(ngx_pid_t pid);
-
-
-int ngx_argc;
-char **ngx_argv;
-char **ngx_os_argv;
-
-ngx_int_t ngx_process_slot;
-ngx_socket_t ngx_channel;
-ngx_int_t ngx_last_process;
-ngx_process_t ngx_processes[NGX_MAX_PROCESSES];
-
-
-ngx_signal_t signals[] = {
- { ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
- "SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
- "reload",
- ngx_signal_handler },
-
- { ngx_signal_value(NGX_REOPEN_SIGNAL),
- "SIG" ngx_value(NGX_REOPEN_SIGNAL),
- "reopen",
- ngx_signal_handler },
-
- { ngx_signal_value(NGX_NOACCEPT_SIGNAL),
- "SIG" ngx_value(NGX_NOACCEPT_SIGNAL),
- "",
- ngx_signal_handler },
-
- { ngx_signal_value(NGX_TERMINATE_SIGNAL),
- "SIG" ngx_value(NGX_TERMINATE_SIGNAL),
- "stop",
- ngx_signal_handler },
-
- { ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
- "SIG" ngx_value(NGX_SHUTDOWN_SIGNAL),
- "quit",
- ngx_signal_handler },
-
- { ngx_signal_value(NGX_CHANGEBIN_SIGNAL),
- "SIG" ngx_value(NGX_CHANGEBIN_SIGNAL),
- "",
- ngx_signal_handler },
-
- { SIGALRM, "SIGALRM", "", ngx_signal_handler },
-
- { SIGINT, "SIGINT", "", ngx_signal_handler },
-
- { SIGIO, "SIGIO", "", ngx_signal_handler },
-
- { SIGCHLD, "SIGCHLD", "", ngx_signal_handler },
-
- { SIGSYS, "SIGSYS, SIG_IGN", "", SIG_IGN },
-
- { SIGPIPE, "SIGPIPE, SIG_IGN", "", SIG_IGN },
-
- { 0, NULL, "", NULL }
-};
-
-
-ngx_pid_t
-ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,
- char *name, ngx_int_t respawn)
-{
- u_long on;
- ngx_pid_t pid;
- ngx_int_t s;
-
- if (respawn >= 0) {
- s = respawn;
-
- } else {
- for (s = 0; s < ngx_last_process; s++) {
- if (ngx_processes[s].pid == -1) {
- break;
- }
- }
-
- if (s == NGX_MAX_PROCESSES) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "no more than %d processes can be spawned",
- NGX_MAX_PROCESSES);
- return NGX_INVALID_PID;
- }
- }
-
-
- if (respawn != NGX_PROCESS_DETACHED) {
-
- /* Solaris 9 still has no AF_LOCAL */
-
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "socketpair() failed while spawning \"%s\"", name);
- return NGX_INVALID_PID;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
- "channel %d:%d",
- ngx_processes[s].channel[0],
- ngx_processes[s].channel[1]);
-
- if (ngx_nonblocking(ngx_processes[s].channel[0]) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- ngx_nonblocking_n " failed while spawning \"%s\"",
- name);
- ngx_close_channel(ngx_processes[s].channel, cycle->log);
- return NGX_INVALID_PID;
- }
-
- if (ngx_nonblocking(ngx_processes[s].channel[1]) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- ngx_nonblocking_n " failed while spawning \"%s\"",
- name);
- ngx_close_channel(ngx_processes[s].channel, cycle->log);
- return NGX_INVALID_PID;
- }
-
- on = 1;
- if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "ioctl(FIOASYNC) failed while spawning \"%s\"", name);
- ngx_close_channel(ngx_processes[s].channel, cycle->log);
- return NGX_INVALID_PID;
- }
-
- if (fcntl(ngx_processes[s].channel[0], F_SETOWN, ngx_pid) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "fcntl(F_SETOWN) failed while spawning \"%s\"", name);
- ngx_close_channel(ngx_processes[s].channel, cycle->log);
- return NGX_INVALID_PID;
- }
-
- if (fcntl(ngx_processes[s].channel[0], F_SETFD, FD_CLOEXEC) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "fcntl(FD_CLOEXEC) failed while spawning \"%s\"",
- name);
- ngx_close_channel(ngx_processes[s].channel, cycle->log);
- return NGX_INVALID_PID;
- }
-
- if (fcntl(ngx_processes[s].channel[1], F_SETFD, FD_CLOEXEC) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "fcntl(FD_CLOEXEC) failed while spawning \"%s\"",
- name);
- ngx_close_channel(ngx_processes[s].channel, cycle->log);
- return NGX_INVALID_PID;
- }
-
- ngx_channel = ngx_processes[s].channel[1];
-
- } else {
- ngx_processes[s].channel[0] = -1;
- ngx_processes[s].channel[1] = -1;
- }
-
- ngx_process_slot = s;
-
-
- pid = fork();
-
- switch (pid) {
-
- case -1:
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "fork() failed while spawning \"%s\"", name);
- ngx_close_channel(ngx_processes[s].channel, cycle->log);
- return NGX_INVALID_PID;
-
- case 0:
- ngx_pid = ngx_getpid();
- proc(cycle, data);
- break;
-
- default:
- break;
- }
-
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start %s %P", name, pid);
-
- ngx_processes[s].pid = pid;
- ngx_processes[s].exited = 0;
-
- if (respawn >= 0) {
- return pid;
- }
-
- ngx_processes[s].proc = proc;
- ngx_processes[s].data = data;
- ngx_processes[s].name = name;
- ngx_processes[s].exiting = 0;
-
- switch (respawn) {
-
- case NGX_PROCESS_NORESPAWN:
- ngx_processes[s].respawn = 0;
- ngx_processes[s].just_spawn = 0;
- ngx_processes[s].detached = 0;
- break;
-
- case NGX_PROCESS_JUST_SPAWN:
- ngx_processes[s].respawn = 0;
- ngx_processes[s].just_spawn = 1;
- ngx_processes[s].detached = 0;
- break;
-
- case NGX_PROCESS_RESPAWN:
- ngx_processes[s].respawn = 1;
- ngx_processes[s].just_spawn = 0;
- ngx_processes[s].detached = 0;
- break;
-
- case NGX_PROCESS_JUST_RESPAWN:
- ngx_processes[s].respawn = 1;
- ngx_processes[s].just_spawn = 1;
- ngx_processes[s].detached = 0;
- break;
-
- case NGX_PROCESS_DETACHED:
- ngx_processes[s].respawn = 0;
- ngx_processes[s].just_spawn = 0;
- ngx_processes[s].detached = 1;
- break;
- }
-
- if (s == ngx_last_process) {
- ngx_last_process++;
- }
-
- return pid;
-}
-
-
-ngx_pid_t
-ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx)
-{
- return ngx_spawn_process(cycle, ngx_execute_proc, ctx, ctx->name,
- NGX_PROCESS_DETACHED);
-}
-
-
-static void
-ngx_execute_proc(ngx_cycle_t *cycle, void *data)
-{
- ngx_exec_ctx_t *ctx = data;
-
- if (execve(ctx->path, ctx->argv, ctx->envp) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "execve() failed while executing %s \"%s\"",
- ctx->name, ctx->path);
- }
-
- exit(1);
-}
-
-
-ngx_int_t
-ngx_init_signals(ngx_log_t *log)
-{
- ngx_signal_t *sig;
- struct sigaction sa;
-
- for (sig = signals; sig->signo != 0; sig++) {
- ngx_memzero(&sa, sizeof(struct sigaction));
- sa.sa_handler = sig->handler;
- sigemptyset(&sa.sa_mask);
- if (sigaction(sig->signo, &sa, NULL) == -1) {
-#if (NGX_VALGRIND)
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "sigaction(%s) failed, ignored", sig->signame);
-#else
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- "sigaction(%s) failed", sig->signame);
- return NGX_ERROR;
-#endif
- }
- }
-
- return NGX_OK;
-}
-
-
-void
-ngx_signal_handler(int signo)
-{
- char *action;
- ngx_int_t ignore;
- ngx_err_t err;
- ngx_signal_t *sig;
-
- ignore = 0;
-
- err = ngx_errno;
-
- for (sig = signals; sig->signo != 0; sig++) {
- if (sig->signo == signo) {
- break;
- }
- }
-
- ngx_time_sigsafe_update();
-
- action = "";
-
- switch (ngx_process) {
-
- case NGX_PROCESS_MASTER:
- case NGX_PROCESS_SINGLE:
- switch (signo) {
-
- case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
- ngx_quit = 1;
- action = ", shutting down";
- break;
-
- case ngx_signal_value(NGX_TERMINATE_SIGNAL):
- case SIGINT:
- ngx_terminate = 1;
- action = ", exiting";
- break;
-
- case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
- if (ngx_daemonized) {
- ngx_noaccept = 1;
- action = ", stop accepting connections";
- }
- break;
-
- case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
- ngx_reconfigure = 1;
- action = ", reconfiguring";
- break;
-
- case ngx_signal_value(NGX_REOPEN_SIGNAL):
- ngx_reopen = 1;
- action = ", reopening logs";
- break;
-
- case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
- if (getppid() > 1 || ngx_new_binary > 0) {
-
- /*
- * Ignore the signal in the new binary if its parent is
- * not the init process, i.e. the old binary's process
- * is still running. Or ignore the signal in the old binary's
- * process if the new binary's process is already running.
- */
-
- action = ", ignoring";
- ignore = 1;
- break;
- }
-
- ngx_change_binary = 1;
- action = ", changing binary";
- break;
-
- case SIGALRM:
- ngx_sigalrm = 1;
- break;
-
- case SIGIO:
- ngx_sigio = 1;
- break;
-
- case SIGCHLD:
- ngx_reap = 1;
- break;
- }
-
- break;
-
- case NGX_PROCESS_WORKER:
- case NGX_PROCESS_HELPER:
- switch (signo) {
-
- case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
- if (!ngx_daemonized) {
- break;
- }
- ngx_debug_quit = 1;
- case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
- ngx_quit = 1;
- action = ", shutting down";
- break;
-
- case ngx_signal_value(NGX_TERMINATE_SIGNAL):
- case SIGINT:
- ngx_terminate = 1;
- action = ", exiting";
- break;
-
- case ngx_signal_value(NGX_REOPEN_SIGNAL):
- ngx_reopen = 1;
- action = ", reopening logs";
- break;
-
- case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
- case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
- case SIGIO:
- action = ", ignoring";
- break;
- }
-
- break;
- }
-
- ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
- "signal %d (%s) received%s", signo, sig->signame, action);
-
- if (ignore) {
- ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, 0,
- "the changing binary signal is ignored: "
- "you should shutdown or terminate "
- "before either old or new binary's process");
- }
-
- if (signo == SIGCHLD) {
- ngx_process_get_status();
- }
-
- ngx_set_errno(err);
-}
-
-
-static void
-ngx_process_get_status(void)
-{
- int status;
- char *process;
- ngx_pid_t pid;
- ngx_err_t err;
- ngx_int_t i;
- ngx_uint_t one;
-
- one = 0;
-
- for ( ;; ) {
- pid = waitpid(-1, &status, WNOHANG);
-
- if (pid == 0) {
- return;
- }
-
- if (pid == -1) {
- err = ngx_errno;
-
- if (err == NGX_EINTR) {
- continue;
- }
-
- if (err == NGX_ECHILD && one) {
- return;
- }
-
- /*
- * Solaris always calls the signal handler for each exited process
- * despite waitpid() may be already called for this process.
- *
- * When several processes exit at the same time FreeBSD may
- * erroneously call the signal handler for exited process
- * despite waitpid() may be already called for this process.
- */
-
- if (err == NGX_ECHILD) {
- ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, err,
- "waitpid() failed");
- return;
- }
-
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err,
- "waitpid() failed");
- return;
- }
-
-
- one = 1;
- process = "unknown process";
-
- for (i = 0; i < ngx_last_process; i++) {
- if (ngx_processes[i].pid == pid) {
- ngx_processes[i].status = status;
- ngx_processes[i].exited = 1;
- process = ngx_processes[i].name;
- break;
- }
- }
-
- if (WTERMSIG(status)) {
-#ifdef WCOREDUMP
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
- "%s %P exited on signal %d%s",
- process, pid, WTERMSIG(status),
- WCOREDUMP(status) ? " (core dumped)" : "");
-#else
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
- "%s %P exited on signal %d",
- process, pid, WTERMSIG(status));
-#endif
-
- } else {
- ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
- "%s %P exited with code %d",
- process, pid, WEXITSTATUS(status));
- }
-
- if (WEXITSTATUS(status) == 2 && ngx_processes[i].respawn) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
- "%s %P exited with fatal code %d "
- "and cannot be respawned",
- process, pid, WEXITSTATUS(status));
- ngx_processes[i].respawn = 0;
- }
-
- ngx_unlock_mutexes(pid);
- }
-}
-
-
-static void
-ngx_unlock_mutexes(ngx_pid_t pid)
-{
- ngx_uint_t i;
- ngx_shm_zone_t *shm_zone;
- ngx_list_part_t *part;
- ngx_slab_pool_t *sp;
-
- /*
- * unlock the accept mutex if the abnormally exited process
- * held it
- */
-
- if (ngx_accept_mutex_ptr) {
- (void) ngx_shmtx_force_unlock(&ngx_accept_mutex, pid);
- }
-
- /*
- * unlock shared memory mutexes if held by the abnormally exited
- * process
- */
-
- part = (ngx_list_part_t *) &ngx_cycle->shared_memory.part;
- shm_zone = part->elts;
-
- for (i = 0; /* void */ ; i++) {
-
- if (i >= part->nelts) {
- if (part->next == NULL) {
- break;
- }
- part = part->next;
- shm_zone = part->elts;
- i = 0;
- }
-
- sp = (ngx_slab_pool_t *) shm_zone[i].shm.addr;
-
- if (ngx_shmtx_force_unlock(&sp->mutex, pid)) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
- "shared memory zone \"%V\" was locked by %P",
- &shm_zone[i].shm.name, pid);
- }
- }
-}
-
-
-void
-ngx_debug_point(void)
-{
- ngx_core_conf_t *ccf;
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
- ngx_core_module);
-
- switch (ccf->debug_points) {
-
- case NGX_DEBUG_POINTS_STOP:
- raise(SIGSTOP);
- break;
-
- case NGX_DEBUG_POINTS_ABORT:
- ngx_abort();
- }
-}
-
-
-ngx_int_t
-ngx_os_signal_process(ngx_cycle_t *cycle, char *name, ngx_int_t pid)
-{
- ngx_signal_t *sig;
-
- for (sig = signals; sig->signo != 0; sig++) {
- if (ngx_strcmp(name, sig->name) == 0) {
- if (kill(pid, sig->signo) != -1) {
- return 0;
- }
-
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "kill(%P, %d) failed", pid, sig->signo);
- }
- }
-
- return 1;
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_process.h b/usr.sbin/nginx/src/os/unix/ngx_process.h
deleted file mode 100644
index 14f7b89cd95..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_process.h
+++ /dev/null
@@ -1,89 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_PROCESS_H_INCLUDED_
-#define _NGX_PROCESS_H_INCLUDED_
-
-
-#include <ngx_setaffinity.h>
-#include <ngx_setproctitle.h>
-
-
-typedef pid_t ngx_pid_t;
-
-#define NGX_INVALID_PID -1
-
-typedef void (*ngx_spawn_proc_pt) (ngx_cycle_t *cycle, void *data);
-
-typedef struct {
- ngx_pid_t pid;
- int status;
- ngx_socket_t channel[2];
-
- ngx_spawn_proc_pt proc;
- void *data;
- char *name;
-
- unsigned respawn:1;
- unsigned just_spawn:1;
- unsigned detached:1;
- unsigned exiting:1;
- unsigned exited:1;
-} ngx_process_t;
-
-
-typedef struct {
- char *path;
- char *name;
- char *const *argv;
- char *const *envp;
-} ngx_exec_ctx_t;
-
-
-#define NGX_MAX_PROCESSES 1024
-
-#define NGX_PROCESS_NORESPAWN -1
-#define NGX_PROCESS_JUST_SPAWN -2
-#define NGX_PROCESS_RESPAWN -3
-#define NGX_PROCESS_JUST_RESPAWN -4
-#define NGX_PROCESS_DETACHED -5
-
-
-#define ngx_getpid getpid
-
-#ifndef ngx_log_pid
-#define ngx_log_pid ngx_pid
-#endif
-
-
-ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle,
- ngx_spawn_proc_pt proc, void *data, char *name, ngx_int_t respawn);
-ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx);
-ngx_int_t ngx_init_signals(ngx_log_t *log);
-void ngx_debug_point(void);
-
-
-#if (NGX_HAVE_SCHED_YIELD)
-#define ngx_sched_yield() sched_yield()
-#else
-#define ngx_sched_yield() usleep(1)
-#endif
-
-
-extern int ngx_argc;
-extern char **ngx_argv;
-extern char **ngx_os_argv;
-extern u_char *ngx_prefix;
-
-extern ngx_pid_t ngx_pid;
-extern ngx_socket_t ngx_channel;
-extern ngx_int_t ngx_process_slot;
-extern ngx_int_t ngx_last_process;
-extern ngx_process_t ngx_processes[NGX_MAX_PROCESSES];
-
-
-#endif /* _NGX_PROCESS_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_process_cycle.c b/usr.sbin/nginx/src/os/unix/ngx_process_cycle.c
deleted file mode 100644
index 078b1251e90..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_process_cycle.c
+++ /dev/null
@@ -1,1459 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-#include <ngx_channel.h>
-
-
-static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n,
- ngx_int_t type);
-static void ngx_start_cache_manager_processes(ngx_cycle_t *cycle,
- ngx_uint_t respawn);
-static void ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch);
-static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo);
-static ngx_uint_t ngx_reap_children(ngx_cycle_t *cycle);
-static void ngx_master_process_exit(ngx_cycle_t *cycle);
-static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data);
-static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker);
-static void ngx_worker_process_exit(ngx_cycle_t *cycle);
-static void ngx_channel_handler(ngx_event_t *ev);
-#if (NGX_THREADS)
-static void ngx_wakeup_worker_threads(ngx_cycle_t *cycle);
-static ngx_thread_value_t ngx_worker_thread_cycle(void *data);
-#endif
-static void ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data);
-static void ngx_cache_manager_process_handler(ngx_event_t *ev);
-static void ngx_cache_loader_process_handler(ngx_event_t *ev);
-
-
-ngx_uint_t ngx_process;
-ngx_pid_t ngx_pid;
-ngx_uint_t ngx_threaded;
-
-sig_atomic_t ngx_reap;
-sig_atomic_t ngx_sigio;
-sig_atomic_t ngx_sigalrm;
-sig_atomic_t ngx_terminate;
-sig_atomic_t ngx_quit;
-sig_atomic_t ngx_debug_quit;
-ngx_uint_t ngx_exiting;
-sig_atomic_t ngx_reconfigure;
-sig_atomic_t ngx_reopen;
-
-sig_atomic_t ngx_change_binary;
-ngx_pid_t ngx_new_binary;
-ngx_uint_t ngx_inherited;
-ngx_uint_t ngx_chrooted = 1;
-ngx_uint_t ngx_daemonized;
-
-sig_atomic_t ngx_noaccept;
-ngx_uint_t ngx_noaccepting;
-ngx_uint_t ngx_restart;
-
-
-#if (NGX_THREADS)
-volatile ngx_thread_t ngx_threads[NGX_MAX_THREADS];
-ngx_int_t ngx_threads_n;
-#endif
-
-
-static u_char master_process[] = "master process";
-
-
-static ngx_cache_manager_ctx_t ngx_cache_manager_ctx = {
- ngx_cache_manager_process_handler, "cache manager process", 0
-};
-
-static ngx_cache_manager_ctx_t ngx_cache_loader_ctx = {
- ngx_cache_loader_process_handler, "cache loader process", 60000
-};
-
-
-static ngx_cycle_t ngx_exit_cycle;
-static ngx_log_t ngx_exit_log;
-static ngx_open_file_t ngx_exit_log_file;
-
-
-void
-ngx_master_process_cycle(ngx_cycle_t *cycle)
-{
- char *title;
- u_char *p;
- size_t size;
- ngx_int_t i;
- ngx_uint_t n, sigio;
- sigset_t set;
- struct itimerval itv;
- ngx_uint_t live;
- ngx_msec_t delay;
- ngx_listening_t *ls;
- ngx_core_conf_t *ccf;
-
- sigemptyset(&set);
- sigaddset(&set, SIGCHLD);
- sigaddset(&set, SIGALRM);
- sigaddset(&set, SIGIO);
- sigaddset(&set, SIGINT);
- sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
- sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
- sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
- sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
- sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
- sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));
-
- if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "sigprocmask() failed");
- }
-
- sigemptyset(&set);
-
-
- size = sizeof(master_process);
-
- for (i = 0; i < ngx_argc; i++) {
- size += ngx_strlen(ngx_argv[i]) + 1;
- }
-
- title = ngx_pnalloc(cycle->pool, size);
-
- p = ngx_cpymem(title, master_process, sizeof(master_process) - 1);
- for (i = 0; i < ngx_argc; i++) {
- *p++ = ' ';
- p = ngx_cpystrn(p, (u_char *) ngx_argv[i], size);
- }
-
- ngx_setproctitle(title);
-
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-
- ngx_start_worker_processes(cycle, ccf->worker_processes,
- NGX_PROCESS_RESPAWN);
- ngx_start_cache_manager_processes(cycle, 0);
-
- ngx_new_binary = 0;
- delay = 0;
- sigio = 0;
- live = 1;
-
- for ( ;; ) {
- if (delay) {
- if (ngx_sigalrm) {
- sigio = 0;
- delay *= 2;
- ngx_sigalrm = 0;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "termination cycle: %d", delay);
-
- itv.it_interval.tv_sec = 0;
- itv.it_interval.tv_usec = 0;
- itv.it_value.tv_sec = delay / 1000;
- itv.it_value.tv_usec = (delay % 1000 ) * 1000;
-
- if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "setitimer() failed");
- }
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "sigsuspend");
-
- sigsuspend(&set);
-
- ngx_time_update();
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "wake up, sigio %i", sigio);
-
- if (ngx_reap) {
- ngx_reap = 0;
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");
-
- live = ngx_reap_children(cycle);
- }
-
- if (!live && (ngx_terminate || ngx_quit)) {
- ngx_master_process_exit(cycle);
- }
-
- if (ngx_terminate) {
- if (delay == 0) {
- delay = 50;
- }
-
- if (sigio) {
- sigio--;
- continue;
- }
-
- sigio = ccf->worker_processes + 2 /* cache processes */;
-
- if (delay > 1000) {
- ngx_signal_worker_processes(cycle, SIGKILL);
- } else {
- ngx_signal_worker_processes(cycle,
- ngx_signal_value(NGX_TERMINATE_SIGNAL));
- }
-
- continue;
- }
-
- if (ngx_quit) {
- ngx_signal_worker_processes(cycle,
- ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
-
- ls = cycle->listening.elts;
- for (n = 0; n < cycle->listening.nelts; n++) {
- if (ngx_close_socket(ls[n].fd) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
- ngx_close_socket_n " %V failed",
- &ls[n].addr_text);
- }
- }
- cycle->listening.nelts = 0;
-
- continue;
- }
-
- if (ngx_reconfigure) {
- ngx_reconfigure = 0;
-
- if (ngx_new_binary) {
- ngx_start_worker_processes(cycle, ccf->worker_processes,
- NGX_PROCESS_RESPAWN);
- ngx_start_cache_manager_processes(cycle, 0);
- ngx_noaccepting = 0;
-
- continue;
- }
-
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");
-
- cycle = ngx_init_cycle(cycle);
- if (cycle == NULL) {
- cycle = (ngx_cycle_t *) ngx_cycle;
- continue;
- }
-
- ngx_cycle = cycle;
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
- ngx_core_module);
- ngx_start_worker_processes(cycle, ccf->worker_processes,
- NGX_PROCESS_JUST_RESPAWN);
- ngx_start_cache_manager_processes(cycle, 1);
-
- /* allow new processes to start */
- ngx_msleep(100);
-
- live = 1;
- ngx_signal_worker_processes(cycle,
- ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
- }
-
- if (ngx_restart) {
- ngx_restart = 0;
- ngx_start_worker_processes(cycle, ccf->worker_processes,
- NGX_PROCESS_RESPAWN);
- ngx_start_cache_manager_processes(cycle, 0);
- live = 1;
- }
-
- if (ngx_reopen) {
- ngx_reopen = 0;
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
- ngx_reopen_files(cycle, ccf->user);
- ngx_signal_worker_processes(cycle,
- ngx_signal_value(NGX_REOPEN_SIGNAL));
- }
-
- if (ngx_change_binary) {
- ngx_change_binary = 0;
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "changing binary");
- ngx_new_binary = ngx_exec_new_binary(cycle, ngx_argv);
- }
-
- if (ngx_noaccept) {
- ngx_noaccept = 0;
- ngx_noaccepting = 1;
- ngx_signal_worker_processes(cycle,
- ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
- }
- }
-}
-
-
-void
-ngx_single_process_cycle(ngx_cycle_t *cycle)
-{
- ngx_uint_t i;
-
- if (ngx_set_environment(cycle, NULL) == NULL) {
- /* fatal */
- exit(2);
- }
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->init_process) {
- if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
- /* fatal */
- exit(2);
- }
- }
- }
-
- for ( ;; ) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
-
- ngx_process_events_and_timers(cycle);
-
- if (ngx_terminate || ngx_quit) {
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->exit_process) {
- ngx_modules[i]->exit_process(cycle);
- }
- }
-
- ngx_master_process_exit(cycle);
- }
-
- if (ngx_reconfigure) {
- ngx_reconfigure = 0;
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");
-
- cycle = ngx_init_cycle(cycle);
- if (cycle == NULL) {
- cycle = (ngx_cycle_t *) ngx_cycle;
- continue;
- }
-
- ngx_cycle = cycle;
- }
-
- if (ngx_reopen) {
- ngx_reopen = 0;
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
- ngx_reopen_files(cycle, (ngx_uid_t) -1);
- }
- }
-}
-
-
-static void
-ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
-{
- ngx_int_t i;
- ngx_channel_t ch;
-
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
-
- ngx_memzero(&ch, sizeof(ngx_channel_t));
-
- ch.command = NGX_CMD_OPEN_CHANNEL;
-
- for (i = 0; i < n; i++) {
-
- ngx_spawn_process(cycle, ngx_worker_process_cycle,
- (void *) (intptr_t) i, "worker process", type);
-
- ch.pid = ngx_processes[ngx_process_slot].pid;
- ch.slot = ngx_process_slot;
- ch.fd = ngx_processes[ngx_process_slot].channel[0];
-
- ngx_pass_open_channel(cycle, &ch);
- }
-}
-
-
-static void
-ngx_start_cache_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn)
-{
- ngx_uint_t i, manager, loader;
- ngx_path_t **path;
- ngx_channel_t ch;
-
- manager = 0;
- loader = 0;
-
- path = ngx_cycle->paths.elts;
- for (i = 0; i < ngx_cycle->paths.nelts; i++) {
-
- if (path[i]->manager) {
- manager = 1;
- }
-
- if (path[i]->loader) {
- loader = 1;
- }
- }
-
- if (manager == 0) {
- return;
- }
-
- ngx_spawn_process(cycle, ngx_cache_manager_process_cycle,
- &ngx_cache_manager_ctx, "cache manager process",
- respawn ? NGX_PROCESS_JUST_RESPAWN : NGX_PROCESS_RESPAWN);
-
- ngx_memzero(&ch, sizeof(ngx_channel_t));
-
- ch.command = NGX_CMD_OPEN_CHANNEL;
- ch.pid = ngx_processes[ngx_process_slot].pid;
- ch.slot = ngx_process_slot;
- ch.fd = ngx_processes[ngx_process_slot].channel[0];
-
- ngx_pass_open_channel(cycle, &ch);
-
- if (loader == 0) {
- return;
- }
-
- ngx_spawn_process(cycle, ngx_cache_manager_process_cycle,
- &ngx_cache_loader_ctx, "cache loader process",
- respawn ? NGX_PROCESS_JUST_SPAWN : NGX_PROCESS_NORESPAWN);
-
- ch.command = NGX_CMD_OPEN_CHANNEL;
- ch.pid = ngx_processes[ngx_process_slot].pid;
- ch.slot = ngx_process_slot;
- ch.fd = ngx_processes[ngx_process_slot].channel[0];
-
- ngx_pass_open_channel(cycle, &ch);
-}
-
-
-static void
-ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch)
-{
- ngx_int_t i;
-
- for (i = 0; i < ngx_last_process; i++) {
-
- if (i == ngx_process_slot
- || ngx_processes[i].pid == -1
- || ngx_processes[i].channel[0] == -1)
- {
- continue;
- }
-
- ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0,
- "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d",
- ch->slot, ch->pid, ch->fd,
- i, ngx_processes[i].pid,
- ngx_processes[i].channel[0]);
-
- /* TODO: NGX_AGAIN */
-
- ngx_write_channel(ngx_processes[i].channel[0],
- ch, sizeof(ngx_channel_t), cycle->log);
- }
-}
-
-
-static void
-ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo)
-{
- ngx_int_t i;
- ngx_err_t err;
- ngx_channel_t ch;
-
- ngx_memzero(&ch, sizeof(ngx_channel_t));
-
-#if (NGX_BROKEN_SCM_RIGHTS)
-
- ch.command = 0;
-
-#else
-
- switch (signo) {
-
- case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
- ch.command = NGX_CMD_QUIT;
- break;
-
- case ngx_signal_value(NGX_TERMINATE_SIGNAL):
- ch.command = NGX_CMD_TERMINATE;
- break;
-
- case ngx_signal_value(NGX_REOPEN_SIGNAL):
- ch.command = NGX_CMD_REOPEN;
- break;
-
- default:
- ch.command = 0;
- }
-
-#endif
-
- ch.fd = -1;
-
-
- for (i = 0; i < ngx_last_process; i++) {
-
- ngx_log_debug7(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "child: %d %P e:%d t:%d d:%d r:%d j:%d",
- i,
- ngx_processes[i].pid,
- ngx_processes[i].exiting,
- ngx_processes[i].exited,
- ngx_processes[i].detached,
- ngx_processes[i].respawn,
- ngx_processes[i].just_spawn);
-
- if (ngx_processes[i].detached || ngx_processes[i].pid == -1) {
- continue;
- }
-
- if (ngx_processes[i].just_spawn) {
- ngx_processes[i].just_spawn = 0;
- continue;
- }
-
- if (ngx_processes[i].exiting
- && signo == ngx_signal_value(NGX_SHUTDOWN_SIGNAL))
- {
- continue;
- }
-
- if (ch.command) {
- if (ngx_write_channel(ngx_processes[i].channel[0],
- &ch, sizeof(ngx_channel_t), cycle->log)
- == NGX_OK)
- {
- if (signo != ngx_signal_value(NGX_REOPEN_SIGNAL)) {
- ngx_processes[i].exiting = 1;
- }
-
- continue;
- }
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
- "kill (%P, %d)", ngx_processes[i].pid, signo);
-
- if (kill(ngx_processes[i].pid, signo) == -1) {
- err = ngx_errno;
- ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
- "kill(%P, %d) failed", ngx_processes[i].pid, signo);
-
- if (err == NGX_ESRCH) {
- ngx_processes[i].exited = 1;
- ngx_processes[i].exiting = 0;
- ngx_reap = 1;
- }
-
- continue;
- }
-
- if (signo != ngx_signal_value(NGX_REOPEN_SIGNAL)) {
- ngx_processes[i].exiting = 1;
- }
- }
-}
-
-
-static ngx_uint_t
-ngx_reap_children(ngx_cycle_t *cycle)
-{
- ngx_int_t i, n;
- ngx_uint_t live;
- ngx_channel_t ch;
- ngx_core_conf_t *ccf;
-
- ngx_memzero(&ch, sizeof(ngx_channel_t));
-
- ch.command = NGX_CMD_CLOSE_CHANNEL;
- ch.fd = -1;
-
- live = 0;
- for (i = 0; i < ngx_last_process; i++) {
-
- ngx_log_debug7(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "child: %d %P e:%d t:%d d:%d r:%d j:%d",
- i,
- ngx_processes[i].pid,
- ngx_processes[i].exiting,
- ngx_processes[i].exited,
- ngx_processes[i].detached,
- ngx_processes[i].respawn,
- ngx_processes[i].just_spawn);
-
- if (ngx_processes[i].pid == -1) {
- continue;
- }
-
- if (ngx_processes[i].exited) {
-
- if (!ngx_processes[i].detached) {
- ngx_close_channel(ngx_processes[i].channel, cycle->log);
-
- ngx_processes[i].channel[0] = -1;
- ngx_processes[i].channel[1] = -1;
-
- ch.pid = ngx_processes[i].pid;
- ch.slot = i;
-
- for (n = 0; n < ngx_last_process; n++) {
- if (ngx_processes[n].exited
- || ngx_processes[n].pid == -1
- || ngx_processes[n].channel[0] == -1)
- {
- continue;
- }
-
- ngx_log_debug3(NGX_LOG_DEBUG_CORE, cycle->log, 0,
- "pass close channel s:%i pid:%P to:%P",
- ch.slot, ch.pid, ngx_processes[n].pid);
-
- /* TODO: NGX_AGAIN */
-
- ngx_write_channel(ngx_processes[n].channel[0],
- &ch, sizeof(ngx_channel_t), cycle->log);
- }
- }
-
- if (ngx_processes[i].respawn
- && !ngx_processes[i].exiting
- && !ngx_terminate
- && !ngx_quit)
- {
- if (ngx_spawn_process(cycle, ngx_processes[i].proc,
- ngx_processes[i].data,
- ngx_processes[i].name, i)
- == NGX_INVALID_PID)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "could not respawn %s",
- ngx_processes[i].name);
- continue;
- }
-
-
- ch.command = NGX_CMD_OPEN_CHANNEL;
- ch.pid = ngx_processes[ngx_process_slot].pid;
- ch.slot = ngx_process_slot;
- ch.fd = ngx_processes[ngx_process_slot].channel[0];
-
- ngx_pass_open_channel(cycle, &ch);
-
- live = 1;
-
- continue;
- }
-
- if (ngx_processes[i].pid == ngx_new_binary) {
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
- ngx_core_module);
-
- if (ngx_rename_file((char *) ccf->oldpid.data,
- (char *) ccf->pid.data)
- == NGX_FILE_ERROR)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- ngx_rename_file_n " %s back to %s failed "
- "after the new binary process \"%s\" exited",
- ccf->oldpid.data, ccf->pid.data, ngx_argv[0]);
- }
-
- ngx_new_binary = 0;
- if (ngx_noaccepting) {
- ngx_restart = 1;
- ngx_noaccepting = 0;
- }
- }
-
- if (i == ngx_last_process - 1) {
- ngx_last_process--;
-
- } else {
- ngx_processes[i].pid = -1;
- }
-
- } else if (ngx_processes[i].exiting || !ngx_processes[i].detached) {
- live = 1;
- }
- }
-
- return live;
-}
-
-
-static void
-ngx_master_process_exit(ngx_cycle_t *cycle)
-{
- ngx_uint_t i;
-
- ngx_delete_pidfile(cycle);
-
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exit");
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->exit_master) {
- ngx_modules[i]->exit_master(cycle);
- }
- }
-
- ngx_close_listening_sockets(cycle);
-
- /*
- * Copy ngx_cycle->log related data to the special static exit cycle,
- * log, and log file structures enough to allow a signal handler to log.
- * The handler may be called when standard ngx_cycle->log allocated from
- * ngx_cycle->pool is already destroyed.
- */
-
-
- ngx_exit_log = *ngx_log_get_file_log(ngx_cycle->log);
-
- ngx_exit_log_file.fd = ngx_exit_log.file->fd;
- ngx_exit_log.file = &ngx_exit_log_file;
- ngx_exit_log.next = NULL;
- ngx_exit_log.writer = NULL;
-
- ngx_exit_cycle.log = &ngx_exit_log;
- ngx_exit_cycle.files = ngx_cycle->files;
- ngx_exit_cycle.files_n = ngx_cycle->files_n;
- ngx_cycle = &ngx_exit_cycle;
-
- ngx_destroy_pool(cycle->pool);
-
- exit(0);
-}
-
-
-static void
-ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
-{
- ngx_int_t worker = (intptr_t) data;
-
- ngx_uint_t i;
- ngx_connection_t *c;
-
- ngx_process = NGX_PROCESS_WORKER;
-
- ngx_worker_process_init(cycle, worker);
-
- ngx_setproctitle("worker process");
-
-#if (NGX_THREADS)
- {
- ngx_int_t n;
- ngx_err_t err;
- ngx_core_conf_t *ccf;
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-
- if (ngx_threads_n) {
- if (ngx_init_threads(ngx_threads_n, ccf->thread_stack_size, cycle)
- == NGX_ERROR)
- {
- /* fatal */
- exit(2);
- }
-
- err = ngx_thread_key_create(&ngx_core_tls_key);
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
- ngx_thread_key_create_n " failed");
- /* fatal */
- exit(2);
- }
-
- for (n = 0; n < ngx_threads_n; n++) {
-
- ngx_threads[n].cv = ngx_cond_init(cycle->log);
-
- if (ngx_threads[n].cv == NULL) {
- /* fatal */
- exit(2);
- }
-
- if (ngx_create_thread((ngx_tid_t *) &ngx_threads[n].tid,
- ngx_worker_thread_cycle,
- (void *) &ngx_threads[n], cycle->log)
- != 0)
- {
- /* fatal */
- exit(2);
- }
- }
- }
- }
-#endif
-
- for ( ;; ) {
-
- if (ngx_exiting) {
-
- c = cycle->connections;
-
- for (i = 0; i < cycle->connection_n; i++) {
-
- /* THREAD: lock */
-
- if (c[i].fd != -1 && c[i].idle) {
- c[i].close = 1;
- c[i].read->handler(c[i].read);
- }
- }
-
- if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel)
- {
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
-
- ngx_worker_process_exit(cycle);
- }
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle");
-
- ngx_process_events_and_timers(cycle);
-
- if (ngx_terminate) {
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
-
- ngx_worker_process_exit(cycle);
- }
-
- if (ngx_quit) {
- ngx_quit = 0;
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
- "gracefully shutting down");
- ngx_setproctitle("worker process is shutting down");
-
- if (!ngx_exiting) {
- ngx_close_listening_sockets(cycle);
- ngx_exiting = 1;
- }
- }
-
- if (ngx_reopen) {
- ngx_reopen = 0;
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
- ngx_reopen_files(cycle, -1);
- }
- }
-}
-
-
-static void
-ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
-{
- sigset_t set;
- uint64_t cpu_affinity;
- ngx_int_t n;
- ngx_uint_t i;
- struct passwd *pw;
- struct stat stb;
- struct rlimit rlmt;
- ngx_core_conf_t *ccf;
- ngx_listening_t *ls;
-
- if (ngx_set_environment(cycle, NULL) == NULL) {
- /* fatal */
- exit(2);
- }
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
-
- if (worker >= 0 && ccf->priority != 0) {
- if (setpriority(PRIO_PROCESS, 0, ccf->priority) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "setpriority(%d) failed", ccf->priority);
- }
- }
-
- if (ccf->rlimit_nofile != NGX_CONF_UNSET) {
- rlmt.rlim_cur = (rlim_t) ccf->rlimit_nofile;
- rlmt.rlim_max = (rlim_t) ccf->rlimit_nofile;
-
- if (setrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "setrlimit(RLIMIT_NOFILE, %i) failed",
- ccf->rlimit_nofile);
- }
- }
-
- if (ccf->rlimit_core != NGX_CONF_UNSET) {
- rlmt.rlim_cur = (rlim_t) ccf->rlimit_core;
- rlmt.rlim_max = (rlim_t) ccf->rlimit_core;
-
- if (setrlimit(RLIMIT_CORE, &rlmt) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "setrlimit(RLIMIT_CORE, %O) failed",
- ccf->rlimit_core);
- }
- }
-
-#ifdef RLIMIT_SIGPENDING
- if (ccf->rlimit_sigpending != NGX_CONF_UNSET) {
- rlmt.rlim_cur = (rlim_t) ccf->rlimit_sigpending;
- rlmt.rlim_max = (rlim_t) ccf->rlimit_sigpending;
-
- if (setrlimit(RLIMIT_SIGPENDING, &rlmt) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "setrlimit(RLIMIT_SIGPENDING, %i) failed",
- ccf->rlimit_sigpending);
- }
- }
-#endif
-
- if (geteuid() == 0) {
- char *prefix;
-
- if (!ngx_chrooted) {
- goto nochroot;
- }
-
- if ((pw = getpwnam(ccf->username)) == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "getpwnam(%s) failed", ccf->username);
- /* fatal */
- exit(2);
- }
-
- if (ngx_prefix)
- prefix = (char *)ngx_prefix;
- else
- prefix = pw->pw_dir;
-
- if (stat(prefix, &stb) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "stat(%s) failed", prefix);
- /* fatal */
- exit(2);
- }
-
- if (stb.st_uid != 0 || (stb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "bad privsep dir permissions on %s", prefix);
- /* fatal */
- exit(2);
- }
-
- if (chroot(prefix) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "chroot(%s) failed", prefix);
- /* fatal */
- exit(2);
- }
-
- if (chdir("/") == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "chdir(\"/\") failed");
- /* fatal */
- exit(2);
- }
-
-nochroot:
- if (setgid(ccf->group) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "setgid(%d) failed", ccf->group);
- /* fatal */
- exit(2);
- }
-
- if (initgroups(ccf->username, ccf->group) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "initgroups(%s, %d) failed",
- ccf->username, ccf->group);
- }
-
- if (setuid(ccf->user) == -1) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
- "setuid(%d) failed", ccf->user);
- /* fatal */
- exit(2);
- }
- }
-
- if (worker >= 0) {
- cpu_affinity = ngx_get_cpu_affinity(worker);
-
- if (cpu_affinity) {
- ngx_setaffinity(cpu_affinity, cycle->log);
- }
- }
-
-#if (NGX_HAVE_PR_SET_DUMPABLE)
-
- /* allow coredump after setuid() in Linux 2.4.x */
-
- if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "prctl(PR_SET_DUMPABLE) failed");
- }
-
-#endif
-
- if (ccf->working_directory.len) {
- if (chdir((char *) ccf->working_directory.data) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "chdir(\"%s\") failed", ccf->working_directory.data);
- /* fatal */
- exit(2);
- }
- }
-
- sigemptyset(&set);
-
- if (sigprocmask(SIG_SETMASK, &set, NULL) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "sigprocmask() failed");
- }
-
- srandom((ngx_pid << 16) ^ ngx_time());
-
- /*
- * disable deleting previous events for the listening sockets because
- * in the worker processes there are no events at all at this point
- */
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
- ls[i].previous = NULL;
- }
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->init_process) {
- if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
- /* fatal */
- exit(2);
- }
- }
- }
-
- for (n = 0; n < ngx_last_process; n++) {
-
- if (ngx_processes[n].pid == -1) {
- continue;
- }
-
- if (n == ngx_process_slot) {
- continue;
- }
-
- if (ngx_processes[n].channel[1] == -1) {
- continue;
- }
-
- if (close(ngx_processes[n].channel[1]) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "close() channel failed");
- }
- }
-
- if (close(ngx_processes[ngx_process_slot].channel[0]) == -1) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "close() channel failed");
- }
-
-#if 0
- ngx_last_process = 0;
-#endif
-
- if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT,
- ngx_channel_handler)
- == NGX_ERROR)
- {
- /* fatal */
- exit(2);
- }
-}
-
-
-static void
-ngx_worker_process_exit(ngx_cycle_t *cycle)
-{
- ngx_uint_t i;
- ngx_connection_t *c;
-
-#if (NGX_THREADS)
- ngx_terminate = 1;
-
- ngx_wakeup_worker_threads(cycle);
-#endif
-
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->exit_process) {
- ngx_modules[i]->exit_process(cycle);
- }
- }
-
- if (ngx_exiting) {
- c = cycle->connections;
- for (i = 0; i < cycle->connection_n; i++) {
- if (c[i].fd != -1
- && c[i].read
- && !c[i].read->accept
- && !c[i].read->channel
- && !c[i].read->resolver)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "*%uA open socket #%d left in connection %ui",
- c[i].number, c[i].fd, i);
- ngx_debug_quit = 1;
- }
- }
-
- if (ngx_debug_quit) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "aborting");
- ngx_debug_point();
- }
- }
-
- /*
- * Copy ngx_cycle->log related data to the special static exit cycle,
- * log, and log file structures enough to allow a signal handler to log.
- * The handler may be called when standard ngx_cycle->log allocated from
- * ngx_cycle->pool is already destroyed.
- */
-
- ngx_exit_log = *ngx_log_get_file_log(ngx_cycle->log);
-
- ngx_exit_log_file.fd = ngx_exit_log.file->fd;
- ngx_exit_log.file = &ngx_exit_log_file;
- ngx_exit_log.next = NULL;
- ngx_exit_log.writer = NULL;
-
- ngx_exit_cycle.log = &ngx_exit_log;
- ngx_exit_cycle.files = ngx_cycle->files;
- ngx_exit_cycle.files_n = ngx_cycle->files_n;
- ngx_cycle = &ngx_exit_cycle;
-
- ngx_destroy_pool(cycle->pool);
-
- ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, "exit");
-
- exit(0);
-}
-
-
-static void
-ngx_channel_handler(ngx_event_t *ev)
-{
- ngx_int_t n;
- ngx_channel_t ch;
- ngx_connection_t *c;
-
- if (ev->timedout) {
- ev->timedout = 0;
- return;
- }
-
- c = ev->data;
-
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel handler");
-
- for ( ;; ) {
-
- n = ngx_read_channel(c->fd, &ch, sizeof(ngx_channel_t), ev->log);
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0, "channel: %i", n);
-
- if (n == NGX_ERROR) {
-
- if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
- ngx_del_conn(c, 0);
- }
-
- ngx_close_connection(c);
- return;
- }
-
- if (ngx_event_flags & NGX_USE_EVENTPORT_EVENT) {
- if (ngx_add_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR) {
- return;
- }
- }
-
- if (n == NGX_AGAIN) {
- return;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0,
- "channel command: %d", ch.command);
-
- switch (ch.command) {
-
- case NGX_CMD_QUIT:
- ngx_quit = 1;
- break;
-
- case NGX_CMD_TERMINATE:
- ngx_terminate = 1;
- break;
-
- case NGX_CMD_REOPEN:
- ngx_reopen = 1;
- break;
-
- case NGX_CMD_OPEN_CHANNEL:
-
- ngx_log_debug3(NGX_LOG_DEBUG_CORE, ev->log, 0,
- "get channel s:%i pid:%P fd:%d",
- ch.slot, ch.pid, ch.fd);
-
- ngx_processes[ch.slot].pid = ch.pid;
- ngx_processes[ch.slot].channel[0] = ch.fd;
- break;
-
- case NGX_CMD_CLOSE_CHANNEL:
-
- ngx_log_debug4(NGX_LOG_DEBUG_CORE, ev->log, 0,
- "close channel s:%i pid:%P our:%P fd:%d",
- ch.slot, ch.pid, ngx_processes[ch.slot].pid,
- ngx_processes[ch.slot].channel[0]);
-
- if (close(ngx_processes[ch.slot].channel[0]) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
- "close() channel failed");
- }
-
- ngx_processes[ch.slot].channel[0] = -1;
- break;
- }
- }
-}
-
-
-#if (NGX_THREADS)
-
-static void
-ngx_wakeup_worker_threads(ngx_cycle_t *cycle)
-{
- ngx_int_t i;
- ngx_uint_t live;
-
- for ( ;; ) {
-
- live = 0;
-
- for (i = 0; i < ngx_threads_n; i++) {
- if (ngx_threads[i].state < NGX_THREAD_EXIT) {
- if (ngx_cond_signal(ngx_threads[i].cv) == NGX_ERROR) {
- ngx_threads[i].state = NGX_THREAD_DONE;
-
- } else {
- live = 1;
- }
- }
-
- if (ngx_threads[i].state == NGX_THREAD_EXIT) {
- ngx_thread_join(ngx_threads[i].tid, NULL);
- ngx_threads[i].state = NGX_THREAD_DONE;
- }
- }
-
- if (live == 0) {
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0,
- "all worker threads are joined");
-
- /* STUB */
- ngx_done_events(cycle);
- ngx_mutex_destroy(ngx_event_timer_mutex);
- ngx_mutex_destroy(ngx_posted_events_mutex);
-
- return;
- }
-
- ngx_sched_yield();
- }
-}
-
-
-static ngx_thread_value_t
-ngx_worker_thread_cycle(void *data)
-{
- ngx_thread_t *thr = data;
-
- sigset_t set;
- ngx_err_t err;
- ngx_core_tls_t *tls;
- ngx_cycle_t *cycle;
-
- cycle = (ngx_cycle_t *) ngx_cycle;
-
- sigemptyset(&set);
- sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
- sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
- sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));
-
- err = ngx_thread_sigmask(SIG_BLOCK, &set, NULL);
- if (err) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
- ngx_thread_sigmask_n " failed");
- return (ngx_thread_value_t) 1;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
- "thread " NGX_TID_T_FMT " started", ngx_thread_self());
-
- ngx_setthrtitle("worker thread");
-
- tls = ngx_calloc(sizeof(ngx_core_tls_t), cycle->log);
- if (tls == NULL) {
- return (ngx_thread_value_t) 1;
- }
-
- err = ngx_thread_set_tls(ngx_core_tls_key, tls);
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
- ngx_thread_set_tls_n " failed");
- return (ngx_thread_value_t) 1;
- }
-
- ngx_mutex_lock(ngx_posted_events_mutex);
-
- for ( ;; ) {
- thr->state = NGX_THREAD_FREE;
-
- if (ngx_cond_wait(thr->cv, ngx_posted_events_mutex) == NGX_ERROR) {
- return (ngx_thread_value_t) 1;
- }
-
- if (ngx_terminate) {
- thr->state = NGX_THREAD_EXIT;
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
- "thread " NGX_TID_T_FMT " is done",
- ngx_thread_self());
-
- return (ngx_thread_value_t) 0;
- }
-
- thr->state = NGX_THREAD_BUSY;
-
- if (ngx_event_thread_process_posted(cycle) == NGX_ERROR) {
- return (ngx_thread_value_t) 1;
- }
-
- if (ngx_event_thread_process_posted(cycle) == NGX_ERROR) {
- return (ngx_thread_value_t) 1;
- }
-
- if (ngx_process_changes) {
- if (ngx_process_changes(cycle, 1) == NGX_ERROR) {
- return (ngx_thread_value_t) 1;
- }
- }
- }
-}
-
-#endif
-
-
-static void
-ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data)
-{
- ngx_cache_manager_ctx_t *ctx = data;
-
- void *ident[4];
- ngx_event_t ev;
-
- /*
- * Set correct process type since closing listening Unix domain socket
- * in a master process also removes the Unix domain socket file.
- */
- ngx_process = NGX_PROCESS_HELPER;
-
- ngx_close_listening_sockets(cycle);
-
- /* Set a moderate number of connections for a helper process. */
- cycle->connection_n = 512;
-
- ngx_worker_process_init(cycle, -1);
-
- ngx_memzero(&ev, sizeof(ngx_event_t));
- ev.handler = ctx->handler;
- ev.data = ident;
- ev.log = cycle->log;
- ident[3] = (void *) -1;
-
- ngx_use_accept_mutex = 0;
-
- ngx_setproctitle(ctx->name);
-
- ngx_add_timer(&ev, ctx->delay);
-
- for ( ;; ) {
-
- if (ngx_terminate || ngx_quit) {
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
- exit(0);
- }
-
- if (ngx_reopen) {
- ngx_reopen = 0;
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
- ngx_reopen_files(cycle, -1);
- }
-
- ngx_process_events_and_timers(cycle);
- }
-}
-
-
-static void
-ngx_cache_manager_process_handler(ngx_event_t *ev)
-{
- time_t next, n;
- ngx_uint_t i;
- ngx_path_t **path;
-
- next = 60 * 60;
-
- path = ngx_cycle->paths.elts;
- for (i = 0; i < ngx_cycle->paths.nelts; i++) {
-
- if (path[i]->manager) {
- n = path[i]->manager(path[i]->data);
-
- next = (n <= next) ? n : next;
-
- ngx_time_update();
- }
- }
-
- if (next == 0) {
- next = 1;
- }
-
- ngx_add_timer(ev, next * 1000);
-}
-
-
-static void
-ngx_cache_loader_process_handler(ngx_event_t *ev)
-{
- ngx_uint_t i;
- ngx_path_t **path;
- ngx_cycle_t *cycle;
-
- cycle = (ngx_cycle_t *) ngx_cycle;
-
- path = cycle->paths.elts;
- for (i = 0; i < cycle->paths.nelts; i++) {
-
- if (ngx_terminate || ngx_quit) {
- break;
- }
-
- if (path[i]->loader) {
- path[i]->loader(path[i]->data);
- ngx_time_update();
- }
- }
-
- exit(0);
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_process_cycle.h b/usr.sbin/nginx/src/os/unix/ngx_process_cycle.h
deleted file mode 100644
index d7f83171e55..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_process_cycle.h
+++ /dev/null
@@ -1,62 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_PROCESS_CYCLE_H_INCLUDED_
-#define _NGX_PROCESS_CYCLE_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#define NGX_CMD_OPEN_CHANNEL 1
-#define NGX_CMD_CLOSE_CHANNEL 2
-#define NGX_CMD_QUIT 3
-#define NGX_CMD_TERMINATE 4
-#define NGX_CMD_REOPEN 5
-
-
-#define NGX_PROCESS_SINGLE 0
-#define NGX_PROCESS_MASTER 1
-#define NGX_PROCESS_SIGNALLER 2
-#define NGX_PROCESS_WORKER 3
-#define NGX_PROCESS_HELPER 4
-
-
-typedef struct {
- ngx_event_handler_pt handler;
- char *name;
- ngx_msec_t delay;
-} ngx_cache_manager_ctx_t;
-
-
-void ngx_master_process_cycle(ngx_cycle_t *cycle);
-void ngx_single_process_cycle(ngx_cycle_t *cycle);
-
-
-extern ngx_uint_t ngx_process;
-extern ngx_pid_t ngx_pid;
-extern ngx_pid_t ngx_new_binary;
-extern ngx_uint_t ngx_inherited;
-extern ngx_uint_t ngx_chrooted;
-extern ngx_uint_t ngx_daemonized;
-extern ngx_uint_t ngx_threaded;
-extern ngx_uint_t ngx_exiting;
-
-extern sig_atomic_t ngx_reap;
-extern sig_atomic_t ngx_sigio;
-extern sig_atomic_t ngx_sigalrm;
-extern sig_atomic_t ngx_quit;
-extern sig_atomic_t ngx_debug_quit;
-extern sig_atomic_t ngx_terminate;
-extern sig_atomic_t ngx_noaccept;
-extern sig_atomic_t ngx_reconfigure;
-extern sig_atomic_t ngx_reopen;
-extern sig_atomic_t ngx_change_binary;
-
-
-#endif /* _NGX_PROCESS_CYCLE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_pthread_thread.c b/usr.sbin/nginx/src/os/unix/ngx_pthread_thread.c
deleted file mode 100644
index 1cf31c3bc2b..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_pthread_thread.c
+++ /dev/null
@@ -1,278 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-static ngx_uint_t nthreads;
-static ngx_uint_t max_threads;
-
-
-static pthread_attr_t thr_attr;
-
-
-ngx_err_t
-ngx_create_thread(ngx_tid_t *tid, ngx_thread_value_t (*func)(void *arg),
- void *arg, ngx_log_t *log)
-{
- int err;
-
- if (nthreads >= max_threads) {
- ngx_log_error(NGX_LOG_CRIT, log, 0,
- "no more than %ui threads can be created", max_threads);
- return NGX_ERROR;
- }
-
- err = pthread_create(tid, &thr_attr, func, arg);
-
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, log, err, "pthread_create() failed");
- return err;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
- "thread is created: " NGX_TID_T_FMT, *tid);
-
- nthreads++;
-
- return err;
-}
-
-
-ngx_int_t
-ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle)
-{
- int err;
-
- max_threads = n;
-
- err = pthread_attr_init(&thr_attr);
-
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
- "pthread_attr_init() failed");
- return NGX_ERROR;
- }
-
- err = pthread_attr_setstacksize(&thr_attr, size);
-
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
- "pthread_attr_setstacksize() failed");
- return NGX_ERROR;
- }
-
- ngx_threaded = 1;
-
- return NGX_OK;
-}
-
-
-ngx_mutex_t *
-ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags)
-{
- int err;
- ngx_mutex_t *m;
-
- m = ngx_alloc(sizeof(ngx_mutex_t), log);
- if (m == NULL) {
- return NULL;
- }
-
- m->log = log;
-
- err = pthread_mutex_init(&m->mutex, NULL);
-
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, m->log, err,
- "pthread_mutex_init() failed");
- return NULL;
- }
-
- return m;
-}
-
-
-void
-ngx_mutex_destroy(ngx_mutex_t *m)
-{
- int err;
-
- err = pthread_mutex_destroy(&m->mutex);
-
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, m->log, err,
- "pthread_mutex_destroy(%p) failed", m);
- }
-
- ngx_free(m);
-}
-
-
-void
-ngx_mutex_lock(ngx_mutex_t *m)
-{
- int err;
-
- if (!ngx_threaded) {
- return;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "lock mutex %p", m);
-
- err = pthread_mutex_lock(&m->mutex);
-
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, m->log, err,
- "pthread_mutex_lock(%p) failed", m);
- ngx_abort();
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m);
-
- return;
-}
-
-
-ngx_int_t
-ngx_mutex_trylock(ngx_mutex_t *m)
-{
- int err;
-
- if (!ngx_threaded) {
- return NGX_OK;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "try lock mutex %p", m);
-
- err = pthread_mutex_trylock(&m->mutex);
-
- if (err == NGX_EBUSY) {
- return NGX_AGAIN;
- }
-
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, m->log, err,
- "pthread_mutex_trylock(%p) failed", m);
- ngx_abort();
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m);
-
- return NGX_OK;
-}
-
-
-void
-ngx_mutex_unlock(ngx_mutex_t *m)
-{
- int err;
-
- if (!ngx_threaded) {
- return;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "unlock mutex %p", m);
-
- err = pthread_mutex_unlock(&m->mutex);
-
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, m->log, err,
- "pthread_mutex_unlock(%p) failed", m);
- ngx_abort();
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is unlocked", m);
-
- return;
-}
-
-
-ngx_cond_t *
-ngx_cond_init(ngx_log_t *log)
-{
- int err;
- ngx_cond_t *cv;
-
- cv = ngx_alloc(sizeof(ngx_cond_t), log);
- if (cv == NULL) {
- return NULL;
- }
-
- cv->log = log;
-
- err = pthread_cond_init(&cv->cond, NULL);
-
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, cv->log, err,
- "pthread_cond_init() failed");
- return NULL;
- }
-
- return cv;
-}
-
-
-void
-ngx_cond_destroy(ngx_cond_t *cv)
-{
- int err;
-
- err = pthread_cond_destroy(&cv->cond);
-
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, cv->log, err,
- "pthread_cond_destroy(%p) failed", cv);
- }
-
- ngx_free(cv);
-}
-
-
-ngx_int_t
-ngx_cond_wait(ngx_cond_t *cv, ngx_mutex_t *m)
-{
- int err;
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p wait", cv);
-
- err = pthread_cond_wait(&cv->cond, &m->mutex);
-
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, cv->log, err,
- "pthread_cond_wait(%p) failed", cv);
- return NGX_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p is waked up", cv);
-
- ngx_log_debug1(NGX_LOG_DEBUG_MUTEX, m->log, 0, "mutex %p is locked", m);
-
- return NGX_OK;
-}
-
-
-ngx_int_t
-ngx_cond_signal(ngx_cond_t *cv)
-{
- int err;
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p to signal", cv);
-
- err = pthread_cond_signal(&cv->cond);
-
- if (err != 0) {
- ngx_log_error(NGX_LOG_ALERT, cv->log, err,
- "pthread_cond_signal(%p) failed", cv);
- return NGX_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cv->log, 0, "cv %p is signaled", cv);
-
- return NGX_OK;
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_readv_chain.c b/usr.sbin/nginx/src/os/unix/ngx_readv_chain.c
deleted file mode 100644
index 8836c817dad..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_readv_chain.c
+++ /dev/null
@@ -1,267 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#define NGX_IOVS 16
-
-
-#if (NGX_HAVE_KQUEUE)
-
-ssize_t
-ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
-{
- u_char *prev;
- ssize_t n, size;
- ngx_err_t err;
- ngx_array_t vec;
- ngx_event_t *rev;
- struct iovec *iov, iovs[NGX_IOVS];
-
- rev = c->read;
-
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "readv: eof:%d, avail:%d, err:%d",
- rev->pending_eof, rev->available, rev->kq_errno);
-
- if (rev->available == 0) {
- if (rev->pending_eof) {
- rev->ready = 0;
- rev->eof = 1;
-
- ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
- "kevent() reported about an closed connection");
-
- if (rev->kq_errno) {
- rev->error = 1;
- ngx_set_socket_errno(rev->kq_errno);
- return NGX_ERROR;
- }
-
- return 0;
-
- } else {
- return NGX_AGAIN;
- }
- }
- }
-
- prev = NULL;
- iov = NULL;
- size = 0;
-
- vec.elts = iovs;
- vec.nelts = 0;
- vec.size = sizeof(struct iovec);
- vec.nalloc = NGX_IOVS;
- vec.pool = c->pool;
-
- /* coalesce the neighbouring bufs */
-
- while (chain) {
- if (prev == chain->buf->last) {
- iov->iov_len += chain->buf->end - chain->buf->last;
-
- } else {
- if (vec.nelts >= IOV_MAX) {
- break;
- }
-
- iov = ngx_array_push(&vec);
- if (iov == NULL) {
- return NGX_ERROR;
- }
-
- iov->iov_base = (void *) chain->buf->last;
- iov->iov_len = chain->buf->end - chain->buf->last;
- }
-
- size += chain->buf->end - chain->buf->last;
- prev = chain->buf->end;
- chain = chain->next;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "readv: %d, last:%d", vec.nelts, iov->iov_len);
-
- rev = c->read;
-
- do {
- n = readv(c->fd, (struct iovec *) vec.elts, vec.nelts);
-
- if (n >= 0) {
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
- rev->available -= n;
-
- /*
- * rev->available may be negative here because some additional
- * bytes may be received between kevent() and recv()
- */
-
- if (rev->available <= 0) {
- if (!rev->pending_eof) {
- rev->ready = 0;
- }
-
- if (rev->available < 0) {
- rev->available = 0;
- }
- }
-
- if (n == 0) {
-
- /*
- * on FreeBSD recv() may return 0 on closed socket
- * even if kqueue reported about available data
- */
-
-#if 0
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
- "readv() returned 0 while kevent() reported "
- "%d available bytes", rev->available);
-#endif
-
- rev->ready = 0;
- rev->eof = 1;
- rev->available = 0;
- }
-
- return n;
- }
-
- if (n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) {
- rev->ready = 0;
- }
-
- if (n == 0) {
- rev->eof = 1;
- }
-
- return n;
- }
-
- err = ngx_socket_errno;
-
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "readv() not ready");
- n = NGX_AGAIN;
-
- } else {
- n = ngx_connection_error(c, err, "readv() failed");
- break;
- }
-
- } while (err == NGX_EINTR);
-
- rev->ready = 0;
-
- if (n == NGX_ERROR) {
- c->read->error = 1;
- }
-
- return n;
-}
-
-#else /* ! NGX_HAVE_KQUEUE */
-
-ssize_t
-ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
-{
- u_char *prev;
- ssize_t n, size;
- ngx_err_t err;
- ngx_array_t vec;
- ngx_event_t *rev;
- struct iovec *iov, iovs[NGX_IOVS];
-
- prev = NULL;
- iov = NULL;
- size = 0;
-
- vec.elts = iovs;
- vec.nelts = 0;
- vec.size = sizeof(struct iovec);
- vec.nalloc = NGX_IOVS;
- vec.pool = c->pool;
-
- /* coalesce the neighbouring bufs */
-
- while (chain) {
- if (prev == chain->buf->last) {
- iov->iov_len += chain->buf->end - chain->buf->last;
-
- } else {
- if (vec.nelts >= IOV_MAX) {
- break;
- }
-
- iov = ngx_array_push(&vec);
- if (iov == NULL) {
- return NGX_ERROR;
- }
-
- iov->iov_base = (void *) chain->buf->last;
- iov->iov_len = chain->buf->end - chain->buf->last;
- }
-
- size += chain->buf->end - chain->buf->last;
- prev = chain->buf->end;
- chain = chain->next;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "readv: %d:%d", vec.nelts, iov->iov_len);
-
- rev = c->read;
-
- do {
- n = readv(c->fd, (struct iovec *) vec.elts, vec.nelts);
-
- if (n == 0) {
- rev->ready = 0;
- rev->eof = 1;
-
- return n;
-
- } else if (n > 0) {
-
- if (n < size && !(ngx_event_flags & NGX_USE_GREEDY_EVENT)) {
- rev->ready = 0;
- }
-
- return n;
- }
-
- err = ngx_socket_errno;
-
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "readv() not ready");
- n = NGX_AGAIN;
-
- } else {
- n = ngx_connection_error(c, err, "readv() failed");
- break;
- }
-
- } while (err == NGX_EINTR);
-
- rev->ready = 0;
-
- if (n == NGX_ERROR) {
- c->read->error = 1;
- }
-
- return n;
-}
-
-#endif /* NGX_HAVE_KQUEUE */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_recv.c b/usr.sbin/nginx/src/os/unix/ngx_recv.c
deleted file mode 100644
index 86675dfdd8f..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_recv.c
+++ /dev/null
@@ -1,183 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#if (NGX_HAVE_KQUEUE)
-
-ssize_t
-ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
-{
- ssize_t n;
- ngx_err_t err;
- ngx_event_t *rev;
-
- rev = c->read;
-
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "recv: eof:%d, avail:%d, err:%d",
- rev->pending_eof, rev->available, rev->kq_errno);
-
- if (rev->available == 0) {
- if (rev->pending_eof) {
- rev->ready = 0;
- rev->eof = 1;
-
- if (rev->kq_errno) {
- rev->error = 1;
- ngx_set_socket_errno(rev->kq_errno);
-
- return ngx_connection_error(c, rev->kq_errno,
- "kevent() reported about an closed connection");
- }
-
- return 0;
-
- } else {
- rev->ready = 0;
- return NGX_AGAIN;
- }
- }
- }
-
- do {
- n = recv(c->fd, buf, size, 0);
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "recv: fd:%d %d of %d", c->fd, n, size);
-
- if (n >= 0) {
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
- rev->available -= n;
-
- /*
- * rev->available may be negative here because some additional
- * bytes may be received between kevent() and recv()
- */
-
- if (rev->available <= 0) {
- if (!rev->pending_eof) {
- rev->ready = 0;
- }
-
- if (rev->available < 0) {
- rev->available = 0;
- }
- }
-
- if (n == 0) {
-
- /*
- * on FreeBSD recv() may return 0 on closed socket
- * even if kqueue reported about available data
- */
-
- rev->ready = 0;
- rev->eof = 1;
- rev->available = 0;
- }
-
- return n;
- }
-
- if ((size_t) n < size
- && !(ngx_event_flags & NGX_USE_GREEDY_EVENT))
- {
- rev->ready = 0;
- }
-
- if (n == 0) {
- rev->eof = 1;
- }
-
- return n;
- }
-
- err = ngx_socket_errno;
-
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "recv() not ready");
- n = NGX_AGAIN;
-
- } else {
- n = ngx_connection_error(c, err, "recv() failed");
- break;
- }
-
- } while (err == NGX_EINTR);
-
- rev->ready = 0;
-
- if (n == NGX_ERROR) {
- rev->error = 1;
- }
-
- return n;
-}
-
-#else /* ! NGX_HAVE_KQUEUE */
-
-ssize_t
-ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
-{
- ssize_t n;
- ngx_err_t err;
- ngx_event_t *rev;
-
- rev = c->read;
-
- do {
- n = recv(c->fd, buf, size, 0);
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "recv: fd:%d %d of %d", c->fd, n, size);
-
- if (n == 0) {
- rev->ready = 0;
- rev->eof = 1;
- return n;
-
- } else if (n > 0) {
-
- if ((size_t) n < size
- && !(ngx_event_flags & NGX_USE_GREEDY_EVENT))
- {
- rev->ready = 0;
- }
-
- return n;
- }
-
- err = ngx_socket_errno;
-
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "recv() not ready");
- n = NGX_AGAIN;
-
- } else {
- n = ngx_connection_error(c, err, "recv() failed");
- break;
- }
-
- } while (err == NGX_EINTR);
-
- rev->ready = 0;
-
- if (n == NGX_ERROR) {
- rev->error = 1;
- }
-
- return n;
-}
-
-#endif /* NGX_HAVE_KQUEUE */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_send.c b/usr.sbin/nginx/src/os/unix/ngx_send.c
deleted file mode 100644
index 80995ab3a50..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_send.c
+++ /dev/null
@@ -1,73 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-ssize_t
-ngx_unix_send(ngx_connection_t *c, u_char *buf, size_t size)
-{
- ssize_t n;
- ngx_err_t err;
- ngx_event_t *wev;
-
- wev = c->write;
-
-#if (NGX_HAVE_KQUEUE)
-
- if ((ngx_event_flags & NGX_USE_KQUEUE_EVENT) && wev->pending_eof) {
- (void) ngx_connection_error(c, wev->kq_errno,
- "kevent() reported about an closed connection");
- wev->error = 1;
- return NGX_ERROR;
- }
-
-#endif
-
- for ( ;; ) {
- n = send(c->fd, buf, size, 0);
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "send: fd:%d %d of %d", c->fd, n, size);
-
- if (n > 0) {
- if (n < (ssize_t) size) {
- wev->ready = 0;
- }
-
- c->sent += n;
-
- return n;
- }
-
- err = ngx_socket_errno;
-
- if (n == 0) {
- ngx_log_error(NGX_LOG_ALERT, c->log, err, "send() returned zero");
- wev->ready = 0;
- return n;
- }
-
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- wev->ready = 0;
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "send() not ready");
-
- if (err == NGX_EAGAIN) {
- return NGX_AGAIN;
- }
-
- } else {
- wev->error = 1;
- (void) ngx_connection_error(c, err, "send() failed");
- return NGX_ERROR;
- }
- }
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_setaffinity.c b/usr.sbin/nginx/src/os/unix/ngx_setaffinity.c
deleted file mode 100644
index 8f6cf35948a..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_setaffinity.c
+++ /dev/null
@@ -1,69 +0,0 @@
-
-/*
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#if (NGX_HAVE_CPUSET_SETAFFINITY)
-
-#include <sys/cpuset.h>
-
-void
-ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log)
-{
- cpuset_t mask;
- ngx_uint_t i;
-
- ngx_log_error(NGX_LOG_NOTICE, log, 0,
- "cpuset_setaffinity(0x%08Xl)", cpu_affinity);
-
- CPU_ZERO(&mask);
- i = 0;
- do {
- if (cpu_affinity & 1) {
- CPU_SET(i, &mask);
- }
- i++;
- cpu_affinity >>= 1;
- } while (cpu_affinity);
-
- if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
- sizeof(cpuset_t), &mask) == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "cpuset_setaffinity() failed");
- }
-}
-
-#elif (NGX_HAVE_SCHED_SETAFFINITY)
-
-void
-ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log)
-{
- cpu_set_t mask;
- ngx_uint_t i;
-
- ngx_log_error(NGX_LOG_NOTICE, log, 0,
- "sched_setaffinity(0x%08Xl)", cpu_affinity);
-
- CPU_ZERO(&mask);
- i = 0;
- do {
- if (cpu_affinity & 1) {
- CPU_SET(i, &mask);
- }
- i++;
- cpu_affinity >>= 1;
- } while (cpu_affinity);
-
- if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "sched_setaffinity() failed");
- }
-}
-
-#endif
diff --git a/usr.sbin/nginx/src/os/unix/ngx_setaffinity.h b/usr.sbin/nginx/src/os/unix/ngx_setaffinity.h
deleted file mode 100644
index 33f5835dee6..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_setaffinity.h
+++ /dev/null
@@ -1,23 +0,0 @@
-
-/*
- * Copyright (C) Nginx, Inc.
- */
-
-#ifndef _NGX_SETAFFINITY_H_INCLUDED_
-#define _NGX_SETAFFINITY_H_INCLUDED_
-
-
-#if (NGX_HAVE_SCHED_SETAFFINITY || NGX_HAVE_CPUSET_SETAFFINITY)
-
-#define NGX_HAVE_CPU_AFFINITY 1
-
-void ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log);
-
-#else
-
-#define ngx_setaffinity(cpu_affinity, log)
-
-#endif
-
-
-#endif /* _NGX_SETAFFINITY_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_setproctitle.c b/usr.sbin/nginx/src/os/unix/ngx_setproctitle.c
deleted file mode 100644
index 91afa519142..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_setproctitle.c
+++ /dev/null
@@ -1,135 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#if (NGX_SETPROCTITLE_USES_ENV)
-
-/*
- * To change the process title in Linux and Solaris we have to set argv[1]
- * to NULL and to copy the title to the same place where the argv[0] points to.
- * However, argv[0] may be too small to hold a new title. Fortunately, Linux
- * and Solaris store argv[] and environ[] one after another. So we should
- * ensure that is the continuous memory and then we allocate the new memory
- * for environ[] and copy it. After this we could use the memory starting
- * from argv[0] for our process title.
- *
- * The Solaris's standard /bin/ps does not show the changed process title.
- * You have to use "/usr/ucb/ps -w" instead. Besides, the UCB ps does not
- * show a new title if its length less than the origin command line length.
- * To avoid it we append to a new title the origin command line in the
- * parenthesis.
- */
-
-extern char **environ;
-
-static char *ngx_os_argv_last;
-
-ngx_int_t
-ngx_init_setproctitle(ngx_log_t *log)
-{
- u_char *p;
- size_t size;
- ngx_uint_t i;
-
- size = 0;
-
- for (i = 0; environ[i]; i++) {
- size += ngx_strlen(environ[i]) + 1;
- }
-
- p = ngx_alloc(size, log);
- if (p == NULL) {
- return NGX_ERROR;
- }
-
- ngx_os_argv_last = ngx_os_argv[0];
-
- for (i = 0; ngx_os_argv[i]; i++) {
- if (ngx_os_argv_last == ngx_os_argv[i]) {
- ngx_os_argv_last = ngx_os_argv[i] + ngx_strlen(ngx_os_argv[i]) + 1;
- }
- }
-
- for (i = 0; environ[i]; i++) {
- if (ngx_os_argv_last == environ[i]) {
-
- size = ngx_strlen(environ[i]) + 1;
- ngx_os_argv_last = environ[i] + size;
-
- ngx_cpystrn(p, (u_char *) environ[i], size);
- environ[i] = (char *) p;
- p += size;
- }
- }
-
- ngx_os_argv_last--;
-
- return NGX_OK;
-}
-
-
-void
-ngx_setproctitle(char *title)
-{
- u_char *p;
-
-#if (NGX_SOLARIS)
-
- ngx_int_t i;
- size_t size;
-
-#endif
-
- ngx_os_argv[1] = NULL;
-
- p = ngx_cpystrn((u_char *) ngx_os_argv[0], (u_char *) "nginx: ",
- ngx_os_argv_last - ngx_os_argv[0]);
-
- p = ngx_cpystrn(p, (u_char *) title, ngx_os_argv_last - (char *) p);
-
-#if (NGX_SOLARIS)
-
- size = 0;
-
- for (i = 0; i < ngx_argc; i++) {
- size += ngx_strlen(ngx_argv[i]) + 1;
- }
-
- if (size > (size_t) ((char *) p - ngx_os_argv[0])) {
-
- /*
- * ngx_setproctitle() is too rare operation so we use
- * the non-optimized copies
- */
-
- p = ngx_cpystrn(p, (u_char *) " (", ngx_os_argv_last - (char *) p);
-
- for (i = 0; i < ngx_argc; i++) {
- p = ngx_cpystrn(p, (u_char *) ngx_argv[i],
- ngx_os_argv_last - (char *) p);
- p = ngx_cpystrn(p, (u_char *) " ", ngx_os_argv_last - (char *) p);
- }
-
- if (*(p - 1) == ' ') {
- *(p - 1) = ')';
- }
- }
-
-#endif
-
- if (ngx_os_argv_last - (char *) p) {
- ngx_memset(p, NGX_SETPROCTITLE_PAD, ngx_os_argv_last - (char *) p);
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
- "setproctitle: \"%s\"", ngx_os_argv[0]);
-}
-
-#endif /* NGX_SETPROCTITLE_USES_ENV */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_setproctitle.h b/usr.sbin/nginx/src/os/unix/ngx_setproctitle.h
deleted file mode 100644
index 2323408c46e..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_setproctitle.h
+++ /dev/null
@@ -1,52 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_SETPROCTITLE_H_INCLUDED_
-#define _NGX_SETPROCTITLE_H_INCLUDED_
-
-
-#if (NGX_HAVE_SETPROCTITLE)
-
-/* FreeBSD, NetBSD, OpenBSD */
-
-#define ngx_init_setproctitle(log)
-#define ngx_setproctitle(title) setproctitle("%s", title)
-
-
-#else /* !NGX_HAVE_SETPROCTITLE */
-
-#if !defined NGX_SETPROCTITLE_USES_ENV
-
-#if (NGX_SOLARIS)
-
-#define NGX_SETPROCTITLE_USES_ENV 1
-#define NGX_SETPROCTITLE_PAD ' '
-
-ngx_int_t ngx_init_setproctitle(ngx_log_t *log);
-void ngx_setproctitle(char *title);
-
-#elif (NGX_LINUX) || (NGX_DARWIN)
-
-#define NGX_SETPROCTITLE_USES_ENV 1
-#define NGX_SETPROCTITLE_PAD '\0'
-
-ngx_int_t ngx_init_setproctitle(ngx_log_t *log);
-void ngx_setproctitle(char *title);
-
-#else
-
-#define ngx_init_setproctitle(log)
-#define ngx_setproctitle(title)
-
-#endif /* OSes */
-
-#endif /* NGX_SETPROCTITLE_USES_ENV */
-
-#endif /* NGX_HAVE_SETPROCTITLE */
-
-
-#endif /* _NGX_SETPROCTITLE_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_shmem.c b/usr.sbin/nginx/src/os/unix/ngx_shmem.c
deleted file mode 100644
index 3ec7cbf1fd3..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_shmem.c
+++ /dev/null
@@ -1,126 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-#if (NGX_HAVE_MAP_ANON)
-
-ngx_int_t
-ngx_shm_alloc(ngx_shm_t *shm)
-{
- shm->addr = (u_char *) mmap(NULL, shm->size,
- PROT_READ|PROT_WRITE,
- MAP_ANON|MAP_SHARED, -1, 0);
-
- if (shm->addr == MAP_FAILED) {
- ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
- "mmap(MAP_ANON|MAP_SHARED, %uz) failed", shm->size);
- return NGX_ERROR;
- }
-
- return NGX_OK;
-}
-
-
-void
-ngx_shm_free(ngx_shm_t *shm)
-{
- if (munmap((void *) shm->addr, shm->size) == -1) {
- ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
- "munmap(%p, %uz) failed", shm->addr, shm->size);
- }
-}
-
-#elif (NGX_HAVE_MAP_DEVZERO)
-
-ngx_int_t
-ngx_shm_alloc(ngx_shm_t *shm)
-{
- ngx_fd_t fd;
-
- fd = open("/dev/zero", O_RDWR);
-
- if (fd == -1) {
- ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
- "open(\"/dev/zero\") failed");
- return NGX_ERROR;
- }
-
- shm->addr = (u_char *) mmap(NULL, shm->size, PROT_READ|PROT_WRITE,
- MAP_SHARED, fd, 0);
-
- if (shm->addr == MAP_FAILED) {
- ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
- "mmap(/dev/zero, MAP_SHARED, %uz) failed", shm->size);
- }
-
- if (close(fd) == -1) {
- ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
- "close(\"/dev/zero\") failed");
- }
-
- return (shm->addr == MAP_FAILED) ? NGX_ERROR : NGX_OK;
-}
-
-
-void
-ngx_shm_free(ngx_shm_t *shm)
-{
- if (munmap((void *) shm->addr, shm->size) == -1) {
- ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
- "munmap(%p, %uz) failed", shm->addr, shm->size);
- }
-}
-
-#elif (NGX_HAVE_SYSVSHM)
-
-#include <sys/ipc.h>
-#include <sys/shm.h>
-
-
-ngx_int_t
-ngx_shm_alloc(ngx_shm_t *shm)
-{
- int id;
-
- id = shmget(IPC_PRIVATE, shm->size, (SHM_R|SHM_W|IPC_CREAT));
-
- if (id == -1) {
- ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
- "shmget(%uz) failed", shm->size);
- return NGX_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, shm->log, 0, "shmget id: %d", id);
-
- shm->addr = shmat(id, NULL, 0);
-
- if (shm->addr == (void *) -1) {
- ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, "shmat() failed");
- }
-
- if (shmctl(id, IPC_RMID, NULL) == -1) {
- ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
- "shmctl(IPC_RMID) failed");
- }
-
- return (shm->addr == (void *) -1) ? NGX_ERROR : NGX_OK;
-}
-
-
-void
-ngx_shm_free(ngx_shm_t *shm)
-{
- if (shmdt(shm->addr) == -1) {
- ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
- "shmdt(%p) failed", shm->addr);
- }
-}
-
-#endif
diff --git a/usr.sbin/nginx/src/os/unix/ngx_shmem.h b/usr.sbin/nginx/src/os/unix/ngx_shmem.h
deleted file mode 100644
index 566a7d3300b..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_shmem.h
+++ /dev/null
@@ -1,29 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_SHMEM_H_INCLUDED_
-#define _NGX_SHMEM_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef struct {
- u_char *addr;
- size_t size;
- ngx_str_t name;
- ngx_log_t *log;
- ngx_uint_t exists; /* unsigned exists:1; */
-} ngx_shm_t;
-
-
-ngx_int_t ngx_shm_alloc(ngx_shm_t *shm);
-void ngx_shm_free(ngx_shm_t *shm);
-
-
-#endif /* _NGX_SHMEM_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_socket.c b/usr.sbin/nginx/src/os/unix/ngx_socket.c
deleted file mode 100644
index 3978f655c04..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_socket.c
+++ /dev/null
@@ -1,116 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/*
- * ioctl(FIONBIO) sets a non-blocking mode with the single syscall
- * while fcntl(F_SETFL, O_NONBLOCK) needs to learn the current state
- * using fcntl(F_GETFL).
- *
- * ioctl() and fcntl() are syscalls at least in FreeBSD 2.x, Linux 2.2
- * and Solaris 7.
- *
- * ioctl() in Linux 2.4 and 2.6 uses BKL, however, fcntl(F_SETFL) uses it too.
- */
-
-
-#if (NGX_HAVE_FIONBIO)
-
-int
-ngx_nonblocking(ngx_socket_t s)
-{
- int nb;
-
- nb = 1;
-
- return ioctl(s, FIONBIO, &nb);
-}
-
-
-int
-ngx_blocking(ngx_socket_t s)
-{
- int nb;
-
- nb = 0;
-
- return ioctl(s, FIONBIO, &nb);
-}
-
-#endif
-
-
-#if (NGX_FREEBSD)
-
-int
-ngx_tcp_nopush(ngx_socket_t s)
-{
- int tcp_nopush;
-
- tcp_nopush = 1;
-
- return setsockopt(s, IPPROTO_TCP, TCP_NOPUSH,
- (const void *) &tcp_nopush, sizeof(int));
-}
-
-
-int
-ngx_tcp_push(ngx_socket_t s)
-{
- int tcp_nopush;
-
- tcp_nopush = 0;
-
- return setsockopt(s, IPPROTO_TCP, TCP_NOPUSH,
- (const void *) &tcp_nopush, sizeof(int));
-}
-
-#elif (NGX_LINUX)
-
-
-int
-ngx_tcp_nopush(ngx_socket_t s)
-{
- int cork;
-
- cork = 1;
-
- return setsockopt(s, IPPROTO_TCP, TCP_CORK,
- (const void *) &cork, sizeof(int));
-}
-
-
-int
-ngx_tcp_push(ngx_socket_t s)
-{
- int cork;
-
- cork = 0;
-
- return setsockopt(s, IPPROTO_TCP, TCP_CORK,
- (const void *) &cork, sizeof(int));
-}
-
-#else
-
-int
-ngx_tcp_nopush(ngx_socket_t s)
-{
- return 0;
-}
-
-
-int
-ngx_tcp_push(ngx_socket_t s)
-{
- return 0;
-}
-
-#endif
diff --git a/usr.sbin/nginx/src/os/unix/ngx_socket.h b/usr.sbin/nginx/src/os/unix/ngx_socket.h
deleted file mode 100644
index fcc51533568..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_socket.h
+++ /dev/null
@@ -1,64 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_SOCKET_H_INCLUDED_
-#define _NGX_SOCKET_H_INCLUDED_
-
-
-#include <ngx_config.h>
-
-
-#define NGX_WRITE_SHUTDOWN SHUT_WR
-
-typedef int ngx_socket_t;
-
-#define ngx_socket socket
-#define ngx_socket_n "socket()"
-
-
-#if (NGX_HAVE_FIONBIO)
-
-int ngx_nonblocking(ngx_socket_t s);
-int ngx_blocking(ngx_socket_t s);
-
-#define ngx_nonblocking_n "ioctl(FIONBIO)"
-#define ngx_blocking_n "ioctl(!FIONBIO)"
-
-#else
-
-#define ngx_nonblocking(s) fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK)
-#define ngx_nonblocking_n "fcntl(O_NONBLOCK)"
-
-#define ngx_blocking(s) fcntl(s, F_SETFL, fcntl(s, F_GETFL) & ~O_NONBLOCK)
-#define ngx_blocking_n "fcntl(!O_NONBLOCK)"
-
-#endif
-
-int ngx_tcp_nopush(ngx_socket_t s);
-int ngx_tcp_push(ngx_socket_t s);
-
-#if (NGX_LINUX)
-
-#define ngx_tcp_nopush_n "setsockopt(TCP_CORK)"
-#define ngx_tcp_push_n "setsockopt(!TCP_CORK)"
-
-#else
-
-#define ngx_tcp_nopush_n "setsockopt(TCP_NOPUSH)"
-#define ngx_tcp_push_n "setsockopt(!TCP_NOPUSH)"
-
-#endif
-
-
-#define ngx_shutdown_socket shutdown
-#define ngx_shutdown_socket_n "shutdown()"
-
-#define ngx_close_socket close
-#define ngx_close_socket_n "close() socket"
-
-
-#endif /* _NGX_SOCKET_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_solaris.h b/usr.sbin/nginx/src/os/unix/ngx_solaris.h
deleted file mode 100644
index 7b167d830ab..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_solaris.h
+++ /dev/null
@@ -1,16 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_SOLARIS_H_INCLUDED_
-#define _NGX_SOLARIS_H_INCLUDED_
-
-
-ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
-
-
-#endif /* _NGX_SOLARIS_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_solaris_config.h b/usr.sbin/nginx/src/os/unix/ngx_solaris_config.h
deleted file mode 100644
index ddfd984577e..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_solaris_config.h
+++ /dev/null
@@ -1,110 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_SOLARIS_CONFIG_H_INCLUDED_
-#define _NGX_SOLARIS_CONFIG_H_INCLUDED_
-
-
-#ifndef _REENTRANT
-#define _REENTRANT
-#endif
-
-#define _FILE_OFFSET_BITS 64 /* must be before <sys/types.h> */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <stddef.h> /* offsetof() */
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <signal.h>
-#include <pwd.h>
-#include <grp.h>
-#include <dirent.h>
-#include <glob.h>
-#include <time.h>
-#include <sys/statvfs.h> /* statvfs() */
-
-#include <sys/filio.h> /* FIONBIO */
-#include <sys/uio.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <sched.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h> /* TCP_NODELAY */
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/un.h>
-
-#include <sys/systeminfo.h>
-#include <limits.h> /* IOV_MAX */
-#include <inttypes.h>
-#include <crypt.h>
-
-#define NGX_ALIGNMENT _MAX_ALIGNMENT
-
-#include <ngx_auto_config.h>
-
-
-#if (NGX_HAVE_POSIX_SEM)
-#include <semaphore.h>
-#endif
-
-
-#if (NGX_HAVE_POLL)
-#include <poll.h>
-#endif
-
-
-#if (NGX_HAVE_DEVPOLL)
-#include <sys/ioctl.h>
-#include <sys/devpoll.h>
-#endif
-
-
-#if (NGX_HAVE_EVENTPORT)
-#include <port.h>
-#endif
-
-
-#if (NGX_HAVE_SENDFILE)
-#include <sys/sendfile.h>
-#endif
-
-
-#define NGX_LISTEN_BACKLOG 511
-
-
-#ifndef NGX_HAVE_INHERITED_NONBLOCK
-#define NGX_HAVE_INHERITED_NONBLOCK 1
-#endif
-
-
-#ifndef NGX_HAVE_SO_SNDLOWAT
-/* setsockopt(SO_SNDLOWAT) returns ENOPROTOOPT */
-#define NGX_HAVE_SO_SNDLOWAT 0
-#endif
-
-
-#define NGX_HAVE_OS_SPECIFIC_INIT 1
-#define ngx_debug_init()
-
-
-extern char **environ;
-
-
-#endif /* _NGX_SOLARIS_CONFIG_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_solaris_init.c b/usr.sbin/nginx/src/os/unix/ngx_solaris_init.c
deleted file mode 100644
index f2f3600dab1..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_solaris_init.c
+++ /dev/null
@@ -1,75 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-char ngx_solaris_sysname[20];
-char ngx_solaris_release[10];
-char ngx_solaris_version[50];
-
-
-static ngx_os_io_t ngx_solaris_io = {
- ngx_unix_recv,
- ngx_readv_chain,
- ngx_udp_unix_recv,
- ngx_unix_send,
-#if (NGX_HAVE_SENDFILE)
- ngx_solaris_sendfilev_chain,
- NGX_IO_SENDFILE
-#else
- ngx_writev_chain,
- 0
-#endif
-};
-
-
-ngx_int_t
-ngx_os_specific_init(ngx_log_t *log)
-{
- if (sysinfo(SI_SYSNAME, ngx_solaris_sysname, sizeof(ngx_solaris_sysname))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "sysinfo(SI_SYSNAME) failed");
- return NGX_ERROR;
- }
-
- if (sysinfo(SI_RELEASE, ngx_solaris_release, sizeof(ngx_solaris_release))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "sysinfo(SI_RELEASE) failed");
- return NGX_ERROR;
- }
-
- if (sysinfo(SI_VERSION, ngx_solaris_version, sizeof(ngx_solaris_version))
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
- "sysinfo(SI_SYSNAME) failed");
- return NGX_ERROR;
- }
-
-
- ngx_os_io = ngx_solaris_io;
-
- return NGX_OK;
-}
-
-
-void
-ngx_os_specific_status(ngx_log_t *log)
-{
-
- ngx_log_error(NGX_LOG_NOTICE, log, 0, "OS: %s %s",
- ngx_solaris_sysname, ngx_solaris_release);
-
- ngx_log_error(NGX_LOG_NOTICE, log, 0, "version: %s",
- ngx_solaris_version);
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c b/usr.sbin/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c
deleted file mode 100644
index 37bb09d961a..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c
+++ /dev/null
@@ -1,260 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#if (NGX_TEST_BUILD_SOLARIS_SENDFILEV)
-
-/* Solaris declarations */
-
-typedef struct sendfilevec {
- int sfv_fd;
- u_int sfv_flag;
- off_t sfv_off;
- size_t sfv_len;
-} sendfilevec_t;
-
-#define SFV_FD_SELF -2
-
-static ssize_t sendfilev(int fd, const struct sendfilevec *vec,
- int sfvcnt, size_t *xferred)
-{
- return -1;
-}
-
-ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in,
- off_t limit);
-
-#endif
-
-
-#if (IOV_MAX > 64)
-#define NGX_SENDFILEVECS 64
-#else
-#define NGX_SENDFILEVECS IOV_MAX
-#endif
-
-
-
-ngx_chain_t *
-ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
-{
- int fd;
- u_char *prev;
- off_t size, send, prev_send, aligned, fprev;
- size_t sent;
- ssize_t n;
- ngx_int_t eintr, complete;
- ngx_err_t err;
- sendfilevec_t *sfv, sfvs[NGX_SENDFILEVECS];
- ngx_array_t vec;
- ngx_event_t *wev;
- ngx_chain_t *cl;
-
- wev = c->write;
-
- if (!wev->ready) {
- return in;
- }
-
- if (!c->sendfile) {
- return ngx_writev_chain(c, in, limit);
- }
-
-
- /* the maximum limit size is the maximum size_t value - the page size */
-
- if (limit == 0 || limit > (off_t) (NGX_MAX_SIZE_T_VALUE - ngx_pagesize)) {
- limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
- }
-
-
- send = 0;
-
- vec.elts = sfvs;
- vec.size = sizeof(sendfilevec_t);
- vec.nalloc = NGX_SENDFILEVECS;
- vec.pool = c->pool;
-
- for ( ;; ) {
- fd = SFV_FD_SELF;
- prev = NULL;
- fprev = 0;
- sfv = NULL;
- eintr = 0;
- complete = 0;
- sent = 0;
- prev_send = send;
-
- vec.nelts = 0;
-
- /* create the sendfilevec and coalesce the neighbouring bufs */
-
- for (cl = in; cl && send < limit; cl = cl->next) {
-
- if (ngx_buf_special(cl->buf)) {
- continue;
- }
-
- if (ngx_buf_in_memory_only(cl->buf)) {
- fd = SFV_FD_SELF;
-
- size = cl->buf->last - cl->buf->pos;
-
- if (send + size > limit) {
- size = limit - send;
- }
-
- if (prev == cl->buf->pos) {
- sfv->sfv_len += (size_t) size;
-
- } else {
- if (vec.nelts >= IOV_MAX) {
- break;
- }
-
- sfv = ngx_array_push(&vec);
- if (sfv == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- sfv->sfv_fd = SFV_FD_SELF;
- sfv->sfv_flag = 0;
- sfv->sfv_off = (off_t) (uintptr_t) cl->buf->pos;
- sfv->sfv_len = (size_t) size;
- }
-
- prev = cl->buf->pos + (size_t) size;
- send += size;
-
- } else {
- prev = NULL;
-
- size = cl->buf->file_last - cl->buf->file_pos;
-
- if (send + size > limit) {
- size = limit - send;
-
- aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
- & ~((off_t) ngx_pagesize - 1);
-
- if (aligned <= cl->buf->file_last) {
- size = aligned - cl->buf->file_pos;
- }
- }
-
- if (fd == cl->buf->file->fd && fprev == cl->buf->file_pos) {
- sfv->sfv_len += (size_t) size;
-
- } else {
- if (vec.nelts >= IOV_MAX) {
- break;
- }
-
- sfv = ngx_array_push(&vec);
- if (sfv == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- fd = cl->buf->file->fd;
- sfv->sfv_fd = fd;
- sfv->sfv_flag = 0;
- sfv->sfv_off = cl->buf->file_pos;
- sfv->sfv_len = (size_t) size;
- }
-
- fprev = cl->buf->file_pos + size;
- send += size;
- }
- }
-
- n = sendfilev(c->fd, vec.elts, vec.nelts, &sent);
-
- if (n == -1) {
- err = ngx_errno;
-
- switch (err) {
- case NGX_EAGAIN:
- break;
-
- case NGX_EINTR:
- eintr = 1;
- break;
-
- default:
- wev->error = 1;
- ngx_connection_error(c, err, "sendfilev() failed");
- return NGX_CHAIN_ERROR;
- }
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err,
- "sendfilev() sent only %uz bytes", sent);
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "sendfilev: %z %z", n, sent);
-
- if (send - prev_send == (off_t) sent) {
- complete = 1;
- }
-
- c->sent += sent;
-
- for ( /* void */ ; in; in = in->next) {
-
- if (ngx_buf_special(in->buf)) {
- continue;
- }
-
- if (sent == 0) {
- break;
- }
-
- size = ngx_buf_size(in->buf);
-
- if ((off_t) sent >= size) {
- sent = (size_t) ((off_t) sent - size);
-
- if (ngx_buf_in_memory(in->buf)) {
- in->buf->pos = in->buf->last;
- }
-
- if (in->buf->in_file) {
- in->buf->file_pos = in->buf->file_last;
- }
-
- continue;
- }
-
- if (ngx_buf_in_memory(in->buf)) {
- in->buf->pos += sent;
- }
-
- if (in->buf->in_file) {
- in->buf->file_pos += sent;
- }
-
- break;
- }
-
- if (eintr) {
- continue;
- }
-
- if (!complete) {
- wev->ready = 0;
- return in;
- }
-
- if (send >= limit || in == NULL) {
- return in;
- }
- }
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_sunpro_amd64.il b/usr.sbin/nginx/src/os/unix/ngx_sunpro_amd64.il
deleted file mode 100644
index dc454b20b2f..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_sunpro_amd64.il
+++ /dev/null
@@ -1,43 +0,0 @@
-/
-/ Copyright (C) Igor Sysoev
-/ Copyright (C) Nginx, Inc.
-/
-
-/ ngx_atomic_uint_t ngx_atomic_cmp_set(ngx_atomic_t *lock,
-/ ngx_atomic_uint_t old, ngx_atomic_uint_t set);
-/
-/ the arguments are passed in %rdi, %rsi, %rdx
-/ the result is returned in the %rax
-
- .inline ngx_atomic_cmp_set,0
- movq %rsi, %rax
- lock
- cmpxchgq %rdx, (%rdi)
- setz %al
- movzbq %al, %rax
- .end
-
-
-/ ngx_atomic_int_t ngx_atomic_fetch_add(ngx_atomic_t *value,
-/ ngx_atomic_int_t add);
-/
-/ the arguments are passed in %rdi, %rsi
-/ the result is returned in the %rax
-
- .inline ngx_atomic_fetch_add,0
- movq %rsi, %rax
- lock
- xaddq %rax, (%rdi)
- .end
-
-
-/ ngx_cpu_pause()
-/
-/ the "rep; nop" is used instead of "pause" to avoid the "[ PAUSE ]" hardware
-/ capability added by linker because Solaris/amd64 does not know about it:
-/
-/ ld.so.1: nginx: fatal: hardware capability unsupported: 0x2000 [ PAUSE ]
-
- .inline ngx_cpu_pause,0
- rep; nop
- .end
diff --git a/usr.sbin/nginx/src/os/unix/ngx_sunpro_atomic_sparc64.h b/usr.sbin/nginx/src/os/unix/ngx_sunpro_atomic_sparc64.h
deleted file mode 100644
index 5f280553c9e..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_sunpro_atomic_sparc64.h
+++ /dev/null
@@ -1,61 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#if (NGX_PTR_SIZE == 4)
-#define NGX_CASA ngx_casa
-#else
-#define NGX_CASA ngx_casxa
-#endif
-
-
-ngx_atomic_uint_t
-ngx_casa(ngx_atomic_uint_t set, ngx_atomic_uint_t old, ngx_atomic_t *lock);
-
-ngx_atomic_uint_t
-ngx_casxa(ngx_atomic_uint_t set, ngx_atomic_uint_t old, ngx_atomic_t *lock);
-
-/* the code in src/os/unix/ngx_sunpro_sparc64.il */
-
-
-static ngx_inline ngx_atomic_uint_t
-ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
- ngx_atomic_uint_t set)
-{
- set = NGX_CASA(set, old, lock);
-
- return (set == old);
-}
-
-
-static ngx_inline ngx_atomic_int_t
-ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
-{
- ngx_atomic_uint_t old, res;
-
- old = *value;
-
- for ( ;; ) {
-
- res = old + add;
-
- res = NGX_CASA(res, old, value);
-
- if (res == old) {
- return res;
- }
-
- old = res;
- }
-}
-
-
-#define ngx_memory_barrier() \
- __asm (".volatile"); \
- __asm ("membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad"); \
- __asm (".nonvolatile")
-
-#define ngx_cpu_pause()
diff --git a/usr.sbin/nginx/src/os/unix/ngx_sunpro_sparc64.il b/usr.sbin/nginx/src/os/unix/ngx_sunpro_sparc64.il
deleted file mode 100644
index bdeef612507..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_sunpro_sparc64.il
+++ /dev/null
@@ -1,36 +0,0 @@
-/
-/ Copyright (C) Igor Sysoev
-/ Copyright (C) Nginx, Inc.
-/
-
-
-/ "casa [%o2] 0x80, %o1, %o0" and
-/ "casxa [%o2] 0x80, %o1, %o0" do the following:
-/
-/ if ([%o2] == %o1) {
-/ swap(%o0, [%o2]);
-/ } else {
-/ %o0 = [%o2];
-/ }
-
-
-/ ngx_atomic_uint_t ngx_casa(ngx_atomic_uint_t set, ngx_atomic_uint_t old,
-/ ngx_atomic_t *lock);
-/
-/ the arguments are passed in the %o0, %o1, %o2
-/ the result is returned in the %o0
-
- .inline ngx_casa,0
- casa [%o2] 0x80, %o1, %o0
- .end
-
-
-/ ngx_atomic_uint_t ngx_casxa(ngx_atomic_uint_t set, ngx_atomic_uint_t old,
-/ ngx_atomic_t *lock);
-/
-/ the arguments are passed in the %o0, %o1, %o2
-/ the result is returned in the %o0
-
- .inline ngx_casxa,0
- casxa [%o2] 0x80, %o1, %o0
- .end
diff --git a/usr.sbin/nginx/src/os/unix/ngx_sunpro_x86.il b/usr.sbin/nginx/src/os/unix/ngx_sunpro_x86.il
deleted file mode 100644
index fd1cc00492e..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_sunpro_x86.il
+++ /dev/null
@@ -1,44 +0,0 @@
-/
-/ Copyright (C) Igor Sysoev
-/ Copyright (C) Nginx, Inc.
-/
-
-/ ngx_atomic_uint_t ngx_atomic_cmp_set(ngx_atomic_t *lock,
-/ ngx_atomic_uint_t old, ngx_atomic_uint_t set);
-/
-/ the arguments are passed on stack (%esp), 4(%esp), 8(%esp)
-
- .inline ngx_atomic_cmp_set,0
- movl (%esp), %ecx
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- lock
- cmpxchgl %edx, (%ecx)
- setz %al
- movzbl %al, %eax
- .end
-
-
-/ ngx_atomic_int_t ngx_atomic_fetch_add(ngx_atomic_t *value,
-/ ngx_atomic_int_t add);
-/
-/ the arguments are passed on stack (%esp), 4(%esp)
-
- .inline ngx_atomic_fetch_add,0
- movl (%esp), %ecx
- movl 4(%esp), %eax
- lock
- xaddl %eax, (%ecx)
- .end
-
-
-/ ngx_cpu_pause()
-/
-/ the "rep; nop" is used instead of "pause" to avoid the "[ PAUSE ]" hardware
-/ capability added by linker because Solaris/i386 does not know about it:
-/
-/ ld.so.1: nginx: fatal: hardware capability unsupported: 0x2000 [ PAUSE ]
-
- .inline ngx_cpu_pause,0
- rep; nop
- .end
diff --git a/usr.sbin/nginx/src/os/unix/ngx_thread.h b/usr.sbin/nginx/src/os/unix/ngx_thread.h
deleted file mode 100644
index 49c5d5656a7..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_thread.h
+++ /dev/null
@@ -1,128 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_THREAD_H_INCLUDED_
-#define _NGX_THREAD_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-#if (NGX_THREADS)
-
-#define NGX_MAX_THREADS 128
-
-#if (NGX_USE_RFORK)
-#include <ngx_freebsd_rfork_thread.h>
-
-
-#else /* use pthreads */
-
-#include <pthread.h>
-
-typedef pthread_t ngx_tid_t;
-
-#define ngx_thread_self() pthread_self()
-#define ngx_log_tid (int) ngx_thread_self()
-
-#if (NGX_FREEBSD) && !(NGX_LINUXTHREADS)
-#define NGX_TID_T_FMT "%p"
-#else
-#define NGX_TID_T_FMT "%d"
-#endif
-
-
-typedef pthread_key_t ngx_tls_key_t;
-
-#define ngx_thread_key_create(key) pthread_key_create(key, NULL)
-#define ngx_thread_key_create_n "pthread_key_create()"
-#define ngx_thread_set_tls pthread_setspecific
-#define ngx_thread_set_tls_n "pthread_setspecific()"
-#define ngx_thread_get_tls pthread_getspecific
-
-
-#define NGX_MUTEX_LIGHT 0
-
-typedef struct {
- pthread_mutex_t mutex;
- ngx_log_t *log;
-} ngx_mutex_t;
-
-typedef struct {
- pthread_cond_t cond;
- ngx_log_t *log;
-} ngx_cond_t;
-
-#define ngx_thread_sigmask pthread_sigmask
-#define ngx_thread_sigmask_n "pthread_sigmask()"
-
-#define ngx_thread_join(t, p) pthread_join(t, p)
-
-#define ngx_setthrtitle(n)
-
-
-
-ngx_int_t ngx_mutex_trylock(ngx_mutex_t *m);
-void ngx_mutex_lock(ngx_mutex_t *m);
-void ngx_mutex_unlock(ngx_mutex_t *m);
-
-#endif
-
-
-#define ngx_thread_volatile volatile
-
-
-typedef struct {
- ngx_tid_t tid;
- ngx_cond_t *cv;
- ngx_uint_t state;
-} ngx_thread_t;
-
-#define NGX_THREAD_FREE 1
-#define NGX_THREAD_BUSY 2
-#define NGX_THREAD_EXIT 3
-#define NGX_THREAD_DONE 4
-
-extern ngx_int_t ngx_threads_n;
-extern volatile ngx_thread_t ngx_threads[NGX_MAX_THREADS];
-
-
-typedef void * ngx_thread_value_t;
-
-ngx_int_t ngx_init_threads(int n, size_t size, ngx_cycle_t *cycle);
-ngx_err_t ngx_create_thread(ngx_tid_t *tid,
- ngx_thread_value_t (*func)(void *arg), void *arg, ngx_log_t *log);
-
-ngx_mutex_t *ngx_mutex_init(ngx_log_t *log, ngx_uint_t flags);
-void ngx_mutex_destroy(ngx_mutex_t *m);
-
-
-ngx_cond_t *ngx_cond_init(ngx_log_t *log);
-void ngx_cond_destroy(ngx_cond_t *cv);
-ngx_int_t ngx_cond_wait(ngx_cond_t *cv, ngx_mutex_t *m);
-ngx_int_t ngx_cond_signal(ngx_cond_t *cv);
-
-
-#else /* !NGX_THREADS */
-
-#define ngx_thread_volatile
-
-#define ngx_log_tid 0
-#define NGX_TID_T_FMT "%d"
-
-#define ngx_mutex_trylock(m) NGX_OK
-#define ngx_mutex_lock(m)
-#define ngx_mutex_unlock(m)
-
-#define ngx_cond_signal(cv)
-
-#define ngx_thread_main() 1
-
-#endif
-
-
-#endif /* _NGX_THREAD_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_time.c b/usr.sbin/nginx/src/os/unix/ngx_time.c
deleted file mode 100644
index cc760b2eb01..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_time.c
+++ /dev/null
@@ -1,104 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/*
- * FreeBSD does not test /etc/localtime change, however, we can workaround it
- * by calling tzset() with TZ and then without TZ to update timezone.
- * The trick should work since FreeBSD 2.1.0.
- *
- * Linux does not test /etc/localtime change in localtime(),
- * but may stat("/etc/localtime") several times in every strftime(),
- * therefore we use it to update timezone.
- *
- * Solaris does not test /etc/TIMEZONE change too and no workaround available.
- */
-
-void
-ngx_timezone_update(void)
-{
-#if (NGX_FREEBSD)
-
- if (getenv("TZ")) {
- return;
- }
-
- putenv("TZ=UTC");
-
- tzset();
-
- unsetenv("TZ");
-
- tzset();
-
-#elif (NGX_LINUX)
- time_t s;
- struct tm *t;
- char buf[4];
-
- s = time(0);
-
- t = localtime(&s);
-
- strftime(buf, 4, "%H", t);
-
-#endif
-}
-
-
-void
-ngx_localtime(time_t s, ngx_tm_t *tm)
-{
-#if (NGX_HAVE_LOCALTIME_R)
- (void) localtime_r(&s, tm);
-
-#else
- ngx_tm_t *t;
-
- t = localtime(&s);
- *tm = *t;
-
-#endif
-
- tm->ngx_tm_mon++;
- tm->ngx_tm_year += 1900;
-}
-
-
-void
-ngx_libc_localtime(time_t s, struct tm *tm)
-{
-#if (NGX_HAVE_LOCALTIME_R)
- (void) localtime_r(&s, tm);
-
-#else
- struct tm *t;
-
- t = localtime(&s);
- *tm = *t;
-
-#endif
-}
-
-
-void
-ngx_libc_gmtime(time_t s, struct tm *tm)
-{
-#if (NGX_HAVE_LOCALTIME_R)
- (void) gmtime_r(&s, tm);
-
-#else
- struct tm *t;
-
- t = gmtime(&s);
- *tm = *t;
-
-#endif
-}
diff --git a/usr.sbin/nginx/src/os/unix/ngx_time.h b/usr.sbin/nginx/src/os/unix/ngx_time.h
deleted file mode 100644
index c128c9aa043..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_time.h
+++ /dev/null
@@ -1,66 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_TIME_H_INCLUDED_
-#define _NGX_TIME_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef ngx_rbtree_key_t ngx_msec_t;
-typedef ngx_rbtree_key_int_t ngx_msec_int_t;
-
-typedef struct tm ngx_tm_t;
-
-#define ngx_tm_sec tm_sec
-#define ngx_tm_min tm_min
-#define ngx_tm_hour tm_hour
-#define ngx_tm_mday tm_mday
-#define ngx_tm_mon tm_mon
-#define ngx_tm_year tm_year
-#define ngx_tm_wday tm_wday
-#define ngx_tm_isdst tm_isdst
-
-#define ngx_tm_sec_t int
-#define ngx_tm_min_t int
-#define ngx_tm_hour_t int
-#define ngx_tm_mday_t int
-#define ngx_tm_mon_t int
-#define ngx_tm_year_t int
-#define ngx_tm_wday_t int
-
-
-#if (NGX_HAVE_GMTOFF)
-#define ngx_tm_gmtoff tm_gmtoff
-#define ngx_tm_zone tm_zone
-#endif
-
-
-#if (NGX_SOLARIS)
-
-#define ngx_timezone(isdst) (- (isdst ? altzone : timezone) / 60)
-
-#else
-
-#define ngx_timezone(isdst) (- (isdst ? timezone + 3600 : timezone) / 60)
-
-#endif
-
-
-void ngx_timezone_update(void);
-void ngx_localtime(time_t s, ngx_tm_t *tm);
-void ngx_libc_localtime(time_t s, struct tm *tm);
-void ngx_libc_gmtime(time_t s, struct tm *tm);
-
-#define ngx_gettimeofday(tp) (void) gettimeofday(tp, NULL);
-#define ngx_msleep(ms) (void) usleep(ms * 1000)
-#define ngx_sleep(s) (void) sleep(s)
-
-
-#endif /* _NGX_TIME_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_udp_recv.c b/usr.sbin/nginx/src/os/unix/ngx_udp_recv.c
deleted file mode 100644
index 1c807a08bb2..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_udp_recv.c
+++ /dev/null
@@ -1,115 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#if (NGX_HAVE_KQUEUE)
-
-ssize_t
-ngx_udp_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
-{
- ssize_t n;
- ngx_err_t err;
- ngx_event_t *rev;
-
- rev = c->read;
-
- do {
- n = recv(c->fd, buf, size, 0);
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "recv: fd:%d %d of %d", c->fd, n, size);
-
- if (n >= 0) {
- if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
- rev->available -= n;
-
- /*
- * rev->available may be negative here because some additional
- * bytes may be received between kevent() and recv()
- */
-
- if (rev->available <= 0) {
- rev->ready = 0;
- rev->available = 0;
- }
- }
-
- return n;
- }
-
- err = ngx_socket_errno;
-
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "recv() not ready");
- n = NGX_AGAIN;
-
- } else {
- n = ngx_connection_error(c, err, "recv() failed");
- break;
- }
-
- } while (err == NGX_EINTR);
-
- rev->ready = 0;
-
- if (n == NGX_ERROR) {
- rev->error = 1;
- }
-
- return n;
-}
-
-#else /* ! NGX_HAVE_KQUEUE */
-
-ssize_t
-ngx_udp_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
-{
- ssize_t n;
- ngx_err_t err;
- ngx_event_t *rev;
-
- rev = c->read;
-
- do {
- n = recv(c->fd, buf, size, 0);
-
- ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "recv: fd:%d %d of %d", c->fd, n, size);
-
- if (n >= 0) {
- return n;
- }
-
- err = ngx_socket_errno;
-
- if (err == NGX_EAGAIN || err == NGX_EINTR) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "recv() not ready");
- n = NGX_AGAIN;
-
- } else {
- n = ngx_connection_error(c, err, "recv() failed");
- break;
- }
-
- } while (err == NGX_EINTR);
-
- rev->ready = 0;
-
- if (n == NGX_ERROR) {
- rev->error = 1;
- }
-
- return n;
-}
-
-#endif /* NGX_HAVE_KQUEUE */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_user.c b/usr.sbin/nginx/src/os/unix/ngx_user.c
deleted file mode 100644
index 7a71203cb8f..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_user.c
+++ /dev/null
@@ -1,108 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-/*
- * Solaris has thread-safe crypt()
- * Linux has crypt_r(); "struct crypt_data" is more than 128K
- * FreeBSD needs the mutex to protect crypt()
- *
- * TODO:
- * ngx_crypt_init() to init mutex
- */
-
-
-#if (NGX_CRYPT)
-
-#if (NGX_HAVE_GNU_CRYPT_R)
-
-ngx_int_t
-ngx_libc_crypt(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
-{
- char *value;
- size_t len;
- struct crypt_data cd;
-
- cd.initialized = 0;
- /* work around the glibc bug */
- cd.current_salt[0] = ~salt[0];
-
- value = crypt_r((char *) key, (char *) salt, &cd);
-
- if (value) {
- len = ngx_strlen(value) + 1;
-
- *encrypted = ngx_pnalloc(pool, len);
- if (*encrypted == NULL) {
- return NGX_ERROR;
- }
-
- ngx_memcpy(*encrypted, value, len);
- return NGX_OK;
- }
-
- ngx_log_error(NGX_LOG_CRIT, pool->log, ngx_errno, "crypt_r() failed");
-
- return NGX_ERROR;
-}
-
-#else
-
-ngx_int_t
-ngx_libc_crypt(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted)
-{
- char *value;
- size_t len;
- ngx_err_t err;
-
-#if (NGX_THREADS && NGX_NONREENTRANT_CRYPT)
-
- /* crypt() is a time consuming function, so we only try to lock */
-
- if (ngx_mutex_trylock(ngx_crypt_mutex) != NGX_OK) {
- return NGX_AGAIN;
- }
-
-#endif
-
- value = crypt((char *) key, (char *) salt);
-
- if (value) {
- len = ngx_strlen(value) + 1;
-
- *encrypted = ngx_pnalloc(pool, len);
- if (*encrypted == NULL) {
-#if (NGX_THREADS && NGX_NONREENTRANT_CRYPT)
- ngx_mutex_unlock(ngx_crypt_mutex);
-#endif
- return NGX_ERROR;
- }
-
- ngx_memcpy(*encrypted, value, len);
-#if (NGX_THREADS && NGX_NONREENTRANT_CRYPT)
- ngx_mutex_unlock(ngx_crypt_mutex);
-#endif
- return NGX_OK;
- }
-
- err = ngx_errno;
-
-#if (NGX_THREADS && NGX_NONREENTRANT_CRYPT)
- ngx_mutex_unlock(ngx_crypt_mutex);
-#endif
-
- ngx_log_error(NGX_LOG_CRIT, pool->log, err, "crypt() failed");
-
- return NGX_ERROR;
-}
-
-#endif
-
-#endif /* NGX_CRYPT */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_user.h b/usr.sbin/nginx/src/os/unix/ngx_user.h
deleted file mode 100644
index 6e82204f4d1..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_user.h
+++ /dev/null
@@ -1,24 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#ifndef _NGX_USER_H_INCLUDED_
-#define _NGX_USER_H_INCLUDED_
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-
-
-typedef uid_t ngx_uid_t;
-typedef gid_t ngx_gid_t;
-
-
-ngx_int_t ngx_libc_crypt(ngx_pool_t *pool, u_char *key, u_char *salt,
- u_char **encrypted);
-
-
-#endif /* _NGX_USER_H_INCLUDED_ */
diff --git a/usr.sbin/nginx/src/os/unix/ngx_writev_chain.c b/usr.sbin/nginx/src/os/unix/ngx_writev_chain.c
deleted file mode 100644
index 805982d6558..00000000000
--- a/usr.sbin/nginx/src/os/unix/ngx_writev_chain.c
+++ /dev/null
@@ -1,185 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_event.h>
-
-
-#if (IOV_MAX > 64)
-#define NGX_IOVS 64
-#else
-#define NGX_IOVS IOV_MAX
-#endif
-
-
-ngx_chain_t *
-ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
-{
- u_char *prev;
- ssize_t n, size, sent;
- off_t send, prev_send;
- ngx_uint_t eintr, complete;
- ngx_err_t err;
- ngx_array_t vec;
- ngx_chain_t *cl;
- ngx_event_t *wev;
- struct iovec *iov, iovs[NGX_IOVS];
-
- wev = c->write;
-
- if (!wev->ready) {
- return in;
- }
-
-#if (NGX_HAVE_KQUEUE)
-
- if ((ngx_event_flags & NGX_USE_KQUEUE_EVENT) && wev->pending_eof) {
- (void) ngx_connection_error(c, wev->kq_errno,
- "kevent() reported about an closed connection");
- wev->error = 1;
- return NGX_CHAIN_ERROR;
- }
-
-#endif
-
- /* the maximum limit size is the maximum size_t value - the page size */
-
- if (limit == 0 || limit > (off_t) (NGX_MAX_SIZE_T_VALUE - ngx_pagesize)) {
- limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
- }
-
- send = 0;
-
- vec.elts = iovs;
- vec.size = sizeof(struct iovec);
- vec.nalloc = NGX_IOVS;
- vec.pool = c->pool;
-
- for ( ;; ) {
- prev = NULL;
- iov = NULL;
- eintr = 0;
- complete = 0;
- prev_send = send;
-
- vec.nelts = 0;
-
- /* create the iovec and coalesce the neighbouring bufs */
-
- for (cl = in; cl && send < limit; cl = cl->next) {
-
- if (ngx_buf_special(cl->buf)) {
- continue;
- }
-
-#if 1
- if (!ngx_buf_in_memory(cl->buf)) {
- ngx_debug_point();
- }
-#endif
-
- size = cl->buf->last - cl->buf->pos;
-
- if (send + size > limit) {
- size = (ssize_t) (limit - send);
- }
-
- if (prev == cl->buf->pos) {
- iov->iov_len += size;
-
- } else {
- if (vec.nelts >= IOV_MAX) {
- break;
- }
-
- iov = ngx_array_push(&vec);
- if (iov == NULL) {
- return NGX_CHAIN_ERROR;
- }
-
- iov->iov_base = (void *) cl->buf->pos;
- iov->iov_len = size;
- }
-
- prev = cl->buf->pos + size;
- send += size;
- }
-
- n = writev(c->fd, vec.elts, vec.nelts);
-
- if (n == -1) {
- err = ngx_errno;
-
- switch (err) {
- case NGX_EAGAIN:
- break;
-
- case NGX_EINTR:
- eintr = 1;
- break;
-
- default:
- wev->error = 1;
- (void) ngx_connection_error(c, err, "writev() failed");
- return NGX_CHAIN_ERROR;
- }
-
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
- "writev() not ready");
- }
-
- sent = n > 0 ? n : 0;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %z", sent);
-
- if (send - prev_send == sent) {
- complete = 1;
- }
-
- c->sent += sent;
-
- for (cl = in; cl; cl = cl->next) {
-
- if (ngx_buf_special(cl->buf)) {
- continue;
- }
-
- if (sent == 0) {
- break;
- }
-
- size = cl->buf->last - cl->buf->pos;
-
- if (sent >= size) {
- sent -= size;
- cl->buf->pos = cl->buf->last;
-
- continue;
- }
-
- cl->buf->pos += sent;
-
- break;
- }
-
- if (eintr) {
- continue;
- }
-
- if (!complete) {
- wev->ready = 0;
- return cl;
- }
-
- if (send >= limit || cl == NULL) {
- return cl;
- }
-
- in = cl;
- }
-}
diff --git a/usr.sbin/nginx/src/os/unix/rfork_thread.S b/usr.sbin/nginx/src/os/unix/rfork_thread.S
deleted file mode 100644
index e570349f93b..00000000000
--- a/usr.sbin/nginx/src/os/unix/rfork_thread.S
+++ /dev/null
@@ -1,73 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <sys/syscall.h>
-#include <machine/asm.h>
-
-/*
- * rfork_thread(3) - rfork_thread(flags, stack, func, arg);
- */
-
-#define KERNCALL int $0x80
-
-ENTRY(rfork_thread)
- push %ebp
- mov %esp, %ebp
- push %esi
-
- mov 12(%ebp), %esi # the thread stack address
-
- sub $4, %esi
- mov 20(%ebp), %eax # the thread argument
- mov %eax, (%esi)
-
- sub $4, %esi
- mov 16(%ebp), %eax # the thread start address
- mov %eax, (%esi)
-
- push 8(%ebp) # rfork(2) flags
- push $0
- mov $SYS_rfork, %eax
- KERNCALL
- jc error
-
- cmp $0, %edx
- jne child
-
-parent:
- add $8, %esp
- pop %esi
- leave
- ret
-
-child:
- mov %esi, %esp
- pop %eax
- call *%eax # call a thread start address ...
- add $4, %esp
-
- push %eax
- push $0
- mov $SYS_exit, %eax # ... and exit(2) after a thread would return
- KERNCALL
-
-error:
- add $8, %esp
- pop %esi
- leave
- PIC_PROLOGUE
-
- /* libc's cerror: jmp PIC_PLT(HIDENAME(cerror)) */
-
- push %eax
- call PIC_PLT(CNAME(__error))
- pop %ecx
- PIC_EPILOGUE
- mov %ecx, (%eax)
- mov $-1, %eax
- mov $-1, %edx
- ret
diff --git a/usr.sbin/nginx/src/pcre/LICENCE b/usr.sbin/nginx/src/pcre/LICENCE
deleted file mode 100644
index ae7bbcf8cfe..00000000000
--- a/usr.sbin/nginx/src/pcre/LICENCE
+++ /dev/null
@@ -1,92 +0,0 @@
-PCRE LICENCE
-------------
-
-PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
-Release 8 of PCRE is distributed under the terms of the "BSD" licence, as
-specified below. The documentation for PCRE, supplied in the "doc"
-directory, is distributed under the same terms as the software itself.
-
-The basic library functions are written in C and are freestanding. Also
-included in the distribution is a set of C++ wrapper functions, and a
-just-in-time compiler that can be used to optimize pattern matching. These
-are both optional features that can be omitted when the library is built.
-
-
-THE BASIC LIBRARY FUNCTIONS
----------------------------
-
-Written by: Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
-
-University of Cambridge Computing Service,
-Cambridge, England.
-
-Copyright (c) 1997-2011 University of Cambridge
-All rights reserved.
-
-
-PCRE JUST-IN-TIME COMPILATION SUPPORT
--------------------------------------
-
-Written by: Zoltan Herczeg
-Email local part: hzmester
-Emain domain: freemail.hu
-
-Copyright(c) 2010-2011 Zoltan Herczeg
-All rights reserved.
-
-
-STACK-LESS JUST-IN-TIME COMPILER
---------------------------------
-
-Written by: Zoltan Herczeg
-Email local part: hzmester
-Emain domain: freemail.hu
-
-Copyright(c) 2009-2011 Zoltan Herczeg
-All rights reserved.
-
-
-THE C++ WRAPPER FUNCTIONS
--------------------------
-
-Contributed by: Google Inc.
-
-Copyright (c) 2007-2011, Google Inc.
-All rights reserved.
-
-
-THE "BSD" LICENCE
------------------
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the name of Google
- Inc. nor the names of their contributors may be used to endorse or
- promote products derived from this software without specific prior
- written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-End
diff --git a/usr.sbin/nginx/src/pcre/config.h b/usr.sbin/nginx/src/pcre/config.h
deleted file mode 100644
index 76dce45094a..00000000000
--- a/usr.sbin/nginx/src/pcre/config.h
+++ /dev/null
@@ -1,350 +0,0 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-
-/* PCRE is written in Standard C, but there are a few non-standard things it
-can cope with, allowing it to run on SunOS4 and other "close to standard"
-systems.
-
-In environments that support the facilities, config.h.in is converted by
-"configure", or config-cmake.h.in is converted by CMake, into config.h. If you
-are going to build PCRE "by hand" without using "configure" or CMake, you
-should copy the distributed config.h.generic to config.h, and then edit the
-macro definitions to be the way you need them. You must then add
--DHAVE_CONFIG_H to all of your compile commands, so that config.h is included
-at the start of every source.
-
-Alternatively, you can avoid editing by using -D on the compiler command line
-to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H.
-
-PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if
-HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set
-them both to 0; an emulation function will be used. */
-
-/* By default, the \R escape sequence matches any Unicode line ending
- character or sequence of characters. If BSR_ANYCRLF is defined (to any
- value), this is changed so that backslash-R matches only CR, LF, or CRLF.
- The build-time default can be overridden by the user of PCRE at runtime. */
-/* #undef BSR_ANYCRLF */
-
-/* If you are compiling for a system that uses EBCDIC instead of ASCII
- character codes, define this macro to any value. You must also edit the
- NEWLINE macro below to set a suitable EBCDIC newline, commonly 21 (0x15).
- On systems that can use "configure" or CMake to set EBCDIC, NEWLINE is
- automatically adjusted. When EBCDIC is set, PCRE assumes that all input
- strings are in EBCDIC. If you do not define this macro, PCRE will assume
- input strings are ASCII or UTF-8/16/32 Unicode. It is not possible to build
- a version of PCRE that supports both EBCDIC and UTF-8/16/32. */
-/* #undef EBCDIC */
-
-/* In an EBCDIC environment, define this macro to any value to arrange for the
- NL character to be 0x25 instead of the default 0x15. NL plays the role that
- LF does in an ASCII/Unicode environment. The value must also be set in the
- NEWLINE macro below. On systems that can use "configure" or CMake to set
- EBCDIC_NL25, the adjustment of NEWLINE is automatic. */
-/* #undef EBCDIC_NL25 */
-
-/* Define to 1 if you have the `bcopy' function. */
-#define HAVE_BCOPY 1
-
-/* Define to 1 if you have the <bits/type_traits.h> header file. */
-/* #undef HAVE_BITS_TYPE_TRAITS_H */
-
-/* Define to 1 if you have the <bzlib.h> header file. */
-/* #undef HAVE_BZLIB_H */
-
-/* Define to 1 if you have the <dirent.h> header file. */
-#define HAVE_DIRENT_H 1
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the <editline/readline.h> header file. */
-/* #undef HAVE_EDITLINE_READLINE_H */
-
-/* Define to 1 if you have the <edit/readline/readline.h> header file. */
-/* #undef HAVE_EDIT_READLINE_READLINE_H */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <limits.h> header file. */
-#define HAVE_LIMITS_H 1
-
-/* Define to 1 if the system has the type `long long'. */
-#define HAVE_LONG_LONG 1
-
-/* Define to 1 if you have the `memmove' function. */
-#define HAVE_MEMMOVE 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define if you have POSIX threads libraries and header files. */
-/* #undef HAVE_PTHREAD */
-
-/* Have PTHREAD_PRIO_INHERIT. */
-/* #undef HAVE_PTHREAD_PRIO_INHERIT */
-
-/* Define to 1 if you have the <readline/history.h> header file. */
-/* #undef HAVE_READLINE_HISTORY_H */
-
-/* Define to 1 if you have the <readline/readline.h> header file. */
-/* #undef HAVE_READLINE_READLINE_H */
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `strerror' function. */
-#define HAVE_STRERROR 1
-
-/* Define to 1 if you have the <string> header file. */
-#define HAVE_STRING 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have `strtoimax'. */
-/* #undef HAVE_STRTOIMAX */
-
-/* Define to 1 if you have `strtoll'. */
-/* #undef HAVE_STRTOLL */
-
-/* Define to 1 if you have `strtoq'. */
-#define HAVE_STRTOQ 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <type_traits.h> header file. */
-/* #undef HAVE_TYPE_TRAITS_H */
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define to 1 if the system has the type `unsigned long long'. */
-#define HAVE_UNSIGNED_LONG_LONG 1
-
-/* Define to 1 or 0, depending whether the compiler supports simple visibility
- declarations. */
-#if !defined(__vax__)
-#define HAVE_VISIBILITY 1
-#endif
-
-/* Define to 1 if you have the <windows.h> header file. */
-/* #undef HAVE_WINDOWS_H */
-
-/* Define to 1 if you have the <zlib.h> header file. */
-#define HAVE_ZLIB_H 1
-
-/* Define to 1 if you have `_strtoi64'. */
-/* #undef HAVE__STRTOI64 */
-
-/* The value of LINK_SIZE determines the number of bytes used to store links
- as offsets within the compiled regex. The default is 2, which allows for
- compiled patterns up to 64K long. This covers the vast majority of cases.
- However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows
- for longer patterns in extreme cases. */
-#define LINK_SIZE 2
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
- */
-#define LT_OBJDIR ".libs/"
-
-/* The value of MATCH_LIMIT determines the default number of times the
- internal match() function can be called during a single execution of
- pcre_exec(). There is a runtime interface for setting a different limit.
- The limit exists in order to catch runaway regular expressions that take
- for ever to determine that they do not match. The default is set very large
- so that it does not accidentally catch legitimate cases. */
-#define MATCH_LIMIT 10000000
-
-/* The above limit applies to all calls of match(), whether or not they
- increase the recursion depth. In some environments it is desirable to limit
- the depth of recursive calls of match() more strictly, in order to restrict
- the maximum amount of stack (or heap, if NO_RECURSE is defined) that is
- used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of
- match(). To have any useful effect, it must be less than the value of
- MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is
- a runtime method for setting a different limit. */
-#define MATCH_LIMIT_RECURSION MATCH_LIMIT
-
-/* This limit is parameterized just in case anybody ever wants to change it.
- Care must be taken if it is increased, because it guards against integer
- overflow caused by enormously large patterns. */
-#define MAX_NAME_COUNT 10000
-
-/* This limit is parameterized just in case anybody ever wants to change it.
- Care must be taken if it is increased, because it guards against integer
- overflow caused by enormously large patterns. */
-#define MAX_NAME_SIZE 32
-
-/* The value of NEWLINE determines the default newline character sequence.
- PCRE client programs can override this by selecting other values at run
- time. In ASCII environments, the value can be 10 (LF), 13 (CR), or 3338
- (CRLF); in EBCDIC environments the value can be 21 or 37 (LF), 13 (CR), or
- 3349 or 3365 (CRLF) because there are two alternative codepoints (0x15 and
- 0x25) that are used as the NL line terminator that is equivalent to ASCII
- LF. In both ASCII and EBCDIC environments the value can also be -1 (ANY),
- or -2 (ANYCRLF). */
-#define NEWLINE 10
-
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-/* #undef NO_MINUS_C_MINUS_O */
-
-/* PCRE uses recursive function calls to handle backtracking while matching.
- This can sometimes be a problem on systems that have stacks of limited
- size. Define NO_RECURSE to any value to get a version that doesn't use
- recursion in the match() function; instead it creates its own stack by
- steam using pcre_recurse_malloc() to obtain memory from the heap. For more
- detail, see the comments and other stuff just above the match() function.
- */
-/* #undef NO_RECURSE */
-
-/* Name of package */
-#define PACKAGE "pcre"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT ""
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "PCRE"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "PCRE 8.32"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "pcre"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "8.32"
-
-#if !defined(__vax__)
-/* to make a symbol visible */
-#define PCRECPP_EXP_DECL extern __attribute__ ((visibility ("default")))
-
-/* to make a symbol visible */
-#define PCRECPP_EXP_DEFN __attribute__ ((visibility ("default")))
-#endif
-
-/* The value of PCREGREP_BUFSIZE determines the size of buffer used by
- pcregrep to hold parts of the file it is searching. This is also the
- minimum value. The actual amount of memory used by pcregrep is three times
- this number, because it allows for the buffering of "before" and "after"
- lines. */
-#define PCREGREP_BUFSIZE 20480
-
-#if !defined(__vax__)
-/* to make a symbol visible */
-#define PCREPOSIX_EXP_DECL extern __attribute__ ((visibility ("default")))
-
-/* to make a symbol visible */
-#define PCREPOSIX_EXP_DEFN extern __attribute__ ((visibility ("default")))
-
-/* to make a symbol visible */
-#define PCRE_EXP_DATA_DEFN __attribute__ ((visibility ("default")))
-
-/* to make a symbol visible */
-#define PCRE_EXP_DECL extern __attribute__ ((visibility ("default")))
-
-
-/* If you are compiling for a system other than a Unix-like system or
- Win32, and it needs some magic to be inserted before the definition
- of a function that is exported by the library, define this macro to
- contain the relevant magic. If you do not define this macro, a suitable
- __declspec value is used for Windows systems; in other environments
- "extern" is used for a C compiler and "extern C" for a C++ compiler.
- This macro apears at the start of every exported function that is part
- of the external API. It does not appear on functions that are "external"
- in the C sense, but which are internal to the library. */
-#define PCRE_EXP_DEFN __attribute__ ((visibility ("default")))
-#endif
-
-/* Define to any value if linking statically (TODO: make nice with Libtool) */
-/* #undef PCRE_STATIC */
-
-/* When calling PCRE via the POSIX interface, additional working storage is
- required for holding the pointers to capturing substrings because PCRE
- requires three integers per substring, whereas the POSIX interface provides
- only two. If the number of expected substrings is small, the wrapper
- function uses space on the stack, because this is faster than using
- malloc() for each call. The threshold above which the stack is no longer
- used is defined by POSIX_MALLOC_THRESHOLD. */
-#define POSIX_MALLOC_THRESHOLD 10
-
-/* Define to necessary symbol if this constant uses a non-standard name on
- your system. */
-/* #undef PTHREAD_CREATE_JOINABLE */
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define to allow pcretest and pcregrep to be linked with gcov, so that they
- are able to generate code coverage reports. */
-/* #undef SUPPORT_GCOV */
-
-/* Define to any value to enable support for Just-In-Time compiling. */
-/* #undef SUPPORT_JIT */
-
-/* Define to any value to allow pcregrep to be linked with libbz2, so that it
- is able to handle .bz2 files. */
-/* #undef SUPPORT_LIBBZ2 */
-
-/* Define to any value to allow pcretest to be linked with libedit. */
-/* #undef SUPPORT_LIBEDIT */
-
-/* Define to any value to allow pcretest to be linked with libreadline. */
-/* #undef SUPPORT_LIBREADLINE */
-
-/* Define to any value to allow pcregrep to be linked with libz, so that it is
- able to handle .gz files. */
-/* #undef SUPPORT_LIBZ */
-
-/* Define to any value to enable the 16 bit PCRE library. */
-#define SUPPORT_PCRE16 /**/
-
-/* Define to any value to enable the 32 bit PCRE library. */
-/* #undef SUPPORT_PCRE32 */
-
-/* Define to any value to enable the 8 bit PCRE library. */
-#define SUPPORT_PCRE8 /**/
-
-/* Define to any value to enable JIT support in pcregrep. */
-/* #undef SUPPORT_PCREGREP_JIT */
-
-/* Define to any value to enable support for Unicode properties. */
-#define SUPPORT_UCP /**/
-
-/* Define to any value to enable support for the UTF-8/16/32 Unicode encoding.
- This will work even in an EBCDIC environment, but it is incompatible with
- the EBCDIC macro. That is, PCRE can support *either* EBCDIC code *or*
- ASCII/UTF-8/16/32, but not both at once. */
-#define SUPPORT_UTF /**/
-
-/* Valgrind support to find invalid memory reads. */
-/* #undef SUPPORT_VALGRIND */
-
-/* Version number of package */
-#define VERSION "8.32"
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to the type of a signed integer type of width exactly 64 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef int64_t */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-/* #undef size_t */
diff --git a/usr.sbin/nginx/src/pcre/pcre.h b/usr.sbin/nginx/src/pcre/pcre.h
deleted file mode 100644
index 0e479667672..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre.h
+++ /dev/null
@@ -1,663 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* This is the public header file for the PCRE library, to be #included by
-applications that call the PCRE functions.
-
- Copyright (c) 1997-2013 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifndef _PCRE_H
-#define _PCRE_H
-
-/* The current PCRE version information. */
-
-#define PCRE_MAJOR 8
-#define PCRE_MINOR 33
-#define PCRE_PRERELEASE
-#define PCRE_DATE 2013-05-28
-
-/* When an application links to a PCRE DLL in Windows, the symbols that are
-imported have to be identified as such. When building PCRE, the appropriate
-export setting is defined in pcre_internal.h, which includes this file. So we
-don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */
-
-#if defined(_WIN32) && !defined(PCRE_STATIC)
-# ifndef PCRE_EXP_DECL
-# define PCRE_EXP_DECL extern __declspec(dllimport)
-# endif
-# ifdef __cplusplus
-# ifndef PCRECPP_EXP_DECL
-# define PCRECPP_EXP_DECL extern __declspec(dllimport)
-# endif
-# ifndef PCRECPP_EXP_DEFN
-# define PCRECPP_EXP_DEFN __declspec(dllimport)
-# endif
-# endif
-#endif
-
-/* By default, we use the standard "extern" declarations. */
-
-#ifndef PCRE_EXP_DECL
-# ifdef __cplusplus
-# define PCRE_EXP_DECL extern "C"
-# else
-# define PCRE_EXP_DECL extern
-# endif
-#endif
-
-#ifdef __cplusplus
-# ifndef PCRECPP_EXP_DECL
-# define PCRECPP_EXP_DECL extern
-# endif
-# ifndef PCRECPP_EXP_DEFN
-# define PCRECPP_EXP_DEFN
-# endif
-#endif
-
-/* Have to include stdlib.h in order to ensure that size_t is defined;
-it is needed here for malloc. */
-
-#include <stdlib.h>
-
-/* Allow for C++ users */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Public options. Some are compile-time only, some are run-time only, and some
-are both. Most of the compile-time options are saved with the compiled regex so
-that they can be inspected during studying (and therefore JIT compiling). Note
-that pcre_study() has its own set of options. Originally, all the options
-defined here used distinct bits. However, almost all the bits in a 32-bit word
-are now used, so in order to conserve them, option bits that were previously
-only recognized at matching time (i.e. by pcre_exec() or pcre_dfa_exec()) may
-also be used for compile-time options that affect only compiling and are not
-relevant for studying or JIT compiling.
-
-Some options for pcre_compile() change its behaviour but do not affect the
-behaviour of the execution functions. Other options are passed through to the
-execution functions and affect their behaviour, with or without affecting the
-behaviour of pcre_compile().
-
-Options that can be passed to pcre_compile() are tagged Cx below, with these
-variants:
-
-C1 Affects compile only
-C2 Does not affect compile; affects exec, dfa_exec
-C3 Affects compile, exec, dfa_exec
-C4 Affects compile, exec, dfa_exec, study
-C5 Affects compile, exec, study
-
-Options that can be set for pcre_exec() and/or pcre_dfa_exec() are flagged with
-E and D, respectively. They take precedence over C3, C4, and C5 settings passed
-from pcre_compile(). Those that are compatible with JIT execution are flagged
-with J. */
-
-#define PCRE_CASELESS 0x00000001 /* C1 */
-#define PCRE_MULTILINE 0x00000002 /* C1 */
-#define PCRE_DOTALL 0x00000004 /* C1 */
-#define PCRE_EXTENDED 0x00000008 /* C1 */
-#define PCRE_ANCHORED 0x00000010 /* C4 E D */
-#define PCRE_DOLLAR_ENDONLY 0x00000020 /* C2 */
-#define PCRE_EXTRA 0x00000040 /* C1 */
-#define PCRE_NOTBOL 0x00000080 /* E D J */
-#define PCRE_NOTEOL 0x00000100 /* E D J */
-#define PCRE_UNGREEDY 0x00000200 /* C1 */
-#define PCRE_NOTEMPTY 0x00000400 /* E D J */
-#define PCRE_UTF8 0x00000800 /* C4 ) */
-#define PCRE_UTF16 0x00000800 /* C4 ) Synonyms */
-#define PCRE_UTF32 0x00000800 /* C4 ) */
-#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* C1 */
-#define PCRE_NO_UTF8_CHECK 0x00002000 /* C1 E D J ) */
-#define PCRE_NO_UTF16_CHECK 0x00002000 /* C1 E D J ) Synonyms */
-#define PCRE_NO_UTF32_CHECK 0x00002000 /* C1 E D J ) */
-#define PCRE_AUTO_CALLOUT 0x00004000 /* C1 */
-#define PCRE_PARTIAL_SOFT 0x00008000 /* E D J ) Synonyms */
-#define PCRE_PARTIAL 0x00008000 /* E D J ) */
-
-/* This pair use the same bit. */
-#define PCRE_NEVER_UTF 0x00010000 /* C1 ) Overlaid */
-#define PCRE_DFA_SHORTEST 0x00010000 /* D ) Overlaid */
-
-#define PCRE_DFA_RESTART 0x00020000 /* D */
-#define PCRE_FIRSTLINE 0x00040000 /* C3 */
-#define PCRE_DUPNAMES 0x00080000 /* C1 */
-#define PCRE_NEWLINE_CR 0x00100000 /* C3 E D */
-#define PCRE_NEWLINE_LF 0x00200000 /* C3 E D */
-#define PCRE_NEWLINE_CRLF 0x00300000 /* C3 E D */
-#define PCRE_NEWLINE_ANY 0x00400000 /* C3 E D */
-#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* C3 E D */
-#define PCRE_BSR_ANYCRLF 0x00800000 /* C3 E D */
-#define PCRE_BSR_UNICODE 0x01000000 /* C3 E D */
-#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* C5 */
-#define PCRE_NO_START_OPTIMIZE 0x04000000 /* C2 E D ) Synonyms */
-#define PCRE_NO_START_OPTIMISE 0x04000000 /* C2 E D ) */
-#define PCRE_PARTIAL_HARD 0x08000000 /* E D J */
-#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* E D J */
-#define PCRE_UCP 0x20000000 /* C3 */
-
-/* Exec-time and get/set-time error codes */
-
-#define PCRE_ERROR_NOMATCH (-1)
-#define PCRE_ERROR_NULL (-2)
-#define PCRE_ERROR_BADOPTION (-3)
-#define PCRE_ERROR_BADMAGIC (-4)
-#define PCRE_ERROR_UNKNOWN_OPCODE (-5)
-#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */
-#define PCRE_ERROR_NOMEMORY (-6)
-#define PCRE_ERROR_NOSUBSTRING (-7)
-#define PCRE_ERROR_MATCHLIMIT (-8)
-#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
-#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16/32 */
-#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16/32 */
-#define PCRE_ERROR_BADUTF32 (-10) /* Same for 8/16/32 */
-#define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */
-#define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */
-#define PCRE_ERROR_PARTIAL (-12)
-#define PCRE_ERROR_BADPARTIAL (-13)
-#define PCRE_ERROR_INTERNAL (-14)
-#define PCRE_ERROR_BADCOUNT (-15)
-#define PCRE_ERROR_DFA_UITEM (-16)
-#define PCRE_ERROR_DFA_UCOND (-17)
-#define PCRE_ERROR_DFA_UMLIMIT (-18)
-#define PCRE_ERROR_DFA_WSSIZE (-19)
-#define PCRE_ERROR_DFA_RECURSE (-20)
-#define PCRE_ERROR_RECURSIONLIMIT (-21)
-#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */
-#define PCRE_ERROR_BADNEWLINE (-23)
-#define PCRE_ERROR_BADOFFSET (-24)
-#define PCRE_ERROR_SHORTUTF8 (-25)
-#define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */
-#define PCRE_ERROR_RECURSELOOP (-26)
-#define PCRE_ERROR_JIT_STACKLIMIT (-27)
-#define PCRE_ERROR_BADMODE (-28)
-#define PCRE_ERROR_BADENDIANNESS (-29)
-#define PCRE_ERROR_DFA_BADRESTART (-30)
-#define PCRE_ERROR_JIT_BADOPTION (-31)
-#define PCRE_ERROR_BADLENGTH (-32)
-#define PCRE_ERROR_UNSET (-33)
-
-/* Specific error codes for UTF-8 validity checks */
-
-#define PCRE_UTF8_ERR0 0
-#define PCRE_UTF8_ERR1 1
-#define PCRE_UTF8_ERR2 2
-#define PCRE_UTF8_ERR3 3
-#define PCRE_UTF8_ERR4 4
-#define PCRE_UTF8_ERR5 5
-#define PCRE_UTF8_ERR6 6
-#define PCRE_UTF8_ERR7 7
-#define PCRE_UTF8_ERR8 8
-#define PCRE_UTF8_ERR9 9
-#define PCRE_UTF8_ERR10 10
-#define PCRE_UTF8_ERR11 11
-#define PCRE_UTF8_ERR12 12
-#define PCRE_UTF8_ERR13 13
-#define PCRE_UTF8_ERR14 14
-#define PCRE_UTF8_ERR15 15
-#define PCRE_UTF8_ERR16 16
-#define PCRE_UTF8_ERR17 17
-#define PCRE_UTF8_ERR18 18
-#define PCRE_UTF8_ERR19 19
-#define PCRE_UTF8_ERR20 20
-#define PCRE_UTF8_ERR21 21
-#define PCRE_UTF8_ERR22 22 /* Unused (was non-character) */
-
-/* Specific error codes for UTF-16 validity checks */
-
-#define PCRE_UTF16_ERR0 0
-#define PCRE_UTF16_ERR1 1
-#define PCRE_UTF16_ERR2 2
-#define PCRE_UTF16_ERR3 3
-#define PCRE_UTF16_ERR4 4 /* Unused (was non-character) */
-
-/* Specific error codes for UTF-32 validity checks */
-
-#define PCRE_UTF32_ERR0 0
-#define PCRE_UTF32_ERR1 1
-#define PCRE_UTF32_ERR2 2 /* Unused (was non-character) */
-#define PCRE_UTF32_ERR3 3
-
-/* Request types for pcre_fullinfo() */
-
-#define PCRE_INFO_OPTIONS 0
-#define PCRE_INFO_SIZE 1
-#define PCRE_INFO_CAPTURECOUNT 2
-#define PCRE_INFO_BACKREFMAX 3
-#define PCRE_INFO_FIRSTBYTE 4
-#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */
-#define PCRE_INFO_FIRSTTABLE 5
-#define PCRE_INFO_LASTLITERAL 6
-#define PCRE_INFO_NAMEENTRYSIZE 7
-#define PCRE_INFO_NAMECOUNT 8
-#define PCRE_INFO_NAMETABLE 9
-#define PCRE_INFO_STUDYSIZE 10
-#define PCRE_INFO_DEFAULT_TABLES 11
-#define PCRE_INFO_OKPARTIAL 12
-#define PCRE_INFO_JCHANGED 13
-#define PCRE_INFO_HASCRORLF 14
-#define PCRE_INFO_MINLENGTH 15
-#define PCRE_INFO_JIT 16
-#define PCRE_INFO_JITSIZE 17
-#define PCRE_INFO_MAXLOOKBEHIND 18
-#define PCRE_INFO_FIRSTCHARACTER 19
-#define PCRE_INFO_FIRSTCHARACTERFLAGS 20
-#define PCRE_INFO_REQUIREDCHAR 21
-#define PCRE_INFO_REQUIREDCHARFLAGS 22
-#define PCRE_INFO_MATCHLIMIT 23
-#define PCRE_INFO_RECURSIONLIMIT 24
-
-/* Request types for pcre_config(). Do not re-arrange, in order to remain
-compatible. */
-
-#define PCRE_CONFIG_UTF8 0
-#define PCRE_CONFIG_NEWLINE 1
-#define PCRE_CONFIG_LINK_SIZE 2
-#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3
-#define PCRE_CONFIG_MATCH_LIMIT 4
-#define PCRE_CONFIG_STACKRECURSE 5
-#define PCRE_CONFIG_UNICODE_PROPERTIES 6
-#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7
-#define PCRE_CONFIG_BSR 8
-#define PCRE_CONFIG_JIT 9
-#define PCRE_CONFIG_UTF16 10
-#define PCRE_CONFIG_JITTARGET 11
-#define PCRE_CONFIG_UTF32 12
-
-/* Request types for pcre_study(). Do not re-arrange, in order to remain
-compatible. */
-
-#define PCRE_STUDY_JIT_COMPILE 0x0001
-#define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002
-#define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004
-#define PCRE_STUDY_EXTRA_NEEDED 0x0008
-
-/* Bit flags for the pcre[16|32]_extra structure. Do not re-arrange or redefine
-these bits, just add new ones on the end, in order to remain compatible. */
-
-#define PCRE_EXTRA_STUDY_DATA 0x0001
-#define PCRE_EXTRA_MATCH_LIMIT 0x0002
-#define PCRE_EXTRA_CALLOUT_DATA 0x0004
-#define PCRE_EXTRA_TABLES 0x0008
-#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010
-#define PCRE_EXTRA_MARK 0x0020
-#define PCRE_EXTRA_EXECUTABLE_JIT 0x0040
-
-/* Types */
-
-struct real_pcre; /* declaration; the definition is private */
-typedef struct real_pcre pcre;
-
-struct real_pcre16; /* declaration; the definition is private */
-typedef struct real_pcre16 pcre16;
-
-struct real_pcre32; /* declaration; the definition is private */
-typedef struct real_pcre32 pcre32;
-
-struct real_pcre_jit_stack; /* declaration; the definition is private */
-typedef struct real_pcre_jit_stack pcre_jit_stack;
-
-struct real_pcre16_jit_stack; /* declaration; the definition is private */
-typedef struct real_pcre16_jit_stack pcre16_jit_stack;
-
-struct real_pcre32_jit_stack; /* declaration; the definition is private */
-typedef struct real_pcre32_jit_stack pcre32_jit_stack;
-
-/* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain
-a 16 bit wide signed data type. Otherwise it can be a dummy data type since
-pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */
-#ifndef PCRE_UCHAR16
-#define PCRE_UCHAR16 unsigned short
-#endif
-
-#ifndef PCRE_SPTR16
-#define PCRE_SPTR16 const PCRE_UCHAR16 *
-#endif
-
-/* If PCRE is compiled with 32 bit character support, PCRE_UCHAR32 must contain
-a 32 bit wide signed data type. Otherwise it can be a dummy data type since
-pcre32 functions are not implemented. There is a check for this in pcre_internal.h. */
-#ifndef PCRE_UCHAR32
-#define PCRE_UCHAR32 unsigned int
-#endif
-
-#ifndef PCRE_SPTR32
-#define PCRE_SPTR32 const PCRE_UCHAR32 *
-#endif
-
-/* When PCRE is compiled as a C++ library, the subject pointer type can be
-replaced with a custom type. For conventional use, the public interface is a
-const char *. */
-
-#ifndef PCRE_SPTR
-#define PCRE_SPTR const char *
-#endif
-
-/* The structure for passing additional data to pcre_exec(). This is defined in
-such as way as to be extensible. Always add new fields at the end, in order to
-remain compatible. */
-
-typedef struct pcre_extra {
- unsigned long int flags; /* Bits for which fields are set */
- void *study_data; /* Opaque data from pcre_study() */
- unsigned long int match_limit; /* Maximum number of calls to match() */
- void *callout_data; /* Data passed back in callouts */
- const unsigned char *tables; /* Pointer to character tables */
- unsigned long int match_limit_recursion; /* Max recursive calls to match() */
- unsigned char **mark; /* For passing back a mark pointer */
- void *executable_jit; /* Contains a pointer to a compiled jit code */
-} pcre_extra;
-
-/* Same structure as above, but with 16 bit char pointers. */
-
-typedef struct pcre16_extra {
- unsigned long int flags; /* Bits for which fields are set */
- void *study_data; /* Opaque data from pcre_study() */
- unsigned long int match_limit; /* Maximum number of calls to match() */
- void *callout_data; /* Data passed back in callouts */
- const unsigned char *tables; /* Pointer to character tables */
- unsigned long int match_limit_recursion; /* Max recursive calls to match() */
- PCRE_UCHAR16 **mark; /* For passing back a mark pointer */
- void *executable_jit; /* Contains a pointer to a compiled jit code */
-} pcre16_extra;
-
-/* Same structure as above, but with 32 bit char pointers. */
-
-typedef struct pcre32_extra {
- unsigned long int flags; /* Bits for which fields are set */
- void *study_data; /* Opaque data from pcre_study() */
- unsigned long int match_limit; /* Maximum number of calls to match() */
- void *callout_data; /* Data passed back in callouts */
- const unsigned char *tables; /* Pointer to character tables */
- unsigned long int match_limit_recursion; /* Max recursive calls to match() */
- PCRE_UCHAR32 **mark; /* For passing back a mark pointer */
- void *executable_jit; /* Contains a pointer to a compiled jit code */
-} pcre32_extra;
-
-/* The structure for passing out data via the pcre_callout_function. We use a
-structure so that new fields can be added on the end in future versions,
-without changing the API of the function, thereby allowing old clients to work
-without modification. */
-
-typedef struct pcre_callout_block {
- int version; /* Identifies version of block */
- /* ------------------------ Version 0 ------------------------------- */
- int callout_number; /* Number compiled into pattern */
- int *offset_vector; /* The offset vector */
- PCRE_SPTR subject; /* The subject being matched */
- int subject_length; /* The length of the subject */
- int start_match; /* Offset to start of this match attempt */
- int current_position; /* Where we currently are in the subject */
- int capture_top; /* Max current capture */
- int capture_last; /* Most recently closed capture */
- void *callout_data; /* Data passed in with the call */
- /* ------------------- Added for Version 1 -------------------------- */
- int pattern_position; /* Offset to next item in the pattern */
- int next_item_length; /* Length of next item in the pattern */
- /* ------------------- Added for Version 2 -------------------------- */
- const unsigned char *mark; /* Pointer to current mark or NULL */
- /* ------------------------------------------------------------------ */
-} pcre_callout_block;
-
-/* Same structure as above, but with 16 bit char pointers. */
-
-typedef struct pcre16_callout_block {
- int version; /* Identifies version of block */
- /* ------------------------ Version 0 ------------------------------- */
- int callout_number; /* Number compiled into pattern */
- int *offset_vector; /* The offset vector */
- PCRE_SPTR16 subject; /* The subject being matched */
- int subject_length; /* The length of the subject */
- int start_match; /* Offset to start of this match attempt */
- int current_position; /* Where we currently are in the subject */
- int capture_top; /* Max current capture */
- int capture_last; /* Most recently closed capture */
- void *callout_data; /* Data passed in with the call */
- /* ------------------- Added for Version 1 -------------------------- */
- int pattern_position; /* Offset to next item in the pattern */
- int next_item_length; /* Length of next item in the pattern */
- /* ------------------- Added for Version 2 -------------------------- */
- const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */
- /* ------------------------------------------------------------------ */
-} pcre16_callout_block;
-
-/* Same structure as above, but with 32 bit char pointers. */
-
-typedef struct pcre32_callout_block {
- int version; /* Identifies version of block */
- /* ------------------------ Version 0 ------------------------------- */
- int callout_number; /* Number compiled into pattern */
- int *offset_vector; /* The offset vector */
- PCRE_SPTR32 subject; /* The subject being matched */
- int subject_length; /* The length of the subject */
- int start_match; /* Offset to start of this match attempt */
- int current_position; /* Where we currently are in the subject */
- int capture_top; /* Max current capture */
- int capture_last; /* Most recently closed capture */
- void *callout_data; /* Data passed in with the call */
- /* ------------------- Added for Version 1 -------------------------- */
- int pattern_position; /* Offset to next item in the pattern */
- int next_item_length; /* Length of next item in the pattern */
- /* ------------------- Added for Version 2 -------------------------- */
- const PCRE_UCHAR32 *mark; /* Pointer to current mark or NULL */
- /* ------------------------------------------------------------------ */
-} pcre32_callout_block;
-
-/* Indirection for store get and free functions. These can be set to
-alternative malloc/free functions if required. Special ones are used in the
-non-recursive case for "frames". There is also an optional callout function
-that is triggered by the (?) regex item. For Virtual Pascal, these definitions
-have to take another form. */
-
-#ifndef VPCOMPAT
-PCRE_EXP_DECL void *(*pcre_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre_free)(void *);
-PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre_stack_free)(void *);
-PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *);
-
-PCRE_EXP_DECL void *(*pcre16_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre16_free)(void *);
-PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre16_stack_free)(void *);
-PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *);
-
-PCRE_EXP_DECL void *(*pcre32_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre32_free)(void *);
-PCRE_EXP_DECL void *(*pcre32_stack_malloc)(size_t);
-PCRE_EXP_DECL void (*pcre32_stack_free)(void *);
-PCRE_EXP_DECL int (*pcre32_callout)(pcre32_callout_block *);
-#else /* VPCOMPAT */
-PCRE_EXP_DECL void *pcre_malloc(size_t);
-PCRE_EXP_DECL void pcre_free(void *);
-PCRE_EXP_DECL void *pcre_stack_malloc(size_t);
-PCRE_EXP_DECL void pcre_stack_free(void *);
-PCRE_EXP_DECL int pcre_callout(pcre_callout_block *);
-
-PCRE_EXP_DECL void *pcre16_malloc(size_t);
-PCRE_EXP_DECL void pcre16_free(void *);
-PCRE_EXP_DECL void *pcre16_stack_malloc(size_t);
-PCRE_EXP_DECL void pcre16_stack_free(void *);
-PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *);
-
-PCRE_EXP_DECL void *pcre32_malloc(size_t);
-PCRE_EXP_DECL void pcre32_free(void *);
-PCRE_EXP_DECL void *pcre32_stack_malloc(size_t);
-PCRE_EXP_DECL void pcre32_stack_free(void *);
-PCRE_EXP_DECL int pcre32_callout(pcre32_callout_block *);
-#endif /* VPCOMPAT */
-
-/* User defined callback which provides a stack just before the match starts. */
-
-typedef pcre_jit_stack *(*pcre_jit_callback)(void *);
-typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *);
-typedef pcre32_jit_stack *(*pcre32_jit_callback)(void *);
-
-/* Exported PCRE functions */
-
-PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
- const unsigned char *);
-PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *,
- const unsigned char *);
-PCRE_EXP_DECL pcre32 *pcre32_compile(PCRE_SPTR32, int, const char **, int *,
- const unsigned char *);
-PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
- int *, const unsigned char *);
-PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **,
- int *, const unsigned char *);
-PCRE_EXP_DECL pcre32 *pcre32_compile2(PCRE_SPTR32, int, int *, const char **,
- int *, const unsigned char *);
-PCRE_EXP_DECL int pcre_config(int, void *);
-PCRE_EXP_DECL int pcre16_config(int, void *);
-PCRE_EXP_DECL int pcre32_config(int, void *);
-PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *,
- int *, int, const char *, char *, int);
-PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16,
- int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int);
-PCRE_EXP_DECL int pcre32_copy_named_substring(const pcre32 *, PCRE_SPTR32,
- int *, int, PCRE_SPTR32, PCRE_UCHAR32 *, int);
-PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int,
- char *, int);
-PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int,
- PCRE_UCHAR16 *, int);
-PCRE_EXP_DECL int pcre32_copy_substring(PCRE_SPTR32, int *, int, int,
- PCRE_UCHAR32 *, int);
-PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *,
- const char *, int, int, int, int *, int , int *, int);
-PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *,
- PCRE_SPTR16, int, int, int, int *, int , int *, int);
-PCRE_EXP_DECL int pcre32_dfa_exec(const pcre32 *, const pcre32_extra *,
- PCRE_SPTR32, int, int, int, int *, int , int *, int);
-PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
- int, int, int, int *, int);
-PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *,
- PCRE_SPTR16, int, int, int, int *, int);
-PCRE_EXP_DECL int pcre32_exec(const pcre32 *, const pcre32_extra *,
- PCRE_SPTR32, int, int, int, int *, int);
-PCRE_EXP_DECL int pcre_jit_exec(const pcre *, const pcre_extra *,
- PCRE_SPTR, int, int, int, int *, int,
- pcre_jit_stack *);
-PCRE_EXP_DECL int pcre16_jit_exec(const pcre16 *, const pcre16_extra *,
- PCRE_SPTR16, int, int, int, int *, int,
- pcre16_jit_stack *);
-PCRE_EXP_DECL int pcre32_jit_exec(const pcre32 *, const pcre32_extra *,
- PCRE_SPTR32, int, int, int, int *, int,
- pcre32_jit_stack *);
-PCRE_EXP_DECL void pcre_free_substring(const char *);
-PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16);
-PCRE_EXP_DECL void pcre32_free_substring(PCRE_SPTR32);
-PCRE_EXP_DECL void pcre_free_substring_list(const char **);
-PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *);
-PCRE_EXP_DECL void pcre32_free_substring_list(PCRE_SPTR32 *);
-PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int,
- void *);
-PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int,
- void *);
-PCRE_EXP_DECL int pcre32_fullinfo(const pcre32 *, const pcre32_extra *, int,
- void *);
-PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *,
- int *, int, const char *, const char **);
-PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16,
- int *, int, PCRE_SPTR16, PCRE_SPTR16 *);
-PCRE_EXP_DECL int pcre32_get_named_substring(const pcre32 *, PCRE_SPTR32,
- int *, int, PCRE_SPTR32, PCRE_SPTR32 *);
-PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *);
-PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16);
-PCRE_EXP_DECL int pcre32_get_stringnumber(const pcre32 *, PCRE_SPTR32);
-PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *,
- char **, char **);
-PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16,
- PCRE_UCHAR16 **, PCRE_UCHAR16 **);
-PCRE_EXP_DECL int pcre32_get_stringtable_entries(const pcre32 *, PCRE_SPTR32,
- PCRE_UCHAR32 **, PCRE_UCHAR32 **);
-PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int,
- const char **);
-PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int,
- PCRE_SPTR16 *);
-PCRE_EXP_DECL int pcre32_get_substring(PCRE_SPTR32, int *, int, int,
- PCRE_SPTR32 *);
-PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int,
- const char ***);
-PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int,
- PCRE_SPTR16 **);
-PCRE_EXP_DECL int pcre32_get_substring_list(PCRE_SPTR32, int *, int,
- PCRE_SPTR32 **);
-PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
-PCRE_EXP_DECL const unsigned char *pcre16_maketables(void);
-PCRE_EXP_DECL const unsigned char *pcre32_maketables(void);
-PCRE_EXP_DECL int pcre_refcount(pcre *, int);
-PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int);
-PCRE_EXP_DECL int pcre32_refcount(pcre32 *, int);
-PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
-PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **);
-PCRE_EXP_DECL pcre32_extra *pcre32_study(const pcre32 *, int, const char **);
-PCRE_EXP_DECL void pcre_free_study(pcre_extra *);
-PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *);
-PCRE_EXP_DECL void pcre32_free_study(pcre32_extra *);
-PCRE_EXP_DECL const char *pcre_version(void);
-PCRE_EXP_DECL const char *pcre16_version(void);
-PCRE_EXP_DECL const char *pcre32_version(void);
-
-/* Utility functions for byte order swaps. */
-PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *,
- const unsigned char *);
-PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *,
- const unsigned char *);
-PCRE_EXP_DECL int pcre32_pattern_to_host_byte_order(pcre32 *, pcre32_extra *,
- const unsigned char *);
-PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *,
- PCRE_SPTR16, int, int *, int);
-PCRE_EXP_DECL int pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *,
- PCRE_SPTR32, int, int *, int);
-
-/* JIT compiler related functions. */
-
-PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int);
-PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int);
-PCRE_EXP_DECL pcre32_jit_stack *pcre32_jit_stack_alloc(int, int);
-PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *);
-PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *);
-PCRE_EXP_DECL void pcre32_jit_stack_free(pcre32_jit_stack *);
-PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *,
- pcre_jit_callback, void *);
-PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *,
- pcre16_jit_callback, void *);
-PCRE_EXP_DECL void pcre32_assign_jit_stack(pcre32_extra *,
- pcre32_jit_callback, void *);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* End of pcre.h */
diff --git a/usr.sbin/nginx/src/pcre/pcre_chartables.c b/usr.sbin/nginx/src/pcre/pcre_chartables.c
deleted file mode 100644
index 2a39e9ff33a..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre_chartables.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* This file contains character tables that are used when no external tables
-are passed to PCRE by the application that calls it. The tables are used only
-for characters whose code values are less than 256.
-
-This is a default version of the tables that assumes ASCII encoding. A program
-called dftables (which is distributed with PCRE) can be used to build
-alternative versions of this file. This is necessary if you are running in an
-EBCDIC environment, or if you want to default to a different encoding, for
-example ISO-8859-1. When dftables is run, it creates these tables in the
-current locale. If PCRE is configured with --enable-rebuild-chartables, this
-happens automatically.
-
-The following #includes are present because without them gcc 4.x may remove the
-array definition from the final binary if PCRE is built into a static library
-and dead code stripping is activated. This leads to link errors. Pulling in the
-header ensures that the array gets flagged as "someone outside this compilation
-unit might reference this" and so it will always be supplied to the linker. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-const pcre_uint8 PRIV(default_tables)[] = {
-
-/* This table is a lower casing table. */
-
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122, 91, 92, 93, 94, 95,
- 96, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122,123,124,125,126,127,
- 128,129,130,131,132,133,134,135,
- 136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,
- 152,153,154,155,156,157,158,159,
- 160,161,162,163,164,165,166,167,
- 168,169,170,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,
- 184,185,186,187,188,189,190,191,
- 192,193,194,195,196,197,198,199,
- 200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,215,
- 216,217,218,219,220,221,222,223,
- 224,225,226,227,228,229,230,231,
- 232,233,234,235,236,237,238,239,
- 240,241,242,243,244,245,246,247,
- 248,249,250,251,252,253,254,255,
-
-/* This table is a case flipping table. */
-
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 97, 98, 99,100,101,102,103,
- 104,105,106,107,108,109,110,111,
- 112,113,114,115,116,117,118,119,
- 120,121,122, 91, 92, 93, 94, 95,
- 96, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79,
- 80, 81, 82, 83, 84, 85, 86, 87,
- 88, 89, 90,123,124,125,126,127,
- 128,129,130,131,132,133,134,135,
- 136,137,138,139,140,141,142,143,
- 144,145,146,147,148,149,150,151,
- 152,153,154,155,156,157,158,159,
- 160,161,162,163,164,165,166,167,
- 168,169,170,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,
- 184,185,186,187,188,189,190,191,
- 192,193,194,195,196,197,198,199,
- 200,201,202,203,204,205,206,207,
- 208,209,210,211,212,213,214,215,
- 216,217,218,219,220,221,222,223,
- 224,225,226,227,228,229,230,231,
- 232,233,234,235,236,237,238,239,
- 240,241,242,243,244,245,246,247,
- 248,249,250,251,252,253,254,255,
-
-/* This table contains bit maps for various character classes. Each map is 32
-bytes long and the bits run from the least significant end of each byte. The
-classes that have their own maps are: space, xdigit, digit, upper, lower, word,
-graph, print, punct, and cntrl. Other classes are built from combinations. */
-
- 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
- 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
- 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
- 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
- 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-
-/* This table identifies various classes of character by individual bits:
- 0x01 white space character
- 0x02 letter
- 0x04 decimal digit
- 0x08 hexadecimal digit
- 0x10 alphanumeric or '_'
- 0x80 regular expression metacharacter or binary zero
-*/
-
- 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
- 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */
- 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */
- 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
- 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */
- 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */
- 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */
- 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */
- 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */
- 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
-
-/* End of pcre_chartables.c */
diff --git a/usr.sbin/nginx/src/pcre/pcre_compile.c b/usr.sbin/nginx/src/pcre/pcre_compile.c
deleted file mode 100644
index ce8e47bbe96..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre_compile.c
+++ /dev/null
@@ -1,8436 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2013 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_compile(), along with
-supporting internal functions that are not used by other modules. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#define NLBLOCK cd /* Block containing newline information */
-#define PSSTART start_pattern /* Field containing processed string start */
-#define PSEND end_pattern /* Field containing processed string end */
-
-#include "pcre_internal.h"
-
-
-/* When PCRE_DEBUG is defined, we need the pcre(16|32)_printint() function, which
-is also used by pcretest. PCRE_DEBUG is not defined when building a production
-library. We do not need to select pcre16_printint.c specially, because the
-COMPILE_PCREx macro will already be appropriately set. */
-
-#ifdef PCRE_DEBUG
-/* pcre_printint.c should not include any headers */
-#define PCRE_INCLUDED
-#include "pcre_printint.c"
-#undef PCRE_INCLUDED
-#endif
-
-
-/* Macro for setting individual bits in class bitmaps. */
-
-#define SETBIT(a,b) a[(b)/8] |= (1 << ((b)&7))
-
-/* Maximum length value to check against when making sure that the integer that
-holds the compiled pattern length does not overflow. We make it a bit less than
-INT_MAX to allow for adding in group terminating bytes, so that we don't have
-to check them every time. */
-
-#define OFLOW_MAX (INT_MAX - 20)
-
-/* Definitions to allow mutual recursion */
-
-static int
- add_list_to_class(pcre_uint8 *, pcre_uchar **, int, compile_data *,
- const pcre_uint32 *, unsigned int);
-
-static BOOL
- compile_regex(int, pcre_uchar **, const pcre_uchar **, int *, BOOL, BOOL, int, int,
- pcre_uint32 *, pcre_int32 *, pcre_uint32 *, pcre_int32 *, branch_chain *,
- compile_data *, int *);
-
-
-
-/*************************************************
-* Code parameters and static tables *
-*************************************************/
-
-/* This value specifies the size of stack workspace that is used during the
-first pre-compile phase that determines how much memory is required. The regex
-is partly compiled into this space, but the compiled parts are discarded as
-soon as they can be, so that hopefully there will never be an overrun. The code
-does, however, check for an overrun. The largest amount I've seen used is 218,
-so this number is very generous.
-
-The same workspace is used during the second, actual compile phase for
-remembering forward references to groups so that they can be filled in at the
-end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE
-is 4 there is plenty of room for most patterns. However, the memory can get
-filled up by repetitions of forward references, for example patterns like
-/(?1){0,1999}(b)/, and one user did hit the limit. The code has been changed so
-that the workspace is expanded using malloc() in this situation. The value
-below is therefore a minimum, and we put a maximum on it for safety. The
-minimum is now also defined in terms of LINK_SIZE so that the use of malloc()
-kicks in at the same number of forward references in all cases. */
-
-#define COMPILE_WORK_SIZE (2048*LINK_SIZE)
-#define COMPILE_WORK_SIZE_MAX (100*COMPILE_WORK_SIZE)
-
-/* The overrun tests check for a slightly smaller size so that they detect the
-overrun before it actually does run off the end of the data block. */
-
-#define WORK_SIZE_SAFETY_MARGIN (100)
-
-/* Private flags added to firstchar and reqchar. */
-
-#define REQ_CASELESS (1 << 0) /* Indicates caselessness */
-#define REQ_VARY (1 << 1) /* Reqchar followed non-literal item */
-/* Negative values for the firstchar and reqchar flags */
-#define REQ_UNSET (-2)
-#define REQ_NONE (-1)
-
-/* Repeated character flags. */
-
-#define UTF_LENGTH 0x10000000l /* The char contains its length. */
-
-/* Table for handling escaped characters in the range '0'-'z'. Positive returns
-are simple data values; negative values are for special things like \d and so
-on. Zero means further processing is needed (for things like \x), or the escape
-is invalid. */
-
-#ifndef EBCDIC
-
-/* This is the "normal" table for ASCII systems or for EBCDIC systems running
-in UTF-8 mode. */
-
-static const short int escapes[] = {
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- 0, 0,
- CHAR_COLON, CHAR_SEMICOLON,
- CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN,
- CHAR_GREATER_THAN_SIGN, CHAR_QUESTION_MARK,
- CHAR_COMMERCIAL_AT, -ESC_A,
- -ESC_B, -ESC_C,
- -ESC_D, -ESC_E,
- 0, -ESC_G,
- -ESC_H, 0,
- 0, -ESC_K,
- 0, 0,
- -ESC_N, 0,
- -ESC_P, -ESC_Q,
- -ESC_R, -ESC_S,
- 0, 0,
- -ESC_V, -ESC_W,
- -ESC_X, 0,
- -ESC_Z, CHAR_LEFT_SQUARE_BRACKET,
- CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET,
- CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE,
- CHAR_GRAVE_ACCENT, 7,
- -ESC_b, 0,
- -ESC_d, ESC_e,
- ESC_f, 0,
- -ESC_h, 0,
- 0, -ESC_k,
- 0, 0,
- ESC_n, 0,
- -ESC_p, 0,
- ESC_r, -ESC_s,
- ESC_tee, 0,
- -ESC_v, -ESC_w,
- 0, 0,
- -ESC_z
-};
-
-#else
-
-/* This is the "abnormal" table for EBCDIC systems without UTF-8 support. */
-
-static const short int escapes[] = {
-/* 48 */ 0, 0, 0, '.', '<', '(', '+', '|',
-/* 50 */ '&', 0, 0, 0, 0, 0, 0, 0,
-/* 58 */ 0, 0, '!', '$', '*', ')', ';', '~',
-/* 60 */ '-', '/', 0, 0, 0, 0, 0, 0,
-/* 68 */ 0, 0, '|', ',', '%', '_', '>', '?',
-/* 70 */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* 78 */ 0, '`', ':', '#', '@', '\'', '=', '"',
-/* 80 */ 0, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0,
-/* 88 */-ESC_h, 0, 0, '{', 0, 0, 0, 0,
-/* 90 */ 0, 0, -ESC_k, 'l', 0, ESC_n, 0, -ESC_p,
-/* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0,
-/* A0 */ 0, '~', -ESC_s, ESC_tee, 0,-ESC_v, -ESC_w, 0,
-/* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0,
-/* B0 */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* B8 */ 0, 0, 0, 0, 0, ']', '=', '-',
-/* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G,
-/* C8 */-ESC_H, 0, 0, 0, 0, 0, 0, 0,
-/* D0 */ '}', 0, -ESC_K, 0, 0,-ESC_N, 0, -ESC_P,
-/* D8 */-ESC_Q,-ESC_R, 0, 0, 0, 0, 0, 0,
-/* E0 */ '\\', 0, -ESC_S, 0, 0,-ESC_V, -ESC_W, -ESC_X,
-/* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0,
-/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* F8 */ 0, 0, 0, 0, 0, 0, 0, 0
-};
-#endif
-
-
-/* Table of special "verbs" like (*PRUNE). This is a short table, so it is
-searched linearly. Put all the names into a single string, in order to reduce
-the number of relocations when a shared library is dynamically linked. The
-string is built from string macros so that it works in UTF-8 mode on EBCDIC
-platforms. */
-
-typedef struct verbitem {
- int len; /* Length of verb name */
- int op; /* Op when no arg, or -1 if arg mandatory */
- int op_arg; /* Op when arg present, or -1 if not allowed */
-} verbitem;
-
-static const char verbnames[] =
- "\0" /* Empty name is a shorthand for MARK */
- STRING_MARK0
- STRING_ACCEPT0
- STRING_COMMIT0
- STRING_F0
- STRING_FAIL0
- STRING_PRUNE0
- STRING_SKIP0
- STRING_THEN;
-
-static const verbitem verbs[] = {
- { 0, -1, OP_MARK },
- { 4, -1, OP_MARK },
- { 6, OP_ACCEPT, -1 },
- { 6, OP_COMMIT, -1 },
- { 1, OP_FAIL, -1 },
- { 4, OP_FAIL, -1 },
- { 5, OP_PRUNE, OP_PRUNE_ARG },
- { 4, OP_SKIP, OP_SKIP_ARG },
- { 4, OP_THEN, OP_THEN_ARG }
-};
-
-static const int verbcount = sizeof(verbs)/sizeof(verbitem);
-
-
-/* Tables of names of POSIX character classes and their lengths. The names are
-now all in a single string, to reduce the number of relocations when a shared
-library is dynamically loaded. The list of lengths is terminated by a zero
-length entry. The first three must be alpha, lower, upper, as this is assumed
-for handling case independence. */
-
-static const char posix_names[] =
- STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0
- STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0
- STRING_graph0 STRING_print0 STRING_punct0 STRING_space0
- STRING_word0 STRING_xdigit;
-
-static const pcre_uint8 posix_name_lengths[] = {
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };
-
-/* Table of class bit maps for each POSIX class. Each class is formed from a
-base map, with an optional addition or removal of another map. Then, for some
-classes, there is some additional tweaking: for [:blank:] the vertical space
-characters are removed, and for [:alpha:] and [:alnum:] the underscore
-character is removed. The triples in the table consist of the base map offset,
-second map offset or -1 if no second map, and a non-negative value for map
-addition or a negative value for map subtraction (if there are two maps). The
-absolute value of the third field has these meanings: 0 => no tweaking, 1 =>
-remove vertical space characters, 2 => remove underscore. */
-
-static const int posix_class_maps[] = {
- cbit_word, cbit_digit, -2, /* alpha */
- cbit_lower, -1, 0, /* lower */
- cbit_upper, -1, 0, /* upper */
- cbit_word, -1, 2, /* alnum - word without underscore */
- cbit_print, cbit_cntrl, 0, /* ascii */
- cbit_space, -1, 1, /* blank - a GNU extension */
- cbit_cntrl, -1, 0, /* cntrl */
- cbit_digit, -1, 0, /* digit */
- cbit_graph, -1, 0, /* graph */
- cbit_print, -1, 0, /* print */
- cbit_punct, -1, 0, /* punct */
- cbit_space, -1, 0, /* space */
- cbit_word, -1, 0, /* word - a Perl extension */
- cbit_xdigit,-1, 0 /* xdigit */
-};
-
-/* Table of substitutes for \d etc when PCRE_UCP is set. The POSIX class
-substitutes must be in the order of the names, defined above, and there are
-both positive and negative cases. NULL means no substitute. */
-
-#ifdef SUPPORT_UCP
-static const pcre_uchar string_PNd[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_pNd[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_PXsp[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_pXsp[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_PXwd[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_pXwd[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-
-static const pcre_uchar *substitutes[] = {
- string_PNd, /* \D */
- string_pNd, /* \d */
- string_PXsp, /* \S */ /* NOTE: Xsp is Perl space */
- string_pXsp, /* \s */
- string_PXwd, /* \W */
- string_pXwd /* \w */
-};
-
-static const pcre_uchar string_pL[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_pLl[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_pLu[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_pXan[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_h[] = {
- CHAR_BACKSLASH, CHAR_h, '\0' };
-static const pcre_uchar string_pXps[] = {
- CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_PL[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_PLl[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_PLu[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_PXan[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-static const pcre_uchar string_H[] = {
- CHAR_BACKSLASH, CHAR_H, '\0' };
-static const pcre_uchar string_PXps[] = {
- CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
- CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' };
-
-static const pcre_uchar *posix_substitutes[] = {
- string_pL, /* alpha */
- string_pLl, /* lower */
- string_pLu, /* upper */
- string_pXan, /* alnum */
- NULL, /* ascii */
- string_h, /* blank */
- NULL, /* cntrl */
- string_pNd, /* digit */
- NULL, /* graph */
- NULL, /* print */
- NULL, /* punct */
- string_pXps, /* space */ /* NOTE: Xps is POSIX space */
- string_pXwd, /* word */
- NULL, /* xdigit */
- /* Negated cases */
- string_PL, /* ^alpha */
- string_PLl, /* ^lower */
- string_PLu, /* ^upper */
- string_PXan, /* ^alnum */
- NULL, /* ^ascii */
- string_H, /* ^blank */
- NULL, /* ^cntrl */
- string_PNd, /* ^digit */
- NULL, /* ^graph */
- NULL, /* ^print */
- NULL, /* ^punct */
- string_PXps, /* ^space */ /* NOTE: Xps is POSIX space */
- string_PXwd, /* ^word */
- NULL /* ^xdigit */
-};
-#define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(pcre_uchar *))
-#endif
-
-#define STRING(a) # a
-#define XSTRING(s) STRING(s)
-
-/* The texts of compile-time error messages. These are "char *" because they
-are passed to the outside world. Do not ever re-use any error number, because
-they are documented. Always add a new error instead. Messages marked DEAD below
-are no longer used. This used to be a table of strings, but in order to reduce
-the number of relocations needed when a shared library is loaded dynamically,
-it is now one long string. We cannot use a table of offsets, because the
-lengths of inserts such as XSTRING(MAX_NAME_SIZE) are not known. Instead, we
-simply count through to the one we want - this isn't a performance issue
-because these strings are used only when there is a compilation error.
-
-Each substring ends with \0 to insert a null character. This includes the final
-substring, so that the whole string ends with \0\0, which can be detected when
-counting through. */
-
-static const char error_texts[] =
- "no error\0"
- "\\ at end of pattern\0"
- "\\c at end of pattern\0"
- "unrecognized character follows \\\0"
- "numbers out of order in {} quantifier\0"
- /* 5 */
- "number too big in {} quantifier\0"
- "missing terminating ] for character class\0"
- "invalid escape sequence in character class\0"
- "range out of order in character class\0"
- "nothing to repeat\0"
- /* 10 */
- "operand of unlimited repeat could match the empty string\0" /** DEAD **/
- "internal error: unexpected repeat\0"
- "unrecognized character after (? or (?-\0"
- "POSIX named classes are supported only within a class\0"
- "missing )\0"
- /* 15 */
- "reference to non-existent subpattern\0"
- "erroffset passed as NULL\0"
- "unknown option bit(s) set\0"
- "missing ) after comment\0"
- "parentheses nested too deeply\0" /** DEAD **/
- /* 20 */
- "regular expression is too large\0"
- "failed to get memory\0"
- "unmatched parentheses\0"
- "internal error: code overflow\0"
- "unrecognized character after (?<\0"
- /* 25 */
- "lookbehind assertion is not fixed length\0"
- "malformed number or name after (?(\0"
- "conditional group contains more than two branches\0"
- "assertion expected after (?(\0"
- "(?R or (?[+-]digits must be followed by )\0"
- /* 30 */
- "unknown POSIX class name\0"
- "POSIX collating elements are not supported\0"
- "this version of PCRE is compiled without UTF support\0"
- "spare error\0" /** DEAD **/
- "character value in \\x{...} sequence is too large\0"
- /* 35 */
- "invalid condition (?(0)\0"
- "\\C not allowed in lookbehind assertion\0"
- "PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0"
- "number after (?C is > 255\0"
- "closing ) for (?C expected\0"
- /* 40 */
- "recursive call could loop indefinitely\0"
- "unrecognized character after (?P\0"
- "syntax error in subpattern name (missing terminator)\0"
- "two named subpatterns have the same name\0"
- "invalid UTF-8 string\0"
- /* 45 */
- "support for \\P, \\p, and \\X has not been compiled\0"
- "malformed \\P or \\p sequence\0"
- "unknown property name after \\P or \\p\0"
- "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)\0"
- "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0"
- /* 50 */
- "repeated subpattern is too long\0" /** DEAD **/
- "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0"
- "internal error: overran compiling workspace\0"
- "internal error: previously-checked referenced subpattern not found\0"
- "DEFINE group contains more than one branch\0"
- /* 55 */
- "repeating a DEFINE group is not allowed\0" /** DEAD **/
- "inconsistent NEWLINE options\0"
- "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0"
- "a numbered reference must not be zero\0"
- "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0"
- /* 60 */
- "(*VERB) not recognized or malformed\0"
- "number is too big\0"
- "subpattern name expected\0"
- "digit expected after (?+\0"
- "] is an invalid data character in JavaScript compatibility mode\0"
- /* 65 */
- "different names for subpatterns of the same number are not allowed\0"
- "(*MARK) must have an argument\0"
- "this version of PCRE is not compiled with Unicode property support\0"
- "\\c must be followed by an ASCII character\0"
- "\\k is not followed by a braced, angle-bracketed, or quoted name\0"
- /* 70 */
- "internal error: unknown opcode in find_fixedlength()\0"
- "\\N is not supported in a class\0"
- "too many forward references\0"
- "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0"
- "invalid UTF-16 string\0"
- /* 75 */
- "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0"
- "character value in \\u.... sequence is too large\0"
- "invalid UTF-32 string\0"
- "setting UTF is disabled by the application\0"
- ;
-
-/* Table to identify digits and hex digits. This is used when compiling
-patterns. Note that the tables in chartables are dependent on the locale, and
-may mark arbitrary characters as digits - but the PCRE compiling code expects
-to handle only 0-9, a-z, and A-Z as digits when compiling. That is why we have
-a private table here. It costs 256 bytes, but it is a lot faster than doing
-character value tests (at least in some simple cases I timed), and in some
-applications one wants PCRE to compile efficiently as well as match
-efficiently.
-
-For convenience, we use the same bit definitions as in chartables:
-
- 0x04 decimal digit
- 0x08 hexadecimal digit
-
-Then we can use ctype_digit and ctype_xdigit in the code. */
-
-/* Using a simple comparison for decimal numbers rather than a memory read
-is much faster, and the resulting code is simpler (the compiler turns it
-into a subtraction and unsigned comparison). */
-
-#define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9)
-
-#ifndef EBCDIC
-
-/* This is the "normal" case, for ASCII systems, and EBCDIC systems running in
-UTF-8 mode. */
-
-static const pcre_uint8 digitab[] =
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */
- 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 */
- 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */
- 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* @ - G */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H - O */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* P - W */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* X - _ */
- 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* ` - g */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h - o */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p - w */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x -127 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
-
-#else
-
-/* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */
-
-static const pcre_uint8 digitab[] =
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 10 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32- 39 20 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 30 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 40 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 72- | */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 50 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 88- 95 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 60 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 104- ? */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 70 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */
- 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* 128- g 80 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144- p 90 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160- x A0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 B0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* { - G C0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* } - P D0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* \ - X E0 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */
- 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */
- 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
-
-static const pcre_uint8 ebcdic_chartab[] = { /* chartable partial dup */
- 0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 0- 7 */
- 0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
- 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 16- 23 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
- 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 32- 39 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */
- 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 */
- 0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80, /* 72- | */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 */
- 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, /* 88- 95 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 */
- 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x80, /* 104- ? */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */
- 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* 128- g */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */
- 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 144- p */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */
- 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* 160- x */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */
- 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 */
- 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
- 0x80,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* { - G */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */
- 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* } - P */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */
- 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* \ - X */
- 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */
- 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
- 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
-#endif
-
-
-
-/*************************************************
-* Find an error text *
-*************************************************/
-
-/* The error texts are now all in one long string, to save on relocations. As
-some of the text is of unknown length, we can't use a table of offsets.
-Instead, just count through the strings. This is not a performance issue
-because it happens only when there has been a compilation error.
-
-Argument: the error number
-Returns: pointer to the error string
-*/
-
-static const char *
-find_error_text(int n)
-{
-const char *s = error_texts;
-for (; n > 0; n--)
- {
- while (*s++ != CHAR_NULL) {};
- if (*s == CHAR_NULL) return "Error text not found (please report)";
- }
-return s;
-}
-
-
-/*************************************************
-* Expand the workspace *
-*************************************************/
-
-/* This function is called during the second compiling phase, if the number of
-forward references fills the existing workspace, which is originally a block on
-the stack. A larger block is obtained from malloc() unless the ultimate limit
-has been reached or the increase will be rather small.
-
-Argument: pointer to the compile data block
-Returns: 0 if all went well, else an error number
-*/
-
-static int
-expand_workspace(compile_data *cd)
-{
-pcre_uchar *newspace;
-int newsize = cd->workspace_size * 2;
-
-if (newsize > COMPILE_WORK_SIZE_MAX) newsize = COMPILE_WORK_SIZE_MAX;
-if (cd->workspace_size >= COMPILE_WORK_SIZE_MAX ||
- newsize - cd->workspace_size < WORK_SIZE_SAFETY_MARGIN)
- return ERR72;
-
-newspace = (PUBL(malloc))(IN_UCHARS(newsize));
-if (newspace == NULL) return ERR21;
-memcpy(newspace, cd->start_workspace, cd->workspace_size * sizeof(pcre_uchar));
-cd->hwm = (pcre_uchar *)newspace + (cd->hwm - cd->start_workspace);
-if (cd->workspace_size > COMPILE_WORK_SIZE)
- (PUBL(free))((void *)cd->start_workspace);
-cd->start_workspace = newspace;
-cd->workspace_size = newsize;
-return 0;
-}
-
-
-
-/*************************************************
-* Check for counted repeat *
-*************************************************/
-
-/* This function is called when a '{' is encountered in a place where it might
-start a quantifier. It looks ahead to see if it really is a quantifier or not.
-It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd}
-where the ddds are digits.
-
-Arguments:
- p pointer to the first char after '{'
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-is_counted_repeat(const pcre_uchar *p)
-{
-if (!IS_DIGIT(*p)) return FALSE;
-p++;
-while (IS_DIGIT(*p)) p++;
-if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
-
-if (*p++ != CHAR_COMMA) return FALSE;
-if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
-
-if (!IS_DIGIT(*p)) return FALSE;
-p++;
-while (IS_DIGIT(*p)) p++;
-
-return (*p == CHAR_RIGHT_CURLY_BRACKET);
-}
-
-
-
-/*************************************************
-* Handle escapes *
-*************************************************/
-
-/* This function is called when a \ has been encountered. It either returns a
-positive value for a simple escape such as \n, or 0 for a data character
-which will be placed in chptr. A backreference to group n is returned as
-negative n. When UTF-8 is enabled, a positive value greater than 255 may
-be returned in chptr.
-On entry,ptr is pointing at the \. On exit, it is on the final character of the
-escape sequence.
-
-Arguments:
- ptrptr points to the pattern position pointer
- chptr points to the data character
- errorcodeptr points to the errorcode variable
- bracount number of previous extracting brackets
- options the options bits
- isclass TRUE if inside a character class
-
-Returns: zero => a data character
- positive => a special escape sequence
- negative => a back reference
- on error, errorcodeptr is set
-*/
-
-static int
-check_escape(const pcre_uchar **ptrptr, pcre_uint32 *chptr, int *errorcodeptr,
- int bracount, int options, BOOL isclass)
-{
-/* PCRE_UTF16 has the same value as PCRE_UTF8. */
-BOOL utf = (options & PCRE_UTF8) != 0;
-const pcre_uchar *ptr = *ptrptr + 1;
-pcre_uint32 c;
-int escape = 0;
-int i;
-
-GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */
-ptr--; /* Set pointer back to the last byte */
-
-/* If backslash is at the end of the pattern, it's an error. */
-
-if (c == CHAR_NULL) *errorcodeptr = ERR1;
-
-/* Non-alphanumerics are literals. For digits or letters, do an initial lookup
-in a table. A non-zero result is something that can be returned immediately.
-Otherwise further processing may be required. */
-
-#ifndef EBCDIC /* ASCII/UTF-8 coding */
-/* Not alphanumeric */
-else if (c < CHAR_0 || c > CHAR_z) {}
-else if ((i = escapes[c - CHAR_0]) != 0)
- { if (i > 0) c = (pcre_uint32)i; else escape = -i; }
-
-#else /* EBCDIC coding */
-/* Not alphanumeric */
-else if (c < CHAR_a || (!MAX_255(c) || (ebcdic_chartab[c] & 0x0E) == 0)) {}
-else if ((i = escapes[c - 0x48]) != 0) { if (i > 0) c = (pcre_uint32)i; else escape = -i; }
-#endif
-
-/* Escapes that need further processing, or are illegal. */
-
-else
- {
- const pcre_uchar *oldptr;
- BOOL braced, negated, overflow;
- int s;
-
- switch (c)
- {
- /* A number of Perl escapes are not handled by PCRE. We give an explicit
- error. */
-
- case CHAR_l:
- case CHAR_L:
- *errorcodeptr = ERR37;
- break;
-
- case CHAR_u:
- if ((options & PCRE_JAVASCRIPT_COMPAT) != 0)
- {
- /* In JavaScript, \u must be followed by four hexadecimal numbers.
- Otherwise it is a lowercase u letter. */
- if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0
- && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0
- && MAX_255(ptr[3]) && (digitab[ptr[3]] & ctype_xdigit) != 0
- && MAX_255(ptr[4]) && (digitab[ptr[4]] & ctype_xdigit) != 0)
- {
- c = 0;
- for (i = 0; i < 4; ++i)
- {
- register pcre_uint32 cc = *(++ptr);
-#ifndef EBCDIC /* ASCII/UTF-8 coding */
- if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
- c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
-#else /* EBCDIC coding */
- if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
- c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
-#endif
- }
-
-#if defined COMPILE_PCRE8
- if (c > (utf ? 0x10ffffU : 0xffU))
-#elif defined COMPILE_PCRE16
- if (c > (utf ? 0x10ffffU : 0xffffU))
-#elif defined COMPILE_PCRE32
- if (utf && c > 0x10ffffU)
-#endif
- {
- *errorcodeptr = ERR76;
- }
- else if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
- }
- }
- else
- *errorcodeptr = ERR37;
- break;
-
- case CHAR_U:
- /* In JavaScript, \U is an uppercase U letter. */
- if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) *errorcodeptr = ERR37;
- break;
-
- /* In a character class, \g is just a literal "g". Outside a character
- class, \g must be followed by one of a number of specific things:
-
- (1) A number, either plain or braced. If positive, it is an absolute
- backreference. If negative, it is a relative backreference. This is a Perl
- 5.10 feature.
-
- (2) Perl 5.10 also supports \g{name} as a reference to a named group. This
- is part of Perl's movement towards a unified syntax for back references. As
- this is synonymous with \k{name}, we fudge it up by pretending it really
- was \k.
-
- (3) For Oniguruma compatibility we also support \g followed by a name or a
- number either in angle brackets or in single quotes. However, these are
- (possibly recursive) subroutine calls, _not_ backreferences. Just return
- the ESC_g code (cf \k). */
-
- case CHAR_g:
- if (isclass) break;
- if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE)
- {
- escape = ESC_g;
- break;
- }
-
- /* Handle the Perl-compatible cases */
-
- if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
- {
- const pcre_uchar *p;
- for (p = ptr+2; *p != CHAR_NULL && *p != CHAR_RIGHT_CURLY_BRACKET; p++)
- if (*p != CHAR_MINUS && !IS_DIGIT(*p)) break;
- if (*p != CHAR_NULL && *p != CHAR_RIGHT_CURLY_BRACKET)
- {
- escape = ESC_k;
- break;
- }
- braced = TRUE;
- ptr++;
- }
- else braced = FALSE;
-
- if (ptr[1] == CHAR_MINUS)
- {
- negated = TRUE;
- ptr++;
- }
- else negated = FALSE;
-
- /* The integer range is limited by the machine's int representation. */
- s = 0;
- overflow = FALSE;
- while (IS_DIGIT(ptr[1]))
- {
- if (s > INT_MAX / 10 - 1) /* Integer overflow */
- {
- overflow = TRUE;
- break;
- }
- s = s * 10 + (int)(*(++ptr) - CHAR_0);
- }
- if (overflow) /* Integer overflow */
- {
- while (IS_DIGIT(ptr[1]))
- ptr++;
- *errorcodeptr = ERR61;
- break;
- }
-
- if (braced && *(++ptr) != CHAR_RIGHT_CURLY_BRACKET)
- {
- *errorcodeptr = ERR57;
- break;
- }
-
- if (s == 0)
- {
- *errorcodeptr = ERR58;
- break;
- }
-
- if (negated)
- {
- if (s > bracount)
- {
- *errorcodeptr = ERR15;
- break;
- }
- s = bracount - (s - 1);
- }
-
- escape = -s;
- break;
-
- /* The handling of escape sequences consisting of a string of digits
- starting with one that is not zero is not straightforward. By experiment,
- the way Perl works seems to be as follows:
-
- Outside a character class, the digits are read as a decimal number. If the
- number is less than 10, or if there are that many previous extracting
- left brackets, then it is a back reference. Otherwise, up to three octal
- digits are read to form an escaped byte. Thus \123 is likely to be octal
- 123 (cf \0123, which is octal 012 followed by the literal 3). If the octal
- value is greater than 377, the least significant 8 bits are taken. Inside a
- character class, \ followed by a digit is always an octal number. */
-
- case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5:
- case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
-
- if (!isclass)
- {
- oldptr = ptr;
- /* The integer range is limited by the machine's int representation. */
- s = (int)(c -CHAR_0);
- overflow = FALSE;
- while (IS_DIGIT(ptr[1]))
- {
- if (s > INT_MAX / 10 - 1) /* Integer overflow */
- {
- overflow = TRUE;
- break;
- }
- s = s * 10 + (int)(*(++ptr) - CHAR_0);
- }
- if (overflow) /* Integer overflow */
- {
- while (IS_DIGIT(ptr[1]))
- ptr++;
- *errorcodeptr = ERR61;
- break;
- }
- if (s < 10 || s <= bracount)
- {
- escape = -s;
- break;
- }
- ptr = oldptr; /* Put the pointer back and fall through */
- }
-
- /* Handle an octal number following \. If the first digit is 8 or 9, Perl
- generates a binary zero byte and treats the digit as a following literal.
- Thus we have to pull back the pointer by one. */
-
- if ((c = *ptr) >= CHAR_8)
- {
- ptr--;
- c = 0;
- break;
- }
-
- /* \0 always starts an octal number, but we may drop through to here with a
- larger first octal digit. The original code used just to take the least
- significant 8 bits of octal numbers (I think this is what early Perls used
- to do). Nowadays we allow for larger numbers in UTF-8 mode and 16-bit mode,
- but no more than 3 octal digits. */
-
- case CHAR_0:
- c -= CHAR_0;
- while(i++ < 2 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7)
- c = c * 8 + *(++ptr) - CHAR_0;
-#ifdef COMPILE_PCRE8
- if (!utf && c > 0xff) *errorcodeptr = ERR51;
-#endif
- break;
-
- /* \x is complicated. \x{ddd} is a character number which can be greater
- than 0xff in utf or non-8bit mode, but only if the ddd are hex digits.
- If not, { is treated as a data character. */
-
- case CHAR_x:
- if ((options & PCRE_JAVASCRIPT_COMPAT) != 0)
- {
- /* In JavaScript, \x must be followed by two hexadecimal numbers.
- Otherwise it is a lowercase x letter. */
- if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0
- && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0)
- {
- c = 0;
- for (i = 0; i < 2; ++i)
- {
- register pcre_uint32 cc = *(++ptr);
-#ifndef EBCDIC /* ASCII/UTF-8 coding */
- if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
- c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
-#else /* EBCDIC coding */
- if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
- c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
-#endif
- }
- }
- break;
- }
-
- if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
- {
- const pcre_uchar *pt = ptr + 2;
-
- c = 0;
- overflow = FALSE;
- while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0)
- {
- register pcre_uint32 cc = *pt++;
- if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
-
-#ifdef COMPILE_PCRE32
- if (c >= 0x10000000l) { overflow = TRUE; break; }
-#endif
-
-#ifndef EBCDIC /* ASCII/UTF-8 coding */
- if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
- c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
-#else /* EBCDIC coding */
- if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
- c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
-#endif
-
-#if defined COMPILE_PCRE8
- if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; }
-#elif defined COMPILE_PCRE16
- if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; }
-#elif defined COMPILE_PCRE32
- if (utf && c > 0x10ffffU) { overflow = TRUE; break; }
-#endif
- }
-
- if (overflow)
- {
- while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) pt++;
- *errorcodeptr = ERR34;
- }
-
- if (*pt == CHAR_RIGHT_CURLY_BRACKET)
- {
- if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
- ptr = pt;
- break;
- }
-
- /* If the sequence of hex digits does not end with '}', then we don't
- recognize this construct; fall through to the normal \x handling. */
- }
-
- /* Read just a single-byte hex-defined char */
-
- c = 0;
- while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0)
- {
- pcre_uint32 cc; /* Some compilers don't like */
- cc = *(++ptr); /* ++ in initializers */
-#ifndef EBCDIC /* ASCII/UTF-8 coding */
- if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
- c = c * 16 + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
-#else /* EBCDIC coding */
- if (cc <= CHAR_z) cc += 64; /* Convert to upper case */
- c = c * 16 + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
-#endif
- }
- break;
-
- /* For \c, a following letter is upper-cased; then the 0x40 bit is flipped.
- An error is given if the byte following \c is not an ASCII character. This
- coding is ASCII-specific, but then the whole concept of \cx is
- ASCII-specific. (However, an EBCDIC equivalent has now been added.) */
-
- case CHAR_c:
- c = *(++ptr);
- if (c == CHAR_NULL)
- {
- *errorcodeptr = ERR2;
- break;
- }
-#ifndef EBCDIC /* ASCII/UTF-8 coding */
- if (c > 127) /* Excludes all non-ASCII in either mode */
- {
- *errorcodeptr = ERR68;
- break;
- }
- if (c >= CHAR_a && c <= CHAR_z) c -= 32;
- c ^= 0x40;
-#else /* EBCDIC coding */
- if (c >= CHAR_a && c <= CHAR_z) c += 64;
- c ^= 0xC0;
-#endif
- break;
-
- /* PCRE_EXTRA enables extensions to Perl in the matter of escapes. Any
- other alphanumeric following \ is an error if PCRE_EXTRA was set;
- otherwise, for Perl compatibility, it is a literal. This code looks a bit
- odd, but there used to be some cases other than the default, and there may
- be again in future, so I haven't "optimized" it. */
-
- default:
- if ((options & PCRE_EXTRA) != 0) switch(c)
- {
- default:
- *errorcodeptr = ERR3;
- break;
- }
- break;
- }
- }
-
-/* Perl supports \N{name} for character names, as well as plain \N for "not
-newline". PCRE does not support \N{name}. However, it does support
-quantification such as \N{2,3}. */
-
-if (escape == ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET &&
- !is_counted_repeat(ptr+2))
- *errorcodeptr = ERR37;
-
-/* If PCRE_UCP is set, we change the values for \d etc. */
-
-if ((options & PCRE_UCP) != 0 && escape >= ESC_D && escape <= ESC_w)
- escape += (ESC_DU - ESC_D);
-
-/* Set the pointer to the final character before returning. */
-
-*ptrptr = ptr;
-*chptr = c;
-return escape;
-}
-
-#ifdef SUPPORT_UCP
-/*************************************************
-* Handle \P and \p *
-*************************************************/
-
-/* This function is called after \P or \p has been encountered, provided that
-PCRE is compiled with support for Unicode properties. On entry, ptrptr is
-pointing at the P or p. On exit, it is pointing at the final character of the
-escape sequence.
-
-Argument:
- ptrptr points to the pattern position pointer
- negptr points to a boolean that is set TRUE for negation else FALSE
- ptypeptr points to an unsigned int that is set to the type value
- pdataptr points to an unsigned int that is set to the detailed property value
- errorcodeptr points to the error code variable
-
-Returns: TRUE if the type value was found, or FALSE for an invalid type
-*/
-
-static BOOL
-get_ucp(const pcre_uchar **ptrptr, BOOL *negptr, unsigned int *ptypeptr,
- unsigned int *pdataptr, int *errorcodeptr)
-{
-pcre_uchar c;
-int i, bot, top;
-const pcre_uchar *ptr = *ptrptr;
-pcre_uchar name[32];
-
-c = *(++ptr);
-if (c == CHAR_NULL) goto ERROR_RETURN;
-
-*negptr = FALSE;
-
-/* \P or \p can be followed by a name in {}, optionally preceded by ^ for
-negation. */
-
-if (c == CHAR_LEFT_CURLY_BRACKET)
- {
- if (ptr[1] == CHAR_CIRCUMFLEX_ACCENT)
- {
- *negptr = TRUE;
- ptr++;
- }
- for (i = 0; i < (int)(sizeof(name) / sizeof(pcre_uchar)) - 1; i++)
- {
- c = *(++ptr);
- if (c == CHAR_NULL) goto ERROR_RETURN;
- if (c == CHAR_RIGHT_CURLY_BRACKET) break;
- name[i] = c;
- }
- if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN;
- name[i] = 0;
- }
-
-/* Otherwise there is just one following character */
-
-else
- {
- name[0] = c;
- name[1] = 0;
- }
-
-*ptrptr = ptr;
-
-/* Search for a recognized property name using binary chop */
-
-bot = 0;
-top = PRIV(utt_size);
-
-while (bot < top)
- {
- int r;
- i = (bot + top) >> 1;
- r = STRCMP_UC_C8(name, PRIV(utt_names) + PRIV(utt)[i].name_offset);
- if (r == 0)
- {
- *ptypeptr = PRIV(utt)[i].type;
- *pdataptr = PRIV(utt)[i].value;
- return TRUE;
- }
- if (r > 0) bot = i + 1; else top = i;
- }
-
-*errorcodeptr = ERR47;
-*ptrptr = ptr;
-return FALSE;
-
-ERROR_RETURN:
-*errorcodeptr = ERR46;
-*ptrptr = ptr;
-return FALSE;
-}
-#endif
-
-
-
-
-/*************************************************
-* Read repeat counts *
-*************************************************/
-
-/* Read an item of the form {n,m} and return the values. This is called only
-after is_counted_repeat() has confirmed that a repeat-count quantifier exists,
-so the syntax is guaranteed to be correct, but we need to check the values.
-
-Arguments:
- p pointer to first char after '{'
- minp pointer to int for min
- maxp pointer to int for max
- returned as -1 if no max
- errorcodeptr points to error code variable
-
-Returns: pointer to '}' on success;
- current ptr on error, with errorcodeptr set non-zero
-*/
-
-static const pcre_uchar *
-read_repeat_counts(const pcre_uchar *p, int *minp, int *maxp, int *errorcodeptr)
-{
-int min = 0;
-int max = -1;
-
-/* Read the minimum value and do a paranoid check: a negative value indicates
-an integer overflow. */
-
-while (IS_DIGIT(*p)) min = min * 10 + (int)(*p++ - CHAR_0);
-if (min < 0 || min > 65535)
- {
- *errorcodeptr = ERR5;
- return p;
- }
-
-/* Read the maximum value if there is one, and again do a paranoid on its size.
-Also, max must not be less than min. */
-
-if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else
- {
- if (*(++p) != CHAR_RIGHT_CURLY_BRACKET)
- {
- max = 0;
- while(IS_DIGIT(*p)) max = max * 10 + (int)(*p++ - CHAR_0);
- if (max < 0 || max > 65535)
- {
- *errorcodeptr = ERR5;
- return p;
- }
- if (max < min)
- {
- *errorcodeptr = ERR4;
- return p;
- }
- }
- }
-
-/* Fill in the required variables, and pass back the pointer to the terminating
-'}'. */
-
-*minp = min;
-*maxp = max;
-return p;
-}
-
-
-
-/*************************************************
-* Subroutine for finding forward reference *
-*************************************************/
-
-/* This recursive function is called only from find_parens() below. The
-top-level call starts at the beginning of the pattern. All other calls must
-start at a parenthesis. It scans along a pattern's text looking for capturing
-subpatterns, and counting them. If it finds a named pattern that matches the
-name it is given, it returns its number. Alternatively, if the name is NULL, it
-returns when it reaches a given numbered subpattern. Recursion is used to keep
-track of subpatterns that reset the capturing group numbers - the (?| feature.
-
-This function was originally called only from the second pass, in which we know
-that if (?< or (?' or (?P< is encountered, the name will be correctly
-terminated because that is checked in the first pass. There is now one call to
-this function in the first pass, to check for a recursive back reference by
-name (so that we can make the whole group atomic). In this case, we need check
-only up to the current position in the pattern, and that is still OK because
-and previous occurrences will have been checked. To make this work, the test
-for "end of pattern" is a check against cd->end_pattern in the main loop,
-instead of looking for a binary zero. This means that the special first-pass
-call can adjust cd->end_pattern temporarily. (Checks for binary zero while
-processing items within the loop are OK, because afterwards the main loop will
-terminate.)
-
-Arguments:
- ptrptr address of the current character pointer (updated)
- cd compile background data
- name name to seek, or NULL if seeking a numbered subpattern
- lorn name length, or subpattern number if name is NULL
- xmode TRUE if we are in /x mode
- utf TRUE if we are in UTF-8 / UTF-16 / UTF-32 mode
- count pointer to the current capturing subpattern number (updated)
-
-Returns: the number of the named subpattern, or -1 if not found
-*/
-
-static int
-find_parens_sub(pcre_uchar **ptrptr, compile_data *cd, const pcre_uchar *name, int lorn,
- BOOL xmode, BOOL utf, int *count)
-{
-pcre_uchar *ptr = *ptrptr;
-int start_count = *count;
-int hwm_count = start_count;
-BOOL dup_parens = FALSE;
-
-/* If the first character is a parenthesis, check on the type of group we are
-dealing with. The very first call may not start with a parenthesis. */
-
-if (ptr[0] == CHAR_LEFT_PARENTHESIS)
- {
- /* Handle specials such as (*SKIP) or (*UTF8) etc. */
-
- if (ptr[1] == CHAR_ASTERISK)
- {
- ptr += 2;
- while (ptr < cd->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
- }
-
- /* Handle a normal, unnamed capturing parenthesis. */
-
- else if (ptr[1] != CHAR_QUESTION_MARK)
- {
- *count += 1;
- if (name == NULL && *count == lorn) return *count;
- ptr++;
- }
-
- /* All cases now have (? at the start. Remember when we are in a group
- where the parenthesis numbers are duplicated. */
-
- else if (ptr[2] == CHAR_VERTICAL_LINE)
- {
- ptr += 3;
- dup_parens = TRUE;
- }
-
- /* Handle comments; all characters are allowed until a ket is reached. */
-
- else if (ptr[2] == CHAR_NUMBER_SIGN)
- {
- for (ptr += 3; *ptr != CHAR_NULL; ptr++)
- if (*ptr == CHAR_RIGHT_PARENTHESIS) break;
- goto FAIL_EXIT;
- }
-
- /* Handle a condition. If it is an assertion, just carry on so that it
- is processed as normal. If not, skip to the closing parenthesis of the
- condition (there can't be any nested parens). */
-
- else if (ptr[2] == CHAR_LEFT_PARENTHESIS)
- {
- ptr += 2;
- if (ptr[1] != CHAR_QUESTION_MARK)
- {
- while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
- if (*ptr != CHAR_NULL) ptr++;
- }
- }
-
- /* Start with (? but not a condition. */
-
- else
- {
- ptr += 2;
- if (*ptr == CHAR_P) ptr++; /* Allow optional P */
-
- /* We have to disambiguate (?<! and (?<= from (?<name> for named groups */
-
- if ((*ptr == CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK &&
- ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE)
- {
- pcre_uchar term;
- const pcre_uchar *thisname;
- *count += 1;
- if (name == NULL && *count == lorn) return *count;
- term = *ptr++;
- if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN;
- thisname = ptr;
- while (*ptr != term) ptr++;
- if (name != NULL && lorn == (int)(ptr - thisname) &&
- STRNCMP_UC_UC(name, thisname, (unsigned int)lorn) == 0)
- return *count;
- term++;
- }
- }
- }
-
-/* Past any initial parenthesis handling, scan for parentheses or vertical
-bars. Stop if we get to cd->end_pattern. Note that this is important for the
-first-pass call when this value is temporarily adjusted to stop at the current
-position. So DO NOT change this to a test for binary zero. */
-
-for (; ptr < cd->end_pattern; ptr++)
- {
- /* Skip over backslashed characters and also entire \Q...\E */
-
- if (*ptr == CHAR_BACKSLASH)
- {
- if (*(++ptr) == CHAR_NULL) goto FAIL_EXIT;
- if (*ptr == CHAR_Q) for (;;)
- {
- while (*(++ptr) != CHAR_NULL && *ptr != CHAR_BACKSLASH) {};
- if (*ptr == CHAR_NULL) goto FAIL_EXIT;
- if (*(++ptr) == CHAR_E) break;
- }
- continue;
- }
-
- /* Skip over character classes; this logic must be similar to the way they
- are handled for real. If the first character is '^', skip it. Also, if the
- first few characters (either before or after ^) are \Q\E or \E we skip them
- too. This makes for compatibility with Perl. Note the use of STR macros to
- encode "Q\\E" so that it works in UTF-8 on EBCDIC platforms. */
-
- if (*ptr == CHAR_LEFT_SQUARE_BRACKET)
- {
- BOOL negate_class = FALSE;
- for (;;)
- {
- if (ptr[1] == CHAR_BACKSLASH)
- {
- if (ptr[2] == CHAR_E)
- ptr+= 2;
- else if (STRNCMP_UC_C8(ptr + 2,
- STR_Q STR_BACKSLASH STR_E, 3) == 0)
- ptr += 4;
- else
- break;
- }
- else if (!negate_class && ptr[1] == CHAR_CIRCUMFLEX_ACCENT)
- {
- negate_class = TRUE;
- ptr++;
- }
- else break;
- }
-
- /* If the next character is ']', it is a data character that must be
- skipped, except in JavaScript compatibility mode. */
-
- if (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET &&
- (cd->external_options & PCRE_JAVASCRIPT_COMPAT) == 0)
- ptr++;
-
- while (*(++ptr) != CHAR_RIGHT_SQUARE_BRACKET)
- {
- if (*ptr == CHAR_NULL) return -1;
- if (*ptr == CHAR_BACKSLASH)
- {
- if (*(++ptr) == CHAR_NULL) goto FAIL_EXIT;
- if (*ptr == CHAR_Q) for (;;)
- {
- while (*(++ptr) != CHAR_NULL && *ptr != CHAR_BACKSLASH) {};
- if (*ptr == CHAR_NULL) goto FAIL_EXIT;
- if (*(++ptr) == CHAR_E) break;
- }
- continue;
- }
- }
- continue;
- }
-
- /* Skip comments in /x mode */
-
- if (xmode && *ptr == CHAR_NUMBER_SIGN)
- {
- ptr++;
- while (*ptr != CHAR_NULL)
- {
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
- ptr++;
-#ifdef SUPPORT_UTF
- if (utf) FORWARDCHAR(ptr);
-#endif
- }
- if (*ptr == CHAR_NULL) goto FAIL_EXIT;
- continue;
- }
-
- /* Check for the special metacharacters */
-
- if (*ptr == CHAR_LEFT_PARENTHESIS)
- {
- int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, count);
- if (rc > 0) return rc;
- if (*ptr == CHAR_NULL) goto FAIL_EXIT;
- }
-
- else if (*ptr == CHAR_RIGHT_PARENTHESIS)
- {
- if (dup_parens && *count < hwm_count) *count = hwm_count;
- goto FAIL_EXIT;
- }
-
- else if (*ptr == CHAR_VERTICAL_LINE && dup_parens)
- {
- if (*count > hwm_count) hwm_count = *count;
- *count = start_count;
- }
- }
-
-FAIL_EXIT:
-*ptrptr = ptr;
-return -1;
-}
-
-
-
-
-/*************************************************
-* Find forward referenced subpattern *
-*************************************************/
-
-/* This function scans along a pattern's text looking for capturing
-subpatterns, and counting them. If it finds a named pattern that matches the
-name it is given, it returns its number. Alternatively, if the name is NULL, it
-returns when it reaches a given numbered subpattern. This is used for forward
-references to subpatterns. We used to be able to start this scan from the
-current compiling point, using the current count value from cd->bracount, and
-do it all in a single loop, but the addition of the possibility of duplicate
-subpattern numbers means that we have to scan from the very start, in order to
-take account of such duplicates, and to use a recursive function to keep track
-of the different types of group.
-
-Arguments:
- cd compile background data
- name name to seek, or NULL if seeking a numbered subpattern
- lorn name length, or subpattern number if name is NULL
- xmode TRUE if we are in /x mode
- utf TRUE if we are in UTF-8 / UTF-16 / UTF-32 mode
-
-Returns: the number of the found subpattern, or -1 if not found
-*/
-
-static int
-find_parens(compile_data *cd, const pcre_uchar *name, int lorn, BOOL xmode,
- BOOL utf)
-{
-pcre_uchar *ptr = (pcre_uchar *)cd->start_pattern;
-int count = 0;
-int rc;
-
-/* If the pattern does not start with an opening parenthesis, the first call
-to find_parens_sub() will scan right to the end (if necessary). However, if it
-does start with a parenthesis, find_parens_sub() will return when it hits the
-matching closing parens. That is why we have to have a loop. */
-
-for (;;)
- {
- rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, &count);
- if (rc > 0 || *ptr++ == CHAR_NULL) break;
- }
-
-return rc;
-}
-
-
-
-
-/*************************************************
-* Find first significant op code *
-*************************************************/
-
-/* This is called by several functions that scan a compiled expression looking
-for a fixed first character, or an anchoring op code etc. It skips over things
-that do not influence this. For some calls, it makes sense to skip negative
-forward and all backward assertions, and also the \b assertion; for others it
-does not.
-
-Arguments:
- code pointer to the start of the group
- skipassert TRUE if certain assertions are to be skipped
-
-Returns: pointer to the first significant opcode
-*/
-
-static const pcre_uchar*
-first_significant_code(const pcre_uchar *code, BOOL skipassert)
-{
-for (;;)
- {
- switch ((int)*code)
- {
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- if (!skipassert) return code;
- do code += GET(code, 1); while (*code == OP_ALT);
- code += PRIV(OP_lengths)[*code];
- break;
-
- case OP_WORD_BOUNDARY:
- case OP_NOT_WORD_BOUNDARY:
- if (!skipassert) return code;
- /* Fall through */
-
- case OP_CALLOUT:
- case OP_CREF:
- case OP_NCREF:
- case OP_RREF:
- case OP_NRREF:
- case OP_DEF:
- code += PRIV(OP_lengths)[*code];
- break;
-
- default:
- return code;
- }
- }
-/* Control never reaches here */
-}
-
-
-
-
-/*************************************************
-* Find the fixed length of a branch *
-*************************************************/
-
-/* Scan a branch and compute the fixed length of subject that will match it,
-if the length is fixed. This is needed for dealing with backward assertions.
-In UTF8 mode, the result is in characters rather than bytes. The branch is
-temporarily terminated with OP_END when this function is called.
-
-This function is called when a backward assertion is encountered, so that if it
-fails, the error message can point to the correct place in the pattern.
-However, we cannot do this when the assertion contains subroutine calls,
-because they can be forward references. We solve this by remembering this case
-and doing the check at the end; a flag specifies which mode we are running in.
-
-Arguments:
- code points to the start of the pattern (the bracket)
- utf TRUE in UTF-8 / UTF-16 / UTF-32 mode
- atend TRUE if called when the pattern is complete
- cd the "compile data" structure
-
-Returns: the fixed length,
- or -1 if there is no fixed length,
- or -2 if \C was encountered (in UTF-8 mode only)
- or -3 if an OP_RECURSE item was encountered and atend is FALSE
- or -4 if an unknown opcode was encountered (internal error)
-*/
-
-static int
-find_fixedlength(pcre_uchar *code, BOOL utf, BOOL atend, compile_data *cd)
-{
-int length = -1;
-
-register int branchlength = 0;
-register pcre_uchar *cc = code + 1 + LINK_SIZE;
-
-/* Scan along the opcodes for this branch. If we get to the end of the
-branch, check the length against that of the other branches. */
-
-for (;;)
- {
- int d;
- pcre_uchar *ce, *cs;
- register pcre_uchar op = *cc;
-
- switch (op)
- {
- /* We only need to continue for OP_CBRA (normal capturing bracket) and
- OP_BRA (normal non-capturing bracket) because the other variants of these
- opcodes are all concerned with unlimited repeated groups, which of course
- are not of fixed length. */
-
- case OP_CBRA:
- case OP_BRA:
- case OP_ONCE:
- case OP_ONCE_NC:
- case OP_COND:
- d = find_fixedlength(cc + ((op == OP_CBRA)? IMM2_SIZE : 0), utf, atend, cd);
- if (d < 0) return d;
- branchlength += d;
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- cc += 1 + LINK_SIZE;
- break;
-
- /* Reached end of a branch; if it's a ket it is the end of a nested call.
- If it's ALT it is an alternation in a nested call. An ACCEPT is effectively
- an ALT. If it is END it's the end of the outer call. All can be handled by
- the same code. Note that we must not include the OP_KETRxxx opcodes here,
- because they all imply an unlimited repeat. */
-
- case OP_ALT:
- case OP_KET:
- case OP_END:
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- if (length < 0) length = branchlength;
- else if (length != branchlength) return -1;
- if (*cc != OP_ALT) return length;
- cc += 1 + LINK_SIZE;
- branchlength = 0;
- break;
-
- /* A true recursion implies not fixed length, but a subroutine call may
- be OK. If the subroutine is a forward reference, we can't deal with
- it until the end of the pattern, so return -3. */
-
- case OP_RECURSE:
- if (!atend) return -3;
- cs = ce = (pcre_uchar *)cd->start_code + GET(cc, 1); /* Start subpattern */
- do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */
- if (cc > cs && cc < ce) return -1; /* Recursion */
- d = find_fixedlength(cs + IMM2_SIZE, utf, atend, cd);
- if (d < 0) return d;
- branchlength += d;
- cc += 1 + LINK_SIZE;
- break;
-
- /* Skip over assertive subpatterns */
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- cc += PRIV(OP_lengths)[*cc];
- break;
-
- /* Skip over things that don't match chars */
-
- case OP_MARK:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- cc += cc[1] + PRIV(OP_lengths)[*cc];
- break;
-
- case OP_CALLOUT:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_CLOSE:
- case OP_COMMIT:
- case OP_CREF:
- case OP_DEF:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_EOD:
- case OP_EODN:
- case OP_FAIL:
- case OP_NCREF:
- case OP_NRREF:
- case OP_NOT_WORD_BOUNDARY:
- case OP_PRUNE:
- case OP_REVERSE:
- case OP_RREF:
- case OP_SET_SOM:
- case OP_SKIP:
- case OP_SOD:
- case OP_SOM:
- case OP_THEN:
- case OP_WORD_BOUNDARY:
- cc += PRIV(OP_lengths)[*cc];
- break;
-
- /* Handle literal characters */
-
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- branchlength++;
- cc += 2;
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- /* Handle exact repetitions. The count is already in characters, but we
- need to skip over a multibyte character in UTF8 mode. */
-
- case OP_EXACT:
- case OP_EXACTI:
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- branchlength += (int)GET2(cc,1);
- cc += 2 + IMM2_SIZE;
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- case OP_TYPEEXACT:
- branchlength += GET2(cc,1);
- if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP)
- cc += 2;
- cc += 1 + IMM2_SIZE + 1;
- break;
-
- /* Handle single-char matchers */
-
- case OP_PROP:
- case OP_NOTPROP:
- cc += 2;
- /* Fall through */
-
- case OP_HSPACE:
- case OP_VSPACE:
- case OP_NOT_HSPACE:
- case OP_NOT_VSPACE:
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- branchlength++;
- cc++;
- break;
-
- /* The single-byte matcher isn't allowed. This only happens in UTF-8 mode;
- otherwise \C is coded as OP_ALLANY. */
-
- case OP_ANYBYTE:
- return -2;
-
- /* Check a class for variable quantification */
-
- case OP_CLASS:
- case OP_NCLASS:
-#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- case OP_XCLASS:
- /* The original code caused an unsigned overflow in 64 bit systems,
- so now we use a conditional statement. */
- if (op == OP_XCLASS)
- cc += GET(cc, 1);
- else
- cc += PRIV(OP_lengths)[OP_CLASS];
-#else
- cc += PRIV(OP_lengths)[OP_CLASS];
-#endif
-
- switch (*cc)
- {
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- return -1;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) return -1;
- branchlength += (int)GET2(cc,1);
- cc += 1 + 2 * IMM2_SIZE;
- break;
-
- default:
- branchlength++;
- }
- break;
-
- /* Anything else is variable length */
-
- case OP_ANYNL:
- case OP_BRAMINZERO:
- case OP_BRAPOS:
- case OP_BRAPOSZERO:
- case OP_BRAZERO:
- case OP_CBRAPOS:
- case OP_EXTUNI:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_KETRPOS:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_POSPLUS:
- case OP_POSPLUSI:
- case OP_POSQUERY:
- case OP_POSQUERYI:
- case OP_POSSTAR:
- case OP_POSSTARI:
- case OP_POSUPTO:
- case OP_POSUPTOI:
- case OP_QUERY:
- case OP_QUERYI:
- case OP_REF:
- case OP_REFI:
- case OP_SBRA:
- case OP_SBRAPOS:
- case OP_SCBRA:
- case OP_SCBRAPOS:
- case OP_SCOND:
- case OP_SKIPZERO:
- case OP_STAR:
- case OP_STARI:
- case OP_TYPEMINPLUS:
- case OP_TYPEMINQUERY:
- case OP_TYPEMINSTAR:
- case OP_TYPEMINUPTO:
- case OP_TYPEPLUS:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSUPTO:
- case OP_TYPEQUERY:
- case OP_TYPESTAR:
- case OP_TYPEUPTO:
- case OP_UPTO:
- case OP_UPTOI:
- return -1;
-
- /* Catch unrecognized opcodes so that when new ones are added they
- are not forgotten, as has happened in the past. */
-
- default:
- return -4;
- }
- }
-/* Control never gets here */
-}
-
-
-
-
-/*************************************************
-* Scan compiled regex for specific bracket *
-*************************************************/
-
-/* This little function scans through a compiled pattern until it finds a
-capturing bracket with the given number, or, if the number is negative, an
-instance of OP_REVERSE for a lookbehind. The function is global in the C sense
-so that it can be called from pcre_study() when finding the minimum matching
-length.
-
-Arguments:
- code points to start of expression
- utf TRUE in UTF-8 / UTF-16 / UTF-32 mode
- number the required bracket number or negative to find a lookbehind
-
-Returns: pointer to the opcode for the bracket, or NULL if not found
-*/
-
-const pcre_uchar *
-PRIV(find_bracket)(const pcre_uchar *code, BOOL utf, int number)
-{
-for (;;)
- {
- register pcre_uchar c = *code;
-
- if (c == OP_END) return NULL;
-
- /* XCLASS is used for classes that cannot be represented just by a bit
- map. This includes negated single high-valued characters. The length in
- the table is zero; the actual length is stored in the compiled code. */
-
- if (c == OP_XCLASS) code += GET(code, 1);
-
- /* Handle recursion */
-
- else if (c == OP_REVERSE)
- {
- if (number < 0) return (pcre_uchar *)code;
- code += PRIV(OP_lengths)[c];
- }
-
- /* Handle capturing bracket */
-
- else if (c == OP_CBRA || c == OP_SCBRA ||
- c == OP_CBRAPOS || c == OP_SCBRAPOS)
- {
- int n = (int)GET2(code, 1+LINK_SIZE);
- if (n == number) return (pcre_uchar *)code;
- code += PRIV(OP_lengths)[c];
- }
-
- /* Otherwise, we can get the item's length from the table, except that for
- repeated character types, we have to test for \p and \P, which have an extra
- two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
- must add in its length. */
-
- else
- {
- switch(c)
- {
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
- break;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- case OP_TYPEPOSUPTO:
- if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
- code += 2;
- break;
-
- case OP_MARK:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- code += code[1];
- break;
- }
-
- /* Add in the fixed length from the table */
-
- code += PRIV(OP_lengths)[c];
-
- /* In UTF-8 mode, opcodes that are followed by a character may be followed by
- a multi-byte character. The length in the table is a minimum, so we have to
- arrange to skip the extra bytes. */
-
-#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
- if (utf) switch(c)
- {
- case OP_CHAR:
- case OP_CHARI:
- case OP_EXACT:
- case OP_EXACTI:
- case OP_UPTO:
- case OP_UPTOI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- case OP_POSUPTO:
- case OP_POSUPTOI:
- case OP_STAR:
- case OP_STARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_POSSTAR:
- case OP_POSSTARI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_POSPLUS:
- case OP_POSPLUSI:
- case OP_QUERY:
- case OP_QUERYI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- case OP_POSQUERY:
- case OP_POSQUERYI:
- if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
- break;
- }
-#else
- (void)(utf); /* Keep compiler happy by referencing function argument */
-#endif
- }
- }
-}
-
-
-
-/*************************************************
-* Scan compiled regex for recursion reference *
-*************************************************/
-
-/* This little function scans through a compiled pattern until it finds an
-instance of OP_RECURSE.
-
-Arguments:
- code points to start of expression
- utf TRUE in UTF-8 / UTF-16 / UTF-32 mode
-
-Returns: pointer to the opcode for OP_RECURSE, or NULL if not found
-*/
-
-static const pcre_uchar *
-find_recurse(const pcre_uchar *code, BOOL utf)
-{
-for (;;)
- {
- register pcre_uchar c = *code;
- if (c == OP_END) return NULL;
- if (c == OP_RECURSE) return code;
-
- /* XCLASS is used for classes that cannot be represented just by a bit
- map. This includes negated single high-valued characters. The length in
- the table is zero; the actual length is stored in the compiled code. */
-
- if (c == OP_XCLASS) code += GET(code, 1);
-
- /* Otherwise, we can get the item's length from the table, except that for
- repeated character types, we have to test for \p and \P, which have an extra
- two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
- must add in its length. */
-
- else
- {
- switch(c)
- {
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSPLUS:
- case OP_TYPEPOSQUERY:
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
- break;
-
- case OP_TYPEPOSUPTO:
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEEXACT:
- if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
- code += 2;
- break;
-
- case OP_MARK:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- code += code[1];
- break;
- }
-
- /* Add in the fixed length from the table */
-
- code += PRIV(OP_lengths)[c];
-
- /* In UTF-8 mode, opcodes that are followed by a character may be followed
- by a multi-byte character. The length in the table is a minimum, so we have
- to arrange to skip the extra bytes. */
-
-#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
- if (utf) switch(c)
- {
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_EXACT:
- case OP_EXACTI:
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- case OP_UPTO:
- case OP_UPTOI:
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- case OP_POSUPTO:
- case OP_POSUPTOI:
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
- case OP_STAR:
- case OP_STARI:
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_POSSTAR:
- case OP_POSSTARI:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_POSPLUS:
- case OP_POSPLUSI:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- case OP_QUERY:
- case OP_QUERYI:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- case OP_POSQUERY:
- case OP_POSQUERYI:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
- if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
- break;
- }
-#else
- (void)(utf); /* Keep compiler happy by referencing function argument */
-#endif
- }
- }
-}
-
-
-
-/*************************************************
-* Scan compiled branch for non-emptiness *
-*************************************************/
-
-/* This function scans through a branch of a compiled pattern to see whether it
-can match the empty string or not. It is called from could_be_empty()
-below and from compile_branch() when checking for an unlimited repeat of a
-group that can match nothing. Note that first_significant_code() skips over
-backward and negative forward assertions when its final argument is TRUE. If we
-hit an unclosed bracket, we return "empty" - this means we've struck an inner
-bracket whose current branch will already have been scanned.
-
-Arguments:
- code points to start of search
- endcode points to where to stop
- utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode
- cd contains pointers to tables etc.
-
-Returns: TRUE if what is matched could be empty
-*/
-
-static BOOL
-could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode,
- BOOL utf, compile_data *cd)
-{
-register pcre_uchar c;
-for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
- code < endcode;
- code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE))
- {
- const pcre_uchar *ccode;
-
- c = *code;
-
- /* Skip over forward assertions; the other assertions are skipped by
- first_significant_code() with a TRUE final argument. */
-
- if (c == OP_ASSERT)
- {
- do code += GET(code, 1); while (*code == OP_ALT);
- c = *code;
- continue;
- }
-
- /* For a recursion/subroutine call, if its end has been reached, which
- implies a backward reference subroutine call, we can scan it. If it's a
- forward reference subroutine call, we can't. To detect forward reference
- we have to scan up the list that is kept in the workspace. This function is
- called only when doing the real compile, not during the pre-compile that
- measures the size of the compiled pattern. */
-
- if (c == OP_RECURSE)
- {
- const pcre_uchar *scode;
- BOOL empty_branch;
-
- /* Test for forward reference */
-
- for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE)
- if ((int)GET(scode, 0) == (int)(code + 1 - cd->start_code)) return TRUE;
-
- /* Not a forward reference, test for completed backward reference */
-
- empty_branch = FALSE;
- scode = cd->start_code + GET(code, 1);
- if (GET(scode, 1) == 0) return TRUE; /* Unclosed */
-
- /* Completed backwards reference */
-
- do
- {
- if (could_be_empty_branch(scode, endcode, utf, cd))
- {
- empty_branch = TRUE;
- break;
- }
- scode += GET(scode, 1);
- }
- while (*scode == OP_ALT);
-
- if (!empty_branch) return FALSE; /* All branches are non-empty */
- continue;
- }
-
- /* Groups with zero repeats can of course be empty; skip them. */
-
- if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO ||
- c == OP_BRAPOSZERO)
- {
- code += PRIV(OP_lengths)[c];
- do code += GET(code, 1); while (*code == OP_ALT);
- c = *code;
- continue;
- }
-
- /* A nested group that is already marked as "could be empty" can just be
- skipped. */
-
- if (c == OP_SBRA || c == OP_SBRAPOS ||
- c == OP_SCBRA || c == OP_SCBRAPOS)
- {
- do code += GET(code, 1); while (*code == OP_ALT);
- c = *code;
- continue;
- }
-
- /* For other groups, scan the branches. */
-
- if (c == OP_BRA || c == OP_BRAPOS ||
- c == OP_CBRA || c == OP_CBRAPOS ||
- c == OP_ONCE || c == OP_ONCE_NC ||
- c == OP_COND)
- {
- BOOL empty_branch;
- if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */
-
- /* If a conditional group has only one branch, there is a second, implied,
- empty branch, so just skip over the conditional, because it could be empty.
- Otherwise, scan the individual branches of the group. */
-
- if (c == OP_COND && code[GET(code, 1)] != OP_ALT)
- code += GET(code, 1);
- else
- {
- empty_branch = FALSE;
- do
- {
- if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd))
- empty_branch = TRUE;
- code += GET(code, 1);
- }
- while (*code == OP_ALT);
- if (!empty_branch) return FALSE; /* All branches are non-empty */
- }
-
- c = *code;
- continue;
- }
-
- /* Handle the other opcodes */
-
- switch (c)
- {
- /* Check for quantifiers after a class. XCLASS is used for classes that
- cannot be represented just by a bit map. This includes negated single
- high-valued characters. The length in PRIV(OP_lengths)[] is zero; the
- actual length is stored in the compiled code, so we must update "code"
- here. */
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- case OP_XCLASS:
- ccode = code += GET(code, 1);
- goto CHECK_CLASS_REPEAT;
-#endif
-
- case OP_CLASS:
- case OP_NCLASS:
- ccode = code + PRIV(OP_lengths)[OP_CLASS];
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- CHECK_CLASS_REPEAT:
-#endif
-
- switch (*ccode)
- {
- case OP_CRSTAR: /* These could be empty; continue */
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- break;
-
- default: /* Non-repeat => class must match */
- case OP_CRPLUS: /* These repeats aren't empty */
- case OP_CRMINPLUS:
- return FALSE;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- if (GET2(ccode, 1) > 0) return FALSE; /* Minimum > 0 */
- break;
- }
- break;
-
- /* Opcodes that must match a character */
-
- case OP_PROP:
- case OP_NOTPROP:
- case OP_EXTUNI:
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- case OP_ANYBYTE:
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- case OP_EXACT:
- case OP_NOTPLUS:
- case OP_NOTMINPLUS:
- case OP_NOTPOSPLUS:
- case OP_NOTEXACT:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- case OP_TYPEEXACT:
- return FALSE;
-
- /* These are going to continue, as they may be empty, but we have to
- fudge the length for the \p and \P cases. */
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPOSSTAR:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSQUERY:
- if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
- break;
-
- /* Same for these */
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
- code += 2;
- break;
-
- /* End of branch */
-
- case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_KETRPOS:
- case OP_ALT:
- return TRUE;
-
- /* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO,
- MINUPTO, and POSUPTO may be followed by a multibyte character */
-
-#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
- case OP_STAR:
- case OP_STARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_POSSTAR:
- case OP_POSSTARI:
- case OP_QUERY:
- case OP_QUERYI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- case OP_POSQUERY:
- case OP_POSQUERYI:
- if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]);
- break;
-
- case OP_UPTO:
- case OP_UPTOI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- case OP_POSUPTO:
- case OP_POSUPTOI:
- if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]);
- break;
-#endif
-
- /* MARK, and PRUNE/SKIP/THEN with an argument must skip over the argument
- string. */
-
- case OP_MARK:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- code += code[1];
- break;
-
- /* None of the remaining opcodes are required to match a character. */
-
- default:
- break;
- }
- }
-
-return TRUE;
-}
-
-
-
-/*************************************************
-* Scan compiled regex for non-emptiness *
-*************************************************/
-
-/* This function is called to check for left recursive calls. We want to check
-the current branch of the current pattern to see if it could match the empty
-string. If it could, we must look outwards for branches at other levels,
-stopping when we pass beyond the bracket which is the subject of the recursion.
-This function is called only during the real compile, not during the
-pre-compile.
-
-Arguments:
- code points to start of the recursion
- endcode points to where to stop (current RECURSE item)
- bcptr points to the chain of current (unclosed) branch starts
- utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode
- cd pointers to tables etc
-
-Returns: TRUE if what is matched could be empty
-*/
-
-static BOOL
-could_be_empty(const pcre_uchar *code, const pcre_uchar *endcode,
- branch_chain *bcptr, BOOL utf, compile_data *cd)
-{
-while (bcptr != NULL && bcptr->current_branch >= code)
- {
- if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd))
- return FALSE;
- bcptr = bcptr->outer;
- }
-return TRUE;
-}
-
-
-
-/*************************************************
-* Check for POSIX class syntax *
-*************************************************/
-
-/* This function is called when the sequence "[:" or "[." or "[=" is
-encountered in a character class. It checks whether this is followed by a
-sequence of characters terminated by a matching ":]" or ".]" or "=]". If we
-reach an unescaped ']' without the special preceding character, return FALSE.
-
-Originally, this function only recognized a sequence of letters between the
-terminators, but it seems that Perl recognizes any sequence of characters,
-though of course unknown POSIX names are subsequently rejected. Perl gives an
-"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE
-didn't consider this to be a POSIX class. Likewise for [:1234:].
-
-The problem in trying to be exactly like Perl is in the handling of escapes. We
-have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX
-class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code
-below handles the special case of \], but does not try to do any other escape
-processing. This makes it different from Perl for cases such as [:l\ower:]
-where Perl recognizes it as the POSIX class "lower" but PCRE does not recognize
-"l\ower". This is a lesser evil that not diagnosing bad classes when Perl does,
-I think.
-
-A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.
-It seems that the appearance of a nested POSIX class supersedes an apparent
-external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or
-a digit.
-
-In Perl, unescaped square brackets may also appear as part of class names. For
-example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for
-[:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not
-seem right at all. PCRE does not allow closing square brackets in POSIX class
-names.
-
-Arguments:
- ptr pointer to the initial [
- endptr where to return the end pointer
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-check_posix_syntax(const pcre_uchar *ptr, const pcre_uchar **endptr)
-{
-pcre_uchar terminator; /* Don't combine these lines; the Solaris cc */
-terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */
-for (++ptr; *ptr != CHAR_NULL; ptr++)
- {
- if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
- ptr++;
- else if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
- else
- {
- if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
- {
- *endptr = ptr;
- return TRUE;
- }
- if (*ptr == CHAR_LEFT_SQUARE_BRACKET &&
- (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
- ptr[1] == CHAR_EQUALS_SIGN) &&
- check_posix_syntax(ptr, endptr))
- return FALSE;
- }
- }
-return FALSE;
-}
-
-
-
-
-/*************************************************
-* Check POSIX class name *
-*************************************************/
-
-/* This function is called to check the name given in a POSIX-style class entry
-such as [:alnum:].
-
-Arguments:
- ptr points to the first letter
- len the length of the name
-
-Returns: a value representing the name, or -1 if unknown
-*/
-
-static int
-check_posix_name(const pcre_uchar *ptr, int len)
-{
-const char *pn = posix_names;
-register int yield = 0;
-while (posix_name_lengths[yield] != 0)
- {
- if (len == posix_name_lengths[yield] &&
- STRNCMP_UC_C8(ptr, pn, (unsigned int)len) == 0) return yield;
- pn += posix_name_lengths[yield] + 1;
- yield++;
- }
-return -1;
-}
-
-
-/*************************************************
-* Adjust OP_RECURSE items in repeated group *
-*************************************************/
-
-/* OP_RECURSE items contain an offset from the start of the regex to the group
-that is referenced. This means that groups can be replicated for fixed
-repetition simply by copying (because the recursion is allowed to refer to
-earlier groups that are outside the current group). However, when a group is
-optional (i.e. the minimum quantifier is zero), OP_BRAZERO or OP_SKIPZERO is
-inserted before it, after it has been compiled. This means that any OP_RECURSE
-items within it that refer to the group itself or any contained groups have to
-have their offsets adjusted. That one of the jobs of this function. Before it
-is called, the partially compiled regex must be temporarily terminated with
-OP_END.
-
-This function has been extended with the possibility of forward references for
-recursions and subroutine calls. It must also check the list of such references
-for the group we are dealing with. If it finds that one of the recursions in
-the current group is on this list, it adjusts the offset in the list, not the
-value in the reference (which is a group number).
-
-Arguments:
- group points to the start of the group
- adjust the amount by which the group is to be moved
- utf TRUE in UTF-8 / UTF-16 / UTF-32 mode
- cd contains pointers to tables etc.
- save_hwm the hwm forward reference pointer at the start of the group
-
-Returns: nothing
-*/
-
-static void
-adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
- pcre_uchar *save_hwm)
-{
-pcre_uchar *ptr = group;
-
-while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL)
- {
- int offset;
- pcre_uchar *hc;
-
- /* See if this recursion is on the forward reference list. If so, adjust the
- reference. */
-
- for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)
- {
- offset = (int)GET(hc, 0);
- if (cd->start_code + offset == ptr + 1)
- {
- PUT(hc, 0, offset + adjust);
- break;
- }
- }
-
- /* Otherwise, adjust the recursion offset if it's after the start of this
- group. */
-
- if (hc >= cd->hwm)
- {
- offset = (int)GET(ptr, 1);
- if (cd->start_code + offset >= group) PUT(ptr, 1, offset + adjust);
- }
-
- ptr += 1 + LINK_SIZE;
- }
-}
-
-
-
-/*************************************************
-* Insert an automatic callout point *
-*************************************************/
-
-/* This function is called when the PCRE_AUTO_CALLOUT option is set, to insert
-callout points before each pattern item.
-
-Arguments:
- code current code pointer
- ptr current pattern pointer
- cd pointers to tables etc
-
-Returns: new code pointer
-*/
-
-static pcre_uchar *
-auto_callout(pcre_uchar *code, const pcre_uchar *ptr, compile_data *cd)
-{
-*code++ = OP_CALLOUT;
-*code++ = 255;
-PUT(code, 0, (int)(ptr - cd->start_pattern)); /* Pattern offset */
-PUT(code, LINK_SIZE, 0); /* Default length */
-return code + 2 * LINK_SIZE;
-}
-
-
-
-/*************************************************
-* Complete a callout item *
-*************************************************/
-
-/* A callout item contains the length of the next item in the pattern, which
-we can't fill in till after we have reached the relevant point. This is used
-for both automatic and manual callouts.
-
-Arguments:
- previous_callout points to previous callout item
- ptr current pattern pointer
- cd pointers to tables etc
-
-Returns: nothing
-*/
-
-static void
-complete_callout(pcre_uchar *previous_callout, const pcre_uchar *ptr, compile_data *cd)
-{
-int length = (int)(ptr - cd->start_pattern - GET(previous_callout, 2));
-PUT(previous_callout, 2 + LINK_SIZE, length);
-}
-
-
-
-#ifdef SUPPORT_UCP
-/*************************************************
-* Get othercase range *
-*************************************************/
-
-/* This function is passed the start and end of a class range, in UTF-8 mode
-with UCP support. It searches up the characters, looking for ranges of
-characters in the "other" case. Each call returns the next one, updating the
-start address. A character with multiple other cases is returned on its own
-with a special return value.
-
-Arguments:
- cptr points to starting character value; updated
- d end value
- ocptr where to put start of othercase range
- odptr where to put end of othercase range
-
-Yield: -1 when no more
- 0 when a range is returned
- >0 the CASESET offset for char with multiple other cases
- in this case, ocptr contains the original
-*/
-
-static int
-get_othercase_range(pcre_uint32 *cptr, pcre_uint32 d, pcre_uint32 *ocptr,
- pcre_uint32 *odptr)
-{
-pcre_uint32 c, othercase, next;
-unsigned int co;
-
-#if defined(__GNUC__) && __GNUC__ == 3
-othercase = 0; /* XXX gcc -Wuninitialized */
-#endif
-
-/* Find the first character that has an other case. If it has multiple other
-cases, return its case offset value. */
-
-for (c = *cptr; c <= d; c++)
- {
- if ((co = UCD_CASESET(c)) != 0)
- {
- *ocptr = c++; /* Character that has the set */
- *cptr = c; /* Rest of input range */
- return (int)co;
- }
- if ((othercase = UCD_OTHERCASE(c)) != c) break;
- }
-
-if (c > d) return -1; /* Reached end of range */
-
-*ocptr = othercase;
-next = othercase + 1;
-
-for (++c; c <= d; c++)
- {
- if (UCD_OTHERCASE(c) != next) break;
- next++;
- }
-
-*odptr = next - 1; /* End of othercase range */
-*cptr = c; /* Rest of input range */
-return 0;
-}
-
-
-
-/*************************************************
-* Check a character and a property *
-*************************************************/
-
-/* This function is called by check_auto_possessive() when a property item
-is adjacent to a fixed character.
-
-Arguments:
- c the character
- ptype the property type
- pdata the data for the type
- negated TRUE if it's a negated property (\P or \p{^)
-
-Returns: TRUE if auto-possessifying is OK
-*/
-
-static BOOL
-check_char_prop(pcre_uint32 c, unsigned int ptype, unsigned int pdata, BOOL negated)
-{
-#ifdef SUPPORT_UCP
-const pcre_uint32 *p;
-#endif
-
-const ucd_record *prop = GET_UCD(c);
-
-switch(ptype)
- {
- case PT_LAMP:
- return (prop->chartype == ucp_Lu ||
- prop->chartype == ucp_Ll ||
- prop->chartype == ucp_Lt) == negated;
-
- case PT_GC:
- return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated;
-
- case PT_PC:
- return (pdata == prop->chartype) == negated;
-
- case PT_SC:
- return (pdata == prop->script) == negated;
-
- /* These are specials */
-
- case PT_ALNUM:
- return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated;
-
- case PT_SPACE: /* Perl space */
- return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
- == negated;
-
- case PT_PXSPACE: /* POSIX space */
- return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR)
- == negated;
-
- case PT_WORD:
- return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
- c == CHAR_UNDERSCORE) == negated;
-
-#ifdef SUPPORT_UCP
- case PT_CLIST:
- p = PRIV(ucd_caseless_sets) + prop->caseset;
- for (;;)
- {
- if (c < *p) return !negated;
- if (c == *p++) return negated;
- }
- break; /* Control never reaches here */
-#endif
- }
-
-return FALSE;
-}
-#endif /* SUPPORT_UCP */
-
-
-
-/*************************************************
-* Check if auto-possessifying is possible *
-*************************************************/
-
-/* This function is called for unlimited repeats of certain items, to see
-whether the next thing could possibly match the repeated item. If not, it makes
-sense to automatically possessify the repeated item.
-
-Arguments:
- previous pointer to the repeated opcode
- utf TRUE in UTF-8 / UTF-16 / UTF-32 mode
- ptr next character in pattern
- options options bits
- cd contains pointers to tables etc.
-
-Returns: TRUE if possessifying is wanted
-*/
-
-static BOOL
-check_auto_possessive(const pcre_uchar *previous, BOOL utf,
- const pcre_uchar *ptr, int options, compile_data *cd)
-{
-pcre_uint32 c = NOTACHAR;
-pcre_uint32 next;
-int escape;
-pcre_uchar op_code = *previous++;
-
-/* Skip whitespace and comments in extended mode */
-
-if ((options & PCRE_EXTENDED) != 0)
- {
- for (;;)
- {
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
- if (*ptr == CHAR_NUMBER_SIGN)
- {
- ptr++;
- while (*ptr != CHAR_NULL)
- {
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
- ptr++;
-#ifdef SUPPORT_UTF
- if (utf) FORWARDCHAR(ptr);
-#endif
- }
- }
- else break;
- }
- }
-
-/* If the next item is one that we can handle, get its value. A non-negative
-value is a character, a negative value is an escape value. */
-
-if (*ptr == CHAR_BACKSLASH)
- {
- int temperrorcode = 0;
- escape = check_escape(&ptr, &next, &temperrorcode, cd->bracount, options,
- FALSE);
- if (temperrorcode != 0) return FALSE;
- ptr++; /* Point after the escape sequence */
- }
-else if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_meta) == 0)
- {
- escape = 0;
-#ifdef SUPPORT_UTF
- if (utf) { GETCHARINC(next, ptr); } else
-#endif
- next = *ptr++;
- }
-else return FALSE;
-
-/* Skip whitespace and comments in extended mode */
-
-if ((options & PCRE_EXTENDED) != 0)
- {
- for (;;)
- {
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
- if (*ptr == CHAR_NUMBER_SIGN)
- {
- ptr++;
- while (*ptr != CHAR_NULL)
- {
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
- ptr++;
-#ifdef SUPPORT_UTF
- if (utf) FORWARDCHAR(ptr);
-#endif
- }
- }
- else break;
- }
- }
-
-/* If the next thing is itself optional, we have to give up. */
-
-if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
- STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
- return FALSE;
-
-/* If the previous item is a character, get its value. */
-
-if (op_code == OP_CHAR || op_code == OP_CHARI ||
- op_code == OP_NOT || op_code == OP_NOTI)
- {
-#ifdef SUPPORT_UTF
- GETCHARTEST(c, previous);
-#else
- c = *previous;
-#endif
- }
-
-/* Now compare the next item with the previous opcode. First, handle cases when
-the next item is a character. */
-
-if (escape == 0)
- {
- /* For a caseless UTF match, the next character may have more than one other
- case, which maps to the special PT_CLIST property. Check this first. */
-
-#ifdef SUPPORT_UCP
- if (utf && c != NOTACHAR && (options & PCRE_CASELESS) != 0)
- {
- unsigned int ocs = UCD_CASESET(next);
- if (ocs > 0) return check_char_prop(c, PT_CLIST, ocs, op_code >= OP_NOT);
- }
-#endif
-
- switch(op_code)
- {
- case OP_CHAR:
- return c != next;
-
- /* For CHARI (caseless character) we must check the other case. If we have
- Unicode property support, we can use it to test the other case of
- high-valued characters. We know that next can have only one other case,
- because multi-other-case characters are dealt with above. */
-
- case OP_CHARI:
- if (c == next) return FALSE;
-#ifdef SUPPORT_UTF
- if (utf)
- {
- pcre_uint32 othercase;
- if (next < 128) othercase = cd->fcc[next]; else
-#ifdef SUPPORT_UCP
- othercase = UCD_OTHERCASE(next);
-#else
- othercase = NOTACHAR;
-#endif
- return c != othercase;
- }
- else
-#endif /* SUPPORT_UTF */
- return (c != TABLE_GET(next, cd->fcc, next)); /* Not UTF */
-
- case OP_NOT:
- return c == next;
-
- case OP_NOTI:
- if (c == next) return TRUE;
-#ifdef SUPPORT_UTF
- if (utf)
- {
- pcre_uint32 othercase;
- if (next < 128) othercase = cd->fcc[next]; else
-#ifdef SUPPORT_UCP
- othercase = UCD_OTHERCASE(next);
-#else
- othercase = NOTACHAR;
-#endif
- return c == othercase;
- }
- else
-#endif /* SUPPORT_UTF */
- return (c == TABLE_GET(next, cd->fcc, next)); /* Not UTF */
-
- /* Note that OP_DIGIT etc. are generated only when PCRE_UCP is *not* set.
- When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */
-
- case OP_DIGIT:
- return next > 255 || (cd->ctypes[next] & ctype_digit) == 0;
-
- case OP_NOT_DIGIT:
- return next <= 255 && (cd->ctypes[next] & ctype_digit) != 0;
-
- case OP_WHITESPACE:
- return next > 255 || (cd->ctypes[next] & ctype_space) == 0;
-
- case OP_NOT_WHITESPACE:
- return next <= 255 && (cd->ctypes[next] & ctype_space) != 0;
-
- case OP_WORDCHAR:
- return next > 255 || (cd->ctypes[next] & ctype_word) == 0;
-
- case OP_NOT_WORDCHAR:
- return next <= 255 && (cd->ctypes[next] & ctype_word) != 0;
-
- case OP_HSPACE:
- case OP_NOT_HSPACE:
- switch(next)
- {
- HSPACE_CASES:
- return op_code == OP_NOT_HSPACE;
-
- default:
- return op_code != OP_NOT_HSPACE;
- }
-
- case OP_ANYNL:
- case OP_VSPACE:
- case OP_NOT_VSPACE:
- switch(next)
- {
- VSPACE_CASES:
- return op_code == OP_NOT_VSPACE;
-
- default:
- return op_code != OP_NOT_VSPACE;
- }
-
-#ifdef SUPPORT_UCP
- case OP_PROP:
- return check_char_prop(next, previous[0], previous[1], FALSE);
-
- case OP_NOTPROP:
- return check_char_prop(next, previous[0], previous[1], TRUE);
-#endif
-
- default:
- return FALSE;
- }
- }
-
-/* Handle the case when the next item is \d, \s, etc. Note that when PCRE_UCP
-is set, \d turns into ESC_du rather than ESC_d, etc., so ESC_d etc. are
-generated only when PCRE_UCP is *not* set, that is, when only ASCII
-characteristics are recognized. Similarly, the opcodes OP_DIGIT etc. are
-replaced by OP_PROP codes when PCRE_UCP is set. */
-
-switch(op_code)
- {
- case OP_CHAR:
- case OP_CHARI:
- switch(escape)
- {
- case ESC_d:
- return c > 255 || (cd->ctypes[c] & ctype_digit) == 0;
-
- case ESC_D:
- return c <= 255 && (cd->ctypes[c] & ctype_digit) != 0;
-
- case ESC_s:
- return c > 255 || (cd->ctypes[c] & ctype_space) == 0;
-
- case ESC_S:
- return c <= 255 && (cd->ctypes[c] & ctype_space) != 0;
-
- case ESC_w:
- return c > 255 || (cd->ctypes[c] & ctype_word) == 0;
-
- case ESC_W:
- return c <= 255 && (cd->ctypes[c] & ctype_word) != 0;
-
- case ESC_h:
- case ESC_H:
- switch(c)
- {
- HSPACE_CASES:
- return escape != ESC_h;
-
- default:
- return escape == ESC_h;
- }
-
- case ESC_v:
- case ESC_V:
- switch(c)
- {
- VSPACE_CASES:
- return escape != ESC_v;
-
- default:
- return escape == ESC_v;
- }
-
- /* When PCRE_UCP is set, these values get generated for \d etc. Find
- their substitutions and process them. The result will always be either
- ESC_p or ESC_P. Then fall through to process those values. */
-
-#ifdef SUPPORT_UCP
- case ESC_du:
- case ESC_DU:
- case ESC_wu:
- case ESC_WU:
- case ESC_su:
- case ESC_SU:
- {
- int temperrorcode = 0;
- ptr = substitutes[escape - ESC_DU];
- escape = check_escape(&ptr, &next, &temperrorcode, 0, options, FALSE);
- if (temperrorcode != 0) return FALSE;
- ptr++; /* For compatibility */
- }
- /* Fall through */
-
- case ESC_p:
- case ESC_P:
- {
- unsigned int ptype = 0, pdata = 0;
- int errorcodeptr;
- BOOL negated;
-
- ptr--; /* Make ptr point at the p or P */
- if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcodeptr))
- return FALSE;
- ptr++; /* Point past the final curly ket */
-
- /* If the property item is optional, we have to give up. (When generated
- from \d etc by PCRE_UCP, this test will have been applied much earlier,
- to the original \d etc. At this point, ptr will point to a zero byte. */
-
- if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
- STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
- return FALSE;
-
- /* Do the property check. */
-
- return check_char_prop(c, ptype, pdata, (escape == ESC_P) != negated);
- }
-#endif
-
- default:
- return FALSE;
- }
-
- /* In principle, support for Unicode properties should be integrated here as
- well. It means re-organizing the above code so as to get hold of the property
- values before switching on the op-code. However, I wonder how many patterns
- combine ASCII \d etc with Unicode properties? (Note that if PCRE_UCP is set,
- these op-codes are never generated.) */
-
- case OP_DIGIT:
- return escape == ESC_D || escape == ESC_s || escape == ESC_W ||
- escape == ESC_h || escape == ESC_v || escape == ESC_R;
-
- case OP_NOT_DIGIT:
- return escape == ESC_d;
-
- case OP_WHITESPACE:
- return escape == ESC_S || escape == ESC_d || escape == ESC_w;
-
- case OP_NOT_WHITESPACE:
- return escape == ESC_s || escape == ESC_h || escape == ESC_v || escape == ESC_R;
-
- case OP_HSPACE:
- return escape == ESC_S || escape == ESC_H || escape == ESC_d ||
- escape == ESC_w || escape == ESC_v || escape == ESC_R;
-
- case OP_NOT_HSPACE:
- return escape == ESC_h;
-
- /* Can't have \S in here because VT matches \S (Perl anomaly) */
- case OP_ANYNL:
- case OP_VSPACE:
- return escape == ESC_V || escape == ESC_d || escape == ESC_w;
-
- case OP_NOT_VSPACE:
- return escape == ESC_v || escape == ESC_R;
-
- case OP_WORDCHAR:
- return escape == ESC_W || escape == ESC_s || escape == ESC_h ||
- escape == ESC_v || escape == ESC_R;
-
- case OP_NOT_WORDCHAR:
- return escape == ESC_w || escape == ESC_d;
-
- default:
- return FALSE;
- }
-
-/* Control does not reach here */
-}
-
-
-
-/*************************************************
-* Add a character or range to a class *
-*************************************************/
-
-/* This function packages up the logic of adding a character or range of
-characters to a class. The character values in the arguments will be within the
-valid values for the current mode (8-bit, 16-bit, UTF, etc). This function is
-mutually recursive with the function immediately below.
-
-Arguments:
- classbits the bit map for characters < 256
- uchardptr points to the pointer for extra data
- options the options word
- cd contains pointers to tables etc.
- start start of range character
- end end of range character
-
-Returns: the number of < 256 characters added
- the pointer to extra data is updated
-*/
-
-static int
-add_to_class(pcre_uint8 *classbits, pcre_uchar **uchardptr, int options,
- compile_data *cd, pcre_uint32 start, pcre_uint32 end)
-{
-pcre_uint32 c;
-int n8 = 0;
-
-/* If caseless matching is required, scan the range and process alternate
-cases. In Unicode, there are 8-bit characters that have alternate cases that
-are greater than 255 and vice-versa. Sometimes we can just extend the original
-range. */
-
-if ((options & PCRE_CASELESS) != 0)
- {
-#ifdef SUPPORT_UCP
- if ((options & PCRE_UTF8) != 0)
- {
- int rc;
- pcre_uint32 oc, od = 0;
-
- options &= ~PCRE_CASELESS; /* Remove for recursive calls */
- c = start;
-
- while ((rc = get_othercase_range(&c, end, &oc, &od)) >= 0)
- {
- /* Handle a single character that has more than one other case. */
-
- if (rc > 0) n8 += add_list_to_class(classbits, uchardptr, options, cd,
- PRIV(ucd_caseless_sets) + rc, oc);
-
- /* Do nothing if the other case range is within the original range. */
-
- else if (oc >= start && od <= end) continue;
-
- /* Extend the original range if there is overlap, noting that if oc < c, we
- can't have od > end because a subrange is always shorter than the basic
- range. Otherwise, use a recursive call to add the additional range. */
-
- else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */
- else if (od > end && oc <= end + 1) end = od; /* Extend upwards */
- else n8 += add_to_class(classbits, uchardptr, options, cd, oc, od);
- }
- }
- else
-#endif /* SUPPORT_UCP */
-
- /* Not UTF-mode, or no UCP */
-
- for (c = start; c <= end && c < 256; c++)
- {
- SETBIT(classbits, cd->fcc[c]);
- n8++;
- }
- }
-
-/* Now handle the original range. Adjust the final value according to the bit
-length - this means that the same lists of (e.g.) horizontal spaces can be used
-in all cases. */
-
-#if defined COMPILE_PCRE8
-#ifdef SUPPORT_UTF
- if ((options & PCRE_UTF8) == 0)
-#endif
- if (end > 0xff) end = 0xff;
-
-#elif defined COMPILE_PCRE16
-#ifdef SUPPORT_UTF
- if ((options & PCRE_UTF16) == 0)
-#endif
- if (end > 0xffff) end = 0xffff;
-
-#endif /* COMPILE_PCRE[8|16] */
-
-/* If all characters are less than 256, use the bit map. Otherwise use extra
-data. */
-
-if (end < 0x100)
- {
- for (c = start; c <= end; c++)
- {
- n8++;
- SETBIT(classbits, c);
- }
- }
-
-else
- {
- pcre_uchar *uchardata = *uchardptr;
-
-#ifdef SUPPORT_UTF
- if ((options & PCRE_UTF8) != 0) /* All UTFs use the same flag bit */
- {
- if (start < end)
- {
- *uchardata++ = XCL_RANGE;
- uchardata += PRIV(ord2utf)(start, uchardata);
- uchardata += PRIV(ord2utf)(end, uchardata);
- }
- else if (start == end)
- {
- *uchardata++ = XCL_SINGLE;
- uchardata += PRIV(ord2utf)(start, uchardata);
- }
- }
- else
-#endif /* SUPPORT_UTF */
-
- /* Without UTF support, character values are constrained by the bit length,
- and can only be > 256 for 16-bit and 32-bit libraries. */
-
-#ifdef COMPILE_PCRE8
- {}
-#else
- if (start < end)
- {
- *uchardata++ = XCL_RANGE;
- *uchardata++ = start;
- *uchardata++ = end;
- }
- else if (start == end)
- {
- *uchardata++ = XCL_SINGLE;
- *uchardata++ = start;
- }
-#endif
-
- *uchardptr = uchardata; /* Updata extra data pointer */
- }
-
-return n8; /* Number of 8-bit characters */
-}
-
-
-
-
-/*************************************************
-* Add a list of characters to a class *
-*************************************************/
-
-/* This function is used for adding a list of case-equivalent characters to a
-class, and also for adding a list of horizontal or vertical whitespace. If the
-list is in order (which it should be), ranges of characters are detected and
-handled appropriately. This function is mutually recursive with the function
-above.
-
-Arguments:
- classbits the bit map for characters < 256
- uchardptr points to the pointer for extra data
- options the options word
- cd contains pointers to tables etc.
- p points to row of 32-bit values, terminated by NOTACHAR
- except character to omit; this is used when adding lists of
- case-equivalent characters to avoid including the one we
- already know about
-
-Returns: the number of < 256 characters added
- the pointer to extra data is updated
-*/
-
-static int
-add_list_to_class(pcre_uint8 *classbits, pcre_uchar **uchardptr, int options,
- compile_data *cd, const pcre_uint32 *p, unsigned int except)
-{
-int n8 = 0;
-while (p[0] < NOTACHAR)
- {
- int n = 0;
- if (p[0] != except)
- {
- while(p[n+1] == p[0] + n + 1) n++;
- n8 += add_to_class(classbits, uchardptr, options, cd, p[0], p[n]);
- }
- p += n + 1;
- }
-return n8;
-}
-
-
-
-/*************************************************
-* Add characters not in a list to a class *
-*************************************************/
-
-/* This function is used for adding the complement of a list of horizontal or
-vertical whitespace to a class. The list must be in order.
-
-Arguments:
- classbits the bit map for characters < 256
- uchardptr points to the pointer for extra data
- options the options word
- cd contains pointers to tables etc.
- p points to row of 32-bit values, terminated by NOTACHAR
-
-Returns: the number of < 256 characters added
- the pointer to extra data is updated
-*/
-
-static int
-add_not_list_to_class(pcre_uint8 *classbits, pcre_uchar **uchardptr,
- int options, compile_data *cd, const pcre_uint32 *p)
-{
-BOOL utf = (options & PCRE_UTF8) != 0;
-int n8 = 0;
-if (p[0] > 0)
- n8 += add_to_class(classbits, uchardptr, options, cd, 0, p[0] - 1);
-while (p[0] < NOTACHAR)
- {
- while (p[1] == p[0] + 1) p++;
- n8 += add_to_class(classbits, uchardptr, options, cd, p[0] + 1,
- (p[1] == NOTACHAR) ? (utf ? 0x10ffffu : 0xffffffffu) : p[1] - 1);
- p++;
- }
-return n8;
-}
-
-
-
-/*************************************************
-* Compile one branch *
-*************************************************/
-
-/* Scan the pattern, compiling it into the a vector. If the options are
-changed during the branch, the pointer is used to change the external options
-bits. This function is used during the pre-compile phase when we are trying
-to find out the amount of memory needed, as well as during the real compile
-phase. The value of lengthptr distinguishes the two phases.
-
-Arguments:
- optionsptr pointer to the option bits
- codeptr points to the pointer to the current code point
- ptrptr points to the current pattern pointer
- errorcodeptr points to error code variable
- firstcharptr place to put the first required character
- firstcharflagsptr place to put the first character flags, or a negative number
- reqcharptr place to put the last required character
- reqcharflagsptr place to put the last required character flags, or a negative number
- bcptr points to current branch chain
- cond_depth conditional nesting depth
- cd contains pointers to tables etc.
- lengthptr NULL during the real compile phase
- points to length accumulator during pre-compile phase
-
-Returns: TRUE on success
- FALSE, with *errorcodeptr set non-zero on error
-*/
-
-static BOOL
-compile_branch(int *optionsptr, pcre_uchar **codeptr,
- const pcre_uchar **ptrptr, int *errorcodeptr,
- pcre_uint32 *firstcharptr, pcre_int32 *firstcharflagsptr,
- pcre_uint32 *reqcharptr, pcre_int32 *reqcharflagsptr,
- branch_chain *bcptr, int cond_depth,
- compile_data *cd, int *lengthptr)
-{
-int repeat_type, op_type;
-int repeat_min = 0, repeat_max = 0; /* To please picky compilers */
-int bravalue = 0;
-int greedy_default, greedy_non_default;
-pcre_uint32 firstchar, reqchar;
-pcre_int32 firstcharflags, reqcharflags;
-pcre_uint32 zeroreqchar, zerofirstchar;
-pcre_int32 zeroreqcharflags, zerofirstcharflags;
-pcre_int32 req_caseopt, reqvary, tempreqvary;
-int options = *optionsptr; /* May change dynamically */
-int after_manual_callout = 0;
-int length_prevgroup = 0;
-register pcre_uint32 c;
-int escape;
-register pcre_uchar *code = *codeptr;
-pcre_uchar *last_code = code;
-pcre_uchar *orig_code = code;
-pcre_uchar *tempcode;
-BOOL inescq = FALSE;
-BOOL groupsetfirstchar = FALSE;
-const pcre_uchar *ptr = *ptrptr;
-const pcre_uchar *tempptr;
-const pcre_uchar *nestptr = NULL;
-pcre_uchar *previous = NULL;
-pcre_uchar *previous_callout = NULL;
-pcre_uchar *save_hwm = NULL;
-pcre_uint8 classbits[32];
-
-/* We can fish out the UTF-8 setting once and for all into a BOOL, but we
-must not do this for other options (e.g. PCRE_EXTENDED) because they may change
-dynamically as we process the pattern. */
-
-#ifdef SUPPORT_UTF
-/* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */
-BOOL utf = (options & PCRE_UTF8) != 0;
-#ifndef COMPILE_PCRE32
-pcre_uchar utf_chars[6];
-#endif
-#else
-BOOL utf = FALSE;
-#endif
-
-/* Helper variables for OP_XCLASS opcode (for characters > 255). We define
-class_uchardata always so that it can be passed to add_to_class() always,
-though it will not be used in non-UTF 8-bit cases. This avoids having to supply
-alternative calls for the different cases. */
-
-pcre_uchar *class_uchardata;
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
-BOOL xclass;
-pcre_uchar *class_uchardata_base;
-#endif
-
-#ifdef PCRE_DEBUG
-if (lengthptr != NULL) DPRINTF((">> start branch\n"));
-#endif
-
-/* Set up the default and non-default settings for greediness */
-
-greedy_default = ((options & PCRE_UNGREEDY) != 0);
-greedy_non_default = greedy_default ^ 1;
-
-/* Initialize no first byte, no required byte. REQ_UNSET means "no char
-matching encountered yet". It gets changed to REQ_NONE if we hit something that
-matches a non-fixed char first char; reqchar just remains unset if we never
-find one.
-
-When we hit a repeat whose minimum is zero, we may have to adjust these values
-to take the zero repeat into account. This is implemented by setting them to
-zerofirstbyte and zeroreqchar when such a repeat is encountered. The individual
-item types that can be repeated set these backoff variables appropriately. */
-
-firstchar = reqchar = zerofirstchar = zeroreqchar = 0;
-firstcharflags = reqcharflags = zerofirstcharflags = zeroreqcharflags = REQ_UNSET;
-
-/* The variable req_caseopt contains either the REQ_CASELESS value
-or zero, according to the current setting of the caseless flag. The
-REQ_CASELESS leaves the lower 28 bit empty. It is added into the
-firstchar or reqchar variables to record the case status of the
-value. This is used only for ASCII characters. */
-
-req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS:0;
-
-/* Switch on next character until the end of the branch */
-
-for (;; ptr++)
- {
- BOOL negate_class;
- BOOL should_flip_negation;
- BOOL possessive_quantifier;
- BOOL is_quantifier;
- BOOL is_recurse;
- BOOL reset_bracount;
- int class_has_8bitchar;
- int class_one_char;
- int newoptions;
- int recno;
- int refsign;
- int skipbytes;
- pcre_uint32 subreqchar, subfirstchar;
- pcre_int32 subreqcharflags, subfirstcharflags;
- int terminator;
- unsigned int mclength;
- unsigned int tempbracount;
- pcre_uint32 ec;
- pcre_uchar mcbuffer[8];
-
- /* Get next character in the pattern */
-
- c = *ptr;
-
- /* If we are at the end of a nested substitution, revert to the outer level
- string. Nesting only happens one level deep. */
-
- if (c == CHAR_NULL && nestptr != NULL)
- {
- ptr = nestptr;
- nestptr = NULL;
- c = *ptr;
- }
-
- /* If we are in the pre-compile phase, accumulate the length used for the
- previous cycle of this loop. */
-
- if (lengthptr != NULL)
- {
-#ifdef PCRE_DEBUG
- if (code > cd->hwm) cd->hwm = code; /* High water info */
-#endif
- if (code > cd->start_workspace + cd->workspace_size -
- WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */
- {
- *errorcodeptr = ERR52;
- goto FAILED;
- }
-
- /* There is at least one situation where code goes backwards: this is the
- case of a zero quantifier after a class (e.g. [ab]{0}). At compile time,
- the class is simply eliminated. However, it is created first, so we have to
- allow memory for it. Therefore, don't ever reduce the length at this point.
- */
-
- if (code < last_code) code = last_code;
-
- /* Paranoid check for integer overflow */
-
- if (OFLOW_MAX - *lengthptr < code - last_code)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
-
- *lengthptr += (int)(code - last_code);
- DPRINTF(("length=%d added %d c=%c (0x%x)\n", *lengthptr,
- (int)(code - last_code), c, c));
-
- /* If "previous" is set and it is not at the start of the work space, move
- it back to there, in order to avoid filling up the work space. Otherwise,
- if "previous" is NULL, reset the current code pointer to the start. */
-
- if (previous != NULL)
- {
- if (previous > orig_code)
- {
- memmove(orig_code, previous, IN_UCHARS(code - previous));
- code -= previous - orig_code;
- previous = orig_code;
- }
- }
- else code = orig_code;
-
- /* Remember where this code item starts so we can pick up the length
- next time round. */
-
- last_code = code;
- }
-
- /* In the real compile phase, just check the workspace used by the forward
- reference list. */
-
- else if (cd->hwm > cd->start_workspace + cd->workspace_size -
- WORK_SIZE_SAFETY_MARGIN)
- {
- *errorcodeptr = ERR52;
- goto FAILED;
- }
-
- /* If in \Q...\E, check for the end; if not, we have a literal */
-
- if (inescq && c != CHAR_NULL)
- {
- if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E)
- {
- inescq = FALSE;
- ptr++;
- continue;
- }
- else
- {
- if (previous_callout != NULL)
- {
- if (lengthptr == NULL) /* Don't attempt in pre-compile phase */
- complete_callout(previous_callout, ptr, cd);
- previous_callout = NULL;
- }
- if ((options & PCRE_AUTO_CALLOUT) != 0)
- {
- previous_callout = code;
- code = auto_callout(code, ptr, cd);
- }
- goto NORMAL_CHAR;
- }
- }
-
- /* Fill in length of a previous callout, except when the next thing is
- a quantifier. */
-
- is_quantifier =
- c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK ||
- (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1));
-
- if (!is_quantifier && previous_callout != NULL &&
- after_manual_callout-- <= 0)
- {
- if (lengthptr == NULL) /* Don't attempt in pre-compile phase */
- complete_callout(previous_callout, ptr, cd);
- previous_callout = NULL;
- }
-
- /* In extended mode, skip white space and comments. */
-
- if ((options & PCRE_EXTENDED) != 0)
- {
- if (MAX_255(*ptr) && (cd->ctypes[c] & ctype_space) != 0) continue;
- if (c == CHAR_NUMBER_SIGN)
- {
- ptr++;
- while (*ptr != CHAR_NULL)
- {
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
- ptr++;
-#ifdef SUPPORT_UTF
- if (utf) FORWARDCHAR(ptr);
-#endif
- }
- if (*ptr != CHAR_NULL) continue;
-
- /* Else fall through to handle end of string */
- c = 0;
- }
- }
-
- /* No auto callout for quantifiers. */
-
- if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier)
- {
- previous_callout = code;
- code = auto_callout(code, ptr, cd);
- }
-
- switch(c)
- {
- /* ===================================================================*/
- case 0: /* The branch terminates at string end */
- case CHAR_VERTICAL_LINE: /* or | or ) */
- case CHAR_RIGHT_PARENTHESIS:
- *firstcharptr = firstchar;
- *firstcharflagsptr = firstcharflags;
- *reqcharptr = reqchar;
- *reqcharflagsptr = reqcharflags;
- *codeptr = code;
- *ptrptr = ptr;
- if (lengthptr != NULL)
- {
- if (OFLOW_MAX - *lengthptr < code - last_code)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
- *lengthptr += (int)(code - last_code); /* To include callout length */
- DPRINTF((">> end branch\n"));
- }
- return TRUE;
-
-
- /* ===================================================================*/
- /* Handle single-character metacharacters. In multiline mode, ^ disables
- the setting of any following char as a first character. */
-
- case CHAR_CIRCUMFLEX_ACCENT:
- previous = NULL;
- if ((options & PCRE_MULTILINE) != 0)
- {
- if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
- *code++ = OP_CIRCM;
- }
- else *code++ = OP_CIRC;
- break;
-
- case CHAR_DOLLAR_SIGN:
- previous = NULL;
- *code++ = ((options & PCRE_MULTILINE) != 0)? OP_DOLLM : OP_DOLL;
- break;
-
- /* There can never be a first char if '.' is first, whatever happens about
- repeats. The value of reqchar doesn't change either. */
-
- case CHAR_DOT:
- if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
- zerofirstchar = firstchar;
- zerofirstcharflags = firstcharflags;
- zeroreqchar = reqchar;
- zeroreqcharflags = reqcharflags;
- previous = code;
- *code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY;
- break;
-
-
- /* ===================================================================*/
- /* Character classes. If the included characters are all < 256, we build a
- 32-byte bitmap of the permitted characters, except in the special case
- where there is only one such character. For negated classes, we build the
- map as usual, then invert it at the end. However, we use a different opcode
- so that data characters > 255 can be handled correctly.
-
- If the class contains characters outside the 0-255 range, a different
- opcode is compiled. It may optionally have a bit map for characters < 256,
- but those above are are explicitly listed afterwards. A flag byte tells
- whether the bitmap is present, and whether this is a negated class or not.
-
- In JavaScript compatibility mode, an isolated ']' causes an error. In
- default (Perl) mode, it is treated as a data character. */
-
- case CHAR_RIGHT_SQUARE_BRACKET:
- if ((cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
- {
- *errorcodeptr = ERR64;
- goto FAILED;
- }
- goto NORMAL_CHAR;
-
- case CHAR_LEFT_SQUARE_BRACKET:
- previous = code;
-
- /* PCRE supports POSIX class stuff inside a class. Perl gives an error if
- they are encountered at the top level, so we'll do that too. */
-
- if ((ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
- ptr[1] == CHAR_EQUALS_SIGN) &&
- check_posix_syntax(ptr, &tempptr))
- {
- *errorcodeptr = (ptr[1] == CHAR_COLON)? ERR13 : ERR31;
- goto FAILED;
- }
-
- /* If the first character is '^', set the negation flag and skip it. Also,
- if the first few characters (either before or after ^) are \Q\E or \E we
- skip them too. This makes for compatibility with Perl. */
-
- negate_class = FALSE;
- for (;;)
- {
- c = *(++ptr);
- if (c == CHAR_BACKSLASH)
- {
- if (ptr[1] == CHAR_E)
- ptr++;
- else if (STRNCMP_UC_C8(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0)
- ptr += 3;
- else
- break;
- }
- else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)
- negate_class = TRUE;
- else break;
- }
-
- /* Empty classes are allowed in JavaScript compatibility mode. Otherwise,
- an initial ']' is taken as a data character -- the code below handles
- that. In JS mode, [] must always fail, so generate OP_FAIL, whereas
- [^] must match any character, so generate OP_ALLANY. */
-
- if (c == CHAR_RIGHT_SQUARE_BRACKET &&
- (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
- {
- *code++ = negate_class? OP_ALLANY : OP_FAIL;
- if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
- zerofirstchar = firstchar;
- zerofirstcharflags = firstcharflags;
- break;
- }
-
- /* If a class contains a negative special such as \S, we need to flip the
- negation flag at the end, so that support for characters > 255 works
- correctly (they are all included in the class). */
-
- should_flip_negation = FALSE;
-
- /* For optimization purposes, we track some properties of the class:
- class_has_8bitchar will be non-zero if the class contains at least one <
- 256 character; class_one_char will be 1 if the class contains just one
- character. */
-
- class_has_8bitchar = 0;
- class_one_char = 0;
-
- /* Initialize the 32-char bit map to all zeros. We build the map in a
- temporary bit of memory, in case the class contains fewer than two
- 8-bit characters because in that case the compiled code doesn't use the bit
- map. */
-
- memset(classbits, 0, 32 * sizeof(pcre_uint8));
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- xclass = FALSE;
- class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */
- class_uchardata_base = class_uchardata; /* Save the start */
-#endif
-
- /* Process characters until ] is reached. By writing this as a "do" it
- means that an initial ] is taken as a data character. At the start of the
- loop, c contains the first byte of the character. */
-
- if (c != CHAR_NULL) do
- {
- const pcre_uchar *oldptr;
-
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(c))
- { /* Braces are required because the */
- GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */
- }
-#endif
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- /* In the pre-compile phase, accumulate the length of any extra
- data and reset the pointer. This is so that very large classes that
- contain a zillion > 255 characters no longer overwrite the work space
- (which is on the stack). We have to remember that there was XCLASS data,
- however. */
-
- if (lengthptr != NULL && class_uchardata > class_uchardata_base)
- {
- xclass = TRUE;
- *lengthptr += class_uchardata - class_uchardata_base;
- class_uchardata = class_uchardata_base;
- }
-#endif
-
- /* Inside \Q...\E everything is literal except \E */
-
- if (inescq)
- {
- if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) /* If we are at \E */
- {
- inescq = FALSE; /* Reset literal state */
- ptr++; /* Skip the 'E' */
- continue; /* Carry on with next */
- }
- goto CHECK_RANGE; /* Could be range if \E follows */
- }
-
- /* Handle POSIX class names. Perl allows a negation extension of the
- form [:^name:]. A square bracket that doesn't match the syntax is
- treated as a literal. We also recognize the POSIX constructions
- [.ch.] and [=ch=] ("collating elements") and fault them, as Perl
- 5.6 and 5.8 do. */
-
- if (c == CHAR_LEFT_SQUARE_BRACKET &&
- (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
- ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr))
- {
- BOOL local_negate = FALSE;
- int posix_class, taboffset, tabopt;
- register const pcre_uint8 *cbits = cd->cbits;
- pcre_uint8 pbits[32];
-
- if (ptr[1] != CHAR_COLON)
- {
- *errorcodeptr = ERR31;
- goto FAILED;
- }
-
- ptr += 2;
- if (*ptr == CHAR_CIRCUMFLEX_ACCENT)
- {
- local_negate = TRUE;
- should_flip_negation = TRUE; /* Note negative special */
- ptr++;
- }
-
- posix_class = check_posix_name(ptr, (int)(tempptr - ptr));
- if (posix_class < 0)
- {
- *errorcodeptr = ERR30;
- goto FAILED;
- }
-
- /* If matching is caseless, upper and lower are converted to
- alpha. This relies on the fact that the class table starts with
- alpha, lower, upper as the first 3 entries. */
-
- if ((options & PCRE_CASELESS) != 0 && posix_class <= 2)
- posix_class = 0;
-
- /* When PCRE_UCP is set, some of the POSIX classes are converted to
- different escape sequences that use Unicode properties. */
-
-#ifdef SUPPORT_UCP
- if ((options & PCRE_UCP) != 0)
- {
- int pc = posix_class + ((local_negate)? POSIX_SUBSIZE/2 : 0);
- if (posix_substitutes[pc] != NULL)
- {
- nestptr = tempptr + 1;
- ptr = posix_substitutes[pc] - 1;
- continue;
- }
- }
-#endif
- /* In the non-UCP case, we build the bit map for the POSIX class in a
- chunk of local store because we may be adding and subtracting from it,
- and we don't want to subtract bits that may be in the main map already.
- At the end we or the result into the bit map that is being built. */
-
- posix_class *= 3;
-
- /* Copy in the first table (always present) */
-
- memcpy(pbits, cbits + posix_class_maps[posix_class],
- 32 * sizeof(pcre_uint8));
-
- /* If there is a second table, add or remove it as required. */
-
- taboffset = posix_class_maps[posix_class + 1];
- tabopt = posix_class_maps[posix_class + 2];
-
- if (taboffset >= 0)
- {
- if (tabopt >= 0)
- for (c = 0; c < 32; c++) pbits[c] |= cbits[c + taboffset];
- else
- for (c = 0; c < 32; c++) pbits[c] &= ~cbits[c + taboffset];
- }
-
- /* Now see if we need to remove any special characters. An option
- value of 1 removes vertical space and 2 removes underscore. */
-
- if (tabopt < 0) tabopt = -tabopt;
- if (tabopt == 1) pbits[1] &= ~0x3c;
- else if (tabopt == 2) pbits[11] &= 0x7f;
-
- /* Add the POSIX table or its complement into the main table that is
- being built and we are done. */
-
- if (local_negate)
- for (c = 0; c < 32; c++) classbits[c] |= ~pbits[c];
- else
- for (c = 0; c < 32; c++) classbits[c] |= pbits[c];
-
- ptr = tempptr + 1;
- /* Every class contains at least one < 256 character. */
- class_has_8bitchar = 1;
- /* Every class contains at least two characters. */
- class_one_char = 2;
- continue; /* End of POSIX syntax handling */
- }
-
- /* Backslash may introduce a single character, or it may introduce one
- of the specials, which just set a flag. The sequence \b is a special
- case. Inside a class (and only there) it is treated as backspace. We
- assume that other escapes have more than one character in them, so
- speculatively set both class_has_8bitchar and class_one_char bigger
- than one. Unrecognized escapes fall through and are either treated
- as literal characters (by default), or are faulted if
- PCRE_EXTRA is set. */
-
- if (c == CHAR_BACKSLASH)
- {
- escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options,
- TRUE);
- if (*errorcodeptr != 0) goto FAILED;
- if (escape == 0) c = ec;
- else if (escape == ESC_b) c = CHAR_BS; /* \b is backspace in a class */
- else if (escape == ESC_N) /* \N is not supported in a class */
- {
- *errorcodeptr = ERR71;
- goto FAILED;
- }
- else if (escape == ESC_Q) /* Handle start of quoted string */
- {
- if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
- {
- ptr += 2; /* avoid empty string */
- }
- else inescq = TRUE;
- continue;
- }
- else if (escape == ESC_E) continue; /* Ignore orphan \E */
-
- else
- {
- register const pcre_uint8 *cbits = cd->cbits;
- /* Every class contains at least two < 256 characters. */
- class_has_8bitchar++;
- /* Every class contains at least two characters. */
- class_one_char += 2;
-
- switch (escape)
- {
-#ifdef SUPPORT_UCP
- case ESC_du: /* These are the values given for \d etc */
- case ESC_DU: /* when PCRE_UCP is set. We replace the */
- case ESC_wu: /* escape sequence with an appropriate \p */
- case ESC_WU: /* or \P to test Unicode properties instead */
- case ESC_su: /* of the default ASCII testing. */
- case ESC_SU:
- nestptr = ptr;
- ptr = substitutes[escape - ESC_DU] - 1; /* Just before substitute */
- class_has_8bitchar--; /* Undo! */
- continue;
-#endif
- case ESC_d:
- for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit];
- continue;
-
- case ESC_D:
- should_flip_negation = TRUE;
- for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit];
- continue;
-
- case ESC_w:
- for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word];
- continue;
-
- case ESC_W:
- should_flip_negation = TRUE;
- for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word];
- continue;
-
- /* Perl 5.004 onwards omits VT from \s, but we must preserve it
- if it was previously set by something earlier in the character
- class. Luckily, the value of CHAR_VT is 0x0b in both ASCII and
- EBCDIC, so we lazily just adjust the appropriate bit. */
-
- case ESC_s:
- classbits[0] |= cbits[cbit_space];
- classbits[1] |= cbits[cbit_space+1] & ~0x08;
- for (c = 2; c < 32; c++) classbits[c] |= cbits[c+cbit_space];
- continue;
-
- case ESC_S:
- should_flip_negation = TRUE;
- for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space];
- classbits[1] |= 0x08; /* Perl 5.004 onwards omits VT from \s */
- continue;
-
- /* The rest apply in both UCP and non-UCP cases. */
-
- case ESC_h:
- (void)add_list_to_class(classbits, &class_uchardata, options, cd,
- PRIV(hspace_list), NOTACHAR);
- continue;
-
- case ESC_H:
- (void)add_not_list_to_class(classbits, &class_uchardata, options,
- cd, PRIV(hspace_list));
- continue;
-
- case ESC_v:
- (void)add_list_to_class(classbits, &class_uchardata, options, cd,
- PRIV(vspace_list), NOTACHAR);
- continue;
-
- case ESC_V:
- (void)add_not_list_to_class(classbits, &class_uchardata, options,
- cd, PRIV(vspace_list));
- continue;
-
-#ifdef SUPPORT_UCP
- case ESC_p:
- case ESC_P:
- {
- BOOL negated;
- unsigned int ptype = 0, pdata = 0;
- if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr))
- goto FAILED;
- *class_uchardata++ = ((escape == ESC_p) != negated)?
- XCL_PROP : XCL_NOTPROP;
- *class_uchardata++ = ptype;
- *class_uchardata++ = pdata;
- class_has_8bitchar--; /* Undo! */
- continue;
- }
-#endif
- /* Unrecognized escapes are faulted if PCRE is running in its
- strict mode. By default, for compatibility with Perl, they are
- treated as literals. */
-
- default:
- if ((options & PCRE_EXTRA) != 0)
- {
- *errorcodeptr = ERR7;
- goto FAILED;
- }
- class_has_8bitchar--; /* Undo the speculative increase. */
- class_one_char -= 2; /* Undo the speculative increase. */
- c = *ptr; /* Get the final character and fall through */
- break;
- }
- }
-
- /* Fall through if the escape just defined a single character (c >= 0).
- This may be greater than 256. */
-
- escape = 0;
-
- } /* End of backslash handling */
-
- /* A character may be followed by '-' to form a range. However, Perl does
- not permit ']' to be the end of the range. A '-' character at the end is
- treated as a literal. Perl ignores orphaned \E sequences entirely. The
- code for handling \Q and \E is messy. */
-
- CHECK_RANGE:
- while (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
- {
- inescq = FALSE;
- ptr += 2;
- }
- oldptr = ptr;
-
- /* Remember if \r or \n were explicitly used */
-
- if (c == CHAR_CR || c == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF;
-
- /* Check for range */
-
- if (!inescq && ptr[1] == CHAR_MINUS)
- {
- pcre_uint32 d;
- ptr += 2;
- while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) ptr += 2;
-
- /* If we hit \Q (not followed by \E) at this point, go into escaped
- mode. */
-
- while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_Q)
- {
- ptr += 2;
- if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E)
- { ptr += 2; continue; }
- inescq = TRUE;
- break;
- }
-
- /* Minus (hyphen) at the end of a class is treated as a literal, so put
- back the pointer and jump to handle the character that preceded it. */
-
- if (*ptr == CHAR_NULL || (!inescq && *ptr == CHAR_RIGHT_SQUARE_BRACKET))
- {
- ptr = oldptr;
- goto CLASS_SINGLE_CHARACTER;
- }
-
- /* Otherwise, we have a potential range; pick up the next character */
-
-#ifdef SUPPORT_UTF
- if (utf)
- { /* Braces are required because the */
- GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */
- }
- else
-#endif
- d = *ptr; /* Not UTF-8 mode */
-
- /* The second part of a range can be a single-character escape, but
- not any of the other escapes. Perl 5.6 treats a hyphen as a literal
- in such circumstances. */
-
- if (!inescq && d == CHAR_BACKSLASH)
- {
- int descape;
- descape = check_escape(&ptr, &d, errorcodeptr, cd->bracount, options, TRUE);
- if (*errorcodeptr != 0) goto FAILED;
-
- /* \b is backspace; any other special means the '-' was literal. */
-
- if (descape != 0)
- {
- if (descape == ESC_b) d = CHAR_BS; else
- {
- ptr = oldptr;
- goto CLASS_SINGLE_CHARACTER; /* A few lines below */
- }
- }
- }
-
- /* Check that the two values are in the correct order. Optimize
- one-character ranges. */
-
- if (d < c)
- {
- *errorcodeptr = ERR8;
- goto FAILED;
- }
- if (d == c) goto CLASS_SINGLE_CHARACTER; /* A few lines below */
-
- /* We have found a character range, so single character optimizations
- cannot be done anymore. Any value greater than 1 indicates that there
- is more than one character. */
-
- class_one_char = 2;
-
- /* Remember an explicit \r or \n, and add the range to the class. */
-
- if (d == CHAR_CR || d == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF;
-
- class_has_8bitchar +=
- add_to_class(classbits, &class_uchardata, options, cd, c, d);
-
- continue; /* Go get the next char in the class */
- }
-
- /* Handle a single character - we can get here for a normal non-escape
- char, or after \ that introduces a single character or for an apparent
- range that isn't. Only the value 1 matters for class_one_char, so don't
- increase it if it is already 2 or more ... just in case there's a class
- with a zillion characters in it. */
-
- CLASS_SINGLE_CHARACTER:
- if (class_one_char < 2) class_one_char++;
-
- /* If class_one_char is 1, we have the first single character in the
- class, and there have been no prior ranges, or XCLASS items generated by
- escapes. If this is the final character in the class, we can optimize by
- turning the item into a 1-character OP_CHAR[I] if it's positive, or
- OP_NOT[I] if it's negative. In the positive case, it can cause firstchar
- to be set. Otherwise, there can be no first char if this item is first,
- whatever repeat count may follow. In the case of reqchar, save the
- previous value for reinstating. */
-
- if (class_one_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
- {
- ptr++;
- zeroreqchar = reqchar;
- zeroreqcharflags = reqcharflags;
-
- if (negate_class)
- {
-#ifdef SUPPORT_UCP
- int d;
-#endif
- if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
- zerofirstchar = firstchar;
- zerofirstcharflags = firstcharflags;
-
- /* For caseless UTF-8 mode when UCP support is available, check
- whether this character has more than one other case. If so, generate
- a special OP_NOTPROP item instead of OP_NOTI. */
-
-#ifdef SUPPORT_UCP
- if (utf && (options & PCRE_CASELESS) != 0 &&
- (d = UCD_CASESET(c)) != 0)
- {
- *code++ = OP_NOTPROP;
- *code++ = PT_CLIST;
- *code++ = d;
- }
- else
-#endif
- /* Char has only one other case, or UCP not available */
-
- {
- *code++ = ((options & PCRE_CASELESS) != 0)? OP_NOTI: OP_NOT;
-#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
- if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR)
- code += PRIV(ord2utf)(c, code);
- else
-#endif
- *code++ = c;
- }
-
- /* We are finished with this character class */
-
- goto END_CLASS;
- }
-
- /* For a single, positive character, get the value into mcbuffer, and
- then we can handle this with the normal one-character code. */
-
-#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
- if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR)
- mclength = PRIV(ord2utf)(c, mcbuffer);
- else
-#endif
- {
- mcbuffer[0] = c;
- mclength = 1;
- }
- goto ONE_CHAR;
- } /* End of 1-char optimization */
-
- /* There is more than one character in the class, or an XCLASS item
- has been generated. Add this character to the class. */
-
- class_has_8bitchar +=
- add_to_class(classbits, &class_uchardata, options, cd, c, c);
- }
-
- /* Loop until ']' reached. This "while" is the end of the "do" far above.
- If we are at the end of an internal nested string, revert to the outer
- string. */
-
- while (((c = *(++ptr)) != CHAR_NULL ||
- (nestptr != NULL &&
- (ptr = nestptr, nestptr = NULL, c = *(++ptr)) != CHAR_NULL)) &&
- (c != CHAR_RIGHT_SQUARE_BRACKET || inescq));
-
- /* Check for missing terminating ']' */
-
- if (c == CHAR_NULL)
- {
- *errorcodeptr = ERR6;
- goto FAILED;
- }
-
- /* We will need an XCLASS if data has been placed in class_uchardata. In
- the second phase this is a sufficient test. However, in the pre-compile
- phase, class_uchardata gets emptied to prevent workspace overflow, so it
- only if the very last character in the class needs XCLASS will it contain
- anything at this point. For this reason, xclass gets set TRUE above when
- uchar_classdata is emptied, and that's why this code is the way it is here
- instead of just doing a test on class_uchardata below. */
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- if (class_uchardata > class_uchardata_base) xclass = TRUE;
-#endif
-
- /* If this is the first thing in the branch, there can be no first char
- setting, whatever the repeat count. Any reqchar setting must remain
- unchanged after any kind of repeat. */
-
- if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
- zerofirstchar = firstchar;
- zerofirstcharflags = firstcharflags;
- zeroreqchar = reqchar;
- zeroreqcharflags = reqcharflags;
-
- /* If there are characters with values > 255, we have to compile an
- extended class, with its own opcode, unless there was a negated special
- such as \S in the class, and PCRE_UCP is not set, because in that case all
- characters > 255 are in the class, so any that were explicitly given as
- well can be ignored. If (when there are explicit characters > 255 that must
- be listed) there are no characters < 256, we can omit the bitmap in the
- actual compiled code. */
-
-#ifdef SUPPORT_UTF
- if (xclass && (!should_flip_negation || (options & PCRE_UCP) != 0))
-#elif !defined COMPILE_PCRE8
- if (xclass && !should_flip_negation)
-#endif
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- {
- *class_uchardata++ = XCL_END; /* Marks the end of extra data */
- *code++ = OP_XCLASS;
- code += LINK_SIZE;
- *code = negate_class? XCL_NOT:0;
-
- /* If the map is required, move up the extra data to make room for it;
- otherwise just move the code pointer to the end of the extra data. */
-
- if (class_has_8bitchar > 0)
- {
- *code++ |= XCL_MAP;
- memmove(code + (32 / sizeof(pcre_uchar)), code,
- IN_UCHARS(class_uchardata - code));
- memcpy(code, classbits, 32);
- code = class_uchardata + (32 / sizeof(pcre_uchar));
- }
- else code = class_uchardata;
-
- /* Now fill in the complete length of the item */
-
- PUT(previous, 1, (int)(code - previous));
- break; /* End of class handling */
- }
-#endif
-
- /* If there are no characters > 255, or they are all to be included or
- excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the
- whole class was negated and whether there were negative specials such as \S
- (non-UCP) in the class. Then copy the 32-byte map into the code vector,
- negating it if necessary. */
-
- *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS;
- if (lengthptr == NULL) /* Save time in the pre-compile phase */
- {
- if (negate_class)
- for (c = 0; c < 32; c++) classbits[c] = ~classbits[c];
- memcpy(code, classbits, 32);
- }
- code += 32 / sizeof(pcre_uchar);
-
- END_CLASS:
- break;
-
-
- /* ===================================================================*/
- /* Various kinds of repeat; '{' is not necessarily a quantifier, but this
- has been tested above. */
-
- case CHAR_LEFT_CURLY_BRACKET:
- if (!is_quantifier) goto NORMAL_CHAR;
- ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorcodeptr);
- if (*errorcodeptr != 0) goto FAILED;
- goto REPEAT;
-
- case CHAR_ASTERISK:
- repeat_min = 0;
- repeat_max = -1;
- goto REPEAT;
-
- case CHAR_PLUS:
- repeat_min = 1;
- repeat_max = -1;
- goto REPEAT;
-
- case CHAR_QUESTION_MARK:
- repeat_min = 0;
- repeat_max = 1;
-
- REPEAT:
- if (previous == NULL)
- {
- *errorcodeptr = ERR9;
- goto FAILED;
- }
-
- if (repeat_min == 0)
- {
- firstchar = zerofirstchar; /* Adjust for zero repeat */
- firstcharflags = zerofirstcharflags;
- reqchar = zeroreqchar; /* Ditto */
- reqcharflags = zeroreqcharflags;
- }
-
- /* Remember whether this is a variable length repeat */
-
- reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY;
-
- op_type = 0; /* Default single-char op codes */
- possessive_quantifier = FALSE; /* Default not possessive quantifier */
-
- /* Save start of previous item, in case we have to move it up in order to
- insert something before it. */
-
- tempcode = previous;
-
- /* If the next character is '+', we have a possessive quantifier. This
- implies greediness, whatever the setting of the PCRE_UNGREEDY option.
- If the next character is '?' this is a minimizing repeat, by default,
- but if PCRE_UNGREEDY is set, it works the other way round. We change the
- repeat type to the non-default. */
-
- if (ptr[1] == CHAR_PLUS)
- {
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- ptr++;
- }
- else if (ptr[1] == CHAR_QUESTION_MARK)
- {
- repeat_type = greedy_non_default;
- ptr++;
- }
- else repeat_type = greedy_default;
-
- /* If previous was a recursion call, wrap it in atomic brackets so that
- previous becomes the atomic group. All recursions were so wrapped in the
- past, but it no longer happens for non-repeated recursions. In fact, the
- repeated ones could be re-implemented independently so as not to need this,
- but for the moment we rely on the code for repeating groups. */
-
- if (*previous == OP_RECURSE)
- {
- memmove(previous + 1 + LINK_SIZE, previous, IN_UCHARS(1 + LINK_SIZE));
- *previous = OP_ONCE;
- PUT(previous, 1, 2 + 2*LINK_SIZE);
- previous[2 + 2*LINK_SIZE] = OP_KET;
- PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE);
- code += 2 + 2 * LINK_SIZE;
- length_prevgroup = 3 + 3*LINK_SIZE;
-
- /* When actually compiling, we need to check whether this was a forward
- reference, and if so, adjust the offset. */
-
- if (lengthptr == NULL && cd->hwm >= cd->start_workspace + LINK_SIZE)
- {
- int offset = GET(cd->hwm, -LINK_SIZE);
- if (offset == previous + 1 - cd->start_code)
- PUT(cd->hwm, -LINK_SIZE, offset + 1 + LINK_SIZE);
- }
- }
-
- /* Now handle repetition for the different types of item. */
-
- /* If previous was a character or negated character match, abolish the item
- and generate a repeat item instead. If a char item has a minimum of more
- than one, ensure that it is set in reqchar - it might not be if a sequence
- such as x{3} is the first thing in a branch because the x will have gone
- into firstchar instead. */
-
- if (*previous == OP_CHAR || *previous == OP_CHARI
- || *previous == OP_NOT || *previous == OP_NOTI)
- {
- switch (*previous)
- {
- default: /* Make compiler happy. */
- case OP_CHAR: op_type = OP_STAR - OP_STAR; break;
- case OP_CHARI: op_type = OP_STARI - OP_STAR; break;
- case OP_NOT: op_type = OP_NOTSTAR - OP_STAR; break;
- case OP_NOTI: op_type = OP_NOTSTARI - OP_STAR; break;
- }
-
- /* Deal with UTF characters that take up more than one character. It's
- easier to write this out separately than try to macrify it. Use c to
- hold the length of the character in bytes, plus UTF_LENGTH to flag that
- it's a length rather than a small character. */
-
-#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
- if (utf && NOT_FIRSTCHAR(code[-1]))
- {
- pcre_uchar *lastchar = code - 1;
- BACKCHAR(lastchar);
- c = (int)(code - lastchar); /* Length of UTF-8 character */
- memcpy(utf_chars, lastchar, IN_UCHARS(c)); /* Save the char */
- c |= UTF_LENGTH; /* Flag c as a length */
- }
- else
-#endif /* SUPPORT_UTF */
-
- /* Handle the case of a single charater - either with no UTF support, or
- with UTF disabled, or for a single character UTF character. */
- {
- c = code[-1];
- if (*previous <= OP_CHARI && repeat_min > 1)
- {
- reqchar = c;
- reqcharflags = req_caseopt | cd->req_varyopt;
- }
- }
-
- /* If the repetition is unlimited, it pays to see if the next thing on
- the line is something that cannot possibly match this character. If so,
- automatically possessifying this item gains some performance in the case
- where the match fails. */
-
- if (!possessive_quantifier &&
- repeat_max < 0 &&
- check_auto_possessive(previous, utf, ptr + 1, options, cd))
- {
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- }
-
- goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */
- }
-
- /* If previous was a character type match (\d or similar), abolish it and
- create a suitable repeat item. The code is shared with single-character
- repeats by setting op_type to add a suitable offset into repeat_type. Note
- the the Unicode property types will be present only when SUPPORT_UCP is
- defined, but we don't wrap the little bits of code here because it just
- makes it horribly messy. */
-
- else if (*previous < OP_EODN)
- {
- pcre_uchar *oldcode;
- int prop_type, prop_value;
- op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */
- c = *previous;
-
- if (!possessive_quantifier &&
- repeat_max < 0 &&
- check_auto_possessive(previous, utf, ptr + 1, options, cd))
- {
- repeat_type = 0; /* Force greedy */
- possessive_quantifier = TRUE;
- }
-
- OUTPUT_SINGLE_REPEAT:
- if (*previous == OP_PROP || *previous == OP_NOTPROP)
- {
- prop_type = previous[1];
- prop_value = previous[2];
- }
- else prop_type = prop_value = -1;
-
- oldcode = code;
- code = previous; /* Usually overwrite previous item */
-
- /* If the maximum is zero then the minimum must also be zero; Perl allows
- this case, so we do too - by simply omitting the item altogether. */
-
- if (repeat_max == 0) goto END_REPEAT;
-
- /* Combine the op_type with the repeat_type */
-
- repeat_type += op_type;
-
- /* A minimum of zero is handled either as the special case * or ?, or as
- an UPTO, with the maximum given. */
-
- if (repeat_min == 0)
- {
- if (repeat_max == -1) *code++ = OP_STAR + repeat_type;
- else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type;
- else
- {
- *code++ = OP_UPTO + repeat_type;
- PUT2INC(code, 0, repeat_max);
- }
- }
-
- /* A repeat minimum of 1 is optimized into some special cases. If the
- maximum is unlimited, we use OP_PLUS. Otherwise, the original item is
- left in place and, if the maximum is greater than 1, we use OP_UPTO with
- one less than the maximum. */
-
- else if (repeat_min == 1)
- {
- if (repeat_max == -1)
- *code++ = OP_PLUS + repeat_type;
- else
- {
- code = oldcode; /* leave previous item in place */
- if (repeat_max == 1) goto END_REPEAT;
- *code++ = OP_UPTO + repeat_type;
- PUT2INC(code, 0, repeat_max - 1);
- }
- }
-
- /* The case {n,n} is just an EXACT, while the general case {n,m} is
- handled as an EXACT followed by an UPTO. */
-
- else
- {
- *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */
- PUT2INC(code, 0, repeat_min);
-
- /* If the maximum is unlimited, insert an OP_STAR. Before doing so,
- we have to insert the character for the previous code. For a repeated
- Unicode property match, there are two extra bytes that define the
- required property. In UTF-8 mode, long characters have their length in
- c, with the UTF_LENGTH bit as a flag. */
-
- if (repeat_max < 0)
- {
-#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
- if (utf && (c & UTF_LENGTH) != 0)
- {
- memcpy(code, utf_chars, IN_UCHARS(c & 7));
- code += c & 7;
- }
- else
-#endif
- {
- *code++ = c;
- if (prop_type >= 0)
- {
- *code++ = prop_type;
- *code++ = prop_value;
- }
- }
- *code++ = OP_STAR + repeat_type;
- }
-
- /* Else insert an UPTO if the max is greater than the min, again
- preceded by the character, for the previously inserted code. If the
- UPTO is just for 1 instance, we can use QUERY instead. */
-
- else if (repeat_max != repeat_min)
- {
-#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
- if (utf && (c & UTF_LENGTH) != 0)
- {
- memcpy(code, utf_chars, IN_UCHARS(c & 7));
- code += c & 7;
- }
- else
-#endif
- *code++ = c;
- if (prop_type >= 0)
- {
- *code++ = prop_type;
- *code++ = prop_value;
- }
- repeat_max -= repeat_min;
-
- if (repeat_max == 1)
- {
- *code++ = OP_QUERY + repeat_type;
- }
- else
- {
- *code++ = OP_UPTO + repeat_type;
- PUT2INC(code, 0, repeat_max);
- }
- }
- }
-
- /* The character or character type itself comes last in all cases. */
-
-#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
- if (utf && (c & UTF_LENGTH) != 0)
- {
- memcpy(code, utf_chars, IN_UCHARS(c & 7));
- code += c & 7;
- }
- else
-#endif
- *code++ = c;
-
- /* For a repeated Unicode property match, there are two extra bytes that
- define the required property. */
-
-#ifdef SUPPORT_UCP
- if (prop_type >= 0)
- {
- *code++ = prop_type;
- *code++ = prop_value;
- }
-#endif
- }
-
- /* If previous was a character class or a back reference, we put the repeat
- stuff after it, but just skip the item if the repeat was {0,0}. */
-
- else if (*previous == OP_CLASS ||
- *previous == OP_NCLASS ||
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- *previous == OP_XCLASS ||
-#endif
- *previous == OP_REF ||
- *previous == OP_REFI)
- {
- if (repeat_max == 0)
- {
- code = previous;
- goto END_REPEAT;
- }
-
- if (repeat_min == 0 && repeat_max == -1)
- *code++ = OP_CRSTAR + repeat_type;
- else if (repeat_min == 1 && repeat_max == -1)
- *code++ = OP_CRPLUS + repeat_type;
- else if (repeat_min == 0 && repeat_max == 1)
- *code++ = OP_CRQUERY + repeat_type;
- else
- {
- *code++ = OP_CRRANGE + repeat_type;
- PUT2INC(code, 0, repeat_min);
- if (repeat_max == -1) repeat_max = 0; /* 2-byte encoding for max */
- PUT2INC(code, 0, repeat_max);
- }
- }
-
- /* If previous was a bracket group, we may have to replicate it in certain
- cases. Note that at this point we can encounter only the "basic" bracket
- opcodes such as BRA and CBRA, as this is the place where they get converted
- into the more special varieties such as BRAPOS and SBRA. A test for >=
- OP_ASSERT and <= OP_COND includes ASSERT, ASSERT_NOT, ASSERTBACK,
- ASSERTBACK_NOT, ONCE, BRA, CBRA, and COND. Originally, PCRE did not allow
- repetition of assertions, but now it does, for Perl compatibility. */
-
- else if (*previous >= OP_ASSERT && *previous <= OP_COND)
- {
- register int i;
- int len = (int)(code - previous);
- pcre_uchar *bralink = NULL;
- pcre_uchar *brazeroptr = NULL;
-
- /* Repeating a DEFINE group is pointless, but Perl allows the syntax, so
- we just ignore the repeat. */
-
- if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_DEF)
- goto END_REPEAT;
-
- /* There is no sense in actually repeating assertions. The only potential
- use of repetition is in cases when the assertion is optional. Therefore,
- if the minimum is greater than zero, just ignore the repeat. If the
- maximum is not not zero or one, set it to 1. */
-
- if (*previous < OP_ONCE) /* Assertion */
- {
- if (repeat_min > 0) goto END_REPEAT;
- if (repeat_max < 0 || repeat_max > 1) repeat_max = 1;
- }
-
- /* The case of a zero minimum is special because of the need to stick
- OP_BRAZERO in front of it, and because the group appears once in the
- data, whereas in other cases it appears the minimum number of times. For
- this reason, it is simplest to treat this case separately, as otherwise
- the code gets far too messy. There are several special subcases when the
- minimum is zero. */
-
- if (repeat_min == 0)
- {
- /* If the maximum is also zero, we used to just omit the group from the
- output altogether, like this:
-
- ** if (repeat_max == 0)
- ** {
- ** code = previous;
- ** goto END_REPEAT;
- ** }
-
- However, that fails when a group or a subgroup within it is referenced
- as a subroutine from elsewhere in the pattern, so now we stick in
- OP_SKIPZERO in front of it so that it is skipped on execution. As we
- don't have a list of which groups are referenced, we cannot do this
- selectively.
-
- If the maximum is 1 or unlimited, we just have to stick in the BRAZERO
- and do no more at this point. However, we do need to adjust any
- OP_RECURSE calls inside the group that refer to the group itself or any
- internal or forward referenced group, because the offset is from the
- start of the whole regex. Temporarily terminate the pattern while doing
- this. */
-
- if (repeat_max <= 1) /* Covers 0, 1, and unlimited */
- {
- *code = OP_END;
- adjust_recurse(previous, 1, utf, cd, save_hwm);
- memmove(previous + 1, previous, IN_UCHARS(len));
- code++;
- if (repeat_max == 0)
- {
- *previous++ = OP_SKIPZERO;
- goto END_REPEAT;
- }
- brazeroptr = previous; /* Save for possessive optimizing */
- *previous++ = OP_BRAZERO + repeat_type;
- }
-
- /* If the maximum is greater than 1 and limited, we have to replicate
- in a nested fashion, sticking OP_BRAZERO before each set of brackets.
- The first one has to be handled carefully because it's the original
- copy, which has to be moved up. The remainder can be handled by code
- that is common with the non-zero minimum case below. We have to
- adjust the value or repeat_max, since one less copy is required. Once
- again, we may have to adjust any OP_RECURSE calls inside the group. */
-
- else
- {
- int offset;
- *code = OP_END;
- adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm);
- memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
- code += 2 + LINK_SIZE;
- *previous++ = OP_BRAZERO + repeat_type;
- *previous++ = OP_BRA;
-
- /* We chain together the bracket offset fields that have to be
- filled in later when the ends of the brackets are reached. */
-
- offset = (bralink == NULL)? 0 : (int)(previous - bralink);
- bralink = previous;
- PUTINC(previous, 0, offset);
- }
-
- repeat_max--;
- }
-
- /* If the minimum is greater than zero, replicate the group as many
- times as necessary, and adjust the maximum to the number of subsequent
- copies that we need. If we set a first char from the group, and didn't
- set a required char, copy the latter from the former. If there are any
- forward reference subroutine calls in the group, there will be entries on
- the workspace list; replicate these with an appropriate increment. */
-
- else
- {
- if (repeat_min > 1)
- {
- /* In the pre-compile phase, we don't actually do the replication. We
- just adjust the length as if we had. Do some paranoid checks for
- potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit
- integer type when available, otherwise double. */
-
- if (lengthptr != NULL)
- {
- int delta = (repeat_min - 1)*length_prevgroup;
- if ((INT64_OR_DOUBLE)(repeat_min - 1)*
- (INT64_OR_DOUBLE)length_prevgroup >
- (INT64_OR_DOUBLE)INT_MAX ||
- OFLOW_MAX - *lengthptr < delta)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
- *lengthptr += delta;
- }
-
- /* This is compiling for real. If there is a set first byte for
- the group, and we have not yet set a "required byte", set it. Make
- sure there is enough workspace for copying forward references before
- doing the copy. */
-
- else
- {
- if (groupsetfirstchar && reqcharflags < 0)
- {
- reqchar = firstchar;
- reqcharflags = firstcharflags;
- }
-
- for (i = 1; i < repeat_min; i++)
- {
- pcre_uchar *hc;
- pcre_uchar *this_hwm = cd->hwm;
- memcpy(code, previous, IN_UCHARS(len));
-
- while (cd->hwm > cd->start_workspace + cd->workspace_size -
- WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
- {
- int save_offset = save_hwm - cd->start_workspace;
- int this_offset = this_hwm - cd->start_workspace;
- *errorcodeptr = expand_workspace(cd);
- if (*errorcodeptr != 0) goto FAILED;
- save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
- this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
- }
-
- for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
- {
- PUT(cd->hwm, 0, GET(hc, 0) + len);
- cd->hwm += LINK_SIZE;
- }
- save_hwm = this_hwm;
- code += len;
- }
- }
- }
-
- if (repeat_max > 0) repeat_max -= repeat_min;
- }
-
- /* This code is common to both the zero and non-zero minimum cases. If
- the maximum is limited, it replicates the group in a nested fashion,
- remembering the bracket starts on a stack. In the case of a zero minimum,
- the first one was set up above. In all cases the repeat_max now specifies
- the number of additional copies needed. Again, we must remember to
- replicate entries on the forward reference list. */
-
- if (repeat_max >= 0)
- {
- /* In the pre-compile phase, we don't actually do the replication. We
- just adjust the length as if we had. For each repetition we must add 1
- to the length for BRAZERO and for all but the last repetition we must
- add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
- paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type is
- a 64-bit integer type when available, otherwise double. */
-
- if (lengthptr != NULL && repeat_max > 0)
- {
- int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
- 2 - 2*LINK_SIZE; /* Last one doesn't nest */
- if ((INT64_OR_DOUBLE)repeat_max *
- (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
- > (INT64_OR_DOUBLE)INT_MAX ||
- OFLOW_MAX - *lengthptr < delta)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
- *lengthptr += delta;
- }
-
- /* This is compiling for real */
-
- else for (i = repeat_max - 1; i >= 0; i--)
- {
- pcre_uchar *hc;
- pcre_uchar *this_hwm = cd->hwm;
-
- *code++ = OP_BRAZERO + repeat_type;
-
- /* All but the final copy start a new nesting, maintaining the
- chain of brackets outstanding. */
-
- if (i != 0)
- {
- int offset;
- *code++ = OP_BRA;
- offset = (bralink == NULL)? 0 : (int)(code - bralink);
- bralink = code;
- PUTINC(code, 0, offset);
- }
-
- memcpy(code, previous, IN_UCHARS(len));
-
- /* Ensure there is enough workspace for forward references before
- copying them. */
-
- while (cd->hwm > cd->start_workspace + cd->workspace_size -
- WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
- {
- int save_offset = save_hwm - cd->start_workspace;
- int this_offset = this_hwm - cd->start_workspace;
- *errorcodeptr = expand_workspace(cd);
- if (*errorcodeptr != 0) goto FAILED;
- save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
- this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
- }
-
- for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
- {
- PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
- cd->hwm += LINK_SIZE;
- }
- save_hwm = this_hwm;
- code += len;
- }
-
- /* Now chain through the pending brackets, and fill in their length
- fields (which are holding the chain links pro tem). */
-
- while (bralink != NULL)
- {
- int oldlinkoffset;
- int offset = (int)(code - bralink + 1);
- pcre_uchar *bra = code - offset;
- oldlinkoffset = GET(bra, 1);
- bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset;
- *code++ = OP_KET;
- PUTINC(code, 0, offset);
- PUT(bra, 1, offset);
- }
- }
-
- /* If the maximum is unlimited, set a repeater in the final copy. For
- ONCE brackets, that's all we need to do. However, possessively repeated
- ONCE brackets can be converted into non-capturing brackets, as the
- behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to
- deal with possessive ONCEs specially.
-
- Otherwise, when we are doing the actual compile phase, check to see
- whether this group is one that could match an empty string. If so,
- convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so
- that runtime checking can be done. [This check is also applied to ONCE
- groups at runtime, but in a different way.]
-
- Then, if the quantifier was possessive and the bracket is not a
- conditional, we convert the BRA code to the POS form, and the KET code to
- KETRPOS. (It turns out to be convenient at runtime to detect this kind of
- subpattern at both the start and at the end.) The use of special opcodes
- makes it possible to reduce greatly the stack usage in pcre_exec(). If
- the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO.
-
- Then, if the minimum number of matches is 1 or 0, cancel the possessive
- flag so that the default action below, of wrapping everything inside
- atomic brackets, does not happen. When the minimum is greater than 1,
- there will be earlier copies of the group, and so we still have to wrap
- the whole thing. */
-
- else
- {
- pcre_uchar *ketcode = code - 1 - LINK_SIZE;
- pcre_uchar *bracode = ketcode - GET(ketcode, 1);
-
- /* Convert possessive ONCE brackets to non-capturing */
-
- if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) &&
- possessive_quantifier) *bracode = OP_BRA;
-
- /* For non-possessive ONCE brackets, all we need to do is to
- set the KET. */
-
- if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC)
- *ketcode = OP_KETRMAX + repeat_type;
-
- /* Handle non-ONCE brackets and possessive ONCEs (which have been
- converted to non-capturing above). */
-
- else
- {
- /* In the compile phase, check for empty string matching. */
-
- if (lengthptr == NULL)
- {
- pcre_uchar *scode = bracode;
- do
- {
- if (could_be_empty_branch(scode, ketcode, utf, cd))
- {
- *bracode += OP_SBRA - OP_BRA;
- break;
- }
- scode += GET(scode, 1);
- }
- while (*scode == OP_ALT);
- }
-
- /* Handle possessive quantifiers. */
-
- if (possessive_quantifier)
- {
- /* For COND brackets, we wrap the whole thing in a possessively
- repeated non-capturing bracket, because we have not invented POS
- versions of the COND opcodes. Because we are moving code along, we
- must ensure that any pending recursive references are updated. */
-
- if (*bracode == OP_COND || *bracode == OP_SCOND)
- {
- int nlen = (int)(code - bracode);
- *code = OP_END;
- adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm);
- memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));
- code += 1 + LINK_SIZE;
- nlen += 1 + LINK_SIZE;
- *bracode = OP_BRAPOS;
- *code++ = OP_KETRPOS;
- PUTINC(code, 0, nlen);
- PUT(bracode, 1, nlen);
- }
-
- /* For non-COND brackets, we modify the BRA code and use KETRPOS. */
-
- else
- {
- *bracode += 1; /* Switch to xxxPOS opcodes */
- *ketcode = OP_KETRPOS;
- }
-
- /* If the minimum is zero, mark it as possessive, then unset the
- possessive flag when the minimum is 0 or 1. */
-
- if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO;
- if (repeat_min < 2) possessive_quantifier = FALSE;
- }
-
- /* Non-possessive quantifier */
-
- else *ketcode = OP_KETRMAX + repeat_type;
- }
- }
- }
-
- /* If previous is OP_FAIL, it was generated by an empty class [] in
- JavaScript mode. The other ways in which OP_FAIL can be generated, that is
- by (*FAIL) or (?!) set previous to NULL, which gives a "nothing to repeat"
- error above. We can just ignore the repeat in JS case. */
-
- else if (*previous == OP_FAIL) goto END_REPEAT;
-
- /* Else there's some kind of shambles */
-
- else
- {
- *errorcodeptr = ERR11;
- goto FAILED;
- }
-
- /* If the character following a repeat is '+', or if certain optimization
- tests above succeeded, possessive_quantifier is TRUE. For some opcodes,
- there are special alternative opcodes for this case. For anything else, we
- wrap the entire repeated item inside OP_ONCE brackets. Logically, the '+'
- notation is just syntactic sugar, taken from Sun's Java package, but the
- special opcodes can optimize it.
-
- Some (but not all) possessively repeated subpatterns have already been
- completely handled in the code just above. For them, possessive_quantifier
- is always FALSE at this stage.
-
- Note that the repeated item starts at tempcode, not at previous, which
- might be the first part of a string whose (former) last char we repeated.
-
- Possessifying an 'exact' quantifier has no effect, so we can ignore it. But
- an 'upto' may follow. We skip over an 'exact' item, and then test the
- length of what remains before proceeding. */
-
- if (possessive_quantifier)
- {
- int len;
-
- if (*tempcode == OP_TYPEEXACT)
- tempcode += PRIV(OP_lengths)[*tempcode] +
- ((tempcode[1 + IMM2_SIZE] == OP_PROP
- || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
-
- else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT)
- {
- tempcode += PRIV(OP_lengths)[*tempcode];
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(tempcode[-1]))
- tempcode += GET_EXTRALEN(tempcode[-1]);
-#endif
- }
-
- len = (int)(code - tempcode);
- if (len > 0) switch (*tempcode)
- {
- case OP_STAR: *tempcode = OP_POSSTAR; break;
- case OP_PLUS: *tempcode = OP_POSPLUS; break;
- case OP_QUERY: *tempcode = OP_POSQUERY; break;
- case OP_UPTO: *tempcode = OP_POSUPTO; break;
-
- case OP_STARI: *tempcode = OP_POSSTARI; break;
- case OP_PLUSI: *tempcode = OP_POSPLUSI; break;
- case OP_QUERYI: *tempcode = OP_POSQUERYI; break;
- case OP_UPTOI: *tempcode = OP_POSUPTOI; break;
-
- case OP_NOTSTAR: *tempcode = OP_NOTPOSSTAR; break;
- case OP_NOTPLUS: *tempcode = OP_NOTPOSPLUS; break;
- case OP_NOTQUERY: *tempcode = OP_NOTPOSQUERY; break;
- case OP_NOTUPTO: *tempcode = OP_NOTPOSUPTO; break;
-
- case OP_NOTSTARI: *tempcode = OP_NOTPOSSTARI; break;
- case OP_NOTPLUSI: *tempcode = OP_NOTPOSPLUSI; break;
- case OP_NOTQUERYI: *tempcode = OP_NOTPOSQUERYI; break;
- case OP_NOTUPTOI: *tempcode = OP_NOTPOSUPTOI; break;
-
- case OP_TYPESTAR: *tempcode = OP_TYPEPOSSTAR; break;
- case OP_TYPEPLUS: *tempcode = OP_TYPEPOSPLUS; break;
- case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break;
- case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break;
-
- /* Because we are moving code along, we must ensure that any
- pending recursive references are updated. */
-
- default:
- *code = OP_END;
- adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);
- memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
- code += 1 + LINK_SIZE;
- len += 1 + LINK_SIZE;
- tempcode[0] = OP_ONCE;
- *code++ = OP_KET;
- PUTINC(code, 0, len);
- PUT(tempcode, 1, len);
- break;
- }
- }
-
- /* In all case we no longer have a previous item. We also set the
- "follows varying string" flag for subsequently encountered reqchars if
- it isn't already set and we have just passed a varying length item. */
-
- END_REPEAT:
- previous = NULL;
- cd->req_varyopt |= reqvary;
- break;
-
-
- /* ===================================================================*/
- /* Start of nested parenthesized sub-expression, or comment or lookahead or
- lookbehind or option setting or condition or all the other extended
- parenthesis forms. */
-
- case CHAR_LEFT_PARENTHESIS:
- newoptions = options;
- skipbytes = 0;
- bravalue = OP_CBRA;
- save_hwm = cd->hwm;
- reset_bracount = FALSE;
-
- /* First deal with various "verbs" that can be introduced by '*'. */
-
- ptr++;
- if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':'
- || (MAX_255(ptr[1]) && ((cd->ctypes[ptr[1]] & ctype_letter) != 0))))
- {
- int i, namelen;
- int arglen = 0;
- const char *vn = verbnames;
- const pcre_uchar *name = ptr + 1;
- const pcre_uchar *arg = NULL;
- previous = NULL;
- ptr++;
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_letter) != 0) ptr++;
- namelen = (int)(ptr - name);
-
- /* It appears that Perl allows any characters whatsoever, other than
- a closing parenthesis, to appear in arguments, so we no longer insist on
- letters, digits, and underscores. */
-
- if (*ptr == CHAR_COLON)
- {
- arg = ++ptr;
- while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
- arglen = (int)(ptr - arg);
- if ((unsigned int)arglen > MAX_MARK)
- {
- *errorcodeptr = ERR75;
- goto FAILED;
- }
- }
-
- if (*ptr != CHAR_RIGHT_PARENTHESIS)
- {
- *errorcodeptr = ERR60;
- goto FAILED;
- }
-
- /* Scan the table of verb names */
-
- for (i = 0; i < verbcount; i++)
- {
- if (namelen == verbs[i].len &&
- STRNCMP_UC_C8(name, vn, namelen) == 0)
- {
- int setverb;
-
- /* Check for open captures before ACCEPT and convert it to
- ASSERT_ACCEPT if in an assertion. */
-
- if (verbs[i].op == OP_ACCEPT)
- {
- open_capitem *oc;
- if (arglen != 0)
- {
- *errorcodeptr = ERR59;
- goto FAILED;
- }
- cd->had_accept = TRUE;
- for (oc = cd->open_caps; oc != NULL; oc = oc->next)
- {
- *code++ = OP_CLOSE;
- PUT2INC(code, 0, oc->number);
- }
- setverb = *code++ =
- (cd->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT;
-
- /* Do not set firstchar after *ACCEPT */
- if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
- }
-
- /* Handle other cases with/without an argument */
-
- else if (arglen == 0)
- {
- if (verbs[i].op < 0) /* Argument is mandatory */
- {
- *errorcodeptr = ERR66;
- goto FAILED;
- }
- setverb = *code++ = verbs[i].op;
- }
-
- else
- {
- if (verbs[i].op_arg < 0) /* Argument is forbidden */
- {
- *errorcodeptr = ERR59;
- goto FAILED;
- }
- setverb = *code++ = verbs[i].op_arg;
- *code++ = arglen;
- memcpy(code, arg, IN_UCHARS(arglen));
- code += arglen;
- *code++ = 0;
- }
-
- switch (setverb)
- {
- case OP_THEN:
- case OP_THEN_ARG:
- cd->external_flags |= PCRE_HASTHEN;
- break;
-
- case OP_PRUNE:
- case OP_PRUNE_ARG:
- case OP_SKIP:
- case OP_SKIP_ARG:
- cd->had_pruneorskip = TRUE;
- break;
- }
-
- break; /* Found verb, exit loop */
- }
-
- vn += verbs[i].len + 1;
- }
-
- if (i < verbcount) continue; /* Successfully handled a verb */
- *errorcodeptr = ERR60; /* Verb not recognized */
- goto FAILED;
- }
-
- /* Deal with the extended parentheses; all are introduced by '?', and the
- appearance of any of them means that this is not a capturing group. */
-
- else if (*ptr == CHAR_QUESTION_MARK)
- {
- int i, set, unset, namelen;
- int *optset;
- const pcre_uchar *name;
- pcre_uchar *slot;
-
- switch (*(++ptr))
- {
- case CHAR_NUMBER_SIGN: /* Comment; skip to ket */
- ptr++;
- while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
- if (*ptr == CHAR_NULL)
- {
- *errorcodeptr = ERR18;
- goto FAILED;
- }
- continue;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */
- reset_bracount = TRUE;
- /* Fall through */
-
- /* ------------------------------------------------------------ */
- case CHAR_COLON: /* Non-capturing bracket */
- bravalue = OP_BRA;
- ptr++;
- break;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_LEFT_PARENTHESIS:
- bravalue = OP_COND; /* Conditional group */
- tempptr = ptr;
-
- /* A condition can be an assertion, a number (referring to a numbered
- group), a name (referring to a named group), or 'R', referring to
- recursion. R<digits> and R&name are also permitted for recursion tests.
-
- There are several syntaxes for testing a named group: (?(name)) is used
- by Python; Perl 5.10 onwards uses (?(<name>) or (?('name')).
-
- There are two unfortunate ambiguities, caused by history. (a) 'R' can
- be the recursive thing or the name 'R' (and similarly for 'R' followed
- by digits), and (b) a number could be a name that consists of digits.
- In both cases, we look for a name first; if not found, we try the other
- cases.
-
- For compatibility with auto-callouts, we allow a callout to be
- specified before a condition that is an assertion. First, check for the
- syntax of a callout; if found, adjust the temporary pointer that is
- used to check for an assertion condition. That's all that is needed! */
-
- if (ptr[1] == CHAR_QUESTION_MARK && ptr[2] == CHAR_C)
- {
- for (i = 3;; i++) if (!IS_DIGIT(ptr[i])) break;
- if (ptr[i] == CHAR_RIGHT_PARENTHESIS)
- tempptr += i + 1;
- }
-
- /* For conditions that are assertions, check the syntax, and then exit
- the switch. This will take control down to where bracketed groups,
- including assertions, are processed. */
-
- if (tempptr[1] == CHAR_QUESTION_MARK &&
- (tempptr[2] == CHAR_EQUALS_SIGN ||
- tempptr[2] == CHAR_EXCLAMATION_MARK ||
- tempptr[2] == CHAR_LESS_THAN_SIGN))
- break;
-
- /* Most other conditions use OP_CREF (a couple change to OP_RREF
- below), and all need to skip 1+IMM2_SIZE bytes at the start of the group. */
-
- code[1+LINK_SIZE] = OP_CREF;
- skipbytes = 1+IMM2_SIZE;
- refsign = -1;
-
- /* Check for a test for recursion in a named group. */
-
- if (ptr[1] == CHAR_R && ptr[2] == CHAR_AMPERSAND)
- {
- terminator = -1;
- ptr += 2;
- code[1+LINK_SIZE] = OP_RREF; /* Change the type of test */
- }
-
- /* Check for a test for a named group's having been set, using the Perl
- syntax (?(<name>) or (?('name') */
-
- else if (ptr[1] == CHAR_LESS_THAN_SIGN)
- {
- terminator = CHAR_GREATER_THAN_SIGN;
- ptr++;
- }
- else if (ptr[1] == CHAR_APOSTROPHE)
- {
- terminator = CHAR_APOSTROPHE;
- ptr++;
- }
- else
- {
- terminator = CHAR_NULL;
- if (ptr[1] == CHAR_MINUS || ptr[1] == CHAR_PLUS) refsign = *(++ptr);
- }
-
- /* We now expect to read a name; any thing else is an error */
-
- if (!MAX_255(ptr[1]) || (cd->ctypes[ptr[1]] & ctype_word) == 0)
- {
- ptr += 1; /* To get the right offset */
- *errorcodeptr = ERR28;
- goto FAILED;
- }
-
- /* Read the name, but also get it as a number if it's all digits */
-
- recno = 0;
- name = ++ptr;
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0)
- {
- if (recno >= 0)
- recno = (IS_DIGIT(*ptr))? recno * 10 + (int)(*ptr - CHAR_0) : -1;
- ptr++;
- }
- namelen = (int)(ptr - name);
-
- if ((terminator > 0 && *ptr++ != (pcre_uchar)terminator) ||
- *ptr++ != CHAR_RIGHT_PARENTHESIS)
- {
- ptr--; /* Error offset */
- *errorcodeptr = ERR26;
- goto FAILED;
- }
-
- /* Do no further checking in the pre-compile phase. */
-
- if (lengthptr != NULL) break;
-
- /* In the real compile we do the work of looking for the actual
- reference. If the string started with "+" or "-" we require the rest to
- be digits, in which case recno will be set. */
-
- if (refsign > 0)
- {
- if (recno <= 0)
- {
- *errorcodeptr = ERR58;
- goto FAILED;
- }
- recno = (refsign == CHAR_MINUS)?
- cd->bracount - recno + 1 : recno +cd->bracount;
- if (recno <= 0 || recno > cd->final_bracount)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
- PUT2(code, 2+LINK_SIZE, recno);
- break;
- }
-
- /* Otherwise (did not start with "+" or "-"), start by looking for the
- name. If we find a name, add one to the opcode to change OP_CREF or
- OP_RREF into OP_NCREF or OP_NRREF. These behave exactly the same,
- except they record that the reference was originally to a name. The
- information is used to check duplicate names. */
-
- slot = cd->name_table;
- for (i = 0; i < cd->names_found; i++)
- {
- if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0) break;
- slot += cd->name_entry_size;
- }
-
- /* Found a previous named subpattern */
-
- if (i < cd->names_found)
- {
- recno = GET2(slot, 0);
- PUT2(code, 2+LINK_SIZE, recno);
- code[1+LINK_SIZE]++;
- }
-
- /* Search the pattern for a forward reference */
-
- else if ((i = find_parens(cd, name, namelen,
- (options & PCRE_EXTENDED) != 0, utf)) > 0)
- {
- PUT2(code, 2+LINK_SIZE, i);
- code[1+LINK_SIZE]++;
- }
-
- /* If terminator == CHAR_NULL it means that the name followed directly
- after the opening parenthesis [e.g. (?(abc)...] and in this case there
- are some further alternatives to try. For the cases where terminator !=
- 0 [things like (?(<name>... or (?('name')... or (?(R&name)... ] we have
- now checked all the possibilities, so give an error. */
-
- else if (terminator != CHAR_NULL)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
-
- /* Check for (?(R) for recursion. Allow digits after R to specify a
- specific group number. */
-
- else if (*name == CHAR_R)
- {
- recno = 0;
- for (i = 1; i < namelen; i++)
- {
- if (!IS_DIGIT(name[i]))
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
- recno = recno * 10 + name[i] - CHAR_0;
- }
- if (recno == 0) recno = RREF_ANY;
- code[1+LINK_SIZE] = OP_RREF; /* Change test type */
- PUT2(code, 2+LINK_SIZE, recno);
- }
-
- /* Similarly, check for the (?(DEFINE) "condition", which is always
- false. */
-
- else if (namelen == 6 && STRNCMP_UC_C8(name, STRING_DEFINE, 6) == 0)
- {
- code[1+LINK_SIZE] = OP_DEF;
- skipbytes = 1;
- }
-
- /* Check for the "name" actually being a subpattern number. We are
- in the second pass here, so final_bracount is set. */
-
- else if (recno > 0 && recno <= cd->final_bracount)
- {
- PUT2(code, 2+LINK_SIZE, recno);
- }
-
- /* Either an unidentified subpattern, or a reference to (?(0) */
-
- else
- {
- *errorcodeptr = (recno == 0)? ERR35: ERR15;
- goto FAILED;
- }
- break;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_EQUALS_SIGN: /* Positive lookahead */
- bravalue = OP_ASSERT;
- cd->assert_depth += 1;
- ptr++;
- break;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_EXCLAMATION_MARK: /* Negative lookahead */
- ptr++;
- if (*ptr == CHAR_RIGHT_PARENTHESIS) /* Optimize (?!) */
- {
- *code++ = OP_FAIL;
- previous = NULL;
- continue;
- }
- bravalue = OP_ASSERT_NOT;
- cd->assert_depth += 1;
- break;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_LESS_THAN_SIGN: /* Lookbehind or named define */
- switch (ptr[1])
- {
- case CHAR_EQUALS_SIGN: /* Positive lookbehind */
- bravalue = OP_ASSERTBACK;
- cd->assert_depth += 1;
- ptr += 2;
- break;
-
- case CHAR_EXCLAMATION_MARK: /* Negative lookbehind */
- bravalue = OP_ASSERTBACK_NOT;
- cd->assert_depth += 1;
- ptr += 2;
- break;
-
- default: /* Could be name define, else bad */
- if (MAX_255(ptr[1]) && (cd->ctypes[ptr[1]] & ctype_word) != 0)
- goto DEFINE_NAME;
- ptr++; /* Correct offset for error */
- *errorcodeptr = ERR24;
- goto FAILED;
- }
- break;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_GREATER_THAN_SIGN: /* One-time brackets */
- bravalue = OP_ONCE;
- ptr++;
- break;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_C: /* Callout - may be followed by digits; */
- previous_callout = code; /* Save for later completion */
- after_manual_callout = 1; /* Skip one item before completing */
- *code++ = OP_CALLOUT;
- {
- int n = 0;
- ptr++;
- while(IS_DIGIT(*ptr))
- n = n * 10 + *ptr++ - CHAR_0;
- if (*ptr != CHAR_RIGHT_PARENTHESIS)
- {
- *errorcodeptr = ERR39;
- goto FAILED;
- }
- if (n > 255)
- {
- *errorcodeptr = ERR38;
- goto FAILED;
- }
- *code++ = n;
- PUT(code, 0, (int)(ptr - cd->start_pattern + 1)); /* Pattern offset */
- PUT(code, LINK_SIZE, 0); /* Default length */
- code += 2 * LINK_SIZE;
- }
- previous = NULL;
- continue;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_P: /* Python-style named subpattern handling */
- if (*(++ptr) == CHAR_EQUALS_SIGN ||
- *ptr == CHAR_GREATER_THAN_SIGN) /* Reference or recursion */
- {
- is_recurse = *ptr == CHAR_GREATER_THAN_SIGN;
- terminator = CHAR_RIGHT_PARENTHESIS;
- goto NAMED_REF_OR_RECURSE;
- }
- else if (*ptr != CHAR_LESS_THAN_SIGN) /* Test for Python-style defn */
- {
- *errorcodeptr = ERR41;
- goto FAILED;
- }
- /* Fall through to handle (?P< as (?< is handled */
-
-
- /* ------------------------------------------------------------ */
- DEFINE_NAME: /* Come here from (?< handling */
- case CHAR_APOSTROPHE:
- {
- terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
- CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
- name = ++ptr;
-
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
- namelen = (int)(ptr - name);
-
- /* In the pre-compile phase, just do a syntax check. */
-
- if (lengthptr != NULL)
- {
- if (*ptr != (pcre_uchar)terminator)
- {
- *errorcodeptr = ERR42;
- goto FAILED;
- }
- if (cd->names_found >= MAX_NAME_COUNT)
- {
- *errorcodeptr = ERR49;
- goto FAILED;
- }
- if (namelen + IMM2_SIZE + 1 > cd->name_entry_size)
- {
- cd->name_entry_size = namelen + IMM2_SIZE + 1;
- if (namelen > MAX_NAME_SIZE)
- {
- *errorcodeptr = ERR48;
- goto FAILED;
- }
- }
- }
-
- /* In the real compile, create the entry in the table, maintaining
- alphabetical order. Duplicate names for different numbers are
- permitted only if PCRE_DUPNAMES is set. Duplicate names for the same
- number are always OK. (An existing number can be re-used if (?|
- appears in the pattern.) In either event, a duplicate name results in
- a duplicate entry in the table, even if the number is the same. This
- is because the number of names, and hence the table size, is computed
- in the pre-compile, and it affects various numbers and pointers which
- would all have to be modified, and the compiled code moved down, if
- duplicates with the same number were omitted from the table. This
- doesn't seem worth the hassle. However, *different* names for the
- same number are not permitted. */
-
- else
- {
- BOOL dupname = FALSE;
- slot = cd->name_table;
-
- for (i = 0; i < cd->names_found; i++)
- {
- int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(namelen));
- if (crc == 0)
- {
- if (slot[IMM2_SIZE+namelen] == 0)
- {
- if (GET2(slot, 0) != cd->bracount + 1 &&
- (options & PCRE_DUPNAMES) == 0)
- {
- *errorcodeptr = ERR43;
- goto FAILED;
- }
- else dupname = TRUE;
- }
- else crc = -1; /* Current name is a substring */
- }
-
- /* Make space in the table and break the loop for an earlier
- name. For a duplicate or later name, carry on. We do this for
- duplicates so that in the simple case (when ?(| is not used) they
- are in order of their numbers. */
-
- if (crc < 0)
- {
- memmove(slot + cd->name_entry_size, slot,
- IN_UCHARS((cd->names_found - i) * cd->name_entry_size));
- break;
- }
-
- /* Continue the loop for a later or duplicate name */
-
- slot += cd->name_entry_size;
- }
-
- /* For non-duplicate names, check for a duplicate number before
- adding the new name. */
-
- if (!dupname)
- {
- pcre_uchar *cslot = cd->name_table;
- for (i = 0; i < cd->names_found; i++)
- {
- if (cslot != slot)
- {
- if (GET2(cslot, 0) == cd->bracount + 1)
- {
- *errorcodeptr = ERR65;
- goto FAILED;
- }
- }
- else i--;
- cslot += cd->name_entry_size;
- }
- }
-
- PUT2(slot, 0, cd->bracount + 1);
- memcpy(slot + IMM2_SIZE, name, IN_UCHARS(namelen));
- slot[IMM2_SIZE + namelen] = 0;
- }
- }
-
- /* In both pre-compile and compile, count the number of names we've
- encountered. */
-
- cd->names_found++;
- ptr++; /* Move past > or ' */
- goto NUMBERED_GROUP;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_AMPERSAND: /* Perl recursion/subroutine syntax */
- terminator = CHAR_RIGHT_PARENTHESIS;
- is_recurse = TRUE;
- /* Fall through */
-
- /* We come here from the Python syntax above that handles both
- references (?P=name) and recursion (?P>name), as well as falling
- through from the Perl recursion syntax (?&name). We also come here from
- the Perl \k<name> or \k'name' back reference syntax and the \k{name}
- .NET syntax, and the Oniguruma \g<...> and \g'...' subroutine syntax. */
-
- NAMED_REF_OR_RECURSE:
- name = ++ptr;
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
- namelen = (int)(ptr - name);
-
- /* In the pre-compile phase, do a syntax check. We used to just set
- a dummy reference number, because it was not used in the first pass.
- However, with the change of recursive back references to be atomic,
- we have to look for the number so that this state can be identified, as
- otherwise the incorrect length is computed. If it's not a backwards
- reference, the dummy number will do. */
-
- if (lengthptr != NULL)
- {
- const pcre_uchar *temp;
-
- if (namelen == 0)
- {
- *errorcodeptr = ERR62;
- goto FAILED;
- }
- if (*ptr != (pcre_uchar)terminator)
- {
- *errorcodeptr = ERR42;
- goto FAILED;
- }
- if (namelen > MAX_NAME_SIZE)
- {
- *errorcodeptr = ERR48;
- goto FAILED;
- }
-
- /* The name table does not exist in the first pass, so we cannot
- do a simple search as in the code below. Instead, we have to scan the
- pattern to find the number. It is important that we scan it only as
- far as we have got because the syntax of named subpatterns has not
- been checked for the rest of the pattern, and find_parens() assumes
- correct syntax. In any case, it's a waste of resources to scan
- further. We stop the scan at the current point by temporarily
- adjusting the value of cd->endpattern. */
-
- temp = cd->end_pattern;
- cd->end_pattern = ptr;
- recno = find_parens(cd, name, namelen,
- (options & PCRE_EXTENDED) != 0, utf);
- cd->end_pattern = temp;
- if (recno < 0) recno = 0; /* Forward ref; set dummy number */
- }
-
- /* In the real compile, seek the name in the table. We check the name
- first, and then check that we have reached the end of the name in the
- table. That way, if the name that is longer than any in the table,
- the comparison will fail without reading beyond the table entry. */
-
- else
- {
- slot = cd->name_table;
- for (i = 0; i < cd->names_found; i++)
- {
- if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0 &&
- slot[IMM2_SIZE+namelen] == 0)
- break;
- slot += cd->name_entry_size;
- }
-
- if (i < cd->names_found) /* Back reference */
- {
- recno = GET2(slot, 0);
- }
- else if ((recno = /* Forward back reference */
- find_parens(cd, name, namelen,
- (options & PCRE_EXTENDED) != 0, utf)) <= 0)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
- }
-
- /* In both phases, we can now go to the code than handles numerical
- recursion or backreferences. */
-
- if (is_recurse) goto HANDLE_RECURSION;
- else goto HANDLE_REFERENCE;
-
-
- /* ------------------------------------------------------------ */
- case CHAR_R: /* Recursion */
- ptr++; /* Same as (?0) */
- /* Fall through */
-
-
- /* ------------------------------------------------------------ */
- case CHAR_MINUS: case CHAR_PLUS: /* Recursion or subroutine */
- case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4:
- case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
- {
- const pcre_uchar *called;
- terminator = CHAR_RIGHT_PARENTHESIS;
-
- /* Come here from the \g<...> and \g'...' code (Oniguruma
- compatibility). However, the syntax has been checked to ensure that
- the ... are a (signed) number, so that neither ERR63 nor ERR29 will
- be called on this path, nor with the jump to OTHER_CHAR_AFTER_QUERY
- ever be taken. */
-
- HANDLE_NUMERICAL_RECURSION:
-
- if ((refsign = *ptr) == CHAR_PLUS)
- {
- ptr++;
- if (!IS_DIGIT(*ptr))
- {
- *errorcodeptr = ERR63;
- goto FAILED;
- }
- }
- else if (refsign == CHAR_MINUS)
- {
- if (!IS_DIGIT(ptr[1]))
- goto OTHER_CHAR_AFTER_QUERY;
- ptr++;
- }
-
- recno = 0;
- while(IS_DIGIT(*ptr))
- recno = recno * 10 + *ptr++ - CHAR_0;
-
- if (*ptr != (pcre_uchar)terminator)
- {
- *errorcodeptr = ERR29;
- goto FAILED;
- }
-
- if (refsign == CHAR_MINUS)
- {
- if (recno == 0)
- {
- *errorcodeptr = ERR58;
- goto FAILED;
- }
- recno = cd->bracount - recno + 1;
- if (recno <= 0)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
- }
- else if (refsign == CHAR_PLUS)
- {
- if (recno == 0)
- {
- *errorcodeptr = ERR58;
- goto FAILED;
- }
- recno += cd->bracount;
- }
-
- /* Come here from code above that handles a named recursion */
-
- HANDLE_RECURSION:
-
- previous = code;
- called = cd->start_code;
-
- /* When we are actually compiling, find the bracket that is being
- referenced. Temporarily end the regex in case it doesn't exist before
- this point. If we end up with a forward reference, first check that
- the bracket does occur later so we can give the error (and position)
- now. Then remember this forward reference in the workspace so it can
- be filled in at the end. */
-
- if (lengthptr == NULL)
- {
- *code = OP_END;
- if (recno != 0)
- called = PRIV(find_bracket)(cd->start_code, utf, recno);
-
- /* Forward reference */
-
- if (called == NULL)
- {
- if (find_parens(cd, NULL, recno,
- (options & PCRE_EXTENDED) != 0, utf) < 0)
- {
- *errorcodeptr = ERR15;
- goto FAILED;
- }
-
- /* Fudge the value of "called" so that when it is inserted as an
- offset below, what it actually inserted is the reference number
- of the group. Then remember the forward reference. */
-
- called = cd->start_code + recno;
- if (cd->hwm >= cd->start_workspace + cd->workspace_size -
- WORK_SIZE_SAFETY_MARGIN)
- {
- *errorcodeptr = expand_workspace(cd);
- if (*errorcodeptr != 0) goto FAILED;
- }
- PUTINC(cd->hwm, 0, (int)(code + 1 - cd->start_code));
- }
-
- /* If not a forward reference, and the subpattern is still open,
- this is a recursive call. We check to see if this is a left
- recursion that could loop for ever, and diagnose that case. We
- must not, however, do this check if we are in a conditional
- subpattern because the condition might be testing for recursion in
- a pattern such as /(?(R)a+|(?R)b)/, which is perfectly valid.
- Forever loops are also detected at runtime, so those that occur in
- conditional subpatterns will be picked up then. */
-
- else if (GET(called, 1) == 0 && cond_depth <= 0 &&
- could_be_empty(called, code, bcptr, utf, cd))
- {
- *errorcodeptr = ERR40;
- goto FAILED;
- }
- }
-
- /* Insert the recursion/subroutine item. It does not have a set first
- character (relevant if it is repeated, because it will then be
- wrapped with ONCE brackets). */
-
- *code = OP_RECURSE;
- PUT(code, 1, (int)(called - cd->start_code));
- code += 1 + LINK_SIZE;
- groupsetfirstchar = FALSE;
- }
-
- /* Can't determine a first byte now */
-
- if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
- continue;
-
-
- /* ------------------------------------------------------------ */
- default: /* Other characters: check option setting */
- OTHER_CHAR_AFTER_QUERY:
- set = unset = 0;
- optset = &set;
-
- while (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON)
- {
- switch (*ptr++)
- {
- case CHAR_MINUS: optset = &unset; break;
-
- case CHAR_J: /* Record that it changed in the external options */
- *optset |= PCRE_DUPNAMES;
- cd->external_flags |= PCRE_JCHANGED;
- break;
-
- case CHAR_i: *optset |= PCRE_CASELESS; break;
- case CHAR_m: *optset |= PCRE_MULTILINE; break;
- case CHAR_s: *optset |= PCRE_DOTALL; break;
- case CHAR_x: *optset |= PCRE_EXTENDED; break;
- case CHAR_U: *optset |= PCRE_UNGREEDY; break;
- case CHAR_X: *optset |= PCRE_EXTRA; break;
-
- default: *errorcodeptr = ERR12;
- ptr--; /* Correct the offset */
- goto FAILED;
- }
- }
-
- /* Set up the changed option bits, but don't change anything yet. */
-
- newoptions = (options | set) & (~unset);
-
- /* If the options ended with ')' this is not the start of a nested
- group with option changes, so the options change at this level. If this
- item is right at the start of the pattern, the options can be
- abstracted and made external in the pre-compile phase, and ignored in
- the compile phase. This can be helpful when matching -- for instance in
- caseless checking of required bytes.
-
- If the code pointer is not (cd->start_code + 1 + LINK_SIZE), we are
- definitely *not* at the start of the pattern because something has been
- compiled. In the pre-compile phase, however, the code pointer can have
- that value after the start, because it gets reset as code is discarded
- during the pre-compile. However, this can happen only at top level - if
- we are within parentheses, the starting BRA will still be present. At
- any parenthesis level, the length value can be used to test if anything
- has been compiled at that level. Thus, a test for both these conditions
- is necessary to ensure we correctly detect the start of the pattern in
- both phases.
-
- If we are not at the pattern start, reset the greedy defaults and the
- case value for firstchar and reqchar. */
-
- if (*ptr == CHAR_RIGHT_PARENTHESIS)
- {
- if (code == cd->start_code + 1 + LINK_SIZE &&
- (lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE))
- {
- cd->external_options = newoptions;
- }
- else
- {
- greedy_default = ((newoptions & PCRE_UNGREEDY) != 0);
- greedy_non_default = greedy_default ^ 1;
- req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS:0;
- }
-
- /* Change options at this level, and pass them back for use
- in subsequent branches. */
-
- *optionsptr = options = newoptions;
- previous = NULL; /* This item can't be repeated */
- continue; /* It is complete */
- }
-
- /* If the options ended with ':' we are heading into a nested group
- with possible change of options. Such groups are non-capturing and are
- not assertions of any kind. All we need to do is skip over the ':';
- the newoptions value is handled below. */
-
- bravalue = OP_BRA;
- ptr++;
- } /* End of switch for character following (? */
- } /* End of (? handling */
-
- /* Opening parenthesis not followed by '*' or '?'. If PCRE_NO_AUTO_CAPTURE
- is set, all unadorned brackets become non-capturing and behave like (?:...)
- brackets. */
-
- else if ((options & PCRE_NO_AUTO_CAPTURE) != 0)
- {
- bravalue = OP_BRA;
- }
-
- /* Else we have a capturing group. */
-
- else
- {
- NUMBERED_GROUP:
- cd->bracount += 1;
- PUT2(code, 1+LINK_SIZE, cd->bracount);
- skipbytes = IMM2_SIZE;
- }
-
- /* Process nested bracketed regex. Assertions used not to be repeatable,
- but this was changed for Perl compatibility, so all kinds can now be
- repeated. We copy code into a non-register variable (tempcode) in order to
- be able to pass its address because some compilers complain otherwise. */
-
- previous = code; /* For handling repetition */
- *code = bravalue;
- tempcode = code;
- tempreqvary = cd->req_varyopt; /* Save value before bracket */
- tempbracount = cd->bracount; /* Save value before bracket */
- length_prevgroup = 0; /* Initialize for pre-compile phase */
-
- if (!compile_regex(
- newoptions, /* The complete new option state */
- &tempcode, /* Where to put code (updated) */
- &ptr, /* Input pointer (updated) */
- errorcodeptr, /* Where to put an error message */
- (bravalue == OP_ASSERTBACK ||
- bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */
- reset_bracount, /* True if (?| group */
- skipbytes, /* Skip over bracket number */
- cond_depth +
- ((bravalue == OP_COND)?1:0), /* Depth of condition subpatterns */
- &subfirstchar, /* For possible first char */
- &subfirstcharflags,
- &subreqchar, /* For possible last char */
- &subreqcharflags,
- bcptr, /* Current branch chain */
- cd, /* Tables block */
- (lengthptr == NULL)? NULL : /* Actual compile phase */
- &length_prevgroup /* Pre-compile phase */
- ))
- goto FAILED;
-
- /* If this was an atomic group and there are no capturing groups within it,
- generate OP_ONCE_NC instead of OP_ONCE. */
-
- if (bravalue == OP_ONCE && cd->bracount <= tempbracount)
- *code = OP_ONCE_NC;
-
- if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT)
- cd->assert_depth -= 1;
-
- /* At the end of compiling, code is still pointing to the start of the
- group, while tempcode has been updated to point past the end of the group.
- The pattern pointer (ptr) is on the bracket.
-
- If this is a conditional bracket, check that there are no more than
- two branches in the group, or just one if it's a DEFINE group. We do this
- in the real compile phase, not in the pre-pass, where the whole group may
- not be available. */
-
- if (bravalue == OP_COND && lengthptr == NULL)
- {
- pcre_uchar *tc = code;
- int condcount = 0;
-
- do {
- condcount++;
- tc += GET(tc,1);
- }
- while (*tc != OP_KET);
-
- /* A DEFINE group is never obeyed inline (the "condition" is always
- false). It must have only one branch. */
-
- if (code[LINK_SIZE+1] == OP_DEF)
- {
- if (condcount > 1)
- {
- *errorcodeptr = ERR54;
- goto FAILED;
- }
- bravalue = OP_DEF; /* Just a flag to suppress char handling below */
- }
-
- /* A "normal" conditional group. If there is just one branch, we must not
- make use of its firstchar or reqchar, because this is equivalent to an
- empty second branch. */
-
- else
- {
- if (condcount > 2)
- {
- *errorcodeptr = ERR27;
- goto FAILED;
- }
- if (condcount == 1) subfirstcharflags = subreqcharflags = REQ_NONE;
- }
- }
-
- /* Error if hit end of pattern */
-
- if (*ptr != CHAR_RIGHT_PARENTHESIS)
- {
- *errorcodeptr = ERR14;
- goto FAILED;
- }
-
- /* In the pre-compile phase, update the length by the length of the group,
- less the brackets at either end. Then reduce the compiled code to just a
- set of non-capturing brackets so that it doesn't use much memory if it is
- duplicated by a quantifier.*/
-
- if (lengthptr != NULL)
- {
- if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
- {
- *errorcodeptr = ERR20;
- goto FAILED;
- }
- *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
- code++; /* This already contains bravalue */
- PUTINC(code, 0, 1 + LINK_SIZE);
- *code++ = OP_KET;
- PUTINC(code, 0, 1 + LINK_SIZE);
- break; /* No need to waste time with special character handling */
- }
-
- /* Otherwise update the main code pointer to the end of the group. */
-
- code = tempcode;
-
- /* For a DEFINE group, required and first character settings are not
- relevant. */
-
- if (bravalue == OP_DEF) break;
-
- /* Handle updating of the required and first characters for other types of
- group. Update for normal brackets of all kinds, and conditions with two
- branches (see code above). If the bracket is followed by a quantifier with
- zero repeat, we have to back off. Hence the definition of zeroreqchar and
- zerofirstchar outside the main loop so that they can be accessed for the
- back off. */
-
- zeroreqchar = reqchar;
- zeroreqcharflags = reqcharflags;
- zerofirstchar = firstchar;
- zerofirstcharflags = firstcharflags;
- groupsetfirstchar = FALSE;
-
- if (bravalue >= OP_ONCE)
- {
- /* If we have not yet set a firstchar in this branch, take it from the
- subpattern, remembering that it was set here so that a repeat of more
- than one can replicate it as reqchar if necessary. If the subpattern has
- no firstchar, set "none" for the whole branch. In both cases, a zero
- repeat forces firstchar to "none". */
-
- if (firstcharflags == REQ_UNSET)
- {
- if (subfirstcharflags >= 0)
- {
- firstchar = subfirstchar;
- firstcharflags = subfirstcharflags;
- groupsetfirstchar = TRUE;
- }
- else firstcharflags = REQ_NONE;
- zerofirstcharflags = REQ_NONE;
- }
-
- /* If firstchar was previously set, convert the subpattern's firstchar
- into reqchar if there wasn't one, using the vary flag that was in
- existence beforehand. */
-
- else if (subfirstcharflags >= 0 && subreqcharflags < 0)
- {
- subreqchar = subfirstchar;
- subreqcharflags = subfirstcharflags | tempreqvary;
- }
-
- /* If the subpattern set a required byte (or set a first byte that isn't
- really the first byte - see above), set it. */
-
- if (subreqcharflags >= 0)
- {
- reqchar = subreqchar;
- reqcharflags = subreqcharflags;
- }
- }
-
- /* For a forward assertion, we take the reqchar, if set. This can be
- helpful if the pattern that follows the assertion doesn't set a different
- char. For example, it's useful for /(?=abcde).+/. We can't set firstchar
- for an assertion, however because it leads to incorrect effect for patterns
- such as /(?=a)a.+/ when the "real" "a" would then become a reqchar instead
- of a firstchar. This is overcome by a scan at the end if there's no
- firstchar, looking for an asserted first char. */
-
- else if (bravalue == OP_ASSERT && subreqcharflags >= 0)
- {
- reqchar = subreqchar;
- reqcharflags = subreqcharflags;
- }
- break; /* End of processing '(' */
-
-
- /* ===================================================================*/
- /* Handle metasequences introduced by \. For ones like \d, the ESC_ values
- are arranged to be the negation of the corresponding OP_values in the
- default case when PCRE_UCP is not set. For the back references, the values
- are negative the reference number. Only back references and those types
- that consume a character may be repeated. We can test for values between
- ESC_b and ESC_Z for the latter; this may have to change if any new ones are
- ever created. */
-
- case CHAR_BACKSLASH:
- tempptr = ptr;
- escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options, FALSE);
- if (*errorcodeptr != 0) goto FAILED;
-
- if (escape == 0) /* The escape coded a single character */
- c = ec;
- else
- {
- if (escape == ESC_Q) /* Handle start of quoted string */
- {
- if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
- ptr += 2; /* avoid empty string */
- else inescq = TRUE;
- continue;
- }
-
- if (escape == ESC_E) continue; /* Perl ignores an orphan \E */
-
- /* For metasequences that actually match a character, we disable the
- setting of a first character if it hasn't already been set. */
-
- if (firstcharflags == REQ_UNSET && escape > ESC_b && escape < ESC_Z)
- firstcharflags = REQ_NONE;
-
- /* Set values to reset to if this is followed by a zero repeat. */
-
- zerofirstchar = firstchar;
- zerofirstcharflags = firstcharflags;
- zeroreqchar = reqchar;
- zeroreqcharflags = reqcharflags;
-
- /* \g<name> or \g'name' is a subroutine call by name and \g<n> or \g'n'
- is a subroutine call by number (Oniguruma syntax). In fact, the value
- ESC_g is returned only for these cases. So we don't need to check for <
- or ' if the value is ESC_g. For the Perl syntax \g{n} the value is
- -n, and for the Perl syntax \g{name} the result is ESC_k (as
- that is a synonym for a named back reference). */
-
- if (escape == ESC_g)
- {
- const pcre_uchar *p;
- save_hwm = cd->hwm; /* Normally this is set when '(' is read */
- terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
- CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
-
- /* These two statements stop the compiler for warning about possibly
- unset variables caused by the jump to HANDLE_NUMERICAL_RECURSION. In
- fact, because we actually check for a number below, the paths that
- would actually be in error are never taken. */
-
- skipbytes = 0;
- reset_bracount = FALSE;
-
- /* Test for a name */
-
- if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS)
- {
- BOOL is_a_number = TRUE;
- for (p = ptr + 1; *p != CHAR_NULL && *p != (pcre_uchar)terminator; p++)
- {
- if (!MAX_255(*p)) { is_a_number = FALSE; break; }
- if ((cd->ctypes[*p] & ctype_digit) == 0) is_a_number = FALSE;
- if ((cd->ctypes[*p] & ctype_word) == 0) break;
- }
- if (*p != (pcre_uchar)terminator)
- {
- *errorcodeptr = ERR57;
- break;
- }
- if (is_a_number)
- {
- ptr++;
- goto HANDLE_NUMERICAL_RECURSION;
- }
- is_recurse = TRUE;
- goto NAMED_REF_OR_RECURSE;
- }
-
- /* Test a signed number in angle brackets or quotes. */
-
- p = ptr + 2;
- while (IS_DIGIT(*p)) p++;
- if (*p != (pcre_uchar)terminator)
- {
- *errorcodeptr = ERR57;
- break;
- }
- ptr++;
- goto HANDLE_NUMERICAL_RECURSION;
- }
-
- /* \k<name> or \k'name' is a back reference by name (Perl syntax).
- We also support \k{name} (.NET syntax). */
-
- if (escape == ESC_k)
- {
- if ((ptr[1] != CHAR_LESS_THAN_SIGN &&
- ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET))
- {
- *errorcodeptr = ERR69;
- break;
- }
- is_recurse = FALSE;
- terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
- CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)?
- CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET;
- goto NAMED_REF_OR_RECURSE;
- }
-
- /* Back references are handled specially; must disable firstchar if
- not set to cope with cases like (?=(\w+))\1: which would otherwise set
- ':' later. */
-
- if (escape < 0)
- {
- open_capitem *oc;
- recno = -escape;
-
- HANDLE_REFERENCE: /* Come here from named backref handling */
- if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
- previous = code;
- *code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
- PUT2INC(code, 0, recno);
- cd->backref_map |= (recno < 32)? (1 << recno) : 1;
- if (recno > cd->top_backref) cd->top_backref = recno;
-
- /* Check to see if this back reference is recursive, that it, it
- is inside the group that it references. A flag is set so that the
- group can be made atomic. */
-
- for (oc = cd->open_caps; oc != NULL; oc = oc->next)
- {
- if (oc->number == recno)
- {
- oc->flag = TRUE;
- break;
- }
- }
- }
-
- /* So are Unicode property matches, if supported. */
-
-#ifdef SUPPORT_UCP
- else if (escape == ESC_P || escape == ESC_p)
- {
- BOOL negated;
- unsigned int ptype = 0, pdata = 0;
- if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr))
- goto FAILED;
- previous = code;
- *code++ = ((escape == ESC_p) != negated)? OP_PROP : OP_NOTPROP;
- *code++ = ptype;
- *code++ = pdata;
- }
-#else
-
- /* If Unicode properties are not supported, \X, \P, and \p are not
- allowed. */
-
- else if (escape == ESC_X || escape == ESC_P || escape == ESC_p)
- {
- *errorcodeptr = ERR45;
- goto FAILED;
- }
-#endif
-
- /* For the rest (including \X when Unicode properties are supported), we
- can obtain the OP value by negating the escape value in the default
- situation when PCRE_UCP is not set. When it *is* set, we substitute
- Unicode property tests. Note that \b and \B do a one-character
- lookbehind, and \A also behaves as if it does. */
-
- else
- {
- if ((escape == ESC_b || escape == ESC_B || escape == ESC_A) &&
- cd->max_lookbehind == 0)
- cd->max_lookbehind = 1;
-#ifdef SUPPORT_UCP
- if (escape >= ESC_DU && escape <= ESC_wu)
- {
- nestptr = ptr + 1; /* Where to resume */
- ptr = substitutes[escape - ESC_DU] - 1; /* Just before substitute */
- }
- else
-#endif
- /* In non-UTF-8 mode, we turn \C into OP_ALLANY instead of OP_ANYBYTE
- so that it works in DFA mode and in lookbehinds. */
-
- {
- previous = (escape > ESC_b && escape < ESC_Z)? code : NULL;
- *code++ = (!utf && escape == ESC_C)? OP_ALLANY : escape;
- }
- }
- continue;
- }
-
- /* We have a data character whose value is in c. In UTF-8 mode it may have
- a value > 127. We set its representation in the length/buffer, and then
- handle it as a data character. */
-
-#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
- if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR)
- mclength = PRIV(ord2utf)(c, mcbuffer);
- else
-#endif
-
- {
- mcbuffer[0] = c;
- mclength = 1;
- }
- goto ONE_CHAR;
-
-
- /* ===================================================================*/
- /* Handle a literal character. It is guaranteed not to be whitespace or #
- when the extended flag is set. If we are in UTF-8 mode, it may be a
- multi-byte literal character. */
-
- default:
- NORMAL_CHAR:
- mclength = 1;
- mcbuffer[0] = c;
-
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(c))
- ACROSSCHAR(TRUE, ptr[1], mcbuffer[mclength++] = *(++ptr));
-#endif
-
- /* At this point we have the character's bytes in mcbuffer, and the length
- in mclength. When not in UTF-8 mode, the length is always 1. */
-
- ONE_CHAR:
- previous = code;
-
- /* For caseless UTF-8 mode when UCP support is available, check whether
- this character has more than one other case. If so, generate a special
- OP_PROP item instead of OP_CHARI. */
-
-#ifdef SUPPORT_UCP
- if (utf && (options & PCRE_CASELESS) != 0)
- {
- GETCHAR(c, mcbuffer);
- if ((c = UCD_CASESET(c)) != 0)
- {
- *code++ = OP_PROP;
- *code++ = PT_CLIST;
- *code++ = c;
- if (firstcharflags == REQ_UNSET) firstcharflags = zerofirstcharflags = REQ_NONE;
- break;
- }
- }
-#endif
-
- /* Caseful matches, or not one of the multicase characters. */
-
- *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARI : OP_CHAR;
- for (c = 0; c < mclength; c++) *code++ = mcbuffer[c];
-
- /* Remember if \r or \n were seen */
-
- if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL)
- cd->external_flags |= PCRE_HASCRORLF;
-
- /* Set the first and required bytes appropriately. If no previous first
- byte, set it from this character, but revert to none on a zero repeat.
- Otherwise, leave the firstchar value alone, and don't change it on a zero
- repeat. */
-
- if (firstcharflags == REQ_UNSET)
- {
- zerofirstcharflags = REQ_NONE;
- zeroreqchar = reqchar;
- zeroreqcharflags = reqcharflags;
-
- /* If the character is more than one byte long, we can set firstchar
- only if it is not to be matched caselessly. */
-
- if (mclength == 1 || req_caseopt == 0)
- {
- firstchar = mcbuffer[0] | req_caseopt;
- firstchar = mcbuffer[0];
- firstcharflags = req_caseopt;
-
- if (mclength != 1)
- {
- reqchar = code[-1];
- reqcharflags = cd->req_varyopt;
- }
- }
- else firstcharflags = reqcharflags = REQ_NONE;
- }
-
- /* firstchar was previously set; we can set reqchar only if the length is
- 1 or the matching is caseful. */
-
- else
- {
- zerofirstchar = firstchar;
- zerofirstcharflags = firstcharflags;
- zeroreqchar = reqchar;
- zeroreqcharflags = reqcharflags;
- if (mclength == 1 || req_caseopt == 0)
- {
- reqchar = code[-1];
- reqcharflags = req_caseopt | cd->req_varyopt;
- }
- }
-
- break; /* End of literal character handling */
- }
- } /* end of big loop */
-
-
-/* Control never reaches here by falling through, only by a goto for all the
-error states. Pass back the position in the pattern so that it can be displayed
-to the user for diagnosing the error. */
-
-FAILED:
-*ptrptr = ptr;
-return FALSE;
-}
-
-
-
-/*************************************************
-* Compile sequence of alternatives *
-*************************************************/
-
-/* On entry, ptr is pointing past the bracket character, but on return it
-points to the closing bracket, or vertical bar, or end of string. The code
-variable is pointing at the byte into which the BRA operator has been stored.
-This function is used during the pre-compile phase when we are trying to find
-out the amount of memory needed, as well as during the real compile phase. The
-value of lengthptr distinguishes the two phases.
-
-Arguments:
- options option bits, including any changes for this subpattern
- codeptr -> the address of the current code pointer
- ptrptr -> the address of the current pattern pointer
- errorcodeptr -> pointer to error code variable
- lookbehind TRUE if this is a lookbehind assertion
- reset_bracount TRUE to reset the count for each branch
- skipbytes skip this many bytes at start (for brackets and OP_COND)
- cond_depth depth of nesting for conditional subpatterns
- firstcharptr place to put the first required character
- firstcharflagsptr place to put the first character flags, or a negative number
- reqcharptr place to put the last required character
- reqcharflagsptr place to put the last required character flags, or a negative number
- bcptr pointer to the chain of currently open branches
- cd points to the data block with tables pointers etc.
- lengthptr NULL during the real compile phase
- points to length accumulator during pre-compile phase
-
-Returns: TRUE on success
-*/
-
-static BOOL
-compile_regex(int options, pcre_uchar **codeptr, const pcre_uchar **ptrptr,
- int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes,
- int cond_depth,
- pcre_uint32 *firstcharptr, pcre_int32 *firstcharflagsptr,
- pcre_uint32 *reqcharptr, pcre_int32 *reqcharflagsptr,
- branch_chain *bcptr, compile_data *cd, int *lengthptr)
-{
-const pcre_uchar *ptr = *ptrptr;
-pcre_uchar *code = *codeptr;
-pcre_uchar *last_branch = code;
-pcre_uchar *start_bracket = code;
-pcre_uchar *reverse_count = NULL;
-open_capitem capitem;
-int capnumber = 0;
-pcre_uint32 firstchar, reqchar;
-pcre_int32 firstcharflags, reqcharflags;
-pcre_uint32 branchfirstchar, branchreqchar;
-pcre_int32 branchfirstcharflags, branchreqcharflags;
-int length;
-unsigned int orig_bracount;
-unsigned int max_bracount;
-branch_chain bc;
-
-bc.outer = bcptr;
-bc.current_branch = code;
-
-firstchar = reqchar = 0;
-firstcharflags = reqcharflags = REQ_UNSET;
-
-/* Accumulate the length for use in the pre-compile phase. Start with the
-length of the BRA and KET and any extra bytes that are required at the
-beginning. We accumulate in a local variable to save frequent testing of
-lenthptr for NULL. We cannot do this by looking at the value of code at the
-start and end of each alternative, because compiled items are discarded during
-the pre-compile phase so that the work space is not exceeded. */
-
-length = 2 + 2*LINK_SIZE + skipbytes;
-
-/* WARNING: If the above line is changed for any reason, you must also change
-the code that abstracts option settings at the start of the pattern and makes
-them global. It tests the value of length for (2 + 2*LINK_SIZE) in the
-pre-compile phase to find out whether anything has yet been compiled or not. */
-
-/* If this is a capturing subpattern, add to the chain of open capturing items
-so that we can detect them if (*ACCEPT) is encountered. This is also used to
-detect groups that contain recursive back references to themselves. Note that
-only OP_CBRA need be tested here; changing this opcode to one of its variants,
-e.g. OP_SCBRAPOS, happens later, after the group has been compiled. */
-
-if (*code == OP_CBRA)
- {
- capnumber = GET2(code, 1 + LINK_SIZE);
- capitem.number = capnumber;
- capitem.next = cd->open_caps;
- capitem.flag = FALSE;
- cd->open_caps = &capitem;
- }
-
-/* Offset is set zero to mark that this bracket is still open */
-
-PUT(code, 1, 0);
-code += 1 + LINK_SIZE + skipbytes;
-
-/* Loop for each alternative branch */
-
-orig_bracount = max_bracount = cd->bracount;
-for (;;)
- {
- /* For a (?| group, reset the capturing bracket count so that each branch
- uses the same numbers. */
-
- if (reset_bracount) cd->bracount = orig_bracount;
-
- /* Set up dummy OP_REVERSE if lookbehind assertion */
-
- if (lookbehind)
- {
- *code++ = OP_REVERSE;
- reverse_count = code;
- PUTINC(code, 0, 0);
- length += 1 + LINK_SIZE;
- }
-
- /* Now compile the branch; in the pre-compile phase its length gets added
- into the length. */
-
- if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstchar,
- &branchfirstcharflags, &branchreqchar, &branchreqcharflags, &bc,
- cond_depth, cd, (lengthptr == NULL)? NULL : &length))
- {
- *ptrptr = ptr;
- return FALSE;
- }
-
- /* Keep the highest bracket count in case (?| was used and some branch
- has fewer than the rest. */
-
- if (cd->bracount > max_bracount) max_bracount = cd->bracount;
-
- /* In the real compile phase, there is some post-processing to be done. */
-
- if (lengthptr == NULL)
- {
- /* If this is the first branch, the firstchar and reqchar values for the
- branch become the values for the regex. */
-
- if (*last_branch != OP_ALT)
- {
- firstchar = branchfirstchar;
- firstcharflags = branchfirstcharflags;
- reqchar = branchreqchar;
- reqcharflags = branchreqcharflags;
- }
-
- /* If this is not the first branch, the first char and reqchar have to
- match the values from all the previous branches, except that if the
- previous value for reqchar didn't have REQ_VARY set, it can still match,
- and we set REQ_VARY for the regex. */
-
- else
- {
- /* If we previously had a firstchar, but it doesn't match the new branch,
- we have to abandon the firstchar for the regex, but if there was
- previously no reqchar, it takes on the value of the old firstchar. */
-
- if (firstcharflags >= 0 &&
- (firstcharflags != branchfirstcharflags || firstchar != branchfirstchar))
- {
- if (reqcharflags < 0)
- {
- reqchar = firstchar;
- reqcharflags = firstcharflags;
- }
- firstcharflags = REQ_NONE;
- }
-
- /* If we (now or from before) have no firstchar, a firstchar from the
- branch becomes a reqchar if there isn't a branch reqchar. */
-
- if (firstcharflags < 0 && branchfirstcharflags >= 0 && branchreqcharflags < 0)
- {
- branchreqchar = branchfirstchar;
- branchreqcharflags = branchfirstcharflags;
- }
-
- /* Now ensure that the reqchars match */
-
- if (((reqcharflags & ~REQ_VARY) != (branchreqcharflags & ~REQ_VARY)) ||
- reqchar != branchreqchar)
- reqcharflags = REQ_NONE;
- else
- {
- reqchar = branchreqchar;
- reqcharflags |= branchreqcharflags; /* To "or" REQ_VARY */
- }
- }
-
- /* If lookbehind, check that this branch matches a fixed-length string, and
- put the length into the OP_REVERSE item. Temporarily mark the end of the
- branch with OP_END. If the branch contains OP_RECURSE, the result is -3
- because there may be forward references that we can't check here. Set a
- flag to cause another lookbehind check at the end. Why not do it all at the
- end? Because common, erroneous checks are picked up here and the offset of
- the problem can be shown. */
-
- if (lookbehind)
- {
- int fixed_length;
- *code = OP_END;
- fixed_length = find_fixedlength(last_branch, (options & PCRE_UTF8) != 0,
- FALSE, cd);
- DPRINTF(("fixed length = %d\n", fixed_length));
- if (fixed_length == -3)
- {
- cd->check_lookbehind = TRUE;
- }
- else if (fixed_length < 0)
- {
- *errorcodeptr = (fixed_length == -2)? ERR36 :
- (fixed_length == -4)? ERR70: ERR25;
- *ptrptr = ptr;
- return FALSE;
- }
- else
- {
- if (fixed_length > cd->max_lookbehind)
- cd->max_lookbehind = fixed_length;
- PUT(reverse_count, 0, fixed_length);
- }
- }
- }
-
- /* Reached end of expression, either ')' or end of pattern. In the real
- compile phase, go back through the alternative branches and reverse the chain
- of offsets, with the field in the BRA item now becoming an offset to the
- first alternative. If there are no alternatives, it points to the end of the
- group. The length in the terminating ket is always the length of the whole
- bracketed item. Return leaving the pointer at the terminating char. */
-
- if (*ptr != CHAR_VERTICAL_LINE)
- {
- if (lengthptr == NULL)
- {
- int branch_length = (int)(code - last_branch);
- do
- {
- int prev_length = GET(last_branch, 1);
- PUT(last_branch, 1, branch_length);
- branch_length = prev_length;
- last_branch -= branch_length;
- }
- while (branch_length > 0);
- }
-
- /* Fill in the ket */
-
- *code = OP_KET;
- PUT(code, 1, (int)(code - start_bracket));
- code += 1 + LINK_SIZE;
-
- /* If it was a capturing subpattern, check to see if it contained any
- recursive back references. If so, we must wrap it in atomic brackets.
- In any event, remove the block from the chain. */
-
- if (capnumber > 0)
- {
- if (cd->open_caps->flag)
- {
- memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
- IN_UCHARS(code - start_bracket));
- *start_bracket = OP_ONCE;
- code += 1 + LINK_SIZE;
- PUT(start_bracket, 1, (int)(code - start_bracket));
- *code = OP_KET;
- PUT(code, 1, (int)(code - start_bracket));
- code += 1 + LINK_SIZE;
- length += 2 + 2*LINK_SIZE;
- }
- cd->open_caps = cd->open_caps->next;
- }
-
- /* Retain the highest bracket number, in case resetting was used. */
-
- cd->bracount = max_bracount;
-
- /* Set values to pass back */
-
- *codeptr = code;
- *ptrptr = ptr;
- *firstcharptr = firstchar;
- *firstcharflagsptr = firstcharflags;
- *reqcharptr = reqchar;
- *reqcharflagsptr = reqcharflags;
- if (lengthptr != NULL)
- {
- if (OFLOW_MAX - *lengthptr < length)
- {
- *errorcodeptr = ERR20;
- return FALSE;
- }
- *lengthptr += length;
- }
- return TRUE;
- }
-
- /* Another branch follows. In the pre-compile phase, we can move the code
- pointer back to where it was for the start of the first branch. (That is,
- pretend that each branch is the only one.)
-
- In the real compile phase, insert an ALT node. Its length field points back
- to the previous branch while the bracket remains open. At the end the chain
- is reversed. It's done like this so that the start of the bracket has a
- zero offset until it is closed, making it possible to detect recursion. */
-
- if (lengthptr != NULL)
- {
- code = *codeptr + 1 + LINK_SIZE + skipbytes;
- length += 1 + LINK_SIZE;
- }
- else
- {
- *code = OP_ALT;
- PUT(code, 1, (int)(code - last_branch));
- bc.current_branch = last_branch = code;
- code += 1 + LINK_SIZE;
- }
-
- ptr++;
- }
-/* Control never reaches here */
-}
-
-
-
-
-/*************************************************
-* Check for anchored expression *
-*************************************************/
-
-/* Try to find out if this is an anchored regular expression. Consider each
-alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket
-all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then
-it's anchored. However, if this is a multiline pattern, then only OP_SOD will
-be found, because ^ generates OP_CIRCM in that mode.
-
-We can also consider a regex to be anchored if OP_SOM starts all its branches.
-This is the code for \G, which means "match at start of match position, taking
-into account the match offset".
-
-A branch is also implicitly anchored if it starts with .* and DOTALL is set,
-because that will try the rest of the pattern at all possible matching points,
-so there is no point trying again.... er ....
-
-.... except when the .* appears inside capturing parentheses, and there is a
-subsequent back reference to those parentheses. We haven't enough information
-to catch that case precisely.
-
-At first, the best we could do was to detect when .* was in capturing brackets
-and the highest back reference was greater than or equal to that level.
-However, by keeping a bitmap of the first 31 back references, we can catch some
-of the more common cases more precisely.
-
-... A second exception is when the .* appears inside an atomic group, because
-this prevents the number of characters it matches from being adjusted.
-
-Arguments:
- code points to start of expression (the bracket)
- bracket_map a bitmap of which brackets we are inside while testing; this
- handles up to substring 31; after that we just have to take
- the less precise approach
- cd points to the compile data block
- atomcount atomic group level
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-is_anchored(register const pcre_uchar *code, unsigned int bracket_map,
- compile_data *cd, int atomcount)
-{
-do {
- const pcre_uchar *scode = first_significant_code(
- code + PRIV(OP_lengths)[*code], FALSE);
- register int op = *scode;
-
- /* Non-capturing brackets */
-
- if (op == OP_BRA || op == OP_BRAPOS ||
- op == OP_SBRA || op == OP_SBRAPOS)
- {
- if (!is_anchored(scode, bracket_map, cd, atomcount)) return FALSE;
- }
-
- /* Capturing brackets */
-
- else if (op == OP_CBRA || op == OP_CBRAPOS ||
- op == OP_SCBRA || op == OP_SCBRAPOS)
- {
- int n = GET2(scode, 1+LINK_SIZE);
- int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
- if (!is_anchored(scode, new_map, cd, atomcount)) return FALSE;
- }
-
- /* Positive forward assertions and conditions */
-
- else if (op == OP_ASSERT || op == OP_COND)
- {
- if (!is_anchored(scode, bracket_map, cd, atomcount)) return FALSE;
- }
-
- /* Atomic groups */
-
- else if (op == OP_ONCE || op == OP_ONCE_NC)
- {
- if (!is_anchored(scode, bracket_map, cd, atomcount + 1))
- return FALSE;
- }
-
- /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and
- it isn't in brackets that are or may be referenced or inside an atomic
- group. */
-
- else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR ||
- op == OP_TYPEPOSSTAR))
- {
- if (scode[1] != OP_ALLANY || (bracket_map & cd->backref_map) != 0 ||
- atomcount > 0 || cd->had_pruneorskip)
- return FALSE;
- }
-
- /* Check for explicit anchoring */
-
- else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE;
-
- code += GET(code, 1);
- }
-while (*code == OP_ALT); /* Loop for each alternative */
-return TRUE;
-}
-
-
-
-/*************************************************
-* Check for starting with ^ or .* *
-*************************************************/
-
-/* This is called to find out if every branch starts with ^ or .* so that
-"first char" processing can be done to speed things up in multiline
-matching and for non-DOTALL patterns that start with .* (which must start at
-the beginning or after \n). As in the case of is_anchored() (see above), we
-have to take account of back references to capturing brackets that contain .*
-because in that case we can't make the assumption. Also, the appearance of .*
-inside atomic brackets or in a pattern that contains *PRUNE or *SKIP does not
-count, because once again the assumption no longer holds.
-
-Arguments:
- code points to start of expression (the bracket)
- bracket_map a bitmap of which brackets we are inside while testing; this
- handles up to substring 31; after that we just have to take
- the less precise approach
- cd points to the compile data
- atomcount atomic group level
-
-Returns: TRUE or FALSE
-*/
-
-static BOOL
-is_startline(const pcre_uchar *code, unsigned int bracket_map,
- compile_data *cd, int atomcount)
-{
-do {
- const pcre_uchar *scode = first_significant_code(
- code + PRIV(OP_lengths)[*code], FALSE);
- register int op = *scode;
-
- /* If we are at the start of a conditional assertion group, *both* the
- conditional assertion *and* what follows the condition must satisfy the test
- for start of line. Other kinds of condition fail. Note that there may be an
- auto-callout at the start of a condition. */
-
- if (op == OP_COND)
- {
- scode += 1 + LINK_SIZE;
- if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT];
- switch (*scode)
- {
- case OP_CREF:
- case OP_NCREF:
- case OP_RREF:
- case OP_NRREF:
- case OP_DEF:
- return FALSE;
-
- default: /* Assertion */
- if (!is_startline(scode, bracket_map, cd, atomcount)) return FALSE;
- do scode += GET(scode, 1); while (*scode == OP_ALT);
- scode += 1 + LINK_SIZE;
- break;
- }
- scode = first_significant_code(scode, FALSE);
- op = *scode;
- }
-
- /* Non-capturing brackets */
-
- if (op == OP_BRA || op == OP_BRAPOS ||
- op == OP_SBRA || op == OP_SBRAPOS)
- {
- if (!is_startline(scode, bracket_map, cd, atomcount)) return FALSE;
- }
-
- /* Capturing brackets */
-
- else if (op == OP_CBRA || op == OP_CBRAPOS ||
- op == OP_SCBRA || op == OP_SCBRAPOS)
- {
- int n = GET2(scode, 1+LINK_SIZE);
- int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
- if (!is_startline(scode, new_map, cd, atomcount)) return FALSE;
- }
-
- /* Positive forward assertions */
-
- else if (op == OP_ASSERT)
- {
- if (!is_startline(scode, bracket_map, cd, atomcount)) return FALSE;
- }
-
- /* Atomic brackets */
-
- else if (op == OP_ONCE || op == OP_ONCE_NC)
- {
- if (!is_startline(scode, bracket_map, cd, atomcount + 1)) return FALSE;
- }
-
- /* .* means "start at start or after \n" if it isn't in atomic brackets or
- brackets that may be referenced, as long as the pattern does not contain
- *PRUNE or *SKIP, because these break the feature. Consider, for example,
- /.*?a(*PRUNE)b/ with the subject "aab", which matches "ab", i.e. not at the
- start of a line. */
-
- else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR)
- {
- if (scode[1] != OP_ANY || (bracket_map & cd->backref_map) != 0 ||
- atomcount > 0 || cd->had_pruneorskip)
- return FALSE;
- }
-
- /* Check for explicit circumflex; anything else gives a FALSE result. Note
- in particular that this includes atomic brackets OP_ONCE and OP_ONCE_NC
- because the number of characters matched by .* cannot be adjusted inside
- them. */
-
- else if (op != OP_CIRC && op != OP_CIRCM) return FALSE;
-
- /* Move on to the next alternative */
-
- code += GET(code, 1);
- }
-while (*code == OP_ALT); /* Loop for each alternative */
-return TRUE;
-}
-
-
-
-/*************************************************
-* Check for asserted fixed first char *
-*************************************************/
-
-/* During compilation, the "first char" settings from forward assertions are
-discarded, because they can cause conflicts with actual literals that follow.
-However, if we end up without a first char setting for an unanchored pattern,
-it is worth scanning the regex to see if there is an initial asserted first
-char. If all branches start with the same asserted char, or with a bracket all
-of whose alternatives start with the same asserted char (recurse ad lib), then
-we return that char, otherwise -1.
-
-Arguments:
- code points to start of expression (the bracket)
- flags points to the first char flags, or to REQ_NONE
- inassert TRUE if in an assertion
-
-Returns: the fixed first char, or 0 with REQ_NONE in flags
-*/
-
-static pcre_uint32
-find_firstassertedchar(const pcre_uchar *code, pcre_int32 *flags,
- BOOL inassert)
-{
-register pcre_uint32 c = 0;
-int cflags = REQ_NONE;
-
-*flags = REQ_NONE;
-do {
- pcre_uint32 d;
- int dflags;
- int xl = (*code == OP_CBRA || *code == OP_SCBRA ||
- *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0;
- const pcre_uchar *scode = first_significant_code(code + 1+LINK_SIZE + xl,
- TRUE);
- register pcre_uchar op = *scode;
-
- switch(op)
- {
- default:
- return 0;
-
- case OP_BRA:
- case OP_BRAPOS:
- case OP_CBRA:
- case OP_SCBRA:
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- case OP_ASSERT:
- case OP_ONCE:
- case OP_ONCE_NC:
- case OP_COND:
- d = find_firstassertedchar(scode, &dflags, op == OP_ASSERT);
- if (dflags < 0)
- return 0;
- if (cflags < 0) { c = d; cflags = dflags; } else if (c != d || cflags != dflags) return 0;
- break;
-
- case OP_EXACT:
- scode += IMM2_SIZE;
- /* Fall through */
-
- case OP_CHAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- if (!inassert) return 0;
- if (cflags < 0) { c = scode[1]; cflags = 0; }
- else if (c != scode[1]) return 0;
- break;
-
- case OP_EXACTI:
- scode += IMM2_SIZE;
- /* Fall through */
-
- case OP_CHARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_POSPLUSI:
- if (!inassert) return 0;
- if (cflags < 0) { c = scode[1]; cflags = REQ_CASELESS; }
- else if (c != scode[1]) return 0;
- break;
- }
-
- code += GET(code, 1);
- }
-while (*code == OP_ALT);
-
-*flags = cflags;
-return c;
-}
-
-
-
-/*************************************************
-* Compile a Regular Expression *
-*************************************************/
-
-/* This function takes a string and returns a pointer to a block of store
-holding a compiled version of the expression. The original API for this
-function had no error code return variable; it is retained for backwards
-compatibility. The new function is given a new name.
-
-Arguments:
- pattern the regular expression
- options various option bits
- errorcodeptr pointer to error code variable (pcre_compile2() only)
- can be NULL if you don't want a code value
- errorptr pointer to pointer to error text
- erroroffset ptr offset in pattern where error was detected
- tables pointer to character tables or NULL
-
-Returns: pointer to compiled data block, or NULL on error,
- with errorptr and erroroffset set
-*/
-
-#if defined COMPILE_PCRE8
-PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
-pcre_compile(const char *pattern, int options, const char **errorptr,
- int *erroroffset, const unsigned char *tables)
-#elif defined COMPILE_PCRE16
-PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION
-pcre16_compile(PCRE_SPTR16 pattern, int options, const char **errorptr,
- int *erroroffset, const unsigned char *tables)
-#elif defined COMPILE_PCRE32
-PCRE_EXP_DEFN pcre32 * PCRE_CALL_CONVENTION
-pcre32_compile(PCRE_SPTR32 pattern, int options, const char **errorptr,
- int *erroroffset, const unsigned char *tables)
-#endif
-{
-#if defined COMPILE_PCRE8
-return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
-#elif defined COMPILE_PCRE16
-return pcre16_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
-#elif defined COMPILE_PCRE32
-return pcre32_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
-#endif
-}
-
-
-#if defined COMPILE_PCRE8
-PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
-pcre_compile2(const char *pattern, int options, int *errorcodeptr,
- const char **errorptr, int *erroroffset, const unsigned char *tables)
-#elif defined COMPILE_PCRE16
-PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION
-pcre16_compile2(PCRE_SPTR16 pattern, int options, int *errorcodeptr,
- const char **errorptr, int *erroroffset, const unsigned char *tables)
-#elif defined COMPILE_PCRE32
-PCRE_EXP_DEFN pcre32 * PCRE_CALL_CONVENTION
-pcre32_compile2(PCRE_SPTR32 pattern, int options, int *errorcodeptr,
- const char **errorptr, int *erroroffset, const unsigned char *tables)
-#endif
-{
-REAL_PCRE *re;
-int length = 1; /* For final END opcode */
-pcre_int32 firstcharflags, reqcharflags;
-pcre_uint32 firstchar, reqchar;
-pcre_uint32 limit_match = PCRE_UINT32_MAX;
-pcre_uint32 limit_recursion = PCRE_UINT32_MAX;
-int newline;
-int errorcode = 0;
-int skipatstart = 0;
-BOOL utf;
-BOOL never_utf = FALSE;
-size_t size;
-pcre_uchar *code;
-const pcre_uchar *codestart;
-const pcre_uchar *ptr;
-compile_data compile_block;
-compile_data *cd = &compile_block;
-
-/* This space is used for "compiling" into during the first phase, when we are
-computing the amount of memory that is needed. Compiled items are thrown away
-as soon as possible, so that a fairly large buffer should be sufficient for
-this purpose. The same space is used in the second phase for remembering where
-to fill in forward references to subpatterns. That may overflow, in which case
-new memory is obtained from malloc(). */
-
-pcre_uchar cworkspace[COMPILE_WORK_SIZE];
-
-/* Set this early so that early errors get offset 0. */
-
-ptr = (const pcre_uchar *)pattern;
-
-/* We can't pass back an error message if errorptr is NULL; I guess the best we
-can do is just return NULL, but we can set a code value if there is a code
-pointer. */
-
-if (errorptr == NULL)
- {
- if (errorcodeptr != NULL) *errorcodeptr = 99;
- return NULL;
- }
-
-*errorptr = NULL;
-if (errorcodeptr != NULL) *errorcodeptr = ERR0;
-
-/* However, we can give a message for this error */
-
-if (erroroffset == NULL)
- {
- errorcode = ERR16;
- goto PCRE_EARLY_ERROR_RETURN2;
- }
-
-*erroroffset = 0;
-
-/* Set up pointers to the individual character tables */
-
-if (tables == NULL) tables = PRIV(default_tables);
-cd->lcc = tables + lcc_offset;
-cd->fcc = tables + fcc_offset;
-cd->cbits = tables + cbits_offset;
-cd->ctypes = tables + ctypes_offset;
-
-/* Check that all undefined public option bits are zero */
-
-if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)
- {
- errorcode = ERR17;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-
-/* If PCRE_NEVER_UTF is set, remember it. */
-
-if ((options & PCRE_NEVER_UTF) != 0) never_utf = TRUE;
-
-/* Check for global one-time settings at the start of the pattern, and remember
-the offset for later. */
-
-cd->external_flags = 0; /* Initialize here for LIMIT_MATCH/RECURSION */
-
-while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&
- ptr[skipatstart+1] == CHAR_ASTERISK)
- {
- int newnl = 0;
- int newbsr = 0;
-
-/* For completeness and backward compatibility, (*UTFn) is supported in the
-relevant libraries, but (*UTF) is generic and always supported. Note that
-PCRE_UTF8 == PCRE_UTF16 == PCRE_UTF32. */
-
-#ifdef COMPILE_PCRE8
- if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF8_RIGHTPAR, 5) == 0)
- { skipatstart += 7; options |= PCRE_UTF8; continue; }
-#endif
-#ifdef COMPILE_PCRE16
- if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF16_RIGHTPAR, 6) == 0)
- { skipatstart += 8; options |= PCRE_UTF16; continue; }
-#endif
-#ifdef COMPILE_PCRE32
- if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF32_RIGHTPAR, 6) == 0)
- { skipatstart += 8; options |= PCRE_UTF32; continue; }
-#endif
-
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 4) == 0)
- { skipatstart += 6; options |= PCRE_UTF8; continue; }
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UCP_RIGHTPAR, 4) == 0)
- { skipatstart += 6; options |= PCRE_UCP; continue; }
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_START_OPT_RIGHTPAR, 13) == 0)
- { skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; }
-
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LIMIT_MATCH_EQ, 12) == 0)
- {
- pcre_uint32 c = 0;
- int p = skipatstart + 14;
- while (isdigit(ptr[p]))
- {
- if (c > PCRE_UINT32_MAX / 10 - 1) break; /* Integer overflow */
- c = c*10 + ptr[p++] - CHAR_0;
- }
- if (ptr[p++] != CHAR_RIGHT_PARENTHESIS) break;
- if (c < limit_match)
- {
- limit_match = c;
- cd->external_flags |= PCRE_MLSET;
- }
- skipatstart = p;
- continue;
- }
-
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LIMIT_RECURSION_EQ, 16) == 0)
- {
- pcre_uint32 c = 0;
- int p = skipatstart + 18;
- while (isdigit(ptr[p]))
- {
- if (c > PCRE_UINT32_MAX / 10 - 1) break; /* Integer overflow check */
- c = c*10 + ptr[p++] - CHAR_0;
- }
- if (ptr[p++] != CHAR_RIGHT_PARENTHESIS) break;
- if (c < limit_recursion)
- {
- limit_recursion = c;
- cd->external_flags |= PCRE_RLSET;
- }
- skipatstart = p;
- continue;
- }
-
- if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CR_RIGHTPAR, 3) == 0)
- { skipatstart += 5; newnl = PCRE_NEWLINE_CR; }
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LF_RIGHTPAR, 3) == 0)
- { skipatstart += 5; newnl = PCRE_NEWLINE_LF; }
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CRLF_RIGHTPAR, 5) == 0)
- { skipatstart += 7; newnl = PCRE_NEWLINE_CR + PCRE_NEWLINE_LF; }
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANY_RIGHTPAR, 4) == 0)
- { skipatstart += 6; newnl = PCRE_NEWLINE_ANY; }
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANYCRLF_RIGHTPAR, 8) == 0)
- { skipatstart += 10; newnl = PCRE_NEWLINE_ANYCRLF; }
-
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0)
- { skipatstart += 14; newbsr = PCRE_BSR_ANYCRLF; }
- else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_UNICODE_RIGHTPAR, 12) == 0)
- { skipatstart += 14; newbsr = PCRE_BSR_UNICODE; }
-
- if (newnl != 0)
- options = (options & ~PCRE_NEWLINE_BITS) | newnl;
- else if (newbsr != 0)
- options = (options & ~(PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) | newbsr;
- else break;
- }
-
-/* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */
-utf = (options & PCRE_UTF8) != 0;
-if (utf && never_utf)
- {
- errorcode = ERR78;
- goto PCRE_EARLY_ERROR_RETURN2;
- }
-
-/* Can't support UTF unless PCRE has been compiled to include the code. The
-return of an error code from PRIV(valid_utf)() is a new feature, introduced in
-release 8.13. It is passed back from pcre_[dfa_]exec(), but at the moment is
-not used here. */
-
-#ifdef SUPPORT_UTF
-if (utf && (options & PCRE_NO_UTF8_CHECK) == 0 &&
- (errorcode = PRIV(valid_utf)((PCRE_PUCHAR)pattern, -1, erroroffset)) != 0)
- {
-#if defined COMPILE_PCRE8
- errorcode = ERR44;
-#elif defined COMPILE_PCRE16
- errorcode = ERR74;
-#elif defined COMPILE_PCRE32
- errorcode = ERR77;
-#endif
- goto PCRE_EARLY_ERROR_RETURN2;
- }
-#else
-if (utf)
- {
- errorcode = ERR32;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-#endif
-
-/* Can't support UCP unless PCRE has been compiled to include the code. */
-
-#ifndef SUPPORT_UCP
-if ((options & PCRE_UCP) != 0)
- {
- errorcode = ERR67;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-#endif
-
-/* Check validity of \R options. */
-
-if ((options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) ==
- (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
- {
- errorcode = ERR56;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-
-/* Handle different types of newline. The three bits give seven cases. The
-current code allows for fixed one- or two-byte sequences, plus "any" and
-"anycrlf". */
-
-switch (options & PCRE_NEWLINE_BITS)
- {
- case 0: newline = NEWLINE; break; /* Build-time default */
- case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
- case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
- case PCRE_NEWLINE_CR+
- PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
- case PCRE_NEWLINE_ANY: newline = -1; break;
- case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
- default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;
- }
-
-if (newline == -2)
- {
- cd->nltype = NLTYPE_ANYCRLF;
- }
-else if (newline < 0)
- {
- cd->nltype = NLTYPE_ANY;
- }
-else
- {
- cd->nltype = NLTYPE_FIXED;
- if (newline > 255)
- {
- cd->nllen = 2;
- cd->nl[0] = (newline >> 8) & 255;
- cd->nl[1] = newline & 255;
- }
- else
- {
- cd->nllen = 1;
- cd->nl[0] = newline;
- }
- }
-
-/* Maximum back reference and backref bitmap. The bitmap records up to 31 back
-references to help in deciding whether (.*) can be treated as anchored or not.
-*/
-
-cd->top_backref = 0;
-cd->backref_map = 0;
-
-/* Reflect pattern for debugging output */
-
-DPRINTF(("------------------------------------------------------------------\n"));
-#ifdef PCRE_DEBUG
-print_puchar(stdout, (PCRE_PUCHAR)pattern);
-#endif
-DPRINTF(("\n"));
-
-/* Pretend to compile the pattern while actually just accumulating the length
-of memory required. This behaviour is triggered by passing a non-NULL final
-argument to compile_regex(). We pass a block of workspace (cworkspace) for it
-to compile parts of the pattern into; the compiled code is discarded when it is
-no longer needed, so hopefully this workspace will never overflow, though there
-is a test for its doing so. */
-
-cd->bracount = cd->final_bracount = 0;
-cd->names_found = 0;
-cd->name_entry_size = 0;
-cd->name_table = NULL;
-cd->start_code = cworkspace;
-cd->hwm = cworkspace;
-cd->start_workspace = cworkspace;
-cd->workspace_size = COMPILE_WORK_SIZE;
-cd->start_pattern = (const pcre_uchar *)pattern;
-cd->end_pattern = (const pcre_uchar *)(pattern + STRLEN_UC((const pcre_uchar *)pattern));
-cd->req_varyopt = 0;
-cd->assert_depth = 0;
-cd->max_lookbehind = 0;
-cd->external_options = options;
-cd->open_caps = NULL;
-
-/* Now do the pre-compile. On error, errorcode will be set non-zero, so we
-don't need to look at the result of the function here. The initial options have
-been put into the cd block so that they can be changed if an option setting is
-found within the regex right at the beginning. Bringing initial option settings
-outside can help speed up starting point checks. */
-
-ptr += skipatstart;
-code = cworkspace;
-*code = OP_BRA;
-(void)compile_regex(cd->external_options, &code, &ptr, &errorcode, FALSE,
- FALSE, 0, 0, &firstchar, &firstcharflags, &reqchar, &reqcharflags, NULL,
- cd, &length);
-if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
-
-DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
- (int)(cd->hwm - cworkspace)));
-
-if (length > MAX_PATTERN_SIZE)
- {
- errorcode = ERR20;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-
-/* Compute the size of data block needed and get it, either from malloc or
-externally provided function. Integer overflow should no longer be possible
-because nowadays we limit the maximum value of cd->names_found and
-cd->name_entry_size. */
-
-size = sizeof(REAL_PCRE) + (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar);
-re = (REAL_PCRE *)(PUBL(malloc))(size);
-
-if (re == NULL)
- {
- errorcode = ERR21;
- goto PCRE_EARLY_ERROR_RETURN;
- }
-
-/* Put in the magic number, and save the sizes, initial options, internal
-flags, and character table pointer. NULL is used for the default character
-tables. The nullpad field is at the end; it's there to help in the case when a
-regex compiled on a system with 4-byte pointers is run on another with 8-byte
-pointers. */
-
-re->magic_number = MAGIC_NUMBER;
-re->size = (int)size;
-re->options = cd->external_options;
-re->flags = cd->external_flags;
-re->limit_match = limit_match;
-re->limit_recursion = limit_recursion;
-re->first_char = 0;
-re->req_char = 0;
-re->name_table_offset = sizeof(REAL_PCRE) / sizeof(pcre_uchar);
-re->name_entry_size = cd->name_entry_size;
-re->name_count = cd->names_found;
-re->ref_count = 0;
-re->tables = (tables == PRIV(default_tables))? NULL : tables;
-re->nullpad = NULL;
-#ifdef COMPILE_PCRE32
-re->dummy = 0;
-#else
-re->dummy1 = re->dummy2 = re->dummy3 = 0;
-#endif
-
-/* The starting points of the name/number translation table and of the code are
-passed around in the compile data block. The start/end pattern and initial
-options are already set from the pre-compile phase, as is the name_entry_size
-field. Reset the bracket count and the names_found field. Also reset the hwm
-field; this time it's used for remembering forward references to subpatterns.
-*/
-
-cd->final_bracount = cd->bracount; /* Save for checking forward references */
-cd->assert_depth = 0;
-cd->bracount = 0;
-cd->max_lookbehind = 0;
-cd->names_found = 0;
-cd->name_table = (pcre_uchar *)re + re->name_table_offset;
-codestart = cd->name_table + re->name_entry_size * re->name_count;
-cd->start_code = codestart;
-cd->hwm = (pcre_uchar *)(cd->start_workspace);
-cd->req_varyopt = 0;
-cd->had_accept = FALSE;
-cd->had_pruneorskip = FALSE;
-cd->check_lookbehind = FALSE;
-cd->open_caps = NULL;
-
-/* Set up a starting, non-extracting bracket, then compile the expression. On
-error, errorcode will be set non-zero, so we don't need to look at the result
-of the function here. */
-
-ptr = (const pcre_uchar *)pattern + skipatstart;
-code = (pcre_uchar *)codestart;
-*code = OP_BRA;
-(void)compile_regex(re->options, &code, &ptr, &errorcode, FALSE, FALSE, 0, 0,
- &firstchar, &firstcharflags, &reqchar, &reqcharflags, NULL, cd, NULL);
-re->top_bracket = cd->bracount;
-re->top_backref = cd->top_backref;
-re->max_lookbehind = cd->max_lookbehind;
-re->flags = cd->external_flags | PCRE_MODE;
-
-if (cd->had_accept)
- {
- reqchar = 0; /* Must disable after (*ACCEPT) */
- reqcharflags = REQ_NONE;
- }
-
-/* If not reached end of pattern on success, there's an excess bracket. */
-
-if (errorcode == 0 && *ptr != CHAR_NULL) errorcode = ERR22;
-
-/* Fill in the terminating state and check for disastrous overflow, but
-if debugging, leave the test till after things are printed out. */
-
-*code++ = OP_END;
-
-#ifndef PCRE_DEBUG
-if (code - codestart > length) errorcode = ERR23;
-#endif
-
-#ifdef SUPPORT_VALGRIND
-/* If the estimated length exceeds the really used length, mark the extra
-allocated memory as unaddressable, so that any out-of-bound reads can be
-detected. */
-VALGRIND_MAKE_MEM_NOACCESS(code, (length - (code - codestart)) * sizeof(pcre_uchar));
-#endif
-
-/* Fill in any forward references that are required. There may be repeated
-references; optimize for them, as searching a large regex takes time. */
-
-if (cd->hwm > cd->start_workspace)
- {
- int prev_recno = -1;
- const pcre_uchar *groupptr = NULL;
- while (errorcode == 0 && cd->hwm > cd->start_workspace)
- {
- int offset, recno;
- cd->hwm -= LINK_SIZE;
- offset = GET(cd->hwm, 0);
- recno = GET(codestart, offset);
- if (recno != prev_recno)
- {
- groupptr = PRIV(find_bracket)(codestart, utf, recno);
- prev_recno = recno;
- }
- if (groupptr == NULL) errorcode = ERR53;
- else PUT(((pcre_uchar *)codestart), offset, (int)(groupptr - codestart));
- }
- }
-
-/* If the workspace had to be expanded, free the new memory. */
-
-if (cd->workspace_size > COMPILE_WORK_SIZE)
- (PUBL(free))((void *)cd->start_workspace);
-
-/* Give an error if there's back reference to a non-existent capturing
-subpattern. */
-
-if (errorcode == 0 && re->top_backref > re->top_bracket) errorcode = ERR15;
-
-/* If there were any lookbehind assertions that contained OP_RECURSE
-(recursions or subroutine calls), a flag is set for them to be checked here,
-because they may contain forward references. Actual recursions cannot be fixed
-length, but subroutine calls can. It is done like this so that those without
-OP_RECURSE that are not fixed length get a diagnosic with a useful offset. The
-exceptional ones forgo this. We scan the pattern to check that they are fixed
-length, and set their lengths. */
-
-if (cd->check_lookbehind)
- {
- pcre_uchar *cc = (pcre_uchar *)codestart;
-
- /* Loop, searching for OP_REVERSE items, and process those that do not have
- their length set. (Actually, it will also re-process any that have a length
- of zero, but that is a pathological case, and it does no harm.) When we find
- one, we temporarily terminate the branch it is in while we scan it. */
-
- for (cc = (pcre_uchar *)PRIV(find_bracket)(codestart, utf, -1);
- cc != NULL;
- cc = (pcre_uchar *)PRIV(find_bracket)(cc, utf, -1))
- {
- if (GET(cc, 1) == 0)
- {
- int fixed_length;
- pcre_uchar *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE);
- int end_op = *be;
- *be = OP_END;
- fixed_length = find_fixedlength(cc, (re->options & PCRE_UTF8) != 0, TRUE,
- cd);
- *be = end_op;
- DPRINTF(("fixed length = %d\n", fixed_length));
- if (fixed_length < 0)
- {
- errorcode = (fixed_length == -2)? ERR36 :
- (fixed_length == -4)? ERR70 : ERR25;
- break;
- }
- if (fixed_length > cd->max_lookbehind) cd->max_lookbehind = fixed_length;
- PUT(cc, 1, fixed_length);
- }
- cc += 1 + LINK_SIZE;
- }
- }
-
-/* Failed to compile, or error while post-processing */
-
-if (errorcode != 0)
- {
- (PUBL(free))(re);
- PCRE_EARLY_ERROR_RETURN:
- *erroroffset = (int)(ptr - (const pcre_uchar *)pattern);
- PCRE_EARLY_ERROR_RETURN2:
- *errorptr = find_error_text(errorcode);
- if (errorcodeptr != NULL) *errorcodeptr = errorcode;
- return NULL;
- }
-
-/* If the anchored option was not passed, set the flag if we can determine that
-the pattern is anchored by virtue of ^ characters or \A or anything else, such
-as starting with non-atomic .* when DOTALL is set and there are no occurrences
-of *PRUNE or *SKIP.
-
-Otherwise, if we know what the first byte has to be, save it, because that
-speeds up unanchored matches no end. If not, see if we can set the
-PCRE_STARTLINE flag. This is helpful for multiline matches when all branches
-start with ^. and also when all branches start with non-atomic .* for
-non-DOTALL matches when *PRUNE and SKIP are not present. */
-
-if ((re->options & PCRE_ANCHORED) == 0)
- {
- if (is_anchored(codestart, 0, cd, 0)) re->options |= PCRE_ANCHORED;
- else
- {
- if (firstcharflags < 0)
- firstchar = find_firstassertedchar(codestart, &firstcharflags, FALSE);
- if (firstcharflags >= 0) /* Remove caseless flag for non-caseable chars */
- {
-#if defined COMPILE_PCRE8
- re->first_char = firstchar & 0xff;
-#elif defined COMPILE_PCRE16
- re->first_char = firstchar & 0xffff;
-#elif defined COMPILE_PCRE32
- re->first_char = firstchar;
-#endif
- if ((firstcharflags & REQ_CASELESS) != 0)
- {
-#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
- /* We ignore non-ASCII first chars in 8 bit mode. */
- if (utf)
- {
- if (re->first_char < 128)
- {
- if (cd->fcc[re->first_char] != re->first_char)
- re->flags |= PCRE_FCH_CASELESS;
- }
- else if (UCD_OTHERCASE(re->first_char) != re->first_char)
- re->flags |= PCRE_FCH_CASELESS;
- }
- else
-#endif
- if (MAX_255(re->first_char)
- && cd->fcc[re->first_char] != re->first_char)
- re->flags |= PCRE_FCH_CASELESS;
- }
-
- re->flags |= PCRE_FIRSTSET;
- }
-
- else if (is_startline(codestart, 0, cd, 0)) re->flags |= PCRE_STARTLINE;
- }
- }
-
-/* For an anchored pattern, we use the "required byte" only if it follows a
-variable length item in the regex. Remove the caseless flag for non-caseable
-bytes. */
-
-if (reqcharflags >= 0 &&
- ((re->options & PCRE_ANCHORED) == 0 || (reqcharflags & REQ_VARY) != 0))
- {
-#if defined COMPILE_PCRE8
- re->req_char = reqchar & 0xff;
-#elif defined COMPILE_PCRE16
- re->req_char = reqchar & 0xffff;
-#elif defined COMPILE_PCRE32
- re->req_char = reqchar;
-#endif
- if ((reqcharflags & REQ_CASELESS) != 0)
- {
-#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
- /* We ignore non-ASCII first chars in 8 bit mode. */
- if (utf)
- {
- if (re->req_char < 128)
- {
- if (cd->fcc[re->req_char] != re->req_char)
- re->flags |= PCRE_RCH_CASELESS;
- }
- else if (UCD_OTHERCASE(re->req_char) != re->req_char)
- re->flags |= PCRE_RCH_CASELESS;
- }
- else
-#endif
- if (MAX_255(re->req_char) && cd->fcc[re->req_char] != re->req_char)
- re->flags |= PCRE_RCH_CASELESS;
- }
-
- re->flags |= PCRE_REQCHSET;
- }
-
-/* Print out the compiled data if debugging is enabled. This is never the
-case when building a production library. */
-
-#ifdef PCRE_DEBUG
-printf("Length = %d top_bracket = %d top_backref = %d\n",
- length, re->top_bracket, re->top_backref);
-
-printf("Options=%08x\n", re->options);
-
-if ((re->flags & PCRE_FIRSTSET) != 0)
- {
- pcre_uchar ch = re->first_char;
- const char *caseless =
- ((re->flags & PCRE_FCH_CASELESS) == 0)? "" : " (caseless)";
- if (PRINTABLE(ch)) printf("First char = %c%s\n", ch, caseless);
- else printf("First char = \\x%02x%s\n", ch, caseless);
- }
-
-if ((re->flags & PCRE_REQCHSET) != 0)
- {
- pcre_uchar ch = re->req_char;
- const char *caseless =
- ((re->flags & PCRE_RCH_CASELESS) == 0)? "" : " (caseless)";
- if (PRINTABLE(ch)) printf("Req char = %c%s\n", ch, caseless);
- else printf("Req char = \\x%02x%s\n", ch, caseless);
- }
-
-#if defined COMPILE_PCRE8
-pcre_printint((pcre *)re, stdout, TRUE);
-#elif defined COMPILE_PCRE16
-pcre16_printint((pcre *)re, stdout, TRUE);
-#elif defined COMPILE_PCRE32
-pcre32_printint((pcre *)re, stdout, TRUE);
-#endif
-
-/* This check is done here in the debugging case so that the code that
-was compiled can be seen. */
-
-if (code - codestart > length)
- {
- (PUBL(free))(re);
- *errorptr = find_error_text(ERR23);
- *erroroffset = ptr - (pcre_uchar *)pattern;
- if (errorcodeptr != NULL) *errorcodeptr = ERR23;
- return NULL;
- }
-#endif /* PCRE_DEBUG */
-
-#if defined COMPILE_PCRE8
-return (pcre *)re;
-#elif defined COMPILE_PCRE16
-return (pcre16 *)re;
-#elif defined COMPILE_PCRE32
-return (pcre32 *)re;
-#endif
-}
-
-/* End of pcre_compile.c */
diff --git a/usr.sbin/nginx/src/pcre/pcre_exec.c b/usr.sbin/nginx/src/pcre/pcre_exec.c
deleted file mode 100644
index 48ba0ef4007..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre_exec.c
+++ /dev/null
@@ -1,7213 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2013 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This module contains pcre_exec(), the externally visible function that does
-pattern matching using an NFA algorithm, trying to mimic Perl as closely as
-possible. There are also some static supporting functions. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#define NLBLOCK md /* Block containing newline information */
-#define PSSTART start_subject /* Field containing processed string start */
-#define PSEND end_subject /* Field containing processed string end */
-
-#include "pcre_internal.h"
-
-/* Undefine some potentially clashing cpp symbols */
-
-#undef min
-#undef max
-
-/* The md->capture_last field uses the lower 16 bits for the last captured
-substring (which can never be greater than 65535) and a bit in the top half
-to mean "capture vector overflowed". This odd way of doing things was
-implemented when it was realized that preserving and restoring the overflow bit
-whenever the last capture number was saved/restored made for a neater
-interface, and doing it this way saved on (a) another variable, which would
-have increased the stack frame size (a big NO-NO in PCRE) and (b) another
-separate set of save/restore instructions. The following defines are used in
-implementing this. */
-
-#define CAPLMASK 0x0000ffff /* The bits used for last_capture */
-#define OVFLMASK 0xffff0000 /* The bits used for the overflow flag */
-#define OVFLBIT 0x00010000 /* The bit that is set for overflow */
-
-/* Values for setting in md->match_function_type to indicate two special types
-of call to match(). We do it this way to save on using another stack variable,
-as stack usage is to be discouraged. */
-
-#define MATCH_CONDASSERT 1 /* Called to check a condition assertion */
-#define MATCH_CBEGROUP 2 /* Could-be-empty unlimited repeat group */
-
-/* Non-error returns from the match() function. Error returns are externally
-defined PCRE_ERROR_xxx codes, which are all negative. */
-
-#define MATCH_MATCH 1
-#define MATCH_NOMATCH 0
-
-/* Special internal returns from the match() function. Make them sufficiently
-negative to avoid the external error codes. */
-
-#define MATCH_ACCEPT (-999)
-#define MATCH_KETRPOS (-998)
-#define MATCH_ONCE (-997)
-/* The next 5 must be kept together and in sequence so that a test that checks
-for any one of them can use a range. */
-#define MATCH_COMMIT (-996)
-#define MATCH_PRUNE (-995)
-#define MATCH_SKIP (-994)
-#define MATCH_SKIP_ARG (-993)
-#define MATCH_THEN (-992)
-#define MATCH_BACKTRACK_MAX MATCH_THEN
-#define MATCH_BACKTRACK_MIN MATCH_COMMIT
-
-/* Maximum number of ints of offset to save on the stack for recursive calls.
-If the offset vector is bigger, malloc is used. This should be a multiple of 3,
-because the offset vector is always a multiple of 3 long. */
-
-#define REC_STACK_SAVE_MAX 30
-
-/* Min and max values for the common repeats; for the maxima, 0 => infinity */
-
-static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };
-static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };
-
-#ifdef PCRE_DEBUG
-/*************************************************
-* Debugging function to print chars *
-*************************************************/
-
-/* Print a sequence of chars in printable format, stopping at the end of the
-subject if the requested.
-
-Arguments:
- p points to characters
- length number to print
- is_subject TRUE if printing from within md->start_subject
- md pointer to matching data block, if is_subject is TRUE
-
-Returns: nothing
-*/
-
-static void
-pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md)
-{
-pcre_uint32 c;
-BOOL utf = md->utf;
-if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
-while (length-- > 0)
- if (isprint(c = RAWUCHARINCTEST(p))) printf("%c", (char)c); else printf("\\x{%02x}", c);
-}
-#endif
-
-
-
-/*************************************************
-* Match a back-reference *
-*************************************************/
-
-/* Normally, if a back reference hasn't been set, the length that is passed is
-negative, so the match always fails. However, in JavaScript compatibility mode,
-the length passed is zero. Note that in caseless UTF-8 mode, the number of
-subject bytes matched may be different to the number of reference bytes.
-
-Arguments:
- offset index into the offset vector
- eptr pointer into the subject
- length length of reference to be matched (number of bytes)
- md points to match data block
- caseless TRUE if caseless
-
-Returns: >= 0 the number of subject bytes matched
- -1 no match
- -2 partial match; always given if at end subject
-*/
-
-static int
-match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md,
- BOOL caseless)
-{
-PCRE_PUCHAR eptr_start = eptr;
-register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
-#ifdef SUPPORT_UTF
-BOOL utf = md->utf;
-#endif
-
-#ifdef PCRE_DEBUG
-if (eptr >= md->end_subject)
- printf("matching subject <null>");
-else
- {
- printf("matching subject ");
- pchars(eptr, length, TRUE, md);
- }
-printf(" against backref ");
-pchars(p, length, FALSE, md);
-printf("\n");
-#endif
-
-/* Always fail if reference not set (and not JavaScript compatible - in that
-case the length is passed as zero). */
-
-if (length < 0) return -1;
-
-/* Separate the caseless case for speed. In UTF-8 mode we can only do this
-properly if Unicode properties are supported. Otherwise, we can check only
-ASCII characters. */
-
-if (caseless)
- {
-#ifdef SUPPORT_UTF
-#ifdef SUPPORT_UCP
- if (utf)
- {
- /* Match characters up to the end of the reference. NOTE: the number of
- data units matched may differ, because in UTF-8 there are some characters
- whose upper and lower case versions code have different numbers of bytes.
- For example, U+023A (2 bytes in UTF-8) is the upper case version of U+2C65
- (3 bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a
- sequence of two of the latter. It is important, therefore, to check the
- length along the reference, not along the subject (earlier code did this
- wrong). */
-
- PCRE_PUCHAR endptr = p + length;
- while (p < endptr)
- {
- pcre_uint32 c, d;
- const ucd_record *ur;
- if (eptr >= md->end_subject) return -2; /* Partial match */
- GETCHARINC(c, eptr);
- GETCHARINC(d, p);
- ur = GET_UCD(d);
- if (c != d && c != d + ur->other_case)
- {
- const pcre_uint32 *pp = PRIV(ucd_caseless_sets) + ur->caseset;
- for (;;)
- {
- if (c < *pp) return -1;
- if (c == *pp++) break;
- }
- }
- }
- }
- else
-#endif
-#endif
-
- /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
- is no UCP support. */
- {
- while (length-- > 0)
- {
- pcre_uint32 cc, cp;
- if (eptr >= md->end_subject) return -2; /* Partial match */
- cc = RAWUCHARTEST(eptr);
- cp = RAWUCHARTEST(p);
- if (TABLE_GET(cp, md->lcc, cp) != TABLE_GET(cc, md->lcc, cc)) return -1;
- p++;
- eptr++;
- }
- }
- }
-
-/* In the caseful case, we can just compare the bytes, whether or not we
-are in UTF-8 mode. */
-
-else
- {
- while (length-- > 0)
- {
- if (eptr >= md->end_subject) return -2; /* Partial match */
- if (RAWUCHARINCTEST(p) != RAWUCHARINCTEST(eptr)) return -1;
- }
- }
-
-return (int)(eptr - eptr_start);
-}
-
-
-
-/***************************************************************************
-****************************************************************************
- RECURSION IN THE match() FUNCTION
-
-The match() function is highly recursive, though not every recursive call
-increases the recursive depth. Nevertheless, some regular expressions can cause
-it to recurse to a great depth. I was writing for Unix, so I just let it call
-itself recursively. This uses the stack for saving everything that has to be
-saved for a recursive call. On Unix, the stack can be large, and this works
-fine.
-
-It turns out that on some non-Unix-like systems there are problems with
-programs that use a lot of stack. (This despite the fact that every last chip
-has oodles of memory these days, and techniques for extending the stack have
-been known for decades.) So....
-
-There is a fudge, triggered by defining NO_RECURSE, which avoids recursive
-calls by keeping local variables that need to be preserved in blocks of memory
-obtained from malloc() instead instead of on the stack. Macros are used to
-achieve this so that the actual code doesn't look very different to what it
-always used to.
-
-The original heap-recursive code used longjmp(). However, it seems that this
-can be very slow on some operating systems. Following a suggestion from Stan
-Switzer, the use of longjmp() has been abolished, at the cost of having to
-provide a unique number for each call to RMATCH. There is no way of generating
-a sequence of numbers at compile time in C. I have given them names, to make
-them stand out more clearly.
-
-Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
-FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
-tests. Furthermore, not using longjmp() means that local dynamic variables
-don't have indeterminate values; this has meant that the frame size can be
-reduced because the result can be "passed back" by straight setting of the
-variable instead of being passed in the frame.
-****************************************************************************
-***************************************************************************/
-
-/* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
-below must be updated in sync. */
-
-enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10,
- RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
- RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
- RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
- RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
- RM51, RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,
- RM61, RM62, RM63, RM64, RM65, RM66, RM67, RM68 };
-
-/* These versions of the macros use the stack, as normal. There are debugging
-versions and production versions. Note that the "rw" argument of RMATCH isn't
-actually used in this definition. */
-
-#ifndef NO_RECURSE
-#define REGISTER register
-
-#ifdef PCRE_DEBUG
-#define RMATCH(ra,rb,rc,rd,re,rw) \
- { \
- printf("match() called in line %d\n", __LINE__); \
- rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1); \
- printf("to line %d\n", __LINE__); \
- }
-#define RRETURN(ra) \
- { \
- printf("match() returned %d from line %d\n", ra, __LINE__); \
- return ra; \
- }
-#else
-#define RMATCH(ra,rb,rc,rd,re,rw) \
- rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1)
-#define RRETURN(ra) return ra
-#endif
-
-#else
-
-
-/* These versions of the macros manage a private stack on the heap. Note that
-the "rd" argument of RMATCH isn't actually used in this definition. It's the md
-argument of match(), which never changes. */
-
-#define REGISTER
-
-#define RMATCH(ra,rb,rc,rd,re,rw)\
- {\
- heapframe *newframe = frame->Xnextframe;\
- if (newframe == NULL)\
- {\
- newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
- if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
- newframe->Xnextframe = NULL;\
- frame->Xnextframe = newframe;\
- }\
- frame->Xwhere = rw;\
- newframe->Xeptr = ra;\
- newframe->Xecode = rb;\
- newframe->Xmstart = mstart;\
- newframe->Xoffset_top = rc;\
- newframe->Xeptrb = re;\
- newframe->Xrdepth = frame->Xrdepth + 1;\
- newframe->Xprevframe = frame;\
- frame = newframe;\
- DPRINTF(("restarting from line %d\n", __LINE__));\
- goto HEAP_RECURSE;\
- L_##rw:\
- DPRINTF(("jumped back to line %d\n", __LINE__));\
- }
-
-#define RRETURN(ra)\
- {\
- heapframe *oldframe = frame;\
- frame = oldframe->Xprevframe;\
- if (frame != NULL)\
- {\
- rrc = ra;\
- goto HEAP_RETURN;\
- }\
- return ra;\
- }
-
-
-/* Structure for remembering the local variables in a private frame */
-
-typedef struct heapframe {
- struct heapframe *Xprevframe;
- struct heapframe *Xnextframe;
-
- /* Function arguments that may change */
-
- PCRE_PUCHAR Xeptr;
- const pcre_uchar *Xecode;
- PCRE_PUCHAR Xmstart;
- int Xoffset_top;
- eptrblock *Xeptrb;
- unsigned int Xrdepth;
-
- /* Function local variables */
-
- PCRE_PUCHAR Xcallpat;
-#ifdef SUPPORT_UTF
- PCRE_PUCHAR Xcharptr;
-#endif
- PCRE_PUCHAR Xdata;
- PCRE_PUCHAR Xnext;
- PCRE_PUCHAR Xpp;
- PCRE_PUCHAR Xprev;
- PCRE_PUCHAR Xsaved_eptr;
-
- recursion_info Xnew_recursive;
-
- BOOL Xcur_is_word;
- BOOL Xcondition;
- BOOL Xprev_is_word;
-
-#ifdef SUPPORT_UCP
- int Xprop_type;
- unsigned int Xprop_value;
- int Xprop_fail_result;
- int Xoclength;
- pcre_uchar Xocchars[6];
-#endif
-
- int Xcodelink;
- int Xctype;
- unsigned int Xfc;
- int Xfi;
- int Xlength;
- int Xmax;
- int Xmin;
- unsigned int Xnumber;
- int Xoffset;
- unsigned int Xop;
- pcre_int32 Xsave_capture_last;
- int Xsave_offset1, Xsave_offset2, Xsave_offset3;
- int Xstacksave[REC_STACK_SAVE_MAX];
-
- eptrblock Xnewptrb;
-
- /* Where to jump back to */
-
- int Xwhere;
-
-} heapframe;
-
-#endif
-
-
-/***************************************************************************
-***************************************************************************/
-
-
-
-/*************************************************
-* Match from current position *
-*************************************************/
-
-/* This function is called recursively in many circumstances. Whenever it
-returns a negative (error) response, the outer incarnation must also return the
-same response. */
-
-/* These macros pack up tests that are used for partial matching, and which
-appear several times in the code. We set the "hit end" flag if the pointer is
-at the end of the subject and also past the start of the subject (i.e.
-something has been matched). For hard partial matching, we then return
-immediately. The second one is used when we already know we are past the end of
-the subject. */
-
-#define CHECK_PARTIAL()\
- if (md->partial != 0 && eptr >= md->end_subject && \
- eptr > md->start_used_ptr) \
- { \
- md->hitend = TRUE; \
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
- }
-
-#define SCHECK_PARTIAL()\
- if (md->partial != 0 && eptr > md->start_used_ptr) \
- { \
- md->hitend = TRUE; \
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
- }
-
-
-/* Performance note: It might be tempting to extract commonly used fields from
-the md structure (e.g. utf, end_subject) into individual variables to improve
-performance. Tests using gcc on a SPARC disproved this; in the first case, it
-made performance worse.
-
-Arguments:
- eptr pointer to current character in subject
- ecode pointer to current position in compiled code
- mstart pointer to the current match start position (can be modified
- by encountering \K)
- offset_top current top pointer
- md pointer to "static" info for the match
- eptrb pointer to chain of blocks containing eptr at start of
- brackets - for testing for empty matches
- rdepth the recursion depth
-
-Returns: MATCH_MATCH if matched ) these values are >= 0
- MATCH_NOMATCH if failed to match )
- a negative MATCH_xxx value for PRUNE, SKIP, etc
- a negative PCRE_ERROR_xxx value if aborted by an error condition
- (e.g. stopped by repeated call or recursion limit)
-*/
-
-static int
-match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
- PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
- unsigned int rdepth)
-{
-/* These variables do not need to be preserved over recursion in this function,
-so they can be ordinary variables in all cases. Mark some of them with
-"register" because they are used a lot in loops. */
-
-register int rrc; /* Returns from recursive calls */
-register int i; /* Used for loops not involving calls to RMATCH() */
-register pcre_uint32 c; /* Character values not kept over RMATCH() calls */
-register BOOL utf; /* Local copy of UTF flag for speed */
-
-BOOL minimize, possessive; /* Quantifier options */
-BOOL caseless;
-int condcode;
-
-/* When recursion is not being used, all "local" variables that have to be
-preserved over calls to RMATCH() are part of a "frame". We set up the top-level
-frame on the stack here; subsequent instantiations are obtained from the heap
-whenever RMATCH() does a "recursion". See the macro definitions above. Putting
-the top-level on the stack rather than malloc-ing them all gives a performance
-boost in many cases where there is not much "recursion". */
-
-#ifdef NO_RECURSE
-heapframe *frame = (heapframe *)md->match_frames_base;
-
-/* Copy in the original argument variables */
-
-frame->Xeptr = eptr;
-frame->Xecode = ecode;
-frame->Xmstart = mstart;
-frame->Xoffset_top = offset_top;
-frame->Xeptrb = eptrb;
-frame->Xrdepth = rdepth;
-
-/* This is where control jumps back to to effect "recursion" */
-
-HEAP_RECURSE:
-
-/* Macros make the argument variables come from the current frame */
-
-#define eptr frame->Xeptr
-#define ecode frame->Xecode
-#define mstart frame->Xmstart
-#define offset_top frame->Xoffset_top
-#define eptrb frame->Xeptrb
-#define rdepth frame->Xrdepth
-
-/* Ditto for the local variables */
-
-#ifdef SUPPORT_UTF
-#define charptr frame->Xcharptr
-#endif
-#define callpat frame->Xcallpat
-#define codelink frame->Xcodelink
-#define data frame->Xdata
-#define next frame->Xnext
-#define pp frame->Xpp
-#define prev frame->Xprev
-#define saved_eptr frame->Xsaved_eptr
-
-#define new_recursive frame->Xnew_recursive
-
-#define cur_is_word frame->Xcur_is_word
-#define condition frame->Xcondition
-#define prev_is_word frame->Xprev_is_word
-
-#ifdef SUPPORT_UCP
-#define prop_type frame->Xprop_type
-#define prop_value frame->Xprop_value
-#define prop_fail_result frame->Xprop_fail_result
-#define oclength frame->Xoclength
-#define occhars frame->Xocchars
-#endif
-
-#define ctype frame->Xctype
-#define fc frame->Xfc
-#define fi frame->Xfi
-#define length frame->Xlength
-#define max frame->Xmax
-#define min frame->Xmin
-#define number frame->Xnumber
-#define offset frame->Xoffset
-#define op frame->Xop
-#define save_capture_last frame->Xsave_capture_last
-#define save_offset1 frame->Xsave_offset1
-#define save_offset2 frame->Xsave_offset2
-#define save_offset3 frame->Xsave_offset3
-#define stacksave frame->Xstacksave
-
-#define newptrb frame->Xnewptrb
-
-/* When recursion is being used, local variables are allocated on the stack and
-get preserved during recursion in the normal way. In this environment, fi and
-i, and fc and c, can be the same variables. */
-
-#else /* NO_RECURSE not defined */
-#define fi i
-#define fc c
-
-/* Many of the following variables are used only in small blocks of the code.
-My normal style of coding would have declared them within each of those blocks.
-However, in order to accommodate the version of this code that uses an external
-"stack" implemented on the heap, it is easier to declare them all here, so the
-declarations can be cut out in a block. The only declarations within blocks
-below are for variables that do not have to be preserved over a recursive call
-to RMATCH(). */
-
-#ifdef SUPPORT_UTF
-const pcre_uchar *charptr;
-#endif
-const pcre_uchar *callpat;
-const pcre_uchar *data;
-const pcre_uchar *next;
-PCRE_PUCHAR pp;
-const pcre_uchar *prev;
-PCRE_PUCHAR saved_eptr;
-
-recursion_info new_recursive;
-
-BOOL cur_is_word;
-BOOL condition;
-BOOL prev_is_word;
-
-#ifdef SUPPORT_UCP
-int prop_type;
-unsigned int prop_value;
-int prop_fail_result;
-int oclength;
-pcre_uchar occhars[6];
-#endif
-
-int codelink;
-int ctype;
-int length;
-int max;
-int min;
-unsigned int number;
-int offset;
-unsigned int op;
-pcre_int32 save_capture_last;
-int save_offset1, save_offset2, save_offset3;
-int stacksave[REC_STACK_SAVE_MAX];
-
-eptrblock newptrb;
-
-/* There is a special fudge for calling match() in a way that causes it to
-measure the size of its basic stack frame when the stack is being used for
-recursion. The second argument (ecode) being NULL triggers this behaviour. It
-cannot normally ever be NULL. The return is the negated value of the frame
-size. */
-
-if (ecode == NULL)
- {
- if (rdepth == 0)
- return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1);
- else
- {
- int len = (char *)&rdepth - (char *)eptr;
- return (len > 0)? -len : len;
- }
- }
-#endif /* NO_RECURSE */
-
-/* To save space on the stack and in the heap frame, I have doubled up on some
-of the local variables that are used only in localised parts of the code, but
-still need to be preserved over recursive calls of match(). These macros define
-the alternative names that are used. */
-
-#define allow_zero cur_is_word
-#define cbegroup condition
-#define code_offset codelink
-#define condassert condition
-#define matched_once prev_is_word
-#define foc number
-#define save_mark data
-
-/* These statements are here to stop the compiler complaining about unitialized
-variables. */
-
-#ifdef SUPPORT_UCP
-prop_value = 0;
-prop_fail_result = 0;
-#endif
-
-
-/* This label is used for tail recursion, which is used in a few cases even
-when NO_RECURSE is not defined, in order to reduce the amount of stack that is
-used. Thanks to Ian Taylor for noticing this possibility and sending the
-original patch. */
-
-TAIL_RECURSE:
-
-/* OK, now we can get on with the real code of the function. Recursive calls
-are specified by the macro RMATCH and RRETURN is used to return. When
-NO_RECURSE is *not* defined, these just turn into a recursive call to match()
-and a "return", respectively (possibly with some debugging if PCRE_DEBUG is
-defined). However, RMATCH isn't like a function call because it's quite a
-complicated macro. It has to be used in one particular way. This shouldn't,
-however, impact performance when true recursion is being used. */
-
-#ifdef SUPPORT_UTF
-utf = md->utf; /* Local copy of the flag */
-#else
-utf = FALSE;
-#endif
-
-/* First check that we haven't called match() too many times, or that we
-haven't exceeded the recursive call limit. */
-
-if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT);
-if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT);
-
-/* At the start of a group with an unlimited repeat that may match an empty
-string, the variable md->match_function_type is set to MATCH_CBEGROUP. It is
-done this way to save having to use another function argument, which would take
-up space on the stack. See also MATCH_CONDASSERT below.
-
-When MATCH_CBEGROUP is set, add the current subject pointer to the chain of
-such remembered pointers, to be checked when we hit the closing ket, in order
-to break infinite loops that match no characters. When match() is called in
-other circumstances, don't add to the chain. The MATCH_CBEGROUP feature must
-NOT be used with tail recursion, because the memory block that is used is on
-the stack, so a new one may be required for each match(). */
-
-if (md->match_function_type == MATCH_CBEGROUP)
- {
- newptrb.epb_saved_eptr = eptr;
- newptrb.epb_prev = eptrb;
- eptrb = &newptrb;
- md->match_function_type = 0;
- }
-
-/* Now start processing the opcodes. */
-
-for (;;)
- {
- minimize = possessive = FALSE;
- op = *ecode;
-
- switch(op)
- {
- case OP_MARK:
- md->nomatch_mark = ecode + 2;
- md->mark = NULL; /* In case previously set by assertion */
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
- eptrb, RM55);
- if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
- md->mark == NULL) md->mark = ecode + 2;
-
- /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
- argument, and we must check whether that argument matches this MARK's
- argument. It is passed back in md->start_match_ptr (an overloading of that
- variable). If it does match, we reset that variable to the current subject
- position and return MATCH_SKIP. Otherwise, pass back the return code
- unaltered. */
-
- else if (rrc == MATCH_SKIP_ARG &&
- STRCMP_UC_UC_TEST(ecode + 2, md->start_match_ptr) == 0)
- {
- md->start_match_ptr = eptr;
- RRETURN(MATCH_SKIP);
- }
- RRETURN(rrc);
-
- case OP_FAIL:
- RRETURN(MATCH_NOMATCH);
-
- case OP_COMMIT:
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM52);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- RRETURN(MATCH_COMMIT);
-
- case OP_PRUNE:
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM51);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- RRETURN(MATCH_PRUNE);
-
- case OP_PRUNE_ARG:
- md->nomatch_mark = ecode + 2;
- md->mark = NULL; /* In case previously set by assertion */
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
- eptrb, RM56);
- if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
- md->mark == NULL) md->mark = ecode + 2;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- RRETURN(MATCH_PRUNE);
-
- case OP_SKIP:
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM53);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->start_match_ptr = eptr; /* Pass back current position */
- RRETURN(MATCH_SKIP);
-
- /* Note that, for Perl compatibility, SKIP with an argument does NOT set
- nomatch_mark. When a pattern match ends with a SKIP_ARG for which there was
- not a matching mark, we have to re-run the match, ignoring the SKIP_ARG
- that failed and any that precede it (either they also failed, or were not
- triggered). To do this, we maintain a count of executed SKIP_ARGs. If a
- SKIP_ARG gets to top level, the match is re-run with md->ignore_skip_arg
- set to the count of the one that failed. */
-
- case OP_SKIP_ARG:
- md->skip_arg_count++;
- if (md->skip_arg_count <= md->ignore_skip_arg)
- {
- ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
- break;
- }
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
- eptrb, RM57);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-
- /* Pass back the current skip name by overloading md->start_match_ptr and
- returning the special MATCH_SKIP_ARG return code. This will either be
- caught by a matching MARK, or get to the top, where it causes a rematch
- with md->ignore_skip_arg set to the value of md->skip_arg_count. */
-
- md->start_match_ptr = ecode + 2;
- RRETURN(MATCH_SKIP_ARG);
-
- /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that
- the branch in which it occurs can be determined. Overload the start of
- match pointer to do this. */
-
- case OP_THEN:
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM54);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->start_match_ptr = ecode;
- RRETURN(MATCH_THEN);
-
- case OP_THEN_ARG:
- md->nomatch_mark = ecode + 2;
- md->mark = NULL; /* In case previously set by assertion */
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
- md, eptrb, RM58);
- if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
- md->mark == NULL) md->mark = ecode + 2;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->start_match_ptr = ecode;
- RRETURN(MATCH_THEN);
-
- /* Handle an atomic group that does not contain any capturing parentheses.
- This can be handled like an assertion. Prior to 8.13, all atomic groups
- were handled this way. In 8.13, the code was changed as below for ONCE, so
- that backups pass through the group and thereby reset captured values.
- However, this uses a lot more stack, so in 8.20, atomic groups that do not
- contain any captures generate OP_ONCE_NC, which can be handled in the old,
- less stack intensive way.
-
- Check the alternative branches in turn - the matching won't pass the KET
- for this kind of subpattern. If any one branch matches, we carry on as at
- the end of a normal bracket, leaving the subject pointer, but resetting
- the start-of-match value in case it was changed by \K. */
-
- case OP_ONCE_NC:
- prev = ecode;
- saved_eptr = eptr;
- save_mark = md->mark;
- do
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);
- if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */
- {
- mstart = md->start_match_ptr;
- break;
- }
- if (rrc == MATCH_THEN)
- {
- next = ecode + GET(ecode,1);
- if (md->start_match_ptr < next &&
- (*ecode == OP_ALT || *next == OP_ALT))
- rrc = MATCH_NOMATCH;
- }
-
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode += GET(ecode,1);
- md->mark = save_mark;
- }
- while (*ecode == OP_ALT);
-
- /* If hit the end of the group (which could be repeated), fail */
-
- if (*ecode != OP_ONCE_NC && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
-
- /* Continue as from after the group, updating the offsets high water
- mark, since extracts may have been taken. */
-
- do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
-
- offset_top = md->end_offset_top;
- eptr = md->end_match_ptr;
-
- /* For a non-repeating ket, just continue at this level. This also
- happens for a repeating ket if no characters were matched in the group.
- This is the forcible breaking of infinite loops as implemented in Perl
- 5.005. */
-
- if (*ecode == OP_KET || eptr == saved_eptr)
- {
- ecode += 1+LINK_SIZE;
- break;
- }
-
- /* The repeating kets try the rest of the pattern or restart from the
- preceding bracket, in the appropriate order. The second "call" of match()
- uses tail recursion, to avoid using another stack frame. */
-
- if (*ecode == OP_KETRMIN)
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM65);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode = prev;
- goto TAIL_RECURSE;
- }
- else /* OP_KETRMAX */
- {
- RMATCH(eptr, prev, offset_top, md, eptrb, RM66);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode += 1 + LINK_SIZE;
- goto TAIL_RECURSE;
- }
- /* Control never gets here */
-
- /* Handle a capturing bracket, other than those that are possessive with an
- unlimited repeat. If there is space in the offset vector, save the current
- subject position in the working slot at the top of the vector. We mustn't
- change the current values of the data slot, because they may be set from a
- previous iteration of this group, and be referred to by a reference inside
- the group. A failure to match might occur after the group has succeeded,
- if something later on doesn't match. For this reason, we need to restore
- the working value and also the values of the final offsets, in case they
- were set by a previous iteration of the same bracket.
-
- If there isn't enough space in the offset vector, treat this as if it were
- a non-capturing bracket. Don't worry about setting the flag for the error
- case here; that is handled in the code for KET. */
-
- case OP_CBRA:
- case OP_SCBRA:
- number = GET2(ecode, 1+LINK_SIZE);
- offset = number << 1;
-
-#ifdef PCRE_DEBUG
- printf("start bracket %d\n", number);
- printf("subject=");
- pchars(eptr, 16, TRUE, md);
- printf("\n");
-#endif
-
- if (offset < md->offset_max)
- {
- save_offset1 = md->offset_vector[offset];
- save_offset2 = md->offset_vector[offset+1];
- save_offset3 = md->offset_vector[md->offset_end - number];
- save_capture_last = md->capture_last;
- save_mark = md->mark;
-
- DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
- md->offset_vector[md->offset_end - number] =
- (int)(eptr - md->start_subject);
-
- for (;;)
- {
- if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM1);
- if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */
-
- /* If we backed up to a THEN, check whether it is within the current
- branch by comparing the address of the THEN that is passed back with
- the end of the branch. If it is within the current branch, and the
- branch is one of two or more alternatives (it either starts or ends
- with OP_ALT), we have reached the limit of THEN's action, so convert
- the return code to NOMATCH, which will cause normal backtracking to
- happen from now on. Otherwise, THEN is passed back to an outer
- alternative. This implements Perl's treatment of parenthesized groups,
- where a group not containing | does not affect the current alternative,
- that is, (X) is NOT the same as (X|(*F)). */
-
- if (rrc == MATCH_THEN)
- {
- next = ecode + GET(ecode,1);
- if (md->start_match_ptr < next &&
- (*ecode == OP_ALT || *next == OP_ALT))
- rrc = MATCH_NOMATCH;
- }
-
- /* Anything other than NOMATCH is passed back. */
-
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->capture_last = save_capture_last;
- ecode += GET(ecode, 1);
- md->mark = save_mark;
- if (*ecode != OP_ALT) break;
- }
-
- DPRINTF(("bracket %d failed\n", number));
- md->offset_vector[offset] = save_offset1;
- md->offset_vector[offset+1] = save_offset2;
- md->offset_vector[md->offset_end - number] = save_offset3;
-
- /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */
-
- RRETURN(rrc);
- }
-
- /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
- as a non-capturing bracket. */
-
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
-
- DPRINTF(("insufficient capture room: treat as non-capturing\n"));
-
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
-
- /* Non-capturing or atomic group, except for possessive with unlimited
- repeat and ONCE group with no captures. Loop for all the alternatives.
-
- When we get to the final alternative within the brackets, we used to return
- the result of a recursive call to match() whatever happened so it was
- possible to reduce stack usage by turning this into a tail recursion,
- except in the case of a possibly empty group. However, now that there is
- the possiblity of (*THEN) occurring in the final alternative, this
- optimization is no longer always possible.
-
- We can optimize if we know there are no (*THEN)s in the pattern; at present
- this is the best that can be done.
-
- MATCH_ONCE is returned when the end of an atomic group is successfully
- reached, but subsequent matching fails. It passes back up the tree (causing
- captured values to be reset) until the original atomic group level is
- reached. This is tested by comparing md->once_target with the start of the
- group. At this point, the return is converted into MATCH_NOMATCH so that
- previous backup points can be taken. */
-
- case OP_ONCE:
- case OP_BRA:
- case OP_SBRA:
- DPRINTF(("start non-capturing bracket\n"));
-
- for (;;)
- {
- if (op >= OP_SBRA || op == OP_ONCE)
- md->match_function_type = MATCH_CBEGROUP;
-
- /* If this is not a possibly empty group, and there are no (*THEN)s in
- the pattern, and this is the final alternative, optimize as described
- above. */
-
- else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
- {
- ecode += PRIV(OP_lengths)[*ecode];
- goto TAIL_RECURSE;
- }
-
- /* In all other cases, we have to make another call to match(). */
-
- save_mark = md->mark;
- save_capture_last = md->capture_last;
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
- RM2);
-
- /* See comment in the code for capturing groups above about handling
- THEN. */
-
- if (rrc == MATCH_THEN)
- {
- next = ecode + GET(ecode,1);
- if (md->start_match_ptr < next &&
- (*ecode == OP_ALT || *next == OP_ALT))
- rrc = MATCH_NOMATCH;
- }
-
- if (rrc != MATCH_NOMATCH)
- {
- if (rrc == MATCH_ONCE)
- {
- const pcre_uchar *scode = ecode;
- if (*scode != OP_ONCE) /* If not at start, find it */
- {
- while (*scode == OP_ALT) scode += GET(scode, 1);
- scode -= GET(scode, 1);
- }
- if (md->once_target == scode) rrc = MATCH_NOMATCH;
- }
- RRETURN(rrc);
- }
- ecode += GET(ecode, 1);
- md->mark = save_mark;
- if (*ecode != OP_ALT) break;
- md->capture_last = save_capture_last;
- }
-
- RRETURN(MATCH_NOMATCH);
-
- /* Handle possessive capturing brackets with an unlimited repeat. We come
- here from BRAZERO with allow_zero set TRUE. The offset_vector values are
- handled similarly to the normal case above. However, the matching is
- different. The end of these brackets will always be OP_KETRPOS, which
- returns MATCH_KETRPOS without going further in the pattern. By this means
- we can handle the group by iteration rather than recursion, thereby
- reducing the amount of stack needed. */
-
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- allow_zero = FALSE;
-
- POSSESSIVE_CAPTURE:
- number = GET2(ecode, 1+LINK_SIZE);
- offset = number << 1;
-
-#ifdef PCRE_DEBUG
- printf("start possessive bracket %d\n", number);
- printf("subject=");
- pchars(eptr, 16, TRUE, md);
- printf("\n");
-#endif
-
- if (offset < md->offset_max)
- {
- matched_once = FALSE;
- code_offset = (int)(ecode - md->start_code);
-
- save_offset1 = md->offset_vector[offset];
- save_offset2 = md->offset_vector[offset+1];
- save_offset3 = md->offset_vector[md->offset_end - number];
- save_capture_last = md->capture_last;
-
- DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
-
- /* Each time round the loop, save the current subject position for use
- when the group matches. For MATCH_MATCH, the group has matched, so we
- restart it with a new subject starting position, remembering that we had
- at least one match. For MATCH_NOMATCH, carry on with the alternatives, as
- usual. If we haven't matched any alternatives in any iteration, check to
- see if a previous iteration matched. If so, the group has matched;
- continue from afterwards. Otherwise it has failed; restore the previous
- capture values before returning NOMATCH. */
-
- for (;;)
- {
- md->offset_vector[md->offset_end - number] =
- (int)(eptr - md->start_subject);
- if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM63);
- if (rrc == MATCH_KETRPOS)
- {
- offset_top = md->end_offset_top;
- eptr = md->end_match_ptr;
- ecode = md->start_code + code_offset;
- save_capture_last = md->capture_last;
- matched_once = TRUE;
- continue;
- }
-
- /* See comment in the code for capturing groups above about handling
- THEN. */
-
- if (rrc == MATCH_THEN)
- {
- next = ecode + GET(ecode,1);
- if (md->start_match_ptr < next &&
- (*ecode == OP_ALT || *next == OP_ALT))
- rrc = MATCH_NOMATCH;
- }
-
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->capture_last = save_capture_last;
- ecode += GET(ecode, 1);
- if (*ecode != OP_ALT) break;
- }
-
- if (!matched_once)
- {
- md->offset_vector[offset] = save_offset1;
- md->offset_vector[offset+1] = save_offset2;
- md->offset_vector[md->offset_end - number] = save_offset3;
- }
-
- if (allow_zero || matched_once)
- {
- ecode += 1 + LINK_SIZE;
- break;
- }
-
- RRETURN(MATCH_NOMATCH);
- }
-
- /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
- as a non-capturing bracket. */
-
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
-
- DPRINTF(("insufficient capture room: treat as non-capturing\n"));
-
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
- /* VVVVVVVVVVVVVVVVVVVVVVVVV */
-
- /* Non-capturing possessive bracket with unlimited repeat. We come here
- from BRAZERO with allow_zero = TRUE. The code is similar to the above,
- without the capturing complication. It is written out separately for speed
- and cleanliness. */
-
- case OP_BRAPOS:
- case OP_SBRAPOS:
- allow_zero = FALSE;
-
- POSSESSIVE_NON_CAPTURE:
- matched_once = FALSE;
- code_offset = (int)(ecode - md->start_code);
- save_capture_last = md->capture_last;
-
- for (;;)
- {
- if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
- RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
- eptrb, RM48);
- if (rrc == MATCH_KETRPOS)
- {
- offset_top = md->end_offset_top;
- eptr = md->end_match_ptr;
- ecode = md->start_code + code_offset;
- matched_once = TRUE;
- continue;
- }
-
- /* See comment in the code for capturing groups above about handling
- THEN. */
-
- if (rrc == MATCH_THEN)
- {
- next = ecode + GET(ecode,1);
- if (md->start_match_ptr < next &&
- (*ecode == OP_ALT || *next == OP_ALT))
- rrc = MATCH_NOMATCH;
- }
-
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode += GET(ecode, 1);
- if (*ecode != OP_ALT) break;
- md->capture_last = save_capture_last;
- }
-
- if (matched_once || allow_zero)
- {
- ecode += 1 + LINK_SIZE;
- break;
- }
- RRETURN(MATCH_NOMATCH);
-
- /* Control never reaches here. */
-
- /* Conditional group: compilation checked that there are no more than
- two branches. If the condition is false, skipping the first branch takes us
- past the end if there is only one branch, but that's OK because that is
- exactly what going to the ket would do. */
-
- case OP_COND:
- case OP_SCOND:
- codelink = GET(ecode, 1);
-
- /* Because of the way auto-callout works during compile, a callout item is
- inserted between OP_COND and an assertion condition. */
-
- if (ecode[LINK_SIZE+1] == OP_CALLOUT)
- {
- if (PUBL(callout) != NULL)
- {
- PUBL(callout_block) cb;
- cb.version = 2; /* Version 1 of the callout block */
- cb.callout_number = ecode[LINK_SIZE+2];
- cb.offset_vector = md->offset_vector;
-#if defined COMPILE_PCRE8
- cb.subject = (PCRE_SPTR)md->start_subject;
-#elif defined COMPILE_PCRE16
- cb.subject = (PCRE_SPTR16)md->start_subject;
-#elif defined COMPILE_PCRE32
- cb.subject = (PCRE_SPTR32)md->start_subject;
-#endif
- cb.subject_length = (int)(md->end_subject - md->start_subject);
- cb.start_match = (int)(mstart - md->start_subject);
- cb.current_position = (int)(eptr - md->start_subject);
- cb.pattern_position = GET(ecode, LINK_SIZE + 3);
- cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
- cb.capture_top = offset_top/2;
- cb.capture_last = md->capture_last & CAPLMASK;
- /* Internal change requires this for API compatibility. */
- if (cb.capture_last == 0) cb.capture_last = -1;
- cb.callout_data = md->callout_data;
- cb.mark = md->nomatch_mark;
- if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
- if (rrc < 0) RRETURN(rrc);
- }
- ecode += PRIV(OP_lengths)[OP_CALLOUT];
- codelink -= PRIV(OP_lengths)[OP_CALLOUT];
- }
-
- condcode = ecode[LINK_SIZE+1];
-
- /* Now see what the actual condition is */
-
- if (condcode == OP_RREF || condcode == OP_NRREF) /* Recursion test */
- {
- if (md->recursive == NULL) /* Not recursing => FALSE */
- {
- condition = FALSE;
- ecode += GET(ecode, 1);
- }
- else
- {
- unsigned int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/
- condition = (recno == RREF_ANY || recno == md->recursive->group_num);
-
- /* If the test is for recursion into a specific subpattern, and it is
- false, but the test was set up by name, scan the table to see if the
- name refers to any other numbers, and test them. The condition is true
- if any one is set. */
-
- if (!condition && condcode == OP_NRREF)
- {
- pcre_uchar *slotA = md->name_table;
- for (i = 0; i < md->name_count; i++)
- {
- if (GET2(slotA, 0) == recno) break;
- slotA += md->name_entry_size;
- }
-
- /* Found a name for the number - there can be only one; duplicate
- names for different numbers are allowed, but not vice versa. First
- scan down for duplicates. */
-
- if (i < md->name_count)
- {
- pcre_uchar *slotB = slotA;
- while (slotB > md->name_table)
- {
- slotB -= md->name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- condition = GET2(slotB, 0) == md->recursive->group_num;
- if (condition) break;
- }
- else break;
- }
-
- /* Scan up for duplicates */
-
- if (!condition)
- {
- slotB = slotA;
- for (i++; i < md->name_count; i++)
- {
- slotB += md->name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- condition = GET2(slotB, 0) == md->recursive->group_num;
- if (condition) break;
- }
- else break;
- }
- }
- }
- }
-
- /* Chose branch according to the condition */
-
- ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
- }
- }
-
- else if (condcode == OP_CREF || condcode == OP_NCREF) /* Group used test */
- {
- offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */
- condition = offset < offset_top && md->offset_vector[offset] >= 0;
-
- /* If the numbered capture is unset, but the reference was by name,
- scan the table to see if the name refers to any other numbers, and test
- them. The condition is true if any one is set. This is tediously similar
- to the code above, but not close enough to try to amalgamate. */
-
- if (!condition && condcode == OP_NCREF)
- {
- unsigned int refno = offset >> 1;
- pcre_uchar *slotA = md->name_table;
-
- for (i = 0; i < md->name_count; i++)
- {
- if (GET2(slotA, 0) == refno) break;
- slotA += md->name_entry_size;
- }
-
- /* Found a name for the number - there can be only one; duplicate names
- for different numbers are allowed, but not vice versa. First scan down
- for duplicates. */
-
- if (i < md->name_count)
- {
- pcre_uchar *slotB = slotA;
- while (slotB > md->name_table)
- {
- slotB -= md->name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- offset = GET2(slotB, 0) << 1;
- condition = offset < offset_top &&
- md->offset_vector[offset] >= 0;
- if (condition) break;
- }
- else break;
- }
-
- /* Scan up for duplicates */
-
- if (!condition)
- {
- slotB = slotA;
- for (i++; i < md->name_count; i++)
- {
- slotB += md->name_entry_size;
- if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
- {
- offset = GET2(slotB, 0) << 1;
- condition = offset < offset_top &&
- md->offset_vector[offset] >= 0;
- if (condition) break;
- }
- else break;
- }
- }
- }
- }
-
- /* Chose branch according to the condition */
-
- ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
- }
-
- else if (condcode == OP_DEF) /* DEFINE - always false */
- {
- condition = FALSE;
- ecode += GET(ecode, 1);
- }
-
- /* The condition is an assertion. Call match() to evaluate it - setting
- md->match_function_type to MATCH_CONDASSERT causes it to stop at the end of
- an assertion. */
-
- else
- {
- md->match_function_type = MATCH_CONDASSERT;
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM3);
- if (rrc == MATCH_MATCH)
- {
- if (md->end_offset_top > offset_top)
- offset_top = md->end_offset_top; /* Captures may have happened */
- condition = TRUE;
- ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
- while (*ecode == OP_ALT) ecode += GET(ecode, 1);
- }
-
- /* PCRE doesn't allow the effect of (*THEN) to escape beyond an
- assertion; it is therefore treated as NOMATCH. */
-
- else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
- {
- RRETURN(rrc); /* Need braces because of following else */
- }
- else
- {
- condition = FALSE;
- ecode += codelink;
- }
- }
-
- /* We are now at the branch that is to be obeyed. As there is only one, can
- use tail recursion to avoid using another stack frame, except when there is
- unlimited repeat of a possibly empty group. In the latter case, a recursive
- call to match() is always required, unless the second alternative doesn't
- exist, in which case we can just plough on. Note that, for compatibility
- with Perl, the | in a conditional group is NOT treated as creating two
- alternatives. If a THEN is encountered in the branch, it propagates out to
- the enclosing alternative (unless nested in a deeper set of alternatives,
- of course). */
-
- if (condition || *ecode == OP_ALT)
- {
- if (op != OP_SCOND)
- {
- ecode += 1 + LINK_SIZE;
- goto TAIL_RECURSE;
- }
-
- md->match_function_type = MATCH_CBEGROUP;
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49);
- RRETURN(rrc);
- }
-
- /* Condition false & no alternative; continue after the group. */
-
- else
- {
- ecode += 1 + LINK_SIZE;
- }
- break;
-
-
- /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
- to close any currently open capturing brackets. */
-
- case OP_CLOSE:
- number = GET2(ecode, 1); /* Must be less than 65536 */
- offset = number << 1;
-
-#ifdef PCRE_DEBUG
- printf("end bracket %d at *ACCEPT", number);
- printf("\n");
-#endif
-
- md->capture_last = (md->capture_last & OVFLMASK) | number;
- if (offset >= md->offset_max) md->capture_last |= OVFLBIT; else
- {
- md->offset_vector[offset] =
- md->offset_vector[md->offset_end - number];
- md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
- if (offset_top <= offset) offset_top = offset + 2;
- }
- ecode += 1 + IMM2_SIZE;
- break;
-
-
- /* End of the pattern, either real or forced. */
-
- case OP_END:
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
-
- /* If we have matched an empty string, fail if not in an assertion and not
- in a recursion if either PCRE_NOTEMPTY is set, or if PCRE_NOTEMPTY_ATSTART
- is set and we have matched at the start of the subject. In both cases,
- backtracking will then try other alternatives, if any. */
-
- if (eptr == mstart && op != OP_ASSERT_ACCEPT &&
- md->recursive == NULL &&
- (md->notempty ||
- (md->notempty_atstart &&
- mstart == md->start_subject + md->start_offset)))
- RRETURN(MATCH_NOMATCH);
-
- /* Otherwise, we have a match. */
-
- md->end_match_ptr = eptr; /* Record where we ended */
- md->end_offset_top = offset_top; /* and how many extracts were taken */
- md->start_match_ptr = mstart; /* and the start (\K can modify) */
-
- /* For some reason, the macros don't work properly if an expression is
- given as the argument to RRETURN when the heap is in use. */
-
- rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
- RRETURN(rrc);
-
- /* Assertion brackets. Check the alternative branches in turn - the
- matching won't pass the KET for an assertion. If any one branch matches,
- the assertion is true. Lookbehind assertions have an OP_REVERSE item at the
- start of each branch to move the current point backwards, so the code at
- this level is identical to the lookahead case. When the assertion is part
- of a condition, we want to return immediately afterwards. The caller of
- this incarnation of the match() function will have set MATCH_CONDASSERT in
- md->match_function type, and one of these opcodes will be the first opcode
- that is processed. We use a local variable that is preserved over calls to
- match() to remember this case. */
-
- case OP_ASSERT:
- case OP_ASSERTBACK:
- save_mark = md->mark;
- if (md->match_function_type == MATCH_CONDASSERT)
- {
- condassert = TRUE;
- md->match_function_type = 0;
- }
- else condassert = FALSE;
-
- /* Loop for each branch */
-
- do
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM4);
-
- /* A match means that the assertion is true; break out of the loop
- that matches its alternatives. */
-
- if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
- {
- mstart = md->start_match_ptr; /* In case \K reset it */
- break;
- }
-
- /* If not matched, restore the previous mark setting. */
-
- md->mark = save_mark;
-
- /* See comment in the code for capturing groups above about handling
- THEN. */
-
- if (rrc == MATCH_THEN)
- {
- next = ecode + GET(ecode,1);
- if (md->start_match_ptr < next &&
- (*ecode == OP_ALT || *next == OP_ALT))
- rrc = MATCH_NOMATCH;
- }
-
- /* Anything other than NOMATCH causes the entire assertion to fail,
- passing back the return code. This includes COMMIT, SKIP, PRUNE and an
- uncaptured THEN, which means they take their normal effect. This
- consistent approach does not always have exactly the same effect as in
- Perl. */
-
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode += GET(ecode, 1);
- }
- while (*ecode == OP_ALT); /* Continue for next alternative */
-
- /* If we have tried all the alternative branches, the assertion has
- failed. If not, we broke out after a match. */
-
- if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
-
- /* If checking an assertion for a condition, return MATCH_MATCH. */
-
- if (condassert) RRETURN(MATCH_MATCH);
-
- /* Continue from after a successful assertion, updating the offsets high
- water mark, since extracts may have been taken during the assertion. */
-
- do ecode += GET(ecode,1); while (*ecode == OP_ALT);
- ecode += 1 + LINK_SIZE;
- offset_top = md->end_offset_top;
- continue;
-
- /* Negative assertion: all branches must fail to match for the assertion to
- succeed. */
-
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK_NOT:
- save_mark = md->mark;
- if (md->match_function_type == MATCH_CONDASSERT)
- {
- condassert = TRUE;
- md->match_function_type = 0;
- }
- else condassert = FALSE;
-
- /* Loop for each alternative branch. */
-
- do
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
- md->mark = save_mark; /* Always restore the mark setting */
-
- switch(rrc)
- {
- case MATCH_MATCH: /* A successful match means */
- case MATCH_ACCEPT: /* the assertion has failed. */
- RRETURN(MATCH_NOMATCH);
-
- case MATCH_NOMATCH: /* Carry on with next branch */
- break;
-
- /* See comment in the code for capturing groups above about handling
- THEN. */
-
- case MATCH_THEN:
- next = ecode + GET(ecode,1);
- if (md->start_match_ptr < next &&
- (*ecode == OP_ALT || *next == OP_ALT))
- {
- rrc = MATCH_NOMATCH;
- break;
- }
- /* Otherwise fall through. */
-
- /* COMMIT, SKIP, PRUNE, and an uncaptured THEN cause the whole
- assertion to fail to match, without considering any more alternatives.
- Failing to match means the assertion is true. This is a consistent
- approach, but does not always have the same effect as in Perl. */
-
- case MATCH_COMMIT:
- case MATCH_SKIP:
- case MATCH_SKIP_ARG:
- case MATCH_PRUNE:
- do ecode += GET(ecode,1); while (*ecode == OP_ALT);
- goto NEG_ASSERT_TRUE; /* Break out of alternation loop */
-
- /* Anything else is an error */
-
- default:
- RRETURN(rrc);
- }
-
- /* Continue with next branch */
-
- ecode += GET(ecode,1);
- }
- while (*ecode == OP_ALT);
-
- /* All branches in the assertion failed to match. */
-
- NEG_ASSERT_TRUE:
- if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */
- ecode += 1 + LINK_SIZE; /* Continue with current branch */
- continue;
-
- /* Move the subject pointer back. This occurs only at the start of
- each branch of a lookbehind assertion. If we are too close to the start to
- move back, this match function fails. When working with UTF-8 we move
- back a number of characters, not bytes. */
-
- case OP_REVERSE:
-#ifdef SUPPORT_UTF
- if (utf)
- {
- i = GET(ecode, 1);
- while (i-- > 0)
- {
- eptr--;
- if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
- BACKCHAR(eptr);
- }
- }
- else
-#endif
-
- /* No UTF-8 support, or not in UTF-8 mode: count is byte count */
-
- {
- eptr -= GET(ecode, 1);
- if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
- }
-
- /* Save the earliest consulted character, then skip to next op code */
-
- if (eptr < md->start_used_ptr) md->start_used_ptr = eptr;
- ecode += 1 + LINK_SIZE;
- break;
-
- /* The callout item calls an external function, if one is provided, passing
- details of the match so far. This is mainly for debugging, though the
- function is able to force a failure. */
-
- case OP_CALLOUT:
- if (PUBL(callout) != NULL)
- {
- PUBL(callout_block) cb;
- cb.version = 2; /* Version 1 of the callout block */
- cb.callout_number = ecode[1];
- cb.offset_vector = md->offset_vector;
-#if defined COMPILE_PCRE8
- cb.subject = (PCRE_SPTR)md->start_subject;
-#elif defined COMPILE_PCRE16
- cb.subject = (PCRE_SPTR16)md->start_subject;
-#elif defined COMPILE_PCRE32
- cb.subject = (PCRE_SPTR32)md->start_subject;
-#endif
- cb.subject_length = (int)(md->end_subject - md->start_subject);
- cb.start_match = (int)(mstart - md->start_subject);
- cb.current_position = (int)(eptr - md->start_subject);
- cb.pattern_position = GET(ecode, 2);
- cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
- cb.capture_top = offset_top/2;
- cb.capture_last = md->capture_last & CAPLMASK;
- /* Internal change requires this for API compatibility. */
- if (cb.capture_last == 0) cb.capture_last = -1;
- cb.callout_data = md->callout_data;
- cb.mark = md->nomatch_mark;
- if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
- if (rrc < 0) RRETURN(rrc);
- }
- ecode += 2 + 2*LINK_SIZE;
- break;
-
- /* Recursion either matches the current regex, or some subexpression. The
- offset data is the offset to the starting bracket from the start of the
- whole pattern. (This is so that it works from duplicated subpatterns.)
-
- The state of the capturing groups is preserved over recursion, and
- re-instated afterwards. We don't know how many are started and not yet
- finished (offset_top records the completed total) so we just have to save
- all the potential data. There may be up to 65535 such values, which is too
- large to put on the stack, but using malloc for small numbers seems
- expensive. As a compromise, the stack is used when there are no more than
- REC_STACK_SAVE_MAX values to store; otherwise malloc is used.
-
- There are also other values that have to be saved. We use a chained
- sequence of blocks that actually live on the stack. Thanks to Robin Houston
- for the original version of this logic. It has, however, been hacked around
- a lot, so he is not to blame for the current way it works. */
-
- case OP_RECURSE:
- {
- recursion_info *ri;
- unsigned int recno;
-
- callpat = md->start_code + GET(ecode, 1);
- recno = (callpat == md->start_code)? 0 :
- GET2(callpat, 1 + LINK_SIZE);
-
- /* Check for repeating a recursion without advancing the subject pointer.
- This should catch convoluted mutual recursions. (Some simple cases are
- caught at compile time.) */
-
- for (ri = md->recursive; ri != NULL; ri = ri->prevrec)
- if (recno == ri->group_num && eptr == ri->subject_position)
- RRETURN(PCRE_ERROR_RECURSELOOP);
-
- /* Add to "recursing stack" */
-
- new_recursive.group_num = recno;
- new_recursive.saved_capture_last = md->capture_last;
- new_recursive.subject_position = eptr;
- new_recursive.prevrec = md->recursive;
- md->recursive = &new_recursive;
-
- /* Where to continue from afterwards */
-
- ecode += 1 + LINK_SIZE;
-
- /* Now save the offset data */
-
- new_recursive.saved_max = md->offset_end;
- if (new_recursive.saved_max <= REC_STACK_SAVE_MAX)
- new_recursive.offset_save = stacksave;
- else
- {
- new_recursive.offset_save =
- (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int));
- if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
- }
- memcpy(new_recursive.offset_save, md->offset_vector,
- new_recursive.saved_max * sizeof(int));
-
- /* OK, now we can do the recursion. After processing each alternative,
- restore the offset data and the last captured value. If there were nested
- recursions, md->recursive might be changed, so reset it before looping.
- */
-
- DPRINTF(("Recursing into group %d\n", new_recursive.group_num));
- cbegroup = (*callpat >= OP_SBRA);
- do
- {
- if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
- RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
- md, eptrb, RM6);
- memcpy(md->offset_vector, new_recursive.offset_save,
- new_recursive.saved_max * sizeof(int));
- md->capture_last = new_recursive.saved_capture_last;
- md->recursive = new_recursive.prevrec;
- if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
- {
- DPRINTF(("Recursion matched\n"));
- if (new_recursive.offset_save != stacksave)
- (PUBL(free))(new_recursive.offset_save);
-
- /* Set where we got to in the subject, and reset the start in case
- it was changed by \K. This *is* propagated back out of a recursion,
- for Perl compatibility. */
-
- eptr = md->end_match_ptr;
- mstart = md->start_match_ptr;
- goto RECURSION_MATCHED; /* Exit loop; end processing */
- }
-
- /* PCRE does not allow THEN, SKIP, PRUNE or COMMIT to escape beyond a
- recursion; they cause a NOMATCH for the entire recursion. These codes
- are defined in a range that can be tested for. */
-
- if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX)
- RRETURN(MATCH_NOMATCH);
-
- /* Any return code other than NOMATCH is an error. */
-
- if (rrc != MATCH_NOMATCH)
- {
- DPRINTF(("Recursion gave error %d\n", rrc));
- if (new_recursive.offset_save != stacksave)
- (PUBL(free))(new_recursive.offset_save);
- RRETURN(rrc);
- }
-
- md->recursive = &new_recursive;
- callpat += GET(callpat, 1);
- }
- while (*callpat == OP_ALT);
-
- DPRINTF(("Recursion didn't match\n"));
- md->recursive = new_recursive.prevrec;
- if (new_recursive.offset_save != stacksave)
- (PUBL(free))(new_recursive.offset_save);
- RRETURN(MATCH_NOMATCH);
- }
-
- RECURSION_MATCHED:
- break;
-
- /* An alternation is the end of a branch; scan along to find the end of the
- bracketed group and go to there. */
-
- case OP_ALT:
- do ecode += GET(ecode,1); while (*ecode == OP_ALT);
- break;
-
- /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
- indicating that it may occur zero times. It may repeat infinitely, or not
- at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets
- with fixed upper repeat limits are compiled as a number of copies, with the
- optional ones preceded by BRAZERO or BRAMINZERO. */
-
- case OP_BRAZERO:
- next = ecode + 1;
- RMATCH(eptr, next, offset_top, md, eptrb, RM10);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- do next += GET(next, 1); while (*next == OP_ALT);
- ecode = next + 1 + LINK_SIZE;
- break;
-
- case OP_BRAMINZERO:
- next = ecode + 1;
- do next += GET(next, 1); while (*next == OP_ALT);
- RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, eptrb, RM11);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- ecode++;
- break;
-
- case OP_SKIPZERO:
- next = ecode+1;
- do next += GET(next,1); while (*next == OP_ALT);
- ecode = next + 1 + LINK_SIZE;
- break;
-
- /* BRAPOSZERO occurs before a possessive bracket group. Don't do anything
- here; just jump to the group, with allow_zero set TRUE. */
-
- case OP_BRAPOSZERO:
- op = *(++ecode);
- allow_zero = TRUE;
- if (op == OP_CBRAPOS || op == OP_SCBRAPOS) goto POSSESSIVE_CAPTURE;
- goto POSSESSIVE_NON_CAPTURE;
-
- /* End of a group, repeated or non-repeating. */
-
- case OP_KET:
- case OP_KETRMIN:
- case OP_KETRMAX:
- case OP_KETRPOS:
- prev = ecode - GET(ecode, 1);
-
- /* If this was a group that remembered the subject start, in order to break
- infinite repeats of empty string matches, retrieve the subject start from
- the chain. Otherwise, set it NULL. */
-
- if (*prev >= OP_SBRA || *prev == OP_ONCE)
- {
- saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */
- eptrb = eptrb->epb_prev; /* Backup to previous group */
- }
- else saved_eptr = NULL;
-
- /* If we are at the end of an assertion group or a non-capturing atomic
- group, stop matching and return MATCH_MATCH, but record the current high
- water mark for use by positive assertions. We also need to record the match
- start in case it was changed by \K. */
-
- if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) ||
- *prev == OP_ONCE_NC)
- {
- md->end_match_ptr = eptr; /* For ONCE_NC */
- md->end_offset_top = offset_top;
- md->start_match_ptr = mstart;
- RRETURN(MATCH_MATCH); /* Sets md->mark */
- }
-
- /* For capturing groups we have to check the group number back at the start
- and if necessary complete handling an extraction by setting the offsets and
- bumping the high water mark. Whole-pattern recursion is coded as a recurse
- into group 0, so it won't be picked up here. Instead, we catch it when the
- OP_END is reached. Other recursion is handled here. We just have to record
- the current subject position and start match pointer and give a MATCH
- return. */
-
- if (*prev == OP_CBRA || *prev == OP_SCBRA ||
- *prev == OP_CBRAPOS || *prev == OP_SCBRAPOS)
- {
- number = GET2(prev, 1+LINK_SIZE);
- offset = number << 1;
-
-#ifdef PCRE_DEBUG
- printf("end bracket %d", number);
- printf("\n");
-#endif
-
- /* Handle a recursively called group. */
-
- if (md->recursive != NULL && md->recursive->group_num == number)
- {
- md->end_match_ptr = eptr;
- md->start_match_ptr = mstart;
- RRETURN(MATCH_MATCH);
- }
-
- /* Deal with capturing */
-
- md->capture_last = (md->capture_last & OVFLMASK) | number;
- if (offset >= md->offset_max) md->capture_last |= OVFLBIT; else
- {
- /* If offset is greater than offset_top, it means that we are
- "skipping" a capturing group, and that group's offsets must be marked
- unset. In earlier versions of PCRE, all the offsets were unset at the
- start of matching, but this doesn't work because atomic groups and
- assertions can cause a value to be set that should later be unset.
- Example: matching /(?>(a))b|(a)c/ against "ac". This sets group 1 as
- part of the atomic group, but this is not on the final matching path,
- so must be unset when 2 is set. (If there is no group 2, there is no
- problem, because offset_top will then be 2, indicating no capture.) */
-
- if (offset > offset_top)
- {
- register int *iptr = md->offset_vector + offset_top;
- register int *iend = md->offset_vector + offset;
- while (iptr < iend) *iptr++ = -1;
- }
-
- /* Now make the extraction */
-
- md->offset_vector[offset] =
- md->offset_vector[md->offset_end - number];
- md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
- if (offset_top <= offset) offset_top = offset + 2;
- }
- }
-
- /* For an ordinary non-repeating ket, just continue at this level. This
- also happens for a repeating ket if no characters were matched in the
- group. This is the forcible breaking of infinite loops as implemented in
- Perl 5.005. For a non-repeating atomic group that includes captures,
- establish a backup point by processing the rest of the pattern at a lower
- level. If this results in a NOMATCH return, pass MATCH_ONCE back to the
- original OP_ONCE level, thereby bypassing intermediate backup points, but
- resetting any captures that happened along the way. */
-
- if (*ecode == OP_KET || eptr == saved_eptr)
- {
- if (*prev == OP_ONCE)
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM12);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */
- RRETURN(MATCH_ONCE);
- }
- ecode += 1 + LINK_SIZE; /* Carry on at this level */
- break;
- }
-
- /* OP_KETRPOS is a possessive repeating ket. Remember the current position,
- and return the MATCH_KETRPOS. This makes it possible to do the repeats one
- at a time from the outer level, thus saving stack. */
-
- if (*ecode == OP_KETRPOS)
- {
- md->end_match_ptr = eptr;
- md->end_offset_top = offset_top;
- RRETURN(MATCH_KETRPOS);
- }
-
- /* The normal repeating kets try the rest of the pattern or restart from
- the preceding bracket, in the appropriate order. In the second case, we can
- use tail recursion to avoid using another stack frame, unless we have an
- an atomic group or an unlimited repeat of a group that can match an empty
- string. */
-
- if (*ecode == OP_KETRMIN)
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM7);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (*prev == OP_ONCE)
- {
- RMATCH(eptr, prev, offset_top, md, eptrb, RM8);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */
- RRETURN(MATCH_ONCE);
- }
- if (*prev >= OP_SBRA) /* Could match an empty string */
- {
- RMATCH(eptr, prev, offset_top, md, eptrb, RM50);
- RRETURN(rrc);
- }
- ecode = prev;
- goto TAIL_RECURSE;
- }
- else /* OP_KETRMAX */
- {
- RMATCH(eptr, prev, offset_top, md, eptrb, RM13);
- if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (*prev == OP_ONCE)
- {
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM9);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- md->once_target = prev;
- RRETURN(MATCH_ONCE);
- }
- ecode += 1 + LINK_SIZE;
- goto TAIL_RECURSE;
- }
- /* Control never gets here */
-
- /* Not multiline mode: start of subject assertion, unless notbol. */
-
- case OP_CIRC:
- if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
-
- /* Start of subject assertion */
-
- case OP_SOD:
- if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- /* Multiline mode: start of subject unless notbol, or after any newline. */
-
- case OP_CIRCM:
- if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
- if (eptr != md->start_subject &&
- (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- /* Start of match assertion */
-
- case OP_SOM:
- if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- /* Reset the start of match point */
-
- case OP_SET_SOM:
- mstart = eptr;
- ecode++;
- break;
-
- /* Multiline mode: assert before any newline, or before end of subject
- unless noteol is set. */
-
- case OP_DOLLM:
- if (eptr < md->end_subject)
- {
- if (!IS_NEWLINE(eptr))
- {
- if (md->partial != 0 &&
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- RRETURN(MATCH_NOMATCH);
- }
- }
- else
- {
- if (md->noteol) RRETURN(MATCH_NOMATCH);
- SCHECK_PARTIAL();
- }
- ecode++;
- break;
-
- /* Not multiline mode: assert before a terminating newline or before end of
- subject unless noteol is set. */
-
- case OP_DOLL:
- if (md->noteol) RRETURN(MATCH_NOMATCH);
- if (!md->endonly) goto ASSERT_NL_OR_EOS;
-
- /* ... else fall through for endonly */
-
- /* End of subject assertion (\z) */
-
- case OP_EOD:
- if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);
- SCHECK_PARTIAL();
- ecode++;
- break;
-
- /* End of subject or ending \n assertion (\Z) */
-
- case OP_EODN:
- ASSERT_NL_OR_EOS:
- if (eptr < md->end_subject &&
- (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
- {
- if (md->partial != 0 &&
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- RRETURN(MATCH_NOMATCH);
- }
-
- /* Either at end of string or \n before end. */
-
- SCHECK_PARTIAL();
- ecode++;
- break;
-
- /* Word boundary assertions */
-
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- {
-
- /* Find out if the previous and current characters are "word" characters.
- It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to
- be "non-word" characters. Remember the earliest consulted character for
- partial matching. */
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- /* Get status of previous character */
-
- if (eptr == md->start_subject) prev_is_word = FALSE; else
- {
- PCRE_PUCHAR lastptr = eptr - 1;
- BACKCHAR(lastptr);
- if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
- GETCHAR(c, lastptr);
-#ifdef SUPPORT_UCP
- if (md->use_ucp)
- {
- if (c == '_') prev_is_word = TRUE; else
- {
- int cat = UCD_CATEGORY(c);
- prev_is_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif
- prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
- }
-
- /* Get status of next character */
-
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- cur_is_word = FALSE;
- }
- else
- {
- GETCHAR(c, eptr);
-#ifdef SUPPORT_UCP
- if (md->use_ucp)
- {
- if (c == '_') cur_is_word = TRUE; else
- {
- int cat = UCD_CATEGORY(c);
- cur_is_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif
- cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
- }
- }
- else
-#endif
-
- /* Not in UTF-8 mode, but we may still have PCRE_UCP set, and for
- consistency with the behaviour of \w we do use it in this case. */
-
- {
- /* Get status of previous character */
-
- if (eptr == md->start_subject) prev_is_word = FALSE; else
- {
- if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;
-#ifdef SUPPORT_UCP
- if (md->use_ucp)
- {
- c = eptr[-1];
- if (c == '_') prev_is_word = TRUE; else
- {
- int cat = UCD_CATEGORY(c);
- prev_is_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif
- prev_is_word = MAX_255(eptr[-1])
- && ((md->ctypes[eptr[-1]] & ctype_word) != 0);
- }
-
- /* Get status of next character */
-
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- cur_is_word = FALSE;
- }
- else
-#ifdef SUPPORT_UCP
- if (md->use_ucp)
- {
- c = *eptr;
- if (c == '_') cur_is_word = TRUE; else
- {
- int cat = UCD_CATEGORY(c);
- cur_is_word = (cat == ucp_L || cat == ucp_N);
- }
- }
- else
-#endif
- cur_is_word = MAX_255(*eptr)
- && ((md->ctypes[*eptr] & ctype_word) != 0);
- }
-
- /* Now see if the situation is what we want */
-
- if ((*ecode++ == OP_WORD_BOUNDARY)?
- cur_is_word == prev_is_word : cur_is_word != prev_is_word)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- /* Match any single character type except newline; have to take care with
- CRLF newlines and partial matching. */
-
- case OP_ANY:
- if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
- if (md->partial != 0 &&
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
-
- /* Fall through */
-
- /* Match any single character whatsoever. */
-
- case OP_ALLANY:
- if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */
- { /* not be updated before SCHECK_PARTIAL. */
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr++;
-#ifdef SUPPORT_UTF
- if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
-#endif
- ecode++;
- break;
-
- /* Match a single byte, even in UTF-8 mode. This opcode really does match
- any byte, even newline, independent of the setting of PCRE_DOTALL. */
-
- case OP_ANYBYTE:
- if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */
- { /* not be updated before SCHECK_PARTIAL. */
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr++;
- ecode++;
- break;
-
- case OP_NOT_DIGIT:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- c < 256 &&
-#endif
- (md->ctypes[c] & ctype_digit) != 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_DIGIT:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- c > 255 ||
-#endif
- (md->ctypes[c] & ctype_digit) == 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_NOT_WHITESPACE:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- c < 256 &&
-#endif
- (md->ctypes[c] & ctype_space) != 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_WHITESPACE:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- c > 255 ||
-#endif
- (md->ctypes[c] & ctype_space) == 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_NOT_WORDCHAR:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- c < 256 &&
-#endif
- (md->ctypes[c] & ctype_word) != 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_WORDCHAR:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (
-#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
- c > 255 ||
-#endif
- (md->ctypes[c] & ctype_word) == 0
- )
- RRETURN(MATCH_NOMATCH);
- ecode++;
- break;
-
- case OP_ANYNL:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
-
- case CHAR_CR:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- }
- else if (RAWUCHARTEST(eptr) == CHAR_LF) eptr++;
- break;
-
- case CHAR_LF:
- break;
-
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#ifndef EBCDIC
- case 0x2028:
- case 0x2029:
-#endif /* Not EBCDIC */
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- ecode++;
- break;
-
- case OP_NOT_HSPACE:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */
- default: break;
- }
- ecode++;
- break;
-
- case OP_HSPACE:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- HSPACE_CASES: break; /* Byte and multibyte cases */
- default: RRETURN(MATCH_NOMATCH);
- }
- ecode++;
- break;
-
- case OP_NOT_VSPACE:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- VSPACE_CASES: RRETURN(MATCH_NOMATCH);
- default: break;
- }
- ecode++;
- break;
-
- case OP_VSPACE:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- switch(c)
- {
- VSPACE_CASES: break;
- default: RRETURN(MATCH_NOMATCH);
- }
- ecode++;
- break;
-
-#ifdef SUPPORT_UCP
- /* Check the next character by Unicode property. We will get here only
- if the support is in the binary; otherwise a compile-time error occurs. */
-
- case OP_PROP:
- case OP_NOTPROP:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- {
- const pcre_uint32 *cp;
- const ucd_record *prop = GET_UCD(c);
-
- switch(ecode[1])
- {
- case PT_ANY:
- if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_LAMP:
- if ((prop->chartype == ucp_Lu ||
- prop->chartype == ucp_Ll ||
- prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_GC:
- if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_PC:
- if ((ecode[2] != prop->chartype) == (op == OP_PROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_SC:
- if ((ecode[2] != prop->script) == (op == OP_PROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- /* These are specials */
-
- case PT_ALNUM:
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_SPACE: /* Perl space */
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
- == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_PXSPACE: /* POSIX space */
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR)
- == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_WORD:
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
- c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- case PT_CLIST:
- cp = PRIV(ucd_caseless_sets) + ecode[2];
- for (;;)
- {
- if (c < *cp)
- { if (op == OP_PROP) { RRETURN(MATCH_NOMATCH); } else break; }
- if (c == *cp++)
- { if (op == OP_PROP) break; else { RRETURN(MATCH_NOMATCH); } }
- }
- break;
-
- case PT_UCNC:
- if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
- c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
- c >= 0xe000) == (op == OP_NOTPROP))
- RRETURN(MATCH_NOMATCH);
- break;
-
- /* This should never occur */
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
-
- ecode += 3;
- }
- break;
-
- /* Match an extended Unicode sequence. We will get here only if the support
- is in the binary; otherwise a compile-time error occurs. */
-
- case OP_EXTUNI:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- else
- {
- int lgb, rgb;
- GETCHARINCTEST(c, eptr);
- lgb = UCD_GRAPHBREAK(c);
- while (eptr < md->end_subject)
- {
- int len = 1;
- if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
- rgb = UCD_GRAPHBREAK(c);
- if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
- lgb = rgb;
- eptr += len;
- }
- }
- CHECK_PARTIAL();
- ecode++;
- break;
-#endif /* SUPPORT_UCP */
-
-
- /* Match a back reference, possibly repeatedly. Look past the end of the
- item to see if there is repeat information following. The code is similar
- to that for character classes, but repeated for efficiency. Then obey
- similar code to character type repeats - written out again for speed.
- However, if the referenced string is the empty string, always treat
- it as matched, any number of times (otherwise there could be infinite
- loops). */
-
- case OP_REF:
- case OP_REFI:
- caseless = op == OP_REFI;
- offset = GET2(ecode, 1) << 1; /* Doubled ref number */
- ecode += 1 + IMM2_SIZE;
-
- /* If the reference is unset, there are two possibilities:
-
- (a) In the default, Perl-compatible state, set the length negative;
- this ensures that every attempt at a match fails. We can't just fail
- here, because of the possibility of quantifiers with zero minima.
-
- (b) If the JavaScript compatibility flag is set, set the length to zero
- so that the back reference matches an empty string.
-
- Otherwise, set the length to the length of what was matched by the
- referenced subpattern. */
-
- if (offset >= offset_top || md->offset_vector[offset] < 0)
- length = (md->jscript_compat)? 0 : -1;
- else
- length = md->offset_vector[offset+1] - md->offset_vector[offset];
-
- /* Set up for repetition, or handle the non-repeated case */
-
- switch (*ecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- minimize = (*ecode == OP_CRMINRANGE);
- min = GET2(ecode, 1);
- max = GET2(ecode, 1 + IMM2_SIZE);
- if (max == 0) max = INT_MAX;
- ecode += 1 + 2 * IMM2_SIZE;
- break;
-
- default: /* No repeat follows */
- if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
- {
- if (length == -2) eptr = md->end_subject; /* Partial match */
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr += length;
- continue; /* With the main loop */
- }
-
- /* Handle repeated back references. If the length of the reference is
- zero, just continue with the main loop. If the length is negative, it
- means the reference is unset in non-Java-compatible mode. If the minimum is
- zero, we can continue at the same level without recursion. For any other
- minimum, carrying on will result in NOMATCH. */
-
- if (length == 0) continue;
- if (length < 0 && min == 0) continue;
-
- /* First, ensure the minimum number of matches are present. We get back
- the length of the reference string explicitly rather than passing the
- address of eptr, so that eptr can be a register variable. */
-
- for (i = 1; i <= min; i++)
- {
- int slength;
- if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
- {
- if (slength == -2) eptr = md->end_subject; /* Partial match */
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr += slength;
- }
-
- /* If min = max, continue at the same level without recursion.
- They are not both allowed to be zero. */
-
- if (min == max) continue;
-
- /* If minimizing, keep trying and advancing the pointer */
-
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- int slength;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
- {
- if (slength == -2) eptr = md->end_subject; /* Partial match */
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr += slength;
- }
- /* Control never gets here */
- }
-
- /* If maximizing, find the longest string and work backwards */
-
- else
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- int slength;
- if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
- {
- /* Can't use CHECK_PARTIAL because we don't want to update eptr in
- the soft partial matching case. */
-
- if (slength == -2 && md->partial != 0 &&
- md->end_subject > md->start_used_ptr)
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- break;
- }
- eptr += slength;
- }
-
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr -= length;
- }
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- /* Match a bit-mapped character class, possibly repeatedly. This op code is
- used when all the characters in the class have values in the range 0-255,
- and either the matching is caseful, or the characters are in the range
- 0-127 when UTF-8 processing is enabled. The only difference between
- OP_CLASS and OP_NCLASS occurs when a data character outside the range is
- encountered.
-
- First, look past the end of the item to see if there is repeat information
- following. Then obey similar code to character type repeats - written out
- again for speed. */
-
- case OP_NCLASS:
- case OP_CLASS:
- {
- /* The data variable is saved across frames, so the byte map needs to
- be stored there. */
-#define BYTE_MAP ((pcre_uint8 *)data)
- data = ecode + 1; /* Save for matching */
- ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
-
- switch (*ecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- minimize = (*ecode == OP_CRMINRANGE);
- min = GET2(ecode, 1);
- max = GET2(ecode, 1 + IMM2_SIZE);
- if (max == 0) max = INT_MAX;
- ecode += 1 + 2 * IMM2_SIZE;
- break;
-
- default: /* No repeat follows */
- min = max = 1;
- break;
- }
-
- /* First, ensure the minimum number of matches are present. */
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- if (c > 255)
- {
- if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
- if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- c = *eptr++;
-#ifndef COMPILE_PCRE8
- if (c > 255)
- {
- if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
-#endif
- if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
-
- /* If max == min we can continue with the main loop without the
- need to recurse. */
-
- if (min == max) continue;
-
- /* If minimizing, keep testing the rest of the expression and advancing
- the pointer while it matches the class. */
-
- if (minimize)
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- if (c > 255)
- {
- if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
- if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- c = *eptr++;
-#ifndef COMPILE_PCRE8
- if (c > 255)
- {
- if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
- }
- else
-#endif
- if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
- }
-
- /* If maximizing, find the longest possible run, then work backwards. */
-
- else
- {
- pp = eptr;
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c > 255)
- {
- if (op == OP_CLASS) break;
- }
- else
- if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
- eptr += len;
- }
- for (;;)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM18);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
- BACKCHAR(eptr);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- c = *eptr;
-#ifndef COMPILE_PCRE8
- if (c > 255)
- {
- if (op == OP_CLASS) break;
- }
- else
-#endif
- if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
- eptr++;
- }
- while (eptr >= pp)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM19);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- }
- }
-
- RRETURN(MATCH_NOMATCH);
- }
-#undef BYTE_MAP
- }
- /* Control never gets here */
-
-
- /* Match an extended character class. This opcode is encountered only
- when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
- mode, because Unicode properties are supported in non-UTF-8 mode. */
-
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- case OP_XCLASS:
- {
- data = ecode + 1 + LINK_SIZE; /* Save for matching */
- ecode += GET(ecode, 1); /* Advance past the item */
-
- switch (*ecode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- minimize = (*ecode == OP_CRMINRANGE);
- min = GET2(ecode, 1);
- max = GET2(ecode, 1 + IMM2_SIZE);
- if (max == 0) max = INT_MAX;
- ecode += 1 + 2 * IMM2_SIZE;
- break;
-
- default: /* No repeat follows */
- min = max = 1;
- break;
- }
-
- /* First, ensure the minimum number of matches are present. */
-
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
- }
-
- /* If max == min we can continue with the main loop without the
- need to recurse. */
-
- if (min == max) continue;
-
- /* If minimizing, keep testing the rest of the expression and advancing
- the pointer while it matches the class. */
-
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
-
- /* If maximizing, find the longest possible run, then work backwards. */
-
- else
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
-#ifdef SUPPORT_UTF
- GETCHARLENTEST(c, eptr, len);
-#else
- c = *eptr;
-#endif
- if (!PRIV(xclass)(c, data, utf)) break;
- eptr += len;
- }
- for(;;)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
-#ifdef SUPPORT_UTF
- if (utf) BACKCHAR(eptr);
-#endif
- }
- RRETURN(MATCH_NOMATCH);
- }
-
- /* Control never gets here */
- }
-#endif /* End of XCLASS */
-
- /* Match a single character, casefully */
-
- case OP_CHAR:
-#ifdef SUPPORT_UTF
- if (utf)
- {
- length = 1;
- ecode++;
- GETCHARLEN(fc, ecode, length);
- if (length > md->end_subject - eptr)
- {
- CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */
- RRETURN(MATCH_NOMATCH);
- }
- while (length-- > 0) if (*ecode++ != RAWUCHARINC(eptr)) RRETURN(MATCH_NOMATCH);
- }
- else
-#endif
- /* Not UTF mode */
- {
- if (md->end_subject - eptr < 1)
- {
- SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */
- RRETURN(MATCH_NOMATCH);
- }
- if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
- ecode += 2;
- }
- break;
-
- /* Match a single character, caselessly. If we are at the end of the
- subject, give up immediately. */
-
- case OP_CHARI:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- length = 1;
- ecode++;
- GETCHARLEN(fc, ecode, length);
-
- /* If the pattern character's value is < 128, we have only one byte, and
- we know that its other case must also be one byte long, so we can use the
- fast lookup table. We know that there is at least one byte left in the
- subject. */
-
- if (fc < 128)
- {
- pcre_uint32 cc = RAWUCHAR(eptr);
- if (md->lcc[fc] != TABLE_GET(cc, md->lcc, cc)) RRETURN(MATCH_NOMATCH);
- ecode++;
- eptr++;
- }
-
- /* Otherwise we must pick up the subject character. Note that we cannot
- use the value of "length" to check for sufficient bytes left, because the
- other case of the character may have more or fewer bytes. */
-
- else
- {
- pcre_uint32 dc;
- GETCHARINC(dc, eptr);
- ecode += length;
-
- /* If we have Unicode property support, we can use it to test the other
- case of the character, if there is one. */
-
- if (fc != dc)
- {
-#ifdef SUPPORT_UCP
- if (dc != UCD_OTHERCASE(fc))
-#endif
- RRETURN(MATCH_NOMATCH);
- }
- }
- }
- else
-#endif /* SUPPORT_UTF */
-
- /* Not UTF mode */
- {
- if (TABLE_GET(ecode[1], md->lcc, ecode[1])
- != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
- eptr++;
- ecode += 2;
- }
- break;
-
- /* Match a single character repeatedly. */
-
- case OP_EXACT:
- case OP_EXACTI:
- min = max = GET2(ecode, 1);
- ecode += 1 + IMM2_SIZE;
- goto REPEATCHAR;
-
- case OP_POSUPTO:
- case OP_POSUPTOI:
- possessive = TRUE;
- /* Fall through */
-
- case OP_UPTO:
- case OP_UPTOI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- min = 0;
- max = GET2(ecode, 1);
- minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
- ecode += 1 + IMM2_SIZE;
- goto REPEATCHAR;
-
- case OP_POSSTAR:
- case OP_POSSTARI:
- possessive = TRUE;
- min = 0;
- max = INT_MAX;
- ecode++;
- goto REPEATCHAR;
-
- case OP_POSPLUS:
- case OP_POSPLUSI:
- possessive = TRUE;
- min = 1;
- max = INT_MAX;
- ecode++;
- goto REPEATCHAR;
-
- case OP_POSQUERY:
- case OP_POSQUERYI:
- possessive = TRUE;
- min = 0;
- max = 1;
- ecode++;
- goto REPEATCHAR;
-
- case OP_STAR:
- case OP_STARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_QUERY:
- case OP_QUERYI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- c = *ecode++ - ((op < OP_STARI)? OP_STAR : OP_STARI);
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
-
- /* Common code for all repeated single-character matches. We first check
- for the minimum number of characters. If the minimum equals the maximum, we
- are done. Otherwise, if minimizing, check the rest of the pattern for a
- match; if there isn't one, advance up to the maximum, one character at a
- time.
-
- If maximizing, advance up to the maximum number of matching characters,
- until eptr is past the end of the maximum run. If possessive, we are
- then done (no backing up). Otherwise, match at this position; anything
- other than no match is immediately returned. For nomatch, back up one
- character, unless we are matching \R and the last thing matched was
- \r\n, in which case, back up two bytes. When we reach the first optional
- character position, we can save stack by doing a tail recurse.
-
- The various UTF/non-UTF and caseful/caseless cases are handled separately,
- for speed. */
-
- REPEATCHAR:
-#ifdef SUPPORT_UTF
- if (utf)
- {
- length = 1;
- charptr = ecode;
- GETCHARLEN(fc, ecode, length);
- ecode += length;
-
- /* Handle multibyte character matching specially here. There is
- support for caseless matching if UCP support is present. */
-
- if (length > 1)
- {
-#ifdef SUPPORT_UCP
- pcre_uint32 othercase;
- if (op >= OP_STARI && /* Caseless */
- (othercase = UCD_OTHERCASE(fc)) != fc)
- oclength = PRIV(ord2utf)(othercase, occhars);
- else oclength = 0;
-#endif /* SUPPORT_UCP */
-
- for (i = 1; i <= min; i++)
- {
- if (eptr <= md->end_subject - length &&
- memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
-#ifdef SUPPORT_UCP
- else if (oclength > 0 &&
- eptr <= md->end_subject - oclength &&
- memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
-#endif /* SUPPORT_UCP */
- else
- {
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- }
-
- if (min == max) continue;
-
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr <= md->end_subject - length &&
- memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
-#ifdef SUPPORT_UCP
- else if (oclength > 0 &&
- eptr <= md->end_subject - oclength &&
- memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
-#endif /* SUPPORT_UCP */
- else
- {
- CHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
- }
-
- else /* Maximize */
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- if (eptr <= md->end_subject - length &&
- memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
-#ifdef SUPPORT_UCP
- else if (oclength > 0 &&
- eptr <= md->end_subject - oclength &&
- memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
-#endif /* SUPPORT_UCP */
- else
- {
- CHECK_PARTIAL();
- break;
- }
- }
-
- if (possessive) continue; /* No backtracking */
- for(;;)
- {
- if (eptr == pp) goto TAIL_RECURSE;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
-#ifdef SUPPORT_UCP
- eptr--;
- BACKCHAR(eptr);
-#else /* without SUPPORT_UCP */
- eptr -= length;
-#endif /* SUPPORT_UCP */
- }
- }
- /* Control never gets here */
- }
-
- /* If the length of a UTF-8 character is 1, we fall through here, and
- obey the code as for non-UTF-8 characters below, though in this case the
- value of fc will always be < 128. */
- }
- else
-#endif /* SUPPORT_UTF */
- /* When not in UTF-8 mode, load a single-byte character. */
- fc = *ecode++;
-
- /* The value of fc at this point is always one character, though we may
- or may not be in UTF mode. The code is duplicated for the caseless and
- caseful cases, for speed, since matching characters is likely to be quite
- common. First, ensure the minimum number of matches are present. If min =
- max, continue at the same level without recursing. Otherwise, if
- minimizing, keep trying the rest of the expression and advancing one
- matching character if failing, up to the maximum. Alternatively, if
- maximizing, find the maximum number of characters and work backwards. */
-
- DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
- max, (char *)eptr));
-
- if (op >= OP_STARI) /* Caseless */
- {
-#ifdef COMPILE_PCRE8
- /* fc must be < 128 if UTF is enabled. */
- foc = md->fcc[fc];
-#else
-#ifdef SUPPORT_UTF
-#ifdef SUPPORT_UCP
- if (utf && fc > 127)
- foc = UCD_OTHERCASE(fc);
-#else
- if (utf && fc > 127)
- foc = fc;
-#endif /* SUPPORT_UCP */
- else
-#endif /* SUPPORT_UTF */
- foc = TABLE_GET(fc, md->fcc, fc);
-#endif /* COMPILE_PCRE8 */
-
- for (i = 1; i <= min; i++)
- {
- pcre_uint32 cc; /* Faster than pcre_uchar */
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = RAWUCHARTEST(eptr);
- if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- if (min == max) continue;
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- pcre_uint32 cc; /* Faster than pcre_uchar */
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = RAWUCHARTEST(eptr);
- if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- /* Control never gets here */
- }
- else /* Maximize */
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- pcre_uint32 cc; /* Faster than pcre_uchar */
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- cc = RAWUCHARTEST(eptr);
- if (fc != cc && foc != cc) break;
- eptr++;
- }
-
- if (possessive) continue; /* No backtracking */
- for (;;)
- {
- if (eptr == pp) goto TAIL_RECURSE;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM25);
- eptr--;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- }
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
-
- /* Caseful comparisons (includes all multi-byte characters) */
-
- else
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH);
- }
-
- if (min == max) continue;
-
- if (minimize)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
- else /* Maximize */
- {
- pp = eptr;
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (fc != RAWUCHARTEST(eptr)) break;
- eptr++;
- }
- if (possessive) continue; /* No backtracking */
- for (;;)
- {
- if (eptr == pp) goto TAIL_RECURSE;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM27);
- eptr--;
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- }
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
-
- /* Match a negated single one-byte character. The character we are
- checking can be multibyte. */
-
- case OP_NOT:
- case OP_NOTI:
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
-#ifdef SUPPORT_UTF
- if (utf)
- {
- register pcre_uint32 ch, och;
-
- ecode++;
- GETCHARINC(ch, ecode);
- GETCHARINC(c, eptr);
-
- if (op == OP_NOT)
- {
- if (ch == c) RRETURN(MATCH_NOMATCH);
- }
- else
- {
-#ifdef SUPPORT_UCP
- if (ch > 127)
- och = UCD_OTHERCASE(ch);
-#else
- if (ch > 127)
- och = ch;
-#endif /* SUPPORT_UCP */
- else
- och = TABLE_GET(ch, md->fcc, ch);
- if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- {
- register pcre_uint32 ch = ecode[1];
- c = *eptr++;
- if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))
- RRETURN(MATCH_NOMATCH);
- ecode += 2;
- }
- break;
-
- /* Match a negated single one-byte character repeatedly. This is almost a
- repeat of the code for a repeated single character, but I haven't found a
- nice way of commoning these up that doesn't require a test of the
- positive/negative option for each character match. Maybe that wouldn't add
- very much to the time taken, but character matching *is* what this is all
- about... */
-
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- min = max = GET2(ecode, 1);
- ecode += 1 + IMM2_SIZE;
- goto REPEATNOTCHAR;
-
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- min = 0;
- max = GET2(ecode, 1);
- minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
- ecode += 1 + IMM2_SIZE;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
- possessive = TRUE;
- min = 0;
- max = INT_MAX;
- ecode++;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- possessive = TRUE;
- min = 1;
- max = INT_MAX;
- ecode++;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
- possessive = TRUE;
- min = 0;
- max = 1;
- ecode++;
- goto REPEATNOTCHAR;
-
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
- possessive = TRUE;
- min = 0;
- max = GET2(ecode, 1);
- ecode += 1 + IMM2_SIZE;
- goto REPEATNOTCHAR;
-
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- c = *ecode++ - ((op >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR);
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
-
- /* Common code for all repeated single-byte matches. */
-
- REPEATNOTCHAR:
- GETCHARINCTEST(fc, ecode);
-
- /* The code is duplicated for the caseless and caseful cases, for speed,
- since matching characters is likely to be quite common. First, ensure the
- minimum number of matches are present. If min = max, continue at the same
- level without recursing. Otherwise, if minimizing, keep trying the rest of
- the expression and advancing one matching character if failing, up to the
- maximum. Alternatively, if maximizing, find the maximum number of
- characters and work backwards. */
-
- DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,
- max, (char *)eptr));
-
- if (op >= OP_NOTSTARI) /* Caseless */
- {
-#ifdef SUPPORT_UTF
-#ifdef SUPPORT_UCP
- if (utf && fc > 127)
- foc = UCD_OTHERCASE(fc);
-#else
- if (utf && fc > 127)
- foc = fc;
-#endif /* SUPPORT_UCP */
- else
-#endif /* SUPPORT_UTF */
- foc = TABLE_GET(fc, md->fcc, fc);
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- register pcre_uint32 d;
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(d, eptr);
- if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif /* SUPPORT_UTF */
- /* Not UTF mode */
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- }
-
- if (min == max) continue;
-
- if (minimize)
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- register pcre_uint32 d;
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(d, eptr);
- if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif /*SUPPORT_UTF */
- /* Not UTF mode */
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- }
- /* Control never gets here */
- }
-
- /* Maximize case */
-
- else
- {
- pp = eptr;
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- register pcre_uint32 d;
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(d, eptr, len);
- if (fc == d || (unsigned int)foc == d) break;
- eptr += len;
- }
- if (possessive) continue; /* No backtracking */
- for(;;)
- {
- if (eptr == pp) goto TAIL_RECURSE;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- BACKCHAR(eptr);
- }
- }
- else
-#endif /* SUPPORT_UTF */
- /* Not UTF mode */
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (fc == *eptr || foc == *eptr) break;
- eptr++;
- }
- if (possessive) continue; /* No backtracking */
- for (;;)
- {
- if (eptr == pp) goto TAIL_RECURSE;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM31);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- }
- }
-
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
- }
-
- /* Caseful comparisons */
-
- else
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- register pcre_uint32 d;
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(d, eptr);
- if (fc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
- }
- }
-
- if (min == max) continue;
-
- if (minimize)
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- register pcre_uint32 d;
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(d, eptr);
- if (fc == d) RRETURN(MATCH_NOMATCH);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
- }
-
- /* Maximize case */
-
- else
- {
- pp = eptr;
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- register pcre_uint32 d;
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(d, eptr, len);
- if (fc == d) break;
- eptr += len;
- }
- if (possessive) continue; /* No backtracking */
- for(;;)
- {
- if (eptr == pp) goto TAIL_RECURSE;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM34);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- BACKCHAR(eptr);
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (fc == *eptr) break;
- eptr++;
- }
- if (possessive) continue; /* No backtracking */
- for (;;)
- {
- if (eptr == pp) goto TAIL_RECURSE;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM35);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- }
- }
-
- RRETURN(MATCH_NOMATCH);
- }
- }
- /* Control never gets here */
-
- /* Match a single character type repeatedly; several different opcodes
- share code. This is very similar to the code for single characters, but we
- repeat it in the interests of efficiency. */
-
- case OP_TYPEEXACT:
- min = max = GET2(ecode, 1);
- minimize = TRUE;
- ecode += 1 + IMM2_SIZE;
- goto REPEATTYPE;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- min = 0;
- max = GET2(ecode, 1);
- minimize = *ecode == OP_TYPEMINUPTO;
- ecode += 1 + IMM2_SIZE;
- goto REPEATTYPE;
-
- case OP_TYPEPOSSTAR:
- possessive = TRUE;
- min = 0;
- max = INT_MAX;
- ecode++;
- goto REPEATTYPE;
-
- case OP_TYPEPOSPLUS:
- possessive = TRUE;
- min = 1;
- max = INT_MAX;
- ecode++;
- goto REPEATTYPE;
-
- case OP_TYPEPOSQUERY:
- possessive = TRUE;
- min = 0;
- max = 1;
- ecode++;
- goto REPEATTYPE;
-
- case OP_TYPEPOSUPTO:
- possessive = TRUE;
- min = 0;
- max = GET2(ecode, 1);
- ecode += 1 + IMM2_SIZE;
- goto REPEATTYPE;
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- c = *ecode++ - OP_TYPESTAR;
- minimize = (c & 1) != 0;
- min = rep_min[c]; /* Pick up values from tables; */
- max = rep_max[c]; /* zero for max => infinity */
- if (max == 0) max = INT_MAX;
-
- /* Common code for all repeated single character type matches. Note that
- in UTF-8 mode, '.' matches a character of any length, but for the other
- character types, the valid characters are all one-byte long. */
-
- REPEATTYPE:
- ctype = *ecode++; /* Code for the character type */
-
-#ifdef SUPPORT_UCP
- if (ctype == OP_PROP || ctype == OP_NOTPROP)
- {
- prop_fail_result = ctype == OP_NOTPROP;
- prop_type = *ecode++;
- prop_value = *ecode++;
- }
- else prop_type = -1;
-#endif
-
- /* First, ensure the minimum number of matches are present. Use inline
- code for maximizing the speed, and do the type test once at the start
- (i.e. keep it out of the loop). Separate the UTF-8 code completely as that
- is tidier. Also separate the UCP code, which can be the same for both UTF-8
- and single-bytes. */
-
- if (min > 0)
- {
-#ifdef SUPPORT_UCP
- if (prop_type >= 0)
- {
- switch(prop_type)
- {
- case PT_ANY:
- if (prop_fail_result) RRETURN(MATCH_NOMATCH);
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- }
- break;
-
- case PT_LAMP:
- for (i = 1; i <= min; i++)
- {
- int chartype;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- chartype = UCD_CHARTYPE(c);
- if ((chartype == ucp_Lu ||
- chartype == ucp_Ll ||
- chartype == ucp_Lt) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_GC:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_PC:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_SC:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_ALNUM:
- for (i = 1; i <= min; i++)
- {
- int category;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- category = UCD_CATEGORY(c);
- if ((category == ucp_L || category == ucp_N) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_SPACE: /* Perl space */
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_PXSPACE: /* POSIX space */
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_WORD:
- for (i = 1; i <= min; i++)
- {
- int category;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- category = UCD_CATEGORY(c);
- if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case PT_CLIST:
- for (i = 1; i <= min; i++)
- {
- const pcre_uint32 *cp;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- cp = PRIV(ucd_caseless_sets) + prop_value;
- for (;;)
- {
- if (c < *cp)
- { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
- if (c == *cp++)
- { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
- }
- }
- break;
-
- case PT_UCNC:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
- c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
- c >= 0xe000) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- /* This should not occur */
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
-
- /* Match extended Unicode sequences. We will get here only if the
- support is in the binary; otherwise a compile-time error occurs. */
-
- else if (ctype == OP_EXTUNI)
- {
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- else
- {
- int lgb, rgb;
- GETCHARINCTEST(c, eptr);
- lgb = UCD_GRAPHBREAK(c);
- while (eptr < md->end_subject)
- {
- int len = 1;
- if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
- rgb = UCD_GRAPHBREAK(c);
- if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
- lgb = rgb;
- eptr += len;
- }
- }
- CHECK_PARTIAL();
- }
- }
-
- else
-#endif /* SUPPORT_UCP */
-
-/* Handle all other cases when the coding is UTF-8 */
-
-#ifdef SUPPORT_UTF
- if (utf) switch(ctype)
- {
- case OP_ANY:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
- if (md->partial != 0 &&
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- RAWUCHAR(eptr) == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- break;
-
- case OP_ALLANY:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- break;
-
- case OP_ANYBYTE:
- if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
- eptr += min;
- break;
-
- case OP_ANYNL:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
-
- case CHAR_CR:
- if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++;
- break;
-
- case CHAR_LF:
- break;
-
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#ifndef EBCDIC
- case 0x2028:
- case 0x2029:
-#endif /* Not EBCDIC */
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- switch(c)
- {
- HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */
- default: break;
- }
- }
- break;
-
- case OP_HSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- switch(c)
- {
- HSPACE_CASES: break; /* Byte and multibyte cases */
- default: RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_NOT_VSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- switch(c)
- {
- VSPACE_CASES: RRETURN(MATCH_NOMATCH);
- default: break;
- }
- }
- break;
-
- case OP_VSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- switch(c)
- {
- VSPACE_CASES: break;
- default: RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINC(c, eptr);
- if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_DIGIT:
- for (i = 1; i <= min; i++)
- {
- pcre_uint32 cc;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = RAWUCHAR(eptr);
- if (cc >= 128 || (md->ctypes[cc] & ctype_digit) == 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- /* No need to skip more bytes - we know it's a 1-byte character */
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = 1; i <= min; i++)
- {
- pcre_uint32 cc;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = RAWUCHAR(eptr);
- if (cc < 128 && (md->ctypes[cc] & ctype_space) != 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- break;
-
- case OP_WHITESPACE:
- for (i = 1; i <= min; i++)
- {
- pcre_uint32 cc;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = RAWUCHAR(eptr);
- if (cc >= 128 || (md->ctypes[cc] & ctype_space) == 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- /* No need to skip more bytes - we know it's a 1-byte character */
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = 1; i <= min; i++)
- {
- pcre_uint32 cc;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = RAWUCHAR(eptr);
- if (cc < 128 && (md->ctypes[cc] & ctype_word) != 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- break;
-
- case OP_WORDCHAR:
- for (i = 1; i <= min; i++)
- {
- pcre_uint32 cc;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- cc = RAWUCHAR(eptr);
- if (cc >= 128 || (md->ctypes[cc] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- /* No need to skip more bytes - we know it's a 1-byte character */
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- } /* End switch(ctype) */
-
- else
-#endif /* SUPPORT_UTF */
-
- /* Code for the non-UTF-8 case for minimum matching of operators other
- than OP_PROP and OP_NOTPROP. */
-
- switch(ctype)
- {
- case OP_ANY:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
- if (md->partial != 0 &&
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- *eptr == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- eptr++;
- }
- break;
-
- case OP_ALLANY:
- if (eptr > md->end_subject - min)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr += min;
- break;
-
- case OP_ANYBYTE:
- if (eptr > md->end_subject - min)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- eptr += min;
- break;
-
- case OP_ANYNL:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*eptr++)
- {
- default: RRETURN(MATCH_NOMATCH);
-
- case CHAR_CR:
- if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++;
- break;
-
- case CHAR_LF:
- break;
-
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- case 0x2028:
- case 0x2029:
-#endif
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*eptr++)
- {
- default: break;
- HSPACE_BYTE_CASES:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- HSPACE_MULTIBYTE_CASES:
-#endif
- RRETURN(MATCH_NOMATCH);
- }
- }
- break;
-
- case OP_HSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*eptr++)
- {
- default: RRETURN(MATCH_NOMATCH);
- HSPACE_BYTE_CASES:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- HSPACE_MULTIBYTE_CASES:
-#endif
- break;
- }
- }
- break;
-
- case OP_NOT_VSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*eptr++)
- {
- VSPACE_BYTE_CASES:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- VSPACE_MULTIBYTE_CASES:
-#endif
- RRETURN(MATCH_NOMATCH);
- default: break;
- }
- }
- break;
-
- case OP_VSPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- switch(*eptr++)
- {
- default: RRETURN(MATCH_NOMATCH);
- VSPACE_BYTE_CASES:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- VSPACE_MULTIBYTE_CASES:
-#endif
- break;
- }
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- break;
-
- case OP_DIGIT:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- break;
-
- case OP_WHITESPACE:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- break;
-
- case OP_WORDCHAR:
- for (i = 1; i <= min; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- eptr++;
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
-
- /* If min = max, continue at the same level without recursing */
-
- if (min == max) continue;
-
- /* If minimizing, we have to test the rest of the pattern before each
- subsequent match. Again, separate the UTF-8 case for speed, and also
- separate the UCP cases. */
-
- if (minimize)
- {
-#ifdef SUPPORT_UCP
- if (prop_type >= 0)
- {
- switch(prop_type)
- {
- case PT_ANY:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if (prop_fail_result) RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_LAMP:
- for (fi = min;; fi++)
- {
- int chartype;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- chartype = UCD_CHARTYPE(c);
- if ((chartype == ucp_Lu ||
- chartype == ucp_Ll ||
- chartype == ucp_Lt) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_GC:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_PC:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_SC:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_ALNUM:
- for (fi = min;; fi++)
- {
- int category;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- category = UCD_CATEGORY(c);
- if ((category == ucp_L || category == ucp_N) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_SPACE: /* Perl space */
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_PXSPACE: /* POSIX space */
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_WORD:
- for (fi = min;; fi++)
- {
- int category;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- category = UCD_CATEGORY(c);
- if ((category == ucp_L ||
- category == ucp_N ||
- c == CHAR_UNDERSCORE)
- == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- case PT_CLIST:
- for (fi = min;; fi++)
- {
- const pcre_uint32 *cp;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM67);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- cp = PRIV(ucd_caseless_sets) + prop_value;
- for (;;)
- {
- if (c < *cp)
- { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
- if (c == *cp++)
- { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
- }
- }
- /* Control never gets here */
-
- case PT_UCNC:
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM68);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- GETCHARINCTEST(c, eptr);
- if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
- c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
- c >= 0xe000) == prop_fail_result)
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- /* This should never occur */
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
-
- /* Match extended Unicode sequences. We will get here only if the
- support is in the binary; otherwise a compile-time error occurs. */
-
- else if (ctype == OP_EXTUNI)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM41);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- else
- {
- int lgb, rgb;
- GETCHARINCTEST(c, eptr);
- lgb = UCD_GRAPHBREAK(c);
- while (eptr < md->end_subject)
- {
- int len = 1;
- if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
- rgb = UCD_GRAPHBREAK(c);
- if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
- lgb = rgb;
- eptr += len;
- }
- }
- CHECK_PARTIAL();
- }
- }
- else
-#endif /* SUPPORT_UCP */
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM42);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (ctype == OP_ANY && IS_NEWLINE(eptr))
- RRETURN(MATCH_NOMATCH);
- GETCHARINC(c, eptr);
- switch(ctype)
- {
- case OP_ANY: /* This is the non-NL case */
- if (md->partial != 0 && /* Take care with CRLF partial */
- eptr >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- break;
-
- case OP_ALLANY:
- case OP_ANYBYTE:
- break;
-
- case OP_ANYNL:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case CHAR_CR:
- if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++;
- break;
-
- case CHAR_LF:
- break;
-
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#ifndef EBCDIC
- case 0x2028:
- case 0x2029:
-#endif /* Not EBCDIC */
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- break;
-
- case OP_NOT_HSPACE:
- switch(c)
- {
- HSPACE_CASES: RRETURN(MATCH_NOMATCH);
- default: break;
- }
- break;
-
- case OP_HSPACE:
- switch(c)
- {
- HSPACE_CASES: break;
- default: RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_NOT_VSPACE:
- switch(c)
- {
- VSPACE_CASES: RRETURN(MATCH_NOMATCH);
- default: break;
- }
- break;
-
- case OP_VSPACE:
- switch(c)
- {
- VSPACE_CASES: break;
- default: RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_NOT_DIGIT:
- if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_DIGIT:
- if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WHITESPACE:
- if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WHITESPACE:
- if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WORDCHAR:
- if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WORDCHAR:
- if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
- RRETURN(MATCH_NOMATCH);
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
- }
- else
-#endif
- /* Not UTF mode */
- {
- for (fi = min;; fi++)
- {
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM43);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (fi >= max) RRETURN(MATCH_NOMATCH);
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
- }
- if (ctype == OP_ANY && IS_NEWLINE(eptr))
- RRETURN(MATCH_NOMATCH);
- c = *eptr++;
- switch(ctype)
- {
- case OP_ANY: /* This is the non-NL case */
- if (md->partial != 0 && /* Take care with CRLF partial */
- eptr >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- c == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- break;
-
- case OP_ALLANY:
- case OP_ANYBYTE:
- break;
-
- case OP_ANYNL:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- case CHAR_CR:
- if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++;
- break;
-
- case CHAR_LF:
- break;
-
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_NEL:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- case 0x2028:
- case 0x2029:
-#endif
- if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
- break;
- }
- break;
-
- case OP_NOT_HSPACE:
- switch(c)
- {
- default: break;
- HSPACE_BYTE_CASES:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- HSPACE_MULTIBYTE_CASES:
-#endif
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_HSPACE:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- HSPACE_BYTE_CASES:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- HSPACE_MULTIBYTE_CASES:
-#endif
- break;
- }
- break;
-
- case OP_NOT_VSPACE:
- switch(c)
- {
- default: break;
- VSPACE_BYTE_CASES:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- VSPACE_MULTIBYTE_CASES:
-#endif
- RRETURN(MATCH_NOMATCH);
- }
- break;
-
- case OP_VSPACE:
- switch(c)
- {
- default: RRETURN(MATCH_NOMATCH);
- VSPACE_BYTE_CASES:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- VSPACE_MULTIBYTE_CASES:
-#endif
- break;
- }
- break;
-
- case OP_NOT_DIGIT:
- if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_DIGIT:
- if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WHITESPACE:
- if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WHITESPACE:
- if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_NOT_WORDCHAR:
- if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
- break;
-
- case OP_WORDCHAR:
- if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
- }
- }
- /* Control never gets here */
- }
-
- /* If maximizing, it is worth using inline code for speed, doing the type
- test once at the start (i.e. keep it out of the loop). Again, keep the
- UTF-8 and UCP stuff separate. */
-
- else
- {
- pp = eptr; /* Remember where we started */
-
-#ifdef SUPPORT_UCP
- if (prop_type >= 0)
- {
- switch(prop_type)
- {
- case PT_ANY:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- if (prop_fail_result) break;
- eptr+= len;
- }
- break;
-
- case PT_LAMP:
- for (i = min; i < max; i++)
- {
- int chartype;
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- chartype = UCD_CHARTYPE(c);
- if ((chartype == ucp_Lu ||
- chartype == ucp_Ll ||
- chartype == ucp_Lt) == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
-
- case PT_GC:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) break;
- eptr+= len;
- }
- break;
-
- case PT_PC:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) break;
- eptr+= len;
- }
- break;
-
- case PT_SC:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) break;
- eptr+= len;
- }
- break;
-
- case PT_ALNUM:
- for (i = min; i < max; i++)
- {
- int category;
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- category = UCD_CATEGORY(c);
- if ((category == ucp_L || category == ucp_N) == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
-
- case PT_SPACE: /* Perl space */
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
-
- case PT_PXSPACE: /* POSIX space */
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
- c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
- == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
-
- case PT_WORD:
- for (i = min; i < max; i++)
- {
- int category;
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- category = UCD_CATEGORY(c);
- if ((category == ucp_L || category == ucp_N ||
- c == CHAR_UNDERSCORE) == prop_fail_result)
- break;
- eptr+= len;
- }
- break;
-
- case PT_CLIST:
- for (i = min; i < max; i++)
- {
- const pcre_uint32 *cp;
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- cp = PRIV(ucd_caseless_sets) + prop_value;
- for (;;)
- {
- if (c < *cp)
- { if (prop_fail_result) break; else goto GOT_MAX; }
- if (c == *cp++)
- { if (prop_fail_result) goto GOT_MAX; else break; }
- }
- eptr += len;
- }
- GOT_MAX:
- break;
-
- case PT_UCNC:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLENTEST(c, eptr, len);
- if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
- c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
- c >= 0xe000) == prop_fail_result)
- break;
- eptr += len;
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
-
- /* eptr is now past the end of the maximum run */
-
- if (possessive) continue; /* No backtracking */
- for(;;)
- {
- if (eptr == pp) goto TAIL_RECURSE;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- if (utf) BACKCHAR(eptr);
- }
- }
-
- /* Match extended Unicode sequences. We will get here only if the
- support is in the binary; otherwise a compile-time error occurs. */
-
- else if (ctype == OP_EXTUNI)
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- else
- {
- int lgb, rgb;
- GETCHARINCTEST(c, eptr);
- lgb = UCD_GRAPHBREAK(c);
- while (eptr < md->end_subject)
- {
- int len = 1;
- if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
- rgb = UCD_GRAPHBREAK(c);
- if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
- lgb = rgb;
- eptr += len;
- }
- }
- CHECK_PARTIAL();
- }
-
- /* eptr is now past the end of the maximum run */
-
- if (possessive) continue; /* No backtracking */
- for(;;)
- {
- if (eptr == pp) goto TAIL_RECURSE;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM45);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- for (;;) /* Move back over one extended */
- {
- if (!utf) c = *eptr; else
- {
- BACKCHAR(eptr);
- GETCHAR(c, eptr);
- }
- if (UCD_CATEGORY(c) != ucp_M) break;
- eptr--;
- }
- }
- }
-
- else
-#endif /* SUPPORT_UCP */
-
-#ifdef SUPPORT_UTF
- if (utf)
- {
- switch(ctype)
- {
- case OP_ANY:
- if (max < INT_MAX)
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (IS_NEWLINE(eptr)) break;
- if (md->partial != 0 && /* Take care with CRLF partial */
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- RAWUCHAR(eptr) == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- }
-
- /* Handle unlimited UTF-8 repeat */
-
- else
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (IS_NEWLINE(eptr)) break;
- if (md->partial != 0 && /* Take care with CRLF partial */
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- RAWUCHAR(eptr) == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- }
- break;
-
- case OP_ALLANY:
- if (max < INT_MAX)
- {
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- eptr++;
- ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
- }
- }
- else
- {
- eptr = md->end_subject; /* Unlimited UTF-8 repeat */
- SCHECK_PARTIAL();
- }
- break;
-
- /* The byte case is the same as non-UTF8 */
-
- case OP_ANYBYTE:
- c = max - min;
- if (c > (unsigned int)(md->end_subject - eptr))
- {
- eptr = md->end_subject;
- SCHECK_PARTIAL();
- }
- else eptr += c;
- break;
-
- case OP_ANYNL:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c == CHAR_CR)
- {
- if (++eptr >= md->end_subject) break;
- if (RAWUCHAR(eptr) == CHAR_LF) eptr++;
- }
- else
- {
- if (c != CHAR_LF &&
- (md->bsr_anycrlf ||
- (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL
-#ifndef EBCDIC
- && c != 0x2028 && c != 0x2029
-#endif /* Not EBCDIC */
- )))
- break;
- eptr += len;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- case OP_HSPACE:
- for (i = min; i < max; i++)
- {
- BOOL gotspace;
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- switch(c)
- {
- HSPACE_CASES: gotspace = TRUE; break;
- default: gotspace = FALSE; break;
- }
- if (gotspace == (ctype == OP_NOT_HSPACE)) break;
- eptr += len;
- }
- break;
-
- case OP_NOT_VSPACE:
- case OP_VSPACE:
- for (i = min; i < max; i++)
- {
- BOOL gotspace;
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- switch(c)
- {
- VSPACE_CASES: gotspace = TRUE; break;
- default: gotspace = FALSE; break;
- }
- if (gotspace == (ctype == OP_NOT_VSPACE)) break;
- eptr += len;
- }
- break;
-
- case OP_NOT_DIGIT:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;
- eptr+= len;
- }
- break;
-
- case OP_DIGIT:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;
- eptr+= len;
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;
- eptr+= len;
- }
- break;
-
- case OP_WHITESPACE:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;
- eptr+= len;
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;
- eptr+= len;
- }
- break;
-
- case OP_WORDCHAR:
- for (i = min; i < max; i++)
- {
- int len = 1;
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- GETCHARLEN(c, eptr, len);
- if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;
- eptr+= len;
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
-
- if (possessive) continue; /* No backtracking */
- for(;;)
- {
- if (eptr == pp) goto TAIL_RECURSE;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM46);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- BACKCHAR(eptr);
- if (ctype == OP_ANYNL && eptr > pp && RAWUCHAR(eptr) == CHAR_NL &&
- RAWUCHAR(eptr - 1) == CHAR_CR) eptr--;
- }
- }
- else
-#endif /* SUPPORT_UTF */
- /* Not UTF mode */
- {
- switch(ctype)
- {
- case OP_ANY:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (IS_NEWLINE(eptr)) break;
- if (md->partial != 0 && /* Take care with CRLF partial */
- eptr + 1 >= md->end_subject &&
- NLBLOCK->nltype == NLTYPE_FIXED &&
- NLBLOCK->nllen == 2 &&
- *eptr == NLBLOCK->nl[0])
- {
- md->hitend = TRUE;
- if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
- }
- eptr++;
- }
- break;
-
- case OP_ALLANY:
- case OP_ANYBYTE:
- c = max - min;
- if (c > (unsigned int)(md->end_subject - eptr))
- {
- eptr = md->end_subject;
- SCHECK_PARTIAL();
- }
- else eptr += c;
- break;
-
- case OP_ANYNL:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- c = *eptr;
- if (c == CHAR_CR)
- {
- if (++eptr >= md->end_subject) break;
- if (*eptr == CHAR_LF) eptr++;
- }
- else
- {
- if (c != CHAR_LF && (md->bsr_anycrlf ||
- (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- && c != 0x2028 && c != 0x2029
-#endif
- ))) break;
- eptr++;
- }
- }
- break;
-
- case OP_NOT_HSPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- switch(*eptr)
- {
- default: eptr++; break;
- HSPACE_BYTE_CASES:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- HSPACE_MULTIBYTE_CASES:
-#endif
- goto ENDLOOP00;
- }
- }
- ENDLOOP00:
- break;
-
- case OP_HSPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- switch(*eptr)
- {
- default: goto ENDLOOP01;
- HSPACE_BYTE_CASES:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- HSPACE_MULTIBYTE_CASES:
-#endif
- eptr++; break;
- }
- }
- ENDLOOP01:
- break;
-
- case OP_NOT_VSPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- switch(*eptr)
- {
- default: eptr++; break;
- VSPACE_BYTE_CASES:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- VSPACE_MULTIBYTE_CASES:
-#endif
- goto ENDLOOP02;
- }
- }
- ENDLOOP02:
- break;
-
- case OP_VSPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- switch(*eptr)
- {
- default: goto ENDLOOP03;
- VSPACE_BYTE_CASES:
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- VSPACE_MULTIBYTE_CASES:
-#endif
- eptr++; break;
- }
- }
- ENDLOOP03:
- break;
-
- case OP_NOT_DIGIT:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break;
- eptr++;
- }
- break;
-
- case OP_DIGIT:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break;
- eptr++;
- }
- break;
-
- case OP_NOT_WHITESPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break;
- eptr++;
- }
- break;
-
- case OP_WHITESPACE:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break;
- eptr++;
- }
- break;
-
- case OP_NOT_WORDCHAR:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break;
- eptr++;
- }
- break;
-
- case OP_WORDCHAR:
- for (i = min; i < max; i++)
- {
- if (eptr >= md->end_subject)
- {
- SCHECK_PARTIAL();
- break;
- }
- if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break;
- eptr++;
- }
- break;
-
- default:
- RRETURN(PCRE_ERROR_INTERNAL);
- }
-
- if (possessive) continue; /* No backtracking */
- for (;;)
- {
- if (eptr == pp) goto TAIL_RECURSE;
- RMATCH(eptr, ecode, offset_top, md, eptrb, RM47);
- if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- eptr--;
- if (ctype == OP_ANYNL && eptr > pp && *eptr == CHAR_LF &&
- eptr[-1] == CHAR_CR) eptr--;
- }
- }
-
- /* Get here if we can't make it match with any permitted repetitions */
-
- RRETURN(MATCH_NOMATCH);
- }
- /* Control never gets here */
-
- /* There's been some horrible disaster. Arrival here can only mean there is
- something seriously wrong in the code above or the OP_xxx definitions. */
-
- default:
- DPRINTF(("Unknown opcode %d\n", *ecode));
- RRETURN(PCRE_ERROR_UNKNOWN_OPCODE);
- }
-
- /* Do not stick any code in here without much thought; it is assumed
- that "continue" in the code above comes out to here to repeat the main
- loop. */
-
- } /* End of main loop */
-/* Control never reaches here */
-
-
-/* When compiling to use the heap rather than the stack for recursive calls to
-match(), the RRETURN() macro jumps here. The number that is saved in
-frame->Xwhere indicates which label we actually want to return to. */
-
-#ifdef NO_RECURSE
-#define LBL(val) case val: goto L_RM##val;
-HEAP_RETURN:
-switch (frame->Xwhere)
- {
- LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
- LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17)
- LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33)
- LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
- LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64)
- LBL(65) LBL(66)
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- LBL(21)
-#endif
-#ifdef SUPPORT_UTF
- LBL(16) LBL(18) LBL(20)
- LBL(22) LBL(23) LBL(28) LBL(30)
- LBL(32) LBL(34) LBL(42) LBL(46)
-#ifdef SUPPORT_UCP
- LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)
- LBL(59) LBL(60) LBL(61) LBL(62) LBL(67) LBL(68)
-#endif /* SUPPORT_UCP */
-#endif /* SUPPORT_UTF */
- default:
- DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
- return PCRE_ERROR_INTERNAL;
- }
-#undef LBL
-#endif /* NO_RECURSE */
-}
-
-
-/***************************************************************************
-****************************************************************************
- RECURSION IN THE match() FUNCTION
-
-Undefine all the macros that were defined above to handle this. */
-
-#ifdef NO_RECURSE
-#undef eptr
-#undef ecode
-#undef mstart
-#undef offset_top
-#undef eptrb
-#undef flags
-
-#undef callpat
-#undef charptr
-#undef data
-#undef next
-#undef pp
-#undef prev
-#undef saved_eptr
-
-#undef new_recursive
-
-#undef cur_is_word
-#undef condition
-#undef prev_is_word
-
-#undef ctype
-#undef length
-#undef max
-#undef min
-#undef number
-#undef offset
-#undef op
-#undef save_capture_last
-#undef save_offset1
-#undef save_offset2
-#undef save_offset3
-#undef stacksave
-
-#undef newptrb
-
-#endif
-
-/* These two are defined as macros in both cases */
-
-#undef fc
-#undef fi
-
-/***************************************************************************
-***************************************************************************/
-
-
-#ifdef NO_RECURSE
-/*************************************************
-* Release allocated heap frames *
-*************************************************/
-
-/* This function releases all the allocated frames. The base frame is on the
-machine stack, and so must not be freed.
-
-Argument: the address of the base frame
-Returns: nothing
-*/
-
-static void
-release_match_heapframes (heapframe *frame_base)
-{
-heapframe *nextframe = frame_base->Xnextframe;
-while (nextframe != NULL)
- {
- heapframe *oldframe = nextframe;
- nextframe = nextframe->Xnextframe;
- (PUBL(stack_free))(oldframe);
- }
-}
-#endif
-
-
-/*************************************************
-* Execute a Regular Expression *
-*************************************************/
-
-/* This function applies a compiled re to a subject string and picks out
-portions of the string if it matches. Two elements in the vector are set for
-each substring: the offsets to the start and end of the substring.
-
-Arguments:
- argument_re points to the compiled expression
- extra_data points to extra data or is NULL
- subject points to the subject string
- length length of subject string (may contain binary zeros)
- start_offset where to start in the subject string
- options option bits
- offsets points to a vector of ints to be filled in with offsets
- offsetcount the number of elements in the vector
-
-Returns: > 0 => success; value is the number of elements filled in
- = 0 => success, but offsets is not big enough
- -1 => failed to match
- < -1 => some kind of unexpected problem
-*/
-
-#if defined COMPILE_PCRE8
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
- PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
- int offsetcount)
-#elif defined COMPILE_PCRE16
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
- PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
- int offsetcount)
-#elif defined COMPILE_PCRE32
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre32_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,
- PCRE_SPTR32 subject, int length, int start_offset, int options, int *offsets,
- int offsetcount)
-#endif
-{
-int rc, ocount, arg_offset_max;
-int newline;
-BOOL using_temporary_offsets = FALSE;
-BOOL anchored;
-BOOL startline;
-BOOL firstline;
-BOOL utf;
-BOOL has_first_char = FALSE;
-BOOL has_req_char = FALSE;
-pcre_uchar first_char = 0;
-pcre_uchar first_char2 = 0;
-pcre_uchar req_char = 0;
-pcre_uchar req_char2 = 0;
-match_data match_block;
-match_data *md = &match_block;
-const pcre_uint8 *tables;
-const pcre_uint8 *start_bits = NULL;
-PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset;
-PCRE_PUCHAR end_subject;
-PCRE_PUCHAR start_partial = NULL;
-PCRE_PUCHAR match_partial = NULL;
-PCRE_PUCHAR req_char_ptr = start_match - 1;
-
-const pcre_study_data *study;
-const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
-
-#ifdef NO_RECURSE
-heapframe frame_zero;
-frame_zero.Xprevframe = NULL; /* Marks the top level */
-frame_zero.Xnextframe = NULL; /* None are allocated yet */
-md->match_frames_base = &frame_zero;
-#endif
-
-/* Check for the special magic call that measures the size of the stack used
-per recursive call of match(). Without the funny casting for sizeof, a Windows
-compiler gave this error: "unary minus operator applied to unsigned type,
-result still unsigned". Hopefully the cast fixes that. */
-
-if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&
- start_offset == -999)
-#ifdef NO_RECURSE
- return -((int)sizeof(heapframe));
-#else
- return match(NULL, NULL, NULL, 0, NULL, NULL, 0);
-#endif
-
-/* Plausibility checks */
-
-if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
-if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))
- return PCRE_ERROR_NULL;
-if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
-if (length < 0) return PCRE_ERROR_BADLENGTH;
-if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
-
-/* Check that the first field in the block is the magic number. If it is not,
-return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
-REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
-means that the pattern is likely compiled with different endianness. */
-
-if (re->magic_number != MAGIC_NUMBER)
- return re->magic_number == REVERSED_MAGIC_NUMBER?
- PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
-if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
-
-/* These two settings are used in the code for checking a UTF-8 string that
-follows immediately afterwards. Other values in the md block are used only
-during "normal" pcre_exec() processing, not when the JIT support is in use,
-so they are set up later. */
-
-/* PCRE_UTF16 has the same value as PCRE_UTF8. */
-utf = md->utf = (re->options & PCRE_UTF8) != 0;
-md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
- ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
-
-/* Check a UTF-8 string if required. Pass back the character offset and error
-code for an invalid string if a results vector is available. */
-
-#ifdef SUPPORT_UTF
-if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
- {
- int erroroffset;
- int errorcode = PRIV(valid_utf)((PCRE_PUCHAR)subject, length, &erroroffset);
- if (errorcode != 0)
- {
- if (offsetcount >= 2)
- {
- offsets[0] = erroroffset;
- offsets[1] = errorcode;
- }
-#if defined COMPILE_PCRE8
- return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?
- PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
-#elif defined COMPILE_PCRE16
- return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)?
- PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16;
-#elif defined COMPILE_PCRE32
- return PCRE_ERROR_BADUTF32;
-#endif
- }
-#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
- /* Check that a start_offset points to the start of a UTF character. */
- if (start_offset > 0 && start_offset < length &&
- NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
- return PCRE_ERROR_BADUTF8_OFFSET;
-#endif
- }
-#endif
-
-/* If the pattern was successfully studied with JIT support, run the JIT
-executable instead of the rest of this function. Most options must be set at
-compile time for the JIT code to be usable. Fallback to the normal code path if
-an unsupported flag is set. */
-
-#ifdef SUPPORT_JIT
-if (extra_data != NULL
- && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT |
- PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT
- && extra_data->executable_jit != NULL
- && (options & ~PUBLIC_JIT_EXEC_OPTIONS) == 0)
- {
- rc = PRIV(jit_exec)(extra_data, (const pcre_uchar *)subject, length,
- start_offset, options, offsets, offsetcount);
-
- /* PCRE_ERROR_NULL means that the selected normal or partial matching
- mode is not compiled. In this case we simply fallback to interpreter. */
-
- if (rc != PCRE_ERROR_JIT_BADOPTION) return rc;
- }
-#endif
-
-/* Carry on with non-JIT matching. This information is for finding all the
-numbers associated with a given name, for condition testing. */
-
-md->name_table = (pcre_uchar *)re + re->name_table_offset;
-md->name_count = re->name_count;
-md->name_entry_size = re->name_entry_size;
-
-/* Fish out the optional data from the extra_data structure, first setting
-the default values. */
-
-study = NULL;
-md->match_limit = MATCH_LIMIT;
-md->match_limit_recursion = MATCH_LIMIT_RECURSION;
-md->callout_data = NULL;
-
-/* The table pointer is always in native byte order. */
-
-tables = re->tables;
-
-/* The two limit values override the defaults, whatever their value. */
-
-if (extra_data != NULL)
- {
- register unsigned int flags = extra_data->flags;
- if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
- study = (const pcre_study_data *)extra_data->study_data;
- if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0)
- md->match_limit = extra_data->match_limit;
- if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
- md->match_limit_recursion = extra_data->match_limit_recursion;
- if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
- md->callout_data = extra_data->callout_data;
- if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;
- }
-
-/* Limits in the regex override only if they are smaller. */
-
-if ((re->flags & PCRE_MLSET) != 0 && re->limit_match < md->match_limit)
- md->match_limit = re->limit_match;
-
-if ((re->flags & PCRE_RLSET) != 0 &&
- re->limit_recursion < md->match_limit_recursion)
- md->match_limit_recursion = re->limit_recursion;
-
-/* If the exec call supplied NULL for tables, use the inbuilt ones. This
-is a feature that makes it possible to save compiled regex and re-use them
-in other programs later. */
-
-if (tables == NULL) tables = PRIV(default_tables);
-
-/* Set up other data */
-
-anchored = ((re->options | options) & PCRE_ANCHORED) != 0;
-startline = (re->flags & PCRE_STARTLINE) != 0;
-firstline = (re->options & PCRE_FIRSTLINE) != 0;
-
-/* The code starts after the real_pcre block and the capture name table. */
-
-md->start_code = (const pcre_uchar *)re + re->name_table_offset +
- re->name_count * re->name_entry_size;
-
-md->start_subject = (PCRE_PUCHAR)subject;
-md->start_offset = start_offset;
-md->end_subject = md->start_subject + length;
-end_subject = md->end_subject;
-
-md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
-md->use_ucp = (re->options & PCRE_UCP) != 0;
-md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
-md->ignore_skip_arg = 0;
-
-/* Some options are unpacked into BOOL variables in the hope that testing
-them will be faster than individual option bits. */
-
-md->notbol = (options & PCRE_NOTBOL) != 0;
-md->noteol = (options & PCRE_NOTEOL) != 0;
-md->notempty = (options & PCRE_NOTEMPTY) != 0;
-md->notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
-
-md->hitend = FALSE;
-md->mark = md->nomatch_mark = NULL; /* In case never set */
-
-md->recursive = NULL; /* No recursion at top level */
-md->hasthen = (re->flags & PCRE_HASTHEN) != 0;
-
-md->lcc = tables + lcc_offset;
-md->fcc = tables + fcc_offset;
-md->ctypes = tables + ctypes_offset;
-
-/* Handle different \R options. */
-
-switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
- {
- case 0:
- if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
- md->bsr_anycrlf = (re->options & PCRE_BSR_ANYCRLF) != 0;
- else
-#ifdef BSR_ANYCRLF
- md->bsr_anycrlf = TRUE;
-#else
- md->bsr_anycrlf = FALSE;
-#endif
- break;
-
- case PCRE_BSR_ANYCRLF:
- md->bsr_anycrlf = TRUE;
- break;
-
- case PCRE_BSR_UNICODE:
- md->bsr_anycrlf = FALSE;
- break;
-
- default: return PCRE_ERROR_BADNEWLINE;
- }
-
-/* Handle different types of newline. The three bits give eight cases. If
-nothing is set at run time, whatever was used at compile time applies. */
-
-switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options :
- (pcre_uint32)options) & PCRE_NEWLINE_BITS)
- {
- case 0: newline = NEWLINE; break; /* Compile-time default */
- case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
- case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
- case PCRE_NEWLINE_CR+
- PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
- case PCRE_NEWLINE_ANY: newline = -1; break;
- case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
- default: return PCRE_ERROR_BADNEWLINE;
- }
-
-if (newline == -2)
- {
- md->nltype = NLTYPE_ANYCRLF;
- }
-else if (newline < 0)
- {
- md->nltype = NLTYPE_ANY;
- }
-else
- {
- md->nltype = NLTYPE_FIXED;
- if (newline > 255)
- {
- md->nllen = 2;
- md->nl[0] = (newline >> 8) & 255;
- md->nl[1] = newline & 255;
- }
- else
- {
- md->nllen = 1;
- md->nl[0] = newline;
- }
- }
-
-/* Partial matching was originally supported only for a restricted set of
-regexes; from release 8.00 there are no restrictions, but the bits are still
-defined (though never set). So there's no harm in leaving this code. */
-
-if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)
- return PCRE_ERROR_BADPARTIAL;
-
-/* If the expression has got more back references than the offsets supplied can
-hold, we get a temporary chunk of working store to use during the matching.
-Otherwise, we can use the vector supplied, rounding down its size to a multiple
-of 3. */
-
-ocount = offsetcount - (offsetcount % 3);
-arg_offset_max = (2*ocount)/3;
-
-if (re->top_backref > 0 && re->top_backref >= ocount/3)
- {
- ocount = re->top_backref * 3 + 3;
- md->offset_vector = (int *)(PUBL(malloc))(ocount * sizeof(int));
- if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
- using_temporary_offsets = TRUE;
- DPRINTF(("Got memory to hold back references\n"));
- }
-else md->offset_vector = offsets;
-md->offset_end = ocount;
-md->offset_max = (2*ocount)/3;
-md->capture_last = 0;
-
-/* Reset the working variable associated with each extraction. These should
-never be used unless previously set, but they get saved and restored, and so we
-initialize them to avoid reading uninitialized locations. Also, unset the
-offsets for the matched string. This is really just for tidiness with callouts,
-in case they inspect these fields. */
-
-if (md->offset_vector != NULL)
- {
- register int *iptr = md->offset_vector + ocount;
- register int *iend = iptr - re->top_bracket;
- if (iend < md->offset_vector + 2) iend = md->offset_vector + 2;
- while (--iptr >= iend) *iptr = -1;
- md->offset_vector[0] = md->offset_vector[1] = -1;
- }
-
-/* Set up the first character to match, if available. The first_char value is
-never set for an anchored regular expression, but the anchoring may be forced
-at run time, so we have to test for anchoring. The first char may be unset for
-an unanchored pattern, of course. If there's no first char and the pattern was
-studied, there may be a bitmap of possible first characters. */
-
-if (!anchored)
- {
- if ((re->flags & PCRE_FIRSTSET) != 0)
- {
- has_first_char = TRUE;
- first_char = first_char2 = (pcre_uchar)(re->first_char);
- if ((re->flags & PCRE_FCH_CASELESS) != 0)
- {
- first_char2 = TABLE_GET(first_char, md->fcc, first_char);
-#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
- if (utf && first_char > 127)
- first_char2 = UCD_OTHERCASE(first_char);
-#endif
- }
- }
- else
- if (!startline && study != NULL &&
- (study->flags & PCRE_STUDY_MAPPED) != 0)
- start_bits = study->start_bits;
- }
-
-/* For anchored or unanchored matches, there may be a "last known required
-character" set. */
-
-if ((re->flags & PCRE_REQCHSET) != 0)
- {
- has_req_char = TRUE;
- req_char = req_char2 = (pcre_uchar)(re->req_char);
- if ((re->flags & PCRE_RCH_CASELESS) != 0)
- {
- req_char2 = TABLE_GET(req_char, md->fcc, req_char);
-#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
- if (utf && req_char > 127)
- req_char2 = UCD_OTHERCASE(req_char);
-#endif
- }
- }
-
-
-/* ==========================================================================*/
-
-/* Loop for handling unanchored repeated matching attempts; for anchored regexs
-the loop runs just once. */
-
-for(;;)
- {
- PCRE_PUCHAR save_end_subject = end_subject;
- PCRE_PUCHAR new_start_match;
-
- /* If firstline is TRUE, the start of the match is constrained to the first
- line of a multiline string. That is, the match must be before or at the first
- newline. Implement this by temporarily adjusting end_subject so that we stop
- scanning at a newline. If the match fails at the newline, later code breaks
- this loop. */
-
- if (firstline)
- {
- PCRE_PUCHAR t = start_match;
-#ifdef SUPPORT_UTF
- if (utf)
- {
- while (t < md->end_subject && !IS_NEWLINE(t))
- {
- t++;
- ACROSSCHAR(t < end_subject, *t, t++);
- }
- }
- else
-#endif
- while (t < md->end_subject && !IS_NEWLINE(t)) t++;
- end_subject = t;
- }
-
- /* There are some optimizations that avoid running the match if a known
- starting point is not found, or if a known later character is not present.
- However, there is an option that disables these, for testing and for ensuring
- that all callouts do actually occur. The option can be set in the regex by
- (*NO_START_OPT) or passed in match-time options. */
-
- if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
- {
- /* Advance to a unique first char if there is one. */
-
- if (has_first_char)
- {
- pcre_uchar smc;
-
- if (first_char != first_char2)
- while (start_match < end_subject &&
- (smc = RAWUCHARTEST(start_match)) != first_char && smc != first_char2)
- start_match++;
- else
- while (start_match < end_subject && RAWUCHARTEST(start_match) != first_char)
- start_match++;
- }
-
- /* Or to just after a linebreak for a multiline match */
-
- else if (startline)
- {
- if (start_match > md->start_subject + start_offset)
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- while (start_match < end_subject && !WAS_NEWLINE(start_match))
- {
- start_match++;
- ACROSSCHAR(start_match < end_subject, *start_match,
- start_match++);
- }
- }
- else
-#endif
- while (start_match < end_subject && !WAS_NEWLINE(start_match))
- start_match++;
-
- /* If we have just passed a CR and the newline option is ANY or ANYCRLF,
- and we are now at a LF, advance the match position by one more character.
- */
-
- if (start_match[-1] == CHAR_CR &&
- (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
- start_match < end_subject &&
- RAWUCHARTEST(start_match) == CHAR_NL)
- start_match++;
- }
- }
-
- /* Or to a non-unique first byte after study */
-
- else if (start_bits != NULL)
- {
- while (start_match < end_subject)
- {
- register pcre_uint32 c = RAWUCHARTEST(start_match);
-#ifndef COMPILE_PCRE8
- if (c > 255) c = 255;
-#endif
- if ((start_bits[c/8] & (1 << (c&7))) == 0)
- {
- start_match++;
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
- /* In non 8-bit mode, the iteration will stop for
- characters > 255 at the beginning or not stop at all. */
- if (utf)
- ACROSSCHAR(start_match < end_subject, *start_match,
- start_match++);
-#endif
- }
- else break;
- }
- }
- } /* Starting optimizations */
-
- /* Restore fudged end_subject */
-
- end_subject = save_end_subject;
-
- /* The following two optimizations are disabled for partial matching or if
- disabling is explicitly requested. */
-
- if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial)
- {
- /* If the pattern was studied, a minimum subject length may be set. This is
- a lower bound; no actual string of that length may actually match the
- pattern. Although the value is, strictly, in characters, we treat it as
- bytes to avoid spending too much time in this optimization. */
-
- if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 &&
- (pcre_uint32)(end_subject - start_match) < study->minlength)
- {
- rc = MATCH_NOMATCH;
- break;
- }
-
- /* If req_char is set, we know that that character must appear in the
- subject for the match to succeed. If the first character is set, req_char
- must be later in the subject; otherwise the test starts at the match point.
- This optimization can save a huge amount of backtracking in patterns with
- nested unlimited repeats that aren't going to match. Writing separate code
- for cased/caseless versions makes it go faster, as does using an
- autoincrement and backing off on a match.
-
- HOWEVER: when the subject string is very, very long, searching to its end
- can take a long time, and give bad performance on quite ordinary patterns.
- This showed up when somebody was matching something like /^\d+C/ on a
- 32-megabyte string... so we don't do this when the string is sufficiently
- long. */
-
- if (has_req_char && end_subject - start_match < REQ_BYTE_MAX)
- {
- register PCRE_PUCHAR p = start_match + (has_first_char? 1:0);
-
- /* We don't need to repeat the search if we haven't yet reached the
- place we found it at last time. */
-
- if (p > req_char_ptr)
- {
- if (req_char != req_char2)
- {
- while (p < end_subject)
- {
- register pcre_uint32 pp = RAWUCHARINCTEST(p);
- if (pp == req_char || pp == req_char2) { p--; break; }
- }
- }
- else
- {
- while (p < end_subject)
- {
- if (RAWUCHARINCTEST(p) == req_char) { p--; break; }
- }
- }
-
- /* If we can't find the required character, break the matching loop,
- forcing a match failure. */
-
- if (p >= end_subject)
- {
- rc = MATCH_NOMATCH;
- break;
- }
-
- /* If we have found the required character, save the point where we
- found it, so that we don't search again next time round the loop if
- the start hasn't passed this character yet. */
-
- req_char_ptr = p;
- }
- }
- }
-
-#ifdef PCRE_DEBUG /* Sigh. Some compilers never learn. */
- printf(">>>> Match against: ");
- pchars(start_match, end_subject - start_match, TRUE, md);
- printf("\n");
-#endif
-
- /* OK, we can now run the match. If "hitend" is set afterwards, remember the
- first starting point for which a partial match was found. */
-
- md->start_match_ptr = start_match;
- md->start_used_ptr = start_match;
- md->match_call_count = 0;
- md->match_function_type = 0;
- md->end_offset_top = 0;
- md->skip_arg_count = 0;
- rc = match(start_match, md->start_code, start_match, 2, md, NULL, 0);
- if (md->hitend && start_partial == NULL)
- {
- start_partial = md->start_used_ptr;
- match_partial = start_match;
- }
-
- switch(rc)
- {
- /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
- the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP
- entirely. The only way we can do that is to re-do the match at the same
- point, with a flag to force SKIP with an argument to be ignored. Just
- treating this case as NOMATCH does not work because it does not check other
- alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */
-
- case MATCH_SKIP_ARG:
- new_start_match = start_match;
- md->ignore_skip_arg = md->skip_arg_count;
- break;
-
- /* SKIP passes back the next starting point explicitly, but if it is no
- greater than the match we have just done, treat it as NOMATCH. */
-
- case MATCH_SKIP:
- if (md->start_match_ptr > start_match)
- {
- new_start_match = md->start_match_ptr;
- break;
- }
- /* Fall through */
-
- /* NOMATCH and PRUNE advance by one character. THEN at this level acts
- exactly like PRUNE. Unset ignore SKIP-with-argument. */
-
- case MATCH_NOMATCH:
- case MATCH_PRUNE:
- case MATCH_THEN:
- md->ignore_skip_arg = 0;
- new_start_match = start_match + 1;
-#ifdef SUPPORT_UTF
- if (utf)
- ACROSSCHAR(new_start_match < end_subject, *new_start_match,
- new_start_match++);
-#endif
- break;
-
- /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */
-
- case MATCH_COMMIT:
- rc = MATCH_NOMATCH;
- goto ENDLOOP;
-
- /* Any other return is either a match, or some kind of error. */
-
- default:
- goto ENDLOOP;
- }
-
- /* Control reaches here for the various types of "no match at this point"
- result. Reset the code to MATCH_NOMATCH for subsequent checking. */
-
- rc = MATCH_NOMATCH;
-
- /* If PCRE_FIRSTLINE is set, the match must happen before or at the first
- newline in the subject (though it may continue over the newline). Therefore,
- if we have just failed to match, starting at a newline, do not continue. */
-
- if (firstline && IS_NEWLINE(start_match)) break;
-
- /* Advance to new matching position */
-
- start_match = new_start_match;
-
- /* Break the loop if the pattern is anchored or if we have passed the end of
- the subject. */
-
- if (anchored || start_match > end_subject) break;
-
- /* If we have just passed a CR and we are now at a LF, and the pattern does
- not contain any explicit matches for \r or \n, and the newline option is CRLF
- or ANY or ANYCRLF, advance the match position by one more character. In
- normal matching start_match will aways be greater than the first position at
- this stage, but a failed *SKIP can cause a return at the same point, which is
- why the first test exists. */
-
- if (start_match > (PCRE_PUCHAR)subject + start_offset &&
- start_match[-1] == CHAR_CR &&
- start_match < end_subject &&
- *start_match == CHAR_NL &&
- (re->flags & PCRE_HASCRORLF) == 0 &&
- (md->nltype == NLTYPE_ANY ||
- md->nltype == NLTYPE_ANYCRLF ||
- md->nllen == 2))
- start_match++;
-
- md->mark = NULL; /* Reset for start of next match attempt */
- } /* End of for(;;) "bumpalong" loop */
-
-/* ==========================================================================*/
-
-/* We reach here when rc is not MATCH_NOMATCH, or if one of the stopping
-conditions is true:
-
-(1) The pattern is anchored or the match was failed by (*COMMIT);
-
-(2) We are past the end of the subject;
-
-(3) PCRE_FIRSTLINE is set and we have failed to match at a newline, because
- this option requests that a match occur at or before the first newline in
- the subject.
-
-When we have a match and the offset vector is big enough to deal with any
-backreferences, captured substring offsets will already be set up. In the case
-where we had to get some local store to hold offsets for backreference
-processing, copy those that we can. In this case there need not be overflow if
-certain parts of the pattern were not used, even though there are more
-capturing parentheses than vector slots. */
-
-ENDLOOP:
-
-if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
- {
- if (using_temporary_offsets)
- {
- if (arg_offset_max >= 4)
- {
- memcpy(offsets + 2, md->offset_vector + 2,
- (arg_offset_max - 2) * sizeof(int));
- DPRINTF(("Copied offsets from temporary memory\n"));
- }
- if (md->end_offset_top > arg_offset_max) md->capture_last |= OVFLBIT;
- DPRINTF(("Freeing temporary memory\n"));
- (PUBL(free))(md->offset_vector);
- }
-
- /* Set the return code to the number of captured strings, or 0 if there were
- too many to fit into the vector. */
-
- rc = ((md->capture_last & OVFLBIT) != 0 &&
- md->end_offset_top >= arg_offset_max)?
- 0 : md->end_offset_top/2;
-
- /* If there is space in the offset vector, set any unused pairs at the end of
- the pattern to -1 for backwards compatibility. It is documented that this
- happens. In earlier versions, the whole set of potential capturing offsets
- was set to -1 each time round the loop, but this is handled differently now.
- "Gaps" are set to -1 dynamically instead (this fixes a bug). Thus, it is only
- those at the end that need unsetting here. We can't just unset them all at
- the start of the whole thing because they may get set in one branch that is
- not the final matching branch. */
-
- if (md->end_offset_top/2 <= re->top_bracket && offsets != NULL)
- {
- register int *iptr, *iend;
- int resetcount = 2 + re->top_bracket * 2;
- if (resetcount > offsetcount) resetcount = offsetcount;
- iptr = offsets + md->end_offset_top;
- iend = offsets + resetcount;
- while (iptr < iend) *iptr++ = -1;
- }
-
- /* If there is space, set up the whole thing as substring 0. The value of
- md->start_match_ptr might be modified if \K was encountered on the success
- matching path. */
-
- if (offsetcount < 2) rc = 0; else
- {
- offsets[0] = (int)(md->start_match_ptr - md->start_subject);
- offsets[1] = (int)(md->end_match_ptr - md->start_subject);
- }
-
- /* Return MARK data if requested */
-
- if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
- *(extra_data->mark) = (pcre_uchar *)md->mark;
- DPRINTF((">>>> returning %d\n", rc));
-#ifdef NO_RECURSE
- release_match_heapframes(&frame_zero);
-#endif
- return rc;
- }
-
-/* Control gets here if there has been an error, or if the overall match
-attempt has failed at all permitted starting positions. */
-
-if (using_temporary_offsets)
- {
- DPRINTF(("Freeing temporary memory\n"));
- (PUBL(free))(md->offset_vector);
- }
-
-/* For anything other than nomatch or partial match, just return the code. */
-
-if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
- {
- DPRINTF((">>>> error: returning %d\n", rc));
-#ifdef NO_RECURSE
- release_match_heapframes(&frame_zero);
-#endif
- return rc;
- }
-
-/* Handle partial matches - disable any mark data */
-
-if (start_partial != NULL)
- {
- DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
- md->mark = NULL;
- if (offsetcount > 1)
- {
- offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);
- offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
- if (offsetcount > 2)
- offsets[2] = (int)(match_partial - (PCRE_PUCHAR)subject);
- }
- rc = PCRE_ERROR_PARTIAL;
- }
-
-/* This is the classic nomatch case */
-
-else
- {
- DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n"));
- rc = PCRE_ERROR_NOMATCH;
- }
-
-/* Return the MARK data if it has been requested. */
-
-if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
- *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
-#ifdef NO_RECURSE
- release_match_heapframes(&frame_zero);
-#endif
-return rc;
-}
-
-/* End of pcre_exec.c */
diff --git a/usr.sbin/nginx/src/pcre/pcre_fullinfo.c b/usr.sbin/nginx/src/pcre/pcre_fullinfo.c
deleted file mode 100644
index c4eb5c0e1ad..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre_fullinfo.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2013 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_fullinfo(), which returns
-information about a compiled pattern. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Return info about compiled pattern *
-*************************************************/
-
-/* This is a newer "info" function which has an extensible interface so
-that additional items can be added compatibly.
-
-Arguments:
- argument_re points to compiled code
- extra_data points extra data, or NULL
- what what information is required
- where where to put the information
-
-Returns: 0 if data returned, negative on error
-*/
-
-#if defined COMPILE_PCRE8
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data,
- int what, void *where)
-#elif defined COMPILE_PCRE16
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre16_fullinfo(const pcre16 *argument_re, const pcre16_extra *extra_data,
- int what, void *where)
-#elif defined COMPILE_PCRE32
-PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
-pcre32_fullinfo(const pcre32 *argument_re, const pcre32_extra *extra_data,
- int what, void *where)
-#endif
-{
-const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
-const pcre_study_data *study = NULL;
-
-if (re == NULL || where == NULL) return PCRE_ERROR_NULL;
-
-if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
- study = (const pcre_study_data *)extra_data->study_data;
-
-/* Check that the first field in the block is the magic number. If it is not,
-return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
-REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
-means that the pattern is likely compiled with different endianness. */
-
-if (re->magic_number != MAGIC_NUMBER)
- return re->magic_number == REVERSED_MAGIC_NUMBER?
- PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
-
-/* Check that this pattern was compiled in the correct bit mode */
-
-if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
-
-switch (what)
- {
- case PCRE_INFO_OPTIONS:
- *((unsigned long int *)where) = re->options & PUBLIC_COMPILE_OPTIONS;
- break;
-
- case PCRE_INFO_SIZE:
- *((size_t *)where) = re->size;
- break;
-
- case PCRE_INFO_STUDYSIZE:
- *((size_t *)where) = (study == NULL)? 0 : study->size;
- break;
-
- case PCRE_INFO_JITSIZE:
-#ifdef SUPPORT_JIT
- *((size_t *)where) =
- (extra_data != NULL &&
- (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
- extra_data->executable_jit != NULL)?
- PRIV(jit_get_size)(extra_data->executable_jit) : 0;
-#else
- *((size_t *)where) = 0;
-#endif
- break;
-
- case PCRE_INFO_CAPTURECOUNT:
- *((int *)where) = re->top_bracket;
- break;
-
- case PCRE_INFO_BACKREFMAX:
- *((int *)where) = re->top_backref;
- break;
-
- case PCRE_INFO_FIRSTBYTE:
- *((int *)where) =
- ((re->flags & PCRE_FIRSTSET) != 0)? (int)re->first_char :
- ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
- break;
-
- case PCRE_INFO_FIRSTCHARACTER:
- *((pcre_uint32 *)where) =
- (re->flags & PCRE_FIRSTSET) != 0 ? re->first_char : 0;
- break;
-
- case PCRE_INFO_FIRSTCHARACTERFLAGS:
- *((int *)where) =
- ((re->flags & PCRE_FIRSTSET) != 0) ? 1 :
- ((re->flags & PCRE_STARTLINE) != 0) ? 2 : 0;
- break;
-
- /* Make sure we pass back the pointer to the bit vector in the external
- block, not the internal copy (with flipped integer fields). */
-
- case PCRE_INFO_FIRSTTABLE:
- *((const pcre_uint8 **)where) =
- (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)?
- ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL;
- break;
-
- case PCRE_INFO_MINLENGTH:
- *((int *)where) =
- (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0)?
- (int)(study->minlength) : -1;
- break;
-
- case PCRE_INFO_JIT:
- *((int *)where) = extra_data != NULL &&
- (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
- extra_data->executable_jit != NULL;
- break;
-
- case PCRE_INFO_LASTLITERAL:
- *((int *)where) =
- ((re->flags & PCRE_REQCHSET) != 0)? (int)re->req_char : -1;
- break;
-
- case PCRE_INFO_REQUIREDCHAR:
- *((pcre_uint32 *)where) =
- ((re->flags & PCRE_REQCHSET) != 0) ? re->req_char : 0;
- break;
-
- case PCRE_INFO_REQUIREDCHARFLAGS:
- *((int *)where) =
- ((re->flags & PCRE_REQCHSET) != 0);
- break;
-
- case PCRE_INFO_NAMEENTRYSIZE:
- *((int *)where) = re->name_entry_size;
- break;
-
- case PCRE_INFO_NAMECOUNT:
- *((int *)where) = re->name_count;
- break;
-
- case PCRE_INFO_NAMETABLE:
- *((const pcre_uchar **)where) = (const pcre_uchar *)re + re->name_table_offset;
- break;
-
- case PCRE_INFO_DEFAULT_TABLES:
- *((const pcre_uint8 **)where) = (const pcre_uint8 *)(PRIV(default_tables));
- break;
-
- /* From release 8.00 this will always return TRUE because NOPARTIAL is
- no longer ever set (the restrictions have been removed). */
-
- case PCRE_INFO_OKPARTIAL:
- *((int *)where) = (re->flags & PCRE_NOPARTIAL) == 0;
- break;
-
- case PCRE_INFO_JCHANGED:
- *((int *)where) = (re->flags & PCRE_JCHANGED) != 0;
- break;
-
- case PCRE_INFO_HASCRORLF:
- *((int *)where) = (re->flags & PCRE_HASCRORLF) != 0;
- break;
-
- case PCRE_INFO_MAXLOOKBEHIND:
- *((int *)where) = re->max_lookbehind;
- break;
-
- case PCRE_INFO_MATCHLIMIT:
- if ((re->flags & PCRE_MLSET) == 0) return PCRE_ERROR_UNSET;
- *((pcre_uint32 *)where) = re->limit_match;
- break;
-
- case PCRE_INFO_RECURSIONLIMIT:
- if ((re->flags & PCRE_RLSET) == 0) return PCRE_ERROR_UNSET;
- *((pcre_uint32 *)where) = re->limit_recursion;
- break;
-
- default: return PCRE_ERROR_BADOPTION;
- }
-
-return 0;
-}
-
-/* End of pcre_fullinfo.c */
diff --git a/usr.sbin/nginx/src/pcre/pcre_globals.c b/usr.sbin/nginx/src/pcre/pcre_globals.c
deleted file mode 100644
index 36e6ddb3a89..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre_globals.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains global variables that are exported by the PCRE library.
-PCRE is thread-clean and doesn't use any global variables in the normal sense.
-However, it calls memory allocation and freeing functions via the four
-indirections below, and it can optionally do callouts, using the fifth
-indirection. These values can be changed by the caller, but are shared between
-all threads.
-
-For MS Visual Studio and Symbian OS, there are problems in initializing these
-variables to non-local functions. In these cases, therefore, an indirection via
-a local function is used.
-
-Also, when compiling for Virtual Pascal, things are done differently, and
-global variables are not used. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-#if defined _MSC_VER || defined __SYMBIAN32__
-static void* LocalPcreMalloc(size_t aSize)
- {
- return malloc(aSize);
- }
-static void LocalPcreFree(void* aPtr)
- {
- free(aPtr);
- }
-PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = LocalPcreMalloc;
-PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = LocalPcreFree;
-PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = LocalPcreMalloc;
-PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = LocalPcreFree;
-PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
-
-#elif !defined VPCOMPAT
-PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = malloc;
-PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = free;
-PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = malloc;
-PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = free;
-PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
-#endif
-
-/* End of pcre_globals.c */
diff --git a/usr.sbin/nginx/src/pcre/pcre_internal.h b/usr.sbin/nginx/src/pcre/pcre_internal.h
deleted file mode 100644
index 307069ca9d6..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre_internal.h
+++ /dev/null
@@ -1,2771 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2013 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-/* This header contains definitions that are shared between the different
-modules, but which are not relevant to the exported API. This includes some
-functions whose names all begin with "_pcre_", "_pcre16_" or "_pcre32_"
-depending on the PRIV macro. */
-
-#ifndef PCRE_INTERNAL_H
-#define PCRE_INTERNAL_H
-
-/* Define PCRE_DEBUG to get debugging output on stdout. */
-
-#if 0
-#define PCRE_DEBUG
-#endif
-
-/* PCRE is compiled as an 8 bit library if it is not requested otherwise. */
-
-#if !defined COMPILE_PCRE16 && !defined COMPILE_PCRE32
-#define COMPILE_PCRE8
-#endif
-
-/* If SUPPORT_UCP is defined, SUPPORT_UTF must also be defined. The
-"configure" script ensures this, but not everybody uses "configure". */
-
-#if defined SUPPORT_UCP && !(defined SUPPORT_UTF)
-#define SUPPORT_UTF 1
-#endif
-
-/* We define SUPPORT_UTF if SUPPORT_UTF8 is enabled for compatibility
-reasons with existing code. */
-
-#if defined SUPPORT_UTF8 && !(defined SUPPORT_UTF)
-#define SUPPORT_UTF 1
-#endif
-
-/* Fixme: SUPPORT_UTF8 should be eventually disappear from the code.
-Until then we define it if SUPPORT_UTF is defined. */
-
-#if defined SUPPORT_UTF && !(defined SUPPORT_UTF8)
-#define SUPPORT_UTF8 1
-#endif
-
-/* We do not support both EBCDIC and UTF-8/16/32 at the same time. The "configure"
-script prevents both being selected, but not everybody uses "configure". */
-
-#if defined EBCDIC && defined SUPPORT_UTF
-#error The use of both EBCDIC and SUPPORT_UTF is not supported.
-#endif
-
-/* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef
-inline, and there are *still* stupid compilers about that don't like indented
-pre-processor statements, or at least there were when I first wrote this. After
-all, it had only been about 10 years then...
-
-It turns out that the Mac Debugging.h header also defines the macro DPRINTF, so
-be absolutely sure we get our version. */
-
-#undef DPRINTF
-#ifdef PCRE_DEBUG
-#define DPRINTF(p) printf p
-#else
-#define DPRINTF(p) /* Nothing */
-#endif
-
-
-/* Standard C headers plus the external interface definition. The only time
-setjmp and stdarg are used is when NO_RECURSE is set. */
-
-#include <ctype.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* Valgrind (memcheck) support */
-
-#ifdef SUPPORT_VALGRIND
-#include <valgrind/memcheck.h>
-#endif
-
-/* When compiling a DLL for Windows, the exported symbols have to be declared
-using some MS magic. I found some useful information on this web page:
-http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the
-information there, using __declspec(dllexport) without "extern" we have a
-definition; with "extern" we have a declaration. The settings here override the
-setting in pcre.h (which is included below); it defines only PCRE_EXP_DECL,
-which is all that is needed for applications (they just import the symbols). We
-use:
-
- PCRE_EXP_DECL for declarations
- PCRE_EXP_DEFN for definitions of exported functions
- PCRE_EXP_DATA_DEFN for definitions of exported variables
-
-The reason for the two DEFN macros is that in non-Windows environments, one
-does not want to have "extern" before variable definitions because it leads to
-compiler warnings. So we distinguish between functions and variables. In
-Windows, the two should always be the same.
-
-The reason for wrapping this in #ifndef PCRE_EXP_DECL is so that pcretest,
-which is an application, but needs to import this file in order to "peek" at
-internals, can #include pcre.h first to get an application's-eye view.
-
-In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon,
-special-purpose environments) might want to stick other stuff in front of
-exported symbols. That's why, in the non-Windows case, we set PCRE_EXP_DEFN and
-PCRE_EXP_DATA_DEFN only if they are not already set. */
-
-#ifndef PCRE_EXP_DECL
-# ifdef _WIN32
-# ifndef PCRE_STATIC
-# define PCRE_EXP_DECL extern __declspec(dllexport)
-# define PCRE_EXP_DEFN __declspec(dllexport)
-# define PCRE_EXP_DATA_DEFN __declspec(dllexport)
-# else
-# define PCRE_EXP_DECL extern
-# define PCRE_EXP_DEFN
-# define PCRE_EXP_DATA_DEFN
-# endif
-# else
-# ifdef __cplusplus
-# define PCRE_EXP_DECL extern "C"
-# else
-# define PCRE_EXP_DECL extern
-# endif
-# ifndef PCRE_EXP_DEFN
-# define PCRE_EXP_DEFN PCRE_EXP_DECL
-# endif
-# ifndef PCRE_EXP_DATA_DEFN
-# define PCRE_EXP_DATA_DEFN
-# endif
-# endif
-#endif
-
-/* When compiling with the MSVC compiler, it is sometimes necessary to include
-a "calling convention" before exported function names. (This is secondhand
-information; I know nothing about MSVC myself). For example, something like
-
- void __cdecl function(....)
-
-might be needed. In order so make this easy, all the exported functions have
-PCRE_CALL_CONVENTION just before their names. It is rarely needed; if not
-set, we ensure here that it has no effect. */
-
-#ifndef PCRE_CALL_CONVENTION
-#define PCRE_CALL_CONVENTION
-#endif
-
-/* We need to have types that specify unsigned 8, 16 and 32-bit integers. We
-cannot determine these outside the compilation (e.g. by running a program as
-part of "configure") because PCRE is often cross-compiled for use on other
-systems. Instead we make use of the maximum sizes that are available at
-preprocessor time in standard C environments. */
-
-typedef unsigned char pcre_uint8;
-
-#if USHRT_MAX == 65535
-typedef unsigned short pcre_uint16;
-typedef short pcre_int16;
-#define PCRE_UINT16_MAX USHRT_MAX
-#define PCRE_INT16_MAX SHRT_MAX
-#elif UINT_MAX == 65535
-typedef unsigned int pcre_uint16;
-typedef int pcre_int16;
-#define PCRE_UINT16_MAX UINT_MAX
-#define PCRE_INT16_MAX INT_MAX
-#else
-#error Cannot determine a type for 16-bit integers
-#endif
-
-#if UINT_MAX == 4294967295U
-typedef unsigned int pcre_uint32;
-typedef int pcre_int32;
-#define PCRE_UINT32_MAX UINT_MAX
-#define PCRE_INT32_MAX INT_MAX
-#elif ULONG_MAX == 4294967295UL
-typedef unsigned long int pcre_uint32;
-typedef long int pcre_int32;
-#define PCRE_UINT32_MAX ULONG_MAX
-#define PCRE_INT32_MAX LONG_MAX
-#else
-#error Cannot determine a type for 32-bit integers
-#endif
-
-/* When checking for integer overflow in pcre_compile(), we need to handle
-large integers. If a 64-bit integer type is available, we can use that.
-Otherwise we have to cast to double, which of course requires floating point
-arithmetic. Handle this by defining a macro for the appropriate type. If
-stdint.h is available, include it; it may define INT64_MAX. Systems that do not
-have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set
-by "configure". */
-
-#if defined HAVE_STDINT_H
-#include <stdint.h>
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#if defined INT64_MAX || defined int64_t
-#define INT64_OR_DOUBLE int64_t
-#else
-#define INT64_OR_DOUBLE double
-#endif
-
-/* All character handling must be done as unsigned characters. Otherwise there
-are problems with top-bit-set characters and functions such as isspace().
-However, we leave the interface to the outside world as char * or short *,
-because that should make things easier for callers. This character type is
-called pcre_uchar.
-
-The IN_UCHARS macro multiply its argument with the byte size of the current
-pcre_uchar type. Useful for memcpy and such operations, whose require the
-byte size of their input/output buffers.
-
-The MAX_255 macro checks whether its pcre_uchar input is less than 256.
-
-The TABLE_GET macro is designed for accessing elements of tables whose contain
-exactly 256 items. When the character is able to contain more than 256
-items, some check is needed before accessing these tables.
-*/
-
-#if defined COMPILE_PCRE8
-
-typedef unsigned char pcre_uchar;
-#define IN_UCHARS(x) (x)
-#define MAX_255(c) 1
-#define TABLE_GET(c, table, default) ((table)[c])
-
-#elif defined COMPILE_PCRE16
-
-#if USHRT_MAX != 65535
-/* This is a warning message. Change PCRE_UCHAR16 to a 16 bit data type in
-pcre.h(.in) and disable (comment out) this message. */
-#error Warning: PCRE_UCHAR16 is not a 16 bit data type.
-#endif
-
-typedef pcre_uint16 pcre_uchar;
-#define UCHAR_SHIFT (1)
-#define IN_UCHARS(x) ((x) << UCHAR_SHIFT)
-#define MAX_255(c) ((c) <= 255u)
-#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default))
-
-#elif defined COMPILE_PCRE32
-
-typedef pcre_uint32 pcre_uchar;
-#define UCHAR_SHIFT (2)
-#define IN_UCHARS(x) ((x) << UCHAR_SHIFT)
-#define MAX_255(c) ((c) <= 255u)
-#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default))
-
-#else
-#error Unsupported compiling mode
-#endif /* COMPILE_PCRE[8|16|32] */
-
-/* This is an unsigned int value that no character can ever have. UTF-8
-characters only go up to 0x7fffffff (though Unicode doesn't go beyond
-0x0010ffff). */
-
-#define NOTACHAR 0xffffffff
-
-/* PCRE is able to support several different kinds of newline (CR, LF, CRLF,
-"any" and "anycrlf" at present). The following macros are used to package up
-testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various
-modules to indicate in which datablock the parameters exist, and what the
-start/end of string field names are. */
-
-#define NLTYPE_FIXED 0 /* Newline is a fixed length string */
-#define NLTYPE_ANY 1 /* Newline is any Unicode line ending */
-#define NLTYPE_ANYCRLF 2 /* Newline is CR, LF, or CRLF */
-
-/* This macro checks for a newline at the given position */
-
-#define IS_NEWLINE(p) \
- ((NLBLOCK->nltype != NLTYPE_FIXED)? \
- ((p) < NLBLOCK->PSEND && \
- PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \
- &(NLBLOCK->nllen), utf)) \
- : \
- ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \
- RAWUCHARTEST(p) == NLBLOCK->nl[0] && \
- (NLBLOCK->nllen == 1 || RAWUCHARTEST(p+1) == NLBLOCK->nl[1]) \
- ) \
- )
-
-/* This macro checks for a newline immediately preceding the given position */
-
-#define WAS_NEWLINE(p) \
- ((NLBLOCK->nltype != NLTYPE_FIXED)? \
- ((p) > NLBLOCK->PSSTART && \
- PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \
- &(NLBLOCK->nllen), utf)) \
- : \
- ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \
- RAWUCHARTEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] && \
- (NLBLOCK->nllen == 1 || RAWUCHARTEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \
- ) \
- )
-
-/* When PCRE is compiled as a C++ library, the subject pointer can be replaced
-with a custom type. This makes it possible, for example, to allow pcre_exec()
-to process subject strings that are discontinuous by using a smart pointer
-class. It must always be possible to inspect all of the subject string in
-pcre_exec() because of the way it backtracks. Two macros are required in the
-normal case, for sign-unspecified and unsigned char pointers. The former is
-used for the external interface and appears in pcre.h, which is why its name
-must begin with PCRE_. */
-
-#ifdef CUSTOM_SUBJECT_PTR
-#define PCRE_PUCHAR CUSTOM_SUBJECT_PTR
-#else
-#define PCRE_PUCHAR const pcre_uchar *
-#endif
-
-/* Include the public PCRE header and the definitions of UCP character property
-values. */
-
-#include "pcre.h"
-#include "ucp.h"
-
-#ifdef COMPILE_PCRE32
-/* Assert that the public PCRE_UCHAR32 is a 32-bit type */
-typedef int __assert_pcre_uchar32_size[sizeof(PCRE_UCHAR32) == 4 ? 1 : -1];
-#endif
-
-/* When compiling for use with the Virtual Pascal compiler, these functions
-need to have their names changed. PCRE must be compiled with the -DVPCOMPAT
-option on the command line. */
-
-#ifdef VPCOMPAT
-#define strlen(s) _strlen(s)
-#define strncmp(s1,s2,m) _strncmp(s1,s2,m)
-#define memcmp(s,c,n) _memcmp(s,c,n)
-#define memcpy(d,s,n) _memcpy(d,s,n)
-#define memmove(d,s,n) _memmove(d,s,n)
-#define memset(s,c,n) _memset(s,c,n)
-#else /* VPCOMPAT */
-
-/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
-define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY
-is set. Otherwise, include an emulating function for those systems that have
-neither (there some non-Unix environments where this is the case). */
-
-#ifndef HAVE_MEMMOVE
-#undef memmove /* some systems may have a macro */
-#ifdef HAVE_BCOPY
-#define memmove(a, b, c) bcopy(b, a, c)
-#else /* HAVE_BCOPY */
-static void *
-pcre_memmove(void *d, const void *s, size_t n)
-{
-size_t i;
-unsigned char *dest = (unsigned char *)d;
-const unsigned char *src = (const unsigned char *)s;
-if (dest > src)
- {
- dest += n;
- src += n;
- for (i = 0; i < n; ++i) *(--dest) = *(--src);
- return (void *)dest;
- }
-else
- {
- for (i = 0; i < n; ++i) *dest++ = *src++;
- return (void *)(dest - n);
- }
-}
-#define memmove(a, b, c) pcre_memmove(a, b, c)
-#endif /* not HAVE_BCOPY */
-#endif /* not HAVE_MEMMOVE */
-#endif /* not VPCOMPAT */
-
-
-/* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored
-in big-endian order) by default. These are used, for example, to link from the
-start of a subpattern to its alternatives and its end. The use of 2 bytes per
-offset limits the size of the compiled regex to around 64K, which is big enough
-for almost everybody. However, I received a request for an even bigger limit.
-For this reason, and also to make the code easier to maintain, the storing and
-loading of offsets from the byte string is now handled by the macros that are
-defined here.
-
-The macros are controlled by the value of LINK_SIZE. This defaults to 2 in
-the config.h file, but can be overridden by using -D on the command line. This
-is automated on Unix systems via the "configure" command. */
-
-#if defined COMPILE_PCRE8
-
-#if LINK_SIZE == 2
-
-#define PUT(a,n,d) \
- (a[n] = (d) >> 8), \
- (a[(n)+1] = (d) & 255)
-
-#define GET(a,n) \
- (((a)[n] << 8) | (a)[(n)+1])
-
-#define MAX_PATTERN_SIZE (1 << 16)
-
-
-#elif LINK_SIZE == 3
-
-#define PUT(a,n,d) \
- (a[n] = (d) >> 16), \
- (a[(n)+1] = (d) >> 8), \
- (a[(n)+2] = (d) & 255)
-
-#define GET(a,n) \
- (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])
-
-#define MAX_PATTERN_SIZE (1 << 24)
-
-
-#elif LINK_SIZE == 4
-
-#define PUT(a,n,d) \
- (a[n] = (d) >> 24), \
- (a[(n)+1] = (d) >> 16), \
- (a[(n)+2] = (d) >> 8), \
- (a[(n)+3] = (d) & 255)
-
-#define GET(a,n) \
- (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])
-
-/* Keep it positive */
-#define MAX_PATTERN_SIZE (1 << 30)
-
-#else
-#error LINK_SIZE must be either 2, 3, or 4
-#endif
-
-#elif defined COMPILE_PCRE16
-
-#if LINK_SIZE == 2
-
-/* Redefine LINK_SIZE as a multiple of sizeof(pcre_uchar) */
-#undef LINK_SIZE
-#define LINK_SIZE 1
-
-#define PUT(a,n,d) \
- (a[n] = (d))
-
-#define GET(a,n) \
- (a[n])
-
-#define MAX_PATTERN_SIZE (1 << 16)
-
-#elif LINK_SIZE == 3 || LINK_SIZE == 4
-
-/* Redefine LINK_SIZE as a multiple of sizeof(pcre_uchar) */
-#undef LINK_SIZE
-#define LINK_SIZE 2
-
-#define PUT(a,n,d) \
- (a[n] = (d) >> 16), \
- (a[(n)+1] = (d) & 65535)
-
-#define GET(a,n) \
- (((a)[n] << 16) | (a)[(n)+1])
-
-/* Keep it positive */
-#define MAX_PATTERN_SIZE (1 << 30)
-
-#else
-#error LINK_SIZE must be either 2, 3, or 4
-#endif
-
-#elif defined COMPILE_PCRE32
-
-/* Only supported LINK_SIZE is 4 */
-/* Redefine LINK_SIZE as a multiple of sizeof(pcre_uchar) */
-#undef LINK_SIZE
-#define LINK_SIZE 1
-
-#define PUT(a,n,d) \
- (a[n] = (d))
-
-#define GET(a,n) \
- (a[n])
-
-/* Keep it positive */
-#define MAX_PATTERN_SIZE (1 << 30)
-
-#else
-#error Unsupported compiling mode
-#endif /* COMPILE_PCRE[8|16|32] */
-
-/* Convenience macro defined in terms of the others */
-
-#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE
-
-
-/* PCRE uses some other 2-byte quantities that do not change when the size of
-offsets changes. There are used for repeat counts and for other things such as
-capturing parenthesis numbers in back references. */
-
-#if defined COMPILE_PCRE8
-
-#define IMM2_SIZE 2
-
-#define PUT2(a,n,d) \
- a[n] = (d) >> 8; \
- a[(n)+1] = (d) & 255
-
-/* For reasons that I do not understand, the expression in this GET2 macro is
-treated by gcc as a signed expression, even when a is declared as unsigned. It
-seems that any kind of arithmetic results in a signed value. */
-
-#define GET2(a,n) \
- (unsigned int)(((a)[n] << 8) | (a)[(n)+1])
-
-#elif defined COMPILE_PCRE16
-
-#define IMM2_SIZE 1
-
-#define PUT2(a,n,d) \
- a[n] = d
-
-#define GET2(a,n) \
- a[n]
-
-#elif defined COMPILE_PCRE32
-
-#define IMM2_SIZE 1
-
-#define PUT2(a,n,d) \
- a[n] = d
-
-#define GET2(a,n) \
- a[n]
-
-#else
-#error Unsupported compiling mode
-#endif /* COMPILE_PCRE[8|16|32] */
-
-#define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE
-
-/* The maximum length of a MARK name is currently one data unit; it may be
-changed in future to be a fixed number of bytes or to depend on LINK_SIZE. */
-
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
-#define MAX_MARK ((1u << 16) - 1)
-#else
-#define MAX_MARK ((1u << 8) - 1)
-#endif
-
-/* When UTF encoding is being used, a character is no longer just a single
-byte. The macros for character handling generate simple sequences when used in
-character-mode, and more complicated ones for UTF characters. GETCHARLENTEST
-and other macros are not used when UTF is not supported, so they are not
-defined. To make sure they can never even appear when UTF support is omitted,
-we don't even define them. */
-
-#ifndef SUPPORT_UTF
-
-/* #define MAX_VALUE_FOR_SINGLE_CHAR */
-/* #define HAS_EXTRALEN(c) */
-/* #define GET_EXTRALEN(c) */
-/* #define NOT_FIRSTCHAR(c) */
-#define GETCHAR(c, eptr) c = *eptr;
-#define GETCHARTEST(c, eptr) c = *eptr;
-#define GETCHARINC(c, eptr) c = *eptr++;
-#define GETCHARINCTEST(c, eptr) c = *eptr++;
-#define GETCHARLEN(c, eptr, len) c = *eptr;
-#define RAWUCHAR(eptr) (*(eptr))
-#define RAWUCHARINC(eptr) (*(eptr)++)
-#define RAWUCHARTEST(eptr) (*(eptr))
-#define RAWUCHARINCTEST(eptr) (*(eptr)++)
-/* #define GETCHARLENTEST(c, eptr, len) */
-/* #define BACKCHAR(eptr) */
-/* #define FORWARDCHAR(eptr) */
-/* #define ACROSSCHAR(condition, eptr, action) */
-
-#else /* SUPPORT_UTF */
-
-/* Tests whether the code point needs extra characters to decode. */
-
-#define HASUTF8EXTRALEN(c) ((c) >= 0xc0)
-
-/* Base macro to pick up the remaining bytes of a UTF-8 character, not
-advancing the pointer. */
-
-#define GETUTF8(c, eptr) \
- { \
- if ((c & 0x20) == 0) \
- c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \
- else if ((c & 0x10) == 0) \
- c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
- else if ((c & 0x08) == 0) \
- c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \
- ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \
- else if ((c & 0x04) == 0) \
- c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \
- ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \
- (eptr[4] & 0x3f); \
- else \
- c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \
- ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \
- ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \
- }
-
-/* Base macro to pick up the remaining bytes of a UTF-8 character, advancing
-the pointer. */
-
-#define GETUTF8INC(c, eptr) \
- { \
- if ((c & 0x20) == 0) \
- c = ((c & 0x1f) << 6) | (*eptr++ & 0x3f); \
- else if ((c & 0x10) == 0) \
- { \
- c = ((c & 0x0f) << 12) | ((*eptr & 0x3f) << 6) | (eptr[1] & 0x3f); \
- eptr += 2; \
- } \
- else if ((c & 0x08) == 0) \
- { \
- c = ((c & 0x07) << 18) | ((*eptr & 0x3f) << 12) | \
- ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
- eptr += 3; \
- } \
- else if ((c & 0x04) == 0) \
- { \
- c = ((c & 0x03) << 24) | ((*eptr & 0x3f) << 18) | \
- ((eptr[1] & 0x3f) << 12) | ((eptr[2] & 0x3f) << 6) | \
- (eptr[3] & 0x3f); \
- eptr += 4; \
- } \
- else \
- { \
- c = ((c & 0x01) << 30) | ((*eptr & 0x3f) << 24) | \
- ((eptr[1] & 0x3f) << 18) | ((eptr[2] & 0x3f) << 12) | \
- ((eptr[3] & 0x3f) << 6) | (eptr[4] & 0x3f); \
- eptr += 5; \
- } \
- }
-
-#if defined COMPILE_PCRE8
-
-/* These macros were originally written in the form of loops that used data
-from the tables whose names start with PRIV(utf8_table). They were rewritten by
-a user so as not to use loops, because in some environments this gives a
-significant performance advantage, and it seems never to do any harm. */
-
-/* Tells the biggest code point which can be encoded as a single character. */
-
-#define MAX_VALUE_FOR_SINGLE_CHAR 127
-
-/* Tests whether the code point needs extra characters to decode. */
-
-#define HAS_EXTRALEN(c) ((c) >= 0xc0)
-
-/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
-Otherwise it has an undefined behaviour. */
-
-#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f])
-
-/* Returns TRUE, if the given character is not the first character
-of a UTF sequence. */
-
-#define NOT_FIRSTCHAR(c) (((c) & 0xc0) == 0x80)
-
-/* Get the next UTF-8 character, not advancing the pointer. This is called when
-we know we are in UTF-8 mode. */
-
-#define GETCHAR(c, eptr) \
- c = *eptr; \
- if (c >= 0xc0) GETUTF8(c, eptr);
-
-/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the
-pointer. */
-
-#define GETCHARTEST(c, eptr) \
- c = *eptr; \
- if (utf && c >= 0xc0) GETUTF8(c, eptr);
-
-/* Get the next UTF-8 character, advancing the pointer. This is called when we
-know we are in UTF-8 mode. */
-
-#define GETCHARINC(c, eptr) \
- c = *eptr++; \
- if (c >= 0xc0) GETUTF8INC(c, eptr);
-
-/* Get the next character, testing for UTF-8 mode, and advancing the pointer.
-This is called when we don't know if we are in UTF-8 mode. */
-
-#define GETCHARINCTEST(c, eptr) \
- c = *eptr++; \
- if (utf && c >= 0xc0) GETUTF8INC(c, eptr);
-
-/* Base macro to pick up the remaining bytes of a UTF-8 character, not
-advancing the pointer, incrementing the length. */
-
-#define GETUTF8LEN(c, eptr, len) \
- { \
- if ((c & 0x20) == 0) \
- { \
- c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \
- len++; \
- } \
- else if ((c & 0x10) == 0) \
- { \
- c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
- len += 2; \
- } \
- else if ((c & 0x08) == 0) \
- {\
- c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \
- ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \
- len += 3; \
- } \
- else if ((c & 0x04) == 0) \
- { \
- c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \
- ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \
- (eptr[4] & 0x3f); \
- len += 4; \
- } \
- else \
- {\
- c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \
- ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \
- ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \
- len += 5; \
- } \
- }
-
-/* Get the next UTF-8 character, not advancing the pointer, incrementing length
-if there are extra bytes. This is called when we know we are in UTF-8 mode. */
-
-#define GETCHARLEN(c, eptr, len) \
- c = *eptr; \
- if (c >= 0xc0) GETUTF8LEN(c, eptr, len);
-
-/* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the
-pointer, incrementing length if there are extra bytes. This is called when we
-do not know if we are in UTF-8 mode. */
-
-#define GETCHARLENTEST(c, eptr, len) \
- c = *eptr; \
- if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len);
-
-/* Returns the next uchar, not advancing the pointer. This is called when
-we know we are in UTF mode. */
-
-#define RAWUCHAR(eptr) \
- (*(eptr))
-
-/* Returns the next uchar, advancing the pointer. This is called when
-we know we are in UTF mode. */
-
-#define RAWUCHARINC(eptr) \
- (*((eptr)++))
-
-/* Returns the next uchar, testing for UTF mode, and not advancing the
-pointer. */
-
-#define RAWUCHARTEST(eptr) \
- (*(eptr))
-
-/* Returns the next uchar, testing for UTF mode, advancing the
-pointer. */
-
-#define RAWUCHARINCTEST(eptr) \
- (*((eptr)++))
-
-/* If the pointer is not at the start of a character, move it back until
-it is. This is called only in UTF-8 mode - we don't put a test within the macro
-because almost all calls are already within a block of UTF-8 only code. */
-
-#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr--
-
-/* Same as above, just in the other direction. */
-#define FORWARDCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr++
-
-/* Same as above, but it allows a fully customizable form. */
-#define ACROSSCHAR(condition, eptr, action) \
- while((condition) && ((eptr) & 0xc0) == 0x80) action
-
-#elif defined COMPILE_PCRE16
-
-/* Tells the biggest code point which can be encoded as a single character. */
-
-#define MAX_VALUE_FOR_SINGLE_CHAR 65535
-
-/* Tests whether the code point needs extra characters to decode. */
-
-#define HAS_EXTRALEN(c) (((c) & 0xfc00) == 0xd800)
-
-/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
-Otherwise it has an undefined behaviour. */
-
-#define GET_EXTRALEN(c) 1
-
-/* Returns TRUE, if the given character is not the first character
-of a UTF sequence. */
-
-#define NOT_FIRSTCHAR(c) (((c) & 0xfc00) == 0xdc00)
-
-/* Base macro to pick up the low surrogate of a UTF-16 character, not
-advancing the pointer. */
-
-#define GETUTF16(c, eptr) \
- { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; }
-
-/* Get the next UTF-16 character, not advancing the pointer. This is called when
-we know we are in UTF-16 mode. */
-
-#define GETCHAR(c, eptr) \
- c = *eptr; \
- if ((c & 0xfc00) == 0xd800) GETUTF16(c, eptr);
-
-/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the
-pointer. */
-
-#define GETCHARTEST(c, eptr) \
- c = *eptr; \
- if (utf && (c & 0xfc00) == 0xd800) GETUTF16(c, eptr);
-
-/* Base macro to pick up the low surrogate of a UTF-16 character, advancing
-the pointer. */
-
-#define GETUTF16INC(c, eptr) \
- { c = (((c & 0x3ff) << 10) | (*eptr++ & 0x3ff)) + 0x10000; }
-
-/* Get the next UTF-16 character, advancing the pointer. This is called when we
-know we are in UTF-16 mode. */
-
-#define GETCHARINC(c, eptr) \
- c = *eptr++; \
- if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr);
-
-/* Get the next character, testing for UTF-16 mode, and advancing the pointer.
-This is called when we don't know if we are in UTF-16 mode. */
-
-#define GETCHARINCTEST(c, eptr) \
- c = *eptr++; \
- if (utf && (c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr);
-
-/* Base macro to pick up the low surrogate of a UTF-16 character, not
-advancing the pointer, incrementing the length. */
-
-#define GETUTF16LEN(c, eptr, len) \
- { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; len++; }
-
-/* Get the next UTF-16 character, not advancing the pointer, incrementing
-length if there is a low surrogate. This is called when we know we are in
-UTF-16 mode. */
-
-#define GETCHARLEN(c, eptr, len) \
- c = *eptr; \
- if ((c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len);
-
-/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the
-pointer, incrementing length if there is a low surrogate. This is called when
-we do not know if we are in UTF-16 mode. */
-
-#define GETCHARLENTEST(c, eptr, len) \
- c = *eptr; \
- if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len);
-
-/* Returns the next uchar, not advancing the pointer. This is called when
-we know we are in UTF mode. */
-
-#define RAWUCHAR(eptr) \
- (*(eptr))
-
-/* Returns the next uchar, advancing the pointer. This is called when
-we know we are in UTF mode. */
-
-#define RAWUCHARINC(eptr) \
- (*((eptr)++))
-
-/* Returns the next uchar, testing for UTF mode, and not advancing the
-pointer. */
-
-#define RAWUCHARTEST(eptr) \
- (*(eptr))
-
-/* Returns the next uchar, testing for UTF mode, advancing the
-pointer. */
-
-#define RAWUCHARINCTEST(eptr) \
- (*((eptr)++))
-
-/* If the pointer is not at the start of a character, move it back until
-it is. This is called only in UTF-16 mode - we don't put a test within the
-macro because almost all calls are already within a block of UTF-16 only
-code. */
-
-#define BACKCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr--
-
-/* Same as above, just in the other direction. */
-#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr++
-
-/* Same as above, but it allows a fully customizable form. */
-#define ACROSSCHAR(condition, eptr, action) \
- if ((condition) && ((eptr) & 0xfc00) == 0xdc00) action
-
-#elif defined COMPILE_PCRE32
-
-/* These are trivial for the 32-bit library, since all UTF-32 characters fit
-into one pcre_uchar unit. */
-#define MAX_VALUE_FOR_SINGLE_CHAR (0x10ffffu)
-#define HAS_EXTRALEN(c) (0)
-#define GET_EXTRALEN(c) (0)
-#define NOT_FIRSTCHAR(c) (0)
-
-/* Get the next UTF-32 character, not advancing the pointer. This is called when
-we know we are in UTF-32 mode. */
-
-#define GETCHAR(c, eptr) \
- c = *(eptr);
-
-/* Get the next UTF-32 character, testing for UTF-32 mode, and not advancing the
-pointer. */
-
-#define GETCHARTEST(c, eptr) \
- c = *(eptr);
-
-/* Get the next UTF-32 character, advancing the pointer. This is called when we
-know we are in UTF-32 mode. */
-
-#define GETCHARINC(c, eptr) \
- c = *((eptr)++);
-
-/* Get the next character, testing for UTF-32 mode, and advancing the pointer.
-This is called when we don't know if we are in UTF-32 mode. */
-
-#define GETCHARINCTEST(c, eptr) \
- c = *((eptr)++);
-
-/* Get the next UTF-32 character, not advancing the pointer, not incrementing
-length (since all UTF-32 is of length 1). This is called when we know we are in
-UTF-32 mode. */
-
-#define GETCHARLEN(c, eptr, len) \
- GETCHAR(c, eptr)
-
-/* Get the next UTF-32character, testing for UTF-32 mode, not advancing the
-pointer, not incrementing the length (since all UTF-32 is of length 1).
-This is called when we do not know if we are in UTF-32 mode. */
-
-#define GETCHARLENTEST(c, eptr, len) \
- GETCHARTEST(c, eptr)
-
-/* Returns the next uchar, not advancing the pointer. This is called when
-we know we are in UTF mode. */
-
-#define RAWUCHAR(eptr) \
- (*(eptr))
-
-/* Returns the next uchar, advancing the pointer. This is called when
-we know we are in UTF mode. */
-
-#define RAWUCHARINC(eptr) \
- (*((eptr)++))
-
-/* Returns the next uchar, testing for UTF mode, and not advancing the
-pointer. */
-
-#define RAWUCHARTEST(eptr) \
- (*(eptr))
-
-/* Returns the next uchar, testing for UTF mode, advancing the
-pointer. */
-
-#define RAWUCHARINCTEST(eptr) \
- (*((eptr)++))
-
-/* If the pointer is not at the start of a character, move it back until
-it is. This is called only in UTF-32 mode - we don't put a test within the
-macro because almost all calls are already within a block of UTF-32 only
-code.
-These are all no-ops since all UTF-32 characters fit into one pcre_uchar. */
-
-#define BACKCHAR(eptr) do { } while (0)
-
-/* Same as above, just in the other direction. */
-#define FORWARDCHAR(eptr) do { } while (0)
-
-/* Same as above, but it allows a fully customizable form. */
-#define ACROSSCHAR(condition, eptr, action) do { } while (0)
-
-#else
-#error Unsupported compiling mode
-#endif /* COMPILE_PCRE[8|16|32] */
-
-#endif /* SUPPORT_UTF */
-
-/* Tests for Unicode horizontal and vertical whitespace characters must check a
-number of different values. Using a switch statement for this generates the
-fastest code (no loop, no memory access), and there are several places in the
-interpreter code where this happens. In order to ensure that all the case lists
-remain in step, we use macros so that there is only one place where the lists
-are defined.
-
-These values are also required as lists in pcre_compile.c when processing \h,
-\H, \v and \V in a character class. The lists are defined in pcre_tables.c, but
-macros that define the values are here so that all the definitions are
-together. The lists must be in ascending character order, terminated by
-NOTACHAR (which is 0xffffffff).
-
-Any changes should ensure that the various macros are kept in step with each
-other. NOTE: The values also appear in pcre_jit_compile.c. */
-
-/* ------ ASCII/Unicode environments ------ */
-
-#ifndef EBCDIC
-
-#define HSPACE_LIST \
- CHAR_HT, CHAR_SPACE, 0xa0, \
- 0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \
- 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202f, 0x205f, 0x3000, \
- NOTACHAR
-
-#define HSPACE_MULTIBYTE_CASES \
- case 0x1680: /* OGHAM SPACE MARK */ \
- case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ \
- case 0x2000: /* EN QUAD */ \
- case 0x2001: /* EM QUAD */ \
- case 0x2002: /* EN SPACE */ \
- case 0x2003: /* EM SPACE */ \
- case 0x2004: /* THREE-PER-EM SPACE */ \
- case 0x2005: /* FOUR-PER-EM SPACE */ \
- case 0x2006: /* SIX-PER-EM SPACE */ \
- case 0x2007: /* FIGURE SPACE */ \
- case 0x2008: /* PUNCTUATION SPACE */ \
- case 0x2009: /* THIN SPACE */ \
- case 0x200A: /* HAIR SPACE */ \
- case 0x202f: /* NARROW NO-BREAK SPACE */ \
- case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ \
- case 0x3000 /* IDEOGRAPHIC SPACE */
-
-#define HSPACE_BYTE_CASES \
- case CHAR_HT: \
- case CHAR_SPACE: \
- case 0xa0 /* NBSP */
-
-#define HSPACE_CASES \
- HSPACE_BYTE_CASES: \
- HSPACE_MULTIBYTE_CASES
-
-#define VSPACE_LIST \
- CHAR_LF, CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, 0x2028, 0x2029, NOTACHAR
-
-#define VSPACE_MULTIBYTE_CASES \
- case 0x2028: /* LINE SEPARATOR */ \
- case 0x2029 /* PARAGRAPH SEPARATOR */
-
-#define VSPACE_BYTE_CASES \
- case CHAR_LF: \
- case CHAR_VT: \
- case CHAR_FF: \
- case CHAR_CR: \
- case CHAR_NEL
-
-#define VSPACE_CASES \
- VSPACE_BYTE_CASES: \
- VSPACE_MULTIBYTE_CASES
-
-/* ------ EBCDIC environments ------ */
-
-#else
-#define HSPACE_LIST CHAR_HT, CHAR_SPACE
-
-#define HSPACE_BYTE_CASES \
- case CHAR_HT: \
- case CHAR_SPACE
-
-#define HSPACE_CASES HSPACE_BYTE_CASES
-
-#ifdef EBCDIC_NL25
-#define VSPACE_LIST \
- CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, CHAR_LF, NOTACHAR
-#else
-#define VSPACE_LIST \
- CHAR_VT, CHAR_FF, CHAR_CR, CHAR_LF, CHAR_NEL, NOTACHAR
-#endif
-
-#define VSPACE_BYTE_CASES \
- case CHAR_LF: \
- case CHAR_VT: \
- case CHAR_FF: \
- case CHAR_CR: \
- case CHAR_NEL
-
-#define VSPACE_CASES VSPACE_BYTE_CASES
-#endif /* EBCDIC */
-
-/* ------ End of whitespace macros ------ */
-
-
-
-/* Private flags containing information about the compiled regex. They used to
-live at the top end of the options word, but that got almost full, so they were
-moved to a 16-bit flags word - which got almost full, so now they are in a
-32-bit flags word. From release 8.00, PCRE_NOPARTIAL is unused, as the
-restrictions on partial matching have been lifted. It remains for backwards
-compatibility. */
-
-#define PCRE_MODE8 0x00000001 /* compiled in 8 bit mode */
-#define PCRE_MODE16 0x00000002 /* compiled in 16 bit mode */
-#define PCRE_MODE32 0x00000004 /* compiled in 32 bit mode */
-#define PCRE_FIRSTSET 0x00000010 /* first_char is set */
-#define PCRE_FCH_CASELESS 0x00000020 /* caseless first char */
-#define PCRE_REQCHSET 0x00000040 /* req_byte is set */
-#define PCRE_RCH_CASELESS 0x00000080 /* caseless requested char */
-#define PCRE_STARTLINE 0x00000100 /* start after \n for multiline */
-#define PCRE_NOPARTIAL 0x00000200 /* can't use partial with this regex */
-#define PCRE_JCHANGED 0x00000400 /* j option used in regex */
-#define PCRE_HASCRORLF 0x00000800 /* explicit \r or \n in pattern */
-#define PCRE_HASTHEN 0x00001000 /* pattern contains (*THEN) */
-#define PCRE_MLSET 0x00002000 /* match limit set by regex */
-#define PCRE_RLSET 0x00004000 /* recursion limit set by regex */
-
-#if defined COMPILE_PCRE8
-#define PCRE_MODE PCRE_MODE8
-#elif defined COMPILE_PCRE16
-#define PCRE_MODE PCRE_MODE16
-#elif defined COMPILE_PCRE32
-#define PCRE_MODE PCRE_MODE32
-#endif
-#define PCRE_MODE_MASK (PCRE_MODE8 | PCRE_MODE16 | PCRE_MODE32)
-
-/* Flags for the "extra" block produced by pcre_study(). */
-
-#define PCRE_STUDY_MAPPED 0x0001 /* a map of starting chars exists */
-#define PCRE_STUDY_MINLEN 0x0002 /* a minimum length field exists */
-
-/* Masks for identifying the public options that are permitted at compile
-time, run time, or study time, respectively. */
-
-#define PCRE_NEWLINE_BITS (PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_ANY| \
- PCRE_NEWLINE_ANYCRLF)
-
-#define PUBLIC_COMPILE_OPTIONS \
- (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
- PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \
- PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \
- PCRE_DUPNAMES|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
- PCRE_JAVASCRIPT_COMPAT|PCRE_UCP|PCRE_NO_START_OPTIMIZE|PCRE_NEVER_UTF)
-
-#define PUBLIC_EXEC_OPTIONS \
- (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
- PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_NEWLINE_BITS| \
- PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE|PCRE_NO_START_OPTIMIZE)
-
-#define PUBLIC_DFA_EXEC_OPTIONS \
- (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
- PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_DFA_SHORTEST| \
- PCRE_DFA_RESTART|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
- PCRE_NO_START_OPTIMIZE)
-
-#define PUBLIC_STUDY_OPTIONS \
- (PCRE_STUDY_JIT_COMPILE|PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE| \
- PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE|PCRE_STUDY_EXTRA_NEEDED)
-
-#define PUBLIC_JIT_EXEC_OPTIONS \
- (PCRE_NO_UTF8_CHECK|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|\
- PCRE_NOTEMPTY_ATSTART|PCRE_PARTIAL_SOFT|PCRE_PARTIAL_HARD)
-
-/* Magic number to provide a small check against being handed junk. */
-
-#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */
-
-/* This variable is used to detect a loaded regular expression
-in different endianness. */
-
-#define REVERSED_MAGIC_NUMBER 0x45524350UL /* 'ERCP' */
-
-/* The maximum remaining length of subject we are prepared to search for a
-req_byte match. */
-
-#define REQ_BYTE_MAX 1000
-
-/* Miscellaneous definitions. The #ifndef is to pacify compiler warnings in
-environments where these macros are defined elsewhere. Unfortunately, there
-is no way to do the same for the typedef. */
-
-typedef int BOOL;
-
-#ifndef FALSE
-#define FALSE 0
-#define TRUE 1
-#endif
-
-/* If PCRE is to support UTF-8 on EBCDIC platforms, we cannot use normal
-character constants like '*' because the compiler would emit their EBCDIC code,
-which is different from their ASCII/UTF-8 code. Instead we define macros for
-the characters so that they always use the ASCII/UTF-8 code when UTF-8 support
-is enabled. When UTF-8 support is not enabled, the definitions use character
-literals. Both character and string versions of each character are needed, and
-there are some longer strings as well.
-
-This means that, on EBCDIC platforms, the PCRE library can handle either
-EBCDIC, or UTF-8, but not both. To support both in the same compiled library
-would need different lookups depending on whether PCRE_UTF8 was set or not.
-This would make it impossible to use characters in switch/case statements,
-which would reduce performance. For a theoretical use (which nobody has asked
-for) in a minority area (EBCDIC platforms), this is not sensible. Any
-application that did need both could compile two versions of the library, using
-macros to give the functions distinct names. */
-
-#ifndef SUPPORT_UTF
-
-/* UTF-8 support is not enabled; use the platform-dependent character literals
-so that PCRE works in both ASCII and EBCDIC environments, but only in non-UTF
-mode. Newline characters are problematic in EBCDIC. Though it has CR and LF
-characters, a common practice has been to use its NL (0x15) character as the
-line terminator in C-like processing environments. However, sometimes the LF
-(0x25) character is used instead, according to this Unicode document:
-
-http://unicode.org/standard/reports/tr13/tr13-5.html
-
-PCRE defaults EBCDIC NL to 0x15, but has a build-time option to select 0x25
-instead. Whichever is *not* chosen is defined as NEL.
-
-In both ASCII and EBCDIC environments, CHAR_NL and CHAR_LF are synonyms for the
-same code point. */
-
-#ifdef EBCDIC
-
-#ifndef EBCDIC_NL25
-#define CHAR_NL '\x15'
-#define CHAR_NEL '\x25'
-#define STR_NL "\x15"
-#define STR_NEL "\x25"
-#else
-#define CHAR_NL '\x25'
-#define CHAR_NEL '\x15'
-#define STR_NL "\x25"
-#define STR_NEL "\x15"
-#endif
-
-#define CHAR_LF CHAR_NL
-#define STR_LF STR_NL
-
-#define CHAR_ESC '\047'
-#define CHAR_DEL '\007'
-#define STR_ESC "\047"
-#define STR_DEL "\007"
-
-#else /* Not EBCDIC */
-
-/* In ASCII/Unicode, linefeed is '\n' and we equate this to NL for
-compatibility. NEL is the Unicode newline character; make sure it is
-a positive value. */
-
-#define CHAR_LF '\n'
-#define CHAR_NL CHAR_LF
-#define CHAR_NEL ((unsigned char)'\x85')
-#define CHAR_ESC '\033'
-#define CHAR_DEL '\177'
-
-#define STR_LF "\n"
-#define STR_NL STR_LF
-#define STR_NEL "\x85"
-#define STR_ESC "\033"
-#define STR_DEL "\177"
-
-#endif /* EBCDIC */
-
-/* The remaining definitions work in both environments. */
-
-#define CHAR_NULL '\0'
-#define CHAR_HT '\t'
-#define CHAR_VT '\v'
-#define CHAR_FF '\f'
-#define CHAR_CR '\r'
-#define CHAR_BS '\b'
-#define CHAR_BEL '\a'
-
-#define CHAR_SPACE ' '
-#define CHAR_EXCLAMATION_MARK '!'
-#define CHAR_QUOTATION_MARK '"'
-#define CHAR_NUMBER_SIGN '#'
-#define CHAR_DOLLAR_SIGN '$'
-#define CHAR_PERCENT_SIGN '%'
-#define CHAR_AMPERSAND '&'
-#define CHAR_APOSTROPHE '\''
-#define CHAR_LEFT_PARENTHESIS '('
-#define CHAR_RIGHT_PARENTHESIS ')'
-#define CHAR_ASTERISK '*'
-#define CHAR_PLUS '+'
-#define CHAR_COMMA ','
-#define CHAR_MINUS '-'
-#define CHAR_DOT '.'
-#define CHAR_SLASH '/'
-#define CHAR_0 '0'
-#define CHAR_1 '1'
-#define CHAR_2 '2'
-#define CHAR_3 '3'
-#define CHAR_4 '4'
-#define CHAR_5 '5'
-#define CHAR_6 '6'
-#define CHAR_7 '7'
-#define CHAR_8 '8'
-#define CHAR_9 '9'
-#define CHAR_COLON ':'
-#define CHAR_SEMICOLON ';'
-#define CHAR_LESS_THAN_SIGN '<'
-#define CHAR_EQUALS_SIGN '='
-#define CHAR_GREATER_THAN_SIGN '>'
-#define CHAR_QUESTION_MARK '?'
-#define CHAR_COMMERCIAL_AT '@'
-#define CHAR_A 'A'
-#define CHAR_B 'B'
-#define CHAR_C 'C'
-#define CHAR_D 'D'
-#define CHAR_E 'E'
-#define CHAR_F 'F'
-#define CHAR_G 'G'
-#define CHAR_H 'H'
-#define CHAR_I 'I'
-#define CHAR_J 'J'
-#define CHAR_K 'K'
-#define CHAR_L 'L'
-#define CHAR_M 'M'
-#define CHAR_N 'N'
-#define CHAR_O 'O'
-#define CHAR_P 'P'
-#define CHAR_Q 'Q'
-#define CHAR_R 'R'
-#define CHAR_S 'S'
-#define CHAR_T 'T'
-#define CHAR_U 'U'
-#define CHAR_V 'V'
-#define CHAR_W 'W'
-#define CHAR_X 'X'
-#define CHAR_Y 'Y'
-#define CHAR_Z 'Z'
-#define CHAR_LEFT_SQUARE_BRACKET '['
-#define CHAR_BACKSLASH '\\'
-#define CHAR_RIGHT_SQUARE_BRACKET ']'
-#define CHAR_CIRCUMFLEX_ACCENT '^'
-#define CHAR_UNDERSCORE '_'
-#define CHAR_GRAVE_ACCENT '`'
-#define CHAR_a 'a'
-#define CHAR_b 'b'
-#define CHAR_c 'c'
-#define CHAR_d 'd'
-#define CHAR_e 'e'
-#define CHAR_f 'f'
-#define CHAR_g 'g'
-#define CHAR_h 'h'
-#define CHAR_i 'i'
-#define CHAR_j 'j'
-#define CHAR_k 'k'
-#define CHAR_l 'l'
-#define CHAR_m 'm'
-#define CHAR_n 'n'
-#define CHAR_o 'o'
-#define CHAR_p 'p'
-#define CHAR_q 'q'
-#define CHAR_r 'r'
-#define CHAR_s 's'
-#define CHAR_t 't'
-#define CHAR_u 'u'
-#define CHAR_v 'v'
-#define CHAR_w 'w'
-#define CHAR_x 'x'
-#define CHAR_y 'y'
-#define CHAR_z 'z'
-#define CHAR_LEFT_CURLY_BRACKET '{'
-#define CHAR_VERTICAL_LINE '|'
-#define CHAR_RIGHT_CURLY_BRACKET '}'
-#define CHAR_TILDE '~'
-
-#define STR_HT "\t"
-#define STR_VT "\v"
-#define STR_FF "\f"
-#define STR_CR "\r"
-#define STR_BS "\b"
-#define STR_BEL "\a"
-
-#define STR_SPACE " "
-#define STR_EXCLAMATION_MARK "!"
-#define STR_QUOTATION_MARK "\""
-#define STR_NUMBER_SIGN "#"
-#define STR_DOLLAR_SIGN "$"
-#define STR_PERCENT_SIGN "%"
-#define STR_AMPERSAND "&"
-#define STR_APOSTROPHE "'"
-#define STR_LEFT_PARENTHESIS "("
-#define STR_RIGHT_PARENTHESIS ")"
-#define STR_ASTERISK "*"
-#define STR_PLUS "+"
-#define STR_COMMA ","
-#define STR_MINUS "-"
-#define STR_DOT "."
-#define STR_SLASH "/"
-#define STR_0 "0"
-#define STR_1 "1"
-#define STR_2 "2"
-#define STR_3 "3"
-#define STR_4 "4"
-#define STR_5 "5"
-#define STR_6 "6"
-#define STR_7 "7"
-#define STR_8 "8"
-#define STR_9 "9"
-#define STR_COLON ":"
-#define STR_SEMICOLON ";"
-#define STR_LESS_THAN_SIGN "<"
-#define STR_EQUALS_SIGN "="
-#define STR_GREATER_THAN_SIGN ">"
-#define STR_QUESTION_MARK "?"
-#define STR_COMMERCIAL_AT "@"
-#define STR_A "A"
-#define STR_B "B"
-#define STR_C "C"
-#define STR_D "D"
-#define STR_E "E"
-#define STR_F "F"
-#define STR_G "G"
-#define STR_H "H"
-#define STR_I "I"
-#define STR_J "J"
-#define STR_K "K"
-#define STR_L "L"
-#define STR_M "M"
-#define STR_N "N"
-#define STR_O "O"
-#define STR_P "P"
-#define STR_Q "Q"
-#define STR_R "R"
-#define STR_S "S"
-#define STR_T "T"
-#define STR_U "U"
-#define STR_V "V"
-#define STR_W "W"
-#define STR_X "X"
-#define STR_Y "Y"
-#define STR_Z "Z"
-#define STR_LEFT_SQUARE_BRACKET "["
-#define STR_BACKSLASH "\\"
-#define STR_RIGHT_SQUARE_BRACKET "]"
-#define STR_CIRCUMFLEX_ACCENT "^"
-#define STR_UNDERSCORE "_"
-#define STR_GRAVE_ACCENT "`"
-#define STR_a "a"
-#define STR_b "b"
-#define STR_c "c"
-#define STR_d "d"
-#define STR_e "e"
-#define STR_f "f"
-#define STR_g "g"
-#define STR_h "h"
-#define STR_i "i"
-#define STR_j "j"
-#define STR_k "k"
-#define STR_l "l"
-#define STR_m "m"
-#define STR_n "n"
-#define STR_o "o"
-#define STR_p "p"
-#define STR_q "q"
-#define STR_r "r"
-#define STR_s "s"
-#define STR_t "t"
-#define STR_u "u"
-#define STR_v "v"
-#define STR_w "w"
-#define STR_x "x"
-#define STR_y "y"
-#define STR_z "z"
-#define STR_LEFT_CURLY_BRACKET "{"
-#define STR_VERTICAL_LINE "|"
-#define STR_RIGHT_CURLY_BRACKET "}"
-#define STR_TILDE "~"
-
-#define STRING_ACCEPT0 "ACCEPT\0"
-#define STRING_COMMIT0 "COMMIT\0"
-#define STRING_F0 "F\0"
-#define STRING_FAIL0 "FAIL\0"
-#define STRING_MARK0 "MARK\0"
-#define STRING_PRUNE0 "PRUNE\0"
-#define STRING_SKIP0 "SKIP\0"
-#define STRING_THEN "THEN"
-
-#define STRING_alpha0 "alpha\0"
-#define STRING_lower0 "lower\0"
-#define STRING_upper0 "upper\0"
-#define STRING_alnum0 "alnum\0"
-#define STRING_ascii0 "ascii\0"
-#define STRING_blank0 "blank\0"
-#define STRING_cntrl0 "cntrl\0"
-#define STRING_digit0 "digit\0"
-#define STRING_graph0 "graph\0"
-#define STRING_print0 "print\0"
-#define STRING_punct0 "punct\0"
-#define STRING_space0 "space\0"
-#define STRING_word0 "word\0"
-#define STRING_xdigit "xdigit"
-
-#define STRING_DEFINE "DEFINE"
-
-#define STRING_CR_RIGHTPAR "CR)"
-#define STRING_LF_RIGHTPAR "LF)"
-#define STRING_CRLF_RIGHTPAR "CRLF)"
-#define STRING_ANY_RIGHTPAR "ANY)"
-#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)"
-#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)"
-#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)"
-#define STRING_UTF8_RIGHTPAR "UTF8)"
-#define STRING_UTF16_RIGHTPAR "UTF16)"
-#define STRING_UTF32_RIGHTPAR "UTF32)"
-#define STRING_UTF_RIGHTPAR "UTF)"
-#define STRING_UCP_RIGHTPAR "UCP)"
-#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)"
-#define STRING_LIMIT_MATCH_EQ "LIMIT_MATCH="
-#define STRING_LIMIT_RECURSION_EQ "LIMIT_RECURSION="
-
-#else /* SUPPORT_UTF */
-
-/* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This
-works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode
-only. */
-
-#define CHAR_HT '\011'
-#define CHAR_VT '\013'
-#define CHAR_FF '\014'
-#define CHAR_CR '\015'
-#define CHAR_LF '\012'
-#define CHAR_NL CHAR_LF
-#define CHAR_NEL ((unsigned char)'\x85')
-#define CHAR_BS '\010'
-#define CHAR_BEL '\007'
-#define CHAR_ESC '\033'
-#define CHAR_DEL '\177'
-
-#define CHAR_NULL '\0'
-#define CHAR_SPACE '\040'
-#define CHAR_EXCLAMATION_MARK '\041'
-#define CHAR_QUOTATION_MARK '\042'
-#define CHAR_NUMBER_SIGN '\043'
-#define CHAR_DOLLAR_SIGN '\044'
-#define CHAR_PERCENT_SIGN '\045'
-#define CHAR_AMPERSAND '\046'
-#define CHAR_APOSTROPHE '\047'
-#define CHAR_LEFT_PARENTHESIS '\050'
-#define CHAR_RIGHT_PARENTHESIS '\051'
-#define CHAR_ASTERISK '\052'
-#define CHAR_PLUS '\053'
-#define CHAR_COMMA '\054'
-#define CHAR_MINUS '\055'
-#define CHAR_DOT '\056'
-#define CHAR_SLASH '\057'
-#define CHAR_0 '\060'
-#define CHAR_1 '\061'
-#define CHAR_2 '\062'
-#define CHAR_3 '\063'
-#define CHAR_4 '\064'
-#define CHAR_5 '\065'
-#define CHAR_6 '\066'
-#define CHAR_7 '\067'
-#define CHAR_8 '\070'
-#define CHAR_9 '\071'
-#define CHAR_COLON '\072'
-#define CHAR_SEMICOLON '\073'
-#define CHAR_LESS_THAN_SIGN '\074'
-#define CHAR_EQUALS_SIGN '\075'
-#define CHAR_GREATER_THAN_SIGN '\076'
-#define CHAR_QUESTION_MARK '\077'
-#define CHAR_COMMERCIAL_AT '\100'
-#define CHAR_A '\101'
-#define CHAR_B '\102'
-#define CHAR_C '\103'
-#define CHAR_D '\104'
-#define CHAR_E '\105'
-#define CHAR_F '\106'
-#define CHAR_G '\107'
-#define CHAR_H '\110'
-#define CHAR_I '\111'
-#define CHAR_J '\112'
-#define CHAR_K '\113'
-#define CHAR_L '\114'
-#define CHAR_M '\115'
-#define CHAR_N '\116'
-#define CHAR_O '\117'
-#define CHAR_P '\120'
-#define CHAR_Q '\121'
-#define CHAR_R '\122'
-#define CHAR_S '\123'
-#define CHAR_T '\124'
-#define CHAR_U '\125'
-#define CHAR_V '\126'
-#define CHAR_W '\127'
-#define CHAR_X '\130'
-#define CHAR_Y '\131'
-#define CHAR_Z '\132'
-#define CHAR_LEFT_SQUARE_BRACKET '\133'
-#define CHAR_BACKSLASH '\134'
-#define CHAR_RIGHT_SQUARE_BRACKET '\135'
-#define CHAR_CIRCUMFLEX_ACCENT '\136'
-#define CHAR_UNDERSCORE '\137'
-#define CHAR_GRAVE_ACCENT '\140'
-#define CHAR_a '\141'
-#define CHAR_b '\142'
-#define CHAR_c '\143'
-#define CHAR_d '\144'
-#define CHAR_e '\145'
-#define CHAR_f '\146'
-#define CHAR_g '\147'
-#define CHAR_h '\150'
-#define CHAR_i '\151'
-#define CHAR_j '\152'
-#define CHAR_k '\153'
-#define CHAR_l '\154'
-#define CHAR_m '\155'
-#define CHAR_n '\156'
-#define CHAR_o '\157'
-#define CHAR_p '\160'
-#define CHAR_q '\161'
-#define CHAR_r '\162'
-#define CHAR_s '\163'
-#define CHAR_t '\164'
-#define CHAR_u '\165'
-#define CHAR_v '\166'
-#define CHAR_w '\167'
-#define CHAR_x '\170'
-#define CHAR_y '\171'
-#define CHAR_z '\172'
-#define CHAR_LEFT_CURLY_BRACKET '\173'
-#define CHAR_VERTICAL_LINE '\174'
-#define CHAR_RIGHT_CURLY_BRACKET '\175'
-#define CHAR_TILDE '\176'
-
-#define STR_HT "\011"
-#define STR_VT "\013"
-#define STR_FF "\014"
-#define STR_CR "\015"
-#define STR_NL "\012"
-#define STR_BS "\010"
-#define STR_BEL "\007"
-#define STR_ESC "\033"
-#define STR_DEL "\177"
-
-#define STR_SPACE "\040"
-#define STR_EXCLAMATION_MARK "\041"
-#define STR_QUOTATION_MARK "\042"
-#define STR_NUMBER_SIGN "\043"
-#define STR_DOLLAR_SIGN "\044"
-#define STR_PERCENT_SIGN "\045"
-#define STR_AMPERSAND "\046"
-#define STR_APOSTROPHE "\047"
-#define STR_LEFT_PARENTHESIS "\050"
-#define STR_RIGHT_PARENTHESIS "\051"
-#define STR_ASTERISK "\052"
-#define STR_PLUS "\053"
-#define STR_COMMA "\054"
-#define STR_MINUS "\055"
-#define STR_DOT "\056"
-#define STR_SLASH "\057"
-#define STR_0 "\060"
-#define STR_1 "\061"
-#define STR_2 "\062"
-#define STR_3 "\063"
-#define STR_4 "\064"
-#define STR_5 "\065"
-#define STR_6 "\066"
-#define STR_7 "\067"
-#define STR_8 "\070"
-#define STR_9 "\071"
-#define STR_COLON "\072"
-#define STR_SEMICOLON "\073"
-#define STR_LESS_THAN_SIGN "\074"
-#define STR_EQUALS_SIGN "\075"
-#define STR_GREATER_THAN_SIGN "\076"
-#define STR_QUESTION_MARK "\077"
-#define STR_COMMERCIAL_AT "\100"
-#define STR_A "\101"
-#define STR_B "\102"
-#define STR_C "\103"
-#define STR_D "\104"
-#define STR_E "\105"
-#define STR_F "\106"
-#define STR_G "\107"
-#define STR_H "\110"
-#define STR_I "\111"
-#define STR_J "\112"
-#define STR_K "\113"
-#define STR_L "\114"
-#define STR_M "\115"
-#define STR_N "\116"
-#define STR_O "\117"
-#define STR_P "\120"
-#define STR_Q "\121"
-#define STR_R "\122"
-#define STR_S "\123"
-#define STR_T "\124"
-#define STR_U "\125"
-#define STR_V "\126"
-#define STR_W "\127"
-#define STR_X "\130"
-#define STR_Y "\131"
-#define STR_Z "\132"
-#define STR_LEFT_SQUARE_BRACKET "\133"
-#define STR_BACKSLASH "\134"
-#define STR_RIGHT_SQUARE_BRACKET "\135"
-#define STR_CIRCUMFLEX_ACCENT "\136"
-#define STR_UNDERSCORE "\137"
-#define STR_GRAVE_ACCENT "\140"
-#define STR_a "\141"
-#define STR_b "\142"
-#define STR_c "\143"
-#define STR_d "\144"
-#define STR_e "\145"
-#define STR_f "\146"
-#define STR_g "\147"
-#define STR_h "\150"
-#define STR_i "\151"
-#define STR_j "\152"
-#define STR_k "\153"
-#define STR_l "\154"
-#define STR_m "\155"
-#define STR_n "\156"
-#define STR_o "\157"
-#define STR_p "\160"
-#define STR_q "\161"
-#define STR_r "\162"
-#define STR_s "\163"
-#define STR_t "\164"
-#define STR_u "\165"
-#define STR_v "\166"
-#define STR_w "\167"
-#define STR_x "\170"
-#define STR_y "\171"
-#define STR_z "\172"
-#define STR_LEFT_CURLY_BRACKET "\173"
-#define STR_VERTICAL_LINE "\174"
-#define STR_RIGHT_CURLY_BRACKET "\175"
-#define STR_TILDE "\176"
-
-#define STRING_ACCEPT0 STR_A STR_C STR_C STR_E STR_P STR_T "\0"
-#define STRING_COMMIT0 STR_C STR_O STR_M STR_M STR_I STR_T "\0"
-#define STRING_F0 STR_F "\0"
-#define STRING_FAIL0 STR_F STR_A STR_I STR_L "\0"
-#define STRING_MARK0 STR_M STR_A STR_R STR_K "\0"
-#define STRING_PRUNE0 STR_P STR_R STR_U STR_N STR_E "\0"
-#define STRING_SKIP0 STR_S STR_K STR_I STR_P "\0"
-#define STRING_THEN STR_T STR_H STR_E STR_N
-
-#define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0"
-#define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0"
-#define STRING_upper0 STR_u STR_p STR_p STR_e STR_r "\0"
-#define STRING_alnum0 STR_a STR_l STR_n STR_u STR_m "\0"
-#define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i "\0"
-#define STRING_blank0 STR_b STR_l STR_a STR_n STR_k "\0"
-#define STRING_cntrl0 STR_c STR_n STR_t STR_r STR_l "\0"
-#define STRING_digit0 STR_d STR_i STR_g STR_i STR_t "\0"
-#define STRING_graph0 STR_g STR_r STR_a STR_p STR_h "\0"
-#define STRING_print0 STR_p STR_r STR_i STR_n STR_t "\0"
-#define STRING_punct0 STR_p STR_u STR_n STR_c STR_t "\0"
-#define STRING_space0 STR_s STR_p STR_a STR_c STR_e "\0"
-#define STRING_word0 STR_w STR_o STR_r STR_d "\0"
-#define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t
-
-#define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E
-
-#define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS
-#define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS
-#define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
-#define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS
-#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS
-#define STRING_UTF16_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS
-#define STRING_UTF32_RIGHTPAR STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS
-#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_RIGHT_PARENTHESIS
-#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS
-#define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS
-#define STRING_LIMIT_MATCH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN
-#define STRING_LIMIT_RECURSION_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_R STR_E STR_C STR_U STR_R STR_S STR_I STR_O STR_N STR_EQUALS_SIGN
-
-#endif /* SUPPORT_UTF */
-
-/* Escape items that are just an encoding of a particular data value. */
-
-#ifndef ESC_e
-#define ESC_e CHAR_ESC
-#endif
-
-#ifndef ESC_f
-#define ESC_f CHAR_FF
-#endif
-
-#ifndef ESC_n
-#define ESC_n CHAR_LF
-#endif
-
-#ifndef ESC_r
-#define ESC_r CHAR_CR
-#endif
-
-/* We can't officially use ESC_t because it is a POSIX reserved identifier
-(presumably because of all the others like size_t). */
-
-#ifndef ESC_tee
-#define ESC_tee CHAR_HT
-#endif
-
-/* Codes for different types of Unicode property */
-
-#define PT_ANY 0 /* Any property - matches all chars */
-#define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */
-#define PT_GC 2 /* Specified general characteristic (e.g. L) */
-#define PT_PC 3 /* Specified particular characteristic (e.g. Lu) */
-#define PT_SC 4 /* Script (e.g. Han) */
-#define PT_ALNUM 5 /* Alphanumeric - the union of L and N */
-#define PT_SPACE 6 /* Perl space - Z plus 9,10,12,13 */
-#define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */
-#define PT_WORD 8 /* Word - L plus N plus underscore */
-#define PT_CLIST 9 /* Pseudo-property: match character list */
-#define PT_UCNC 10 /* Universal Character nameable character */
-
-/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
-contain characters with values greater than 255. */
-
-#define XCL_NOT 0x01 /* Flag: this is a negative class */
-#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */
-
-#define XCL_END 0 /* Marks end of individual items */
-#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */
-#define XCL_RANGE 2 /* A range (two multibyte chars) follows */
-#define XCL_PROP 3 /* Unicode property (2-byte property code follows) */
-#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */
-
-/* These are escaped items that aren't just an encoding of a particular data
-value such as \n. They must have non-zero values, as check_escape() returns
-0 for a data character. Also, they must appear in the same order as in the opcode
-definitions below, up to ESC_z. There's a dummy for OP_ALLANY because it
-corresponds to "." in DOTALL mode rather than an escape sequence. It is also
-used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In
-non-DOTALL mode, "." behaves like \N.
-
-The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc.
-when PCRE_UCP is set and replacement of \d etc by \p sequences is required.
-They must be contiguous, and remain in order so that the replacements can be
-looked up from a table.
-
-Negative numbers are used to encode a backreference (\1, \2, \3, etc.) in
-check_escape(). There are two tests in the code for an escape
-greater than ESC_b and less than ESC_Z to detect the types that may be
-repeated. These are the types that consume characters. If any new escapes are
-put in between that don't consume a character, that code will have to change.
-*/
-
-enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
- ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H,
- ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z,
- ESC_E, ESC_Q, ESC_g, ESC_k,
- ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu };
-
-/* Opcode table: Starting from 1 (i.e. after OP_END), the values up to
-OP_EOD must correspond in order to the list of escapes immediately above.
-
-*** NOTE NOTE NOTE *** Whenever this list is updated, the two macro definitions
-that follow must also be updated to match. There are also tables called
-"coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */
-
-enum {
- OP_END, /* 0 End of pattern */
-
- /* Values corresponding to backslashed metacharacters */
-
- OP_SOD, /* 1 Start of data: \A */
- OP_SOM, /* 2 Start of match (subject + offset): \G */
- OP_SET_SOM, /* 3 Set start of match (\K) */
- OP_NOT_WORD_BOUNDARY, /* 4 \B */
- OP_WORD_BOUNDARY, /* 5 \b */
- OP_NOT_DIGIT, /* 6 \D */
- OP_DIGIT, /* 7 \d */
- OP_NOT_WHITESPACE, /* 8 \S */
- OP_WHITESPACE, /* 9 \s */
- OP_NOT_WORDCHAR, /* 10 \W */
- OP_WORDCHAR, /* 11 \w */
-
- OP_ANY, /* 12 Match any character except newline (\N) */
- OP_ALLANY, /* 13 Match any character */
- OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */
- OP_NOTPROP, /* 15 \P (not Unicode property) */
- OP_PROP, /* 16 \p (Unicode property) */
- OP_ANYNL, /* 17 \R (any newline sequence) */
- OP_NOT_HSPACE, /* 18 \H (not horizontal whitespace) */
- OP_HSPACE, /* 19 \h (horizontal whitespace) */
- OP_NOT_VSPACE, /* 20 \V (not vertical whitespace) */
- OP_VSPACE, /* 21 \v (vertical whitespace) */
- OP_EXTUNI, /* 22 \X (extended Unicode sequence */
- OP_EODN, /* 23 End of data or \n at end of data (\Z) */
- OP_EOD, /* 24 End of data (\z) */
-
- OP_CIRC, /* 25 Start of line - not multiline */
- OP_CIRCM, /* 26 Start of line - multiline */
- OP_DOLL, /* 27 End of line - not multiline */
- OP_DOLLM, /* 28 End of line - multiline */
- OP_CHAR, /* 29 Match one character, casefully */
- OP_CHARI, /* 30 Match one character, caselessly */
- OP_NOT, /* 31 Match one character, not the given one, casefully */
- OP_NOTI, /* 32 Match one character, not the given one, caselessly */
-
- /* The following sets of 13 opcodes must always be kept in step because
- the offset from the first one is used to generate the others. */
-
- /**** Single characters, caseful, must precede the caseless ones ****/
-
- OP_STAR, /* 33 The maximizing and minimizing versions of */
- OP_MINSTAR, /* 34 these six opcodes must come in pairs, with */
- OP_PLUS, /* 35 the minimizing one second. */
- OP_MINPLUS, /* 36 */
- OP_QUERY, /* 37 */
- OP_MINQUERY, /* 38 */
-
- OP_UPTO, /* 39 From 0 to n matches of one character, caseful*/
- OP_MINUPTO, /* 40 */
- OP_EXACT, /* 41 Exactly n matches */
-
- OP_POSSTAR, /* 42 Possessified star, caseful */
- OP_POSPLUS, /* 43 Possessified plus, caseful */
- OP_POSQUERY, /* 44 Posesssified query, caseful */
- OP_POSUPTO, /* 45 Possessified upto, caseful */
-
- /**** Single characters, caseless, must follow the caseful ones */
-
- OP_STARI, /* 46 */
- OP_MINSTARI, /* 47 */
- OP_PLUSI, /* 48 */
- OP_MINPLUSI, /* 49 */
- OP_QUERYI, /* 50 */
- OP_MINQUERYI, /* 51 */
-
- OP_UPTOI, /* 52 From 0 to n matches of one character, caseless */
- OP_MINUPTOI, /* 53 */
- OP_EXACTI, /* 54 */
-
- OP_POSSTARI, /* 55 Possessified star, caseless */
- OP_POSPLUSI, /* 56 Possessified plus, caseless */
- OP_POSQUERYI, /* 57 Posesssified query, caseless */
- OP_POSUPTOI, /* 58 Possessified upto, caseless */
-
- /**** The negated ones must follow the non-negated ones, and match them ****/
- /**** Negated single character, caseful; must precede the caseless ones ****/
-
- OP_NOTSTAR, /* 59 The maximizing and minimizing versions of */
- OP_NOTMINSTAR, /* 60 these six opcodes must come in pairs, with */
- OP_NOTPLUS, /* 61 the minimizing one second. They must be in */
- OP_NOTMINPLUS, /* 62 exactly the same order as those above. */
- OP_NOTQUERY, /* 63 */
- OP_NOTMINQUERY, /* 64 */
-
- OP_NOTUPTO, /* 65 From 0 to n matches, caseful */
- OP_NOTMINUPTO, /* 66 */
- OP_NOTEXACT, /* 67 Exactly n matches */
-
- OP_NOTPOSSTAR, /* 68 Possessified versions, caseful */
- OP_NOTPOSPLUS, /* 69 */
- OP_NOTPOSQUERY, /* 70 */
- OP_NOTPOSUPTO, /* 71 */
-
- /**** Negated single character, caseless; must follow the caseful ones ****/
-
- OP_NOTSTARI, /* 72 */
- OP_NOTMINSTARI, /* 73 */
- OP_NOTPLUSI, /* 74 */
- OP_NOTMINPLUSI, /* 75 */
- OP_NOTQUERYI, /* 76 */
- OP_NOTMINQUERYI, /* 77 */
-
- OP_NOTUPTOI, /* 78 From 0 to n matches, caseless */
- OP_NOTMINUPTOI, /* 79 */
- OP_NOTEXACTI, /* 80 Exactly n matches */
-
- OP_NOTPOSSTARI, /* 81 Possessified versions, caseless */
- OP_NOTPOSPLUSI, /* 82 */
- OP_NOTPOSQUERYI, /* 83 */
- OP_NOTPOSUPTOI, /* 84 */
-
- /**** Character types ****/
-
- OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */
- OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */
- OP_TYPEPLUS, /* 87 the minimizing one second. These codes must */
- OP_TYPEMINPLUS, /* 88 be in exactly the same order as those above. */
- OP_TYPEQUERY, /* 89 */
- OP_TYPEMINQUERY, /* 90 */
-
- OP_TYPEUPTO, /* 91 From 0 to n matches */
- OP_TYPEMINUPTO, /* 92 */
- OP_TYPEEXACT, /* 93 Exactly n matches */
-
- OP_TYPEPOSSTAR, /* 94 Possessified versions */
- OP_TYPEPOSPLUS, /* 95 */
- OP_TYPEPOSQUERY, /* 96 */
- OP_TYPEPOSUPTO, /* 97 */
-
- /* These are used for character classes and back references; only the
- first six are the same as the sets above. */
-
- OP_CRSTAR, /* 98 The maximizing and minimizing versions of */
- OP_CRMINSTAR, /* 99 all these opcodes must come in pairs, with */
- OP_CRPLUS, /* 100 the minimizing one second. These codes must */
- OP_CRMINPLUS, /* 101 be in exactly the same order as those above. */
- OP_CRQUERY, /* 102 */
- OP_CRMINQUERY, /* 103 */
-
- OP_CRRANGE, /* 104 These are different to the three sets above. */
- OP_CRMINRANGE, /* 105 */
-
- /* End of quantifier opcodes */
-
- OP_CLASS, /* 106 Match a character class, chars < 256 only */
- OP_NCLASS, /* 107 Same, but the bitmap was created from a negative
- class - the difference is relevant only when a
- character > 255 is encountered. */
- OP_XCLASS, /* 108 Extended class for handling > 255 chars within the
- class. This does both positive and negative. */
- OP_REF, /* 109 Match a back reference, casefully */
- OP_REFI, /* 110 Match a back reference, caselessly */
- OP_RECURSE, /* 111 Match a numbered subpattern (possibly recursive) */
- OP_CALLOUT, /* 112 Call out to external function if provided */
-
- OP_ALT, /* 113 Start of alternation */
- OP_KET, /* 114 End of group that doesn't have an unbounded repeat */
- OP_KETRMAX, /* 115 These two must remain together and in this */
- OP_KETRMIN, /* 116 order. They are for groups the repeat for ever. */
- OP_KETRPOS, /* 117 Possessive unlimited repeat. */
-
- /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four
- asserts must remain in order. */
-
- OP_REVERSE, /* 118 Move pointer back - used in lookbehind assertions */
- OP_ASSERT, /* 119 Positive lookahead */
- OP_ASSERT_NOT, /* 120 Negative lookahead */
- OP_ASSERTBACK, /* 121 Positive lookbehind */
- OP_ASSERTBACK_NOT, /* 122 Negative lookbehind */
-
- /* ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately
- after the assertions, with ONCE first, as there's a test for >= ONCE for a
- subpattern that isn't an assertion. The POS versions must immediately follow
- the non-POS versions in each case. */
-
- OP_ONCE, /* 123 Atomic group, contains captures */
- OP_ONCE_NC, /* 124 Atomic group containing no captures */
- OP_BRA, /* 125 Start of non-capturing bracket */
- OP_BRAPOS, /* 126 Ditto, with unlimited, possessive repeat */
- OP_CBRA, /* 127 Start of capturing bracket */
- OP_CBRAPOS, /* 128 Ditto, with unlimited, possessive repeat */
- OP_COND, /* 129 Conditional group */
-
- /* These five must follow the previous five, in the same order. There's a
- check for >= SBRA to distinguish the two sets. */
-
- OP_SBRA, /* 130 Start of non-capturing bracket, check empty */
- OP_SBRAPOS, /* 131 Ditto, with unlimited, possessive repeat */
- OP_SCBRA, /* 132 Start of capturing bracket, check empty */
- OP_SCBRAPOS, /* 133 Ditto, with unlimited, possessive repeat */
- OP_SCOND, /* 134 Conditional group, check empty */
-
- /* The next two pairs must (respectively) be kept together. */
-
- OP_CREF, /* 135 Used to hold a capture number as condition */
- OP_NCREF, /* 136 Same, but generated by a name reference*/
- OP_RREF, /* 137 Used to hold a recursion number as condition */
- OP_NRREF, /* 138 Same, but generated by a name reference*/
- OP_DEF, /* 139 The DEFINE condition */
-
- OP_BRAZERO, /* 140 These two must remain together and in this */
- OP_BRAMINZERO, /* 141 order. */
- OP_BRAPOSZERO, /* 142 */
-
- /* These are backtracking control verbs */
-
- OP_MARK, /* 143 always has an argument */
- OP_PRUNE, /* 144 */
- OP_PRUNE_ARG, /* 145 same, but with argument */
- OP_SKIP, /* 146 */
- OP_SKIP_ARG, /* 147 same, but with argument */
- OP_THEN, /* 148 */
- OP_THEN_ARG, /* 149 same, but with argument */
- OP_COMMIT, /* 150 */
-
- /* These are forced failure and success verbs */
-
- OP_FAIL, /* 151 */
- OP_ACCEPT, /* 152 */
- OP_ASSERT_ACCEPT, /* 153 Used inside assertions */
- OP_CLOSE, /* 154 Used before OP_ACCEPT to close open captures */
-
- /* This is used to skip a subpattern with a {0} quantifier */
-
- OP_SKIPZERO, /* 155 */
-
- /* This is not an opcode, but is used to check that tables indexed by opcode
- are the correct length, in order to catch updating errors - there have been
- some in the past. */
-
- OP_TABLE_LENGTH
-};
-
-/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro
-definitions that follow must also be updated to match. There are also tables
-called "coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */
-
-
-/* This macro defines textual names for all the opcodes. These are used only
-for debugging, and some of them are only partial names. The macro is referenced
-only in pcre_printint.c, which fills out the full names in many cases (and in
-some cases doesn't actually use these names at all). */
-
-#define OP_NAME_LIST \
- "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \
- "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \
- "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \
- "extuni", "\\Z", "\\z", \
- "^", "^", "$", "$", "char", "chari", "not", "noti", \
- "*", "*?", "+", "+?", "?", "??", \
- "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", \
- "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", \
- "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", \
- "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
- "*+","++", "?+", "{", \
- "*", "*?", "+", "+?", "?", "??", "{", "{", \
- "class", "nclass", "xclass", "Ref", "Refi", \
- "Recurse", "Callout", \
- "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \
- "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \
- "Once", "Once_NC", \
- "Bra", "BraPos", "CBra", "CBraPos", \
- "Cond", \
- "SBra", "SBraPos", "SCBra", "SCBraPos", \
- "SCond", \
- "Cond ref", "Cond nref", "Cond rec", "Cond nrec", "Cond def", \
- "Brazero", "Braminzero", "Braposzero", \
- "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \
- "*THEN", "*THEN", "*COMMIT", "*FAIL", \
- "*ACCEPT", "*ASSERT_ACCEPT", \
- "Close", "Skip zero"
-
-
-/* This macro defines the length of fixed length operations in the compiled
-regex. The lengths are used when searching for specific things, and also in the
-debugging printing of a compiled regex. We use a macro so that it can be
-defined close to the definitions of the opcodes themselves.
-
-As things have been extended, some of these are no longer fixed lenths, but are
-minima instead. For example, the length of a single-character repeat may vary
-in UTF-8 mode. The code that uses this table must know about such things. */
-
-#define OP_LENGTHS \
- 1, /* End */ \
- 1, 1, 1, 1, 1, /* \A, \G, \K, \B, \b */ \
- 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ \
- 1, 1, 1, /* Any, AllAny, Anybyte */ \
- 3, 3, /* \P, \p */ \
- 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \
- 1, /* \X */ \
- 1, 1, 1, 1, 1, 1, /* \Z, \z, ^, ^M, $, $M */ \
- 2, /* Char - the minimum length */ \
- 2, /* Chari - the minimum length */ \
- 2, /* not */ \
- 2, /* noti */ \
- /* Positive single-char repeats ** These are */ \
- 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto, minupto ** mode */ \
- 2+IMM2_SIZE, /* exact */ \
- 2, 2, 2, 2+IMM2_SIZE, /* *+, ++, ?+, upto+ */ \
- 2, 2, 2, 2, 2, 2, /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8 */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto I, minupto I */ \
- 2+IMM2_SIZE, /* exact I */ \
- 2, 2, 2, 2+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ \
- /* Negative single-char repeats - only for chars < 256 */ \
- 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto, minupto */ \
- 2+IMM2_SIZE, /* NOT exact */ \
- 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *, +, ?, upto */ \
- 2, 2, 2, 2, 2, 2, /* NOT *I, *?I, +I, +?I, ?I, ??I */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto I, minupto I */ \
- 2+IMM2_SIZE, /* NOT exact I */ \
- 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *I, +I, ?I, upto I */ \
- /* Positive type repeats */ \
- 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \
- 2+IMM2_SIZE, 2+IMM2_SIZE, /* Type upto, minupto */ \
- 2+IMM2_SIZE, /* Type exact */ \
- 2, 2, 2, 2+IMM2_SIZE, /* Possessive *+, ++, ?+, upto+ */ \
- /* Character class & ref repeats */ \
- 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \
- 1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \
- 1+(32/sizeof(pcre_uchar)), /* CLASS */ \
- 1+(32/sizeof(pcre_uchar)), /* NCLASS */ \
- 0, /* XCLASS - variable length */ \
- 1+IMM2_SIZE, /* REF */ \
- 1+IMM2_SIZE, /* REFI */ \
- 1+LINK_SIZE, /* RECURSE */ \
- 2+2*LINK_SIZE, /* CALLOUT */ \
- 1+LINK_SIZE, /* Alt */ \
- 1+LINK_SIZE, /* Ket */ \
- 1+LINK_SIZE, /* KetRmax */ \
- 1+LINK_SIZE, /* KetRmin */ \
- 1+LINK_SIZE, /* KetRpos */ \
- 1+LINK_SIZE, /* Reverse */ \
- 1+LINK_SIZE, /* Assert */ \
- 1+LINK_SIZE, /* Assert not */ \
- 1+LINK_SIZE, /* Assert behind */ \
- 1+LINK_SIZE, /* Assert behind not */ \
- 1+LINK_SIZE, /* ONCE */ \
- 1+LINK_SIZE, /* ONCE_NC */ \
- 1+LINK_SIZE, /* BRA */ \
- 1+LINK_SIZE, /* BRAPOS */ \
- 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \
- 1+LINK_SIZE+IMM2_SIZE, /* CBRAPOS */ \
- 1+LINK_SIZE, /* COND */ \
- 1+LINK_SIZE, /* SBRA */ \
- 1+LINK_SIZE, /* SBRAPOS */ \
- 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \
- 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \
- 1+LINK_SIZE, /* SCOND */ \
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* CREF, NCREF */ \
- 1+IMM2_SIZE, 1+IMM2_SIZE, /* RREF, NRREF */ \
- 1, /* DEF */ \
- 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \
- 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \
- 1, 3, /* SKIP, SKIP_ARG */ \
- 1, 3, /* THEN, THEN_ARG */ \
- 1, 1, 1, 1, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ \
- 1+IMM2_SIZE, 1 /* CLOSE, SKIPZERO */
-
-/* A magic value for OP_RREF and OP_NRREF to indicate the "any recursion"
-condition. */
-
-#define RREF_ANY 0xffff
-
-/* Compile time error code numbers. They are given names so that they can more
-easily be tracked. When a new number is added, the table called eint in
-pcreposix.c must be updated. */
-
-enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9,
- ERR10, ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19,
- ERR20, ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29,
- ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39,
- ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49,
- ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59,
- ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69,
- ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERRCOUNT };
-
-/* JIT compiling modes. The function list is indexed by them. */
-enum { JIT_COMPILE, JIT_PARTIAL_SOFT_COMPILE, JIT_PARTIAL_HARD_COMPILE,
- JIT_NUMBER_OF_COMPILE_MODES };
-
-/* The real format of the start of the pcre block; the index of names and the
-code vector run on as long as necessary after the end. We store an explicit
-offset to the name table so that if a regex is compiled on one host, saved, and
-then run on another where the size of pointers is different, all might still
-be well.
-
-The size of the structure must be a multiple of 8 bytes. For the case of
-compiled-on-4 and run-on-8, we include an extra pointer that is always NULL so
-that there are an even number of pointers which therefore are a multiple of 8
-bytes.
-
-It is necessary to fork the struct for the 32 bit library, since it needs to
-use pcre_uint32 for first_char and req_char. We can't put an ifdef inside the
-typedef because pcretest needs access to the struct of the 8-, 16- and 32-bit
-variants.
-
-*** WARNING ***
-When new fields are added to these structures, remember to adjust the code in
-pcre_byte_order.c that is concerned with swapping the byte order of the fields
-when a compiled regex is reloaded on a host with different endianness.
-*** WARNING ***
-There is also similar byte-flipping code in pcretest.c, which is used for
-testing the byte-flipping features. It must also be kept in step.
-*** WARNING ***
-*/
-
-typedef struct real_pcre8_or_16 {
- pcre_uint32 magic_number;
- pcre_uint32 size; /* Total that was malloced */
- pcre_uint32 options; /* Public options */
- pcre_uint32 flags; /* Private flags */
- pcre_uint32 limit_match; /* Limit set from regex */
- pcre_uint32 limit_recursion; /* Limit set from regex */
- pcre_uint16 first_char; /* Starting character */
- pcre_uint16 req_char; /* This character must be seen */
- pcre_uint16 max_lookbehind; /* Longest lookbehind (characters) */
- pcre_uint16 top_bracket; /* Highest numbered group */
- pcre_uint16 top_backref; /* Highest numbered back reference */
- pcre_uint16 name_table_offset; /* Offset to name table that follows */
- pcre_uint16 name_entry_size; /* Size of any name items */
- pcre_uint16 name_count; /* Number of name items */
- pcre_uint16 ref_count; /* Reference count */
- pcre_uint16 dummy1; /* To ensure size is a multiple of 8 */
- pcre_uint16 dummy2; /* To ensure size is a multiple of 8 */
- pcre_uint16 dummy3; /* To ensure size is a multiple of 8 */
- const pcre_uint8 *tables; /* Pointer to tables or NULL for std */
- void *nullpad; /* NULL padding */
-} real_pcre8_or_16;
-
-typedef struct real_pcre8_or_16 real_pcre;
-typedef struct real_pcre8_or_16 real_pcre16;
-
-typedef struct real_pcre32 {
- pcre_uint32 magic_number;
- pcre_uint32 size; /* Total that was malloced */
- pcre_uint32 options; /* Public options */
- pcre_uint32 flags; /* Private flags */
- pcre_uint32 limit_match; /* Limit set from regex */
- pcre_uint32 limit_recursion; /* Limit set from regex */
- pcre_uint32 first_char; /* Starting character */
- pcre_uint32 req_char; /* This character must be seen */
- pcre_uint16 max_lookbehind; /* Longest lookbehind (characters) */
- pcre_uint16 top_bracket; /* Highest numbered group */
- pcre_uint16 top_backref; /* Highest numbered back reference */
- pcre_uint16 name_table_offset; /* Offset to name table that follows */
- pcre_uint16 name_entry_size; /* Size of any name items */
- pcre_uint16 name_count; /* Number of name items */
- pcre_uint16 ref_count; /* Reference count */
- pcre_uint16 dummy; /* To ensure size is a multiple of 8 */
- const pcre_uint8 *tables; /* Pointer to tables or NULL for std */
- void *nullpad; /* NULL padding */
-} real_pcre32;
-
-#if defined COMPILE_PCRE8
-#define REAL_PCRE real_pcre
-#elif defined COMPILE_PCRE16
-#define REAL_PCRE real_pcre16
-#elif defined COMPILE_PCRE32
-#define REAL_PCRE real_pcre32
-#endif
-
-/* Assert that the size of REAL_PCRE is divisible by 8 */
-typedef int __assert_real_pcre_size_divisible_8[(sizeof(REAL_PCRE) % 8) == 0 ? 1 : -1];
-
-/* Needed in pcretest to access some fields in the real_pcre* structures
- * directly. They're unified for 8/16/32 bits since the structs only differ
- * after these fields; if that ever changes, need to fork those defines into
- * 8/16 and 32 bit versions. */
-#define REAL_PCRE_MAGIC(re) (((REAL_PCRE*)re)->magic_number)
-#define REAL_PCRE_SIZE(re) (((REAL_PCRE*)re)->size)
-#define REAL_PCRE_OPTIONS(re) (((REAL_PCRE*)re)->options)
-#define REAL_PCRE_FLAGS(re) (((REAL_PCRE*)re)->flags)
-
-/* The format of the block used to store data from pcre_study(). The same
-remark (see NOTE above) about extending this structure applies. */
-
-typedef struct pcre_study_data {
- pcre_uint32 size; /* Total that was malloced */
- pcre_uint32 flags; /* Private flags */
- pcre_uint8 start_bits[32]; /* Starting char bits */
- pcre_uint32 minlength; /* Minimum subject length */
-} pcre_study_data;
-
-/* Structure for building a chain of open capturing subpatterns during
-compiling, so that instructions to close them can be compiled when (*ACCEPT) is
-encountered. This is also used to identify subpatterns that contain recursive
-back references to themselves, so that they can be made atomic. */
-
-typedef struct open_capitem {
- struct open_capitem *next; /* Chain link */
- pcre_uint16 number; /* Capture number */
- pcre_uint16 flag; /* Set TRUE if recursive back ref */
-} open_capitem;
-
-/* Structure for passing "static" information around between the functions
-doing the compiling, so that they are thread-safe. */
-
-typedef struct compile_data {
- const pcre_uint8 *lcc; /* Points to lower casing table */
- const pcre_uint8 *fcc; /* Points to case-flipping table */
- const pcre_uint8 *cbits; /* Points to character type table */
- const pcre_uint8 *ctypes; /* Points to table of type maps */
- const pcre_uchar *start_workspace;/* The start of working space */
- const pcre_uchar *start_code; /* The start of the compiled code */
- const pcre_uchar *start_pattern; /* The start of the pattern */
- const pcre_uchar *end_pattern; /* The end of the pattern */
- open_capitem *open_caps; /* Chain of open capture items */
- pcre_uchar *hwm; /* High watermark of workspace */
- pcre_uchar *name_table; /* The name/number table */
- int names_found; /* Number of entries so far */
- int name_entry_size; /* Size of each entry */
- int workspace_size; /* Size of workspace */
- unsigned int bracount; /* Count of capturing parens as we compile */
- int final_bracount; /* Saved value after first pass */
- int max_lookbehind; /* Maximum lookbehind (characters) */
- int top_backref; /* Maximum back reference */
- unsigned int backref_map; /* Bitmap of low back refs */
- int assert_depth; /* Depth of nested assertions */
- pcre_uint32 external_options; /* External (initial) options */
- pcre_uint32 external_flags; /* External flag bits to be set */
- int req_varyopt; /* "After variable item" flag for reqbyte */
- BOOL had_accept; /* (*ACCEPT) encountered */
- BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */
- BOOL check_lookbehind; /* Lookbehinds need later checking */
- int nltype; /* Newline type */
- int nllen; /* Newline string length */
- pcre_uchar nl[4]; /* Newline string when fixed length */
-} compile_data;
-
-/* Structure for maintaining a chain of pointers to the currently incomplete
-branches, for testing for left recursion while compiling. */
-
-typedef struct branch_chain {
- struct branch_chain *outer;
- pcre_uchar *current_branch;
-} branch_chain;
-
-/* Structure for items in a linked list that represents an explicit recursive
-call within the pattern; used by pcre_exec(). */
-
-typedef struct recursion_info {
- struct recursion_info *prevrec; /* Previous recursion record (or NULL) */
- unsigned int group_num; /* Number of group that was called */
- int *offset_save; /* Pointer to start of saved offsets */
- int saved_max; /* Number of saved offsets */
- int saved_capture_last; /* Last capture number */
- PCRE_PUCHAR subject_position; /* Position at start of recursion */
-} recursion_info;
-
-/* A similar structure for pcre_dfa_exec(). */
-
-typedef struct dfa_recursion_info {
- struct dfa_recursion_info *prevrec;
- int group_num;
- PCRE_PUCHAR subject_position;
-} dfa_recursion_info;
-
-/* Structure for building a chain of data for holding the values of the subject
-pointer at the start of each subpattern, so as to detect when an empty string
-has been matched by a subpattern - to break infinite loops; used by
-pcre_exec(). */
-
-typedef struct eptrblock {
- struct eptrblock *epb_prev;
- PCRE_PUCHAR epb_saved_eptr;
-} eptrblock;
-
-
-/* Structure for passing "static" information around between the functions
-doing traditional NFA matching, so that they are thread-safe. */
-
-typedef struct match_data {
- unsigned long int match_call_count; /* As it says */
- unsigned long int match_limit; /* As it says */
- unsigned long int match_limit_recursion; /* As it says */
- int *offset_vector; /* Offset vector */
- int offset_end; /* One past the end */
- int offset_max; /* The maximum usable for return data */
- int nltype; /* Newline type */
- int nllen; /* Newline string length */
- int name_count; /* Number of names in name table */
- int name_entry_size; /* Size of entry in names table */
- unsigned int skip_arg_count; /* For counting SKIP_ARGs */
- unsigned int ignore_skip_arg; /* For re-run when SKIP arg name not found */
- pcre_uchar *name_table; /* Table of names */
- pcre_uchar nl[4]; /* Newline string when fixed */
- const pcre_uint8 *lcc; /* Points to lower casing table */
- const pcre_uint8 *fcc; /* Points to case-flipping table */
- const pcre_uint8 *ctypes; /* Points to table of type maps */
- BOOL notbol; /* NOTBOL flag */
- BOOL noteol; /* NOTEOL flag */
- BOOL utf; /* UTF-8 / UTF-16 flag */
- BOOL jscript_compat; /* JAVASCRIPT_COMPAT flag */
- BOOL use_ucp; /* PCRE_UCP flag */
- BOOL endonly; /* Dollar not before final \n */
- BOOL notempty; /* Empty string match not wanted */
- BOOL notempty_atstart; /* Empty string match at start not wanted */
- BOOL hitend; /* Hit the end of the subject at some point */
- BOOL bsr_anycrlf; /* \R is just any CRLF, not full Unicode */
- BOOL hasthen; /* Pattern contains (*THEN) */
- const pcre_uchar *start_code; /* For use when recursing */
- PCRE_PUCHAR start_subject; /* Start of the subject string */
- PCRE_PUCHAR end_subject; /* End of the subject string */
- PCRE_PUCHAR start_match_ptr; /* Start of matched string */
- PCRE_PUCHAR end_match_ptr; /* Subject position at end match */
- PCRE_PUCHAR start_used_ptr; /* Earliest consulted character */
- int partial; /* PARTIAL options */
- int end_offset_top; /* Highwater mark at end of match */
- pcre_int32 capture_last; /* Most recent capture number + overflow flag */
- int start_offset; /* The start offset value */
- int match_function_type; /* Set for certain special calls of MATCH() */
- eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */
- int eptrn; /* Next free eptrblock */
- recursion_info *recursive; /* Linked list of recursion data */
- void *callout_data; /* To pass back to callouts */
- const pcre_uchar *mark; /* Mark pointer to pass back on success */
- const pcre_uchar *nomatch_mark;/* Mark pointer to pass back on failure */
- const pcre_uchar *once_target; /* Where to back up to for atomic groups */
-#ifdef NO_RECURSE
- void *match_frames_base; /* For remembering malloc'd frames */
-#endif
-} match_data;
-
-/* A similar structure is used for the same purpose by the DFA matching
-functions. */
-
-typedef struct dfa_match_data {
- const pcre_uchar *start_code; /* Start of the compiled pattern */
- const pcre_uchar *start_subject ; /* Start of the subject string */
- const pcre_uchar *end_subject; /* End of subject string */
- const pcre_uchar *start_used_ptr; /* Earliest consulted character */
- const pcre_uint8 *tables; /* Character tables */
- int start_offset; /* The start offset value */
- int moptions; /* Match options */
- int poptions; /* Pattern options */
- int nltype; /* Newline type */
- int nllen; /* Newline string length */
- pcre_uchar nl[4]; /* Newline string when fixed */
- void *callout_data; /* To pass back to callouts */
- dfa_recursion_info *recursive; /* Linked list of recursion data */
-} dfa_match_data;
-
-/* Bit definitions for entries in the pcre_ctypes table. */
-
-#define ctype_space 0x01
-#define ctype_letter 0x02
-#define ctype_digit 0x04
-#define ctype_xdigit 0x08
-#define ctype_word 0x10 /* alphanumeric or '_' */
-#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */
-
-/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set
-of bits for a class map. Some classes are built by combining these tables. */
-
-#define cbit_space 0 /* [:space:] or \s */
-#define cbit_xdigit 32 /* [:xdigit:] */
-#define cbit_digit 64 /* [:digit:] or \d */
-#define cbit_upper 96 /* [:upper:] */
-#define cbit_lower 128 /* [:lower:] */
-#define cbit_word 160 /* [:word:] or \w */
-#define cbit_graph 192 /* [:graph:] */
-#define cbit_print 224 /* [:print:] */
-#define cbit_punct 256 /* [:punct:] */
-#define cbit_cntrl 288 /* [:cntrl:] */
-#define cbit_length 320 /* Length of the cbits table */
-
-/* Offsets of the various tables from the base tables pointer, and
-total length. */
-
-#define lcc_offset 0
-#define fcc_offset 256
-#define cbits_offset 512
-#define ctypes_offset (cbits_offset + cbit_length)
-#define tables_length (ctypes_offset + 256)
-
-/* Internal function and data prefixes. */
-
-#if defined COMPILE_PCRE8
-#ifndef PUBL
-#define PUBL(name) pcre_##name
-#endif
-#ifndef PRIV
-#define PRIV(name) _pcre_##name
-#endif
-#elif defined COMPILE_PCRE16
-#ifndef PUBL
-#define PUBL(name) pcre16_##name
-#endif
-#ifndef PRIV
-#define PRIV(name) _pcre16_##name
-#endif
-#elif defined COMPILE_PCRE32
-#ifndef PUBL
-#define PUBL(name) pcre32_##name
-#endif
-#ifndef PRIV
-#define PRIV(name) _pcre32_##name
-#endif
-#else
-#error Unsupported compiling mode
-#endif /* COMPILE_PCRE[8|16|32] */
-
-/* Layout of the UCP type table that translates property names into types and
-codes. Each entry used to point directly to a name, but to reduce the number of
-relocations in shared libraries, it now has an offset into a single string
-instead. */
-
-typedef struct {
- pcre_uint16 name_offset;
- pcre_uint16 type;
- pcre_uint16 value;
-} ucp_type_table;
-
-
-/* Internal shared data tables. These are tables that are used by more than one
-of the exported public functions. They have to be "external" in the C sense,
-but are not part of the PCRE public API. The data for these tables is in the
-pcre_tables.c module. */
-
-#ifdef COMPILE_PCRE8
-extern const int PRIV(utf8_table1)[];
-extern const int PRIV(utf8_table1_size);
-extern const int PRIV(utf8_table2)[];
-extern const int PRIV(utf8_table3)[];
-extern const pcre_uint8 PRIV(utf8_table4)[];
-#endif /* COMPILE_PCRE8 */
-
-extern const char PRIV(utt_names)[];
-extern const ucp_type_table PRIV(utt)[];
-extern const int PRIV(utt_size);
-
-extern const pcre_uint8 PRIV(OP_lengths)[];
-extern const pcre_uint8 PRIV(default_tables)[];
-
-extern const pcre_uint32 PRIV(hspace_list)[];
-extern const pcre_uint32 PRIV(vspace_list)[];
-
-
-/* Internal shared functions. These are functions that are used by more than
-one of the exported public functions. They have to be "external" in the C
-sense, but are not part of the PCRE public API. */
-
-/* String comparison functions. */
-#if defined COMPILE_PCRE8
-
-#define STRCMP_UC_UC(str1, str2) \
- strcmp((char *)(str1), (char *)(str2))
-#define STRCMP_UC_C8(str1, str2) \
- strcmp((char *)(str1), (str2))
-#define STRNCMP_UC_UC(str1, str2, num) \
- strncmp((char *)(str1), (char *)(str2), (num))
-#define STRNCMP_UC_C8(str1, str2, num) \
- strncmp((char *)(str1), (str2), (num))
-#define STRLEN_UC(str) strlen((const char *)str)
-
-#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
-
-extern int PRIV(strcmp_uc_uc)(const pcre_uchar *,
- const pcre_uchar *);
-extern int PRIV(strcmp_uc_c8)(const pcre_uchar *,
- const char *);
-extern int PRIV(strncmp_uc_uc)(const pcre_uchar *,
- const pcre_uchar *, unsigned int num);
-extern int PRIV(strncmp_uc_c8)(const pcre_uchar *,
- const char *, unsigned int num);
-extern unsigned int PRIV(strlen_uc)(const pcre_uchar *str);
-
-#define STRCMP_UC_UC(str1, str2) \
- PRIV(strcmp_uc_uc)((str1), (str2))
-#define STRCMP_UC_C8(str1, str2) \
- PRIV(strcmp_uc_c8)((str1), (str2))
-#define STRNCMP_UC_UC(str1, str2, num) \
- PRIV(strncmp_uc_uc)((str1), (str2), (num))
-#define STRNCMP_UC_C8(str1, str2, num) \
- PRIV(strncmp_uc_c8)((str1), (str2), (num))
-#define STRLEN_UC(str) PRIV(strlen_uc)(str)
-
-#endif /* COMPILE_PCRE[8|16|32] */
-
-#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
-
-#define STRCMP_UC_UC_TEST(str1, str2) STRCMP_UC_UC(str1, str2)
-#define STRCMP_UC_C8_TEST(str1, str2) STRCMP_UC_C8(str1, str2)
-
-#elif defined COMPILE_PCRE32
-
-extern int PRIV(strcmp_uc_uc_utf)(const pcre_uchar *,
- const pcre_uchar *);
-extern int PRIV(strcmp_uc_c8_utf)(const pcre_uchar *,
- const char *);
-
-#define STRCMP_UC_UC_TEST(str1, str2) \
- (utf ? PRIV(strcmp_uc_uc_utf)((str1), (str2)) : PRIV(strcmp_uc_uc)((str1), (str2)))
-#define STRCMP_UC_C8_TEST(str1, str2) \
- (utf ? PRIV(strcmp_uc_c8_utf)((str1), (str2)) : PRIV(strcmp_uc_c8)((str1), (str2)))
-
-#endif /* COMPILE_PCRE[8|16|32] */
-
-extern const pcre_uchar *PRIV(find_bracket)(const pcre_uchar *, BOOL, int);
-extern BOOL PRIV(is_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR,
- int *, BOOL);
-extern unsigned int PRIV(ord2utf)(pcre_uint32, pcre_uchar *);
-extern int PRIV(valid_utf)(PCRE_PUCHAR, int, int *);
-extern BOOL PRIV(was_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR,
- int *, BOOL);
-extern BOOL PRIV(xclass)(pcre_uint32, const pcre_uchar *, BOOL);
-
-#ifdef SUPPORT_JIT
-extern void PRIV(jit_compile)(const REAL_PCRE *,
- PUBL(extra) *, int);
-extern int PRIV(jit_exec)(const PUBL(extra) *,
- const pcre_uchar *, int, int, int, int *, int);
-extern void PRIV(jit_free)(void *);
-extern int PRIV(jit_get_size)(void *);
-extern const char* PRIV(jit_get_target)(void);
-#endif
-
-/* Unicode character database (UCD) */
-
-typedef struct {
- pcre_uint8 script; /* ucp_Arabic, etc. */
- pcre_uint8 chartype; /* ucp_Cc, etc. (general categories) */
- pcre_uint8 gbprop; /* ucp_gbControl, etc. (grapheme break property) */
- pcre_uint8 caseset; /* offset to multichar other cases or zero */
- pcre_int32 other_case; /* offset to other case, or zero if none */
-} ucd_record;
-
-extern const pcre_uint32 PRIV(ucd_caseless_sets)[];
-extern const ucd_record PRIV(ucd_records)[];
-extern const pcre_uint8 PRIV(ucd_stage1)[];
-extern const pcre_uint16 PRIV(ucd_stage2)[];
-extern const pcre_uint32 PRIV(ucp_gentype)[];
-extern const pcre_uint32 PRIV(ucp_gbtable)[];
-#ifdef SUPPORT_JIT
-extern const int PRIV(ucp_typerange)[];
-#endif
-
-#ifdef SUPPORT_UCP
-/* UCD access macros */
-
-#define UCD_BLOCK_SIZE 128
-#define GET_UCD(ch) (PRIV(ucd_records) + \
- PRIV(ucd_stage2)[PRIV(ucd_stage1)[(int)(ch) / UCD_BLOCK_SIZE] * \
- UCD_BLOCK_SIZE + (int)(ch) % UCD_BLOCK_SIZE])
-
-#define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype
-#define UCD_SCRIPT(ch) GET_UCD(ch)->script
-#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)]
-#define UCD_GRAPHBREAK(ch) GET_UCD(ch)->gbprop
-#define UCD_CASESET(ch) GET_UCD(ch)->caseset
-#define UCD_OTHERCASE(ch) ((pcre_uint32)((int)ch + (int)(GET_UCD(ch)->other_case)))
-
-#endif /* SUPPORT_UCP */
-
-#endif
-
-/* End of pcre_internal.h */
diff --git a/usr.sbin/nginx/src/pcre/pcre_newline.c b/usr.sbin/nginx/src/pcre/pcre_newline.c
deleted file mode 100644
index b8f5a4de19c..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre_newline.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains internal functions for testing newlines when more than
-one kind of newline is to be recognized. When a newline is found, its length is
-returned. In principle, we could implement several newline "types", each
-referring to a different set of newline characters. At present, PCRE supports
-only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF,
-and NLTYPE_ANY. The full list of Unicode newline characters is taken from
-http://unicode.org/unicode/reports/tr18/. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-
-/*************************************************
-* Check for newline at given position *
-*************************************************/
-
-/* It is guaranteed that the initial value of ptr is less than the end of the
-string that is being processed.
-
-Arguments:
- ptr pointer to possible newline
- type the newline type
- endptr pointer to the end of the string
- lenptr where to return the length
- utf TRUE if in utf mode
-
-Returns: TRUE or FALSE
-*/
-
-BOOL
-PRIV(is_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR endptr, int *lenptr,
- BOOL utf)
-{
-pcre_uint32 c;
-(void)utf;
-#ifdef SUPPORT_UTF
-if (utf)
- {
- GETCHAR(c, ptr);
- }
-else
-#endif /* SUPPORT_UTF */
- c = *ptr;
-
-/* Note that this function is called only for ANY or ANYCRLF. */
-
-if (type == NLTYPE_ANYCRLF) switch(c)
- {
- case CHAR_LF: *lenptr = 1; return TRUE;
- case CHAR_CR: *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1;
- return TRUE;
- default: return FALSE;
- }
-
-/* NLTYPE_ANY */
-
-else switch(c)
- {
-#ifdef EBCDIC
- case CHAR_NEL:
-#endif
- case CHAR_LF:
- case CHAR_VT:
- case CHAR_FF: *lenptr = 1; return TRUE;
-
- case CHAR_CR:
- *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1;
- return TRUE;
-
-#ifndef EBCDIC
-#ifdef COMPILE_PCRE8
- case CHAR_NEL: *lenptr = utf? 2 : 1; return TRUE;
- case 0x2028: /* LS */
- case 0x2029: *lenptr = 3; return TRUE; /* PS */
-#else /* COMPILE_PCRE16 || COMPILE_PCRE32 */
- case CHAR_NEL:
- case 0x2028: /* LS */
- case 0x2029: *lenptr = 1; return TRUE; /* PS */
-#endif /* COMPILE_PCRE8 */
-#endif /* Not EBCDIC */
-
- default: return FALSE;
- }
-}
-
-
-
-/*************************************************
-* Check for newline at previous position *
-*************************************************/
-
-/* It is guaranteed that the initial value of ptr is greater than the start of
-the string that is being processed.
-
-Arguments:
- ptr pointer to possible newline
- type the newline type
- startptr pointer to the start of the string
- lenptr where to return the length
- utf TRUE if in utf mode
-
-Returns: TRUE or FALSE
-*/
-
-BOOL
-PRIV(was_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR startptr, int *lenptr,
- BOOL utf)
-{
-pcre_uint32 c;
-(void)utf;
-ptr--;
-#ifdef SUPPORT_UTF
-if (utf)
- {
- BACKCHAR(ptr);
- GETCHAR(c, ptr);
- }
-else
-#endif /* SUPPORT_UTF */
- c = *ptr;
-
-/* Note that this function is called only for ANY or ANYCRLF. */
-
-if (type == NLTYPE_ANYCRLF) switch(c)
- {
- case CHAR_LF:
- *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1;
- return TRUE;
-
- case CHAR_CR: *lenptr = 1; return TRUE;
- default: return FALSE;
- }
-
-/* NLTYPE_ANY */
-
-else switch(c)
- {
- case CHAR_LF:
- *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1;
- return TRUE;
-
-#ifdef EBCDIC
- case CHAR_NEL:
-#endif
- case CHAR_VT:
- case CHAR_FF:
- case CHAR_CR: *lenptr = 1; return TRUE;
-
-#ifndef EBCDIC
-#ifdef COMPILE_PCRE8
- case CHAR_NEL: *lenptr = utf? 2 : 1; return TRUE;
- case 0x2028: /* LS */
- case 0x2029: *lenptr = 3; return TRUE; /* PS */
-#else /* COMPILE_PCRE16 || COMPILE_PCRE32 */
- case CHAR_NEL:
- case 0x2028: /* LS */
- case 0x2029: *lenptr = 1; return TRUE; /* PS */
-#endif /* COMPILE_PCRE8 */
-#endif /* NotEBCDIC */
-
- default: return FALSE;
- }
-}
-
-/* End of pcre_newline.c */
diff --git a/usr.sbin/nginx/src/pcre/pcre_ord2utf8.c b/usr.sbin/nginx/src/pcre/pcre_ord2utf8.c
deleted file mode 100644
index 95f1beb963e..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre_ord2utf8.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This file contains a private PCRE function that converts an ordinal
-character value into a UTF8 string. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#define COMPILE_PCRE8
-
-#include "pcre_internal.h"
-
-/*************************************************
-* Convert character value to UTF-8 *
-*************************************************/
-
-/* This function takes an integer value in the range 0 - 0x10ffff
-and encodes it as a UTF-8 character in 1 to 4 pcre_uchars.
-
-Arguments:
- cvalue the character value
- buffer pointer to buffer for result - at least 6 pcre_uchars long
-
-Returns: number of characters placed in the buffer
-*/
-
-unsigned
-int
-PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer)
-{
-#ifdef SUPPORT_UTF
-
-register int i, j;
-
-for (i = 0; i < PRIV(utf8_table1_size); i++)
- if ((int)cvalue <= PRIV(utf8_table1)[i]) break;
-buffer += i;
-for (j = i; j > 0; j--)
- {
- *buffer-- = 0x80 | (cvalue & 0x3f);
- cvalue >>= 6;
- }
-*buffer = PRIV(utf8_table2)[i] | cvalue;
-return i + 1;
-
-#else
-
-(void)(cvalue); /* Keep compiler happy; this function won't ever be */
-(void)(buffer); /* called when SUPPORT_UTF is not defined. */
-return 0;
-
-#endif
-}
-
-/* End of pcre_ord2utf8.c */
diff --git a/usr.sbin/nginx/src/pcre/pcre_study.c b/usr.sbin/nginx/src/pcre/pcre_study.c
deleted file mode 100644
index 12d2a66817b..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre_study.c
+++ /dev/null
@@ -1,1562 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains the external function pcre_study(), along with local
-supporting functions. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-#define SET_BIT(c) start_bits[c/8] |= (1 << (c&7))
-
-/* Returns from set_start_bits() */
-
-enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN };
-
-
-
-/*************************************************
-* Find the minimum subject length for a group *
-*************************************************/
-
-/* Scan a parenthesized group and compute the minimum length of subject that
-is needed to match it. This is a lower bound; it does not mean there is a
-string of that length that matches. In UTF8 mode, the result is in characters
-rather than bytes.
-
-Arguments:
- code pointer to start of group (the bracket)
- startcode pointer to start of the whole pattern
- options the compiling options
- int RECURSE depth
-
-Returns: the minimum length
- -1 if \C in UTF-8 mode or (*ACCEPT) was encountered
- -2 internal error (missing capturing bracket)
- -3 internal error (opcode not listed)
-*/
-
-static int
-find_minlength(const pcre_uchar *code, const pcre_uchar *startcode, int options,
- int recurse_depth)
-{
-int length = -1;
-/* PCRE_UTF16 has the same value as PCRE_UTF8. */
-BOOL utf = (options & PCRE_UTF8) != 0;
-BOOL had_recurse = FALSE;
-register int branchlength = 0;
-register pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE;
-
-if (*code == OP_CBRA || *code == OP_SCBRA ||
- *code == OP_CBRAPOS || *code == OP_SCBRAPOS) cc += IMM2_SIZE;
-
-/* Scan along the opcodes for this branch. If we get to the end of the
-branch, check the length against that of the other branches. */
-
-for (;;)
- {
- int d, min;
- pcre_uchar *cs, *ce;
- register pcre_uchar op = *cc;
-
- switch (op)
- {
- case OP_COND:
- case OP_SCOND:
-
- /* If there is only one branch in a condition, the implied branch has zero
- length, so we don't add anything. This covers the DEFINE "condition"
- automatically. */
-
- cs = cc + GET(cc, 1);
- if (*cs != OP_ALT)
- {
- cc = cs + 1 + LINK_SIZE;
- break;
- }
-
- /* Otherwise we can fall through and treat it the same as any other
- subpattern. */
-
- case OP_CBRA:
- case OP_SCBRA:
- case OP_BRA:
- case OP_SBRA:
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- case OP_BRAPOS:
- case OP_SBRAPOS:
- case OP_ONCE:
- case OP_ONCE_NC:
- d = find_minlength(cc, startcode, options, recurse_depth);
- if (d < 0) return d;
- branchlength += d;
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- cc += 1 + LINK_SIZE;
- break;
-
- /* ACCEPT makes things far too complicated; we have to give up. */
-
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- return -1;
-
- /* Reached end of a branch; if it's a ket it is the end of a nested
- call. If it's ALT it is an alternation in a nested call. If it is END it's
- the end of the outer call. All can be handled by the same code. If an
- ACCEPT was previously encountered, use the length that was in force at that
- time, and pass back the shortest ACCEPT length. */
-
- case OP_ALT:
- case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_KETRPOS:
- case OP_END:
- if (length < 0 || (!had_recurse && branchlength < length))
- length = branchlength;
- if (op != OP_ALT) return length;
- cc += 1 + LINK_SIZE;
- branchlength = 0;
- had_recurse = FALSE;
- break;
-
- /* Skip over assertive subpatterns */
-
- case OP_ASSERT:
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- /* Fall through */
-
- /* Skip over things that don't match chars */
-
- case OP_REVERSE:
- case OP_CREF:
- case OP_NCREF:
- case OP_RREF:
- case OP_NRREF:
- case OP_DEF:
- case OP_CALLOUT:
- case OP_SOD:
- case OP_SOM:
- case OP_EOD:
- case OP_EODN:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_NOT_WORD_BOUNDARY:
- case OP_WORD_BOUNDARY:
- cc += PRIV(OP_lengths)[*cc];
- break;
-
- /* Skip over a subpattern that has a {0} or {0,x} quantifier */
-
- case OP_BRAZERO:
- case OP_BRAMINZERO:
- case OP_BRAPOSZERO:
- case OP_SKIPZERO:
- cc += PRIV(OP_lengths)[*cc];
- do cc += GET(cc, 1); while (*cc == OP_ALT);
- cc += 1 + LINK_SIZE;
- break;
-
- /* Handle literal characters and + repetitions */
-
- case OP_CHAR:
- case OP_CHARI:
- case OP_NOT:
- case OP_NOTI:
- case OP_PLUS:
- case OP_PLUSI:
- case OP_MINPLUS:
- case OP_MINPLUSI:
- case OP_POSPLUS:
- case OP_POSPLUSI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- branchlength++;
- cc += 2;
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- branchlength++;
- cc += (cc[1] == OP_PROP || cc[1] == OP_NOTPROP)? 4 : 2;
- break;
-
- /* Handle exact repetitions. The count is already in characters, but we
- need to skip over a multibyte character in UTF8 mode. */
-
- case OP_EXACT:
- case OP_EXACTI:
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- branchlength += GET2(cc,1);
- cc += 2 + IMM2_SIZE;
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- case OP_TYPEEXACT:
- branchlength += GET2(cc,1);
- cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP
- || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
- break;
-
- /* Handle single-char non-literal matchers */
-
- case OP_PROP:
- case OP_NOTPROP:
- cc += 2;
- /* Fall through */
-
- case OP_NOT_DIGIT:
- case OP_DIGIT:
- case OP_NOT_WHITESPACE:
- case OP_WHITESPACE:
- case OP_NOT_WORDCHAR:
- case OP_WORDCHAR:
- case OP_ANY:
- case OP_ALLANY:
- case OP_EXTUNI:
- case OP_HSPACE:
- case OP_NOT_HSPACE:
- case OP_VSPACE:
- case OP_NOT_VSPACE:
- branchlength++;
- cc++;
- break;
-
- /* "Any newline" might match two characters, but it also might match just
- one. */
-
- case OP_ANYNL:
- branchlength += 1;
- cc++;
- break;
-
- /* The single-byte matcher means we can't proceed in UTF-8 mode. (In
- non-UTF-8 mode \C will actually be turned into OP_ALLANY, so won't ever
- appear, but leave the code, just in case.) */
-
- case OP_ANYBYTE:
-#ifdef SUPPORT_UTF
- if (utf) return -1;
-#endif
- branchlength++;
- cc++;
- break;
-
- /* For repeated character types, we have to test for \p and \P, which have
- an extra two bytes of parameters. */
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSSTAR:
- case OP_TYPEPOSQUERY:
- if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2;
- cc += PRIV(OP_lengths)[op];
- break;
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- if (cc[1 + IMM2_SIZE] == OP_PROP
- || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2;
- cc += PRIV(OP_lengths)[op];
- break;
-
- /* Check a class for variable quantification */
-
- case OP_CLASS:
- case OP_NCLASS:
-#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- case OP_XCLASS:
- /* The original code caused an unsigned overflow in 64 bit systems,
- so now we use a conditional statement. */
- if (op == OP_XCLASS)
- cc += GET(cc, 1);
- else
- cc += PRIV(OP_lengths)[OP_CLASS];
-#else
- cc += PRIV(OP_lengths)[OP_CLASS];
-#endif
-
- switch (*cc)
- {
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- branchlength++;
- /* Fall through */
-
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- cc++;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- branchlength += GET2(cc,1);
- cc += 1 + 2 * IMM2_SIZE;
- break;
-
- default:
- branchlength++;
- break;
- }
- break;
-
- /* Backreferences and subroutine calls are treated in the same way: we find
- the minimum length for the subpattern. A recursion, however, causes an
- a flag to be set that causes the length of this branch to be ignored. The
- logic is that a recursion can only make sense if there is another
- alternation that stops the recursing. That will provide the minimum length
- (when no recursion happens). A backreference within the group that it is
- referencing behaves in the same way.
-
- If PCRE_JAVASCRIPT_COMPAT is set, a backreference to an unset bracket
- matches an empty string (by default it causes a matching failure), so in
- that case we must set the minimum length to zero. */
-
- case OP_REF:
- case OP_REFI:
- if ((options & PCRE_JAVASCRIPT_COMPAT) == 0)
- {
- ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(cc, 1));
- if (cs == NULL) return -2;
- do ce += GET(ce, 1); while (*ce == OP_ALT);
- if (cc > cs && cc < ce)
- {
- d = 0;
- had_recurse = TRUE;
- }
- else
- {
- d = find_minlength(cs, startcode, options, recurse_depth);
- }
- }
- else d = 0;
- cc += 1 + IMM2_SIZE;
-
- /* Handle repeated back references */
-
- switch (*cc)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- min = 0;
- cc++;
- break;
-
- case OP_CRPLUS:
- case OP_CRMINPLUS:
- min = 1;
- cc++;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- min = GET2(cc, 1);
- cc += 1 + 2 * IMM2_SIZE;
- break;
-
- default:
- min = 1;
- break;
- }
-
- branchlength += min * d;
- break;
-
- /* We can easily detect direct recursion, but not mutual recursion. This is
- caught by a recursion depth count. */
-
- case OP_RECURSE:
- cs = ce = (pcre_uchar *)startcode + GET(cc, 1);
- do ce += GET(ce, 1); while (*ce == OP_ALT);
- if ((cc > cs && cc < ce) || recurse_depth > 10)
- had_recurse = TRUE;
- else
- {
- branchlength += find_minlength(cs, startcode, options, recurse_depth + 1);
- }
- cc += 1 + LINK_SIZE;
- break;
-
- /* Anything else does not or need not match a character. We can get the
- item's length from the table, but for those that can match zero occurrences
- of a character, we must take special action for UTF-8 characters. As it
- happens, the "NOT" versions of these opcodes are used at present only for
- ASCII characters, so they could be omitted from this list. However, in
- future that may change, so we include them here so as not to leave a
- gotcha for a future maintainer. */
-
- case OP_UPTO:
- case OP_UPTOI:
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_MINUPTO:
- case OP_MINUPTOI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- case OP_POSUPTO:
- case OP_POSUPTOI:
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
-
- case OP_STAR:
- case OP_STARI:
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_MINSTAR:
- case OP_MINSTARI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_POSSTAR:
- case OP_POSSTARI:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
-
- case OP_QUERY:
- case OP_QUERYI:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_MINQUERY:
- case OP_MINQUERYI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- case OP_POSQUERY:
- case OP_POSQUERYI:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
-
- cc += PRIV(OP_lengths)[op];
-#ifdef SUPPORT_UTF
- if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- break;
-
- /* Skip these, but we need to add in the name length. */
-
- case OP_MARK:
- case OP_PRUNE_ARG:
- case OP_SKIP_ARG:
- case OP_THEN_ARG:
- cc += PRIV(OP_lengths)[op] + cc[1];
- break;
-
- /* The remaining opcodes are just skipped over. */
-
- case OP_CLOSE:
- case OP_COMMIT:
- case OP_FAIL:
- case OP_PRUNE:
- case OP_SET_SOM:
- case OP_SKIP:
- case OP_THEN:
- cc += PRIV(OP_lengths)[op];
- break;
-
- /* This should not occur: we list all opcodes explicitly so that when
- new ones get added they are properly considered. */
-
- default:
- return -3;
- }
- }
-/* Control never gets here */
-}
-
-
-
-/*************************************************
-* Set a bit and maybe its alternate case *
-*************************************************/
-
-/* Given a character, set its first byte's bit in the table, and also the
-corresponding bit for the other version of a letter if we are caseless. In
-UTF-8 mode, for characters greater than 127, we can only do the caseless thing
-when Unicode property support is available.
-
-Arguments:
- start_bits points to the bit map
- p points to the character
- caseless the caseless flag
- cd the block with char table pointers
- utf TRUE for UTF-8 / UTF-16 / UTF-32 mode
-
-Returns: pointer after the character
-*/
-
-static const pcre_uchar *
-set_table_bit(pcre_uint8 *start_bits, const pcre_uchar *p, BOOL caseless,
- compile_data *cd, BOOL utf)
-{
-pcre_uint32 c = *p;
-
-#ifdef COMPILE_PCRE8
-SET_BIT(c);
-
-#ifdef SUPPORT_UTF
-if (utf && c > 127)
- {
- GETCHARINC(c, p);
-#ifdef SUPPORT_UCP
- if (caseless)
- {
- pcre_uchar buff[6];
- c = UCD_OTHERCASE(c);
- (void)PRIV(ord2utf)(c, buff);
- SET_BIT(buff[0]);
- }
-#endif /* Not SUPPORT_UCP */
- return p;
- }
-#else /* Not SUPPORT_UTF */
-(void)(utf); /* Stops warning for unused parameter */
-#endif /* SUPPORT_UTF */
-
-/* Not UTF-8 mode, or character is less than 127. */
-
-if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]);
-return p + 1;
-#endif /* COMPILE_PCRE8 */
-
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
-if (c > 0xff)
- {
- c = 0xff;
- caseless = FALSE;
- }
-SET_BIT(c);
-
-#ifdef SUPPORT_UTF
-if (utf && c > 127)
- {
- GETCHARINC(c, p);
-#ifdef SUPPORT_UCP
- if (caseless)
- {
- c = UCD_OTHERCASE(c);
- if (c > 0xff)
- c = 0xff;
- SET_BIT(c);
- }
-#endif /* SUPPORT_UCP */
- return p;
- }
-#else /* Not SUPPORT_UTF */
-(void)(utf); /* Stops warning for unused parameter */
-#endif /* SUPPORT_UTF */
-
-if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]);
-return p + 1;
-#endif
-}
-
-
-
-/*************************************************
-* Set bits for a positive character type *
-*************************************************/
-
-/* This function sets starting bits for a character type. In UTF-8 mode, we can
-only do a direct setting for bytes less than 128, as otherwise there can be
-confusion with bytes in the middle of UTF-8 characters. In a "traditional"
-environment, the tables will only recognize ASCII characters anyway, but in at
-least one Windows environment, some higher bytes bits were set in the tables.
-So we deal with that case by considering the UTF-8 encoding.
-
-Arguments:
- start_bits the starting bitmap
- cbit type the type of character wanted
- table_limit 32 for non-UTF-8; 16 for UTF-8
- cd the block with char table pointers
-
-Returns: nothing
-*/
-
-static void
-set_type_bits(pcre_uint8 *start_bits, int cbit_type, unsigned int table_limit,
- compile_data *cd)
-{
-register pcre_uint32 c;
-for (c = 0; c < table_limit; c++) start_bits[c] |= cd->cbits[c+cbit_type];
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
-if (table_limit == 32) return;
-for (c = 128; c < 256; c++)
- {
- if ((cd->cbits[c/8] & (1 << (c&7))) != 0)
- {
- pcre_uchar buff[6];
- (void)PRIV(ord2utf)(c, buff);
- SET_BIT(buff[0]);
- }
- }
-#endif
-}
-
-
-/*************************************************
-* Set bits for a negative character type *
-*************************************************/
-
-/* This function sets starting bits for a negative character type such as \D.
-In UTF-8 mode, we can only do a direct setting for bytes less than 128, as
-otherwise there can be confusion with bytes in the middle of UTF-8 characters.
-Unlike in the positive case, where we can set appropriate starting bits for
-specific high-valued UTF-8 characters, in this case we have to set the bits for
-all high-valued characters. The lowest is 0xc2, but we overkill by starting at
-0xc0 (192) for simplicity.
-
-Arguments:
- start_bits the starting bitmap
- cbit type the type of character wanted
- table_limit 32 for non-UTF-8; 16 for UTF-8
- cd the block with char table pointers
-
-Returns: nothing
-*/
-
-static void
-set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, unsigned int table_limit,
- compile_data *cd)
-{
-register pcre_uint32 c;
-for (c = 0; c < table_limit; c++) start_bits[c] |= ~cd->cbits[c+cbit_type];
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
-if (table_limit != 32) for (c = 24; c < 32; c++) start_bits[c] = 0xff;
-#endif
-}
-
-
-
-/*************************************************
-* Create bitmap of starting bytes *
-*************************************************/
-
-/* This function scans a compiled unanchored expression recursively and
-attempts to build a bitmap of the set of possible starting bytes. As time goes
-by, we may be able to get more clever at doing this. The SSB_CONTINUE return is
-useful for parenthesized groups in patterns such as (a*)b where the group
-provides some optional starting bytes but scanning must continue at the outer
-level to find at least one mandatory byte. At the outermost level, this
-function fails unless the result is SSB_DONE.
-
-Arguments:
- code points to an expression
- start_bits points to a 32-byte table, initialized to 0
- utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode
- cd the block with char table pointers
-
-Returns: SSB_FAIL => Failed to find any starting bytes
- SSB_DONE => Found mandatory starting bytes
- SSB_CONTINUE => Found optional starting bytes
- SSB_UNKNOWN => Hit an unrecognized opcode
-*/
-
-static int
-set_start_bits(const pcre_uchar *code, pcre_uint8 *start_bits, BOOL utf,
- compile_data *cd)
-{
-register pcre_uint32 c;
-int yield = SSB_DONE;
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
-int table_limit = utf? 16:32;
-#else
-int table_limit = 32;
-#endif
-
-#if 0
-/* ========================================================================= */
-/* The following comment and code was inserted in January 1999. In May 2006,
-when it was observed to cause compiler warnings about unused values, I took it
-out again. If anybody is still using OS/2, they will have to put it back
-manually. */
-
-/* This next statement and the later reference to dummy are here in order to
-trick the optimizer of the IBM C compiler for OS/2 into generating correct
-code. Apparently IBM isn't going to fix the problem, and we would rather not
-disable optimization (in this module it actually makes a big difference, and
-the pcre module can use all the optimization it can get). */
-
-volatile int dummy;
-/* ========================================================================= */
-#endif
-
-do
- {
- BOOL try_next = TRUE;
- const pcre_uchar *tcode = code + 1 + LINK_SIZE;
-
- if (*code == OP_CBRA || *code == OP_SCBRA ||
- *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE;
-
- while (try_next) /* Loop for items in this branch */
- {
- int rc;
-
- switch(*tcode)
- {
- /* If we reach something we don't understand, it means a new opcode has
- been created that hasn't been added to this code. Hopefully this problem
- will be discovered during testing. */
-
- default:
- return SSB_UNKNOWN;
-
- /* Fail for a valid opcode that implies no starting bits. */
-
- case OP_ACCEPT:
- case OP_ASSERT_ACCEPT:
- case OP_ALLANY:
- case OP_ANY:
- case OP_ANYBYTE:
- case OP_CIRC:
- case OP_CIRCM:
- case OP_CLOSE:
- case OP_COMMIT:
- case OP_COND:
- case OP_CREF:
- case OP_DEF:
- case OP_DOLL:
- case OP_DOLLM:
- case OP_END:
- case OP_EOD:
- case OP_EODN:
- case OP_EXTUNI:
- case OP_FAIL:
- case OP_MARK:
- case OP_NCREF:
- case OP_NOT:
- case OP_NOTEXACT:
- case OP_NOTEXACTI:
- case OP_NOTI:
- case OP_NOTMINPLUS:
- case OP_NOTMINPLUSI:
- case OP_NOTMINQUERY:
- case OP_NOTMINQUERYI:
- case OP_NOTMINSTAR:
- case OP_NOTMINSTARI:
- case OP_NOTMINUPTO:
- case OP_NOTMINUPTOI:
- case OP_NOTPLUS:
- case OP_NOTPLUSI:
- case OP_NOTPOSPLUS:
- case OP_NOTPOSPLUSI:
- case OP_NOTPOSQUERY:
- case OP_NOTPOSQUERYI:
- case OP_NOTPOSSTAR:
- case OP_NOTPOSSTARI:
- case OP_NOTPOSUPTO:
- case OP_NOTPOSUPTOI:
- case OP_NOTPROP:
- case OP_NOTQUERY:
- case OP_NOTQUERYI:
- case OP_NOTSTAR:
- case OP_NOTSTARI:
- case OP_NOTUPTO:
- case OP_NOTUPTOI:
- case OP_NOT_HSPACE:
- case OP_NOT_VSPACE:
- case OP_NRREF:
- case OP_PROP:
- case OP_PRUNE:
- case OP_PRUNE_ARG:
- case OP_RECURSE:
- case OP_REF:
- case OP_REFI:
- case OP_REVERSE:
- case OP_RREF:
- case OP_SCOND:
- case OP_SET_SOM:
- case OP_SKIP:
- case OP_SKIP_ARG:
- case OP_SOD:
- case OP_SOM:
- case OP_THEN:
- case OP_THEN_ARG:
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- case OP_XCLASS:
-#endif
- return SSB_FAIL;
-
- /* We can ignore word boundary tests. */
-
- case OP_WORD_BOUNDARY:
- case OP_NOT_WORD_BOUNDARY:
- tcode++;
- break;
-
- /* If we hit a bracket or a positive lookahead assertion, recurse to set
- bits from within the subpattern. If it can't find anything, we have to
- give up. If it finds some mandatory character(s), we are done for this
- branch. Otherwise, carry on scanning after the subpattern. */
-
- case OP_BRA:
- case OP_SBRA:
- case OP_CBRA:
- case OP_SCBRA:
- case OP_BRAPOS:
- case OP_SBRAPOS:
- case OP_CBRAPOS:
- case OP_SCBRAPOS:
- case OP_ONCE:
- case OP_ONCE_NC:
- case OP_ASSERT:
- rc = set_start_bits(tcode, start_bits, utf, cd);
- if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
- if (rc == SSB_DONE) try_next = FALSE; else
- {
- do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- }
- break;
-
- /* If we hit ALT or KET, it means we haven't found anything mandatory in
- this branch, though we might have found something optional. For ALT, we
- continue with the next alternative, but we have to arrange that the final
- result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET,
- return SSB_CONTINUE: if this is the top level, that indicates failure,
- but after a nested subpattern, it causes scanning to continue. */
-
- case OP_ALT:
- yield = SSB_CONTINUE;
- try_next = FALSE;
- break;
-
- case OP_KET:
- case OP_KETRMAX:
- case OP_KETRMIN:
- case OP_KETRPOS:
- return SSB_CONTINUE;
-
- /* Skip over callout */
-
- case OP_CALLOUT:
- tcode += 2 + 2*LINK_SIZE;
- break;
-
- /* Skip over lookbehind and negative lookahead assertions */
-
- case OP_ASSERT_NOT:
- case OP_ASSERTBACK:
- case OP_ASSERTBACK_NOT:
- do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- break;
-
- /* BRAZERO does the bracket, but carries on. */
-
- case OP_BRAZERO:
- case OP_BRAMINZERO:
- case OP_BRAPOSZERO:
- rc = set_start_bits(++tcode, start_bits, utf, cd);
- if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
-/* =========================================================================
- See the comment at the head of this function concerning the next line,
- which was an old fudge for the benefit of OS/2.
- dummy = 1;
- ========================================================================= */
- do tcode += GET(tcode,1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- break;
-
- /* SKIPZERO skips the bracket. */
-
- case OP_SKIPZERO:
- tcode++;
- do tcode += GET(tcode,1); while (*tcode == OP_ALT);
- tcode += 1 + LINK_SIZE;
- break;
-
- /* Single-char * or ? sets the bit and tries the next item */
-
- case OP_STAR:
- case OP_MINSTAR:
- case OP_POSSTAR:
- case OP_QUERY:
- case OP_MINQUERY:
- case OP_POSQUERY:
- tcode = set_table_bit(start_bits, tcode + 1, FALSE, cd, utf);
- break;
-
- case OP_STARI:
- case OP_MINSTARI:
- case OP_POSSTARI:
- case OP_QUERYI:
- case OP_MINQUERYI:
- case OP_POSQUERYI:
- tcode = set_table_bit(start_bits, tcode + 1, TRUE, cd, utf);
- break;
-
- /* Single-char upto sets the bit and tries the next */
-
- case OP_UPTO:
- case OP_MINUPTO:
- case OP_POSUPTO:
- tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, FALSE, cd, utf);
- break;
-
- case OP_UPTOI:
- case OP_MINUPTOI:
- case OP_POSUPTOI:
- tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, TRUE, cd, utf);
- break;
-
- /* At least one single char sets the bit and stops */
-
- case OP_EXACT:
- tcode += IMM2_SIZE;
- /* Fall through */
- case OP_CHAR:
- case OP_PLUS:
- case OP_MINPLUS:
- case OP_POSPLUS:
- (void)set_table_bit(start_bits, tcode + 1, FALSE, cd, utf);
- try_next = FALSE;
- break;
-
- case OP_EXACTI:
- tcode += IMM2_SIZE;
- /* Fall through */
- case OP_CHARI:
- case OP_PLUSI:
- case OP_MINPLUSI:
- case OP_POSPLUSI:
- (void)set_table_bit(start_bits, tcode + 1, TRUE, cd, utf);
- try_next = FALSE;
- break;
-
- /* Special spacing and line-terminating items. These recognize specific
- lists of characters. The difference between VSPACE and ANYNL is that the
- latter can match the two-character CRLF sequence, but that is not
- relevant for finding the first character, so their code here is
- identical. */
-
- case OP_HSPACE:
- SET_BIT(CHAR_HT);
- SET_BIT(CHAR_SPACE);
-#ifdef SUPPORT_UTF
- if (utf)
- {
-#ifdef COMPILE_PCRE8
- SET_BIT(0xC2); /* For U+00A0 */
- SET_BIT(0xE1); /* For U+1680, U+180E */
- SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
- SET_BIT(0xE3); /* For U+3000 */
-#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- SET_BIT(0xA0);
- SET_BIT(0xFF); /* For characters > 255 */
-#endif /* COMPILE_PCRE[8|16|32] */
- }
- else
-#endif /* SUPPORT_UTF */
- {
-#ifndef EBCDIC
- SET_BIT(0xA0);
-#endif /* Not EBCDIC */
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- SET_BIT(0xFF); /* For characters > 255 */
-#endif /* COMPILE_PCRE[16|32] */
- }
- try_next = FALSE;
- break;
-
- case OP_ANYNL:
- case OP_VSPACE:
- SET_BIT(CHAR_LF);
- SET_BIT(CHAR_VT);
- SET_BIT(CHAR_FF);
- SET_BIT(CHAR_CR);
-#ifdef SUPPORT_UTF
- if (utf)
- {
-#ifdef COMPILE_PCRE8
- SET_BIT(0xC2); /* For U+0085 */
- SET_BIT(0xE2); /* For U+2028, U+2029 */
-#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- SET_BIT(CHAR_NEL);
- SET_BIT(0xFF); /* For characters > 255 */
-#endif /* COMPILE_PCRE[8|16|32] */
- }
- else
-#endif /* SUPPORT_UTF */
- {
- SET_BIT(CHAR_NEL);
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- SET_BIT(0xFF); /* For characters > 255 */
-#endif
- }
- try_next = FALSE;
- break;
-
- /* Single character types set the bits and stop. Note that if PCRE_UCP
- is set, we do not see these op codes because \d etc are converted to
- properties. Therefore, these apply in the case when only characters less
- than 256 are recognized to match the types. */
-
- case OP_NOT_DIGIT:
- set_nottype_bits(start_bits, cbit_digit, table_limit, cd);
- try_next = FALSE;
- break;
-
- case OP_DIGIT:
- set_type_bits(start_bits, cbit_digit, table_limit, cd);
- try_next = FALSE;
- break;
-
- /* The cbit_space table has vertical tab as whitespace; we have to
- ensure it is set as not whitespace. Luckily, the code value is the same
- (0x0b) in ASCII and EBCDIC, so we can just adjust the appropriate bit. */
-
- case OP_NOT_WHITESPACE:
- set_nottype_bits(start_bits, cbit_space, table_limit, cd);
- start_bits[1] |= 0x08;
- try_next = FALSE;
- break;
-
- /* The cbit_space table has vertical tab as whitespace; we have to not
- set it from the table. Luckily, the code value is the same (0x0b) in
- ASCII and EBCDIC, so we can just adjust the appropriate bit. */
-
- case OP_WHITESPACE:
- c = start_bits[1]; /* Save in case it was already set */
- set_type_bits(start_bits, cbit_space, table_limit, cd);
- start_bits[1] = (start_bits[1] & ~0x08) | c;
- try_next = FALSE;
- break;
-
- case OP_NOT_WORDCHAR:
- set_nottype_bits(start_bits, cbit_word, table_limit, cd);
- try_next = FALSE;
- break;
-
- case OP_WORDCHAR:
- set_type_bits(start_bits, cbit_word, table_limit, cd);
- try_next = FALSE;
- break;
-
- /* One or more character type fudges the pointer and restarts, knowing
- it will hit a single character type and stop there. */
-
- case OP_TYPEPLUS:
- case OP_TYPEMINPLUS:
- case OP_TYPEPOSPLUS:
- tcode++;
- break;
-
- case OP_TYPEEXACT:
- tcode += 1 + IMM2_SIZE;
- break;
-
- /* Zero or more repeats of character types set the bits and then
- try again. */
-
- case OP_TYPEUPTO:
- case OP_TYPEMINUPTO:
- case OP_TYPEPOSUPTO:
- tcode += IMM2_SIZE; /* Fall through */
-
- case OP_TYPESTAR:
- case OP_TYPEMINSTAR:
- case OP_TYPEPOSSTAR:
- case OP_TYPEQUERY:
- case OP_TYPEMINQUERY:
- case OP_TYPEPOSQUERY:
- switch(tcode[1])
- {
- default:
- case OP_ANY:
- case OP_ALLANY:
- return SSB_FAIL;
-
- case OP_HSPACE:
- SET_BIT(CHAR_HT);
- SET_BIT(CHAR_SPACE);
-#ifdef SUPPORT_UTF
- if (utf)
- {
-#ifdef COMPILE_PCRE8
- SET_BIT(0xC2); /* For U+00A0 */
- SET_BIT(0xE1); /* For U+1680, U+180E */
- SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
- SET_BIT(0xE3); /* For U+3000 */
-#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- SET_BIT(0xA0);
- SET_BIT(0xFF); /* For characters > 255 */
-#endif /* COMPILE_PCRE[8|16|32] */
- }
- else
-#endif /* SUPPORT_UTF */
-#ifndef EBCDIC
- SET_BIT(0xA0);
-#endif /* Not EBCDIC */
- break;
-
- case OP_ANYNL:
- case OP_VSPACE:
- SET_BIT(CHAR_LF);
- SET_BIT(CHAR_VT);
- SET_BIT(CHAR_FF);
- SET_BIT(CHAR_CR);
-#ifdef SUPPORT_UTF
- if (utf)
- {
-#ifdef COMPILE_PCRE8
- SET_BIT(0xC2); /* For U+0085 */
- SET_BIT(0xE2); /* For U+2028, U+2029 */
-#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- SET_BIT(CHAR_NEL);
- SET_BIT(0xFF); /* For characters > 255 */
-#endif /* COMPILE_PCRE16 */
- }
- else
-#endif /* SUPPORT_UTF */
- SET_BIT(CHAR_NEL);
- break;
-
- case OP_NOT_DIGIT:
- set_nottype_bits(start_bits, cbit_digit, table_limit, cd);
- break;
-
- case OP_DIGIT:
- set_type_bits(start_bits, cbit_digit, table_limit, cd);
- break;
-
- /* The cbit_space table has vertical tab as whitespace; we have to
- ensure it gets set as not whitespace. Luckily, the code value is the
- same (0x0b) in ASCII and EBCDIC, so we can just adjust the appropriate
- bit. */
-
- case OP_NOT_WHITESPACE:
- set_nottype_bits(start_bits, cbit_space, table_limit, cd);
- start_bits[1] |= 0x08;
- break;
-
- /* The cbit_space table has vertical tab as whitespace; we have to
- avoid setting it. Luckily, the code value is the same (0x0b) in ASCII
- and EBCDIC, so we can just adjust the appropriate bit. */
-
- case OP_WHITESPACE:
- c = start_bits[1]; /* Save in case it was already set */
- set_type_bits(start_bits, cbit_space, table_limit, cd);
- start_bits[1] = (start_bits[1] & ~0x08) | c;
- break;
-
- case OP_NOT_WORDCHAR:
- set_nottype_bits(start_bits, cbit_word, table_limit, cd);
- break;
-
- case OP_WORDCHAR:
- set_type_bits(start_bits, cbit_word, table_limit, cd);
- break;
- }
-
- tcode += 2;
- break;
-
- /* Character class where all the information is in a bit map: set the
- bits and either carry on or not, according to the repeat count. If it was
- a negative class, and we are operating with UTF-8 characters, any byte
- with a value >= 0xc4 is a potentially valid starter because it starts a
- character with a value > 255. */
-
- case OP_NCLASS:
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
- if (utf)
- {
- start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */
- memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */
- }
-#endif
-#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
- SET_BIT(0xFF); /* For characters > 255 */
-#endif
- /* Fall through */
-
- case OP_CLASS:
- {
- pcre_uint8 *map;
- tcode++;
- map = (pcre_uint8 *)tcode;
-
- /* In UTF-8 mode, the bits in a bit map correspond to character
- values, not to byte values. However, the bit map we are constructing is
- for byte values. So we have to do a conversion for characters whose
- value is > 127. In fact, there are only two possible starting bytes for
- characters in the range 128 - 255. */
-
-#if defined SUPPORT_UTF && defined COMPILE_PCRE8
- if (utf)
- {
- for (c = 0; c < 16; c++) start_bits[c] |= map[c];
- for (c = 128; c < 256; c++)
- {
- if ((map[c/8] && (1 << (c&7))) != 0)
- {
- int d = (c >> 6) | 0xc0; /* Set bit for this starter */
- start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */
- c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */
- }
- }
- }
- else
-#endif
- {
- /* In non-UTF-8 mode, the two bit maps are completely compatible. */
- for (c = 0; c < 32; c++) start_bits[c] |= map[c];
- }
-
- /* Advance past the bit map, and act on what follows. For a zero
- minimum repeat, continue; otherwise stop processing. */
-
- tcode += 32 / sizeof(pcre_uchar);
- switch (*tcode)
- {
- case OP_CRSTAR:
- case OP_CRMINSTAR:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- tcode++;
- break;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE;
- else try_next = FALSE;
- break;
-
- default:
- try_next = FALSE;
- break;
- }
- }
- break; /* End of bitmap class handling */
-
- } /* End of switch */
- } /* End of try_next loop */
-
- code += GET(code, 1); /* Advance to next branch */
- }
-while (*code == OP_ALT);
-return yield;
-}
-
-
-
-
-
-/*************************************************
-* Study a compiled expression *
-*************************************************/
-
-/* This function is handed a compiled expression that it must study to produce
-information that will speed up the matching. It returns a pcre[16]_extra block
-which then gets handed back to pcre_exec().
-
-Arguments:
- re points to the compiled expression
- options contains option bits
- errorptr points to where to place error messages;
- set NULL unless error
-
-Returns: pointer to a pcre[16]_extra block, with study_data filled in and
- the appropriate flags set;
- NULL on error or if no optimization possible
-*/
-
-#if defined COMPILE_PCRE8
-PCRE_EXP_DEFN pcre_extra * PCRE_CALL_CONVENTION
-pcre_study(const pcre *external_re, int options, const char **errorptr)
-#elif defined COMPILE_PCRE16
-PCRE_EXP_DEFN pcre16_extra * PCRE_CALL_CONVENTION
-pcre16_study(const pcre16 *external_re, int options, const char **errorptr)
-#elif defined COMPILE_PCRE32
-PCRE_EXP_DEFN pcre32_extra * PCRE_CALL_CONVENTION
-pcre32_study(const pcre32 *external_re, int options, const char **errorptr)
-#endif
-{
-int min;
-BOOL bits_set = FALSE;
-pcre_uint8 start_bits[32];
-PUBL(extra) *extra = NULL;
-pcre_study_data *study;
-const pcre_uint8 *tables;
-pcre_uchar *code;
-compile_data compile_block;
-const REAL_PCRE *re = (const REAL_PCRE *)external_re;
-
-*errorptr = NULL;
-
-if (re == NULL || re->magic_number != MAGIC_NUMBER)
- {
- *errorptr = "argument is not a compiled regular expression";
- return NULL;
- }
-
-if ((re->flags & PCRE_MODE) == 0)
- {
-#if defined COMPILE_PCRE8
- *errorptr = "argument not compiled in 8 bit mode";
-#elif defined COMPILE_PCRE16
- *errorptr = "argument not compiled in 16 bit mode";
-#elif defined COMPILE_PCRE32
- *errorptr = "argument not compiled in 32 bit mode";
-#endif
- return NULL;
- }
-
-if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
- {
- *errorptr = "unknown or incorrect option bit(s) set";
- return NULL;
- }
-
-code = (pcre_uchar *)re + re->name_table_offset +
- (re->name_count * re->name_entry_size);
-
-/* For an anchored pattern, or an unanchored pattern that has a first char, or
-a multiline pattern that matches only at "line starts", there is no point in
-seeking a list of starting bytes. */
-
-if ((re->options & PCRE_ANCHORED) == 0 &&
- (re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) == 0)
- {
- int rc;
-
- /* Set the character tables in the block that is passed around */
-
- tables = re->tables;
-
-#if defined COMPILE_PCRE8
- if (tables == NULL)
- (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
- (void *)(&tables));
-#elif defined COMPILE_PCRE16
- if (tables == NULL)
- (void)pcre16_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
- (void *)(&tables));
-#elif defined COMPILE_PCRE32
- if (tables == NULL)
- (void)pcre32_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
- (void *)(&tables));
-#endif
-
- compile_block.lcc = tables + lcc_offset;
- compile_block.fcc = tables + fcc_offset;
- compile_block.cbits = tables + cbits_offset;
- compile_block.ctypes = tables + ctypes_offset;
-
- /* See if we can find a fixed set of initial characters for the pattern. */
-
- memset(start_bits, 0, 32 * sizeof(pcre_uint8));
- rc = set_start_bits(code, start_bits, (re->options & PCRE_UTF8) != 0,
- &compile_block);
- bits_set = rc == SSB_DONE;
- if (rc == SSB_UNKNOWN)
- {
- *errorptr = "internal error: opcode not recognized";
- return NULL;
- }
- }
-
-/* Find the minimum length of subject string. */
-
-switch(min = find_minlength(code, code, re->options, 0))
- {
- case -2: *errorptr = "internal error: missing capturing bracket"; return NULL;
- case -3: *errorptr = "internal error: opcode not recognized"; return NULL;
- default: break;
- }
-
-/* If a set of starting bytes has been identified, or if the minimum length is
-greater than zero, or if JIT optimization has been requested, or if
-PCRE_STUDY_EXTRA_NEEDED is set, get a pcre[16]_extra block and a
-pcre_study_data block. The study data is put in the latter, which is pointed to
-by the former, which may also get additional data set later by the calling
-program. At the moment, the size of pcre_study_data is fixed. We nevertheless
-save it in a field for returning via the pcre_fullinfo() function so that if it
-becomes variable in the future, we don't have to change that code. */
-
-if (bits_set || min > 0 || (options & (
-#ifdef SUPPORT_JIT
- PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE |
- PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE |
-#endif
- PCRE_STUDY_EXTRA_NEEDED)) != 0)
- {
- extra = (PUBL(extra) *)(PUBL(malloc))
- (sizeof(PUBL(extra)) + sizeof(pcre_study_data));
- if (extra == NULL)
- {
- *errorptr = "failed to get memory";
- return NULL;
- }
-
- study = (pcre_study_data *)((char *)extra + sizeof(PUBL(extra)));
- extra->flags = PCRE_EXTRA_STUDY_DATA;
- extra->study_data = study;
-
- study->size = sizeof(pcre_study_data);
- study->flags = 0;
-
- /* Set the start bits always, to avoid unset memory errors if the
- study data is written to a file, but set the flag only if any of the bits
- are set, to save time looking when none are. */
-
- if (bits_set)
- {
- study->flags |= PCRE_STUDY_MAPPED;
- memcpy(study->start_bits, start_bits, sizeof(start_bits));
- }
- else memset(study->start_bits, 0, 32 * sizeof(pcre_uint8));
-
-#ifdef PCRE_DEBUG
- if (bits_set)
- {
- pcre_uint8 *ptr = start_bits;
- int i;
-
- printf("Start bits:\n");
- for (i = 0; i < 32; i++)
- printf("%3d: %02x%s", i * 8, *ptr++, ((i + 1) & 0x7) != 0? " " : "\n");
- }
-#endif
-
- /* Always set the minlength value in the block, because the JIT compiler
- makes use of it. However, don't set the bit unless the length is greater than
- zero - the interpretive pcre_exec() and pcre_dfa_exec() needn't waste time
- checking the zero case. */
-
- if (min > 0)
- {
- study->flags |= PCRE_STUDY_MINLEN;
- study->minlength = min;
- }
- else study->minlength = 0;
-
- /* If JIT support was compiled and requested, attempt the JIT compilation.
- If no starting bytes were found, and the minimum length is zero, and JIT
- compilation fails, abandon the extra block and return NULL, unless
- PCRE_STUDY_EXTRA_NEEDED is set. */
-
-#ifdef SUPPORT_JIT
- extra->executable_jit = NULL;
- if ((options & PCRE_STUDY_JIT_COMPILE) != 0)
- PRIV(jit_compile)(re, extra, JIT_COMPILE);
- if ((options & PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE) != 0)
- PRIV(jit_compile)(re, extra, JIT_PARTIAL_SOFT_COMPILE);
- if ((options & PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE) != 0)
- PRIV(jit_compile)(re, extra, JIT_PARTIAL_HARD_COMPILE);
-
- if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0 &&
- (options & PCRE_STUDY_EXTRA_NEEDED) == 0)
- {
-#if defined COMPILE_PCRE8
- pcre_free_study(extra);
-#elif defined COMPILE_PCRE16
- pcre16_free_study(extra);
-#elif defined COMPILE_PCRE32
- pcre32_free_study(extra);
-#endif
- extra = NULL;
- }
-#endif
- }
-
-return extra;
-}
-
-
-/*************************************************
-* Free the study data *
-*************************************************/
-
-/* This function frees the memory that was obtained by pcre_study().
-
-Argument: a pointer to the pcre[16]_extra block
-Returns: nothing
-*/
-
-#if defined COMPILE_PCRE8
-PCRE_EXP_DEFN void
-pcre_free_study(pcre_extra *extra)
-#elif defined COMPILE_PCRE16
-PCRE_EXP_DEFN void
-pcre16_free_study(pcre16_extra *extra)
-#elif defined COMPILE_PCRE32
-PCRE_EXP_DEFN void
-pcre32_free_study(pcre32_extra *extra)
-#endif
-{
-if (extra == NULL)
- return;
-#ifdef SUPPORT_JIT
-if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
- extra->executable_jit != NULL)
- PRIV(jit_free)(extra->executable_jit);
-#endif
-PUBL(free)(extra);
-}
-
-/* End of pcre_study.c */
diff --git a/usr.sbin/nginx/src/pcre/pcre_tables.c b/usr.sbin/nginx/src/pcre/pcre_tables.c
deleted file mode 100644
index f38ab52cbb8..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre_tables.c
+++ /dev/null
@@ -1,658 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-#ifndef PCRE_INCLUDED
-
-/* This module contains some fixed tables that are used by more than one of the
-PCRE code modules. The tables are also #included by the pcretest program, which
-uses macros to change their names from _pcre_xxx to xxxx, thereby avoiding name
-clashes with the library. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-#endif /* PCRE_INCLUDED */
-
-/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
-the definition is next to the definition of the opcodes in pcre_internal.h. */
-
-const pcre_uint8 PRIV(OP_lengths)[] = { OP_LENGTHS };
-
-/* Tables of horizontal and vertical whitespace characters, suitable for
-adding to classes. */
-
-const pcre_uint32 PRIV(hspace_list)[] = { HSPACE_LIST };
-const pcre_uint32 PRIV(vspace_list)[] = { VSPACE_LIST };
-
-
-
-/*************************************************
-* Tables for UTF-8 support *
-*************************************************/
-
-/* These are the breakpoints for different numbers of bytes in a UTF-8
-character. */
-
-#if (defined SUPPORT_UTF && defined COMPILE_PCRE8) \
- || (defined PCRE_INCLUDED && (defined SUPPORT_PCRE16 || defined SUPPORT_PCRE32))
-
-/* These tables are also required by pcretest in 16- or 32-bit mode. */
-
-const int PRIV(utf8_table1)[] =
- { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
-
-const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int);
-
-/* These are the indicator bits and the mask for the data bits to set in the
-first byte of a character, indexed by the number of additional bytes. */
-
-const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
-const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
-
-/* Table of the number of extra bytes, indexed by the first byte masked with
-0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */
-
-const pcre_uint8 PRIV(utf8_table4)[] = {
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
-
-#endif /* (SUPPORT_UTF && COMPILE_PCRE8) || (PCRE_INCLUDED && SUPPORT_PCRE[16|32])*/
-
-#ifdef SUPPORT_UTF
-
-/* Table to translate from particular type value to the general value. */
-
-const pcre_uint32 PRIV(ucp_gentype)[] = {
- ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */
- ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */
- ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */
- ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */
- ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */
- ucp_P, ucp_P, /* Ps, Po */
- ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */
- ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */
-};
-
-/* This table encodes the rules for finding the end of an extended grapheme
-cluster. Every code point has a grapheme break property which is one of the
-ucp_gbXX values defined in ucp.h. The 2-dimensional table is indexed by the
-properties of two adjacent code points. The left property selects a word from
-the table, and the right property selects a bit from that word like this:
-
- ucp_gbtable[left-property] & (1 << right-property)
-
-The value is non-zero if a grapheme break is NOT permitted between the relevant
-two code points. The breaking rules are as follows:
-
-1. Break at the start and end of text (pretty obviously).
-
-2. Do not break between a CR and LF; otherwise, break before and after
- controls.
-
-3. Do not break Hangul syllable sequences, the rules for which are:
-
- L may be followed by L, V, LV or LVT
- LV or V may be followed by V or T
- LVT or T may be followed by T
-
-4. Do not break before extending characters.
-
-The next two rules are only for extended grapheme clusters (but that's what we
-are implementing).
-
-5. Do not break before SpacingMarks.
-
-6. Do not break after Prepend characters.
-
-7. Otherwise, break everywhere.
-*/
-
-const pcre_uint32 PRIV(ucp_gbtable[]) = {
- (1<<ucp_gbLF), /* 0 CR */
- 0, /* 1 LF */
- 0, /* 2 Control */
- (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark), /* 3 Extend */
- (1<<ucp_gbExtend)|(1<<ucp_gbPrepend)| /* 4 Prepend */
- (1<<ucp_gbSpacingMark)|(1<<ucp_gbL)|
- (1<<ucp_gbV)|(1<<ucp_gbT)|(1<<ucp_gbLV)|
- (1<<ucp_gbLVT)|(1<<ucp_gbOther),
-
- (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark), /* 5 SpacingMark */
- (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbL)| /* 6 L */
- (1<<ucp_gbL)|(1<<ucp_gbV)|(1<<ucp_gbLV)|(1<<ucp_gbLVT),
-
- (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbV)| /* 7 V */
- (1<<ucp_gbT),
-
- (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbT), /* 8 T */
- (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbV)| /* 9 LV */
- (1<<ucp_gbT),
-
- (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbT), /* 10 LVT */
- (1<<ucp_gbRegionalIndicator), /* 11 RegionalIndicator */
- (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark) /* 12 Other */
-};
-
-#ifdef SUPPORT_JIT
-/* This table reverses PRIV(ucp_gentype). We can save the cost
-of a memory load. */
-
-const int PRIV(ucp_typerange)[] = {
- ucp_Cc, ucp_Cs,
- ucp_Ll, ucp_Lu,
- ucp_Mc, ucp_Mn,
- ucp_Nd, ucp_No,
- ucp_Pc, ucp_Ps,
- ucp_Sc, ucp_So,
- ucp_Zl, ucp_Zs,
-};
-#endif /* SUPPORT_JIT */
-
-/* The pcre_utt[] table below translates Unicode property names into type and
-code values. It is searched by binary chop, so must be in collating sequence of
-name. Originally, the table contained pointers to the name strings in the first
-field of each entry. However, that leads to a large number of relocations when
-a shared library is dynamically loaded. A significant reduction is made by
-putting all the names into a single, large string and then using offsets in the
-table itself. Maintenance is more error-prone, but frequent changes to this
-data are unlikely.
-
-July 2008: There is now a script called maint/GenerateUtt.py that can be used
-to generate this data automatically instead of maintaining it by hand.
-
-The script was updated in March 2009 to generate a new EBCDIC-compliant
-version. Like all other character and string literals that are compared against
-the regular expression pattern, we must use STR_ macros instead of literal
-strings to make sure that UTF-8 support works on EBCDIC platforms. */
-
-#define STRING_Any0 STR_A STR_n STR_y "\0"
-#define STRING_Arabic0 STR_A STR_r STR_a STR_b STR_i STR_c "\0"
-#define STRING_Armenian0 STR_A STR_r STR_m STR_e STR_n STR_i STR_a STR_n "\0"
-#define STRING_Avestan0 STR_A STR_v STR_e STR_s STR_t STR_a STR_n "\0"
-#define STRING_Balinese0 STR_B STR_a STR_l STR_i STR_n STR_e STR_s STR_e "\0"
-#define STRING_Bamum0 STR_B STR_a STR_m STR_u STR_m "\0"
-#define STRING_Batak0 STR_B STR_a STR_t STR_a STR_k "\0"
-#define STRING_Bengali0 STR_B STR_e STR_n STR_g STR_a STR_l STR_i "\0"
-#define STRING_Bopomofo0 STR_B STR_o STR_p STR_o STR_m STR_o STR_f STR_o "\0"
-#define STRING_Brahmi0 STR_B STR_r STR_a STR_h STR_m STR_i "\0"
-#define STRING_Braille0 STR_B STR_r STR_a STR_i STR_l STR_l STR_e "\0"
-#define STRING_Buginese0 STR_B STR_u STR_g STR_i STR_n STR_e STR_s STR_e "\0"
-#define STRING_Buhid0 STR_B STR_u STR_h STR_i STR_d "\0"
-#define STRING_C0 STR_C "\0"
-#define STRING_Canadian_Aboriginal0 STR_C STR_a STR_n STR_a STR_d STR_i STR_a STR_n STR_UNDERSCORE STR_A STR_b STR_o STR_r STR_i STR_g STR_i STR_n STR_a STR_l "\0"
-#define STRING_Carian0 STR_C STR_a STR_r STR_i STR_a STR_n "\0"
-#define STRING_Cc0 STR_C STR_c "\0"
-#define STRING_Cf0 STR_C STR_f "\0"
-#define STRING_Chakma0 STR_C STR_h STR_a STR_k STR_m STR_a "\0"
-#define STRING_Cham0 STR_C STR_h STR_a STR_m "\0"
-#define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0"
-#define STRING_Cn0 STR_C STR_n "\0"
-#define STRING_Co0 STR_C STR_o "\0"
-#define STRING_Common0 STR_C STR_o STR_m STR_m STR_o STR_n "\0"
-#define STRING_Coptic0 STR_C STR_o STR_p STR_t STR_i STR_c "\0"
-#define STRING_Cs0 STR_C STR_s "\0"
-#define STRING_Cuneiform0 STR_C STR_u STR_n STR_e STR_i STR_f STR_o STR_r STR_m "\0"
-#define STRING_Cypriot0 STR_C STR_y STR_p STR_r STR_i STR_o STR_t "\0"
-#define STRING_Cyrillic0 STR_C STR_y STR_r STR_i STR_l STR_l STR_i STR_c "\0"
-#define STRING_Deseret0 STR_D STR_e STR_s STR_e STR_r STR_e STR_t "\0"
-#define STRING_Devanagari0 STR_D STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i "\0"
-#define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
-#define STRING_Ethiopic0 STR_E STR_t STR_h STR_i STR_o STR_p STR_i STR_c "\0"
-#define STRING_Georgian0 STR_G STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0"
-#define STRING_Glagolitic0 STR_G STR_l STR_a STR_g STR_o STR_l STR_i STR_t STR_i STR_c "\0"
-#define STRING_Gothic0 STR_G STR_o STR_t STR_h STR_i STR_c "\0"
-#define STRING_Greek0 STR_G STR_r STR_e STR_e STR_k "\0"
-#define STRING_Gujarati0 STR_G STR_u STR_j STR_a STR_r STR_a STR_t STR_i "\0"
-#define STRING_Gurmukhi0 STR_G STR_u STR_r STR_m STR_u STR_k STR_h STR_i "\0"
-#define STRING_Han0 STR_H STR_a STR_n "\0"
-#define STRING_Hangul0 STR_H STR_a STR_n STR_g STR_u STR_l "\0"
-#define STRING_Hanunoo0 STR_H STR_a STR_n STR_u STR_n STR_o STR_o "\0"
-#define STRING_Hebrew0 STR_H STR_e STR_b STR_r STR_e STR_w "\0"
-#define STRING_Hiragana0 STR_H STR_i STR_r STR_a STR_g STR_a STR_n STR_a "\0"
-#define STRING_Imperial_Aramaic0 STR_I STR_m STR_p STR_e STR_r STR_i STR_a STR_l STR_UNDERSCORE STR_A STR_r STR_a STR_m STR_a STR_i STR_c "\0"
-#define STRING_Inherited0 STR_I STR_n STR_h STR_e STR_r STR_i STR_t STR_e STR_d "\0"
-#define STRING_Inscriptional_Pahlavi0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_h STR_l STR_a STR_v STR_i "\0"
-#define STRING_Inscriptional_Parthian0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_r STR_t STR_h STR_i STR_a STR_n "\0"
-#define STRING_Javanese0 STR_J STR_a STR_v STR_a STR_n STR_e STR_s STR_e "\0"
-#define STRING_Kaithi0 STR_K STR_a STR_i STR_t STR_h STR_i "\0"
-#define STRING_Kannada0 STR_K STR_a STR_n STR_n STR_a STR_d STR_a "\0"
-#define STRING_Katakana0 STR_K STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0"
-#define STRING_Kayah_Li0 STR_K STR_a STR_y STR_a STR_h STR_UNDERSCORE STR_L STR_i "\0"
-#define STRING_Kharoshthi0 STR_K STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0"
-#define STRING_Khmer0 STR_K STR_h STR_m STR_e STR_r "\0"
-#define STRING_L0 STR_L "\0"
-#define STRING_L_AMPERSAND0 STR_L STR_AMPERSAND "\0"
-#define STRING_Lao0 STR_L STR_a STR_o "\0"
-#define STRING_Latin0 STR_L STR_a STR_t STR_i STR_n "\0"
-#define STRING_Lepcha0 STR_L STR_e STR_p STR_c STR_h STR_a "\0"
-#define STRING_Limbu0 STR_L STR_i STR_m STR_b STR_u "\0"
-#define STRING_Linear_B0 STR_L STR_i STR_n STR_e STR_a STR_r STR_UNDERSCORE STR_B "\0"
-#define STRING_Lisu0 STR_L STR_i STR_s STR_u "\0"
-#define STRING_Ll0 STR_L STR_l "\0"
-#define STRING_Lm0 STR_L STR_m "\0"
-#define STRING_Lo0 STR_L STR_o "\0"
-#define STRING_Lt0 STR_L STR_t "\0"
-#define STRING_Lu0 STR_L STR_u "\0"
-#define STRING_Lycian0 STR_L STR_y STR_c STR_i STR_a STR_n "\0"
-#define STRING_Lydian0 STR_L STR_y STR_d STR_i STR_a STR_n "\0"
-#define STRING_M0 STR_M "\0"
-#define STRING_Malayalam0 STR_M STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m "\0"
-#define STRING_Mandaic0 STR_M STR_a STR_n STR_d STR_a STR_i STR_c "\0"
-#define STRING_Mc0 STR_M STR_c "\0"
-#define STRING_Me0 STR_M STR_e "\0"
-#define STRING_Meetei_Mayek0 STR_M STR_e STR_e STR_t STR_e STR_i STR_UNDERSCORE STR_M STR_a STR_y STR_e STR_k "\0"
-#define STRING_Meroitic_Cursive0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_C STR_u STR_r STR_s STR_i STR_v STR_e "\0"
-#define STRING_Meroitic_Hieroglyphs0 STR_M STR_e STR_r STR_o STR_i STR_t STR_i STR_c STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
-#define STRING_Miao0 STR_M STR_i STR_a STR_o "\0"
-#define STRING_Mn0 STR_M STR_n "\0"
-#define STRING_Mongolian0 STR_M STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0"
-#define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0"
-#define STRING_N0 STR_N "\0"
-#define STRING_Nd0 STR_N STR_d "\0"
-#define STRING_New_Tai_Lue0 STR_N STR_e STR_w STR_UNDERSCORE STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_u STR_e "\0"
-#define STRING_Nko0 STR_N STR_k STR_o "\0"
-#define STRING_Nl0 STR_N STR_l "\0"
-#define STRING_No0 STR_N STR_o "\0"
-#define STRING_Ogham0 STR_O STR_g STR_h STR_a STR_m "\0"
-#define STRING_Ol_Chiki0 STR_O STR_l STR_UNDERSCORE STR_C STR_h STR_i STR_k STR_i "\0"
-#define STRING_Old_Italic0 STR_O STR_l STR_d STR_UNDERSCORE STR_I STR_t STR_a STR_l STR_i STR_c "\0"
-#define STRING_Old_Persian0 STR_O STR_l STR_d STR_UNDERSCORE STR_P STR_e STR_r STR_s STR_i STR_a STR_n "\0"
-#define STRING_Old_South_Arabian0 STR_O STR_l STR_d STR_UNDERSCORE STR_S STR_o STR_u STR_t STR_h STR_UNDERSCORE STR_A STR_r STR_a STR_b STR_i STR_a STR_n "\0"
-#define STRING_Old_Turkic0 STR_O STR_l STR_d STR_UNDERSCORE STR_T STR_u STR_r STR_k STR_i STR_c "\0"
-#define STRING_Oriya0 STR_O STR_r STR_i STR_y STR_a "\0"
-#define STRING_Osmanya0 STR_O STR_s STR_m STR_a STR_n STR_y STR_a "\0"
-#define STRING_P0 STR_P "\0"
-#define STRING_Pc0 STR_P STR_c "\0"
-#define STRING_Pd0 STR_P STR_d "\0"
-#define STRING_Pe0 STR_P STR_e "\0"
-#define STRING_Pf0 STR_P STR_f "\0"
-#define STRING_Phags_Pa0 STR_P STR_h STR_a STR_g STR_s STR_UNDERSCORE STR_P STR_a "\0"
-#define STRING_Phoenician0 STR_P STR_h STR_o STR_e STR_n STR_i STR_c STR_i STR_a STR_n "\0"
-#define STRING_Pi0 STR_P STR_i "\0"
-#define STRING_Po0 STR_P STR_o "\0"
-#define STRING_Ps0 STR_P STR_s "\0"
-#define STRING_Rejang0 STR_R STR_e STR_j STR_a STR_n STR_g "\0"
-#define STRING_Runic0 STR_R STR_u STR_n STR_i STR_c "\0"
-#define STRING_S0 STR_S "\0"
-#define STRING_Samaritan0 STR_S STR_a STR_m STR_a STR_r STR_i STR_t STR_a STR_n "\0"
-#define STRING_Saurashtra0 STR_S STR_a STR_u STR_r STR_a STR_s STR_h STR_t STR_r STR_a "\0"
-#define STRING_Sc0 STR_S STR_c "\0"
-#define STRING_Sharada0 STR_S STR_h STR_a STR_r STR_a STR_d STR_a "\0"
-#define STRING_Shavian0 STR_S STR_h STR_a STR_v STR_i STR_a STR_n "\0"
-#define STRING_Sinhala0 STR_S STR_i STR_n STR_h STR_a STR_l STR_a "\0"
-#define STRING_Sk0 STR_S STR_k "\0"
-#define STRING_Sm0 STR_S STR_m "\0"
-#define STRING_So0 STR_S STR_o "\0"
-#define STRING_Sora_Sompeng0 STR_S STR_o STR_r STR_a STR_UNDERSCORE STR_S STR_o STR_m STR_p STR_e STR_n STR_g "\0"
-#define STRING_Sundanese0 STR_S STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e "\0"
-#define STRING_Syloti_Nagri0 STR_S STR_y STR_l STR_o STR_t STR_i STR_UNDERSCORE STR_N STR_a STR_g STR_r STR_i "\0"
-#define STRING_Syriac0 STR_S STR_y STR_r STR_i STR_a STR_c "\0"
-#define STRING_Tagalog0 STR_T STR_a STR_g STR_a STR_l STR_o STR_g "\0"
-#define STRING_Tagbanwa0 STR_T STR_a STR_g STR_b STR_a STR_n STR_w STR_a "\0"
-#define STRING_Tai_Le0 STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_e "\0"
-#define STRING_Tai_Tham0 STR_T STR_a STR_i STR_UNDERSCORE STR_T STR_h STR_a STR_m "\0"
-#define STRING_Tai_Viet0 STR_T STR_a STR_i STR_UNDERSCORE STR_V STR_i STR_e STR_t "\0"
-#define STRING_Takri0 STR_T STR_a STR_k STR_r STR_i "\0"
-#define STRING_Tamil0 STR_T STR_a STR_m STR_i STR_l "\0"
-#define STRING_Telugu0 STR_T STR_e STR_l STR_u STR_g STR_u "\0"
-#define STRING_Thaana0 STR_T STR_h STR_a STR_a STR_n STR_a "\0"
-#define STRING_Thai0 STR_T STR_h STR_a STR_i "\0"
-#define STRING_Tibetan0 STR_T STR_i STR_b STR_e STR_t STR_a STR_n "\0"
-#define STRING_Tifinagh0 STR_T STR_i STR_f STR_i STR_n STR_a STR_g STR_h "\0"
-#define STRING_Ugaritic0 STR_U STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0"
-#define STRING_Vai0 STR_V STR_a STR_i "\0"
-#define STRING_Xan0 STR_X STR_a STR_n "\0"
-#define STRING_Xps0 STR_X STR_p STR_s "\0"
-#define STRING_Xsp0 STR_X STR_s STR_p "\0"
-#define STRING_Xuc0 STR_X STR_u STR_c "\0"
-#define STRING_Xwd0 STR_X STR_w STR_d "\0"
-#define STRING_Yi0 STR_Y STR_i "\0"
-#define STRING_Z0 STR_Z "\0"
-#define STRING_Zl0 STR_Z STR_l "\0"
-#define STRING_Zp0 STR_Z STR_p "\0"
-#define STRING_Zs0 STR_Z STR_s "\0"
-
-const char PRIV(utt_names)[] =
- STRING_Any0
- STRING_Arabic0
- STRING_Armenian0
- STRING_Avestan0
- STRING_Balinese0
- STRING_Bamum0
- STRING_Batak0
- STRING_Bengali0
- STRING_Bopomofo0
- STRING_Brahmi0
- STRING_Braille0
- STRING_Buginese0
- STRING_Buhid0
- STRING_C0
- STRING_Canadian_Aboriginal0
- STRING_Carian0
- STRING_Cc0
- STRING_Cf0
- STRING_Chakma0
- STRING_Cham0
- STRING_Cherokee0
- STRING_Cn0
- STRING_Co0
- STRING_Common0
- STRING_Coptic0
- STRING_Cs0
- STRING_Cuneiform0
- STRING_Cypriot0
- STRING_Cyrillic0
- STRING_Deseret0
- STRING_Devanagari0
- STRING_Egyptian_Hieroglyphs0
- STRING_Ethiopic0
- STRING_Georgian0
- STRING_Glagolitic0
- STRING_Gothic0
- STRING_Greek0
- STRING_Gujarati0
- STRING_Gurmukhi0
- STRING_Han0
- STRING_Hangul0
- STRING_Hanunoo0
- STRING_Hebrew0
- STRING_Hiragana0
- STRING_Imperial_Aramaic0
- STRING_Inherited0
- STRING_Inscriptional_Pahlavi0
- STRING_Inscriptional_Parthian0
- STRING_Javanese0
- STRING_Kaithi0
- STRING_Kannada0
- STRING_Katakana0
- STRING_Kayah_Li0
- STRING_Kharoshthi0
- STRING_Khmer0
- STRING_L0
- STRING_L_AMPERSAND0
- STRING_Lao0
- STRING_Latin0
- STRING_Lepcha0
- STRING_Limbu0
- STRING_Linear_B0
- STRING_Lisu0
- STRING_Ll0
- STRING_Lm0
- STRING_Lo0
- STRING_Lt0
- STRING_Lu0
- STRING_Lycian0
- STRING_Lydian0
- STRING_M0
- STRING_Malayalam0
- STRING_Mandaic0
- STRING_Mc0
- STRING_Me0
- STRING_Meetei_Mayek0
- STRING_Meroitic_Cursive0
- STRING_Meroitic_Hieroglyphs0
- STRING_Miao0
- STRING_Mn0
- STRING_Mongolian0
- STRING_Myanmar0
- STRING_N0
- STRING_Nd0
- STRING_New_Tai_Lue0
- STRING_Nko0
- STRING_Nl0
- STRING_No0
- STRING_Ogham0
- STRING_Ol_Chiki0
- STRING_Old_Italic0
- STRING_Old_Persian0
- STRING_Old_South_Arabian0
- STRING_Old_Turkic0
- STRING_Oriya0
- STRING_Osmanya0
- STRING_P0
- STRING_Pc0
- STRING_Pd0
- STRING_Pe0
- STRING_Pf0
- STRING_Phags_Pa0
- STRING_Phoenician0
- STRING_Pi0
- STRING_Po0
- STRING_Ps0
- STRING_Rejang0
- STRING_Runic0
- STRING_S0
- STRING_Samaritan0
- STRING_Saurashtra0
- STRING_Sc0
- STRING_Sharada0
- STRING_Shavian0
- STRING_Sinhala0
- STRING_Sk0
- STRING_Sm0
- STRING_So0
- STRING_Sora_Sompeng0
- STRING_Sundanese0
- STRING_Syloti_Nagri0
- STRING_Syriac0
- STRING_Tagalog0
- STRING_Tagbanwa0
- STRING_Tai_Le0
- STRING_Tai_Tham0
- STRING_Tai_Viet0
- STRING_Takri0
- STRING_Tamil0
- STRING_Telugu0
- STRING_Thaana0
- STRING_Thai0
- STRING_Tibetan0
- STRING_Tifinagh0
- STRING_Ugaritic0
- STRING_Vai0
- STRING_Xan0
- STRING_Xps0
- STRING_Xsp0
- STRING_Xuc0
- STRING_Xwd0
- STRING_Yi0
- STRING_Z0
- STRING_Zl0
- STRING_Zp0
- STRING_Zs0;
-
-const ucp_type_table PRIV(utt)[] = {
- { 0, PT_ANY, 0 },
- { 4, PT_SC, ucp_Arabic },
- { 11, PT_SC, ucp_Armenian },
- { 20, PT_SC, ucp_Avestan },
- { 28, PT_SC, ucp_Balinese },
- { 37, PT_SC, ucp_Bamum },
- { 43, PT_SC, ucp_Batak },
- { 49, PT_SC, ucp_Bengali },
- { 57, PT_SC, ucp_Bopomofo },
- { 66, PT_SC, ucp_Brahmi },
- { 73, PT_SC, ucp_Braille },
- { 81, PT_SC, ucp_Buginese },
- { 90, PT_SC, ucp_Buhid },
- { 96, PT_GC, ucp_C },
- { 98, PT_SC, ucp_Canadian_Aboriginal },
- { 118, PT_SC, ucp_Carian },
- { 125, PT_PC, ucp_Cc },
- { 128, PT_PC, ucp_Cf },
- { 131, PT_SC, ucp_Chakma },
- { 138, PT_SC, ucp_Cham },
- { 143, PT_SC, ucp_Cherokee },
- { 152, PT_PC, ucp_Cn },
- { 155, PT_PC, ucp_Co },
- { 158, PT_SC, ucp_Common },
- { 165, PT_SC, ucp_Coptic },
- { 172, PT_PC, ucp_Cs },
- { 175, PT_SC, ucp_Cuneiform },
- { 185, PT_SC, ucp_Cypriot },
- { 193, PT_SC, ucp_Cyrillic },
- { 202, PT_SC, ucp_Deseret },
- { 210, PT_SC, ucp_Devanagari },
- { 221, PT_SC, ucp_Egyptian_Hieroglyphs },
- { 242, PT_SC, ucp_Ethiopic },
- { 251, PT_SC, ucp_Georgian },
- { 260, PT_SC, ucp_Glagolitic },
- { 271, PT_SC, ucp_Gothic },
- { 278, PT_SC, ucp_Greek },
- { 284, PT_SC, ucp_Gujarati },
- { 293, PT_SC, ucp_Gurmukhi },
- { 302, PT_SC, ucp_Han },
- { 306, PT_SC, ucp_Hangul },
- { 313, PT_SC, ucp_Hanunoo },
- { 321, PT_SC, ucp_Hebrew },
- { 328, PT_SC, ucp_Hiragana },
- { 337, PT_SC, ucp_Imperial_Aramaic },
- { 354, PT_SC, ucp_Inherited },
- { 364, PT_SC, ucp_Inscriptional_Pahlavi },
- { 386, PT_SC, ucp_Inscriptional_Parthian },
- { 409, PT_SC, ucp_Javanese },
- { 418, PT_SC, ucp_Kaithi },
- { 425, PT_SC, ucp_Kannada },
- { 433, PT_SC, ucp_Katakana },
- { 442, PT_SC, ucp_Kayah_Li },
- { 451, PT_SC, ucp_Kharoshthi },
- { 462, PT_SC, ucp_Khmer },
- { 468, PT_GC, ucp_L },
- { 470, PT_LAMP, 0 },
- { 473, PT_SC, ucp_Lao },
- { 477, PT_SC, ucp_Latin },
- { 483, PT_SC, ucp_Lepcha },
- { 490, PT_SC, ucp_Limbu },
- { 496, PT_SC, ucp_Linear_B },
- { 505, PT_SC, ucp_Lisu },
- { 510, PT_PC, ucp_Ll },
- { 513, PT_PC, ucp_Lm },
- { 516, PT_PC, ucp_Lo },
- { 519, PT_PC, ucp_Lt },
- { 522, PT_PC, ucp_Lu },
- { 525, PT_SC, ucp_Lycian },
- { 532, PT_SC, ucp_Lydian },
- { 539, PT_GC, ucp_M },
- { 541, PT_SC, ucp_Malayalam },
- { 551, PT_SC, ucp_Mandaic },
- { 559, PT_PC, ucp_Mc },
- { 562, PT_PC, ucp_Me },
- { 565, PT_SC, ucp_Meetei_Mayek },
- { 578, PT_SC, ucp_Meroitic_Cursive },
- { 595, PT_SC, ucp_Meroitic_Hieroglyphs },
- { 616, PT_SC, ucp_Miao },
- { 621, PT_PC, ucp_Mn },
- { 624, PT_SC, ucp_Mongolian },
- { 634, PT_SC, ucp_Myanmar },
- { 642, PT_GC, ucp_N },
- { 644, PT_PC, ucp_Nd },
- { 647, PT_SC, ucp_New_Tai_Lue },
- { 659, PT_SC, ucp_Nko },
- { 663, PT_PC, ucp_Nl },
- { 666, PT_PC, ucp_No },
- { 669, PT_SC, ucp_Ogham },
- { 675, PT_SC, ucp_Ol_Chiki },
- { 684, PT_SC, ucp_Old_Italic },
- { 695, PT_SC, ucp_Old_Persian },
- { 707, PT_SC, ucp_Old_South_Arabian },
- { 725, PT_SC, ucp_Old_Turkic },
- { 736, PT_SC, ucp_Oriya },
- { 742, PT_SC, ucp_Osmanya },
- { 750, PT_GC, ucp_P },
- { 752, PT_PC, ucp_Pc },
- { 755, PT_PC, ucp_Pd },
- { 758, PT_PC, ucp_Pe },
- { 761, PT_PC, ucp_Pf },
- { 764, PT_SC, ucp_Phags_Pa },
- { 773, PT_SC, ucp_Phoenician },
- { 784, PT_PC, ucp_Pi },
- { 787, PT_PC, ucp_Po },
- { 790, PT_PC, ucp_Ps },
- { 793, PT_SC, ucp_Rejang },
- { 800, PT_SC, ucp_Runic },
- { 806, PT_GC, ucp_S },
- { 808, PT_SC, ucp_Samaritan },
- { 818, PT_SC, ucp_Saurashtra },
- { 829, PT_PC, ucp_Sc },
- { 832, PT_SC, ucp_Sharada },
- { 840, PT_SC, ucp_Shavian },
- { 848, PT_SC, ucp_Sinhala },
- { 856, PT_PC, ucp_Sk },
- { 859, PT_PC, ucp_Sm },
- { 862, PT_PC, ucp_So },
- { 865, PT_SC, ucp_Sora_Sompeng },
- { 878, PT_SC, ucp_Sundanese },
- { 888, PT_SC, ucp_Syloti_Nagri },
- { 901, PT_SC, ucp_Syriac },
- { 908, PT_SC, ucp_Tagalog },
- { 916, PT_SC, ucp_Tagbanwa },
- { 925, PT_SC, ucp_Tai_Le },
- { 932, PT_SC, ucp_Tai_Tham },
- { 941, PT_SC, ucp_Tai_Viet },
- { 950, PT_SC, ucp_Takri },
- { 956, PT_SC, ucp_Tamil },
- { 962, PT_SC, ucp_Telugu },
- { 969, PT_SC, ucp_Thaana },
- { 976, PT_SC, ucp_Thai },
- { 981, PT_SC, ucp_Tibetan },
- { 989, PT_SC, ucp_Tifinagh },
- { 998, PT_SC, ucp_Ugaritic },
- { 1007, PT_SC, ucp_Vai },
- { 1011, PT_ALNUM, 0 },
- { 1015, PT_PXSPACE, 0 },
- { 1019, PT_SPACE, 0 },
- { 1023, PT_UCNC, 0 },
- { 1027, PT_WORD, 0 },
- { 1031, PT_SC, ucp_Yi },
- { 1034, PT_GC, ucp_Z },
- { 1036, PT_PC, ucp_Zl },
- { 1039, PT_PC, ucp_Zp },
- { 1042, PT_PC, ucp_Zs }
-};
-
-const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
-
-#endif /* SUPPORT_UTF */
-
-/* End of pcre_tables.c */
diff --git a/usr.sbin/nginx/src/pcre/pcre_ucd.c b/usr.sbin/nginx/src/pcre/pcre_ucd.c
deleted file mode 100644
index 56f31a1e69b..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre_ucd.c
+++ /dev/null
@@ -1,3298 +0,0 @@
-/* This module is generated by the maint/MultiStage2.py script.
-Do not modify it by hand. Instead modify the script and run it
-to regenerate this code.
-
-As well as being part of the PCRE library, this module is #included
-by the pcretest program, which redefines the PRIV macro to change
-table names from _pcre_xxx to xxxx, thereby avoiding name clashes
-with the library. At present, just one of these tables is actually
-needed. */
-
-#ifndef PCRE_INCLUDED
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-#endif /* PCRE_INCLUDED */
-
-/* Unicode character database. */
-/* This file was autogenerated by the MultiStage2.py script. */
-/* Total size: 65696 bytes, block size: 128. */
-
-/* The tables herein are needed only when UCP support is built
-into PCRE. This module should not be referenced otherwise, so
-it should not matter whether it is compiled or not. However
-a comment was received about space saving - maybe the guy linked
-all the modules rather than using a library - so we include a
-condition to cut out the tables when not needed. But don't leave
-a totally empty module because some compilers barf at that.
-Instead, just supply small dummy tables. */
-
-#ifndef SUPPORT_UCP
-const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0 }};
-const pcre_uint8 PRIV(ucd_stage1)[] = {0};
-const pcre_uint16 PRIV(ucd_stage2)[] = {0};
-const pcre_uint32 PRIV(ucd_caseless_sets)[] = {0};
-#else
-
-/* When recompiling tables with a new Unicode version, please check the
-types in this structure definition from pcre_internal.h (the actual
-field names will be different):
-
-typedef struct {
-pcre_uint8 property_0;
-pcre_uint8 property_1;
-pcre_uint8 property_2;
-pcre_uint8 property_3;
-pcre_int32 property_4;
-} ucd_record;
-*/
-
-
-const pcre_uint32 PRIV(ucd_caseless_sets)[] = {
- NOTACHAR,
- 0x0053, 0x0073, 0x017f, NOTACHAR,
- 0x01c4, 0x01c5, 0x01c6, NOTACHAR,
- 0x01c7, 0x01c8, 0x01c9, NOTACHAR,
- 0x01ca, 0x01cb, 0x01cc, NOTACHAR,
- 0x01f1, 0x01f2, 0x01f3, NOTACHAR,
- 0x0345, 0x0399, 0x03b9, 0x1fbe, NOTACHAR,
- 0x00b5, 0x039c, 0x03bc, NOTACHAR,
- 0x03a3, 0x03c2, 0x03c3, NOTACHAR,
- 0x0392, 0x03b2, 0x03d0, NOTACHAR,
- 0x0398, 0x03b8, 0x03d1, 0x03f4, NOTACHAR,
- 0x03a6, 0x03c6, 0x03d5, NOTACHAR,
- 0x03a0, 0x03c0, 0x03d6, NOTACHAR,
- 0x039a, 0x03ba, 0x03f0, NOTACHAR,
- 0x03a1, 0x03c1, 0x03f1, NOTACHAR,
- 0x0395, 0x03b5, 0x03f5, NOTACHAR,
- 0x1e60, 0x1e61, 0x1e9b, NOTACHAR,
- 0x03a9, 0x03c9, 0x2126, NOTACHAR,
- 0x004b, 0x006b, 0x212a, NOTACHAR,
- 0x00c5, 0x00e5, 0x212b, NOTACHAR,
-};
-
-/* When #included in pcretest, we don't need this large table. */
-
-#ifndef PCRE_INCLUDED
-
-const ucd_record PRIV(ucd_records)[] = { /* 5024 bytes, record size 8 */
- { 9, 0, 2, 0, 0, }, /* 0 */
- { 9, 0, 1, 0, 0, }, /* 1 */
- { 9, 0, 0, 0, 0, }, /* 2 */
- { 9, 29, 12, 0, 0, }, /* 3 */
- { 9, 21, 12, 0, 0, }, /* 4 */
- { 9, 23, 12, 0, 0, }, /* 5 */
- { 9, 22, 12, 0, 0, }, /* 6 */
- { 9, 18, 12, 0, 0, }, /* 7 */
- { 9, 25, 12, 0, 0, }, /* 8 */
- { 9, 17, 12, 0, 0, }, /* 9 */
- { 9, 13, 12, 0, 0, }, /* 10 */
- { 33, 9, 12, 0, 32, }, /* 11 */
- { 33, 9, 12, 71, 32, }, /* 12 */
- { 33, 9, 12, 1, 32, }, /* 13 */
- { 9, 24, 12, 0, 0, }, /* 14 */
- { 9, 16, 12, 0, 0, }, /* 15 */
- { 33, 5, 12, 0, -32, }, /* 16 */
- { 33, 5, 12, 71, -32, }, /* 17 */
- { 33, 5, 12, 1, -32, }, /* 18 */
- { 9, 26, 12, 0, 0, }, /* 19 */
- { 33, 7, 12, 0, 0, }, /* 20 */
- { 9, 20, 12, 0, 0, }, /* 21 */
- { 9, 1, 2, 0, 0, }, /* 22 */
- { 9, 15, 12, 0, 0, }, /* 23 */
- { 9, 5, 12, 26, 775, }, /* 24 */
- { 9, 19, 12, 0, 0, }, /* 25 */
- { 33, 9, 12, 75, 32, }, /* 26 */
- { 33, 5, 12, 0, 7615, }, /* 27 */
- { 33, 5, 12, 75, -32, }, /* 28 */
- { 33, 5, 12, 0, 121, }, /* 29 */
- { 33, 9, 12, 0, 1, }, /* 30 */
- { 33, 5, 12, 0, -1, }, /* 31 */
- { 33, 9, 12, 0, 0, }, /* 32 */
- { 33, 5, 12, 0, 0, }, /* 33 */
- { 33, 9, 12, 0, -121, }, /* 34 */
- { 33, 5, 12, 1, -268, }, /* 35 */
- { 33, 5, 12, 0, 195, }, /* 36 */
- { 33, 9, 12, 0, 210, }, /* 37 */
- { 33, 9, 12, 0, 206, }, /* 38 */
- { 33, 9, 12, 0, 205, }, /* 39 */
- { 33, 9, 12, 0, 79, }, /* 40 */
- { 33, 9, 12, 0, 202, }, /* 41 */
- { 33, 9, 12, 0, 203, }, /* 42 */
- { 33, 9, 12, 0, 207, }, /* 43 */
- { 33, 5, 12, 0, 97, }, /* 44 */
- { 33, 9, 12, 0, 211, }, /* 45 */
- { 33, 9, 12, 0, 209, }, /* 46 */
- { 33, 5, 12, 0, 163, }, /* 47 */
- { 33, 9, 12, 0, 213, }, /* 48 */
- { 33, 5, 12, 0, 130, }, /* 49 */
- { 33, 9, 12, 0, 214, }, /* 50 */
- { 33, 9, 12, 0, 218, }, /* 51 */
- { 33, 9, 12, 0, 217, }, /* 52 */
- { 33, 9, 12, 0, 219, }, /* 53 */
- { 33, 5, 12, 0, 56, }, /* 54 */
- { 33, 9, 12, 5, 2, }, /* 55 */
- { 33, 8, 12, 5, 1, }, /* 56 */
- { 33, 5, 12, 5, -2, }, /* 57 */
- { 33, 9, 12, 9, 2, }, /* 58 */
- { 33, 8, 12, 9, 1, }, /* 59 */
- { 33, 5, 12, 9, -2, }, /* 60 */
- { 33, 9, 12, 13, 2, }, /* 61 */
- { 33, 8, 12, 13, 1, }, /* 62 */
- { 33, 5, 12, 13, -2, }, /* 63 */
- { 33, 5, 12, 0, -79, }, /* 64 */
- { 33, 9, 12, 17, 2, }, /* 65 */
- { 33, 8, 12, 17, 1, }, /* 66 */
- { 33, 5, 12, 17, -2, }, /* 67 */
- { 33, 9, 12, 0, -97, }, /* 68 */
- { 33, 9, 12, 0, -56, }, /* 69 */
- { 33, 9, 12, 0, -130, }, /* 70 */
- { 33, 9, 12, 0, 10795, }, /* 71 */
- { 33, 9, 12, 0, -163, }, /* 72 */
- { 33, 9, 12, 0, 10792, }, /* 73 */
- { 33, 5, 12, 0, 10815, }, /* 74 */
- { 33, 9, 12, 0, -195, }, /* 75 */
- { 33, 9, 12, 0, 69, }, /* 76 */
- { 33, 9, 12, 0, 71, }, /* 77 */
- { 33, 5, 12, 0, 10783, }, /* 78 */
- { 33, 5, 12, 0, 10780, }, /* 79 */
- { 33, 5, 12, 0, 10782, }, /* 80 */
- { 33, 5, 12, 0, -210, }, /* 81 */
- { 33, 5, 12, 0, -206, }, /* 82 */
- { 33, 5, 12, 0, -205, }, /* 83 */
- { 33, 5, 12, 0, -202, }, /* 84 */
- { 33, 5, 12, 0, -203, }, /* 85 */
- { 33, 5, 12, 0, -207, }, /* 86 */
- { 33, 5, 12, 0, 42280, }, /* 87 */
- { 33, 5, 12, 0, 42308, }, /* 88 */
- { 33, 5, 12, 0, -209, }, /* 89 */
- { 33, 5, 12, 0, -211, }, /* 90 */
- { 33, 5, 12, 0, 10743, }, /* 91 */
- { 33, 5, 12, 0, 10749, }, /* 92 */
- { 33, 5, 12, 0, -213, }, /* 93 */
- { 33, 5, 12, 0, -214, }, /* 94 */
- { 33, 5, 12, 0, 10727, }, /* 95 */
- { 33, 5, 12, 0, -218, }, /* 96 */
- { 33, 5, 12, 0, -69, }, /* 97 */
- { 33, 5, 12, 0, -217, }, /* 98 */
- { 33, 5, 12, 0, -71, }, /* 99 */
- { 33, 5, 12, 0, -219, }, /* 100 */
- { 33, 6, 12, 0, 0, }, /* 101 */
- { 9, 6, 12, 0, 0, }, /* 102 */
- { 3, 24, 12, 0, 0, }, /* 103 */
- { 27, 12, 3, 0, 0, }, /* 104 */
- { 27, 12, 3, 21, 116, }, /* 105 */
- { 19, 9, 12, 0, 1, }, /* 106 */
- { 19, 5, 12, 0, -1, }, /* 107 */
- { 19, 24, 12, 0, 0, }, /* 108 */
- { 9, 2, 12, 0, 0, }, /* 109 */
- { 19, 6, 12, 0, 0, }, /* 110 */
- { 19, 5, 12, 0, 130, }, /* 111 */
- { 19, 9, 12, 0, 38, }, /* 112 */
- { 19, 9, 12, 0, 37, }, /* 113 */
- { 19, 9, 12, 0, 64, }, /* 114 */
- { 19, 9, 12, 0, 63, }, /* 115 */
- { 19, 5, 12, 0, 0, }, /* 116 */
- { 19, 9, 12, 0, 32, }, /* 117 */
- { 19, 9, 12, 34, 32, }, /* 118 */
- { 19, 9, 12, 59, 32, }, /* 119 */
- { 19, 9, 12, 38, 32, }, /* 120 */
- { 19, 9, 12, 21, 32, }, /* 121 */
- { 19, 9, 12, 51, 32, }, /* 122 */
- { 19, 9, 12, 26, 32, }, /* 123 */
- { 19, 9, 12, 47, 32, }, /* 124 */
- { 19, 9, 12, 55, 32, }, /* 125 */
- { 19, 9, 12, 30, 32, }, /* 126 */
- { 19, 9, 12, 43, 32, }, /* 127 */
- { 19, 9, 12, 67, 32, }, /* 128 */
- { 19, 5, 12, 0, -38, }, /* 129 */
- { 19, 5, 12, 0, -37, }, /* 130 */
- { 19, 5, 12, 0, -32, }, /* 131 */
- { 19, 5, 12, 34, -32, }, /* 132 */
- { 19, 5, 12, 59, -32, }, /* 133 */
- { 19, 5, 12, 38, -32, }, /* 134 */
- { 19, 5, 12, 21, -116, }, /* 135 */
- { 19, 5, 12, 51, -32, }, /* 136 */
- { 19, 5, 12, 26, -775, }, /* 137 */
- { 19, 5, 12, 47, -32, }, /* 138 */
- { 19, 5, 12, 55, -32, }, /* 139 */
- { 19, 5, 12, 30, 1, }, /* 140 */
- { 19, 5, 12, 30, -32, }, /* 141 */
- { 19, 5, 12, 43, -32, }, /* 142 */
- { 19, 5, 12, 67, -32, }, /* 143 */
- { 19, 5, 12, 0, -64, }, /* 144 */
- { 19, 5, 12, 0, -63, }, /* 145 */
- { 19, 9, 12, 0, 8, }, /* 146 */
- { 19, 5, 12, 34, -30, }, /* 147 */
- { 19, 5, 12, 38, -25, }, /* 148 */
- { 19, 9, 12, 0, 0, }, /* 149 */
- { 19, 5, 12, 43, -15, }, /* 150 */
- { 19, 5, 12, 47, -22, }, /* 151 */
- { 19, 5, 12, 0, -8, }, /* 152 */
- { 10, 9, 12, 0, 1, }, /* 153 */
- { 10, 5, 12, 0, -1, }, /* 154 */
- { 19, 5, 12, 51, -54, }, /* 155 */
- { 19, 5, 12, 55, -48, }, /* 156 */
- { 19, 5, 12, 0, 7, }, /* 157 */
- { 19, 9, 12, 38, -60, }, /* 158 */
- { 19, 5, 12, 59, -64, }, /* 159 */
- { 19, 25, 12, 0, 0, }, /* 160 */
- { 19, 9, 12, 0, -7, }, /* 161 */
- { 19, 9, 12, 0, -130, }, /* 162 */
- { 12, 9, 12, 0, 80, }, /* 163 */
- { 12, 9, 12, 0, 32, }, /* 164 */
- { 12, 5, 12, 0, -32, }, /* 165 */
- { 12, 5, 12, 0, -80, }, /* 166 */
- { 12, 9, 12, 0, 1, }, /* 167 */
- { 12, 5, 12, 0, -1, }, /* 168 */
- { 12, 26, 12, 0, 0, }, /* 169 */
- { 12, 12, 3, 0, 0, }, /* 170 */
- { 12, 11, 3, 0, 0, }, /* 171 */
- { 12, 9, 12, 0, 15, }, /* 172 */
- { 12, 5, 12, 0, -15, }, /* 173 */
- { 1, 9, 12, 0, 48, }, /* 174 */
- { 1, 6, 12, 0, 0, }, /* 175 */
- { 1, 21, 12, 0, 0, }, /* 176 */
- { 1, 5, 12, 0, -48, }, /* 177 */
- { 1, 5, 12, 0, 0, }, /* 178 */
- { 1, 17, 12, 0, 0, }, /* 179 */
- { 1, 23, 12, 0, 0, }, /* 180 */
- { 25, 12, 3, 0, 0, }, /* 181 */
- { 25, 17, 12, 0, 0, }, /* 182 */
- { 25, 21, 12, 0, 0, }, /* 183 */
- { 25, 7, 12, 0, 0, }, /* 184 */
- { 0, 1, 2, 0, 0, }, /* 185 */
- { 0, 25, 12, 0, 0, }, /* 186 */
- { 0, 21, 12, 0, 0, }, /* 187 */
- { 0, 23, 12, 0, 0, }, /* 188 */
- { 0, 26, 12, 0, 0, }, /* 189 */
- { 0, 12, 3, 0, 0, }, /* 190 */
- { 0, 7, 12, 0, 0, }, /* 191 */
- { 0, 6, 12, 0, 0, }, /* 192 */
- { 0, 13, 12, 0, 0, }, /* 193 */
- { 49, 21, 12, 0, 0, }, /* 194 */
- { 49, 1, 2, 0, 0, }, /* 195 */
- { 49, 7, 12, 0, 0, }, /* 196 */
- { 49, 12, 3, 0, 0, }, /* 197 */
- { 55, 7, 12, 0, 0, }, /* 198 */
- { 55, 12, 3, 0, 0, }, /* 199 */
- { 63, 13, 12, 0, 0, }, /* 200 */
- { 63, 7, 12, 0, 0, }, /* 201 */
- { 63, 12, 3, 0, 0, }, /* 202 */
- { 63, 6, 12, 0, 0, }, /* 203 */
- { 63, 26, 12, 0, 0, }, /* 204 */
- { 63, 21, 12, 0, 0, }, /* 205 */
- { 89, 7, 12, 0, 0, }, /* 206 */
- { 89, 12, 3, 0, 0, }, /* 207 */
- { 89, 6, 12, 0, 0, }, /* 208 */
- { 89, 21, 12, 0, 0, }, /* 209 */
- { 94, 7, 12, 0, 0, }, /* 210 */
- { 94, 12, 3, 0, 0, }, /* 211 */
- { 94, 21, 12, 0, 0, }, /* 212 */
- { 14, 12, 3, 0, 0, }, /* 213 */
- { 14, 10, 5, 0, 0, }, /* 214 */
- { 14, 7, 12, 0, 0, }, /* 215 */
- { 14, 13, 12, 0, 0, }, /* 216 */
- { 14, 21, 12, 0, 0, }, /* 217 */
- { 14, 6, 12, 0, 0, }, /* 218 */
- { 2, 12, 3, 0, 0, }, /* 219 */
- { 2, 10, 5, 0, 0, }, /* 220 */
- { 2, 7, 12, 0, 0, }, /* 221 */
- { 2, 10, 3, 0, 0, }, /* 222 */
- { 2, 13, 12, 0, 0, }, /* 223 */
- { 2, 23, 12, 0, 0, }, /* 224 */
- { 2, 15, 12, 0, 0, }, /* 225 */
- { 2, 26, 12, 0, 0, }, /* 226 */
- { 21, 12, 3, 0, 0, }, /* 227 */
- { 21, 10, 5, 0, 0, }, /* 228 */
- { 21, 7, 12, 0, 0, }, /* 229 */
- { 21, 13, 12, 0, 0, }, /* 230 */
- { 20, 12, 3, 0, 0, }, /* 231 */
- { 20, 10, 5, 0, 0, }, /* 232 */
- { 20, 7, 12, 0, 0, }, /* 233 */
- { 20, 13, 12, 0, 0, }, /* 234 */
- { 20, 21, 12, 0, 0, }, /* 235 */
- { 20, 23, 12, 0, 0, }, /* 236 */
- { 43, 12, 3, 0, 0, }, /* 237 */
- { 43, 10, 5, 0, 0, }, /* 238 */
- { 43, 7, 12, 0, 0, }, /* 239 */
- { 43, 10, 3, 0, 0, }, /* 240 */
- { 43, 13, 12, 0, 0, }, /* 241 */
- { 43, 26, 12, 0, 0, }, /* 242 */
- { 43, 15, 12, 0, 0, }, /* 243 */
- { 53, 12, 3, 0, 0, }, /* 244 */
- { 53, 7, 12, 0, 0, }, /* 245 */
- { 53, 10, 3, 0, 0, }, /* 246 */
- { 53, 10, 5, 0, 0, }, /* 247 */
- { 53, 13, 12, 0, 0, }, /* 248 */
- { 53, 15, 12, 0, 0, }, /* 249 */
- { 53, 26, 12, 0, 0, }, /* 250 */
- { 53, 23, 12, 0, 0, }, /* 251 */
- { 54, 10, 5, 0, 0, }, /* 252 */
- { 54, 7, 12, 0, 0, }, /* 253 */
- { 54, 12, 3, 0, 0, }, /* 254 */
- { 54, 13, 12, 0, 0, }, /* 255 */
- { 54, 15, 12, 0, 0, }, /* 256 */
- { 54, 26, 12, 0, 0, }, /* 257 */
- { 28, 10, 5, 0, 0, }, /* 258 */
- { 28, 7, 12, 0, 0, }, /* 259 */
- { 28, 12, 3, 0, 0, }, /* 260 */
- { 28, 10, 3, 0, 0, }, /* 261 */
- { 28, 13, 12, 0, 0, }, /* 262 */
- { 36, 10, 5, 0, 0, }, /* 263 */
- { 36, 7, 12, 0, 0, }, /* 264 */
- { 36, 10, 3, 0, 0, }, /* 265 */
- { 36, 12, 3, 0, 0, }, /* 266 */
- { 36, 13, 12, 0, 0, }, /* 267 */
- { 36, 15, 12, 0, 0, }, /* 268 */
- { 36, 26, 12, 0, 0, }, /* 269 */
- { 47, 10, 5, 0, 0, }, /* 270 */
- { 47, 7, 12, 0, 0, }, /* 271 */
- { 47, 12, 3, 0, 0, }, /* 272 */
- { 47, 10, 3, 0, 0, }, /* 273 */
- { 47, 21, 12, 0, 0, }, /* 274 */
- { 56, 7, 12, 0, 0, }, /* 275 */
- { 56, 12, 3, 0, 0, }, /* 276 */
- { 56, 7, 5, 0, 0, }, /* 277 */
- { 56, 6, 12, 0, 0, }, /* 278 */
- { 56, 21, 12, 0, 0, }, /* 279 */
- { 56, 13, 12, 0, 0, }, /* 280 */
- { 32, 7, 12, 0, 0, }, /* 281 */
- { 32, 12, 3, 0, 0, }, /* 282 */
- { 32, 7, 5, 0, 0, }, /* 283 */
- { 32, 6, 12, 0, 0, }, /* 284 */
- { 32, 13, 12, 0, 0, }, /* 285 */
- { 57, 7, 12, 0, 0, }, /* 286 */
- { 57, 26, 12, 0, 0, }, /* 287 */
- { 57, 21, 12, 0, 0, }, /* 288 */
- { 57, 12, 3, 0, 0, }, /* 289 */
- { 57, 13, 12, 0, 0, }, /* 290 */
- { 57, 15, 12, 0, 0, }, /* 291 */
- { 57, 22, 12, 0, 0, }, /* 292 */
- { 57, 18, 12, 0, 0, }, /* 293 */
- { 57, 10, 5, 0, 0, }, /* 294 */
- { 38, 7, 12, 0, 0, }, /* 295 */
- { 38, 10, 12, 0, 0, }, /* 296 */
- { 38, 12, 3, 0, 0, }, /* 297 */
- { 38, 10, 5, 0, 0, }, /* 298 */
- { 38, 13, 12, 0, 0, }, /* 299 */
- { 38, 21, 12, 0, 0, }, /* 300 */
- { 38, 26, 12, 0, 0, }, /* 301 */
- { 16, 9, 12, 0, 7264, }, /* 302 */
- { 16, 7, 12, 0, 0, }, /* 303 */
- { 16, 6, 12, 0, 0, }, /* 304 */
- { 23, 7, 6, 0, 0, }, /* 305 */
- { 23, 7, 7, 0, 0, }, /* 306 */
- { 23, 7, 8, 0, 0, }, /* 307 */
- { 15, 7, 12, 0, 0, }, /* 308 */
- { 15, 12, 3, 0, 0, }, /* 309 */
- { 15, 21, 12, 0, 0, }, /* 310 */
- { 15, 15, 12, 0, 0, }, /* 311 */
- { 15, 26, 12, 0, 0, }, /* 312 */
- { 8, 7, 12, 0, 0, }, /* 313 */
- { 7, 17, 12, 0, 0, }, /* 314 */
- { 7, 7, 12, 0, 0, }, /* 315 */
- { 7, 21, 12, 0, 0, }, /* 316 */
- { 40, 29, 12, 0, 0, }, /* 317 */
- { 40, 7, 12, 0, 0, }, /* 318 */
- { 40, 22, 12, 0, 0, }, /* 319 */
- { 40, 18, 12, 0, 0, }, /* 320 */
- { 45, 7, 12, 0, 0, }, /* 321 */
- { 45, 14, 12, 0, 0, }, /* 322 */
- { 50, 7, 12, 0, 0, }, /* 323 */
- { 50, 12, 3, 0, 0, }, /* 324 */
- { 24, 7, 12, 0, 0, }, /* 325 */
- { 24, 12, 3, 0, 0, }, /* 326 */
- { 6, 7, 12, 0, 0, }, /* 327 */
- { 6, 12, 3, 0, 0, }, /* 328 */
- { 51, 7, 12, 0, 0, }, /* 329 */
- { 51, 12, 3, 0, 0, }, /* 330 */
- { 31, 7, 12, 0, 0, }, /* 331 */
- { 31, 12, 3, 0, 0, }, /* 332 */
- { 31, 10, 5, 0, 0, }, /* 333 */
- { 31, 21, 12, 0, 0, }, /* 334 */
- { 31, 6, 12, 0, 0, }, /* 335 */
- { 31, 23, 12, 0, 0, }, /* 336 */
- { 31, 13, 12, 0, 0, }, /* 337 */
- { 31, 15, 12, 0, 0, }, /* 338 */
- { 37, 21, 12, 0, 0, }, /* 339 */
- { 37, 17, 12, 0, 0, }, /* 340 */
- { 37, 12, 3, 0, 0, }, /* 341 */
- { 37, 29, 12, 0, 0, }, /* 342 */
- { 37, 13, 12, 0, 0, }, /* 343 */
- { 37, 7, 12, 0, 0, }, /* 344 */
- { 37, 6, 12, 0, 0, }, /* 345 */
- { 34, 7, 12, 0, 0, }, /* 346 */
- { 34, 12, 3, 0, 0, }, /* 347 */
- { 34, 10, 5, 0, 0, }, /* 348 */
- { 34, 26, 12, 0, 0, }, /* 349 */
- { 34, 21, 12, 0, 0, }, /* 350 */
- { 34, 13, 12, 0, 0, }, /* 351 */
- { 52, 7, 12, 0, 0, }, /* 352 */
- { 39, 7, 12, 0, 0, }, /* 353 */
- { 39, 10, 12, 0, 0, }, /* 354 */
- { 39, 10, 5, 0, 0, }, /* 355 */
- { 39, 13, 12, 0, 0, }, /* 356 */
- { 39, 15, 12, 0, 0, }, /* 357 */
- { 39, 26, 12, 0, 0, }, /* 358 */
- { 31, 26, 12, 0, 0, }, /* 359 */
- { 5, 7, 12, 0, 0, }, /* 360 */
- { 5, 12, 3, 0, 0, }, /* 361 */
- { 5, 10, 5, 0, 0, }, /* 362 */
- { 5, 21, 12, 0, 0, }, /* 363 */
- { 90, 7, 12, 0, 0, }, /* 364 */
- { 90, 10, 5, 0, 0, }, /* 365 */
- { 90, 12, 3, 0, 0, }, /* 366 */
- { 90, 10, 12, 0, 0, }, /* 367 */
- { 90, 13, 12, 0, 0, }, /* 368 */
- { 90, 21, 12, 0, 0, }, /* 369 */
- { 90, 6, 12, 0, 0, }, /* 370 */
- { 61, 12, 3, 0, 0, }, /* 371 */
- { 61, 10, 5, 0, 0, }, /* 372 */
- { 61, 7, 12, 0, 0, }, /* 373 */
- { 61, 13, 12, 0, 0, }, /* 374 */
- { 61, 21, 12, 0, 0, }, /* 375 */
- { 61, 26, 12, 0, 0, }, /* 376 */
- { 75, 12, 3, 0, 0, }, /* 377 */
- { 75, 10, 5, 0, 0, }, /* 378 */
- { 75, 7, 12, 0, 0, }, /* 379 */
- { 75, 13, 12, 0, 0, }, /* 380 */
- { 92, 7, 12, 0, 0, }, /* 381 */
- { 92, 12, 3, 0, 0, }, /* 382 */
- { 92, 10, 5, 0, 0, }, /* 383 */
- { 92, 21, 12, 0, 0, }, /* 384 */
- { 69, 7, 12, 0, 0, }, /* 385 */
- { 69, 10, 5, 0, 0, }, /* 386 */
- { 69, 12, 3, 0, 0, }, /* 387 */
- { 69, 21, 12, 0, 0, }, /* 388 */
- { 69, 13, 12, 0, 0, }, /* 389 */
- { 72, 13, 12, 0, 0, }, /* 390 */
- { 72, 7, 12, 0, 0, }, /* 391 */
- { 72, 6, 12, 0, 0, }, /* 392 */
- { 72, 21, 12, 0, 0, }, /* 393 */
- { 75, 21, 12, 0, 0, }, /* 394 */
- { 9, 10, 5, 0, 0, }, /* 395 */
- { 9, 7, 12, 0, 0, }, /* 396 */
- { 12, 5, 12, 0, 0, }, /* 397 */
- { 12, 6, 12, 0, 0, }, /* 398 */
- { 33, 5, 12, 0, 35332, }, /* 399 */
- { 33, 5, 12, 0, 3814, }, /* 400 */
- { 33, 9, 12, 63, 1, }, /* 401 */
- { 33, 5, 12, 63, -1, }, /* 402 */
- { 33, 5, 12, 63, -58, }, /* 403 */
- { 33, 9, 12, 0, -7615, }, /* 404 */
- { 19, 5, 12, 0, 8, }, /* 405 */
- { 19, 9, 12, 0, -8, }, /* 406 */
- { 19, 5, 12, 0, 74, }, /* 407 */
- { 19, 5, 12, 0, 86, }, /* 408 */
- { 19, 5, 12, 0, 100, }, /* 409 */
- { 19, 5, 12, 0, 128, }, /* 410 */
- { 19, 5, 12, 0, 112, }, /* 411 */
- { 19, 5, 12, 0, 126, }, /* 412 */
- { 19, 8, 12, 0, -8, }, /* 413 */
- { 19, 5, 12, 0, 9, }, /* 414 */
- { 19, 9, 12, 0, -74, }, /* 415 */
- { 19, 8, 12, 0, -9, }, /* 416 */
- { 19, 5, 12, 21, -7173, }, /* 417 */
- { 19, 9, 12, 0, -86, }, /* 418 */
- { 19, 9, 12, 0, -100, }, /* 419 */
- { 19, 9, 12, 0, -112, }, /* 420 */
- { 19, 9, 12, 0, -128, }, /* 421 */
- { 19, 9, 12, 0, -126, }, /* 422 */
- { 27, 1, 3, 0, 0, }, /* 423 */
- { 9, 27, 2, 0, 0, }, /* 424 */
- { 9, 28, 2, 0, 0, }, /* 425 */
- { 9, 2, 2, 0, 0, }, /* 426 */
- { 27, 11, 3, 0, 0, }, /* 427 */
- { 9, 9, 12, 0, 0, }, /* 428 */
- { 9, 5, 12, 0, 0, }, /* 429 */
- { 19, 9, 12, 67, -7517, }, /* 430 */
- { 33, 9, 12, 71, -8383, }, /* 431 */
- { 33, 9, 12, 75, -8262, }, /* 432 */
- { 33, 9, 12, 0, 28, }, /* 433 */
- { 33, 5, 12, 0, -28, }, /* 434 */
- { 33, 14, 12, 0, 16, }, /* 435 */
- { 33, 14, 12, 0, -16, }, /* 436 */
- { 33, 14, 12, 0, 0, }, /* 437 */
- { 9, 26, 12, 0, 26, }, /* 438 */
- { 9, 26, 12, 0, -26, }, /* 439 */
- { 4, 26, 12, 0, 0, }, /* 440 */
- { 17, 9, 12, 0, 48, }, /* 441 */
- { 17, 5, 12, 0, -48, }, /* 442 */
- { 33, 9, 12, 0, -10743, }, /* 443 */
- { 33, 9, 12, 0, -3814, }, /* 444 */
- { 33, 9, 12, 0, -10727, }, /* 445 */
- { 33, 5, 12, 0, -10795, }, /* 446 */
- { 33, 5, 12, 0, -10792, }, /* 447 */
- { 33, 9, 12, 0, -10780, }, /* 448 */
- { 33, 9, 12, 0, -10749, }, /* 449 */
- { 33, 9, 12, 0, -10783, }, /* 450 */
- { 33, 9, 12, 0, -10782, }, /* 451 */
- { 33, 9, 12, 0, -10815, }, /* 452 */
- { 10, 5, 12, 0, 0, }, /* 453 */
- { 10, 26, 12, 0, 0, }, /* 454 */
- { 10, 12, 3, 0, 0, }, /* 455 */
- { 10, 21, 12, 0, 0, }, /* 456 */
- { 10, 15, 12, 0, 0, }, /* 457 */
- { 16, 5, 12, 0, -7264, }, /* 458 */
- { 58, 7, 12, 0, 0, }, /* 459 */
- { 58, 6, 12, 0, 0, }, /* 460 */
- { 58, 21, 12, 0, 0, }, /* 461 */
- { 58, 12, 3, 0, 0, }, /* 462 */
- { 22, 26, 12, 0, 0, }, /* 463 */
- { 22, 6, 12, 0, 0, }, /* 464 */
- { 22, 14, 12, 0, 0, }, /* 465 */
- { 23, 10, 3, 0, 0, }, /* 466 */
- { 26, 7, 12, 0, 0, }, /* 467 */
- { 26, 6, 12, 0, 0, }, /* 468 */
- { 29, 7, 12, 0, 0, }, /* 469 */
- { 29, 6, 12, 0, 0, }, /* 470 */
- { 3, 7, 12, 0, 0, }, /* 471 */
- { 23, 7, 12, 0, 0, }, /* 472 */
- { 23, 26, 12, 0, 0, }, /* 473 */
- { 29, 26, 12, 0, 0, }, /* 474 */
- { 22, 7, 12, 0, 0, }, /* 475 */
- { 60, 7, 12, 0, 0, }, /* 476 */
- { 60, 6, 12, 0, 0, }, /* 477 */
- { 60, 26, 12, 0, 0, }, /* 478 */
- { 85, 7, 12, 0, 0, }, /* 479 */
- { 85, 6, 12, 0, 0, }, /* 480 */
- { 85, 21, 12, 0, 0, }, /* 481 */
- { 76, 7, 12, 0, 0, }, /* 482 */
- { 76, 6, 12, 0, 0, }, /* 483 */
- { 76, 21, 12, 0, 0, }, /* 484 */
- { 76, 13, 12, 0, 0, }, /* 485 */
- { 12, 7, 12, 0, 0, }, /* 486 */
- { 12, 21, 12, 0, 0, }, /* 487 */
- { 78, 7, 12, 0, 0, }, /* 488 */
- { 78, 14, 12, 0, 0, }, /* 489 */
- { 78, 12, 3, 0, 0, }, /* 490 */
- { 78, 21, 12, 0, 0, }, /* 491 */
- { 33, 9, 12, 0, -35332, }, /* 492 */
- { 33, 9, 12, 0, -42280, }, /* 493 */
- { 33, 9, 12, 0, -42308, }, /* 494 */
- { 48, 7, 12, 0, 0, }, /* 495 */
- { 48, 12, 3, 0, 0, }, /* 496 */
- { 48, 10, 5, 0, 0, }, /* 497 */
- { 48, 26, 12, 0, 0, }, /* 498 */
- { 64, 7, 12, 0, 0, }, /* 499 */
- { 64, 21, 12, 0, 0, }, /* 500 */
- { 74, 10, 5, 0, 0, }, /* 501 */
- { 74, 7, 12, 0, 0, }, /* 502 */
- { 74, 12, 3, 0, 0, }, /* 503 */
- { 74, 21, 12, 0, 0, }, /* 504 */
- { 74, 13, 12, 0, 0, }, /* 505 */
- { 68, 13, 12, 0, 0, }, /* 506 */
- { 68, 7, 12, 0, 0, }, /* 507 */
- { 68, 12, 3, 0, 0, }, /* 508 */
- { 68, 21, 12, 0, 0, }, /* 509 */
- { 73, 7, 12, 0, 0, }, /* 510 */
- { 73, 12, 3, 0, 0, }, /* 511 */
- { 73, 10, 5, 0, 0, }, /* 512 */
- { 73, 21, 12, 0, 0, }, /* 513 */
- { 83, 12, 3, 0, 0, }, /* 514 */
- { 83, 10, 5, 0, 0, }, /* 515 */
- { 83, 7, 12, 0, 0, }, /* 516 */
- { 83, 21, 12, 0, 0, }, /* 517 */
- { 83, 6, 12, 0, 0, }, /* 518 */
- { 83, 13, 12, 0, 0, }, /* 519 */
- { 67, 7, 12, 0, 0, }, /* 520 */
- { 67, 12, 3, 0, 0, }, /* 521 */
- { 67, 10, 5, 0, 0, }, /* 522 */
- { 67, 13, 12, 0, 0, }, /* 523 */
- { 67, 21, 12, 0, 0, }, /* 524 */
- { 38, 6, 12, 0, 0, }, /* 525 */
- { 91, 7, 12, 0, 0, }, /* 526 */
- { 91, 12, 3, 0, 0, }, /* 527 */
- { 91, 6, 12, 0, 0, }, /* 528 */
- { 91, 21, 12, 0, 0, }, /* 529 */
- { 86, 7, 12, 0, 0, }, /* 530 */
- { 86, 10, 5, 0, 0, }, /* 531 */
- { 86, 12, 3, 0, 0, }, /* 532 */
- { 86, 21, 12, 0, 0, }, /* 533 */
- { 86, 6, 12, 0, 0, }, /* 534 */
- { 86, 13, 12, 0, 0, }, /* 535 */
- { 23, 7, 9, 0, 0, }, /* 536 */
- { 23, 7, 10, 0, 0, }, /* 537 */
- { 9, 4, 2, 0, 0, }, /* 538 */
- { 9, 3, 12, 0, 0, }, /* 539 */
- { 25, 25, 12, 0, 0, }, /* 540 */
- { 0, 24, 12, 0, 0, }, /* 541 */
- { 9, 6, 3, 0, 0, }, /* 542 */
- { 35, 7, 12, 0, 0, }, /* 543 */
- { 19, 14, 12, 0, 0, }, /* 544 */
- { 19, 15, 12, 0, 0, }, /* 545 */
- { 19, 26, 12, 0, 0, }, /* 546 */
- { 70, 7, 12, 0, 0, }, /* 547 */
- { 66, 7, 12, 0, 0, }, /* 548 */
- { 41, 7, 12, 0, 0, }, /* 549 */
- { 41, 15, 12, 0, 0, }, /* 550 */
- { 18, 7, 12, 0, 0, }, /* 551 */
- { 18, 14, 12, 0, 0, }, /* 552 */
- { 59, 7, 12, 0, 0, }, /* 553 */
- { 59, 21, 12, 0, 0, }, /* 554 */
- { 42, 7, 12, 0, 0, }, /* 555 */
- { 42, 21, 12, 0, 0, }, /* 556 */
- { 42, 14, 12, 0, 0, }, /* 557 */
- { 13, 9, 12, 0, 40, }, /* 558 */
- { 13, 5, 12, 0, -40, }, /* 559 */
- { 46, 7, 12, 0, 0, }, /* 560 */
- { 44, 7, 12, 0, 0, }, /* 561 */
- { 44, 13, 12, 0, 0, }, /* 562 */
- { 11, 7, 12, 0, 0, }, /* 563 */
- { 80, 7, 12, 0, 0, }, /* 564 */
- { 80, 21, 12, 0, 0, }, /* 565 */
- { 80, 15, 12, 0, 0, }, /* 566 */
- { 65, 7, 12, 0, 0, }, /* 567 */
- { 65, 15, 12, 0, 0, }, /* 568 */
- { 65, 21, 12, 0, 0, }, /* 569 */
- { 71, 7, 12, 0, 0, }, /* 570 */
- { 71, 21, 12, 0, 0, }, /* 571 */
- { 97, 7, 12, 0, 0, }, /* 572 */
- { 96, 7, 12, 0, 0, }, /* 573 */
- { 30, 7, 12, 0, 0, }, /* 574 */
- { 30, 12, 3, 0, 0, }, /* 575 */
- { 30, 15, 12, 0, 0, }, /* 576 */
- { 30, 21, 12, 0, 0, }, /* 577 */
- { 87, 7, 12, 0, 0, }, /* 578 */
- { 87, 15, 12, 0, 0, }, /* 579 */
- { 87, 21, 12, 0, 0, }, /* 580 */
- { 77, 7, 12, 0, 0, }, /* 581 */
- { 77, 21, 12, 0, 0, }, /* 582 */
- { 82, 7, 12, 0, 0, }, /* 583 */
- { 82, 15, 12, 0, 0, }, /* 584 */
- { 81, 7, 12, 0, 0, }, /* 585 */
- { 81, 15, 12, 0, 0, }, /* 586 */
- { 88, 7, 12, 0, 0, }, /* 587 */
- { 0, 15, 12, 0, 0, }, /* 588 */
- { 93, 10, 5, 0, 0, }, /* 589 */
- { 93, 12, 3, 0, 0, }, /* 590 */
- { 93, 7, 12, 0, 0, }, /* 591 */
- { 93, 21, 12, 0, 0, }, /* 592 */
- { 93, 15, 12, 0, 0, }, /* 593 */
- { 93, 13, 12, 0, 0, }, /* 594 */
- { 84, 12, 3, 0, 0, }, /* 595 */
- { 84, 10, 5, 0, 0, }, /* 596 */
- { 84, 7, 12, 0, 0, }, /* 597 */
- { 84, 21, 12, 0, 0, }, /* 598 */
- { 84, 1, 2, 0, 0, }, /* 599 */
- { 100, 7, 12, 0, 0, }, /* 600 */
- { 100, 13, 12, 0, 0, }, /* 601 */
- { 95, 12, 3, 0, 0, }, /* 602 */
- { 95, 7, 12, 0, 0, }, /* 603 */
- { 95, 10, 5, 0, 0, }, /* 604 */
- { 95, 13, 12, 0, 0, }, /* 605 */
- { 95, 21, 12, 0, 0, }, /* 606 */
- { 99, 12, 3, 0, 0, }, /* 607 */
- { 99, 10, 5, 0, 0, }, /* 608 */
- { 99, 7, 12, 0, 0, }, /* 609 */
- { 99, 21, 12, 0, 0, }, /* 610 */
- { 99, 13, 12, 0, 0, }, /* 611 */
- { 101, 7, 12, 0, 0, }, /* 612 */
- { 101, 12, 3, 0, 0, }, /* 613 */
- { 101, 10, 5, 0, 0, }, /* 614 */
- { 101, 13, 12, 0, 0, }, /* 615 */
- { 62, 7, 12, 0, 0, }, /* 616 */
- { 62, 14, 12, 0, 0, }, /* 617 */
- { 62, 21, 12, 0, 0, }, /* 618 */
- { 79, 7, 12, 0, 0, }, /* 619 */
- { 98, 7, 12, 0, 0, }, /* 620 */
- { 98, 10, 5, 0, 0, }, /* 621 */
- { 98, 12, 3, 0, 0, }, /* 622 */
- { 98, 6, 12, 0, 0, }, /* 623 */
- { 9, 10, 3, 0, 0, }, /* 624 */
- { 19, 12, 3, 0, 0, }, /* 625 */
- { 9, 26, 11, 0, 0, }, /* 626 */
- { 26, 26, 12, 0, 0, }, /* 627 */
-};
-
-const pcre_uint8 PRIV(ucd_stage1)[] = { /* 8704 bytes */
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* U+0000 */
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* U+0800 */
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 41, 41, 42, 43, 44, 45, /* U+1000 */
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, /* U+1800 */
- 62, 63, 64, 65, 66, 66, 67, 68, 69, 70, 71, 72, 73, 71, 74, 75, /* U+2000 */
- 76, 76, 66, 77, 66, 66, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, /* U+2800 */
- 88, 89, 90, 91, 92, 93, 94, 71, 95, 95, 95, 95, 95, 95, 95, 95, /* U+3000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+3800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+4000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 96, 95, 95, 95, 95, /* U+4800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+5000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+5800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+6000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+6800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+7000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+7800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+8000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+8800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+9000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 97, /* U+9800 */
- 98, 99, 99, 99, 99, 99, 99, 99, 99,100,101,101,102,103,104,105, /* U+A000 */
-106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,114, /* U+A800 */
-115,116,117,118,119,120,114,115,116,117,118,119,120,114,115,116, /* U+B000 */
-117,118,119,120,114,115,116,117,118,119,120,114,115,116,117,118, /* U+B800 */
-119,120,114,115,116,117,118,119,120,114,115,116,117,118,119,120, /* U+C000 */
-114,115,116,117,118,119,120,114,115,116,117,118,119,120,114,115, /* U+C800 */
-116,117,118,119,120,114,115,116,117,118,119,120,114,115,116,121, /* U+D000 */
-122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122, /* U+D800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+E000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+E800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F000 */
-123,123, 95, 95,124,125,126,127,128,128,129,130,131,132,133,134, /* U+F800 */
-135,136,137,138, 79,139,140,141,142,143, 79, 79, 79, 79, 79, 79, /* U+10000 */
-144, 79,145,146,147, 79,148, 79,149, 79, 79, 79,150, 79, 79, 79, /* U+10800 */
-151,152,153,154, 79, 79, 79, 79, 79, 79, 79, 79, 79,155, 79, 79, /* U+11000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+11800 */
-156,156,156,156,156,156,157, 79,158, 79, 79, 79, 79, 79, 79, 79, /* U+12000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+12800 */
-159,159,159,159,159,159,159,159,160, 79, 79, 79, 79, 79, 79, 79, /* U+13000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+13800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+14000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+14800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+15000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+15800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+16000 */
-161,161,161,161,162, 79, 79, 79, 79, 79, 79, 79, 79, 79,163,164, /* U+16800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+17000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+17800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+18000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+18800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+19000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+19800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+1A000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+1A800 */
-165, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+1B000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+1B800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+1C000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+1C800 */
- 71,166,167,168,169, 79,170, 79,171,172,173,174,175,176,177,178, /* U+1D000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+1D800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+1E000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,179,180, 79, 79, /* U+1E800 */
-181,182,183,184,185, 79,186,187,188,189,190,191,192,193,194, 79, /* U+1F000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+1F800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+20000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+20800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+21000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+21800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+22000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+22800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+23000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+23800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+24000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+24800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+25000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+25800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+26000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+26800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+27000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+27800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+28000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+28800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+29000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+29800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,195, 95, 95, /* U+2A000 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, /* U+2A800 */
- 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,196, 95, /* U+2B000 */
-197, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+2B800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+2C000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+2C800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+2D000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+2D800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+2E000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+2E800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+2F000 */
- 95, 95, 95, 95,197, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+2F800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+30000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+30800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+31000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+31800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+32000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+32800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+33000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+33800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+34000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+34800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+35000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+35800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+36000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+36800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+37000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+37800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+38000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+38800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+39000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+39800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+3A000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+3A800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+3B000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+3B800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+3C000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+3C800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+3D000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+3D800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+3E000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+3E800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+3F000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+3F800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+40000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+40800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+41000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+41800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+42000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+42800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+43000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+43800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+44000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+44800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+45000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+45800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+46000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+46800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+47000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+47800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+48000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+48800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+49000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+49800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+4A000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+4A800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+4B000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+4B800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+4C000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+4C800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+4D000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+4D800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+4E000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+4E800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+4F000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+4F800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+50000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+50800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+51000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+51800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+52000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+52800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+53000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+53800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+54000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+54800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+55000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+55800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+56000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+56800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+57000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+57800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+58000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+58800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+59000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+59800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+5A000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+5A800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+5B000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+5B800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+5C000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+5C800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+5D000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+5D800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+5E000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+5E800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+5F000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+5F800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+60000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+60800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+61000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+61800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+62000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+62800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+63000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+63800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+64000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+64800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+65000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+65800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+66000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+66800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+67000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+67800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+68000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+68800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+69000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+69800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+6A000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+6A800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+6B000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+6B800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+6C000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+6C800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+6D000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+6D800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+6E000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+6E800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+6F000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+6F800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+70000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+70800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+71000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+71800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+72000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+72800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+73000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+73800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+74000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+74800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+75000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+75800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+76000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+76800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+77000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+77800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+78000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+78800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+79000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+79800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+7A000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+7A800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+7B000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+7B800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+7C000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+7C800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+7D000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+7D800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+7E000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+7E800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+7F000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+7F800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+80000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+80800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+81000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+81800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+82000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+82800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+83000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+83800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+84000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+84800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+85000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+85800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+86000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+86800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+87000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+87800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+88000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+88800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+89000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+89800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+8A000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+8A800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+8B000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+8B800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+8C000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+8C800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+8D000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+8D800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+8E000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+8E800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+8F000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+8F800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+90000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+90800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+91000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+91800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+92000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+92800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+93000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+93800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+94000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+94800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+95000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+95800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+96000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+96800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+97000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+97800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+98000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+98800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+99000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+99800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+9A000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+9A800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+9B000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+9B800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+9C000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+9C800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+9D000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+9D800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+9E000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+9E800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+9F000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+9F800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A0000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A0800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A1000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A1800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A2000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A2800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A3000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A3800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A4000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A4800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A5000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A5800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A6000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A6800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A7000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A7800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A8000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A8800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A9000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+A9800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+AA000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+AA800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+AB000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+AB800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+AC000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+AC800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+AD000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+AD800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+AE000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+AE800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+AF000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+AF800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B0000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B0800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B1000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B1800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B2000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B2800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B3000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B3800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B4000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B4800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B5000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B5800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B6000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B6800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B7000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B7800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B8000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B8800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B9000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+B9800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+BA000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+BA800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+BB000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+BB800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+BC000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+BC800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+BD000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+BD800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+BE000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+BE800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+BF000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+BF800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C0000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C0800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C1000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C1800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C2000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C2800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C3000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C3800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C4000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C4800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C5000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C5800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C6000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C6800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C7000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C7800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C8000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C8800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C9000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+C9800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+CA000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+CA800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+CB000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+CB800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+CC000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+CC800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+CD000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+CD800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+CE000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+CE800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+CF000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+CF800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D0000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D0800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D1000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D1800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D2000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D2800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D3000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D3800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D4000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D4800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D5000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D5800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D6000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D6800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D7000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D7800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D8000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D8800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D9000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+D9800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+DA000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+DA800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+DB000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+DB800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+DC000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+DC800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+DD000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+DD800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+DE000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+DE800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+DF000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+DF800 */
-198,199,200,201,199,199,199,199,199,199,199,199,199,199,199,199, /* U+E0000 */
-199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199, /* U+E0800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E1000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E1800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E2000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E2800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E3000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E3800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E4000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E4800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E5000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E5800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E6000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E6800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E7000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E7800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E8000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E8800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E9000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+E9800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+EA000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+EA800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+EB000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+EB800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+EC000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+EC800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+ED000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+ED800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+EE000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+EE800 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+EF000 */
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, /* U+EF800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F0000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F0800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F1000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F1800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F2000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F2800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F3000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F3800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F4000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F4800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F5000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F5800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F6000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F6800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F7000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F7800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F8000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F8800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F9000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+F9800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FA000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FA800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FB000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FB800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FC000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FC800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FD000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FD800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FE000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FE800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+FF000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,202, /* U+FF800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+100000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+100800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+101000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+101800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+102000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+102800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+103000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+103800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+104000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+104800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+105000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+105800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+106000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+106800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+107000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+107800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+108000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+108800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+109000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+109800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10A000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10A800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10B000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10B800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10C000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10C800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10D000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10D800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10E000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10E800 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123, /* U+10F000 */
-123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,202, /* U+10F800 */
-};
-
-const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
-/* block 0 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 3, 4, 4, 4, 5, 4, 4, 4, 6, 7, 4, 8, 4, 9, 4, 4,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 4, 8, 8, 8, 4,
- 4, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 11, 11, 11, 11,
- 11, 11, 11, 13, 11, 11, 11, 11, 11, 11, 11, 6, 4, 7, 14, 15,
- 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 16, 16, 16, 16,
- 16, 16, 16, 18, 16, 16, 16, 16, 16, 16, 16, 6, 8, 7, 8, 0,
-
-/* block 1 */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 3, 4, 5, 5, 5, 5, 19, 4, 14, 19, 20, 21, 8, 22, 19, 14,
- 19, 8, 23, 23, 14, 24, 4, 4, 14, 23, 20, 25, 23, 23, 23, 4,
- 11, 11, 11, 11, 11, 26, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 8, 11, 11, 11, 11, 11, 11, 11, 27,
- 16, 16, 16, 16, 16, 28, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 8, 16, 16, 16, 16, 16, 16, 16, 29,
-
-/* block 2 */
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 32, 33, 30, 31, 30, 31, 30, 31, 33, 30, 31, 30, 31, 30, 31, 30,
- 31, 30, 31, 30, 31, 30, 31, 30, 31, 33, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 34, 30, 31, 30, 31, 30, 31, 35,
-
-/* block 3 */
- 36, 37, 30, 31, 30, 31, 38, 30, 31, 39, 39, 30, 31, 33, 40, 41,
- 42, 30, 31, 39, 43, 44, 45, 46, 30, 31, 47, 33, 45, 48, 49, 50,
- 30, 31, 30, 31, 30, 31, 51, 30, 31, 51, 33, 33, 30, 31, 51, 30,
- 31, 52, 52, 30, 31, 30, 31, 53, 30, 31, 33, 20, 30, 31, 33, 54,
- 20, 20, 20, 20, 55, 56, 57, 58, 59, 60, 61, 62, 63, 30, 31, 30,
- 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 64, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 33, 65, 66, 67, 30, 31, 68, 69, 30, 31, 30, 31, 30, 31, 30, 31,
-
-/* block 4 */
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 70, 33, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 33, 33, 33, 33, 33, 33, 71, 30, 31, 72, 73, 74,
- 74, 30, 31, 75, 76, 77, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 78, 79, 80, 81, 82, 33, 83, 83, 33, 84, 33, 85, 33, 33, 33, 33,
- 83, 33, 33, 86, 33, 87, 88, 33, 89, 90, 33, 91, 33, 33, 33, 90,
- 33, 92, 93, 33, 33, 94, 33, 33, 33, 33, 33, 33, 33, 95, 33, 33,
-
-/* block 5 */
- 96, 33, 33, 96, 33, 33, 33, 33, 96, 97, 98, 98, 99, 33, 33, 33,
- 33, 33,100, 33, 20, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
-101,101,101,101,101,101,101,101,101,102,102,102,102,102,102,102,
-102,102, 14, 14, 14, 14,102,102,102,102,102,102,102,102,102,102,
-102,102, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-101,101,101,101,101, 14, 14, 14, 14, 14,103,103,102, 14,102, 14,
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-
-/* block 6 */
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,105,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-106,107,106,107,102,108,106,107,109,109,110,111,111,111, 4,109,
-
-/* block 7 */
-109,109,109,109,108, 14,112, 4,113,113,113,109,114,109,115,115,
-116,117,118,117,117,119,117,117,120,121,122,117,123,117,117,117,
-124,125,109,126,117,117,127,117,117,128,117,117,129,130,130,130,
-116,131,132,131,131,133,131,131,134,135,136,131,137,131,131,131,
-138,139,140,141,131,131,142,131,131,143,131,131,144,145,145,146,
-147,148,149,149,149,150,151,152,106,107,106,107,106,107,106,107,
-106,107,153,154,153,154,153,154,153,154,153,154,153,154,153,154,
-155,156,157,116,158,159,160,106,107,161,106,107,116,162,162,162,
-
-/* block 8 */
-163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
-164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
-164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
-165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
-165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
-166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,167,168,
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,167,168,
-
-/* block 9 */
-167,168,169,170,170,104,104,170,171,171,167,168,167,168,167,168,
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,167,168,
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,167,168,
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,167,168,
-172,167,168,167,168,167,168,167,168,167,168,167,168,167,168,173,
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,167,168,
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,167,168,
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,167,168,
-
-/* block 10 */
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,167,168,
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,167,168,
-167,168,167,168,167,168,167,168,109,109,109,109,109,109,109,109,
-109,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
-174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
-174,174,174,174,174,174,174,109,109,175,176,176,176,176,176,176,
-109,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
-
-/* block 11 */
-177,177,177,177,177,177,177,178,109, 4,179,109,109,109,109,180,
-109,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
-181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
-181,181,181,181,181,181,181,181,181,181,181,181,181,181,182,181,
-183,181,181,183,181,181,183,181,109,109,109,109,109,109,109,109,
-184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
-184,184,184,184,184,184,184,184,184,184,184,109,109,109,109,109,
-184,184,184,183,183,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 12 */
-185,185,185,185,185,109,186,186,186,187,187,188, 4,187,189,189,
-190,190,190,190,190,190,190,190,190,190,190, 4,109,109,187, 4,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-102,191,191,191,191,191,191,191,191,191,191,104,104,104,104,104,
-104,104,104,104,104,104,190,190,190,190,190,190,190,190,190,190,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,187,187,187,187,191,191,
-104,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-
-/* block 13 */
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,187,191,190,190,190,190,190,190,190, 22,189,190,
-190,190,190,190,190,192,192,190,190,189,190,190,190,190,191,191,
-193,193,193,193,193,193,193,193,193,193,191,191,191,189,189,191,
-
-/* block 14 */
-194,194,194,194,194,194,194,194,194,194,194,194,194,194,109,195,
-196,197,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
-196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
-197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
-197,197,197,197,197,197,197,197,197,197,197,109,109,196,196,196,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-
-/* block 15 */
-198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
-198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
-198,198,198,198,198,198,199,199,199,199,199,199,199,199,199,199,
-199,198,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-200,200,200,200,200,200,200,200,200,200,201,201,201,201,201,201,
-201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
-201,201,201,201,201,201,201,201,201,201,201,202,202,202,202,202,
-202,202,202,202,203,203,204,205,205,205,203,109,109,109,109,109,
-
-/* block 16 */
-206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
-206,206,206,206,206,206,207,207,207,207,208,207,207,207,207,207,
-207,207,207,207,208,207,207,207,208,207,207,207,207,207,109,109,
-209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,109,
-210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
-210,210,210,210,210,210,210,210,210,211,211,211,109,109,212,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 17 */
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-191,109,191,191,191,191,191,191,191,191,191,191,191,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,190,190,190,190,190,190,190,190,190,190,190,190,
-190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,109,
-
-/* block 18 */
-213,213,213,214,215,215,215,215,215,215,215,215,215,215,215,215,
-215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
-215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
-215,215,215,215,215,215,215,215,215,215,213,214,213,215,214,214,
-214,213,213,213,213,213,213,213,213,214,214,214,214,213,214,214,
-215,104,104,213,213,213,213,213,215,215,215,215,215,215,215,215,
-215,215,213,213, 4, 4,216,216,216,216,216,216,216,216,216,216,
-217,218,215,215,215,215,215,215,109,215,215,215,215,215,215,215,
-
-/* block 19 */
-109,219,220,220,109,221,221,221,221,221,221,221,221,109,109,221,
-221,109,109,221,221,221,221,221,221,221,221,221,221,221,221,221,
-221,221,221,221,221,221,221,221,221,109,221,221,221,221,221,221,
-221,109,221,109,109,109,221,221,221,221,109,109,219,221,222,220,
-220,219,219,219,219,109,109,220,220,109,109,220,220,219,221,109,
-109,109,109,109,109,109,109,222,109,109,109,109,221,221,109,221,
-221,221,219,219,109,109,223,223,223,223,223,223,223,223,223,223,
-221,221,224,224,225,225,225,225,225,225,226,224,109,109,109,109,
-
-/* block 20 */
-109,227,227,228,109,229,229,229,229,229,229,109,109,109,109,229,
-229,109,109,229,229,229,229,229,229,229,229,229,229,229,229,229,
-229,229,229,229,229,229,229,229,229,109,229,229,229,229,229,229,
-229,109,229,229,109,229,229,109,229,229,109,109,227,109,228,228,
-228,227,227,109,109,109,109,227,227,109,109,227,227,227,109,109,
-109,227,109,109,109,109,109,109,109,229,229,229,229,109,229,109,
-109,109,109,109,109,109,230,230,230,230,230,230,230,230,230,230,
-227,227,229,229,229,227,109,109,109,109,109,109,109,109,109,109,
-
-/* block 21 */
-109,231,231,232,109,233,233,233,233,233,233,233,233,233,109,233,
-233,233,109,233,233,233,233,233,233,233,233,233,233,233,233,233,
-233,233,233,233,233,233,233,233,233,109,233,233,233,233,233,233,
-233,109,233,233,109,233,233,233,233,233,109,109,231,233,232,232,
-232,231,231,231,231,231,109,231,231,232,109,232,232,231,109,109,
-233,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-233,233,231,231,109,109,234,234,234,234,234,234,234,234,234,234,
-235,236,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 22 */
-109,237,238,238,109,239,239,239,239,239,239,239,239,109,109,239,
-239,109,109,239,239,239,239,239,239,239,239,239,239,239,239,239,
-239,239,239,239,239,239,239,239,239,109,239,239,239,239,239,239,
-239,109,239,239,109,239,239,239,239,239,109,109,237,239,240,237,
-238,237,237,237,237,109,109,238,238,109,109,238,238,237,109,109,
-109,109,109,109,109,109,237,240,109,109,109,109,239,239,109,239,
-239,239,237,237,109,109,241,241,241,241,241,241,241,241,241,241,
-242,239,243,243,243,243,243,243,109,109,109,109,109,109,109,109,
-
-/* block 23 */
-109,109,244,245,109,245,245,245,245,245,245,109,109,109,245,245,
-245,109,245,245,245,245,109,109,109,245,245,109,245,109,245,245,
-109,109,109,245,245,109,109,109,245,245,245,109,109,109,245,245,
-245,245,245,245,245,245,245,245,245,245,109,109,109,109,246,247,
-244,247,247,109,109,109,247,247,247,109,247,247,247,244,109,109,
-245,109,109,109,109,109,109,246,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,248,248,248,248,248,248,248,248,248,248,
-249,249,249,250,250,250,250,250,250,251,250,109,109,109,109,109,
-
-/* block 24 */
-109,252,252,252,109,253,253,253,253,253,253,253,253,109,253,253,
-253,109,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
-253,253,253,253,253,253,253,253,253,109,253,253,253,253,253,253,
-253,253,253,253,109,253,253,253,253,253,109,109,109,253,254,254,
-254,252,252,252,252,109,254,254,254,109,254,254,254,254,109,109,
-109,109,109,109,109,254,254,109,253,253,109,109,109,109,109,109,
-253,253,254,254,109,109,255,255,255,255,255,255,255,255,255,255,
-109,109,109,109,109,109,109,109,256,256,256,256,256,256,256,257,
-
-/* block 25 */
-109,109,258,258,109,259,259,259,259,259,259,259,259,109,259,259,
-259,109,259,259,259,259,259,259,259,259,259,259,259,259,259,259,
-259,259,259,259,259,259,259,259,259,109,259,259,259,259,259,259,
-259,259,259,259,109,259,259,259,259,259,109,109,260,259,258,260,
-258,258,261,258,258,109,260,258,258,109,258,258,260,260,109,109,
-109,109,109,109,109,261,261,109,109,109,109,109,109,109,259,109,
-259,259,260,260,109,109,262,262,262,262,262,262,262,262,262,262,
-109,259,259,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 26 */
-109,109,263,263,109,264,264,264,264,264,264,264,264,109,264,264,
-264,109,264,264,264,264,264,264,264,264,264,264,264,264,264,264,
-264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,
-264,264,264,264,264,264,264,264,264,264,264,109,109,264,265,263,
-263,266,266,266,266,109,263,263,263,109,263,263,263,266,264,109,
-109,109,109,109,109,109,109,265,109,109,109,109,109,109,109,109,
-264,264,266,266,109,109,267,267,267,267,267,267,267,267,267,267,
-268,268,268,268,268,268,109,109,109,269,264,264,264,264,264,264,
-
-/* block 27 */
-109,109,270,270,109,271,271,271,271,271,271,271,271,271,271,271,
-271,271,271,271,271,271,271,109,109,109,271,271,271,271,271,271,
-271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,
-271,271,109,271,271,271,271,271,271,271,271,271,109,271,109,109,
-271,271,271,271,271,271,271,109,109,109,272,109,109,109,109,273,
-270,270,272,272,272,109,272,109,270,270,270,270,270,270,270,273,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,270,270,274,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 28 */
-109,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,
-275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,
-275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,275,
-275,276,275,277,276,276,276,276,276,276,276,109,109,109,109, 5,
-275,275,275,275,275,275,278,276,276,276,276,276,276,276,276,279,
-280,280,280,280,280,280,280,280,280,280,279,279,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 29 */
-109,281,281,109,281,109,109,281,281,109,281,109,109,281,109,109,
-109,109,109,109,281,281,281,281,109,281,281,281,281,281,281,281,
-109,281,281,281,109,281,109,281,109,109,281,281,109,281,281,281,
-281,282,281,283,282,282,282,282,282,282,109,282,282,281,109,109,
-281,281,281,281,281,109,284,109,282,282,282,282,282,282,109,109,
-285,285,285,285,285,285,285,285,285,285,109,109,281,281,281,281,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 30 */
-286,287,287,287,288,288,288,288,288,288,288,288,288,288,288,288,
-288,288,288,287,288,287,287,287,289,289,287,287,287,287,287,287,
-290,290,290,290,290,290,290,290,290,290,291,291,291,291,291,291,
-291,291,291,291,287,289,287,289,287,289,292,293,292,293,294,294,
-286,286,286,286,286,286,286,286,109,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,
-286,286,286,286,286,286,286,286,286,286,286,286,286,109,109,109,
-109,289,289,289,289,289,289,289,289,289,289,289,289,289,289,294,
-
-/* block 31 */
-289,289,289,289,289,288,289,289,286,286,286,286,286,289,289,289,
-289,289,289,289,289,289,289,289,109,289,289,289,289,289,289,289,
-289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,289,
-289,289,289,289,289,289,289,289,289,289,289,289,289,109,287,287,
-287,287,287,287,287,287,289,287,287,287,287,287,287,109,287,287,
-288,288,288,288,288, 19, 19, 19, 19,288,288,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 32 */
-295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,
-295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,
-295,295,295,295,295,295,295,295,295,295,295,296,296,297,297,297,
-297,298,297,297,297,297,297,297,296,297,297,298,298,297,297,295,
-299,299,299,299,299,299,299,299,299,299,300,300,300,300,300,300,
-295,295,295,295,295,295,298,298,297,297,295,295,295,295,297,297,
-297,295,296,296,296,295,295,296,296,296,296,296,296,296,295,295,
-295,297,297,297,297,295,295,295,295,295,295,295,295,295,295,295,
-
-/* block 33 */
-295,295,297,296,298,297,297,296,296,296,296,296,296,297,295,296,
-299,299,299,299,299,299,299,299,299,299,296,296,296,297,301,301,
-302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,
-302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,
-302,302,302,302,302,302,109,302,109,109,109,109,109,302,109,109,
-303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,
-303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,303,
-303,303,303,303,303,303,303,303,303,303,303, 4,304,303,303,303,
-
-/* block 34 */
-305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
-305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
-305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
-305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
-305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
-305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
-306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,
-306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,
-
-/* block 35 */
-306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,
-306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,
-306,306,306,306,306,306,306,306,307,307,307,307,307,307,307,307,
-307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,
-307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,
-307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,
-307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,
-307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,
-
-/* block 36 */
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,308,308,109,308,308,308,308,109,109,
-308,308,308,308,308,308,308,109,308,109,308,308,308,308,109,109,
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-
-/* block 37 */
-308,308,308,308,308,308,308,308,308,109,308,308,308,308,109,109,
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,109,308,308,308,308,109,109,308,308,308,308,308,308,308,109,
-308,109,308,308,308,308,109,109,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,109,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-
-/* block 38 */
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,109,308,308,308,308,109,109,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,308,308,308,308,109,109,309,309,309,
-310,310,310,310,310,310,310,310,310,311,311,311,311,311,311,311,
-311,311,311,311,311,311,311,311,311,311,311,311,311,109,109,109,
-
-/* block 39 */
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-312,312,312,312,312,312,312,312,312,312,109,109,109,109,109,109,
-313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
-313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
-313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
-313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
-313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
-313,313,313,313,313,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 40 */
-314,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-
-/* block 41 */
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-
-/* block 42 */
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,316,316,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-
-/* block 43 */
-317,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,318,318,319,320,109,109,109,
-321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,
-321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,
-321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,
-321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,
-321,321,321,321,321,321,321,321,321,321,321, 4, 4, 4,322,322,
-322,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 44 */
-323,323,323,323,323,323,323,323,323,323,323,323,323,109,323,323,
-323,323,324,324,324,109,109,109,109,109,109,109,109,109,109,109,
-325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,
-325,325,326,326,326, 4, 4,109,109,109,109,109,109,109,109,109,
-327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,
-327,327,328,328,109,109,109,109,109,109,109,109,109,109,109,109,
-329,329,329,329,329,329,329,329,329,329,329,329,329,109,329,329,
-329,109,330,330,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 45 */
-331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,
-331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,
-331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,
-331,331,331,331,332,332,333,332,332,332,332,332,332,332,333,333,
-333,333,333,333,333,333,332,333,333,332,332,332,332,332,332,332,
-332,332,332,332,334,334,334,335,334,334,334,336,331,332,109,109,
-337,337,337,337,337,337,337,337,337,337,109,109,109,109,109,109,
-338,338,338,338,338,338,338,338,338,338,109,109,109,109,109,109,
-
-/* block 46 */
-339,339, 4, 4,339, 4,340,339,339,339,339,341,341,341,342,109,
-343,343,343,343,343,343,343,343,343,343,109,109,109,109,109,109,
-344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,
-344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,
-344,344,344,345,344,344,344,344,344,344,344,344,344,344,344,344,
-344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,
-344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,
-344,344,344,344,344,344,344,344,109,109,109,109,109,109,109,109,
-
-/* block 47 */
-344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,
-344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,344,
-344,344,344,344,344,344,344,344,344,341,344,109,109,109,109,109,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,315,
-315,315,315,315,315,315,109,109,109,109,109,109,109,109,109,109,
-
-/* block 48 */
-346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,
-346,346,346,346,346,346,346,346,346,346,346,346,346,109,109,109,
-347,347,347,348,348,348,348,347,347,348,348,348,109,109,109,109,
-348,348,347,348,348,348,348,348,348,347,347,347,109,109,109,109,
-349,109,109,109,350,350,351,351,351,351,351,351,351,351,351,351,
-352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,
-352,352,352,352,352,352,352,352,352,352,352,352,352,352,109,109,
-352,352,352,352,352,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 49 */
-353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,
-353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,
-353,353,353,353,353,353,353,353,353,353,353,353,109,109,109,109,
-354,354,354,354,354,355,355,355,354,354,355,354,354,354,354,354,
-354,353,353,353,353,353,353,353,354,354,109,109,109,109,109,109,
-356,356,356,356,356,356,356,356,356,356,357,109,109,109,358,358,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
-
-/* block 50 */
-360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,361,361,362,362,362,109,109,363,363,
-364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
-364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
-364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
-364,364,364,364,364,365,366,365,366,366,366,366,366,366,366,109,
-366,367,366,367,367,366,366,366,366,366,366,366,366,365,365,365,
-365,365,365,366,366,366,366,366,366,366,366,366,366,109,109,366,
-
-/* block 51 */
-368,368,368,368,368,368,368,368,368,368,109,109,109,109,109,109,
-368,368,368,368,368,368,368,368,368,368,109,109,109,109,109,109,
-369,369,369,369,369,369,369,370,369,369,369,369,369,369,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 52 */
-371,371,371,371,372,373,373,373,373,373,373,373,373,373,373,373,
-373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
-373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
-373,373,373,373,371,372,371,371,371,371,371,372,371,372,372,372,
-372,372,371,372,372,373,373,373,373,373,373,373,109,109,109,109,
-374,374,374,374,374,374,374,374,374,374,375,375,375,375,375,375,
-375,376,376,376,376,376,376,376,376,376,376,371,371,371,371,371,
-371,371,371,371,376,376,376,376,376,376,376,376,376,109,109,109,
-
-/* block 53 */
-377,377,378,379,379,379,379,379,379,379,379,379,379,379,379,379,
-379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,
-379,378,377,377,377,377,378,378,377,377,378,377,378,378,379,379,
-380,380,380,380,380,380,380,380,380,380,379,379,379,379,379,379,
-381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
-381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
-381,381,381,381,381,381,382,383,382,382,383,383,383,382,383,382,
-382,382,383,383,109,109,109,109,109,109,109,109,384,384,384,384,
-
-/* block 54 */
-385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,
-385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,385,
-385,385,385,385,386,386,386,386,386,386,386,386,387,387,387,387,
-387,387,387,387,386,386,387,387,109,109,109,388,388,388,388,388,
-389,389,389,389,389,389,389,389,389,389,109,109,109,385,385,385,
-390,390,390,390,390,390,390,390,390,390,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,
-391,391,391,391,391,391,391,391,392,392,392,392,392,392,393,393,
-
-/* block 55 */
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-394,394,394,394,394,394,394,394,109,109,109,109,109,109,109,109,
-104,104,104, 4,104,104,104,104,104,104,104,104,104,104,104,104,
-104,395,104,104,104,104,104,104,104,396,396,396,396,104,396,396,
-396,396,395,395,104,396,396,109,109,109,109,109,109,109,109,109,
-
-/* block 56 */
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33,116,116,116,116,116,397,101,101,101,101,
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
-101,101,101,101,101,101,101,101,101,101,101,101,101,110,110,110,
-110,110,101,101,101,101,110,110,110,110,110, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33,398,399, 33, 33, 33,400, 33, 33,
-
-/* block 57 */
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,101,101,101,101,101,
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
-101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,110,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,104,104,104,104,
-
-/* block 58 */
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
-401,402, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
-
-/* block 59 */
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 33, 33, 33, 33, 33,403, 33, 33,404, 33,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
-
-/* block 60 */
-405,405,405,405,405,405,405,405,406,406,406,406,406,406,406,406,
-405,405,405,405,405,405,109,109,406,406,406,406,406,406,109,109,
-405,405,405,405,405,405,405,405,406,406,406,406,406,406,406,406,
-405,405,405,405,405,405,405,405,406,406,406,406,406,406,406,406,
-405,405,405,405,405,405,109,109,406,406,406,406,406,406,109,109,
-116,405,116,405,116,405,116,405,109,406,109,406,109,406,109,406,
-405,405,405,405,405,405,405,405,406,406,406,406,406,406,406,406,
-407,407,408,408,408,408,409,409,410,410,411,411,412,412,109,109,
-
-/* block 61 */
-405,405,405,405,405,405,405,405,413,413,413,413,413,413,413,413,
-405,405,405,405,405,405,405,405,413,413,413,413,413,413,413,413,
-405,405,405,405,405,405,405,405,413,413,413,413,413,413,413,413,
-405,405,116,414,116,109,116,116,406,406,415,415,416,108,417,108,
-108,108,116,414,116,109,116,116,418,418,418,418,416,108,108,108,
-405,405,116,116,109,109,116,116,406,406,419,419,109,108,108,108,
-405,405,116,116,116,157,116,116,406,406,420,420,161,108,108,108,
-109,109,116,414,116,109,116,116,421,421,422,422,416,108,108,109,
-
-/* block 62 */
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 22,423,423, 22, 22,
- 9, 9, 9, 9, 9, 9, 4, 4, 21, 25, 6, 21, 21, 25, 6, 21,
- 4, 4, 4, 4, 4, 4, 4, 4,424,425, 22, 22, 22, 22, 22, 3,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 21, 25, 4, 4, 4, 4, 15,
- 15, 4, 4, 4, 8, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 8, 4, 15, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
- 22, 22, 22, 22, 22,426,426,426,426,426, 22, 22, 22, 22, 22, 22,
- 23,101,109,109, 23, 23, 23, 23, 23, 23, 8, 8, 8, 6, 7,101,
-
-/* block 63 */
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 8, 8, 8, 6, 7,109,
-101,101,101,101,101,101,101,101,101,101,101,101,101,109,109,109,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-104,104,104,104,104,104,104,104,104,104,104,104,104,427,427,427,
-427,104,427,427,427,104,104,104,104,104,104,104,104,104,104,104,
-104,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 64 */
- 19, 19,428, 19, 19, 19, 19,428, 19, 19,429,428,428,428,429,429,
-428,428,428,429, 19,428, 19, 19, 8,428,428,428,428,428, 19, 19,
- 19, 19, 19, 19,428, 19,430, 19,428, 19,431,432,428,428, 19,429,
-428,428,433,428,429,396,396,396,396,429, 19, 19,429,429,428,428,
- 8, 8, 8, 8, 8,428,429,429,429,429, 19, 8, 19, 19,434, 19,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,
-436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,
-
-/* block 65 */
-437,437,437, 30, 31,437,437,437,437, 23,109,109,109,109,109,109,
- 8, 8, 8, 8, 8, 19, 19, 19, 19, 19, 8, 8, 19, 19, 19, 19,
- 8, 19, 19, 8, 19, 19, 8, 19, 19, 19, 19, 19, 19, 19, 8, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8, 8,
- 19, 19, 8, 19, 8, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-
-/* block 66 */
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-
-/* block 67 */
- 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 8, 8, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 8, 8, 19, 19, 19, 19, 19, 19, 19, 6, 7, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8, 19, 19, 19,
-
-/* block 68 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 8, 8,
- 8, 8, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 69 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-
-/* block 70 */
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,439,
-439,439,439,439,439,439,439,439,439,439, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-
-/* block 71 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-
-/* block 72 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 8, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 8, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 8, 8, 8, 8, 8, 8,
-
-/* block 73 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-
-/* block 74 */
-109, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 6, 7, 6, 7, 6, 7, 6, 7,
- 6, 7, 6, 7, 6, 7, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-
-/* block 75 */
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 23, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 8, 8, 8, 8, 8, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-
-/* block 76 */
-440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
-440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
-440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
-440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
-440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
-440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
-440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
-440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
-
-/* block 77 */
- 8, 8, 8, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6,
- 7, 6, 7, 6, 7, 6, 7, 6, 7, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 6, 7, 6, 7, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 7, 8, 8,
-
-/* block 78 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 19, 19, 8, 8, 8, 8, 8, 8,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 79 */
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 80 */
-441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,
-441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,
-441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,109,
-442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,
-442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,
-442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,109,
- 30, 31,443,444,445,446,447, 30, 31, 30, 31, 30, 31,448,449,450,
-451, 33, 30, 31, 33, 30, 31, 33, 33, 33, 33, 33,101,101,452,452,
-
-/* block 81 */
-153,154,153,154,153,154,153,154,153,154,153,154,153,154,153,154,
-153,154,153,154,153,154,153,154,153,154,153,154,153,154,153,154,
-153,154,153,154,153,154,153,154,153,154,153,154,153,154,153,154,
-153,154,153,154,153,154,153,154,153,154,153,154,153,154,153,154,
-153,154,153,154,153,154,153,154,153,154,153,154,153,154,153,154,
-153,154,153,154,153,154,153,154,153,154,153,154,153,154,153,154,
-153,154,153,154,453,454,454,454,454,454,454,153,154,153,154,455,
-455,455,153,154,109,109,109,109,109,456,456,456,456,457,456,456,
-
-/* block 82 */
-458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,
-458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,458,
-458,458,458,458,458,458,109,458,109,109,109,109,109,458,109,109,
-459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,
-459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,
-459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,459,
-459,459,459,459,459,459,459,459,109,109,109,109,109,109,109,460,
-461,109,109,109,109,109,109,109,109,109,109,109,109,109,109,462,
-
-/* block 83 */
-308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,
-308,308,308,308,308,308,308,109,109,109,109,109,109,109,109,109,
-308,308,308,308,308,308,308,109,308,308,308,308,308,308,308,109,
-308,308,308,308,308,308,308,109,308,308,308,308,308,308,308,109,
-308,308,308,308,308,308,308,109,308,308,308,308,308,308,308,109,
-308,308,308,308,308,308,308,109,308,308,308,308,308,308,308,109,
-170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
-170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
-
-/* block 84 */
- 4, 4, 21, 25, 21, 25, 4, 4, 4, 21, 25, 4, 21, 25, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 9, 4, 4, 9, 4, 21, 25, 4, 4,
- 21, 25, 6, 7, 6, 7, 6, 7, 6, 7, 4, 4, 4, 4, 4,102,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, 9,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 85 */
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,109,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 86 */
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-
-/* block 87 */
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,
-463,463,463,463,463,463,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,
-
-/* block 88 */
- 3, 4, 4, 4, 19,464,396,465, 6, 7, 6, 7, 6, 7, 6, 7,
- 6, 7, 19, 19, 6, 7, 6, 7, 6, 7, 6, 7, 9, 6, 7, 7,
- 19,465,465,465,465,465,465,465,465,465,104,104,104,104,466,466,
- 9,102,102,102,102,102, 19, 19,465,465,465,464,396, 4, 19, 19,
-109,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
-467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
-467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
-467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
-
-/* block 89 */
-467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,
-467,467,467,467,467,467,467,109,109,104,104, 14, 14,468,468,467,
- 9,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
-469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
-469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
-469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
-469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
-469,469,469,469,469,469,469,469,469,469,469, 4,102,470,470,469,
-
-/* block 90 */
-109,109,109,109,109,471,471,471,471,471,471,471,471,471,471,471,
-471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,
-471,471,471,471,471,471,471,471,471,471,471,471,471,471,109,109,
-109,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,
-472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,
-472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,
-472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,
-472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,
-
-/* block 91 */
-472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,109,
- 19, 19, 23, 23, 23, 23, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,
-471,471,471,471,471,471,471,471,471,471,471,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,
-469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
-
-/* block 92 */
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,109,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 23, 23, 23, 23, 23, 23, 23, 23,
- 19, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,
-473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, 19,
-
-/* block 93 */
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,
-474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,
-474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,109,
-
-/* block 94 */
-474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,
-474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,
-474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,
-474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,
-474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,
-474,474,474,474,474,474,474,474, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-
-/* block 95 */
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-
-/* block 96 */
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,109,109,109,109,109,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-
-/* block 97 */
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 98 */
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,477,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-
-/* block 99 */
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
-
-/* block 100 */
-476,476,476,476,476,476,476,476,476,476,476,476,476,109,109,109,
-478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,
-478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,
-478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,
-478,478,478,478,478,478,478,109,109,109,109,109,109,109,109,109,
-479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
-479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
-479,479,479,479,479,479,479,479,480,480,480,480,480,480,481,481,
-
-/* block 101 */
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-
-/* block 102 */
-482,482,482,482,482,482,482,482,482,482,482,482,483,484,484,484,
-482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
-485,485,485,485,485,485,485,485,485,485,482,482,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,167,168,
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,167,168,
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,486,170,
-171,171,171,487,170,170,170,170,170,170,170,170,170,170,487,398,
-
-/* block 103 */
-167,168,167,168,167,168,167,168,167,168,167,168,167,168,167,168,
-167,168,167,168,167,168,167,168,109,109,109,109,109,109,109,170,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,489,489,489,489,489,489,489,489,489,489,
-490,490,491,491,491,491,491,491,109,109,109,109,109,109,109,109,
-
-/* block 104 */
- 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 14, 14, 14, 14, 14, 14,102,102,102,102,102,102,102,102,102,
- 14, 14, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 33, 33, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,
-101, 33, 33, 33, 33, 33, 33, 33, 33, 30, 31, 30, 31,492, 30, 31,
-
-/* block 105 */
- 30, 31, 30, 31, 30, 31, 30, 31,102, 14, 14, 30, 31,493, 33,109,
- 30, 31, 30, 31,109,109,109,109,109,109,109,109,109,109,109,109,
- 30, 31, 30, 31, 30, 31, 30, 31, 30, 31,494,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,101,101, 33, 20, 20, 20, 20, 20,
-
-/* block 106 */
-495,495,496,495,495,495,496,495,495,495,495,496,495,495,495,495,
-495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
-495,495,495,497,497,496,496,497,498,498,498,498,109,109,109,109,
- 23, 23, 23, 23, 23, 23, 19, 19, 5, 19,109,109,109,109,109,109,
-499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
-499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
-499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
-499,499,499,499,500,500,500,500,109,109,109,109,109,109,109,109,
-
-/* block 107 */
-501,501,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,501,501,501,501,501,501,501,501,501,501,501,501,
-501,501,501,501,503,109,109,109,109,109,109,109,109,109,504,504,
-505,505,505,505,505,505,505,505,505,505,109,109,109,109,109,109,
-213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
-213,213,215,215,215,215,215,215,217,217,217,215,109,109,109,109,
-
-/* block 108 */
-506,506,506,506,506,506,506,506,506,506,507,507,507,507,507,507,
-507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,507,
-507,507,507,507,507,507,508,508,508,508,508,508,508,508,509,509,
-510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,
-510,510,510,510,510,510,510,511,511,511,511,511,511,511,511,511,
-511,511,512,512,109,109,109,109,109,109,109,109,109,109,109,513,
-305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
-305,305,305,305,305,305,305,305,305,305,305,305,305,109,109,109,
-
-/* block 109 */
-514,514,514,515,516,516,516,516,516,516,516,516,516,516,516,516,
-516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
-516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
-516,516,516,514,515,515,514,514,514,514,515,515,514,515,515,515,
-515,517,517,517,517,517,517,517,517,517,517,517,517,517,109,518,
-519,519,519,519,519,519,519,519,519,519,109,109,109,109,517,517,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 110 */
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
-520,520,520,520,520,520,520,520,520,521,521,521,521,521,521,522,
-522,521,521,522,522,521,521,109,109,109,109,109,109,109,109,109,
-520,520,520,521,520,520,520,520,520,520,520,520,521,522,109,109,
-523,523,523,523,523,523,523,523,523,523,109,109,524,524,524,524,
-295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,
-525,295,295,295,295,295,295,301,301,301,295,296,109,109,109,109,
-
-/* block 111 */
-526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,
-526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,
-526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,
-527,526,527,527,527,526,526,527,527,526,526,526,526,526,527,527,
-526,527,526,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,526,526,528,529,529,
-530,530,530,530,530,530,530,530,530,530,530,531,532,532,531,531,
-533,533,530,534,534,531,532,109,109,109,109,109,109,109,109,109,
-
-/* block 112 */
-109,308,308,308,308,308,308,109,109,308,308,308,308,308,308,109,
-109,308,308,308,308,308,308,109,109,109,109,109,109,109,109,109,
-308,308,308,308,308,308,308,109,308,308,308,308,308,308,308,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 113 */
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
-530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
-530,530,530,531,531,532,531,531,532,531,531,533,531,532,109,109,
-535,535,535,535,535,535,535,535,535,535,109,109,109,109,109,109,
-
-/* block 114 */
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-
-/* block 115 */
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-
-/* block 116 */
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-
-/* block 117 */
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-
-/* block 118 */
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-
-/* block 119 */
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-
-/* block 120 */
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-
-/* block 121 */
-537,537,537,537,537,537,537,537,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,109,109,109,109,109,109,109,109,109,109,109,109,
-306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,
-306,306,306,306,306,306,306,109,109,109,109,307,307,307,307,307,
-307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,
-307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,
-307,307,307,307,307,307,307,307,307,307,307,307,109,109,109,109,
-
-/* block 122 */
-538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
-538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
-538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
-538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
-538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
-538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
-538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
-538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
-
-/* block 123 */
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-
-/* block 124 */
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,109,109,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-
-/* block 125 */
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 126 */
- 33, 33, 33, 33, 33, 33, 33,109,109,109,109,109,109,109,109,109,
-109,109,109,178,178,178,178,178,109,109,109,109,109,184,181,184,
-184,184,184,184,184,184,184,184,184,540,184,184,184,184,184,184,
-184,184,184,184,184,184,184,109,184,184,184,184,184,109,184,109,
-184,184,109,184,184,109,184,184,184,184,184,184,184,184,184,184,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-
-/* block 127 */
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,541,541,541,541,541,541,541,541,541,541,541,541,541,541,
-541,541,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-
-/* block 128 */
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-
-/* block 129 */
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191, 6, 7,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-
-/* block 130 */
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-109,109,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-191,191,191,191,191,191,191,191,191,191,191,191,188, 19,109,109,
-
-/* block 131 */
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
- 4, 4, 4, 4, 4, 4, 4, 6, 7, 4,109,109,109,109,109,109,
-104,104,104,104,104,104,104,109,109,109,109,109,109,109,109,109,
- 4, 9, 9, 15, 15, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6,
- 7, 6, 7, 6, 7, 4, 4, 6, 7, 4, 4, 4, 4, 15, 15, 15,
- 4, 4, 4,109, 4, 4, 4, 4, 9, 6, 7, 6, 7, 6, 7, 4,
- 4, 4, 8, 9, 8, 8, 8,109, 4, 5, 4, 4,109,109,109,109,
-191,191,191,191,191,109,191,191,191,191,191,191,191,191,191,191,
-
-/* block 132 */
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,109,109, 22,
-
-/* block 133 */
-109, 4, 4, 4, 5, 4, 4, 4, 6, 7, 4, 8, 4, 9, 4, 4,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 4, 8, 8, 8, 4,
- 4, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 6, 4, 7, 14, 15,
- 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
- 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 6, 8, 7, 8, 6,
- 7, 4, 6, 7, 4, 4,469,469,469,469,469,469,469,469,469,469,
-102,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
-
-/* block 134 */
-469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
-469,469,469,469,469,469,469,469,469,469,469,469,469,469,542,542,
-472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,
-472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,109,
-109,109,472,472,472,472,472,472,109,109,472,472,472,472,472,472,
-109,109,472,472,472,472,472,472,109,109,472,472,472,109,109,109,
- 5, 5, 8, 14, 19, 5, 5,109, 19, 8, 8, 8, 8, 19, 19,109,
-426,426,426,426,426,426,426,426,426, 22, 22, 22, 19, 19,109,109,
-
-/* block 135 */
-543,543,543,543,543,543,543,543,543,543,543,543,109,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,109,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,109,543,543,109,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,109,109,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 136 */
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,109,109,109,109,109,
-
-/* block 137 */
- 4, 4, 4,109,109,109,109, 23, 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 23,109,109,109, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,
-544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,
-544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,
-544,544,544,544,544,545,545,545,545,546,546,546,546,546,546,546,
-
-/* block 138 */
-546,546,546,546,546,546,546,546,546,546,545,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,104,109,109,
-
-/* block 139 */
-547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,
-547,547,547,547,547,547,547,547,547,547,547,547,547,109,109,109,
-548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
-548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
-548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
-548,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 140 */
-549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,
-549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,109,
-550,550,550,550,109,109,109,109,109,109,109,109,109,109,109,109,
-551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,
-551,552,551,551,551,551,551,551,551,551,552,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 141 */
-553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,
-553,553,553,553,553,553,553,553,553,553,553,553,553,553,109,554,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,109,109,109,109,555,555,555,555,555,555,555,555,
-556,557,557,557,557,557,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 142 */
-558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,
-558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,
-558,558,558,558,558,558,558,558,559,559,559,559,559,559,559,559,
-559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,
-559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,
-560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
-560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
-560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
-
-/* block 143 */
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,109,109,
-562,562,562,562,562,562,562,562,562,562,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 144 */
-563,563,563,563,563,563,109,109,563,109,563,563,563,563,563,563,
-563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,
-563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,
-563,563,563,563,563,563,109,563,563,109,109,109,563,109,109,563,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,109,565,566,566,566,566,566,566,566,566,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 145 */
-567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,
-567,567,567,567,567,567,568,568,568,568,568,568,109,109,109,569,
-570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,
-570,570,570,570,570,570,570,570,570,570,109,109,109,109,109,571,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 146 */
-572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
-572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
-573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
-573,573,573,573,573,573,573,573,109,109,109,109,109,109,573,573,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 147 */
-574,575,575,575,109,575,575,109,109,109,109,109,575,575,575,575,
-574,574,574,574,109,574,574,574,109,574,574,574,574,574,574,574,
-574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,
-574,574,574,574,109,109,109,109,575,575,575,109,109,109,109,575,
-576,576,576,576,576,576,576,576,109,109,109,109,109,109,109,109,
-577,577,577,577,577,577,577,577,577,109,109,109,109,109,109,109,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,579,579,580,
-
-/* block 148 */
-581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
-581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
-581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
-581,581,581,581,581,581,109,109,109,582,582,582,582,582,582,582,
-583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,
-583,583,583,583,583,583,109,109,584,584,584,584,584,584,584,584,
-585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,
-585,585,585,109,109,109,109,109,586,586,586,586,586,586,586,586,
-
-/* block 149 */
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 150 */
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,
-588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,109,
-
-/* block 151 */
-589,590,589,591,591,591,591,591,591,591,591,591,591,591,591,591,
-591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,
-591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,
-591,591,591,591,591,591,591,591,590,590,590,590,590,590,590,590,
-590,590,590,590,590,590,590,592,592,592,592,592,592,592,109,109,
-109,109,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
-593,593,593,593,593,593,594,594,594,594,594,594,594,594,594,594,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 152 */
-595,595,596,597,597,597,597,597,597,597,597,597,597,597,597,597,
-597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,
-597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,
-596,596,596,595,595,595,595,596,596,595,595,598,598,599,598,598,
-598,598,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,
-600,600,600,600,600,600,600,600,600,109,109,109,109,109,109,109,
-601,601,601,601,601,601,601,601,601,601,109,109,109,109,109,109,
-
-/* block 153 */
-602,602,602,603,603,603,603,603,603,603,603,603,603,603,603,603,
-603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,
-603,603,603,603,603,603,603,602,602,602,602,602,604,602,602,602,
-602,602,602,602,602,109,605,605,605,605,605,605,605,605,605,605,
-606,606,606,606,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 154 */
-607,607,608,609,609,609,609,609,609,609,609,609,609,609,609,609,
-609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,
-609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,
-609,609,609,608,608,608,607,607,607,607,607,607,607,607,607,608,
-608,609,609,609,609,610,610,610,610,109,109,109,109,109,109,109,
-611,611,611,611,611,611,611,611,611,611,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 155 */
-612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,
-612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,
-612,612,612,612,612,612,612,612,612,612,612,613,614,613,614,614,
-613,613,613,613,613,613,614,613,109,109,109,109,109,109,109,109,
-615,615,615,615,615,615,615,615,615,615,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 156 */
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-
-/* block 157 */
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 158 */
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,109,109,109,109,109,109,109,109,109,109,109,109,109,
-618,618,618,618,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 159 */
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-
-/* block 160 */
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 161 */
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-
-/* block 162 */
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,
-488,488,488,488,488,488,488,488,488,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 163 */
-620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
-620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
-620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
-620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
-620,620,620,620,620,109,109,109,109,109,109,109,109,109,109,109,
-620,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,
-621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,
-621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,109,
-
-/* block 164 */
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,622,
-622,622,622,623,623,623,623,623,623,623,623,623,623,623,623,623,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 165 */
-469,467,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 166 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19,109,109,109,109,109,109,109,109,109,109,
-
-/* block 167 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19,109,109, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19,624,395,104,104,104, 19, 19, 19,395,624,624,
-624,624,624, 22, 22, 22, 22, 22, 22, 22, 22,104,104,104,104,104,
-
-/* block 168 */
-104,104,104, 19, 19,104,104,104,104,104,104,104, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,104,104,104,104, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 169 */
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,625,625,625,546,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 170 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19,109,109,109,109,109,109,109,109,109,
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 171 */
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
-428,428,428,428,428,428,428,428,428,428,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,428,428,428,428,428,428,428,428,428,428,428,428,
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,429,429,
-429,429,429,429,429,109,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,428,428,428,428,428,428,428,428,
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
-
-/* block 172 */
-428,428,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,428,109,428,428,
-109,109,428,109,109,428,428,109,109,428,428,428,428,109,428,428,
-428,428,428,428,428,428,429,429,429,429,109,429,109,429,429,429,
-429,429,429,429,109,429,429,429,429,429,429,429,429,429,429,429,
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
-428,428,428,428,428,428,428,428,428,428,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-
-/* block 173 */
-429,429,429,429,428,428,109,428,428,428,428,109,109,428,428,428,
-428,428,428,428,428,109,428,428,428,428,428,428,428,109,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,428,428,109,428,428,428,428,109,
-428,428,428,428,428,109,428,109,109,109,428,428,428,428,428,428,
-428,109,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,428,428,428,428,
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
-
-/* block 174 */
-428,428,428,428,428,428,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
-428,428,428,428,428,428,428,428,428,428,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,428,428,428,428,428,428,428,428,428,428,428,428,
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-
-/* block 175 */
-429,429,429,429,429,429,429,429,428,428,428,428,428,428,428,428,
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
-428,428,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,428,428,428,428,
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
-428,428,428,428,428,428,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
-
-/* block 176 */
-428,428,428,428,428,428,428,428,428,428,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,429,429,109,109,428,428,428,428,428,428,428,428,
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
-428, 8,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429, 8,429,429,429,429,
-429,429,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
-428,428,428,428,428,428,428,428,428,428,428, 8,429,429,429,429,
-
-/* block 177 */
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,429, 8,429,429,429,429,429,429,428,428,428,428,
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
-428,428,428,428,428, 8,429,429,429,429,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429, 8,
-429,429,429,429,429,429,428,428,428,428,428,428,428,428,428,428,
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,428, 8,
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-
-/* block 178 */
-429,429,429,429,429,429,429,429,429, 8,429,429,429,429,429,429,
-428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
-428,428,428,428,428,428,428,428,428, 8,429,429,429,429,429,429,
-429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
-429,429,429, 8,429,429,429,429,429,429,428,429,109,109, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-
-/* block 179 */
-191,191,191,191,109,191,191,191,191,191,191,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-109,191,191,109,191,109,109,191,109,191,191,191,191,191,191,191,
-191,191,191,109,191,191,191,191,109,191,109,191,109,109,109,109,
-109,109,191,109,109,109,109,191,109,191,109,191,109,191,191,191,
-109,191,191,109,191,109,109,191,109,191,109,191,109,191,109,191,
-109,191,191,109,191,109,109,191,191,191,191,109,191,191,191,191,
-191,191,191,109,191,191,191,191,109,191,191,191,191,109,191,109,
-
-/* block 180 */
-191,191,191,191,191,191,191,191,191,191,109,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,109,109,109,109,
-109,191,191,191,109,191,191,191,191,191,109,191,191,191,191,191,
-191,191,191,191,191,191,191,191,191,191,191,191,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-186,186,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 181 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-
-/* block 182 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,
-109, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,
-109, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-109, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 183 */
- 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-
-/* block 184 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,626,626,626,626,626,626,626,626,626,626,
-626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,
-
-/* block 185 */
-627, 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,109,109,109,
- 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 186 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19,109, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,
-
-/* block 187 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19,109, 19, 19, 19, 19, 19,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 188 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,
- 19,109, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-
-/* block 189 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,109, 19, 19, 19, 19,109,109,109,
-
-/* block 190 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,
- 19, 19, 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 191 */
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109, 19, 19, 19, 19, 19,
-
-/* block 192 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19,109,109,109,109, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 193 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 194 */
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 195 */
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 196 */
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,109,109,109,109,109,109,109,109,109,109,109,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-
-/* block 197 */
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
-475,475,475,475,475,475,475,475,475,475,475,475,475,475,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 198 */
-426, 22,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
- 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
-
-/* block 199 */
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-
-/* block 200 */
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-
-/* block 201 */
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-
-/* block 202 */
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,109,109,
-
-};
-
-#if UCD_BLOCK_SIZE != 128
-#error Please correct UCD_BLOCK_SIZE in pcre_internal.h
-#endif
-#endif /* SUPPORT_UCP */
-
-#endif /* PCRE_INCLUDED */
diff --git a/usr.sbin/nginx/src/pcre/pcre_valid_utf8.c b/usr.sbin/nginx/src/pcre/pcre_valid_utf8.c
deleted file mode 100644
index a4159275681..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre_valid_utf8.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2012 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains an internal function for validating UTF-8 character
-strings. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Validate a UTF-8 string *
-*************************************************/
-
-/* This function is called (optionally) at the start of compile or match, to
-check that a supposed UTF-8 string is actually valid. The early check means
-that subsequent code can assume it is dealing with a valid string. The check
-can be turned off for maximum performance, but the consequences of supplying an
-invalid string are then undefined.
-
-Originally, this function checked according to RFC 2279, allowing for values in
-the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were in
-the canonical format. Once somebody had pointed out RFC 3629 to me (it
-obsoletes 2279), additional restrictions were applied. The values are now
-limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the
-subrange 0xd000 to 0xdfff is excluded. However, the format of 5-byte and 6-byte
-characters is still checked.
-
-From release 8.13 more information about the details of the error are passed
-back in the returned value:
-
-PCRE_UTF8_ERR0 No error
-PCRE_UTF8_ERR1 Missing 1 byte at the end of the string
-PCRE_UTF8_ERR2 Missing 2 bytes at the end of the string
-PCRE_UTF8_ERR3 Missing 3 bytes at the end of the string
-PCRE_UTF8_ERR4 Missing 4 bytes at the end of the string
-PCRE_UTF8_ERR5 Missing 5 bytes at the end of the string
-PCRE_UTF8_ERR6 2nd-byte's two top bits are not 0x80
-PCRE_UTF8_ERR7 3rd-byte's two top bits are not 0x80
-PCRE_UTF8_ERR8 4th-byte's two top bits are not 0x80
-PCRE_UTF8_ERR9 5th-byte's two top bits are not 0x80
-PCRE_UTF8_ERR10 6th-byte's two top bits are not 0x80
-PCRE_UTF8_ERR11 5-byte character is not permitted by RFC 3629
-PCRE_UTF8_ERR12 6-byte character is not permitted by RFC 3629
-PCRE_UTF8_ERR13 4-byte character with value > 0x10ffff is not permitted
-PCRE_UTF8_ERR14 3-byte character with value 0xd000-0xdfff is not permitted
-PCRE_UTF8_ERR15 Overlong 2-byte sequence
-PCRE_UTF8_ERR16 Overlong 3-byte sequence
-PCRE_UTF8_ERR17 Overlong 4-byte sequence
-PCRE_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur)
-PCRE_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur)
-PCRE_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character)
-PCRE_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff
-PCRE_UTF8_ERR22 Non-character
-
-Arguments:
- string points to the string
- length length of string, or -1 if the string is zero-terminated
- errp pointer to an error position offset variable
-
-Returns: = 0 if the string is a valid UTF-8 string
- > 0 otherwise, setting the offset of the bad character
-*/
-
-int
-PRIV(valid_utf)(PCRE_PUCHAR string, int length, int *erroroffset)
-{
-#ifdef SUPPORT_UTF
-register PCRE_PUCHAR p;
-
-if (length < 0)
- {
- for (p = string; *p != 0; p++);
- length = (int)(p - string);
- }
-
-for (p = string; length-- > 0; p++)
- {
- register pcre_uchar ab, c, d;
- pcre_uint32 v = 0;
-
- c = *p;
- if (c < 128) continue; /* ASCII character */
-
- if (c < 0xc0) /* Isolated 10xx xxxx byte */
- {
- *erroroffset = (int)(p - string);
- return PCRE_UTF8_ERR20;
- }
-
- if (c >= 0xfe) /* Invalid 0xfe or 0xff bytes */
- {
- *erroroffset = (int)(p - string);
- return PCRE_UTF8_ERR21;
- }
-
- ab = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */
- if (length < ab)
- {
- *erroroffset = (int)(p - string); /* Missing bytes */
- return ab - length; /* Codes ERR1 to ERR5 */
- }
- length -= ab; /* Length remaining */
-
- /* Check top bits in the second byte */
-
- if (((d = *(++p)) & 0xc0) != 0x80)
- {
- *erroroffset = (int)(p - string) - 1;
- return PCRE_UTF8_ERR6;
- }
-
- /* For each length, check that the remaining bytes start with the 0x80 bit
- set and not the 0x40 bit. Then check for an overlong sequence, and for the
- excluded range 0xd800 to 0xdfff. */
-
- switch (ab)
- {
- /* 2-byte character. No further bytes to check for 0x80. Check first byte
- for for xx00 000x (overlong sequence). */
-
- case 1: if ((c & 0x3e) == 0)
- {
- *erroroffset = (int)(p - string) - 1;
- return PCRE_UTF8_ERR15;
- }
- break;
-
- /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes
- for 1110 0000, xx0x xxxx (overlong sequence) or
- 1110 1101, 1010 xxxx (0xd800 - 0xdfff) */
-
- case 2:
- if ((*(++p) & 0xc0) != 0x80) /* Third byte */
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE_UTF8_ERR7;
- }
- if (c == 0xe0 && (d & 0x20) == 0)
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE_UTF8_ERR16;
- }
- if (c == 0xed && d >= 0xa0)
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE_UTF8_ERR14;
- }
- v = ((c & 0x0f) << 12) | ((d & 0x3f) << 6) | (*p & 0x3f);
- break;
-
- /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2
- bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a
- character greater than 0x0010ffff (f4 8f bf bf) */
-
- case 3:
- if ((*(++p) & 0xc0) != 0x80) /* Third byte */
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE_UTF8_ERR7;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE_UTF8_ERR8;
- }
- if (c == 0xf0 && (d & 0x30) == 0)
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE_UTF8_ERR17;
- }
- if (c > 0xf4 || (c == 0xf4 && d > 0x8f))
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE_UTF8_ERR13;
- }
- v = ((c & 0x07) << 18) | ((d & 0x3f) << 12) | ((p[-1] & 0x3f) << 6) | (*p & 0x3f);
- break;
-
- /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be
- rejected by the length test below. However, we do the appropriate tests
- here so that overlong sequences get diagnosed, and also in case there is
- ever an option for handling these larger code points. */
-
- /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for
- 1111 1000, xx00 0xxx */
-
- case 4:
- if ((*(++p) & 0xc0) != 0x80) /* Third byte */
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE_UTF8_ERR7;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE_UTF8_ERR8;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
- {
- *erroroffset = (int)(p - string) - 4;
- return PCRE_UTF8_ERR9;
- }
- if (c == 0xf8 && (d & 0x38) == 0)
- {
- *erroroffset = (int)(p - string) - 4;
- return PCRE_UTF8_ERR18;
- }
- break;
-
- /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for
- 1111 1100, xx00 00xx. */
-
- case 5:
- if ((*(++p) & 0xc0) != 0x80) /* Third byte */
- {
- *erroroffset = (int)(p - string) - 2;
- return PCRE_UTF8_ERR7;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
- {
- *erroroffset = (int)(p - string) - 3;
- return PCRE_UTF8_ERR8;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
- {
- *erroroffset = (int)(p - string) - 4;
- return PCRE_UTF8_ERR9;
- }
- if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */
- {
- *erroroffset = (int)(p - string) - 5;
- return PCRE_UTF8_ERR10;
- }
- if (c == 0xfc && (d & 0x3c) == 0)
- {
- *erroroffset = (int)(p - string) - 5;
- return PCRE_UTF8_ERR19;
- }
- break;
- }
-
- /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are
- excluded by RFC 3629. The pointer p is currently at the last byte of the
- character. */
-
- if (ab > 3)
- {
- *erroroffset = (int)(p - string) - ab;
- return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12;
- }
-
- /* Reject non-characters. The pointer p is currently at the last byte of the
- character. */
- if ((v & 0xfffeu) == 0xfffeu || (v >= 0xfdd0 && v <= 0xfdef))
- {
- *erroroffset = (int)(p - string) - ab;
- return PCRE_UTF8_ERR22;
- }
- }
-
-#else /* Not SUPPORT_UTF */
-(void)(string); /* Keep picky compilers happy */
-(void)(length);
-(void)(erroroffset);
-#endif
-
-return PCRE_UTF8_ERR0; /* This indicates success */
-}
-
-/* End of pcre_valid_utf8.c */
diff --git a/usr.sbin/nginx/src/pcre/pcre_xclass.c b/usr.sbin/nginx/src/pcre/pcre_xclass.c
deleted file mode 100644
index d777acb57c9..00000000000
--- a/usr.sbin/nginx/src/pcre/pcre_xclass.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- Copyright (c) 1997-2013 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-
-/* This module contains an internal function that is used to match an extended
-class. It is used by both pcre_exec() and pcre_def_exec(). */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcre_internal.h"
-
-
-/*************************************************
-* Match character against an XCLASS *
-*************************************************/
-
-/* This function is called to match a character against an extended class that
-might contain values > 255 and/or Unicode properties.
-
-Arguments:
- c the character
- data points to the flag byte of the XCLASS data
-
-Returns: TRUE if character matches, else FALSE
-*/
-
-BOOL
-PRIV(xclass)(pcre_uint32 c, const pcre_uchar *data, BOOL utf)
-{
-pcre_uchar t;
-BOOL negated = (*data & XCL_NOT) != 0;
-
-(void)utf;
-#ifdef COMPILE_PCRE8
-/* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */
-utf = TRUE;
-#endif
-
-/* Character values < 256 are matched against a bitmap, if one is present. If
-not, we still carry on, because there may be ranges that start below 256 in the
-additional data. */
-
-if (c < 256)
- {
- if ((*data & XCL_MAP) != 0 &&
- (((pcre_uint8 *)(data + 1))[c/8] & (1 << (c&7))) != 0)
- return !negated; /* char found */
- }
-
-/* First skip the bit map if present. Then match against the list of Unicode
-properties or large chars or ranges that end with a large char. We won't ever
-encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */
-
-if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(pcre_uchar);
-
-while ((t = *data++) != XCL_END)
- {
- pcre_uint32 x, y;
- if (t == XCL_SINGLE)
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- GETCHARINC(x, data); /* macro generates multiple statements */
- }
- else
-#endif
- x = *data++;
- if (c == x) return !negated;
- }
- else if (t == XCL_RANGE)
- {
-#ifdef SUPPORT_UTF
- if (utf)
- {
- GETCHARINC(x, data); /* macro generates multiple statements */
- GETCHARINC(y, data); /* macro generates multiple statements */
- }
- else
-#endif
- {
- x = *data++;
- y = *data++;
- }
- if (c >= x && c <= y) return !negated;
- }
-
-#ifdef SUPPORT_UCP
- else /* XCL_PROP & XCL_NOTPROP */
- {
- const ucd_record *prop = GET_UCD(c);
-
- switch(*data)
- {
- case PT_ANY:
- if (t == XCL_PROP) return !negated;
- break;
-
- case PT_LAMP:
- if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
- prop->chartype == ucp_Lt) == (t == XCL_PROP)) return !negated;
- break;
-
- case PT_GC:
- if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == (t == XCL_PROP))
- return !negated;
- break;
-
- case PT_PC:
- if ((data[1] == prop->chartype) == (t == XCL_PROP)) return !negated;
- break;
-
- case PT_SC:
- if ((data[1] == prop->script) == (t == XCL_PROP)) return !negated;
- break;
-
- case PT_ALNUM:
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (t == XCL_PROP))
- return !negated;
- break;
-
- case PT_SPACE: /* Perl space */
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
- == (t == XCL_PROP))
- return !negated;
- break;
-
- case PT_PXSPACE: /* POSIX space */
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
- c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
- c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP))
- return !negated;
- break;
-
- case PT_WORD:
- if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE)
- == (t == XCL_PROP))
- return !negated;
- break;
-
- case PT_UCNC:
- if (c < 0xa0)
- {
- if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
- c == CHAR_GRAVE_ACCENT) == (t == XCL_PROP))
- return !negated;
- }
- else
- {
- if ((c < 0xd800 || c > 0xdfff) == (t == XCL_PROP))
- return !negated;
- }
- break;
-
- /* This should never occur, but compilers may mutter if there is no
- default. */
-
- default:
- return FALSE;
- }
-
- data += 2;
- }
-#endif /* SUPPORT_UCP */
- }
-
-return negated; /* char did not match */
-}
-
-/* End of pcre_xclass.c */
diff --git a/usr.sbin/nginx/src/pcre/ucp.h b/usr.sbin/nginx/src/pcre/ucp.h
deleted file mode 100644
index 21039106e58..00000000000
--- a/usr.sbin/nginx/src/pcre/ucp.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/*************************************************
-* Unicode Property Table handler *
-*************************************************/
-
-#ifndef _UCP_H
-#define _UCP_H
-
-/* This file contains definitions of the property values that are returned by
-the UCD access macros. New values that are added for new releases of Unicode
-should always be at the end of each enum, for backwards compatibility.
-
-IMPORTANT: Note also that the specific numeric values of the enums have to be
-the same as the values that are generated by the maint/MultiStage2.py script,
-where the equivalent property descriptive names are listed in vectors. */
-
-/* These are the general character categories. */
-
-enum {
- ucp_C, /* Other */
- ucp_L, /* Letter */
- ucp_M, /* Mark */
- ucp_N, /* Number */
- ucp_P, /* Punctuation */
- ucp_S, /* Symbol */
- ucp_Z /* Separator */
-};
-
-/* These are the particular character categories. */
-
-enum {
- ucp_Cc, /* Control */
- ucp_Cf, /* Format */
- ucp_Cn, /* Unassigned */
- ucp_Co, /* Private use */
- ucp_Cs, /* Surrogate */
- ucp_Ll, /* Lower case letter */
- ucp_Lm, /* Modifier letter */
- ucp_Lo, /* Other letter */
- ucp_Lt, /* Title case letter */
- ucp_Lu, /* Upper case letter */
- ucp_Mc, /* Spacing mark */
- ucp_Me, /* Enclosing mark */
- ucp_Mn, /* Non-spacing mark */
- ucp_Nd, /* Decimal number */
- ucp_Nl, /* Letter number */
- ucp_No, /* Other number */
- ucp_Pc, /* Connector punctuation */
- ucp_Pd, /* Dash punctuation */
- ucp_Pe, /* Close punctuation */
- ucp_Pf, /* Final punctuation */
- ucp_Pi, /* Initial punctuation */
- ucp_Po, /* Other punctuation */
- ucp_Ps, /* Open punctuation */
- ucp_Sc, /* Currency symbol */
- ucp_Sk, /* Modifier symbol */
- ucp_Sm, /* Mathematical symbol */
- ucp_So, /* Other symbol */
- ucp_Zl, /* Line separator */
- ucp_Zp, /* Paragraph separator */
- ucp_Zs /* Space separator */
-};
-
-/* These are grapheme break properties. Note that the code for processing them
-assumes that the values are less than 16. If more values are added that take
-the number to 16 or more, the code will have to be rewritten. */
-
-enum {
- ucp_gbCR, /* 0 */
- ucp_gbLF, /* 1 */
- ucp_gbControl, /* 2 */
- ucp_gbExtend, /* 3 */
- ucp_gbPrepend, /* 4 */
- ucp_gbSpacingMark, /* 5 */
- ucp_gbL, /* 6 Hangul syllable type L */
- ucp_gbV, /* 7 Hangul syllable type V */
- ucp_gbT, /* 8 Hangul syllable type T */
- ucp_gbLV, /* 9 Hangul syllable type LV */
- ucp_gbLVT, /* 10 Hangul syllable type LVT */
- ucp_gbRegionalIndicator, /* 11 */
- ucp_gbOther /* 12 */
-};
-
-/* These are the script identifications. */
-
-enum {
- ucp_Arabic,
- ucp_Armenian,
- ucp_Bengali,
- ucp_Bopomofo,
- ucp_Braille,
- ucp_Buginese,
- ucp_Buhid,
- ucp_Canadian_Aboriginal,
- ucp_Cherokee,
- ucp_Common,
- ucp_Coptic,
- ucp_Cypriot,
- ucp_Cyrillic,
- ucp_Deseret,
- ucp_Devanagari,
- ucp_Ethiopic,
- ucp_Georgian,
- ucp_Glagolitic,
- ucp_Gothic,
- ucp_Greek,
- ucp_Gujarati,
- ucp_Gurmukhi,
- ucp_Han,
- ucp_Hangul,
- ucp_Hanunoo,
- ucp_Hebrew,
- ucp_Hiragana,
- ucp_Inherited,
- ucp_Kannada,
- ucp_Katakana,
- ucp_Kharoshthi,
- ucp_Khmer,
- ucp_Lao,
- ucp_Latin,
- ucp_Limbu,
- ucp_Linear_B,
- ucp_Malayalam,
- ucp_Mongolian,
- ucp_Myanmar,
- ucp_New_Tai_Lue,
- ucp_Ogham,
- ucp_Old_Italic,
- ucp_Old_Persian,
- ucp_Oriya,
- ucp_Osmanya,
- ucp_Runic,
- ucp_Shavian,
- ucp_Sinhala,
- ucp_Syloti_Nagri,
- ucp_Syriac,
- ucp_Tagalog,
- ucp_Tagbanwa,
- ucp_Tai_Le,
- ucp_Tamil,
- ucp_Telugu,
- ucp_Thaana,
- ucp_Thai,
- ucp_Tibetan,
- ucp_Tifinagh,
- ucp_Ugaritic,
- ucp_Yi,
- /* New for Unicode 5.0: */
- ucp_Balinese,
- ucp_Cuneiform,
- ucp_Nko,
- ucp_Phags_Pa,
- ucp_Phoenician,
- /* New for Unicode 5.1: */
- ucp_Carian,
- ucp_Cham,
- ucp_Kayah_Li,
- ucp_Lepcha,
- ucp_Lycian,
- ucp_Lydian,
- ucp_Ol_Chiki,
- ucp_Rejang,
- ucp_Saurashtra,
- ucp_Sundanese,
- ucp_Vai,
- /* New for Unicode 5.2: */
- ucp_Avestan,
- ucp_Bamum,
- ucp_Egyptian_Hieroglyphs,
- ucp_Imperial_Aramaic,
- ucp_Inscriptional_Pahlavi,
- ucp_Inscriptional_Parthian,
- ucp_Javanese,
- ucp_Kaithi,
- ucp_Lisu,
- ucp_Meetei_Mayek,
- ucp_Old_South_Arabian,
- ucp_Old_Turkic,
- ucp_Samaritan,
- ucp_Tai_Tham,
- ucp_Tai_Viet,
- /* New for Unicode 6.0.0: */
- ucp_Batak,
- ucp_Brahmi,
- ucp_Mandaic,
- /* New for Unicode 6.1.0: */
- ucp_Chakma,
- ucp_Meroitic_Cursive,
- ucp_Meroitic_Hieroglyphs,
- ucp_Miao,
- ucp_Sharada,
- ucp_Sora_Sompeng,
- ucp_Takri
-};
-
-#endif
-
-/* End of ucp.h */